Add support for 'long double' number output.
[gnulib.git] / m4 / printf.m4
index 7c97b95..32325bf 100644 (file)
@@ -1,4 +1,4 @@
-# printf.m4 serial 1
+# printf.m4 serial 10
 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,
@@ -13,7 +13,6 @@ AC_DEFUN([gl_PRINTF_SIZES_C99],
   AC_REQUIRE([AC_PROG_CC])
   AC_REQUIRE([gl_AC_HEADER_STDINT_H])
   AC_REQUIRE([gl_AC_HEADER_INTTYPES_H])
-  AC_REQUIRE([gt_TYPE_LONGDOUBLE])
   AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
   AC_CACHE_CHECK([whether printf supports size specifiers as in C99],
     [gl_cv_func_printf_sizes_c99], 
@@ -46,32 +45,35 @@ int main ()
   if (sprintf (buf, "%tu %d", (ptrdiff_t) 12345673, 33, 44, 55) < 0
       || strcmp (buf, "12345673 33") != 0)
     return 1;
-#if HAVE_LONG_DOUBLE
   buf[0] = '\0';
   if (sprintf (buf, "%Lg %d", (long double) 1.5, 33, 44, 55) < 0
       || strcmp (buf, "1.5 33") != 0)
     return 1;
-#endif
   return 0;
 }], [gl_cv_func_printf_sizes_c99=yes], [gl_cv_func_printf_sizes_c99=no],
       [
 changequote(,)dnl
        case "$host_os" in
-                               dnl Guess yes on glibc systems.
+                               # Guess yes on glibc systems.
          *-gnu*)               gl_cv_func_printf_sizes_c99="guessing yes";;
-                               dnl Guess yes on FreeBSD >= 5.
+                               # Guess yes on FreeBSD >= 5.
          freebsd[1-4]*)        gl_cv_func_printf_sizes_c99="guessing no";;
          freebsd* | kfreebsd*) gl_cv_func_printf_sizes_c99="guessing yes";;
-                               dnl Gusss yes on MacOS X >= 10.3.
+                               # Guess yes on MacOS X >= 10.3.
          darwin[1-6].*)        gl_cv_func_printf_sizes_c99="guessing no";;
          darwin*)              gl_cv_func_printf_sizes_c99="guessing yes";;
-                               dnl Guess yes on Solaris >= 2.10.
+                               # Guess yes on OpenBSD >= 3.9.
+         openbsd[1-2].* | openbsd3.[0-8] | openbsd3.[0-8].*)
+                               gl_cv_func_printf_sizes_c99="guessing no";;
+         openbsd*)             gl_cv_func_printf_sizes_c99="guessing yes";;
+                               # Guess yes on Solaris >= 2.10.
          solaris2.[0-9]*)      gl_cv_func_printf_sizes_c99="guessing no";;
          solaris*)             gl_cv_func_printf_sizes_c99="guessing yes";;
-                               dnl Guess yes on NetBSD >= 3.
-         netbsd[1-2]*)         gl_cv_func_printf_sizes_c99="guessing no";;
+                               # Guess yes on NetBSD >= 3.
+         netbsd[1-2]* | netbsdelf[1-2]* | netbsdaout[1-2]* | netbsdcoff[1-2]*)
+                               gl_cv_func_printf_sizes_c99="guessing no";;
          netbsd*)              gl_cv_func_printf_sizes_c99="guessing yes";;
-                               dnl If we don't know, assume the worst.
+                               # If we don't know, assume the worst.
          *)                    gl_cv_func_printf_sizes_c99="guessing no";;
        esac
 changequote([,])dnl
