This is the mail archive of the libstdc++@sourceware.cygnus.com mailing list for the libstdc++ project. See the libstdc++ home page for more information.
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |
Hi, I enclose a diff against a clean egcs-1.1.2/libio/iovfscanf.c and a test file to show the patch effect. The patch applies also cleanly to libstdc++-2.90.4, but I have not tested it with that distribution. Implementing the changes at this level will affect all derived classes. I have relinked some C++ applications with the newly created lib and they work OK. The decision to implement the changes only at iovfscanf.c and not also at floatconv.c, _IO_strtod(), was due to a conditional compilation at iovfscanf.c that could imply that in some platforms the system atof() would be used, with no warranty that it would be able to read inf/nan's. This makes the patch a bit ugly. The test case, teste2.cc, should produce the following output: 1. -INF +INF INF -Infinity Infinity Infinity 2. -Inf +Inf Inf -Infinity Infinity Infinity 3. -inf +inf inf -Infinity Infinity Infinity 4. -infI +iNfiN iNfInity -Infinity Infinity Infinity 5. -nan +nan nan -NaN -NaN -NaN 6. -NaN +NaN NaN -NaN -NaN -NaN 7. -NAN +NAN NAN -NaN -NaN -NaN 8. -NAN(0x123123) +NaN(0x5464) nan(0x34) -NaN -NaN -NaN 9. -121.12 NaN +3123.4 Inf 0.232 -121.12 -NaN 3123.4 Infinity 0.232 If you have any problem with the patch, please contact me or <ajc@inescn.pt>, the real code writer. Hopping that this will be accepted, Joao -- Joao Cardoso, INESC | e-mail: jcardoso@inescn.pt R. Jose Falcao 110 | tel: + 351 2 2094345 4050 Porto, Portugal | fax: + 351 2 2008487
#include <strstream.h> #include <ieeefp.h> main(){ double x=1./0., y=0./0.; double a=0.1, b=0.1, d=0.1, e=0.1, f=0.1, g=0.1, h=0.1, j=0.1; char c, buf[100]; ostrstream os(buf,100); istrstream is(buf,100); os << "-INF\t" << "+INF\t" << "INF" << '\0'; is >> a >> c >> b >> c >> d >> c; if (finite(a) || finite(b) || finite(d)) cout << "1- Error\n"; cout << "1. " << buf << "\n " << a << "\t" << b << "\t" << d << '\n'; os.seekp(ios::beg); is.seekg(0L,ios::beg); os << "-Inf\t" << "+Inf\t" << "Inf" << '\0'; is >> a >> c >> b >> c >> d >> c; if (finite(a) || finite(b) || finite(d)) cout << "2- Error\n"; cout << "2. " << buf << "\n " << a << "\t" << b << "\t" << d << '\n'; os.seekp(ios::beg); is.seekg(0L,ios::beg); os << "-inf\t" << "+inf\t" << "inf" << '\0'; is >> a >> c >> b >> c >> d >> c; if (finite(a) || finite(b) || finite(d)) cout << "3- Error\n"; cout << "3. " << buf << "\n " << a << "\t" << b << "\t" << d << '\n'; os.seekp(ios::beg); is.seekg(0L,ios::beg); os << "-infI\t" << "+iNfiN\t" << "iNfInity" << '\0'; is >> a >> c >> b >> c >> d >> c; if (finite(a) || finite(b) || finite(d)) cout << "4- Error\n"; cout << "4. " << buf << "\n " << a << "\t" << b << "\t" << d << '\n'; os.seekp(ios::beg); is.seekg(0L,ios::beg); os << "-nan\t" << "+nan\t" << "nan" << '\0'; is >> a >> c >> b >> c >> d >> c; if (!isnand(a) || !isnand(b) || !isnand(d)) cout << "5- Error\n"; cout << "5. " << buf << "\n " << a << "\t" << b << "\t" << d << '\n'; os.seekp(ios::beg); is.seekg(0L,ios::beg); os << "-NaN\t" << "+NaN\t" << "NaN" << '\0'; is >> a >> c >> b >> c >> d >> c; if (!isnand(a) || !isnand(b) || !isnand(d)) cout << "6- Error\n"; cout << "6. " << buf << "\n " << a << "\t" << b << "\t" << d << '\n'; os.seekp(ios::beg); is.seekg(0L,ios::beg); os << "-NAN\t" << "+NAN\t" << "NAN" << '\0'; is >> a >> c >> b >> c >> d >> c; if (!isnand(a) || !isnand(b) || !isnand(d)) cout << "7- Error\n"; cout << "7. " << buf << "\n " << a << "\t" << b << "\t" << d << '\n'; os.seekp(ios::beg); is.seekg(0L,ios::beg); os << "-NAN(0x123123)\t" << "+NaN(0x5464)\t" << "nan(0x34)" << '\0'; is >> a >> c >> b >> c >> d >> c; if (!isnand(a) || !isnand(b) || !isnand(d)) cout << "8- Error\n"; cout << "8. " << buf << "\n " << a << "\t" << b << "\t" << d << '\n'; os.seekp(ios::beg); is.seekg(0L,ios::beg); os << "-121.12\t" << "NaN\t" << "+3123.4\t" << "Inf\t" << "0.232" << '\0'; is >> a >> c >> b >> c >> d >> c >> e >> c >> f; if (a != -121.12 || !isnand(b) || d != 3123.4 || finite(e) || f != 0.232) cout << "9- Error\n"; cout << "9. " << buf << "\n " << a << "\t" << b << "\t" << d << "\t" << e << "\t" << f <<'\n'; }
*** iovfscanf.c.org Sat Apr 10 04:10:34 1999 --- iovfscanf.c Sat Apr 10 05:03:34 1999 *************** *** 81,86 **** --- 81,88 ---- * SIGNOK, NDIGITS, DPTOK, and EXPOK are for floating point; * SIGNOK, NDIGITS, PFXOK, and NZDIGITS are for integral. */ + #define NNAN 0x02 + #define NINF 0x04 #define SIGNOK 0x40 /* +/- is (still) legal */ #define NDIGITS 0x80 /* no digits detected */ *************** *** 627,632 **** --- 629,641 ---- goto fok; } break; + case 'n': case 'N': case 'i': case 'I': + flags|=NNAN; + case 'f': case 't': case 'y': case 'a': + case 'F': case 'T': case 'Y': case 'A': + case 'x': case 'X': case '(': case ')': + if(flags&NNAN) + goto fok; } break; fok: *************** *** 637,642 **** --- 646,659 ---- break; /* EOF */ } } + + if (flags & NNAN) { + flags|=NDIGITS|EXPOK; + if((flags & SIGNOK)==0) + if ((*buf!='+')&&(*buf!='-')) + flags|=SIGNOK; + } + /* * If no digits, might be missing exponent digits * (just give back the exponent) or might be missing *************** *** 644,654 **** */ if (flags & NDIGITS) { if (flags & EXPOK) { ! /* no digits at all */ ! while (p > buf) _IO_ungetc (*(u_char *)--p, fp); ! goto match_failure; ! } /* just a bad exponent (e and maybe sign) */ c = *(u_char *)--p; if (c != 'e' && c != 'E') { --- 661,706 ---- */ if (flags & NDIGITS) { if (flags & EXPOK) { ! int sign; ! double res; ! char *s; ! ! sign=1; ! s=buf; ! flags&=~(NINF|NNAN); ! if((flags & SIGNOK)==0) ! sign= (*s++=='-')? -1: 1; ! ! if(*s=='I'||*s=='i') { ! ++s; ! if(*s=='N'||*s=='n') { ! ++s; ! if(*s=='F'||*s=='f') ! flags|=NINF; ! } ! } ! else if(*s=='N'||*s=='n') { ! ++s; ! if(*s=='A'||*s=='a') { ! ++s; ! if(*s=='N'||*s=='n') ! flags|=NNAN; ! } ! } ! if (flags&(NINF|NNAN)) { ! nassigned++; ! res= (double)sign*(((flags & NINF))?1.0/0.:0./0.); ! if (flags & LONG) ! *va_arg(ap, double *) = res; ! else ! *va_arg(ap, float *) = res; ! break; ! } ! /* no digits at all */ ! while (p > buf) _IO_ungetc (*(u_char *)--p, fp); ! goto match_failure; ! } /* just a bad exponent (e and maybe sign) */ c = *(u_char *)--p; if (c != 'e' && c != 'E') {