From 474d4b34c610ef1d888457d4ee6130add2bba3c2 Mon Sep 17 00:00:00 2001 From: Bruno Haible Date: Sun, 4 Nov 2007 17:19:42 +0100 Subject: [PATCH] Fix *printf behaviour for large precisions on mingw and BeOS. --- ChangeLog | 26 ++++++ 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 | 186 +++++++++++++++++++++++++++++++++---------- m4/fprintf-posix.m4 | 16 ++-- m4/printf.m4 | 112 ++++++++++++++++++-------- m4/snprintf-posix.m4 | 24 +++--- m4/sprintf-posix.m4 | 16 ++-- m4/vasnprintf-posix.m4 | 20 +++-- m4/vasnprintf.m4 | 24 +++++- m4/vasprintf-posix.m4 | 20 +++-- m4/vfprintf-posix.m4 | 16 ++-- m4/vsnprintf-posix.m4 | 24 +++--- m4/vsprintf-posix.m4 | 16 ++-- 20 files changed, 400 insertions(+), 132 deletions(-) diff --git a/ChangeLog b/ChangeLog index 34465ea50..848ef0f94 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,31 @@ 2007-11-04 Bruno Haible + Fix *printf behaviour for large precisions on mingw and BeOS. + * m4/printf.m4 (gl_PRINTF_PRECISION): New macro. + * lib/vasnprintf.c (VASNPRINTF): Handle NEED_PRINTF_UNBOUNDED_PRECISION. + * m4/vasnprintf.m4 (gl_PREREQ_VASNPRINTF_PRECISION): New macro. + (gl_PREREQ_VASNPRINTF_WITH_EXTRAS): Invoke it. + * m4/fprintf-posix.m4 (gl_FUNC_FPRINTF_POSIX): Invoke + gl_PRINTF_PRECISION and test its result. Invoke + gl_PREREQ_VASNPRINTF_PRECISION. + * 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-11-04 Bruno Haible + * lib/vasnprintf.c (scale10_round_decimal_decoded): Fix shift loop. 2007-11-04 Bruno Haible diff --git a/doc/functions/fprintf.texi b/doc/functions/fprintf.texi index 5c76d3d87..2b04fd467 100644 --- a/doc/functions/fprintf.texi +++ b/doc/functions/fprintf.texi @@ -38,6 +38,10 @@ printf @code{"%010f"} of NaN and Infinity yields an incorrect result (padded with zeroes) on some platforms: MacOS X 10.3, FreeBSD 6.0, NetBSD 3.0, AIX 5.2, IRIX 6.5, OSF/1 5.1, Solaris 10, Cygwin 2007, mingw. @item +This function does not support precisions larger than 512 or 1024 in integer, +floating-point and pointer output on some platforms: +mingw, BeOS. +@item This function can crash in out-of-memory conditions on some platforms: MacOS X 10.3, FreeBSD 6.0, NetBSD 3.0. @end itemize diff --git a/doc/functions/printf.texi b/doc/functions/printf.texi index dc49ed544..6ce2c04c2 100644 --- a/doc/functions/printf.texi +++ b/doc/functions/printf.texi @@ -38,6 +38,10 @@ printf @code{"%010f"} of NaN and Infinity yields an incorrect result (padded with zeroes) on some platforms: MacOS X 10.3, FreeBSD 6.0, NetBSD 3.0, AIX 5.2, IRIX 6.5, OSF/1 5.1, Solaris 10, Cygwin 2007, mingw. @item +This function does not support precisions larger than 512 or 1024 in integer, +floating-point and pointer output on some platforms: +mingw, BeOS. +@item This function can crash in out-of-memory conditions on some platforms: MacOS X 10.3, FreeBSD 6.0, NetBSD 3.0. @end itemize diff --git a/doc/functions/snprintf.texi b/doc/functions/snprintf.texi index a2a81bcff..7e5f2f8ac 100644 --- a/doc/functions/snprintf.texi +++ b/doc/functions/snprintf.texi @@ -45,6 +45,10 @@ printf @code{"%010f"} of NaN and Infinity yields an incorrect result (padded with zeroes) on some platforms: MacOS X 10.3, FreeBSD 6.0, NetBSD 3.0, AIX 5.2, IRIX 6.5, OSF/1 5.1, Solaris 10, Cygwin 2007, mingw. @item +This function does not support precisions larger than 512 or 1024 in integer, +floating-point and pointer output on some platforms: +mingw, BeOS. +@item This function can crash in out-of-memory conditions on some platforms: MacOS X 10.3, FreeBSD 6.0, NetBSD 3.0. @item diff --git a/doc/functions/sprintf.texi b/doc/functions/sprintf.texi index 458a36f8a..405110d77 100644 --- a/doc/functions/sprintf.texi +++ b/doc/functions/sprintf.texi @@ -38,6 +38,10 @@ printf @code{"%010f"} of NaN and Infinity yields an incorrect result (padded with zeroes) on some platforms: MacOS X 10.3, FreeBSD 6.0, NetBSD 3.0, AIX 5.2, IRIX 6.5, OSF/1 5.1, Solaris 10, Cygwin 2007, mingw. @item +This function does not support precisions larger than 512 or 1024 in integer, +floating-point and pointer output on some platforms: +mingw, BeOS. +@item This function can crash in out-of-memory conditions on some platforms: MacOS X 10.3, FreeBSD 6.0, NetBSD 3.0. @end itemize diff --git a/doc/functions/vfprintf.texi b/doc/functions/vfprintf.texi index 5726dcb0f..1ff23743a 100644 --- a/doc/functions/vfprintf.texi +++ b/doc/functions/vfprintf.texi @@ -38,6 +38,10 @@ printf @code{"%010f"} of NaN and Infinity yields an incorrect result (padded with zeroes) on some platforms: MacOS X 10.3, FreeBSD 6.0, NetBSD 3.0, AIX 5.2, IRIX 6.5, OSF/1 5.1, Solaris 10, Cygwin 2007, mingw. @item +This function does not support precisions larger than 512 or 1024 in integer, +floating-point and pointer output on some platforms: +mingw, BeOS. +@item This function can crash in out-of-memory conditions on some platforms: MacOS X 10.3, FreeBSD 6.0, NetBSD 3.0. @end itemize diff --git a/doc/functions/vprintf.texi b/doc/functions/vprintf.texi index 62f5fe974..0c6f49457 100644 --- a/doc/functions/vprintf.texi +++ b/doc/functions/vprintf.texi @@ -38,6 +38,10 @@ printf @code{"%010f"} of NaN and Infinity yields an incorrect result (padded with zeroes) on some platforms: MacOS X 10.3, FreeBSD 6.0, NetBSD 3.0, AIX 5.2, IRIX 6.5, OSF/1 5.1, Solaris 10, Cygwin 2007, mingw. @item +This function does not support precisions larger than 512 or 1024 in integer, +floating-point and pointer output on some platforms: +mingw, BeOS. +@item This function can crash in out-of-memory conditions on some platforms: MacOS X 10.3, FreeBSD 6.0, NetBSD 3.0. @end itemize diff --git a/doc/functions/vsnprintf.texi b/doc/functions/vsnprintf.texi index 36d477807..13c009cf9 100644 --- a/doc/functions/vsnprintf.texi +++ b/doc/functions/vsnprintf.texi @@ -45,6 +45,10 @@ printf @code{"%010f"} of NaN and Infinity yields an incorrect result (padded with zeroes) on some platforms: MacOS X 10.3, FreeBSD 6.0, NetBSD 3.0, AIX 5.2, IRIX 6.5, OSF/1 5.1, Solaris 10, Cygwin 2007, mingw. @item +This function does not support precisions larger than 512 or 1024 in integer, +floating-point and pointer output on some platforms: +mingw, BeOS. +@item This function can crash in out-of-memory conditions on some platforms: MacOS X 10.3, FreeBSD 6.0, NetBSD 3.0. @item diff --git a/doc/functions/vsprintf.texi b/doc/functions/vsprintf.texi index bc0ed4c01..afe7a2cce 100644 --- a/doc/functions/vsprintf.texi +++ b/doc/functions/vsprintf.texi @@ -38,6 +38,10 @@ printf @code{"%010f"} of NaN and Infinity yields an incorrect result (padded with zeroes) on some platforms: MacOS X 10.3, FreeBSD 6.0, NetBSD 3.0, AIX 5.2, IRIX 6.5, OSF/1 5.1, Solaris 10, Cygwin 2007, mingw. @item +This function does not support precisions larger than 512 or 1024 in integer, +floating-point and pointer output on some platforms: +mingw, BeOS. +@item This function can crash in out-of-memory conditions on some platforms: MacOS X 10.3, FreeBSD 6.0, NetBSD 3.0. @end itemize diff --git a/lib/vasnprintf.c b/lib/vasnprintf.c index 17a604630..675e337b3 100644 --- a/lib/vasnprintf.c +++ b/lib/vasnprintf.c @@ -3540,11 +3540,20 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, { arg_type type = a.arg[dp->arg_index].type; int flags = dp->flags; -#if !USE_SNPRINTF || !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_ZERO +#if !USE_SNPRINTF || !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION int has_width; size_t width; #endif -#if !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_ZERO +#if !USE_SNPRINTF || NEED_PRINTF_UNBOUNDED_PRECISION + int has_precision; + size_t precision; +#endif +#if NEED_PRINTF_UNBOUNDED_PRECISION + int prec_ourselves; +#else +# define prec_ourselves 0 +#endif +#if !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION int pad_ourselves; #else # define pad_ourselves 0 @@ -3558,7 +3567,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, TCHAR_T *tmp; #endif -#if !USE_SNPRINTF || !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_ZERO +#if !USE_SNPRINTF || !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION has_width = 0; width = 0; if (dp->width_start != dp->width_end) @@ -3592,34 +3601,42 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, } #endif +#if !USE_SNPRINTF || NEED_PRINTF_UNBOUNDED_PRECISION + has_precision = 0; + precision = 6; + if (dp->precision_start != dp->precision_end) + { + if (dp->precision_arg_index != ARG_NONE) + { + int arg; + + if (!(a.arg[dp->precision_arg_index].type == TYPE_INT)) + abort (); + arg = a.arg[dp->precision_arg_index].a.a_int; + /* "A negative precision is taken as if the precision + were omitted." */ + if (arg >= 0) + { + precision = arg; + has_precision = 1; + } + } + else + { + const FCHAR_T *digitp = dp->precision_start + 1; + + precision = 0; + while (digitp != dp->precision_end) + precision = xsum (xtimes (precision, 10), *digitp++ - '0'); + has_precision = 1; + } + } +#endif + #if !USE_SNPRINTF /* Allocate a temporary buffer of sufficient size for calling sprintf. */ { - size_t precision; - - precision = 6; - if (dp->precision_start != dp->precision_end) - { - if (dp->precision_arg_index != ARG_NONE) - { - int arg; - - if (!(a.arg[dp->precision_arg_index].type == TYPE_INT)) - abort (); - arg = a.arg[dp->precision_arg_index].a.a_int; - precision = (arg < 0 ? 0 : arg); - } - else - { - const FCHAR_T *digitp = dp->precision_start + 1; - - precision = 0; - while (digitp != dp->precision_end) - precision = xsum (xtimes (precision, 10), *digitp++ - '0'); - } - } - switch (dp->conversion) { @@ -3824,8 +3841,23 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, } #endif + /* Decide whether to handle the precision ourselves. */ +#if NEED_PRINTF_UNBOUNDED_PRECISION + switch (dp->conversion) + { + case 'd': case 'i': case 'u': + case 'o': + case 'x': case 'X': case 'p': + prec_ourselves = has_precision && (precision > 0); + break; + default: + prec_ourselves = 0; + break; + } +#endif + /* Decide whether to perform the padding ourselves. */ -#if !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_ZERO +#if !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION switch (dp->conversion) { # if !DCHAR_IS_TCHAR || ENABLE_UNISTDIO @@ -3842,7 +3874,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, pad_ourselves = 1; break; default: - pad_ourselves = 0; + pad_ourselves = prec_ourselves; break; } #endif @@ -3890,22 +3922,25 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, } } } - if (dp->precision_start != dp->precision_end) + if (!prec_ourselves) { - size_t n = dp->precision_end - dp->precision_start; - /* The precision specification is known to consist only - of standard ASCII characters. */ - if (sizeof (FCHAR_T) == sizeof (TCHAR_T)) + if (dp->precision_start != dp->precision_end) { - memcpy (fbp, dp->precision_start, n * sizeof (TCHAR_T)); - fbp += n; - } - else - { - const FCHAR_T *mp = dp->precision_start; - do - *fbp++ = (unsigned char) *mp++; - while (--n > 0); + size_t n = dp->precision_end - dp->precision_start; + /* The precision specification is known to consist only + of standard ASCII characters. */ + if (sizeof (FCHAR_T) == sizeof (TCHAR_T)) + { + memcpy (fbp, dp->precision_start, n * sizeof (TCHAR_T)); + fbp += n; + } + else + { + const FCHAR_T *mp = dp->precision_start; + do + *fbp++ = (unsigned char) *mp++; + while (--n > 0); + } } } @@ -4252,6 +4287,69 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, } #endif +#if NEED_PRINTF_UNBOUNDED_PRECISION + if (prec_ourselves) + { + /* Handle the precision. */ + TCHAR_T *prec_ptr = +# if USE_SNPRINTF + (TCHAR_T *) (result + length); +# else + tmp; +# endif + size_t prefix_count; + size_t move; + + prefix_count = 0; + /* Put the additional zeroes after the sign. */ + if (count >= 1 + && (*prec_ptr == '-' || *prec_ptr == '+' + || *prec_ptr == ' ')) + prefix_count = 1; + /* Put the additional zeroes after the 0x prefix if + (flags & FLAG_ALT) || (dp->conversion == 'p'). */ + else if (count >= 2 + && prec_ptr[0] == '0' + && (prec_ptr[1] == 'x' || prec_ptr[1] == 'X')) + prefix_count = 2; + + move = count - prefix_count; + if (precision > move) + { + /* Insert zeroes. */ + size_t insert = precision - move; + TCHAR_T *prec_end; + +# if USE_SNPRINTF + size_t n = + xsum (length, + (count + insert + TCHARS_PER_DCHAR - 1) + / TCHARS_PER_DCHAR); + length += (count + TCHARS_PER_DCHAR - 1) / TCHARS_PER_DCHAR; + ENSURE_ALLOCATION (n); + length -= (count + TCHARS_PER_DCHAR - 1) / TCHARS_PER_DCHAR; + prec_ptr = (TCHAR_T *) (result + length); +# endif + + prec_end = prec_ptr + count; + prec_ptr += prefix_count; + + while (prec_end > prec_ptr) + { + prec_end--; + prec_end[insert] = prec_end[0]; + } + + prec_end += insert; + do + *--prec_end = '0'; + while (prec_end > prec_ptr); + + count += insert; + } + } +#endif + #if !DCHAR_IS_TCHAR # if !USE_SNPRINTF if (count >= tmp_length) @@ -4360,7 +4458,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, /* Here count <= allocated - length. */ /* Perform padding. */ -#if !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_ZERO +#if !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION if (pad_ourselves && has_width) { size_t w; diff --git a/m4/fprintf-posix.m4 b/m4/fprintf-posix.m4 index 9908f9412..287889b17 100644 --- a/m4/fprintf-posix.m4 +++ b/m4/fprintf-posix.m4 @@ -1,4 +1,4 @@ -# fprintf-posix.m4 serial 8 +# fprintf-posix.m4 serial 9 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, @@ -17,6 +17,7 @@ AC_DEFUN([gl_FUNC_FPRINTF_POSIX], AC_REQUIRE([gl_PRINTF_POSITIONS]) AC_REQUIRE([gl_PRINTF_FLAG_GROUPING]) AC_REQUIRE([gl_PRINTF_FLAG_ZERO]) + AC_REQUIRE([gl_PRINTF_PRECISION]) AC_REQUIRE([gl_PRINTF_ENOMEM]) gl_cv_func_fprintf_posix=no case "$gl_cv_func_printf_sizes_c99" in @@ -39,11 +40,15 @@ AC_DEFUN([gl_FUNC_FPRINTF_POSIX], *yes) case "$gl_cv_func_printf_flag_zero" in *yes) - case "$gl_cv_func_printf_enomem" in + case "$gl_cv_func_printf_precision" in *yes) - # fprintf exists and is already - # POSIX compliant. - gl_cv_func_fprintf_posix=yes + case "$gl_cv_func_printf_enomem" in + *yes) + # fprintf exists and is + # already POSIX compliant. + gl_cv_func_fprintf_posix=yes + ;; + esac ;; esac ;; @@ -74,6 +79,7 @@ AC_DEFUN([gl_FUNC_FPRINTF_POSIX], gl_PREREQ_VASNPRINTF_DIRECTIVE_F gl_PREREQ_VASNPRINTF_FLAG_GROUPING gl_PREREQ_VASNPRINTF_FLAG_ZERO + gl_PREREQ_VASNPRINTF_PRECISION gl_PREREQ_VASNPRINTF_ENOMEM gl_REPLACE_VASNPRINTF gl_REPLACE_FPRINTF diff --git a/m4/printf.m4 b/m4/printf.m4 index ab5698edc..a35c83378 100644 --- a/m4/printf.m4 +++ b/m4/printf.m4 @@ -1,4 +1,4 @@ -# printf.m4 serial 18 +# printf.m4 serial 19 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, @@ -721,6 +721,46 @@ changequote([,])dnl ]) ]) +dnl Test whether the *printf family of functions supports large precisions. +dnl On mingw, precisions larger than 512 are treated like 512, in integer, +dnl floating-point or pointer output. On BeOS, precisions larger than 1044 +dnl crash the program. +dnl Result is gl_cv_func_printf_precision. + +AC_DEFUN([gl_PRINTF_PRECISION], +[ + AC_REQUIRE([AC_PROG_CC]) + AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles + AC_CACHE_CHECK([whether printf supports large precisions], + [gl_cv_func_printf_precision], + [ + AC_TRY_RUN([ +#include +#include +static char buf[5000]; +int main () +{ +#ifdef __BEOS__ + /* On BeOS, this would crash and show a dialog box. Avoid the crash. */ + return 1; +#endif + if (sprintf (buf, "%.4000d %d", 1, 33, 44) < 4000 + 3) + return 1; + return 0; +}], [gl_cv_func_printf_precision=yes], [gl_cv_func_printf_precision=no], + [ +changequote(,)dnl + case "$host_os" in + # Guess no only on native Win32 and BeOS systems. + mingw* | pw*) gl_cv_func_printf_precision="guessing no" ;; + beos*) gl_cv_func_printf_precision="guessing no" ;; + *) gl_cv_func_printf_precision="guessing yes" ;; + esac +changequote([,])dnl + ]) + ]) +]) + dnl Test whether the *printf family of functions recovers gracefully in case dnl of an out-of-memory condition, or whether it crashes the entire program. dnl Result is gl_cv_func_printf_enomem. @@ -1142,12 +1182,13 @@ dnl 7 = gl_PRINTF_DIRECTIVE_N dnl 8 = gl_PRINTF_POSITIONS dnl 9 = gl_PRINTF_FLAG_GROUPING dnl 10 = gl_PRINTF_FLAG_ZERO -dnl 11 = gl_PRINTF_ENOMEM -dnl 12 = gl_SNPRINTF_PRESENCE -dnl 13 = gl_SNPRINTF_TRUNCATION_C99 -dnl 14 = gl_SNPRINTF_RETVAL_C99 -dnl 15 = gl_SNPRINTF_DIRECTIVE_N -dnl 16 = gl_VSNPRINTF_ZEROSIZE_C99 +dnl 11 = gl_PRINTF_PRECISION +dnl 12 = gl_PRINTF_ENOMEM +dnl 13 = gl_SNPRINTF_PRESENCE +dnl 14 = gl_SNPRINTF_TRUNCATION_C99 +dnl 15 = gl_SNPRINTF_RETVAL_C99 +dnl 16 = gl_SNPRINTF_DIRECTIVE_N +dnl 17 = 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... @@ -1159,34 +1200,35 @@ dnl 7 = checking whether printf supports the 'n' directive... dnl 8 = checking whether printf supports POSIX/XSI format strings with positions... dnl 9 = checking whether printf supports the grouping flag... dnl 10 = checking whether printf supports the zero flag correctly... -dnl 11 = checking whether printf survives out-of-memory conditions... -dnl 12 = checking for snprintf... -dnl 13 = checking whether snprintf truncates the result as in C99... -dnl 14 = checking whether snprintf returns a byte count as in C99... -dnl 15 = checking whether snprintf fully supports the 'n' directive... -dnl 16 = checking whether vsnprintf respects a zero size as in C99... +dnl 11 = checking whether printf supports large precisions... +dnl 12 = checking whether printf survives out-of-memory conditions... +dnl 13 = checking for snprintf... +dnl 14 = checking whether snprintf truncates the result as in C99... +dnl 15 = checking whether snprintf returns a byte count as in C99... +dnl 16 = checking whether snprintf fully supports the 'n' directive... +dnl 17 = 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 14 15 16 -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 # # # # # # . # # # ? . # # # . +dnl 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 +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 6353d9c63..666812f39 100644 --- a/m4/snprintf-posix.m4 +++ b/m4/snprintf-posix.m4 @@ -1,4 +1,4 @@ -# snprintf-posix.m4 serial 9 +# snprintf-posix.m4 serial 10 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, @@ -17,6 +17,7 @@ AC_DEFUN([gl_FUNC_SNPRINTF_POSIX], AC_REQUIRE([gl_PRINTF_POSITIONS]) AC_REQUIRE([gl_PRINTF_FLAG_GROUPING]) AC_REQUIRE([gl_PRINTF_FLAG_ZERO]) + AC_REQUIRE([gl_PRINTF_PRECISION]) AC_REQUIRE([gl_PRINTF_ENOMEM]) gl_cv_func_snprintf_posix=no AC_CHECK_FUNCS([snprintf]) @@ -45,19 +46,23 @@ AC_DEFUN([gl_FUNC_SNPRINTF_POSIX], *yes) case "$gl_cv_func_printf_flag_zero" in *yes) - case "$gl_cv_func_printf_enomem" in + case "$gl_cv_func_printf_precision" in *yes) - case "$gl_cv_func_snprintf_truncation_c99" in + case "$gl_cv_func_printf_enomem" 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 ;; @@ -97,6 +102,7 @@ AC_DEFUN([gl_FUNC_SNPRINTF_POSIX], gl_PREREQ_VASNPRINTF_DIRECTIVE_F gl_PREREQ_VASNPRINTF_FLAG_GROUPING gl_PREREQ_VASNPRINTF_FLAG_ZERO + gl_PREREQ_VASNPRINTF_PRECISION gl_PREREQ_VASNPRINTF_ENOMEM gl_REPLACE_VASNPRINTF gl_REPLACE_SNPRINTF diff --git a/m4/sprintf-posix.m4 b/m4/sprintf-posix.m4 index 8e6fcaa86..494b9307b 100644 --- a/m4/sprintf-posix.m4 +++ b/m4/sprintf-posix.m4 @@ -1,4 +1,4 @@ -# sprintf-posix.m4 serial 8 +# sprintf-posix.m4 serial 9 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, @@ -17,6 +17,7 @@ AC_DEFUN([gl_FUNC_SPRINTF_POSIX], AC_REQUIRE([gl_PRINTF_POSITIONS]) AC_REQUIRE([gl_PRINTF_FLAG_GROUPING]) AC_REQUIRE([gl_PRINTF_FLAG_ZERO]) + AC_REQUIRE([gl_PRINTF_PRECISION]) AC_REQUIRE([gl_PRINTF_ENOMEM]) gl_cv_func_sprintf_posix=no case "$gl_cv_func_printf_sizes_c99" in @@ -39,11 +40,15 @@ AC_DEFUN([gl_FUNC_SPRINTF_POSIX], *yes) case "$gl_cv_func_printf_flag_zero" in *yes) - case "$gl_cv_func_printf_enomem" in + case "$gl_cv_func_printf_precision" in *yes) - # sprintf exists and is already - # POSIX compliant. - gl_cv_func_sprintf_posix=yes + case "$gl_cv_func_printf_enomem" in + *yes) + # sprintf exists and is + # already POSIX compliant. + gl_cv_func_sprintf_posix=yes + ;; + esac ;; esac ;; @@ -74,6 +79,7 @@ AC_DEFUN([gl_FUNC_SPRINTF_POSIX], gl_PREREQ_VASNPRINTF_DIRECTIVE_F gl_PREREQ_VASNPRINTF_FLAG_GROUPING gl_PREREQ_VASNPRINTF_FLAG_ZERO + gl_PREREQ_VASNPRINTF_PRECISION gl_PREREQ_VASNPRINTF_ENOMEM gl_REPLACE_VASNPRINTF gl_REPLACE_SPRINTF diff --git a/m4/vasnprintf-posix.m4 b/m4/vasnprintf-posix.m4 index 73b10bafa..d28c8986b 100644 --- a/m4/vasnprintf-posix.m4 +++ b/m4/vasnprintf-posix.m4 @@ -1,4 +1,4 @@ -# vasnprintf-posix.m4 serial 9 +# vasnprintf-posix.m4 serial 10 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, @@ -17,6 +17,7 @@ AC_DEFUN([gl_FUNC_VASNPRINTF_POSIX], AC_REQUIRE([gl_PRINTF_POSITIONS]) AC_REQUIRE([gl_PRINTF_FLAG_GROUPING]) AC_REQUIRE([gl_PRINTF_FLAG_ZERO]) + AC_REQUIRE([gl_PRINTF_PRECISION]) AC_REQUIRE([gl_PRINTF_ENOMEM]) gl_cv_func_vasnprintf_posix=no AC_CHECK_FUNCS_ONCE([vasnprintf]) @@ -40,13 +41,17 @@ AC_DEFUN([gl_FUNC_VASNPRINTF_POSIX], *yes) case "$gl_cv_func_printf_flag_zero" in *yes) - case "$gl_cv_func_printf_enomem" in + case "$gl_cv_func_printf_precision" 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_enomem" 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 ;; @@ -77,6 +82,7 @@ AC_DEFUN([gl_FUNC_VASNPRINTF_POSIX], gl_PREREQ_VASNPRINTF_DIRECTIVE_F gl_PREREQ_VASNPRINTF_FLAG_GROUPING gl_PREREQ_VASNPRINTF_FLAG_ZERO + gl_PREREQ_VASNPRINTF_PRECISION gl_PREREQ_VASNPRINTF_ENOMEM gl_REPLACE_VASNPRINTF fi diff --git a/m4/vasnprintf.m4 b/m4/vasnprintf.m4 index e9733354e..ef39db601 100644 --- a/m4/vasnprintf.m4 +++ b/m4/vasnprintf.m4 @@ -1,4 +1,4 @@ -# vasnprintf.m4 serial 21 +# vasnprintf.m4 serial 22 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, @@ -178,6 +178,27 @@ AC_DEFUN([gl_PREREQ_VASNPRINTF_FLAG_ZERO], esac ]) +# Extra prerequisites of lib/vasnprintf.c for supporting large precisions. +AC_DEFUN([gl_PREREQ_VASNPRINTF_PRECISION], +[ + AC_REQUIRE([gl_PRINTF_PRECISION]) + case "$gl_cv_func_printf_precision" in + *yes) + ;; + *) + AC_DEFINE([NEED_PRINTF_UNBOUNDED_PRECISION], 1, + [Define if the vasnprintf implementation needs special code for + supporting large precisions without arbitrary bounds.]) + AC_DEFINE([NEED_PRINTF_DOUBLE], 1, + [Define if the vasnprintf implementation needs special code for + 'double' arguments.]) + AC_DEFINE([NEED_PRINTF_LONG_DOUBLE], 1, + [Define if the vasnprintf implementation needs special code for + 'long double' arguments.]) + ;; + esac +]) + # Extra prerequisites of lib/vasnprintf.c for surviving out-of-memory # conditions. AC_DEFUN([gl_PREREQ_VASNPRINTF_ENOMEM], @@ -211,6 +232,7 @@ AC_DEFUN([gl_PREREQ_VASNPRINTF_WITH_EXTRAS], gl_PREREQ_VASNPRINTF_DIRECTIVE_F gl_PREREQ_VASNPRINTF_FLAG_GROUPING gl_PREREQ_VASNPRINTF_FLAG_ZERO + gl_PREREQ_VASNPRINTF_PRECISION gl_PREREQ_VASNPRINTF_ENOMEM ]) diff --git a/m4/vasprintf-posix.m4 b/m4/vasprintf-posix.m4 index 9d63ea3ee..cba0fdc26 100644 --- a/m4/vasprintf-posix.m4 +++ b/m4/vasprintf-posix.m4 @@ -1,4 +1,4 @@ -# vasprintf-posix.m4 serial 9 +# vasprintf-posix.m4 serial 10 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, @@ -17,6 +17,7 @@ AC_DEFUN([gl_FUNC_VASPRINTF_POSIX], AC_REQUIRE([gl_PRINTF_POSITIONS]) AC_REQUIRE([gl_PRINTF_FLAG_GROUPING]) AC_REQUIRE([gl_PRINTF_FLAG_ZERO]) + AC_REQUIRE([gl_PRINTF_PRECISION]) AC_REQUIRE([gl_PRINTF_ENOMEM]) gl_cv_func_vasprintf_posix=no AC_CHECK_FUNCS([vasprintf]) @@ -40,13 +41,17 @@ AC_DEFUN([gl_FUNC_VASPRINTF_POSIX], *yes) case "$gl_cv_func_printf_flag_zero" in *yes) - case "$gl_cv_func_printf_enomem" in + case "$gl_cv_func_printf_precision" 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_enomem" 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 ;; @@ -77,6 +82,7 @@ AC_DEFUN([gl_FUNC_VASPRINTF_POSIX], gl_PREREQ_VASNPRINTF_DIRECTIVE_F gl_PREREQ_VASNPRINTF_FLAG_GROUPING gl_PREREQ_VASNPRINTF_FLAG_ZERO + gl_PREREQ_VASNPRINTF_PRECISION gl_PREREQ_VASNPRINTF_ENOMEM gl_REPLACE_VASNPRINTF gl_REPLACE_VASPRINTF diff --git a/m4/vfprintf-posix.m4 b/m4/vfprintf-posix.m4 index da2b19a56..b6690ec6a 100644 --- a/m4/vfprintf-posix.m4 +++ b/m4/vfprintf-posix.m4 @@ -1,4 +1,4 @@ -# vfprintf-posix.m4 serial 8 +# vfprintf-posix.m4 serial 9 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, @@ -17,6 +17,7 @@ AC_DEFUN([gl_FUNC_VFPRINTF_POSIX], AC_REQUIRE([gl_PRINTF_POSITIONS]) AC_REQUIRE([gl_PRINTF_FLAG_GROUPING]) AC_REQUIRE([gl_PRINTF_FLAG_ZERO]) + AC_REQUIRE([gl_PRINTF_PRECISION]) AC_REQUIRE([gl_PRINTF_ENOMEM]) gl_cv_func_vfprintf_posix=no case "$gl_cv_func_printf_sizes_c99" in @@ -39,11 +40,15 @@ AC_DEFUN([gl_FUNC_VFPRINTF_POSIX], *yes) case "$gl_cv_func_printf_flag_zero" in *yes) - case "$gl_cv_func_printf_enomem" in + case "$gl_cv_func_printf_precision" in *yes) - # vfprintf exists and is already - # POSIX compliant. - gl_cv_func_vfprintf_posix=yes + case "$gl_cv_func_printf_enomem" in + *yes) + # vfprintf exists and is + # already POSIX compliant. + gl_cv_func_vfprintf_posix=yes + ;; + esac ;; esac ;; @@ -74,6 +79,7 @@ AC_DEFUN([gl_FUNC_VFPRINTF_POSIX], gl_PREREQ_VASNPRINTF_DIRECTIVE_F gl_PREREQ_VASNPRINTF_FLAG_GROUPING gl_PREREQ_VASNPRINTF_FLAG_ZERO + gl_PREREQ_VASNPRINTF_PRECISION gl_PREREQ_VASNPRINTF_ENOMEM gl_REPLACE_VASNPRINTF gl_REPLACE_VFPRINTF diff --git a/m4/vsnprintf-posix.m4 b/m4/vsnprintf-posix.m4 index aaf5d2c2c..8004f657c 100644 --- a/m4/vsnprintf-posix.m4 +++ b/m4/vsnprintf-posix.m4 @@ -1,4 +1,4 @@ -# vsnprintf-posix.m4 serial 9 +# vsnprintf-posix.m4 serial 10 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, @@ -17,6 +17,7 @@ AC_DEFUN([gl_FUNC_VSNPRINTF_POSIX], AC_REQUIRE([gl_PRINTF_POSITIONS]) AC_REQUIRE([gl_PRINTF_FLAG_GROUPING]) AC_REQUIRE([gl_PRINTF_FLAG_ZERO]) + AC_REQUIRE([gl_PRINTF_PRECISION]) AC_REQUIRE([gl_PRINTF_ENOMEM]) gl_cv_func_vsnprintf_posix=no AC_CHECK_FUNCS([vsnprintf]) @@ -46,19 +47,23 @@ AC_DEFUN([gl_FUNC_VSNPRINTF_POSIX], *yes) case "$gl_cv_func_printf_flag_zero" in *yes) - case "$gl_cv_func_printf_enomem" in + case "$gl_cv_func_printf_precision" in *yes) - case "$gl_cv_func_snprintf_truncation_c99" in + case "$gl_cv_func_printf_enomem" 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 ;; @@ -98,6 +103,7 @@ AC_DEFUN([gl_FUNC_VSNPRINTF_POSIX], gl_PREREQ_VASNPRINTF_DIRECTIVE_F gl_PREREQ_VASNPRINTF_FLAG_GROUPING gl_PREREQ_VASNPRINTF_FLAG_ZERO + gl_PREREQ_VASNPRINTF_PRECISION gl_PREREQ_VASNPRINTF_ENOMEM gl_REPLACE_VASNPRINTF gl_REPLACE_VSNPRINTF diff --git a/m4/vsprintf-posix.m4 b/m4/vsprintf-posix.m4 index 48ca6eff6..a218559d0 100644 --- a/m4/vsprintf-posix.m4 +++ b/m4/vsprintf-posix.m4 @@ -1,4 +1,4 @@ -# vsprintf-posix.m4 serial 8 +# vsprintf-posix.m4 serial 9 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, @@ -17,6 +17,7 @@ AC_DEFUN([gl_FUNC_VSPRINTF_POSIX], AC_REQUIRE([gl_PRINTF_POSITIONS]) AC_REQUIRE([gl_PRINTF_FLAG_GROUPING]) AC_REQUIRE([gl_PRINTF_FLAG_ZERO]) + AC_REQUIRE([gl_PRINTF_PRECISION]) AC_REQUIRE([gl_PRINTF_ENOMEM]) gl_cv_func_vsprintf_posix=no case "$gl_cv_func_printf_sizes_c99" in @@ -39,11 +40,15 @@ AC_DEFUN([gl_FUNC_VSPRINTF_POSIX], *yes) case "$gl_cv_func_printf_flag_zero" in *yes) - case "$gl_cv_func_printf_enomem" in + case "$gl_cv_func_printf_precision" in *yes) - # vsprintf exists and is already - # POSIX compliant. - gl_cv_func_vsprintf_posix=yes + case "$gl_cv_func_printf_enomem" in + *yes) + # vsprintf exists and is + # already POSIX compliant. + gl_cv_func_vsprintf_posix=yes + ;; + esac ;; esac ;; @@ -74,6 +79,7 @@ AC_DEFUN([gl_FUNC_VSPRINTF_POSIX], gl_PREREQ_VASNPRINTF_DIRECTIVE_F gl_PREREQ_VASNPRINTF_FLAG_GROUPING gl_PREREQ_VASNPRINTF_FLAG_ZERO + gl_PREREQ_VASNPRINTF_PRECISION gl_PREREQ_VASNPRINTF_ENOMEM gl_REPLACE_VASNPRINTF gl_REPLACE_VSPRINTF -- 2.11.0