@@ -79,6 +81,49 @@ 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.
+
+AC_DEFUN([gl_PRINTF_LONG_DOUBLE],
+[
+  AC_REQUIRE([AC_PROG_CC])
+  AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
+  AC_CACHE_CHECK([whether printf supports 'long double' arguments],
+    [gl_cv_func_printf_long_double], 
+    [
+      AC_TRY_RUN([
+#include <stdio.h>
+#include <string.h>
+static char buf[100];
+int main ()
+{
+  buf[0] = '\0';
+  if (sprintf (buf, "%Lf %d", 1.75L, 33, 44, 55) < 0
+      || strcmp (buf, "1.750000 33") != 0)
+    return 1;
+  buf[0] = '\0';
+  if (sprintf (buf, "%Le %d", 1.75L, 33, 44, 55) < 0
+      || strcmp (buf, "1.750000e+00 33") != 0)
+    return 1;
+  buf[0] = '\0';
+  if (sprintf (buf, "%Lg %d", 1.75L, 33, 44, 55) < 0
+      || strcmp (buf, "1.75 33") != 0)
+    return 1;
+  return 0;
+}], [gl_cv_func_printf_long_double=yes], [gl_cv_func_printf_long_double=no],
+      [
+changequote(,)dnl
+       case "$host_os" in
+         beos*)        gl_cv_func_printf_long_double="guessing no";;
+         mingw* | pw*) gl_cv_func_printf_long_double="guessing no";;
+         *)            gl_cv_func_printf_long_double="guessing yes";;
+       esac
+changequote([,])dnl
+      ])
+    ])
+])
+
 dnl Test whether the *printf family of functions supports the 'a' and 'A'
 dnl conversion specifier for hexadecimal output of floating-point numbers.
 dnl (ISO C99, POSIX:2001)
@@ -98,27 +143,114 @@ static char buf[100];
 int main ()
 {
   if (sprintf (buf, "%a %d", 3.1416015625, 33, 44, 55) < 0
-      || strcmp (buf, "0x1.922p+1 33") != 0)
+      || (strcmp (buf, "0x1.922p+1 33") != 0
+          && strcmp (buf, "0x3.244p+0 33") != 0
+          && strcmp (buf, "0x6.488p-1 33") != 0
+          && strcmp (buf, "0xc.91p-2 33") != 0))
     return 1;
   if (sprintf (buf, "%A %d", -3.1416015625, 33, 44, 55) < 0
-      || strcmp (buf, "-0X1.922P+1 33") != 0)
+      || (strcmp (buf, "-0X1.922P+1 33") != 0
+          && strcmp (buf, "-0X3.244P+0 33") != 0
+          && strcmp (buf, "-0X6.488P-1 33") != 0
+          && strcmp (buf, "-0XC.91P-2 33") != 0))
+    return 1;
+  /* This catches a FreeBSD 6.1 bug: it doesn't round.  */
+  if (sprintf (buf, "%.2a %d", 1.51, 33, 44, 55) < 0
+      || (strcmp (buf, "0x1.83p+0 33") != 0
+          && strcmp (buf, "0x3.05p-1 33") != 0
+          && strcmp (buf, "0x6.0ap-2 33") != 0
+          && strcmp (buf, "0xc.14p-3 33") != 0))
+    return 1;
+  /* This catches a FreeBSD 6.1 bug.  See
+     <http://lists.gnu.org/archive/html/bug-gnulib/2007-04/msg00107.html> */
+  if (sprintf (buf, "%010a %d", 1.0 / 0.0, 33, 44, 55) < 0
+      || buf[0] == '0')
+    return 1;
+  /* This catches a MacOS X 10.3.9 (Darwin 7.9) bug.  */
+  if (sprintf (buf, "%.1a", 1.999) < 0
+      || (strcmp (buf, "0x1.0p+1") != 0
+          && strcmp (buf, "0x2.0p+0") != 0
+          && strcmp (buf, "0x4.0p-1") != 0
+          && strcmp (buf, "0x8.0p-2") != 0))
+    return 1;
+  /* This catches the same MacOS X 10.3.9 (Darwin 7.9) bug and also a
+     glibc 2.4 bug <http://sourceware.org/bugzilla/show_bug.cgi?id=2908>.  */
+  if (sprintf (buf, "%.1La", 1.999L) < 0
+      || (strcmp (buf, "0x1.0p+1") != 0
+          && strcmp (buf, "0x2.0p+0") != 0
+          && strcmp (buf, "0x4.0p-1") != 0
+          && strcmp (buf, "0x8.0p-2") != 0))
     return 1;
   return 0;
 }], [gl_cv_func_printf_directive_a=yes], [gl_cv_func_printf_directive_a=no],
       [
-changequote(,)dnl
        case "$host_os" in
-                               dnl Guess yes on glibc systems.
-         *-gnu*)               gl_cv_func_printf_directive_a="guessing yes";;
-                               dnl Guess yes on FreeBSD >= 5.
-         freebsd[1-4]*)        gl_cv_func_printf_directive_a="guessing no";;
-         freebsd* | kfreebsd*) gl_cv_func_printf_directive_a="guessing yes";;
-                               dnl Gusss yes on MacOS X >= 10.3.
-         darwin[1-6].*)        gl_cv_func_printf_directive_a="guessing no";;
-         darwin*)              gl_cv_func_printf_directive_a="guessing yes";;
-                               dnl If we don't know, assume the worst.
+                               # Guess yes on glibc >= 2.5 systems.
+         *-gnu*)
+           AC_EGREP_CPP([BZ2908], [
+             #include <features.h>
+             #ifdef __GNU_LIBRARY__
+              #if (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 5) || (__GLIBC__ > 2)
+               BZ2908
+              #endif
+             #endif
+             ],
+             [gl_cv_func_printf_directive_a="guessing yes"],
+             [gl_cv_func_printf_directive_a="guessing no"])
+           ;;
+                               # If we don't know, assume the worst.
          *)                    gl_cv_func_printf_directive_a="guessing no";;
        esac
