From 558bf1289781500029425c2383a55d543070cfa6 Mon Sep 17 00:00:00 2001 From: Eric Blake Date: Tue, 16 Sep 2008 09:36:24 -0600 Subject: [PATCH] vasnprintf: support Irix 5.3 * lib/vasnprintf.c (VASNPRINTF): Also handle -0.0L on platforms that mishandle long double infinity. Reported by Tom G. Christensen. Signed-off-by: Eric Blake --- ChangeLog | 8 ++++++++ lib/vasnprintf.c | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++------ 2 files changed, 63 insertions(+), 6 deletions(-) diff --git a/ChangeLog b/ChangeLog index 86939ecd7..47fbf013d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,4 +1,12 @@ 2008-09-16 Bruno Haible + and Eric Blake + + vasnprintf: support Irix 5.3 + * lib/vasnprintf.c (VASNPRINTF): Also handle -0.0L on platforms + that mishandle long double infinity. + Reported by Tom G. Christensen. + +2008-09-16 Bruno Haible * doc/glibc-functions/scandir.texi: Mention the function is missing on Solaris 9. diff --git a/lib/vasnprintf.c b/lib/vasnprintf.c index 4ddf45fa0..ace89338e 100644 --- a/lib/vasnprintf.c +++ b/lib/vasnprintf.c @@ -255,11 +255,11 @@ is_infinite_or_zero (double x) #if NEED_PRINTF_INFINITE_LONG_DOUBLE && !NEED_PRINTF_LONG_DOUBLE && !defined IN_LIBINTL -/* Equivalent to !isfinite(x), but does not require libm. */ +/* Equivalent to !isfinite(x) || x == 0, but does not require libm. */ static int -is_infinitel (long double x) +is_infinite_or_zerol (long double x) { - return isnanl (x) || (x + x == x && x != 0.0L); + return isnanl (x) || x + x == x; } #endif @@ -2578,8 +2578,10 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, # elif NEED_PRINTF_INFINITE_LONG_DOUBLE || (a.arg[dp->arg_index].type == TYPE_LONGDOUBLE /* Some systems produce wrong output for Inf, - -Inf, and NaN. */ - && is_infinitel (a.arg[dp->arg_index].a.a_longdouble)) + -Inf, and NaN. Some systems in this category + (IRIX 5.3) also do so for -0.0. Therefore we + treat this case here as well. */ + && is_infinite_or_zerol (a.arg[dp->arg_index].a.a_longdouble)) # endif )) { @@ -3139,7 +3141,54 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, abort (); # else /* arg is finite. */ - abort (); + if (!(arg == 0.0L)) + abort (); + + pad_ptr = p; + + if (dp->conversion == 'f' || dp->conversion == 'F') + { + *p++ = '0'; + if ((flags & FLAG_ALT) || precision > 0) + { + *p++ = decimal_point_char (); + for (; precision > 0; precision--) + *p++ = '0'; + } + } + else if (dp->conversion == 'e' || dp->conversion == 'E') + { + *p++ = '0'; + if ((flags & FLAG_ALT) || precision > 0) + { + *p++ = decimal_point_char (); + for (; precision > 0; precision--) + *p++ = '0'; + } + *p++ = dp->conversion; /* 'e' or 'E' */ + *p++ = '+'; + /* Produce the same number of exponent digits as + the native printf implementation. */ +# if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ + *p++ = '0'; +# endif + *p++ = '0'; + *p++ = '0'; + } + else if (dp->conversion == 'g' || dp->conversion == 'G') + { + *p++ = '0'; + if (flags & FLAG_ALT) + { + size_t ndigits = + (precision > 0 ? precision - 1 : 0); + *p++ = decimal_point_char (); + for (; ndigits > 0; --ndigits) + *p++ = '0'; + } + } + else + abort (); # endif } -- 2.11.0