From 6bdac416e9e1aecfb94cd3ae383889cc7b7e62e3 Mon Sep 17 00:00:00 2001 From: Jeff Johnston Date: Wed, 6 Dec 2000 23:50:11 +0000 Subject: 2000-12-06 Jeff Johnston * libc/stdlib/Makefile.am: Added ldtoa.c to list of sources. * libc/stdlib/Makefile.in: Regenerated. * libc/stdio/floatio.h: Added suitable MAXEXP for long double. * libc/stdio/vfieeefp.h: Added long double bit structures. * libc/stdio/vfprintf.c[WANT_IO_LONG_DBL]: Added long double support. [WANT_IO_LONG_DBL](isinfl, isnanl): New static long double routines. (exponent): Changed expbuf to reasonable maximum instead of MAXEXP. * libc/stdio/vfscanf.c[WANT_IO_LONG_DBL]: Added long double support. * libc/stdlib/ldtoa.c: New file containing _ldtoa_r and _strtold routines used for conversions between character and long double. --- newlib/libc/stdio/vfscanf.c | 28 ++++++++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) (limited to 'newlib/libc/stdio/vfscanf.c') diff --git a/newlib/libc/stdio/vfscanf.c b/newlib/libc/stdio/vfscanf.c index 7e88f1202..cc0f26d3c 100644 --- a/newlib/libc/stdio/vfscanf.c +++ b/newlib/libc/stdio/vfscanf.c @@ -34,6 +34,17 @@ #endif #ifdef FLOATING_POINT +#include + +/* Currently a test is made to see if long double processing is warranted. + This could be changed in the future should the _ldtoa_r code be + preferred over _dtoa_r. */ +#define _NO_LONGDBL +#if defined WANT_IO_LONG_DBL && (LDBL_MANT_DIG > DBL_MANT_DIG) +#undef _NO_LONGDBL +extern _LONG_DOUBLE _strtold _PARAMS((char *s, char **sptr)); +#endif + #include "floatio.h" #define BUF (MAXEXP+MAXFRACT+3) /* 3 = sign + decimal point + NUL */ /* An upper bound for how long a long prints in decimal. 4 / 13 approximates @@ -48,7 +59,7 @@ */ #define LONG 0x01 /* l: long or double */ -#define LONGDBL 0x02 /* L: long double; unimplemented */ +#define LONGDBL 0x02 /* L: long double */ #define SHORT 0x04 /* h: short */ #define SUPPRESS 0x08 /* suppress assignment */ #define POINTER 0x10 /* weird %p pointer (`fake hex') */ @@ -372,7 +383,7 @@ __svfscanf (fp, fmt0, ap) for (;;) { - if ((n = fp->_r) < width) + if ((n = fp->_r) < (int)width) { sum += n; width -= n; @@ -683,8 +694,9 @@ __svfscanf (fp, fmt0, ap) However, ANSI / ISO C makes no such stipulation; we have to get exact results even when there is an unreasonable amount of leading zeroes. */ - long leading_zeroes, zeroes, exp_adjust; - char *exp_start; + long leading_zeroes = 0; + long zeroes, exp_adjust; + char *exp_start = NULL; #ifdef hardway if (width == 0 || width > sizeof (buf) - 1) width = sizeof (buf) - 1; @@ -808,7 +820,11 @@ __svfscanf (fp, fmt0, ap) } if ((flags & SUPPRESS) == 0) { +#ifdef _NO_LONGDBL double res; +#else /* !_NO_LONG_DBL */ + long double res; +#endif /* !_NO_LONG_DBL */ long new_exp; *p = 0; @@ -829,7 +845,11 @@ __svfscanf (fp, fmt0, ap) exp_start = buf + sizeof (buf) - MAX_LONG_LEN - 1; sprintf (exp_start, "e%ld", new_exp); } +#ifdef _NO_LONG_DBL res = atof (buf); +#else /* !_NO_LONG_DBL */ + res = _strtold (buf, NULL); +#endif /* !_NO_LONG_DBL */ if (flags & LONG) { dp = va_arg (ap, double *); -- cgit v1.2.3