+      ])
+    ])
+])
+
+dnl Test whether the *printf family of functions supports the %F format
+dnl directive. (ISO C99, POSIX:2001)
+dnl Result is gl_cv_func_printf_directive_f.
+
+AC_DEFUN([gl_PRINTF_DIRECTIVE_F],
+[
+  AC_REQUIRE([AC_PROG_CC])
+  AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
+  AC_CACHE_CHECK([whether printf supports the 'F' directive],
+    [gl_cv_func_printf_directive_f], 
+    [
+      AC_TRY_RUN([
+#include <stdio.h>
+#include <string.h>
+static char buf[100];
+int main ()
+{
+  if (sprintf (buf, "%F %d", 1234567.0, 33, 44, 55) < 0
+      || strcmp (buf, "1234567.000000 33") != 0)
+    return 1;
+  if (sprintf (buf, "%F", 1.0 / 0.0) < 0
+      || (strcmp (buf, "INF") != 0 && strcmp (buf, "INFINITY") != 0))
+    return 1;
+  /* This catches a Cygwin 2007 bug.  */
+  if (sprintf (buf, "%.F", 1234.0) < 0
+      || strcmp (buf, "1234") != 0)
+    return 1;
+  return 0;
+}], [gl_cv_func_printf_directive_f=yes], [gl_cv_func_printf_directive_f=no],
+      [
+changequote(,)dnl
+       case "$host_os" in
+                               # Guess yes on glibc systems.
+         *-gnu*)               gl_cv_func_printf_directive_f="guessing yes";;
+                               # Guess yes on FreeBSD >= 6.
+         freebsd[1-5]*)        gl_cv_func_printf_directive_f="guessing no";;
+         freebsd* | kfreebsd*) gl_cv_func_printf_directive_f="guessing yes";;
+                               # Guess yes on MacOS X >= 10.3.
+         darwin[1-6].*)        gl_cv_func_printf_directive_f="guessing no";;
+         darwin*)              gl_cv_func_printf_directive_f="guessing yes";;
+                               # Guess yes on Solaris >= 2.10.
+         solaris2.[0-9]*)      gl_cv_func_printf_directive_f="guessing no";;
+         solaris*)             gl_cv_func_printf_directive_f="guessing yes";;
+                               # If we don't know, assume the worst.
+         *)                    gl_cv_func_printf_directive_f="guessing no";;
+       esac
 changequote([,])dnl
       ])
     ])
@@ -151,7 +283,6 @@ int main ()
       [
 changequote(,)dnl
        case "$host_os" in
-         hpux*) gl_cv_func_printf_directive_n="guessing no";;
          *)     gl_cv_func_printf_directive_n="guessing yes";;
        esac
 changequote([,])dnl
@@ -185,7 +316,8 @@ int main ()
       [
 changequote(,)dnl
        case "$host_os" in
-         netbsd*)      gl_cv_func_printf_positions="guessing no";;
+         netbsd[1-3]* | netbsdelf[1-3]* | netbsdaout[1-3]* | netbsdcoff[1-3]*)
+                       gl_cv_func_printf_positions="guessing no";;
          beos*)        gl_cv_func_printf_positions="guessing no";;
          mingw* | pw*) gl_cv_func_printf_positions="guessing no";;
          *)            gl_cv_func_printf_positions="guessing yes";;
@@ -195,6 +327,80 @@ changequote([,])dnl
     ])
 ])
 
