From 118b9d3f012ecb34be9e3a68a25996f30b7868ab Mon Sep 17 00:00:00 2001 From: Bruno Haible Date: Sat, 19 May 2007 14:52:36 +0000 Subject: [PATCH] Fix *printf result for NaN, Inf, -0.0 on mingw. --- ChangeLog | 28 ++ doc/functions/fprintf.texi | 4 + doc/functions/printf.texi | 4 + doc/functions/snprintf.texi | 4 + doc/functions/sprintf.texi | 4 + doc/functions/vfprintf.texi | 4 + doc/functions/vprintf.texi | 4 + doc/functions/vsnprintf.texi | 4 + doc/functions/vsprintf.texi | 4 + lib/vasnprintf.c | 675 ++++++++++++++++++++++++++----------------- m4/fprintf-posix.m4 | 28 +- m4/printf.m4 | 144 ++++++--- m4/snprintf-posix.m4 | 36 ++- m4/sprintf-posix.m4 | 28 +- m4/vasnprintf-posix.m4 | 32 +- m4/vasnprintf.m4 | 18 +- m4/vasprintf-posix.m4 | 32 +- m4/vfprintf-posix.m4 | 28 +- m4/vsnprintf-posix.m4 | 36 ++- m4/vsprintf-posix.m4 | 28 +- 20 files changed, 734 insertions(+), 411 deletions(-) diff --git a/ChangeLog b/ChangeLog index f4bcfacf3..785b19c04 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,33 @@ 2007-05-19 Bruno Haible + Fix *printf result for NaN, Inf, -0.0 on mingw. + * m4/printf.m4 (gl_PRINTF_INFINITE): New macro. + * lib/vasnprintf.c: Include math.h and isnan.h. + (is_infinite_or_zero): New function. + (VASNPRINTF): Fix also the handling of infinite or zero 'double' + values in the %f, %F, %e, %E, %g, %G directives. + * m4/vasnprintf.m4 (gl_PREREQ_VASNPRINTF_INFINITE): New macro. + * m4/fprintf-posix.m4 (gl_FUNC_FPRINTF_POSIX): Invoke + gl_PRINTF_INFINITE and test its result. Invoke + gl_PREREQ_VASNPRINTF_INFINITE. + * m4/snprintf-posix.m4 (gl_FUNC_SNPRINTF_POSIX): Likewise. + * m4/sprintf-posix.m4 (gl_FUNC_SPRINTF_POSIX): Likewise. + * m4/vasnprintf-posix.m4 (gl_FUNC_VASNPRINTF_POSIX): Likewise. + * m4/vasprintf-posix.m4 (gl_FUNC_VASPRINTF_POSIX): Likewise. + * m4/vfprintf-posix.m4 (gl_FUNC_VFPRINTF_POSIX): Likewise. + * m4/vsnprintf-posix.m4 (gl_FUNC_VSNPRINTF_POSIX): Likewise. + * m4/vsprintf-posix.m4 (gl_FUNC_VSPRINTF_POSIX): Likewise. + * doc/functions/fprintf.texi: Update. + * doc/functions/printf.texi: Update. + * doc/functions/snprintf.texi: Update. + * doc/functions/sprintf.texi: Update. + * doc/functions/vfprintf.texi: Update. + * doc/functions/vprintf.texi: Update. + * doc/functions/vsnprintf.texi: Update. + * doc/functions/vsprintf.texi: Update. + +2007-05-19 Bruno Haible + * lib/vasnprintf.c (convert_to_decimal): Add an extra_zeroes argument. (scale10_round_decimal_long_double): Inline scale10_round_long_double. Instead of multiplying with 10^k, set extra_zeroes to k. diff --git a/doc/functions/fprintf.texi b/doc/functions/fprintf.texi index fc366df6b..d87f312ad 100644 --- a/doc/functions/fprintf.texi +++ b/doc/functions/fprintf.texi @@ -13,6 +13,10 @@ This function does not support size specifiers as in C99 (@code{hh}, @code{ll}, @code{j}, @code{t}, @code{z}) on some platforms: AIX 5.1, HP-UX 11.23, IRIX 6.5, OSF/1 5.1, Solaris 9, Cygwin 2006, mingw, BeOS. @item +printf @code{"%f"}, @code{"%e"}, @code{"%g"} of Infinity and NaN yields an +incorrect result on some platforms: +mingw. +@item printf of @samp{long double} numbers is unsupported on some platforms: mingw, BeOS. @item diff --git a/doc/functions/printf.texi b/doc/functions/printf.texi index 741e1975f..57fe9e38a 100644 --- a/doc/functions/printf.texi +++ b/doc/functions/printf.texi @@ -13,6 +13,10 @@ This function does not support size specifiers as in C99 (@code{hh}, @code{ll}, @code{j}, @code{t}, @code{z}) on some platforms: AIX 5.1, HP-UX 11.23, IRIX 6.5, OSF/1 5.1, Solaris 9, Cygwin 2006, mingw, BeOS. @item +printf @code{"%f"}, @code{"%e"}, @code{"%g"} of Infinity and NaN yields an +incorrect result on some platforms: +mingw. +@item printf of @samp{long double} numbers is unsupported on some platforms: mingw, BeOS. @item diff --git a/doc/functions/snprintf.texi b/doc/functions/snprintf.texi index 2f3e315e2..5b431bba5 100644 --- a/doc/functions/snprintf.texi +++ b/doc/functions/snprintf.texi @@ -20,6 +20,10 @@ This function does not support size specifiers as in C99 (@code{hh}, @code{ll}, @code{j}, @code{t}, @code{z}) on some platforms: AIX 5.1, HP-UX 11.23, IRIX 6.5, OSF/1 5.1, Solaris 9, Cygwin 2006, mingw, BeOS. @item +printf @code{"%f"}, @code{"%e"}, @code{"%g"} of Infinity and NaN yields an +incorrect result on some platforms: +mingw. +@item printf of @samp{long double} numbers is unsupported on some platforms: mingw, BeOS. @item diff --git a/doc/functions/sprintf.texi b/doc/functions/sprintf.texi index b04e3d060..b7a1b0d19 100644 --- a/doc/functions/sprintf.texi +++ b/doc/functions/sprintf.texi @@ -13,6 +13,10 @@ This function does not support size specifiers as in C99 (@code{hh}, @code{ll}, @code{j}, @code{t}, @code{z}) on some platforms: AIX 5.1, HP-UX 11.23, IRIX 6.5, OSF/1 5.1, Solaris 9, Cygwin 2006, mingw, BeOS. @item +printf @code{"%f"}, @code{"%e"}, @code{"%g"} of Infinity and NaN yields an +incorrect result on some platforms: +mingw. +@item printf of @samp{long double} numbers is unsupported on some platforms: mingw, BeOS. @item diff --git a/doc/functions/vfprintf.texi b/doc/functions/vfprintf.texi index 830d3cbc9..084a0509e 100644 --- a/doc/functions/vfprintf.texi +++ b/doc/functions/vfprintf.texi @@ -13,6 +13,10 @@ This function does not support size specifiers as in C99 (@code{hh}, @code{ll}, @code{j}, @code{t}, @code{z}) on some platforms: AIX 5.1, HP-UX 11.23, IRIX 6.5, OSF/1 5.1, Solaris 9, Cygwin 2006, mingw, BeOS. @item +printf @code{"%f"}, @code{"%e"}, @code{"%g"} of Infinity and NaN yields an +incorrect result on some platforms: +mingw. +@item printf of @samp{long double} numbers is unsupported on some platforms: mingw, BeOS. @item diff --git a/doc/functions/vprintf.texi b/doc/functions/vprintf.texi index e57a2f30d..05c6aac26 100644 --- a/doc/functions/vprintf.texi +++ b/doc/functions/vprintf.texi @@ -13,6 +13,10 @@ This function does not support size specifiers as in C99 (@code{hh}, @code{ll}, @code{j}, @code{t}, @code{z}) on some platforms: AIX 5.1, HP-UX 11.23, IRIX 6.5, OSF/1 5.1, Solaris 9, Cygwin 2006, mingw, BeOS. @item +printf @code{"%f"}, @code{"%e"}, @code{"%g"} of Infinity and NaN yields an +incorrect result on some platforms: +mingw. +@item printf of @samp{long double} numbers is unsupported on some platforms: mingw, BeOS. @item diff --git a/doc/functions/vsnprintf.texi b/doc/functions/vsnprintf.texi index b938bd7ca..616eced39 100644 --- a/doc/functions/vsnprintf.texi +++ b/doc/functions/vsnprintf.texi @@ -20,6 +20,10 @@ This function does not support size specifiers as in C99 (@code{hh}, @code{ll}, @code{j}, @code{t}, @code{z}) on some platforms: AIX 5.1, HP-UX 11.23, IRIX 6.5, OSF/1 5.1, Solaris 9, Cygwin 2006, mingw, BeOS. @item +printf @code{"%f"}, @code{"%e"}, @code{"%g"} of Infinity and NaN yields an +incorrect result on some platforms: +mingw. +@item printf of @samp{long double} numbers is unsupported on some platforms: mingw, BeOS. @item diff --git a/doc/functions/vsprintf.texi b/doc/functions/vsprintf.texi index ce6a3c298..70aaf31e6 100644 --- a/doc/functions/vsprintf.texi +++ b/doc/functions/vsprintf.texi @@ -13,6 +13,10 @@ This function does not support size specifiers as in C99 (@code{hh}, @code{ll}, @code{j}, @code{t}, @code{z}) on some platforms: AIX 5.1, HP-UX 11.23, IRIX 6.5, OSF/1 5.1, Solaris 9, Cygwin 2006, mingw, BeOS. @item +printf @code{"%f"}, @code{"%e"}, @code{"%g"} of Infinity and NaN yields an +incorrect result on some platforms: +mingw. +@item printf of @samp{long double} numbers is unsupported on some platforms: mingw, BeOS. @item diff --git a/lib/vasnprintf.c b/lib/vasnprintf.c index 00c4a6daa..49692f16a 100644 --- a/lib/vasnprintf.c +++ b/lib/vasnprintf.c @@ -53,13 +53,9 @@ /* Checked size_t computations. */ #include "xsize.h" -#if NEED_PRINTF_DIRECTIVE_A && !defined IN_LIBINTL +#if NEED_PRINTF_INFINITE && !defined IN_LIBINTL # include # include "isnan.h" -# include "printf-frexp.h" -# include "isnanl-nolibm.h" -# include "printf-frexpl.h" -# include "fpucw.h" #endif #if NEED_PRINTF_LONG_DOUBLE && !defined IN_LIBINTL @@ -67,6 +63,15 @@ # include "float+.h" #endif +#if NEED_PRINTF_DIRECTIVE_A && !defined IN_LIBINTL +# include +# include "isnan.h" +# include "printf-frexp.h" +# include "isnanl-nolibm.h" +# include "printf-frexpl.h" +# include "fpucw.h" +#endif + /* Some systems, like OSF/1 4.0 and Woe32, don't have EOVERFLOW. */ #ifndef EOVERFLOW # define EOVERFLOW E2BIG @@ -164,6 +169,17 @@ decimal_point_char () # endif #endif +#if NEED_PRINTF_INFINITE && !defined IN_LIBINTL + +/* Equivalent to !isfinite(x) || x == 0, but does not require libm. */ +static int +is_infinite_or_zero (double x) +{ + return isnan (x) || x + x == x; +} + +#endif + #if NEED_PRINTF_LONG_DOUBLE && !defined IN_LIBINTL /* Converting 'long double' to decimal without rare rounding bugs requires @@ -1257,18 +1273,29 @@ VASNPRINTF (CHAR_T *resultbuf, size_t *lengthp, const CHAR_T *format, va_list ar abort (); } } -#if NEED_PRINTF_LONG_DOUBLE && !defined IN_LIBINTL +#if (NEED_PRINTF_INFINITE || NEED_PRINTF_LONG_DOUBLE) && !defined IN_LIBINTL else if ((dp->conversion == 'f' || dp->conversion == 'F' || dp->conversion == 'e' || dp->conversion == 'E' || dp->conversion == 'g' || dp->conversion == 'G') - && a.arg[dp->arg_index].type == TYPE_LONGDOUBLE) + && (0 +# if NEED_PRINTF_INFINITE + || (a.arg[dp->arg_index].type == TYPE_DOUBLE + /* The systems (mingw) which produce wrong output + for Inf and -Inf also do so for NaN and -0.0. + Therefore we treat these cases here as well. */ + && is_infinite_or_zero (a.arg[dp->arg_index].a.a_double)) +# endif +# if NEED_PRINTF_LONG_DOUBLE + || a.arg[dp->arg_index].type == TYPE_LONGDOUBLE +# endif + )) { + arg_type type = a.arg[dp->arg_index].type; int flags = dp->flags; int has_width; size_t width; int has_precision; size_t precision; - long double arg; size_t tmp_length; CHAR_T tmpbuf[700]; CHAR_T *tmp; @@ -1337,19 +1364,38 @@ VASNPRINTF (CHAR_T *resultbuf, size_t *lengthp, const CHAR_T *format, va_list ar } } - arg = a.arg[dp->arg_index].a.a_longdouble; + /* POSIX specifies the default precision to be 6 for %f, %F, + %e, %E, but not for %g, %G. Implementations appear to use + the same default precision also for %g, %G. */ + if (!has_precision) + precision = 6; /* Allocate a temporary buffer of sufficient size. */ +# if NEED_PRINTF_INFINITE && NEED_PRINTF_LONG_DOUBLE + tmp_length = (type == TYPE_LONGDOUBLE ? LDBL_DIG + 1 : 0); +# elif NEED_PRINTF_LONG_DOUBLE tmp_length = LDBL_DIG + 1; +# elif NEED_PRINTF_INFINITE + tmp_length = 0; +# endif if (tmp_length < precision) tmp_length = precision; - if (dp->conversion == 'f' || dp->conversion == 'F') - if (!(isnanl (arg) || arg + arg == arg)) +# if NEED_PRINTF_LONG_DOUBLE +# if NEED_PRINTF_INFINITE + if (type == TYPE_LONGDOUBLE) +# endif + if (dp->conversion == 'f' || dp->conversion == 'F') { - int exponent = floorlog10l (arg < 0 ? -arg : arg); - if (exponent >= 0 && tmp_length < exponent + precision) - tmp_length = exponent + precision; + long double arg = a.arg[dp->arg_index].a.a_longdouble; + if (!(isnanl (arg) || arg + arg == arg)) + { + /* arg is finite and nonzero. */ + int exponent = floorlog10l (arg < 0 ? -arg : arg); + if (exponent >= 0 && tmp_length < exponent + precision) + tmp_length = exponent + precision; + } } +# endif /* Account for sign, decimal point etc. */ tmp_length = xsum (tmp_length, 12); @@ -1376,156 +1422,88 @@ VASNPRINTF (CHAR_T *resultbuf, size_t *lengthp, const CHAR_T *format, va_list ar pad_ptr = NULL; p = tmp; - if (isnanl (arg)) - { - if (dp->conversion >= 'A' && dp->conversion <= 'Z') - { - *p++ = 'N'; *p++ = 'A'; *p++ = 'N'; - } - else - { - *p++ = 'n'; *p++ = 'a'; *p++ = 'n'; - } - } - else +# if NEED_PRINTF_LONG_DOUBLE +# if NEED_PRINTF_INFINITE + if (type == TYPE_LONGDOUBLE) +# endif { - int sign = 0; - DECL_LONG_DOUBLE_ROUNDING - - BEGIN_LONG_DOUBLE_ROUNDING (); - - if (signbit (arg)) /* arg < 0.0L or negative zero */ - { - sign = -1; - arg = -arg; - } - - if (sign < 0) - *p++ = '-'; - else if (flags & FLAG_SHOWSIGN) - *p++ = '+'; - else if (flags & FLAG_SPACE) - *p++ = ' '; + long double arg = a.arg[dp->arg_index].a.a_longdouble; - if (arg > 0.0L && arg + arg == arg) + if (isnanl (arg)) { if (dp->conversion >= 'A' && dp->conversion <= 'Z') { - *p++ = 'I'; *p++ = 'N'; *p++ = 'F'; + *p++ = 'N'; *p++ = 'A'; *p++ = 'N'; } else { - *p++ = 'i'; *p++ = 'n'; *p++ = 'f'; + *p++ = 'n'; *p++ = 'a'; *p++ = 'n'; } } else { - pad_ptr = p; + int sign = 0; + DECL_LONG_DOUBLE_ROUNDING + + BEGIN_LONG_DOUBLE_ROUNDING (); - if (dp->conversion == 'f' || dp->conversion == 'F') + if (signbit (arg)) /* arg < 0.0L or negative zero */ { - char *digits; - size_t ndigits; + sign = -1; + arg = -arg; + } - if (!has_precision) - precision = 6; + if (sign < 0) + *p++ = '-'; + else if (flags & FLAG_SHOWSIGN) + *p++ = '+'; + else if (flags & FLAG_SPACE) + *p++ = ' '; - digits = - scale10_round_decimal_long_double (arg, precision); - if (digits == NULL) + if (arg > 0.0L && arg + arg == arg) + { + if (dp->conversion >= 'A' && dp->conversion <= 'Z') { - END_LONG_DOUBLE_ROUNDING (); - goto out_of_memory; + *p++ = 'I'; *p++ = 'N'; *p++ = 'F'; } - ndigits = strlen (digits); - - if (ndigits > precision) - do - { - --ndigits; - *p++ = digits[ndigits]; - } - while (ndigits > precision); else - *p++ = '0'; - /* Here ndigits <= precision. */ - if ((flags & FLAG_ALT) || precision > 0) { - *p++ = decimal_point_char (); - for (; precision > ndigits; precision--) - *p++ = '0'; - while (ndigits > 0) - { - --ndigits; - *p++ = digits[ndigits]; - } + *p++ = 'i'; *p++ = 'n'; *p++ = 'f'; } - - free (digits); } - else if (dp->conversion == 'e' || dp->conversion == 'E') + else { - int exponent; - - if (!has_precision) - precision = 6; + pad_ptr = p; - if (arg == 0.0L) - { - exponent = 0; - *p++ = '0'; - if ((flags & FLAG_ALT) || precision > 0) - { - *p++ = decimal_point_char (); - for (; precision > 0; precision--) - *p++ = '0'; - } - } - else + if (dp->conversion == 'f' || dp->conversion == 'F') { - /* arg > 0.0L. */ - int adjusted; char *digits; size_t ndigits; - exponent = floorlog10l (arg); - adjusted = 0; - for (;;) + digits = + scale10_round_decimal_long_double (arg, precision); + if (digits == NULL) { - digits = - scale10_round_decimal_long_double (arg, - (int)precision - exponent); - if (digits == NULL) - { - END_LONG_DOUBLE_ROUNDING (); - goto out_of_memory; - } - ndigits = strlen (digits); - - if (ndigits == precision + 1) - break; - if (ndigits < precision - || ndigits > precision + 2) - /* The exponent was not guessed precisely - enough. */ - abort (); - if (adjusted) - /* None of two values of exponent is the - right one. Prevent an endless loop. */ - abort (); - free (digits); - if (ndigits == precision) - exponent -= 1; - else - exponent += 1; - adjusted = 1; + END_LONG_DOUBLE_ROUNDING (); + goto out_of_memory; } + ndigits = strlen (digits); - /* Here ndigits = precision+1. */ - *p++ = digits[--ndigits]; + if (ndigits > precision) + do + { + --ndigits; + *p++ = digits[ndigits]; + } + while (ndigits > precision); + else + *p++ = '0'; + /* Here ndigits <= precision. */ if ((flags & FLAG_ALT) || precision > 0) { *p++ = decimal_point_char (); + for (; precision > ndigits; precision--) + *p++ = '0'; while (ndigits > 0) { --ndigits; @@ -1535,176 +1513,347 @@ VASNPRINTF (CHAR_T *resultbuf, size_t *lengthp, const CHAR_T *format, va_list ar free (digits); } - - *p++ = dp->conversion; /* 'e' or 'E' */ -# if WIDE_CHAR_VERSION - { - static const wchar_t decimal_format[] = - { '%', '+', '.', '2', 'd', '\0' }; - SNPRINTF (p, 6 + 1, decimal_format, exponent); - } -# else - sprintf (p, "%+.2d", exponent); -# endif - while (*p != '\0') - p++; - } - else if (dp->conversion == 'g' || dp->conversion == 'G') - { - /* This is not specified by POSIX, but - implementations appear to do this. */ - if (!has_precision) - precision = 6; - - if (precision == 0) - precision = 1; - /* precision >= 1. */ - - if (arg == 0.0L) - /* The exponent is 0, >= -4, < precision. - Use fixed-point notation. */ - { - size_t ndigits = precision; - /* Number of trailing zeroes that have to be - dropped. */ - size_t nzeroes = - (flags & FLAG_ALT ? 0 : precision - 1); - - --ndigits; - *p++ = '0'; - if ((flags & FLAG_ALT) || ndigits > nzeroes) - { - *p++ = decimal_point_char (); - while (ndigits > nzeroes) - { - --ndigits; - *p++ = '0'; - } - } - } - else + else if (dp->conversion == 'e' || dp->conversion == 'E') { - /* arg > 0.0L. */ int exponent; - int adjusted; - char *digits; - size_t ndigits; - size_t nzeroes; - exponent = floorlog10l (arg); - adjusted = 0; - for (;;) + if (arg == 0.0L) { - digits = - scale10_round_decimal_long_double (arg, - (int)(precision - 1) - exponent); - if (digits == NULL) + exponent = 0; + *p++ = '0'; + if ((flags & FLAG_ALT) || precision > 0) { - END_LONG_DOUBLE_ROUNDING (); - goto out_of_memory; + *p++ = decimal_point_char (); + for (; precision > 0; precision--) + *p++ = '0'; } - ndigits = strlen (digits); - - if (ndigits == precision) - break; - if (ndigits < precision - 1 - || ndigits > precision + 1) - /* The exponent was not guessed precisely - enough. */ - abort (); - if (adjusted) - /* None of two values of exponent is the - right one. Prevent an endless loop. */ - abort (); - free (digits); - if (ndigits < precision) - exponent -= 1; - else - exponent += 1; - adjusted = 1; } - /* Here ndigits = precision. */ - - /* Determine the number of trailing zeroes that - have to be dropped. */ - nzeroes = 0; - if ((flags & FLAG_ALT) == 0) - while (nzeroes < ndigits - && digits[nzeroes] == '0') - nzeroes++; - - /* The exponent is now determined. */ - if (exponent >= -4 && exponent < (long)precision) + else { - /* Fixed-point notation: max(exponent,0)+1 - digits, then the decimal point, then the - remaining digits without trailing zeroes. */ - if (exponent >= 0) + /* arg > 0.0L. */ + int adjusted; + char *digits; + size_t ndigits; + + exponent = floorlog10l (arg); + adjusted = 0; + for (;;) { - size_t count = exponent + 1; - /* Note: count <= precision = ndigits. */ - for (; count > 0; count--) - *p++ = digits[--ndigits]; - if ((flags & FLAG_ALT) || ndigits > nzeroes) + digits = + scale10_round_decimal_long_double (arg, + (int)precision - exponent); + if (digits == NULL) { - *p++ = decimal_point_char (); - while (ndigits > nzeroes) - { - --ndigits; - *p++ = digits[ndigits]; - } + END_LONG_DOUBLE_ROUNDING (); + goto out_of_memory; } + ndigits = strlen (digits); + + if (ndigits == precision + 1) + break; + if (ndigits < precision + || ndigits > precision + 2) + /* The exponent was not guessed + precisely enough. */ + abort (); + if (adjusted) + /* None of two values of exponent is + the right one. Prevent an endless + loop. */ + abort (); + free (digits); + if (ndigits == precision) + exponent -= 1; + else + exponent += 1; + adjusted = 1; } - else + + /* Here ndigits = precision+1. */ + *p++ = digits[--ndigits]; + if ((flags & FLAG_ALT) || precision > 0) { - size_t count = -exponent - 1; - *p++ = '0'; *p++ = decimal_point_char (); - for (; count > 0; count--) - *p++ = '0'; - while (ndigits > nzeroes) + while (ndigits > 0) { --ndigits; *p++ = digits[ndigits]; } } + + free (digits); } - else + + *p++ = dp->conversion; /* 'e' or 'E' */ +# if WIDE_CHAR_VERSION + { + static const wchar_t decimal_format[] = + { '%', '+', '.', '2', 'd', '\0' }; + SNPRINTF (p, 6 + 1, decimal_format, exponent); + } +# else + sprintf (p, "%+.2d", exponent); +# endif + while (*p != '\0') + p++; + } + else if (dp->conversion == 'g' || dp->conversion == 'G') + { + if (precision == 0) + precision = 1; + /* precision >= 1. */ + + if (arg == 0.0L) + /* The exponent is 0, >= -4, < precision. + Use fixed-point notation. */ { - /* Exponential notation. */ - *p++ = digits[--ndigits]; + size_t ndigits = precision; + /* Number of trailing zeroes that have to be + dropped. */ + size_t nzeroes = + (flags & FLAG_ALT ? 0 : precision - 1); + + --ndigits; + *p++ = '0'; if ((flags & FLAG_ALT) || ndigits > nzeroes) { *p++ = decimal_point_char (); while (ndigits > nzeroes) { --ndigits; - *p++ = digits[ndigits]; + *p++ = '0'; } } - *p++ = dp->conversion - 'G' + 'E'; /* 'e' or 'E' */ -# if WIDE_CHAR_VERSION - { - static const wchar_t decimal_format[] = - { '%', '+', '.', '2', 'd', '\0' }; - SNPRINTF (p, 6 + 1, decimal_format, exponent); - } -# else - sprintf (p, "%+.2d", exponent); -# endif - while (*p != '\0') - p++; } + else + { + /* arg > 0.0L. */ + int exponent; + int adjusted; + char *digits; + size_t ndigits; + size_t nzeroes; + + exponent = floorlog10l (arg); + adjusted = 0; + for (;;) + { + digits = + scale10_round_decimal_long_double (arg, + (int)(precision - 1) - exponent); + if (digits == NULL) + { + END_LONG_DOUBLE_ROUNDING (); + goto out_of_memory; + } + ndigits = strlen (digits); + + if (ndigits == precision) + break; + if (ndigits < precision - 1 + || ndigits > precision + 1) + /* The exponent was not guessed + precisely enough. */ + abort (); + if (adjusted) + /* None of two values of exponent is + the right one. Prevent an endless + loop. */ + abort (); + free (digits); + if (ndigits < precision) + exponent -= 1; + else + exponent += 1; + adjusted = 1; + } + /* Here ndigits = precision. */ + + /* Determine the number of trailing zeroes + that have to be dropped. */ + nzeroes = 0; + if ((flags & FLAG_ALT) == 0) + while (nzeroes < ndigits + && digits[nzeroes] == '0') + nzeroes++; + + /* The exponent is now determined. */ + if (exponent >= -4 + && exponent < (long)precision) + { + /* Fixed-point notation: + max(exponent,0)+1 digits, then the + decimal point, then the remaining + digits without trailing zeroes. */ + if (exponent >= 0) + { + size_t count = exponent + 1; + /* Note: count <= precision = ndigits. */ + for (; count > 0; count--) + *p++ = digits[--ndigits]; + if ((flags & FLAG_ALT) || ndigits > nzeroes) + { + *p++ = decimal_point_char (); + while (ndigits > nzeroes) + { + --ndigits; + *p++ = digits[ndigits]; + } + } + } + else + { + size_t count = -exponent - 1; + *p++ = '0'; + *p++ = decimal_point_char (); + for (; count > 0; count--) + *p++ = '0'; + while (ndigits > nzeroes) + { + --ndigits; + *p++ = digits[ndigits]; + } + } + } + else + { + /* Exponential notation. */ + *p++ = digits[--ndigits]; + if ((flags & FLAG_ALT) || ndigits > nzeroes) + { + *p++ = decimal_point_char (); + while (ndigits > nzeroes) + { + --ndigits; + *p++ = digits[ndigits]; + } + } + *p++ = dp->conversion - 'G' + 'E'; /* 'e' or 'E' */ +# if WIDE_CHAR_VERSION + { + static const wchar_t decimal_format[] = + { '%', '+', '.', '2', 'd', '\0' }; + SNPRINTF (p, 6 + 1, decimal_format, exponent); + } +# else + sprintf (p, "%+.2d", exponent); +# endif + while (*p != '\0') + p++; + } - free (digits); + free (digits); + } } + else + abort (); + } + + END_LONG_DOUBLE_ROUNDING (); + } + } +# if NEED_PRINTF_INFINITE + else +# endif +# endif +# if NEED_PRINTF_INFINITE + { + /* Simpler than above: handle only NaN, Infinity, zero. */ + double arg = a.arg[dp->arg_index].a.a_double; + + if (isnan (arg)) + { + if (dp->conversion >= 'A' && dp->conversion <= 'Z') + { + *p++ = 'N'; *p++ = 'A'; *p++ = 'N'; } else - abort (); + { + *p++ = 'n'; *p++ = 'a'; *p++ = 'n'; + } } + else + { + int sign = 0; + + if (signbit (arg)) /* arg < 0.0L or negative zero */ + { + sign = -1; + arg = -arg; + } + + if (sign < 0) + *p++ = '-'; + else if (flags & FLAG_SHOWSIGN) + *p++ = '+'; + else if (flags & FLAG_SPACE) + *p++ = ' '; + + if (arg > 0.0 && arg + arg == arg) + { + if (dp->conversion >= 'A' && dp->conversion <= 'Z') + { + *p++ = 'I'; *p++ = 'N'; *p++ = 'F'; + } + else + { + *p++ = 'i'; *p++ = 'n'; *p++ = 'f'; + } + } + else + { + if (!(arg == 0.0)) + abort (); - END_LONG_DOUBLE_ROUNDING (); + 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 /* The generated string now extends from tmp to p, with the zero padding insertion point being at pad_ptr. */ diff --git a/m4/fprintf-posix.m4 b/m4/fprintf-posix.m4 index fe5c7cdde..9242684f1 100644 --- a/m4/fprintf-posix.m4 +++ b/m4/fprintf-posix.m4 @@ -1,4 +1,4 @@ -# fprintf-posix.m4 serial 6 +# fprintf-posix.m4 serial 7 dnl Copyright (C) 2007 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -8,6 +8,7 @@ AC_DEFUN([gl_FUNC_FPRINTF_POSIX], [ AC_REQUIRE([gl_EOVERFLOW]) AC_REQUIRE([gl_PRINTF_SIZES_C99]) + AC_REQUIRE([gl_PRINTF_INFINITE]) AC_REQUIRE([gl_PRINTF_LONG_DOUBLE]) AC_REQUIRE([gl_PRINTF_DIRECTIVE_A]) AC_REQUIRE([gl_PRINTF_DIRECTIVE_F]) @@ -18,23 +19,27 @@ AC_DEFUN([gl_FUNC_FPRINTF_POSIX], gl_cv_func_fprintf_posix=no case "$gl_cv_func_printf_sizes_c99" in *yes) - case "$gl_cv_func_printf_long_double" in + case "$gl_cv_func_printf_infinite" in *yes) - case "$gl_cv_func_printf_directive_a" in + case "$gl_cv_func_printf_long_double" in *yes) - case "$gl_cv_func_printf_directive_f" in + case "$gl_cv_func_printf_directive_a" in *yes) - case "$gl_cv_func_printf_directive_n" in + case "$gl_cv_func_printf_directive_f" in *yes) - case "$gl_cv_func_printf_positions" in + case "$gl_cv_func_printf_directive_n" in *yes) - case "$gl_cv_func_printf_flag_grouping" in + case "$gl_cv_func_printf_positions" in *yes) - case "$gl_cv_func_printf_flag_zero" in + case "$gl_cv_func_printf_flag_grouping" in *yes) - # fprintf exists and is already POSIX - # compliant. - gl_cv_func_fprintf_posix=yes + case "$gl_cv_func_printf_flag_zero" in + *yes) + # fprintf exists and is already POSIX + # compliant. + gl_cv_func_fprintf_posix=yes + ;; + esac ;; esac ;; @@ -52,6 +57,7 @@ AC_DEFUN([gl_FUNC_FPRINTF_POSIX], ;; esac if test $gl_cv_func_fprintf_posix = no; then + gl_PREREQ_VASNPRINTF_INFINITE gl_PREREQ_VASNPRINTF_LONG_DOUBLE gl_PREREQ_VASNPRINTF_DIRECTIVE_A gl_PREREQ_VASNPRINTF_DIRECTIVE_F diff --git a/m4/printf.m4 b/m4/printf.m4 index 32325bf06..25889f954 100644 --- a/m4/printf.m4 +++ b/m4/printf.m4 @@ -1,4 +1,4 @@ -# printf.m4 serial 10 +# printf.m4 serial 11 dnl Copyright (C) 2003, 2007 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -81,6 +81,54 @@ changequote([,])dnl ]) ]) +dnl Test whether the *printf family of functions supports infinite 'double' +dnl arguments in the %f, %e, %g directives. (ISO C99, POSIX:2001) +dnl Result is gl_cv_func_printf_infinite. + +AC_DEFUN([gl_PRINTF_INFINITE], +[ + AC_REQUIRE([AC_PROG_CC]) + AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles + AC_CACHE_CHECK([whether printf supports infinite 'double' arguments], + [gl_cv_func_printf_infinite], + [ + AC_TRY_RUN([ +#include +#include +static char buf[100]; +int main () +{ + if (sprintf (buf, "%f", 1.0 / 0.0) < 0 + || (strcmp (buf, "inf") != 0 && strcmp (buf, "infinity") != 0)) + return 1; + if (sprintf (buf, "%f", -1.0 / 0.0) < 0 + || (strcmp (buf, "-inf") != 0 && strcmp (buf, "-infinity") != 0)) + return 1; + if (sprintf (buf, "%e", 1.0 / 0.0) < 0 + || (strcmp (buf, "inf") != 0 && strcmp (buf, "infinity") != 0)) + return 1; + if (sprintf (buf, "%e", -1.0 / 0.0) < 0 + || (strcmp (buf, "-inf") != 0 && strcmp (buf, "-infinity") != 0)) + return 1; + if (sprintf (buf, "%g", 1.0 / 0.0) < 0 + || (strcmp (buf, "inf") != 0 && strcmp (buf, "infinity") != 0)) + return 1; + if (sprintf (buf, "%g", -1.0 / 0.0) < 0 + || (strcmp (buf, "-inf") != 0 && strcmp (buf, "-infinity") != 0)) + return 1; + return 0; +}], [gl_cv_func_printf_infinite=yes], [gl_cv_func_printf_infinite=no], + [ +changequote(,)dnl + case "$host_os" in + mingw* | pw*) gl_cv_func_printf_infinite="guessing no";; + *) gl_cv_func_printf_infinite="guessing yes";; + esac +changequote([,])dnl + ]) + ]) +]) + dnl Test whether the *printf family of functions supports 'long double' dnl arguments together with the 'L' size specifier. (ISO C99, POSIX:2001) dnl Result is gl_cv_func_printf_long_double. @@ -705,54 +753,56 @@ changequote([,])dnl dnl The results of these tests on various platforms are: dnl dnl 1 = gl_PRINTF_SIZES_C99 -dnl 2 = gl_PRINTF_LONG_DOUBLE -dnl 3 = gl_PRINTF_DIRECTIVE_A -dnl 4 = gl_PRINTF_DIRECTIVE_F -dnl 5 = gl_PRINTF_DIRECTIVE_N -dnl 6 = gl_PRINTF_POSITIONS -dnl 7 = gl_PRINTF_FLAG_GROUPING -dnl 8 = gl_PRINTF_FLAG_ZERO -dnl 9 = gl_SNPRINTF_PRESENCE -dnl 10 = gl_SNPRINTF_TRUNCATION_C99 -dnl 11 = gl_SNPRINTF_RETVAL_C99 -dnl 12 = gl_SNPRINTF_DIRECTIVE_N -dnl 13 = gl_VSNPRINTF_ZEROSIZE_C99 +dnl 2 = gl_PRINTF_INFINITE +dnl 3 = gl_PRINTF_LONG_DOUBLE +dnl 4 = gl_PRINTF_DIRECTIVE_A +dnl 5 = gl_PRINTF_DIRECTIVE_F +dnl 6 = gl_PRINTF_DIRECTIVE_N +dnl 7 = gl_PRINTF_POSITIONS +dnl 8 = gl_PRINTF_FLAG_GROUPING +dnl 9 = gl_PRINTF_FLAG_ZERO +dnl 10 = gl_SNPRINTF_PRESENCE +dnl 11 = gl_SNPRINTF_TRUNCATION_C99 +dnl 12 = gl_SNPRINTF_RETVAL_C99 +dnl 13 = gl_SNPRINTF_DIRECTIVE_N +dnl 14 = gl_VSNPRINTF_ZEROSIZE_C99 dnl dnl 1 = checking whether printf supports size specifiers as in C99... -dnl 2 = checking whether printf supports 'long double' arguments... -dnl 3 = checking whether printf supports the 'a' and 'A' directives... -dnl 4 = checking whether printf supports the 'F' directive... -dnl 5 = checking whether printf supports the 'n' directive... -dnl 6 = checking whether printf supports POSIX/XSI format strings with positions... -dnl 7 = checking whether printf supports the grouping flag... -dnl 8 = checking whether printf supports the zero flag correctly... -dnl 9 = checking for snprintf... -dnl 10 = checking whether snprintf truncates the result as in C99... -dnl 11 = checking whether snprintf returns a byte count as in C99... -dnl 12 = checking whether snprintf fully supports the 'n' directive... -dnl 13 = checking whether vsnprintf respects a zero size as in C99... +dnl 2 = checking whether printf supports infinite 'double' arguments... +dnl 3 = checking whether printf supports 'long double' arguments... +dnl 4 = checking whether printf supports the 'a' and 'A' directives... +dnl 5 = checking whether printf supports the 'F' directive... +dnl 6 = checking whether printf supports the 'n' directive... +dnl 7 = checking whether printf supports POSIX/XSI format strings with positions... +dnl 8 = checking whether printf supports the grouping flag... +dnl 9 = checking whether printf supports the zero flag correctly... +dnl 10 = checking for snprintf... +dnl 11 = checking whether snprintf truncates the result as in C99... +dnl 12 = checking whether snprintf returns a byte count as in C99... +dnl 13 = checking whether snprintf fully supports the 'n' directive... +dnl 14 = checking whether vsnprintf respects a zero size as in C99... dnl dnl . = yes, # = no. dnl -dnl 1 2 3 4 5 6 7 8 9 10 11 12 13 -dnl glibc 2.5 . . . . . . . . . . . . . -dnl glibc 2.3.6 . . # . . . . . . . . . . -dnl FreeBSD 5.4, 6.1 . ? ? . . . . # . . . . . -dnl MacOS X 10.3.9 . . # . . . . # . . . . . -dnl OpenBSD 3.9, 4.0 . ? # ? . . ? ? . . . ? ? -dnl Cygwin 2007 (= Cygwin 1.5.24) . ? # # . . . # . . . . . -dnl Cygwin 2006 (= Cygwin 1.5.19) # ? # # . . # # . . . . . -dnl Solaris 10 . . # . . . . # . . . . . -dnl Solaris 2.6 ... 9 # . # # . . . # . . . . . -dnl Solaris 2.5.1 # . # # . . . # # # # # # -dnl AIX 5.2 . . # . . . . # . . . . . -dnl AIX 4.3.2, 5.1 # . # # . . . # . . . . . -dnl HP-UX 11.31 . . # . . . . # . . # # . -dnl HP-UX 10.20, 11.00, 11.11, 11.23 # . # # . . . # . . # # # -dnl IRIX 6.5 # . # # . . . # . . # . . -dnl OSF/1 5.1 # . # # . . . # . . # . # -dnl OSF/1 4.0d # . # # . . . # # # # # # -dnl NetBSD 4.0 . ? ? ? . . ? ? . . . ? ? -dnl NetBSD 3.0 . ? # # . # # # . . . . . -dnl BeOS # # # # . # . . . . . . . -dnl mingw # # # # . # # # . # # # . +dnl 1 2 3 4 5 6 7 8 9 10 11 12 13 14 +dnl glibc 2.5 . . . . . . . . . . . . . . +dnl glibc 2.3.6 . . . # . . . . . . . . . . +dnl FreeBSD 5.4, 6.1 . . ? ? . . . . # . . . . . +dnl MacOS X 10.3.9 . . . # . . . . # . . . . . +dnl OpenBSD 3.9, 4.0 . ? ? # ? . . ? ? . . . ? ? +dnl Cygwin 2007 (= Cygwin 1.5.24) . ? ? # # . . . # . . . . . +dnl Cygwin 2006 (= Cygwin 1.5.19) # ? ? # # . . # # . . . . . +dnl Solaris 10 . ? . # . . . . # . . . . . +dnl Solaris 2.6 ... 9 # ? . # # . . . # . . . . . +dnl Solaris 2.5.1 # ? . # # . . . # # # # # # +dnl AIX 5.2 . ? . # . . . . # . . . . . +dnl AIX 4.3.2, 5.1 # ? . # # . . . # . . . . . +dnl HP-UX 11.31 . . . # . . . . # . . # # . +dnl HP-UX 10.20, 11.{00,11,23} # . . # # . . . # . . # # # +dnl IRIX 6.5 # ? . # # . . . # . . # . . +dnl OSF/1 5.1 # ? . # # . . . # . . # . # +dnl OSF/1 4.0d # ? . # # . . . # # # # # # +dnl NetBSD 4.0 . ? ? ? ? . . ? ? . . . ? ? +dnl NetBSD 3.0 . ? ? # # . # # # . . . . . +dnl BeOS # ? # # # . # . . . . . . . +dnl mingw # # # # # . # # # . # # # . diff --git a/m4/snprintf-posix.m4 b/m4/snprintf-posix.m4 index b3d9439fe..99f11ecd4 100644 --- a/m4/snprintf-posix.m4 +++ b/m4/snprintf-posix.m4 @@ -1,4 +1,4 @@ -# snprintf-posix.m4 serial 7 +# snprintf-posix.m4 serial 8 dnl Copyright (C) 2007 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -8,6 +8,7 @@ AC_DEFUN([gl_FUNC_SNPRINTF_POSIX], [ AC_REQUIRE([gl_EOVERFLOW]) AC_REQUIRE([gl_PRINTF_SIZES_C99]) + AC_REQUIRE([gl_PRINTF_INFINITE]) AC_REQUIRE([gl_PRINTF_LONG_DOUBLE]) AC_REQUIRE([gl_PRINTF_DIRECTIVE_A]) AC_REQUIRE([gl_PRINTF_DIRECTIVE_F]) @@ -24,31 +25,35 @@ AC_DEFUN([gl_FUNC_SNPRINTF_POSIX], gl_VSNPRINTF_ZEROSIZE_C99 case "$gl_cv_func_printf_sizes_c99" in *yes) - case "$gl_cv_func_printf_long_double" in + case "$gl_cv_func_printf_infinite" in *yes) - case "$gl_cv_func_printf_directive_a" in + case "$gl_cv_func_printf_long_double" in *yes) - case "$gl_cv_func_printf_directive_f" in + case "$gl_cv_func_printf_directive_a" in *yes) - case "$gl_cv_func_printf_directive_n" in + case "$gl_cv_func_printf_directive_f" in *yes) - case "$gl_cv_func_printf_positions" in + case "$gl_cv_func_printf_directive_n" in *yes) - case "$gl_cv_func_printf_flag_grouping" in + case "$gl_cv_func_printf_positions" in *yes) - case "$gl_cv_func_printf_flag_zero" in + case "$gl_cv_func_printf_flag_grouping" in *yes) - case "$gl_cv_func_snprintf_truncation_c99" in + case "$gl_cv_func_printf_flag_zero" in *yes) - case "$gl_cv_func_snprintf_retval_c99" in + case "$gl_cv_func_snprintf_truncation_c99" in *yes) - case "$gl_cv_func_snprintf_directive_n" in + case "$gl_cv_func_snprintf_retval_c99" in *yes) - case "$gl_cv_func_vsnprintf_zerosize_c99" in + case "$gl_cv_func_snprintf_directive_n" in *yes) - # snprintf exists and is - # already POSIX compliant. - gl_cv_func_snprintf_posix=yes + case "$gl_cv_func_vsnprintf_zerosize_c99" in + *yes) + # snprintf exists and is + # already POSIX compliant. + gl_cv_func_snprintf_posix=yes + ;; + esac ;; esac ;; @@ -75,6 +80,7 @@ AC_DEFUN([gl_FUNC_SNPRINTF_POSIX], esac fi if test $gl_cv_func_snprintf_posix = no; then + gl_PREREQ_VASNPRINTF_INFINITE gl_PREREQ_VASNPRINTF_LONG_DOUBLE gl_PREREQ_VASNPRINTF_DIRECTIVE_A gl_PREREQ_VASNPRINTF_DIRECTIVE_F diff --git a/m4/sprintf-posix.m4 b/m4/sprintf-posix.m4 index 918758f57..7d844d340 100644 --- a/m4/sprintf-posix.m4 +++ b/m4/sprintf-posix.m4 @@ -1,4 +1,4 @@ -# sprintf-posix.m4 serial 6 +# sprintf-posix.m4 serial 7 dnl Copyright (C) 2007 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -8,6 +8,7 @@ AC_DEFUN([gl_FUNC_SPRINTF_POSIX], [ AC_REQUIRE([gl_EOVERFLOW]) AC_REQUIRE([gl_PRINTF_SIZES_C99]) + AC_REQUIRE([gl_PRINTF_INFINITE]) AC_REQUIRE([gl_PRINTF_LONG_DOUBLE]) AC_REQUIRE([gl_PRINTF_DIRECTIVE_A]) AC_REQUIRE([gl_PRINTF_DIRECTIVE_F]) @@ -18,23 +19,27 @@ AC_DEFUN([gl_FUNC_SPRINTF_POSIX], gl_cv_func_sprintf_posix=no case "$gl_cv_func_printf_sizes_c99" in *yes) - case "$gl_cv_func_printf_long_double" in + case "$gl_cv_func_printf_infinite" in *yes) - case "$gl_cv_func_printf_directive_a" in + case "$gl_cv_func_printf_long_double" in *yes) - case "$gl_cv_func_printf_directive_f" in + case "$gl_cv_func_printf_directive_a" in *yes) - case "$gl_cv_func_printf_directive_n" in + case "$gl_cv_func_printf_directive_f" in *yes) - case "$gl_cv_func_printf_positions" in + case "$gl_cv_func_printf_directive_n" in *yes) - case "$gl_cv_func_printf_flag_grouping" in + case "$gl_cv_func_printf_positions" in *yes) - case "$gl_cv_func_printf_flag_zero" in + case "$gl_cv_func_printf_flag_grouping" in *yes) - # sprintf exists and is already POSIX - # compliant. - gl_cv_func_sprintf_posix=yes + case "$gl_cv_func_printf_flag_zero" in + *yes) + # sprintf exists and is already POSIX + # compliant. + gl_cv_func_sprintf_posix=yes + ;; + esac ;; esac ;; @@ -52,6 +57,7 @@ AC_DEFUN([gl_FUNC_SPRINTF_POSIX], ;; esac if test $gl_cv_func_sprintf_posix = no; then + gl_PREREQ_VASNPRINTF_INFINITE gl_PREREQ_VASNPRINTF_LONG_DOUBLE gl_PREREQ_VASNPRINTF_DIRECTIVE_A gl_PREREQ_VASNPRINTF_DIRECTIVE_F diff --git a/m4/vasnprintf-posix.m4 b/m4/vasnprintf-posix.m4 index 0a9e4a833..ac56fe352 100644 --- a/m4/vasnprintf-posix.m4 +++ b/m4/vasnprintf-posix.m4 @@ -1,4 +1,4 @@ -# vasnprintf-posix.m4 serial 7 +# vasnprintf-posix.m4 serial 8 dnl Copyright (C) 2007 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -8,6 +8,7 @@ AC_DEFUN([gl_FUNC_VASNPRINTF_POSIX], [ AC_REQUIRE([gl_EOVERFLOW]) AC_REQUIRE([gl_PRINTF_SIZES_C99]) + AC_REQUIRE([gl_PRINTF_INFINITE]) AC_REQUIRE([gl_PRINTF_LONG_DOUBLE]) AC_REQUIRE([gl_PRINTF_DIRECTIVE_A]) AC_REQUIRE([gl_PRINTF_DIRECTIVE_F]) @@ -19,25 +20,29 @@ AC_DEFUN([gl_FUNC_VASNPRINTF_POSIX], AC_CHECK_FUNCS_ONCE([vasnprintf]) case "$gl_cv_func_printf_sizes_c99" in *yes) - case "$gl_cv_func_printf_long_double" in + case "$gl_cv_func_printf_infinite" in *yes) - case "$gl_cv_func_printf_directive_a" in + case "$gl_cv_func_printf_long_double" in *yes) - case "$gl_cv_func_printf_directive_f" in + case "$gl_cv_func_printf_directive_a" in *yes) - case "$gl_cv_func_printf_directive_n" in + case "$gl_cv_func_printf_directive_f" in *yes) - case "$gl_cv_func_printf_positions" in + case "$gl_cv_func_printf_directive_n" in *yes) - case "$gl_cv_func_printf_flag_grouping" in + case "$gl_cv_func_printf_positions" in *yes) - case "$gl_cv_func_printf_flag_zero" in + case "$gl_cv_func_printf_flag_grouping" in *yes) - if test $ac_cv_func_vasnprintf = yes; then - # vasnprintf exists and is already POSIX - # compliant. - gl_cv_func_vasnprintf_posix=yes - fi + case "$gl_cv_func_printf_flag_zero" in + *yes) + if test $ac_cv_func_vasnprintf = yes; then + # vasnprintf exists and is already POSIX + # compliant. + gl_cv_func_vasnprintf_posix=yes + fi + ;; + esac ;; esac ;; @@ -55,6 +60,7 @@ AC_DEFUN([gl_FUNC_VASNPRINTF_POSIX], ;; esac if test $gl_cv_func_vasnprintf_posix = no; then + gl_PREREQ_VASNPRINTF_INFINITE gl_PREREQ_VASNPRINTF_LONG_DOUBLE gl_PREREQ_VASNPRINTF_DIRECTIVE_A gl_PREREQ_VASNPRINTF_DIRECTIVE_F diff --git a/m4/vasnprintf.m4 b/m4/vasnprintf.m4 index be1506544..ecbb28175 100644 --- a/m4/vasnprintf.m4 +++ b/m4/vasnprintf.m4 @@ -1,4 +1,4 @@ -# vasnprintf.m4 serial 16 +# vasnprintf.m4 serial 17 dnl Copyright (C) 2002-2004, 2006-2007 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -59,6 +59,22 @@ AC_DEFUN([gl_PREREQ_VASNPRINTF], AC_CHECK_FUNCS(snprintf wcslen) ]) +# Extra prerequisites of lib/vasnprintf.c for supporting infinite 'double' +# arguments. +AC_DEFUN([gl_PREREQ_VASNPRINTF_INFINITE], +[ + AC_REQUIRE([gl_PRINTF_INFINITE]) + case "$gl_cv_func_printf_infinite" in + *yes) + ;; + *) + AC_DEFINE([NEED_PRINTF_INFINITE], 1, + [Define if the vasnprintf implementation needs special code for + infinite 'double' arguments.]) + ;; + esac +]) + # Extra prerequisites of lib/vasnprintf.c for supporting 'long double' # arguments. AC_DEFUN([gl_PREREQ_VASNPRINTF_LONG_DOUBLE], diff --git a/m4/vasprintf-posix.m4 b/m4/vasprintf-posix.m4 index 8da4023a6..279e0def4 100644 --- a/m4/vasprintf-posix.m4 +++ b/m4/vasprintf-posix.m4 @@ -1,4 +1,4 @@ -# vasprintf-posix.m4 serial 7 +# vasprintf-posix.m4 serial 8 dnl Copyright (C) 2007 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -8,6 +8,7 @@ AC_DEFUN([gl_FUNC_VASPRINTF_POSIX], [ AC_REQUIRE([gl_EOVERFLOW]) AC_REQUIRE([gl_PRINTF_SIZES_C99]) + AC_REQUIRE([gl_PRINTF_INFINITE]) AC_REQUIRE([gl_PRINTF_LONG_DOUBLE]) AC_REQUIRE([gl_PRINTF_DIRECTIVE_A]) AC_REQUIRE([gl_PRINTF_DIRECTIVE_F]) @@ -19,25 +20,29 @@ AC_DEFUN([gl_FUNC_VASPRINTF_POSIX], AC_CHECK_FUNCS([vasprintf]) case "$gl_cv_func_printf_sizes_c99" in *yes) - case "$gl_cv_func_printf_long_double" in + case "$gl_cv_func_printf_infinite" in *yes) - case "$gl_cv_func_printf_directive_a" in + case "$gl_cv_func_printf_long_double" in *yes) - case "$gl_cv_func_printf_directive_f" in + case "$gl_cv_func_printf_directive_a" in *yes) - case "$gl_cv_func_printf_directive_n" in + case "$gl_cv_func_printf_directive_f" in *yes) - case "$gl_cv_func_printf_positions" in + case "$gl_cv_func_printf_directive_n" in *yes) - case "$gl_cv_func_printf_flag_grouping" in + case "$gl_cv_func_printf_positions" in *yes) - case "$gl_cv_func_printf_flag_zero" in + case "$gl_cv_func_printf_flag_grouping" in *yes) - if test $ac_cv_func_vasprintf = yes; then - # vasprintf exists and is already POSIX - # compliant. - gl_cv_func_vasprintf_posix=yes - fi + case "$gl_cv_func_printf_flag_zero" in + *yes) + if test $ac_cv_func_vasprintf = yes; then + # vasprintf exists and is already POSIX + # compliant. + gl_cv_func_vasprintf_posix=yes + fi + ;; + esac ;; esac ;; @@ -55,6 +60,7 @@ AC_DEFUN([gl_FUNC_VASPRINTF_POSIX], ;; esac if test $gl_cv_func_vasprintf_posix = no; then + gl_PREREQ_VASNPRINTF_INFINITE gl_PREREQ_VASNPRINTF_LONG_DOUBLE gl_PREREQ_VASNPRINTF_DIRECTIVE_A gl_PREREQ_VASNPRINTF_DIRECTIVE_F diff --git a/m4/vfprintf-posix.m4 b/m4/vfprintf-posix.m4 index fc8b62405..bf936f14e 100644 --- a/m4/vfprintf-posix.m4 +++ b/m4/vfprintf-posix.m4 @@ -1,4 +1,4 @@ -# vfprintf-posix.m4 serial 6 +# vfprintf-posix.m4 serial 7 dnl Copyright (C) 2007 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -8,6 +8,7 @@ AC_DEFUN([gl_FUNC_VFPRINTF_POSIX], [ AC_REQUIRE([gl_EOVERFLOW]) AC_REQUIRE([gl_PRINTF_SIZES_C99]) + AC_REQUIRE([gl_PRINTF_INFINITE]) AC_REQUIRE([gl_PRINTF_LONG_DOUBLE]) AC_REQUIRE([gl_PRINTF_DIRECTIVE_A]) AC_REQUIRE([gl_PRINTF_DIRECTIVE_F]) @@ -18,23 +19,27 @@ AC_DEFUN([gl_FUNC_VFPRINTF_POSIX], gl_cv_func_vfprintf_posix=no case "$gl_cv_func_printf_sizes_c99" in *yes) - case "$gl_cv_func_printf_long_double" in + case "$gl_cv_func_printf_infinite" in *yes) - case "$gl_cv_func_printf_directive_a" in + case "$gl_cv_func_printf_long_double" in *yes) - case "$gl_cv_func_printf_directive_f" in + case "$gl_cv_func_printf_directive_a" in *yes) - case "$gl_cv_func_printf_directive_n" in + case "$gl_cv_func_printf_directive_f" in *yes) - case "$gl_cv_func_printf_positions" in + case "$gl_cv_func_printf_directive_n" in *yes) - case "$gl_cv_func_printf_flag_grouping" in + case "$gl_cv_func_printf_positions" in *yes) - case "$gl_cv_func_printf_flag_zero" in + case "$gl_cv_func_printf_flag_grouping" in *yes) - # vfprintf exists and is already POSIX - # compliant. - gl_cv_func_vfprintf_posix=yes + case "$gl_cv_func_printf_flag_zero" in + *yes) + # vfprintf exists and is already POSIX + # compliant. + gl_cv_func_vfprintf_posix=yes + ;; + esac ;; esac ;; @@ -52,6 +57,7 @@ AC_DEFUN([gl_FUNC_VFPRINTF_POSIX], ;; esac if test $gl_cv_func_vfprintf_posix = no; then + gl_PREREQ_VASNPRINTF_INFINITE gl_PREREQ_VASNPRINTF_LONG_DOUBLE gl_PREREQ_VASNPRINTF_DIRECTIVE_A gl_PREREQ_VASNPRINTF_DIRECTIVE_F diff --git a/m4/vsnprintf-posix.m4 b/m4/vsnprintf-posix.m4 index bce47b74e..29189863b 100644 --- a/m4/vsnprintf-posix.m4 +++ b/m4/vsnprintf-posix.m4 @@ -1,4 +1,4 @@ -# vsnprintf-posix.m4 serial 7 +# vsnprintf-posix.m4 serial 8 dnl Copyright (C) 2007 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -8,6 +8,7 @@ AC_DEFUN([gl_FUNC_VSNPRINTF_POSIX], [ AC_REQUIRE([gl_EOVERFLOW]) AC_REQUIRE([gl_PRINTF_SIZES_C99]) + AC_REQUIRE([gl_PRINTF_INFINITE]) AC_REQUIRE([gl_PRINTF_LONG_DOUBLE]) AC_REQUIRE([gl_PRINTF_DIRECTIVE_A]) AC_REQUIRE([gl_PRINTF_DIRECTIVE_F]) @@ -25,31 +26,35 @@ AC_DEFUN([gl_FUNC_VSNPRINTF_POSIX], gl_VSNPRINTF_ZEROSIZE_C99 case "$gl_cv_func_printf_sizes_c99" in *yes) - case "$gl_cv_func_printf_long_double" in + case "$gl_cv_func_printf_infinite" in *yes) - case "$gl_cv_func_printf_directive_a" in + case "$gl_cv_func_printf_long_double" in *yes) - case "$gl_cv_func_printf_directive_f" in + case "$gl_cv_func_printf_directive_a" in *yes) - case "$gl_cv_func_printf_directive_n" in + case "$gl_cv_func_printf_directive_f" in *yes) - case "$gl_cv_func_printf_positions" in + case "$gl_cv_func_printf_directive_n" in *yes) - case "$gl_cv_func_printf_flag_grouping" in + case "$gl_cv_func_printf_positions" in *yes) - case "$gl_cv_func_printf_flag_zero" in + case "$gl_cv_func_printf_flag_grouping" in *yes) - case "$gl_cv_func_snprintf_truncation_c99" in + case "$gl_cv_func_printf_flag_zero" in *yes) - case "$gl_cv_func_snprintf_retval_c99" in + case "$gl_cv_func_snprintf_truncation_c99" in *yes) - case "$gl_cv_func_snprintf_directive_n" in + case "$gl_cv_func_snprintf_retval_c99" in *yes) - case "$gl_cv_func_vsnprintf_zerosize_c99" in + case "$gl_cv_func_snprintf_directive_n" in *yes) - # vsnprintf exists and is - # already POSIX compliant. - gl_cv_func_vsnprintf_posix=yes + case "$gl_cv_func_vsnprintf_zerosize_c99" in + *yes) + # vsnprintf exists and is + # already POSIX compliant. + gl_cv_func_vsnprintf_posix=yes + ;; + esac ;; esac ;; @@ -76,6 +81,7 @@ AC_DEFUN([gl_FUNC_VSNPRINTF_POSIX], esac fi if test $gl_cv_func_vsnprintf_posix = no; then + gl_PREREQ_VASNPRINTF_INFINITE gl_PREREQ_VASNPRINTF_LONG_DOUBLE gl_PREREQ_VASNPRINTF_DIRECTIVE_A gl_PREREQ_VASNPRINTF_DIRECTIVE_F diff --git a/m4/vsprintf-posix.m4 b/m4/vsprintf-posix.m4 index 62c864615..de4466163 100644 --- a/m4/vsprintf-posix.m4 +++ b/m4/vsprintf-posix.m4 @@ -1,4 +1,4 @@ -# vsprintf-posix.m4 serial 6 +# vsprintf-posix.m4 serial 7 dnl Copyright (C) 2007 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -8,6 +8,7 @@ AC_DEFUN([gl_FUNC_VSPRINTF_POSIX], [ AC_REQUIRE([gl_EOVERFLOW]) AC_REQUIRE([gl_PRINTF_SIZES_C99]) + AC_REQUIRE([gl_PRINTF_INFINITE]) AC_REQUIRE([gl_PRINTF_LONG_DOUBLE]) AC_REQUIRE([gl_PRINTF_DIRECTIVE_A]) AC_REQUIRE([gl_PRINTF_DIRECTIVE_F]) @@ -18,23 +19,27 @@ AC_DEFUN([gl_FUNC_VSPRINTF_POSIX], gl_cv_func_vsprintf_posix=no case "$gl_cv_func_printf_sizes_c99" in *yes) - case "$gl_cv_func_printf_long_double" in + case "$gl_cv_func_printf_infinite" in *yes) - case "$gl_cv_func_printf_directive_a" in + case "$gl_cv_func_printf_long_double" in *yes) - case "$gl_cv_func_printf_directive_f" in + case "$gl_cv_func_printf_directive_a" in *yes) - case "$gl_cv_func_printf_directive_n" in + case "$gl_cv_func_printf_directive_f" in *yes) - case "$gl_cv_func_printf_positions" in + case "$gl_cv_func_printf_directive_n" in *yes) - case "$gl_cv_func_printf_flag_grouping" in + case "$gl_cv_func_printf_positions" in *yes) - case "$gl_cv_func_printf_flag_zero" in + case "$gl_cv_func_printf_flag_grouping" in *yes) - # vsprintf exists and is already POSIX - # compliant. - gl_cv_func_vsprintf_posix=yes + case "$gl_cv_func_printf_flag_zero" in + *yes) + # vsprintf exists and is already POSIX + # compliant. + gl_cv_func_vsprintf_posix=yes + ;; + esac ;; esac ;; @@ -52,6 +57,7 @@ AC_DEFUN([gl_FUNC_VSPRINTF_POSIX], ;; esac if test $gl_cv_func_vsprintf_posix = no; then + gl_PREREQ_VASNPRINTF_INFINITE gl_PREREQ_VASNPRINTF_LONG_DOUBLE gl_PREREQ_VASNPRINTF_DIRECTIVE_A gl_PREREQ_VASNPRINTF_DIRECTIVE_F -- 2.11.0