The test cases for large precisions, meant to uncover out-of-memory handling problems, also uncovered another problem: - On mingw, precisions larger than 512 are capped, i.e. treated like if they were 512. So, you ask for 2000 digits, you get 512 digits. - On BeOS, precisions larger than 1044 even crash the program. The odd value of this limit suggests that it's a buffer overflow of a buffer of size 1024.
POSIX imposes no limit on the possible precisions. ISO C 99 does not do either, but mentions another limit in 7.19.6.1.(15): "The number of characters that can be produced by any single conversion shall be at least 4095." So the behaviour of mingw and BeOS is not POSIX and not ISO C compliant. I'm adding a workaround to gnulib. 2007-11-04 Bruno Haible <[EMAIL PROTECTED]> 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. *** doc/functions/fprintf.texi.orig 2007-11-04 17:05:18.000000000 +0100 --- doc/functions/fprintf.texi 2007-11-04 16:48:08.000000000 +0100 *************** *** 38,43 **** --- 38,47 ---- 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 *** doc/functions/printf.texi.orig 2007-11-04 17:05:18.000000000 +0100 --- doc/functions/printf.texi 2007-11-04 16:48:05.000000000 +0100 *************** *** 38,43 **** --- 38,47 ---- 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 *** doc/functions/snprintf.texi.orig 2007-11-04 17:05:18.000000000 +0100 --- doc/functions/snprintf.texi 2007-11-04 16:48:10.000000000 +0100 *************** *** 45,50 **** --- 45,54 ---- 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 *** doc/functions/sprintf.texi.orig 2007-11-04 17:05:18.000000000 +0100 --- doc/functions/sprintf.texi 2007-11-04 16:48:15.000000000 +0100 *************** *** 38,43 **** --- 38,47 ---- 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 *** doc/functions/vfprintf.texi.orig 2007-11-04 17:05:18.000000000 +0100 --- doc/functions/vfprintf.texi 2007-11-04 16:48:13.000000000 +0100 *************** *** 38,43 **** --- 38,47 ---- 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 *** doc/functions/vprintf.texi.orig 2007-11-04 17:05:19.000000000 +0100 --- doc/functions/vprintf.texi 2007-11-04 16:48:20.000000000 +0100 *************** *** 38,43 **** --- 38,47 ---- 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 *** doc/functions/vsnprintf.texi.orig 2007-11-04 17:05:19.000000000 +0100 --- doc/functions/vsnprintf.texi 2007-11-04 16:48:18.000000000 +0100 *************** *** 45,50 **** --- 45,54 ---- 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 *** doc/functions/vsprintf.texi.orig 2007-11-04 17:05:19.000000000 +0100 --- doc/functions/vsprintf.texi 2007-11-04 16:48:22.000000000 +0100 *************** *** 38,43 **** --- 38,47 ---- 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 *** lib/vasnprintf.c.orig 2007-11-04 17:05:19.000000000 +0100 --- lib/vasnprintf.c 2007-11-04 16:51:25.000000000 +0100 *************** *** 3540,3550 **** { 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 int has_width; size_t width; #endif ! #if !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_ZERO int pad_ourselves; #else # define pad_ourselves 0 --- 3540,3559 ---- { 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 || NEED_PRINTF_UNBOUNDED_PRECISION int has_width; size_t width; #endif ! #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,3564 **** TCHAR_T *tmp; #endif ! #if !USE_SNPRINTF || !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_ZERO has_width = 0; width = 0; if (dp->width_start != dp->width_end) --- 3567,3573 ---- TCHAR_T *tmp; #endif ! #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,3625 **** } #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) { --- 3601,3642 ---- } #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. */ { switch (dp->conversion) { *************** *** 3824,3831 **** } #endif /* Decide whether to perform the padding ourselves. */ ! #if !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_ZERO switch (dp->conversion) { # if !DCHAR_IS_TCHAR || ENABLE_UNISTDIO --- 3841,3863 ---- } #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 || NEED_PRINTF_UNBOUNDED_PRECISION switch (dp->conversion) { # if !DCHAR_IS_TCHAR || ENABLE_UNISTDIO *************** *** 3842,3848 **** pad_ourselves = 1; break; default: ! pad_ourselves = 0; break; } #endif --- 3874,3880 ---- pad_ourselves = 1; break; default: ! pad_ourselves = prec_ourselves; break; } #endif *************** *** 3890,3911 **** } } } ! if (dp->precision_start != dp->precision_end) { ! 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); } } --- 3922,3946 ---- } } } ! if (!prec_ourselves) { ! if (dp->precision_start != dp->precision_end) { ! 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,4257 **** --- 4287,4355 ---- } #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,4366 **** /* Here count <= allocated - length. */ /* Perform padding. */ ! #if !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_ZERO if (pad_ourselves && has_width) { size_t w; --- 4458,4464 ---- /* Here count <= allocated - length. */ /* Perform padding. */ ! #if !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION if (pad_ourselves && has_width) { size_t w; *** m4/fprintf-posix.m4.orig 2007-11-04 17:05:19.000000000 +0100 --- m4/fprintf-posix.m4 2007-11-04 15:29:40.000000000 +0100 *************** *** 1,4 **** ! # fprintf-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, --- 1,4 ---- ! # 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,22 **** --- 17,23 ---- 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,49 **** *yes) case "$gl_cv_func_printf_flag_zero" in *yes) ! case "$gl_cv_func_printf_enomem" in *yes) ! # fprintf exists and is already ! # POSIX compliant. ! gl_cv_func_fprintf_posix=yes ;; esac ;; --- 40,54 ---- *yes) case "$gl_cv_func_printf_flag_zero" in *yes) ! case "$gl_cv_func_printf_precision" in *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,79 **** --- 79,85 ---- 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 *** m4/printf.m4.orig 2007-11-04 17:05:19.000000000 +0100 --- m4/printf.m4 2007-11-04 16:57:41.000000000 +0100 *************** *** 1,4 **** ! # printf.m4 serial 18 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, --- 1,4 ---- ! # 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,726 **** --- 721,766 ---- ]) ]) + 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 <stdio.h> + #include <string.h> + 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,1153 **** 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 dnl 1 = checking whether printf supports size specifiers as in C99... dnl 2 = checking whether printf supports 'long double' arguments... --- 1182,1194 ---- dnl 8 = gl_PRINTF_POSITIONS dnl 9 = gl_PRINTF_FLAG_GROUPING dnl 10 = gl_PRINTF_FLAG_ZERO ! 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,1192 **** 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 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 # # # # # # . # # # ? . # # # . --- 1200,1234 ---- 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 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 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 # # # # # # . # # # # ? . # # # . *** m4/snprintf-posix.m4.orig 2007-11-04 17:05:19.000000000 +0100 --- m4/snprintf-posix.m4 2007-11-04 15:30:12.000000000 +0100 *************** *** 1,4 **** ! # snprintf-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, --- 1,4 ---- ! # 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,22 **** --- 17,23 ---- 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,63 **** *yes) case "$gl_cv_func_printf_flag_zero" in *yes) ! case "$gl_cv_func_printf_enomem" in *yes) ! case "$gl_cv_func_snprintf_truncation_c99" in *yes) ! case "$gl_cv_func_snprintf_retval_c99" in *yes) ! case "$gl_cv_func_snprintf_directive_n" in *yes) ! case "$gl_cv_func_vsnprintf_zerosize_c99" in *yes) ! # snprintf exists and is ! # already POSIX compliant. ! gl_cv_func_snprintf_posix=yes ;; esac ;; --- 46,68 ---- *yes) case "$gl_cv_func_printf_flag_zero" in *yes) ! case "$gl_cv_func_printf_precision" in *yes) ! case "$gl_cv_func_printf_enomem" in *yes) ! case "$gl_cv_func_snprintf_truncation_c99" in *yes) ! case "$gl_cv_func_snprintf_retval_c99" in *yes) ! case "$gl_cv_func_snprintf_directive_n" in *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,102 **** --- 102,108 ---- 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 *** m4/sprintf-posix.m4.orig 2007-11-04 17:05:19.000000000 +0100 --- m4/sprintf-posix.m4 2007-11-04 15:30:39.000000000 +0100 *************** *** 1,4 **** ! # sprintf-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, --- 1,4 ---- ! # 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,22 **** --- 17,23 ---- 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,49 **** *yes) case "$gl_cv_func_printf_flag_zero" in *yes) ! case "$gl_cv_func_printf_enomem" in *yes) ! # sprintf exists and is already ! # POSIX compliant. ! gl_cv_func_sprintf_posix=yes ;; esac ;; --- 40,54 ---- *yes) case "$gl_cv_func_printf_flag_zero" in *yes) ! case "$gl_cv_func_printf_precision" in *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,79 **** --- 79,85 ---- 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 *** m4/vasnprintf-posix.m4.orig 2007-11-04 17:05:19.000000000 +0100 --- m4/vasnprintf-posix.m4 2007-11-04 15:31:18.000000000 +0100 *************** *** 1,4 **** ! # vasnprintf-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, --- 1,4 ---- ! # 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,22 **** --- 17,23 ---- 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,52 **** *yes) case "$gl_cv_func_printf_flag_zero" in *yes) ! 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 ;; --- 41,57 ---- *yes) case "$gl_cv_func_printf_flag_zero" in *yes) ! case "$gl_cv_func_printf_precision" in *yes) ! 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,82 **** --- 82,88 ---- 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 *** m4/vasnprintf.m4.orig 2007-11-04 17:05:19.000000000 +0100 --- m4/vasnprintf.m4 2007-11-04 17:02:58.000000000 +0100 *************** *** 1,4 **** ! # vasnprintf.m4 serial 21 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, --- 1,4 ---- ! # 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,183 **** --- 178,204 ---- 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,216 **** --- 232,238 ---- gl_PREREQ_VASNPRINTF_DIRECTIVE_F gl_PREREQ_VASNPRINTF_FLAG_GROUPING gl_PREREQ_VASNPRINTF_FLAG_ZERO + gl_PREREQ_VASNPRINTF_PRECISION gl_PREREQ_VASNPRINTF_ENOMEM ]) *** m4/vasprintf-posix.m4.orig 2007-11-04 17:05:19.000000000 +0100 --- m4/vasprintf-posix.m4 2007-11-04 15:32:09.000000000 +0100 *************** *** 1,4 **** ! # vasprintf-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, --- 1,4 ---- ! # 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,22 **** --- 17,23 ---- 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,52 **** *yes) case "$gl_cv_func_printf_flag_zero" in *yes) ! 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 ;; --- 41,57 ---- *yes) case "$gl_cv_func_printf_flag_zero" in *yes) ! case "$gl_cv_func_printf_precision" in *yes) ! 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,82 **** --- 82,88 ---- 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 *** m4/vfprintf-posix.m4.orig 2007-11-04 17:05:19.000000000 +0100 --- m4/vfprintf-posix.m4 2007-11-04 15:32:36.000000000 +0100 *************** *** 1,4 **** ! # vfprintf-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, --- 1,4 ---- ! # 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,22 **** --- 17,23 ---- 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,49 **** *yes) case "$gl_cv_func_printf_flag_zero" in *yes) ! case "$gl_cv_func_printf_enomem" in *yes) ! # vfprintf exists and is already ! # POSIX compliant. ! gl_cv_func_vfprintf_posix=yes ;; esac ;; --- 40,54 ---- *yes) case "$gl_cv_func_printf_flag_zero" in *yes) ! case "$gl_cv_func_printf_precision" in *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,79 **** --- 79,85 ---- 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 *** m4/vsnprintf-posix.m4.orig 2007-11-04 17:05:19.000000000 +0100 --- m4/vsnprintf-posix.m4 2007-11-04 15:33:05.000000000 +0100 *************** *** 1,4 **** ! # vsnprintf-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, --- 1,4 ---- ! # 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,22 **** --- 17,23 ---- 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,64 **** *yes) case "$gl_cv_func_printf_flag_zero" in *yes) ! case "$gl_cv_func_printf_enomem" in *yes) ! case "$gl_cv_func_snprintf_truncation_c99" in *yes) ! case "$gl_cv_func_snprintf_retval_c99" in *yes) ! case "$gl_cv_func_snprintf_directive_n" in *yes) ! case "$gl_cv_func_vsnprintf_zerosize_c99" in *yes) ! # vsnprintf exists and is ! # already POSIX compliant. ! gl_cv_func_vsnprintf_posix=yes ;; esac ;; --- 47,69 ---- *yes) case "$gl_cv_func_printf_flag_zero" in *yes) ! case "$gl_cv_func_printf_precision" in *yes) ! case "$gl_cv_func_printf_enomem" in *yes) ! case "$gl_cv_func_snprintf_truncation_c99" in *yes) ! case "$gl_cv_func_snprintf_retval_c99" in *yes) ! case "$gl_cv_func_snprintf_directive_n" in *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,103 **** --- 103,109 ---- 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 *** m4/vsprintf-posix.m4.orig 2007-11-04 17:05:19.000000000 +0100 --- m4/vsprintf-posix.m4 2007-11-04 15:33:32.000000000 +0100 *************** *** 1,4 **** ! # vsprintf-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, --- 1,4 ---- ! # 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,22 **** --- 17,23 ---- 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,49 **** *yes) case "$gl_cv_func_printf_flag_zero" in *yes) ! case "$gl_cv_func_printf_enomem" in *yes) ! # vsprintf exists and is already ! # POSIX compliant. ! gl_cv_func_vsprintf_posix=yes ;; esac ;; --- 40,54 ---- *yes) case "$gl_cv_func_printf_flag_zero" in *yes) ! case "$gl_cv_func_printf_precision" in *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,79 **** --- 79,85 ---- 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