+dnl Test whether the *printf family of functions supports POSIX/XSI format
+dnl strings with the ' flag for grouping of decimal digits. (POSIX:2001)
+dnl Result is gl_cv_func_printf_flag_grouping.
+
+AC_DEFUN([gl_PRINTF_FLAG_GROUPING],
+[
+  AC_REQUIRE([AC_PROG_CC])
+  AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
+  AC_CACHE_CHECK([whether printf supports the grouping flag],
+    [gl_cv_func_printf_flag_grouping],
+    [
+      AC_TRY_RUN([
+#include <stdio.h>
+#include <string.h>
+static char buf[100];
+int main ()
+{
+  if (sprintf (buf, "%'d %d", 1234567, 99) < 0
+      || buf[strlen (buf) - 1] != '9')
+    return 1;
+  return 0;
+}], [gl_cv_func_printf_flag_grouping=yes], [gl_cv_func_printf_flag_grouping=no],
+      [
+changequote(,)dnl
+       case "$host_os" in
+         cygwin*)      gl_cv_func_printf_flag_grouping="guessing no";;
+         netbsd*)      gl_cv_func_printf_flag_grouping="guessing no";;
+         mingw* | pw*) gl_cv_func_printf_flag_grouping="guessing no";;
+         *)            gl_cv_func_printf_flag_grouping="guessing yes";;
+       esac
+changequote([,])dnl
+      ])
+    ])
+])
+
+dnl Test whether the *printf family of functions supports padding of non-finite
+dnl values with the 0 flag correctly. (ISO C99 + TC1 + TC2.) See
+dnl <http://lists.gnu.org/archive/html/bug-gnulib/2007-04/msg00107.html>
+dnl Result is gl_cv_func_printf_flag_zero.
+
+AC_DEFUN([gl_PRINTF_FLAG_ZERO],
+[
+  AC_REQUIRE([AC_PROG_CC])
+  AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
+  AC_CACHE_CHECK([whether printf supports the zero flag correctly],
+    [gl_cv_func_printf_flag_zero],
+    [
+      AC_TRY_RUN([
+#include <stdio.h>
+#include <string.h>
+static char buf[100];
+int main ()
+{
+  if (sprintf (buf, "%010f", 1.0 / 0.0, 33, 44, 55) < 0
+      || (strcmp (buf, "       inf") != 0
+          && strcmp (buf, "  infinity") != 0))
+    return 1;
+  return 0;
+}], [gl_cv_func_printf_flag_zero=yes], [gl_cv_func_printf_flag_zero=no],
+      [
+changequote(,)dnl
+       case "$host_os" in
+                 # Guess yes on glibc systems.
+         *-gnu*) gl_cv_func_printf_flag_zero="guessing yes";;
+                 # Guess yes on BeOS.
+         beos*)  gl_cv_func_printf_flag_zero="guessing yes";;
+                 # If we don't know, assume the worst.
+         *)      gl_cv_func_printf_flag_zero="guessing no";;
+       esac
+changequote([,])dnl
+      ])
+    ])
+])
+
 dnl Test whether the snprintf function exists. (ISO C99, POSIX:2001)
 dnl Result is ac_cv_func_snprintf.
 
@@ -229,34 +435,39 @@ int main ()
       [
 changequote(,)dnl
        case "$host_os" in
-                               dnl Guess yes on glibc systems.
+                               # Guess yes on glibc systems.
          *-gnu*)               gl_cv_func_snprintf_truncation_c99="guessing yes";;
-                               dnl Guess yes on FreeBSD >= 5.
+                               # Guess yes on FreeBSD >= 5.
          freebsd[1-4]*)        gl_cv_func_snprintf_truncation_c99="guessing no";;
          freebsd* | kfreebsd*) gl_cv_func_snprintf_truncation_c99="guessing yes";;
-                               dnl Gusss yes on MacOS X >= 10.3.
+                               # Guess yes on MacOS X >= 10.3.
          darwin[1-6].*)        gl_cv_func_snprintf_truncation_c99="guessing no";;
          darwin*)              gl_cv_func_snprintf_truncation_c99="guessing yes";;
-                               dnl Guess yes on Solaris >= 2.6.
+                               # Guess yes on OpenBSD >= 3.9.
+         openbsd[1-2].* | openbsd3.[0-8] | openbsd3.[0-8].*)
+                               gl_cv_func_snprintf_truncation_c99="guessing no";;
+         openbsd*)             gl_cv_func_snprintf_truncation_c99="guessing yes";;
+                               # Guess yes on Solaris >= 2.6.
          solaris2.[0-5]*)      gl_cv_func_snprintf_truncation_c99="guessing no";;
          solaris*)             gl_cv_func_snprintf_truncation_c99="guessing yes";;
-                               dnl Guess yes on AIX >= 4.
+                               # Guess yes on AIX >= 4.
          aix[1-3]*)            gl_cv_func_snprintf_truncation_c99="guessing no";;
          aix*)                 gl_cv_func_snprintf_truncation_c99="guessing yes";;
-                               dnl Guess yes on HP-UX >= 11.
+                               # Guess yes on HP-UX >= 11.
          hpux[7-9]* | hpux10*) gl_cv_func_snprintf_truncation_c99="guessing no";;
          hpux*)                gl_cv_func_snprintf_truncation_c99="guessing yes";;
-                               dnl Guess yes on IRIX >= 6.5.
+                               # Guess yes on IRIX >= 6.5.
          irix6.5)              gl_cv_func_snprintf_truncation_c99="guessing yes";;
-                               dnl Guess yes on OSF/1 >= 5.
+                               # Guess yes on OSF/1 >= 5.
          osf[3-4]*)            gl_cv_func_snprintf_truncation_c99="guessing no";;
          osf*)                 gl_cv_func_snprintf_truncation_c99="guessing yes";;
-                               dnl Guess yes on NetBSD >= 3.
-         netbsd[1-2]*)         gl_cv_func_snprintf_truncation_c99="guessing no";;
+                               # Guess yes on NetBSD >= 3.
+         netbsd[1-2]* | netbsdelf[1-2]* | netbsdaout[1-2]* | netbsdcoff[1-2]*)
+                               gl_cv_func_snprintf_truncation_c99="guessing no";;
          netbsd*)              gl_cv_func_snprintf_truncation_c99="guessing yes";;
-                               dnl Guess yes on BeOS.
+                               # Guess yes on BeOS.
          beos*)                gl_cv_func_snprintf_truncation_c99="guessing yes";;
-                               dnl If we don't know, assume the worst.
+                               # If we don't know, assume the worst.
          *)                    gl_cv_func_snprintf_truncation_c99="guessing no";;
        esac
 changequote([,])dnl
@@ -267,14 +478,24 @@ changequote([,])dnl
 dnl Test whether the return value of the snprintf function is the number
 dnl of bytes (excluding the terminating NUL) that would have been produced
 dnl if the buffer had been large enough. (ISO C99, POSIX:2001)
-dnl Result is gl_cv_func_printf_retval_c99.
+dnl For example, this test program fails on IRIX 6.5:
+dnl     ---------------------------------------------------------------------
+dnl     #include <stdio.h>
+dnl     int main()
+dnl     {
+dnl       static char buf[8];
+dnl       int retval = snprintf (buf, 3, "%d", 12345);
+dnl       return retval >= 0 && retval < 3;
+dnl     }
+dnl     ---------------------------------------------------------------------
+dnl Result is gl_cv_func_snprintf_retval_c99.
 
 AC_DEFUN([gl_SNPRINTF_RETVAL_C99],
 [
   AC_REQUIRE([AC_PROG_CC])
   AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
   AC_CACHE_CHECK([whether snprintf returns a byte count as in C99],
-    [gl_cv_func_printf_retval_c99], 
+    [gl_cv_func_snprintf_retval_c99], 
     [
       AC_TRY_RUN([
 #include <stdio.h>
@@ -286,31 +507,195 @@ int main ()
   if (snprintf (buf, 3, "%d %d", 4567, 89) != 7)
     return 1;
   return 0;
-}], [gl_cv_func_printf_retval_c99=yes], [gl_cv_func_printf_retval_c99=no],
+}], [gl_cv_func_snprintf_retval_c99=yes], [gl_cv_func_snprintf_retval_c99=no],
+      [
+changequote(,)dnl
+       case "$host_os" in
+                               # Guess yes on glibc systems.
+         *-gnu*)               gl_cv_func_snprintf_retval_c99="guessing yes";;
+                               # Guess yes on FreeBSD >= 5.
+         freebsd[1-4]*)        gl_cv_func_snprintf_retval_c99="guessing no";;
+         freebsd* | kfreebsd*) gl_cv_func_snprintf_retval_c99="guessing yes";;
+                               # Guess yes on MacOS X >= 10.3.
+         darwin[1-6].*)        gl_cv_func_snprintf_retval_c99="guessing no";;
+         darwin*)              gl_cv_func_snprintf_retval_c99="guessing yes";;
+                               # Guess yes on OpenBSD >= 3.9.
+         openbsd[1-2].* | openbsd3.[0-8] | openbsd3.[0-8].*)
+                               gl_cv_func_snprintf_retval_c99="guessing no";;
+         openbsd*)             gl_cv_func_snprintf_retval_c99="guessing yes";;
+                               # Guess yes on Solaris >= 2.6.
+         solaris2.[0-5]*)      gl_cv_func_snprintf_retval_c99="guessing no";;
+         solaris*)             gl_cv_func_snprintf_retval_c99="guessing yes";;
+                               # Guess yes on AIX >= 4.
+         aix[1-3]*)            gl_cv_func_snprintf_retval_c99="guessing no";;
+         aix*)                 gl_cv_func_snprintf_retval_c99="guessing yes";;
+                               # Guess yes on NetBSD >= 3.
+         netbsd[1-2]* | netbsdelf[1-2]* | netbsdaout[1-2]* | netbsdcoff[1-2]*)
+                               gl_cv_func_snprintf_retval_c99="guessing no";;
+         netbsd*)              gl_cv_func_snprintf_retval_c99="guessing yes";;
+                               # Guess yes on BeOS.
+         beos*)                gl_cv_func_snprintf_retval_c99="guessing yes";;
+                               # If we don't know, assume the worst.
+         *)                    gl_cv_func_snprintf_retval_c99="guessing no";;
+       esac
+changequote([,])dnl
+      ])
+    ])
+])
+
+dnl Test whether the snprintf function supports the %n format directive
+dnl also in truncated portions of the format string. (ISO C99, POSIX:2001)
+dnl Result is gl_cv_func_snprintf_directive_n.
+
+AC_DEFUN([gl_SNPRINTF_DIRECTIVE_N],
+[
+  AC_REQUIRE([AC_PROG_CC])
+  AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
+  AC_CACHE_CHECK([whether snprintf fully supports the 'n' directive],
+    [gl_cv_func_snprintf_directive_n], 
+    [
+      AC_TRY_RUN([
+#include <stdio.h>
+#include <string.h>
+static char buf[100];
+int main ()
+{
+  int count = -1;
+  snprintf (buf, 4, "%d %n", 12345, &count, 33, 44, 55);
+  if (count != 6)
+    return 1;
+  return 0;
+}], [gl_cv_func_snprintf_directive_n=yes], [gl_cv_func_snprintf_directive_n=no],
+      [
+changequote(,)dnl
+       case "$host_os" in
+                               # Guess yes on glibc systems.
+         *-gnu*)               gl_cv_func_snprintf_directive_n="guessing yes";;
+                               # Guess yes on FreeBSD >= 5.
+         freebsd[1-4]*)        gl_cv_func_snprintf_directive_n="guessing no";;
+         freebsd* | kfreebsd*) gl_cv_func_snprintf_directive_n="guessing yes";;
+                               # Guess yes on MacOS X >= 10.3.
+         darwin[1-6].*)        gl_cv_func_snprintf_directive_n="guessing no";;
+         darwin*)              gl_cv_func_snprintf_directive_n="guessing yes";;
+                               # Guess yes on Solaris >= 2.6.
+         solaris2.[0-5]*)      gl_cv_func_snprintf_directive_n="guessing no";;
+         solaris*)             gl_cv_func_snprintf_directive_n="guessing yes";;
+                               # Guess yes on AIX >= 4.
+         aix[1-3]*)            gl_cv_func_snprintf_directive_n="guessing no";;
+         aix*)                 gl_cv_func_snprintf_directive_n="guessing yes";;
+                               # Guess yes on IRIX >= 6.5.
+         irix6.5)              gl_cv_func_snprintf_directive_n="guessing yes";;
+                               # Guess yes on OSF/1 >= 5.
+         osf[3-4]*)            gl_cv_func_snprintf_directive_n="guessing no";;
+         osf*)                 gl_cv_func_snprintf_directive_n="guessing yes";;
+                               # Guess yes on NetBSD >= 3.
+         netbsd[1-2]* | netbsdelf[1-2]* | netbsdaout[1-2]* | netbsdcoff[1-2]*)
+                               gl_cv_func_snprintf_directive_n="guessing no";;
+         netbsd*)              gl_cv_func_snprintf_directive_n="guessing yes";;
+                               # Guess yes on BeOS.
+         beos*)                gl_cv_func_snprintf_directive_n="guessing yes";;
+                               # If we don't know, assume the worst.
+         *)                    gl_cv_func_snprintf_directive_n="guessing no";;
+       esac
+changequote([,])dnl
+      ])
+    ])
+])
+
+dnl Test whether the vsnprintf function, when passed a zero size, produces no
+dnl output. (ISO C99, POSIX:2001)
+dnl For example, snprintf nevertheless writes a NUL byte in this case
+dnl on OSF/1 5.1:
+dnl     ---------------------------------------------------------------------
+dnl     #include <stdio.h>
+dnl     int main()
+dnl     {
+dnl       static char buf[8] = "DEADBEEF";
+dnl       snprintf (buf, 0, "%d", 12345);
+dnl       return buf[0] != 'D';
+dnl     }
+dnl     ---------------------------------------------------------------------
+dnl And vsnprintf writes any output without bounds in this case, behaving like
+dnl vsprintf, on HP-UX 11 and OSF/1 5.1:
+dnl     ---------------------------------------------------------------------
+dnl     #include <stdarg.h>
+dnl     #include <stdio.h>
+dnl     static int my_snprintf (char *buf, int size, const char *format, ...)
+dnl     {
+dnl       va_list args;
+dnl       int ret;
+dnl       va_start (args, format);
+dnl       ret = vsnprintf (buf, size, format, args);
+dnl       va_end (args);
+dnl       return ret;
+dnl     }
+dnl     int main()
+dnl     {
+dnl       static char buf[8] = "DEADBEEF";
+dnl       my_snprintf (buf, 0, "%d", 12345);
+dnl       return buf[0] != 'D';
+dnl     }
+dnl     ---------------------------------------------------------------------
+dnl Result is gl_cv_func_vsnprintf_zerosize_c99.
+
+AC_DEFUN([gl_VSNPRINTF_ZEROSIZE_C99],
+[
+  AC_REQUIRE([AC_PROG_CC])
+  AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
+  AC_CACHE_CHECK([whether vsnprintf respects a zero size as in C99],
+    [gl_cv_func_vsnprintf_zerosize_c99], 
+    [
+      AC_TRY_RUN([
+#include <stdarg.h>
+#include <stdio.h>
+static int my_snprintf (char *buf, int size, const char *format, ...)
+{
+  va_list args;
+  int ret;
+  va_start (args, format);
+  ret = vsnprintf (buf, size, format, args);
+  va_end (args);
+  return ret;
+}
+int main()
+{
+  static char buf[8] = "DEADBEEF";
+  my_snprintf (buf, 0, "%d", 12345);
+  return buf[0] != 'D';
+}],
+      [gl_cv_func_vsnprintf_zerosize_c99=yes],
+      [gl_cv_func_vsnprintf_zerosize_c99=no],
       [
 changequote(,)dnl
        case "$host_os" in
-                               dnl Guess yes on glibc systems.
-         *-gnu*)               gl_cv_func_printf_retval_c99="guessing yes";;
-                               dnl Guess yes on FreeBSD >= 5.
-         freebsd[1-4]*)        gl_cv_func_printf_retval_c99="guessing no";;
-         freebsd* | kfreebsd*) gl_cv_func_printf_retval_c99="guessing yes";;
-                               dnl Gusss yes on MacOS X >= 10.3.
-         darwin[1-6].*)        gl_cv_func_printf_retval_c99="guessing no";;
-         darwin*)              gl_cv_func_printf_retval_c99="guessing yes";;
-                               dnl Guess yes on Solaris >= 2.6.
-         solaris2.[0-5]*)      gl_cv_func_printf_retval_c99="guessing no";;
-         solaris*)             gl_cv_func_printf_retval_c99="guessing yes";;
-                               dnl Guess yes on AIX >= 4.
-         aix[1-3]*)            gl_cv_func_printf_retval_c99="guessing no";;
-         aix*)                 gl_cv_func_printf_retval_c99="guessing yes";;
-                               dnl Guess yes on NetBSD >= 3.
-         netbsd[1-2]*)         gl_cv_func_printf_retval_c99="guessing no";;
-         netbsd*)              gl_cv_func_printf_retval_c99="guessing yes";;
-                               dnl Guess yes on BeOS.
-         beos*)                gl_cv_func_printf_retval_c99="guessing yes";;
-                               dnl If we don't know, assume the worst.
-         *)                    gl_cv_func_printf_retval_c99="guessing no";;
+                               # Guess yes on glibc systems.
+         *-gnu*)               gl_cv_func_vsnprintf_zerosize_c99="guessing yes";;
+                               # Guess yes on FreeBSD >= 5.
+         freebsd[1-4]*)        gl_cv_func_vsnprintf_zerosize_c99="guessing no";;
+         freebsd* | kfreebsd*) gl_cv_func_vsnprintf_zerosize_c99="guessing yes";;
+                               # Guess yes on MacOS X >= 10.3.
+         darwin[1-6].*)        gl_cv_func_vsnprintf_zerosize_c99="guessing no";;
+         darwin*)              gl_cv_func_vsnprintf_zerosize_c99="guessing yes";;
+                               # Guess yes on Cygwin.
+         cygwin*)              gl_cv_func_vsnprintf_zerosize_c99="guessing yes";;
+                               # Guess yes on Solaris >= 2.6.
+         solaris2.[0-5]*)      gl_cv_func_vsnprintf_zerosize_c99="guessing no";;
+         solaris*)             gl_cv_func_vsnprintf_zerosize_c99="guessing yes";;
+                               # Guess yes on AIX >= 4.
+         aix[1-3]*)            gl_cv_func_vsnprintf_zerosize_c99="guessing no";;
+         aix*)                 gl_cv_func_vsnprintf_zerosize_c99="guessing yes";;
+                               # Guess yes on IRIX >= 6.5.
+         irix6.5)              gl_cv_func_vsnprintf_zerosize_c99="guessing yes";;
+                               # Guess yes on NetBSD >= 3.
+         netbsd[1-2]* | netbsdelf[1-2]* | netbsdaout[1-2]* | netbsdcoff[1-2]*)
+                               gl_cv_func_vsnprintf_zerosize_c99="guessing no";;
+         netbsd*)              gl_cv_func_vsnprintf_zerosize_c99="guessing yes";;
+                               # Guess yes on BeOS.
+         beos*)                gl_cv_func_vsnprintf_zerosize_c99="guessing yes";;
+                               # Guess yes on mingw.
+         mingw* | pw*)         gl_cv_func_vsnprintf_zerosize_c99="guessing yes";;
+                               # If we don't know, assume the worst.
+         *)                    gl_cv_func_vsnprintf_zerosize_c99="guessing no";;
        esac
 changequote([,])dnl
       ])
@@ -320,38 +705,54 @@ changequote([,])dnl
 dnl The results of these tests on various platforms are:
 dnl
 dnl 1 = gl_PRINTF_SIZES_C99
-dnl 2 = gl_PRINTF_DIRECTIVE_A
-dnl 3 = gl_PRINTF_DIRECTIVE_N
-dnl 4 = gl_PRINTF_POSITIONS
-dnl 5 = gl_SNPRINTF_PRESENCE
-dnl 6 = gl_SNPRINTF_TRUNCATION_C99
-dnl 7 = gl_SNPRINTF_RETVAL_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
 dnl 1 = checking whether printf supports size specifiers as in C99...
-dnl 2 = checking whether printf supports the 'a' and 'A' directives...
-dnl 3 = checking whether printf supports the 'n' directive...
-dnl 4 = checking whether printf supports POSIX/XSI format strings with positions...
-dnl 5 = checking for snprintf...
-dnl 6 = checking whether snprintf truncates the result as in C99...
-dnl 7 = checking whether snprintf returns a byte count 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
 dnl . = yes, # = no.
 dnl
-dnl                                   1  2  3  4  5  6  7
-dnl   glibc 2.3.6                     .  .  .  .  .  .  .
-dnl   FreeBSD 5.4, 6.1                .  .  .  .  .  .  .
-dnl   MacOS X 10.3.9                  .  .  .  .  .  .  .
-dnl   Cygwin 2007                     .  #  .  .  .  .  .
-dnl   Solaris 10                      .  #  .  .  .  .  .
-dnl   Solaris 2.6 ... 9               #  #  .  .  .  .  .
-dnl   Solaris 2.5.1                   #  #  .  .  #  #  #
-dnl   AIX 4.3.2, 5.1                  #  #  .  .  .  .  .
-dnl   HP-UX 11.31                     .  #  .  .  .  .  #
-dnl   HP-UX 11.00, 11.11, 11.23       #  #  .  .  .  .  #
-dnl   HP-UX 10.20                     #  #  #  ?  .  ?  #
-dnl   IRIX 6.5                        #  #  .  .  .  .  #
-dnl   OSF/1 5.1                       #  #  .  .  .  .  #
-dnl   OSF/1 4.0d                      #  #  .  .  #  #  #
-dnl   NetBSD 3.0                      .  #  .  #  .  .  .
-dnl   BeOS                            #  #  .  #  .  .  .
-dnl   mingw                           #  #  .  #  .  #  #
+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                                #  #  #  #  .  #  #  #  .  #  #  #  .