Work around an incorrect implementation of the 0 flag on most platforms.
authorBruno Haible <bruno@clisp.org>
Sun, 6 May 2007 23:02:10 +0000 (23:02 +0000)
committerBruno Haible <bruno@clisp.org>
Sun, 6 May 2007 23:02:10 +0000 (23:02 +0000)
24 files changed:
ChangeLog
doc/functions/fprintf.texi
doc/functions/printf.texi
doc/functions/snprintf.texi
doc/functions/sprintf.texi
doc/functions/vfprintf.texi
doc/functions/vprintf.texi
doc/functions/vsnprintf.texi
doc/functions/vsprintf.texi
lib/vasnprintf.c
m4/fprintf-posix.m4
m4/printf.m4
m4/snprintf-posix.m4
m4/sprintf-posix.m4
m4/vasnprintf-posix.m4
m4/vasnprintf.m4
m4/vasprintf-posix.m4
m4/vfprintf-posix.m4
m4/vsnprintf-posix.m4
m4/vsprintf-posix.m4
tests/test-snprintf-posix.h
tests/test-sprintf-posix.h
tests/test-vasnprintf-posix.c
tests/test-vasprintf-posix.c

index 3bae344..9ffbae8 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,35 @@
 2007-05-06  Bruno Haible  <bruno@clisp.org>
 
+       * lib/vasnprintf.c (VASNPRINTF) [NEED_PRINTF_FLAG_ZERO]: Perform the
+       padding ourselves for the floating-point directives.
+       * m4/printf.m4 (gl_PRINTF_FLAG_ZERO): New macro.
+       * m4/vasnprintf.m4 (gl_PREREQ_VASNPRINTF_FLAG_ZERO): New macro.
+       * m4/snprintf-posix.m4 (gl_FUNC_SNPRINTF_POSIX): Invoke
+       gl_PRINTF_FLAG_ZERO and test its result. Invoke
+       gl_PREREQ_VASNPRINTF_FLAG_ZERO.
+       * m4/sprintf-posix.m4 (gl_FUNC_SPRINTF_POSIX): Likewise.
+       * m4/fprintf-posix.m4 (gl_FUNC_FPRINTF_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.
+       * tests/test-snprintf-posix.h (test_function): Also check the width
+       and some flags in the %f directive.
+       * tests/test-sprintf-posix.h (test_function): Likewise.
+       * tests/test-vasnprintf-posix.c (test_function): Likewise.
+       * tests/test-vasprintf-posix.c (test_function): Likewise.
+       * doc/functions/fprintf.texi: Update.
+       * doc/functions/printf.texi: Update.
+       * doc/functions/snprintf.texi: Update.
+       * doc/functions/sprintf.texi: Update.
+       * doc/functions/vfprintf.texi: Update.
+       * doc/functions/vprintf.texi: Update.
+       * doc/functions/vsnprintf.texi: Update.
+       * doc/functions/vsprintf.texi: Update.
+
+2007-05-06  Bruno Haible  <bruno@clisp.org>
+
        * lib/vasnprintf.c (VASNPRINTF) [NEED_PRINTF_FLAG_GROUPING]: Don't
        pass the ' flag character to sprintf or snprintf.
        * m4/printf.m4 (gl_PRINTF_FLAG_GROUPING): New macro.
index 476c31c..6619640 100644 (file)
@@ -26,15 +26,15 @@ NetBSD 3.0, mingw, BeOS.
 @item
 This function doesn't support the @code{'} flag on some platforms:
 NetBSD 3.0, mingw.
+@item
+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, mingw.
 @end itemize
 
 Portability problems not fixed by Gnulib:
 @itemize
 @item
-printf @code{"%010f"} of NaN and Infinity yields an incorrect result (padded
-with zeroes) on some platforms:
-FreeBSD 6.0.
-@item
 printf of @samp{long double} numbers is unsupported on some platforms:
 mingw.
 @end itemize
index f794c80..cd76aa9 100644 (file)
@@ -26,15 +26,15 @@ NetBSD 3.0, mingw, BeOS.
 @item
 This function doesn't support the @code{'} flag on some platforms:
 NetBSD 3.0, mingw.
+@item
+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, mingw.
 @end itemize
 
 Portability problems not fixed by Gnulib:
 @itemize
 @item
-printf @code{"%010f"} of NaN and Infinity yields an incorrect result (padded
-with zeroes) on some platforms:
-FreeBSD 6.0.
-@item
 printf of @samp{long double} numbers is unsupported on some platforms:
 mingw.
 @end itemize
index 5a41a67..f7427bb 100644 (file)
@@ -34,6 +34,10 @@ NetBSD 3.0, mingw, BeOS.
 This function doesn't support the @code{'} flag on some platforms:
 NetBSD 3.0, mingw.
 @item
+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, mingw.
+@item
 This function does not truncate the result as specified in C99 on some platforms:
 mingw.
 @item
@@ -51,10 +55,6 @@ OSF/1 5.1.
 Portability problems not fixed by Gnulib:
 @itemize
 @item
-printf @code{"%010f"} of NaN and Infinity yields an incorrect result (padded
-with zeroes) on some platforms:
-FreeBSD 6.0.
-@item
 printf of @samp{long double} numbers is unsupported on some platforms:
 mingw.
 @end itemize
index 0760dd5..30a1273 100644 (file)
@@ -26,15 +26,15 @@ NetBSD 3.0, mingw, BeOS.
 @item
 This function doesn't support the @code{'} flag on some platforms:
 NetBSD 3.0, mingw.
+@item
+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, mingw.
 @end itemize
 
 Portability problems not fixed by Gnulib:
 @itemize
 @item
-printf @code{"%010f"} of NaN and Infinity yields an incorrect result (padded
-with zeroes) on some platforms:
-FreeBSD 6.0.
-@item
 printf of @samp{long double} numbers is unsupported on some platforms:
 mingw.
 @end itemize
index d5eeef2..5010ba2 100644 (file)
@@ -26,15 +26,15 @@ NetBSD 3.0, mingw, BeOS.
 @item
 This function doesn't support the @code{'} flag on some platforms:
 NetBSD 3.0, mingw.
+@item
+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, mingw.
 @end itemize
 
 Portability problems not fixed by Gnulib:
 @itemize
 @item
-printf @code{"%010f"} of NaN and Infinity yields an incorrect result (padded
-with zeroes) on some platforms:
-FreeBSD 6.0.
-@item
 printf of @samp{long double} numbers is unsupported on some platforms:
 mingw.
 @end itemize
index 430dab2..f7b8609 100644 (file)
@@ -26,15 +26,15 @@ NetBSD 3.0, mingw, BeOS.
 @item
 This function doesn't support the @code{'} flag on some platforms:
 NetBSD 3.0, mingw.
+@item
+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, mingw.
 @end itemize
 
 Portability problems not fixed by Gnulib:
 @itemize
 @item
-printf @code{"%010f"} of NaN and Infinity yields an incorrect result (padded
-with zeroes) on some platforms:
-FreeBSD 6.0.
-@item
 printf of @samp{long double} numbers is unsupported on some platforms:
 mingw.
 @end itemize
index 3e61716..4be1bbf 100644 (file)
@@ -34,6 +34,10 @@ NetBSD 3.0, mingw, BeOS.
 This function doesn't support the @code{'} flag on some platforms:
 NetBSD 3.0, mingw.
 @item
+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, mingw.
+@item
 This function does not truncate the result as specified in C99 on some platforms:
 mingw.
 @item
@@ -51,10 +55,6 @@ HP-UX 11, OSF/1 5.1.
 Portability problems not fixed by Gnulib:
 @itemize
 @item
-printf @code{"%010f"} of NaN and Infinity yields an incorrect result (padded
-with zeroes) on some platforms:
-FreeBSD 6.0.
-@item
 printf of @samp{long double} numbers is unsupported on some platforms:
 mingw.
 @end itemize
index 6ec8e1b..8f0d8ec 100644 (file)
@@ -26,15 +26,15 @@ NetBSD 3.0, mingw, BeOS.
 @item
 This function doesn't support the @code{'} flag on some platforms:
 NetBSD 3.0, mingw.
+@item
+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, mingw.
 @end itemize
 
 Portability problems not fixed by Gnulib:
 @itemize
 @item
-printf @code{"%010f"} of NaN and Infinity yields an incorrect result (padded
-with zeroes) on some platforms:
-FreeBSD 6.0.
-@item
 printf of @samp{long double} numbers is unsupported on some platforms:
 mingw.
 @end itemize
index 205200b..45a2199 100644 (file)
@@ -756,42 +756,65 @@ VASNPRINTF (CHAR_T *resultbuf, size_t *lengthp, const CHAR_T *format, va_list ar
            else
              {
                arg_type type = a.arg[dp->arg_index].type;
-               CHAR_T *p;
+               int flags = dp->flags;
+#if !USE_SNPRINTF || NEED_PRINTF_FLAG_ZERO
+               int has_width;
+               size_t width;
+#endif
+#if NEED_PRINTF_FLAG_ZERO
+               int pad_ourselves;
+#else
+#              define pad_ourselves 0
+#endif
+               CHAR_T *fbp;
                unsigned int prefix_count;
                int prefixes[2];
 #if !USE_SNPRINTF
                size_t tmp_length;
                CHAR_T tmpbuf[700];
                CHAR_T *tmp;
+#endif
+
+#if !USE_SNPRINTF || NEED_PRINTF_FLAG_ZERO
+               has_width = 0;
+               width = 0;
+               if (dp->width_start != dp->width_end)
+                 {
+                   if (dp->width_arg_index != ARG_NONE)
+                     {
+                       int arg;
+
+                       if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
+                         abort ();
+                       arg = a.arg[dp->width_arg_index].a.a_int;
+                       if (arg < 0)
+                         {
+                           /* "A negative field width is taken as a '-' flag
+                               followed by a positive field width."  */
+                           flags |= FLAG_LEFT;
+                           width = (unsigned int) (-arg);
+                         }
+                       else
+                         width = arg;
+                     }
+                   else
+                     {
+                       const CHAR_T *digitp = dp->width_start;
+
+                       do
+                         width = xsum (xtimes (width, 10), *digitp++ - '0');
+                       while (digitp != dp->width_end);
+                     }
+                   has_width = 1;
+                 }
+#endif
 
+#if !USE_SNPRINTF
                /* Allocate a temporary buffer of sufficient size for calling
                   sprintf.  */
                {
-                 size_t width;
                  size_t precision;
 
-                 width = 0;
-                 if (dp->width_start != dp->width_end)
-                   {
-                     if (dp->width_arg_index != ARG_NONE)
-                       {
-                         int arg;
-
-                         if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
-                           abort ();
-                         arg = a.arg[dp->width_arg_index].a.a_int;
-                         width = (arg < 0 ? (unsigned int) (-arg) : arg);
-                       }
-                     else
-                       {
-                         const CHAR_T *digitp = dp->width_start;
-
-                         do
-                           width = xsum (xtimes (width, 10), *digitp++ - '0');
-                         while (digitp != dp->width_end);
-                       }
-                   }
-
                  precision = 6;
                  if (dp->precision_start != dp->precision_end)
                    {
@@ -1008,39 +1031,56 @@ VASNPRINTF (CHAR_T *resultbuf, size_t *lengthp, const CHAR_T *format, va_list ar
                  }
 #endif
 
+               /* Decide whether to perform the padding ourselves.  */
+#if NEED_PRINTF_FLAG_ZERO
+               switch (dp->conversion)
+                 {
+                 case 'f': case 'F': case 'e': case 'E': case 'g': case 'G':
+                 case 'a': case 'A':
+                   pad_ourselves = 1;
+                   break;
+                 default:
+                   pad_ourselves = 0;
+                   break;
+                 }
+#endif
+
                /* Construct the format string for calling snprintf or
                   sprintf.  */
-               p = buf;
-               *p++ = '%';
+               fbp = buf;
+               *fbp++ = '%';
 #if NEED_PRINTF_FLAG_GROUPING
                /* The underlying implementation doesn't support the ' flag.
                   Produce no grouping characters in this case; this is
                   acceptable because the grouping is locale dependent.  */
 #else
-               if (dp->flags & FLAG_GROUP)
-                 *p++ = '\'';
+               if (flags & FLAG_GROUP)
+                 *fbp++ = '\'';
 #endif
-               if (dp->flags & FLAG_LEFT)
-                 *p++ = '-';
-               if (dp->flags & FLAG_SHOWSIGN)
-                 *p++ = '+';
-               if (dp->flags & FLAG_SPACE)
-                 *p++ = ' ';
-               if (dp->flags & FLAG_ALT)
-                 *p++ = '#';
-               if (dp->flags & FLAG_ZERO)
-                 *p++ = '0';
-               if (dp->width_start != dp->width_end)
+               if (flags & FLAG_LEFT)
+                 *fbp++ = '-';
+               if (flags & FLAG_SHOWSIGN)
+                 *fbp++ = '+';
+               if (flags & FLAG_SPACE)
+                 *fbp++ = ' ';
+               if (flags & FLAG_ALT)
+                 *fbp++ = '#';
+               if (!pad_ourselves)
                  {
-                   size_t n = dp->width_end - dp->width_start;
-                   memcpy (p, dp->width_start, n * sizeof (CHAR_T));
-                   p += n;
+                   if (flags & FLAG_ZERO)
+                     *fbp++ = '0';
+                   if (dp->width_start != dp->width_end)
+                     {
+                       size_t n = dp->width_end - dp->width_start;
+                       memcpy (fbp, dp->width_start, n * sizeof (CHAR_T));
+                       fbp += n;
+                     }
                  }
                if (dp->precision_start != dp->precision_end)
                  {
                    size_t n = dp->precision_end - dp->precision_start;
-                   memcpy (p, dp->precision_start, n * sizeof (CHAR_T));
-                   p += n;
+                   memcpy (fbp, dp->precision_start, n * sizeof (CHAR_T));
+                   fbp += n;
                  }
 
                switch (type)
@@ -1048,7 +1088,7 @@ VASNPRINTF (CHAR_T *resultbuf, size_t *lengthp, const CHAR_T *format, va_list ar
 #if HAVE_LONG_LONG_INT
                  case TYPE_LONGLONGINT:
                  case TYPE_ULONGLONGINT:
-                   *p++ = 'l';
+                   *fbp++ = 'l';
                    /*FALLTHROUGH*/
 #endif
                  case TYPE_LONGINT:
@@ -1059,31 +1099,31 @@ VASNPRINTF (CHAR_T *resultbuf, size_t *lengthp, const CHAR_T *format, va_list ar
 #if HAVE_WCHAR_T
                  case TYPE_WIDE_STRING:
 #endif
-                   *p++ = 'l';
+                   *fbp++ = 'l';
                    break;
                  case TYPE_LONGDOUBLE:
-                   *p++ = 'L';
+                   *fbp++ = 'L';
                    break;
                  default:
                    break;
                  }
 #if NEED_PRINTF_DIRECTIVE_F
                if (dp->conversion == 'F')
-                 *p = 'f';
+                 *fbp = 'f';
                else
 #endif
-                 *p = dp->conversion;
+                 *fbp = dp->conversion;
 #if USE_SNPRINTF
-               p[1] = '%';
-               p[2] = 'n';
-               p[3] = '\0';
+               fbp[1] = '%';
+               fbp[2] = 'n';
+               fbp[3] = '\0';
 #else
-               p[1] = '\0';
+               fbp[1] = '\0';
 #endif
 
                /* Construct the arguments for calling snprintf or sprintf.  */
                prefix_count = 0;
-               if (dp->width_arg_index != ARG_NONE)
+               if (!pad_ourselves && dp->width_arg_index != ARG_NONE)
                  {
                    if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
                      abort ();
@@ -1288,11 +1328,11 @@ VASNPRINTF (CHAR_T *resultbuf, size_t *lengthp, const CHAR_T *format, va_list ar
                      {
                        /* snprintf() doesn't understand the '%n'
                           directive.  */
-                       if (p[1] != '\0')
+                       if (fbp[1] != '\0')
                          {
                            /* Don't use the '%n' directive; instead, look
                               at the snprintf() return value.  */
-                           p[1] = '\0';
+                           fbp[1] = '\0';
                            continue;
                          }
                        else
@@ -1328,6 +1368,77 @@ VASNPRINTF (CHAR_T *resultbuf, size_t *lengthp, const CHAR_T *format, va_list ar
                        return NULL;
                      }
 
+                   /* Perform padding.  */
+#if NEED_PRINTF_FLAG_ZERO
+                   if (pad_ourselves && has_width && count < width)
+                     {
+# if USE_SNPRINTF
+                       /* Make room for the result.  */
+                       if (width >= maxlen)
+                         {
+                           /* Need at least width bytes.  But allocate
+                              proportionally, to avoid looping eternally if
+                              snprintf() reports a too small count.  */
+                           size_t n =
+                             xmax (xsum (length, width),
+                                   xtimes (allocated, 2));
+
+                           length += count;
+                           ENSURE_ALLOCATION (n);
+                           length -= count;
+                           maxlen = allocated - length; /* >= width */
+                         }
+# endif
+                       {
+# if USE_SNPRINTF
+                         CHAR_T * const rp = result + length;
+# else
+                         CHAR_T * const rp = tmp;
+# endif
+                         CHAR_T *p = rp + count;
+                         size_t pad = width - count;
+                         CHAR_T *end = p + pad;
+                         CHAR_T *pad_ptr = (*rp == '-' ? rp + 1 : rp);
+                         /* No zero-padding of "inf" and "nan".  */
+                         if ((*pad_ptr >= 'A' && *pad_ptr <= 'Z')
+                             || (*pad_ptr >= 'a' && *pad_ptr <= 'z'))
+                           pad_ptr = NULL;
+                         /* The generated string now extends from rp to p,
+                            with the zero padding insertion point being at
+                            pad_ptr.  */
+
+                         if (flags & FLAG_LEFT)
+                           {
+                             /* Pad with spaces on the right.  */
+                             for (; pad > 0; pad--)
+                               *p++ = ' ';
+                           }
+                         else if ((flags & FLAG_ZERO) && pad_ptr != NULL)
+                           {
+                             /* Pad with zeroes.  */
+                             CHAR_T *q = end;
+
+                             while (p > pad_ptr)
+                               *--q = *--p;
+                             for (; pad > 0; pad--)
+                               *p++ = '0';
+                           }
+                         else
+                           {
+                             /* Pad with spaces on the left.  */
+                             CHAR_T *q = end;
+
+                             while (p > rp)
+                               *--q = *--p;
+                             for (; pad > 0; pad--)
+                               *p++ = ' ';
+                           }
+
+                         count = width; /* = count + pad = end - rp */
+                       }
+                     }
+#endif
+
 #if !USE_SNPRINTF
                    if (count >= tmp_length)
                      /* tmp_length was incorrectly calculated - fix the
index c638158..064527b 100644 (file)
@@ -1,4 +1,4 @@
-# fprintf-posix.m4 serial 4
+# fprintf-posix.m4 serial 5
 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,
@@ -13,6 +13,7 @@ AC_DEFUN([gl_FUNC_FPRINTF_POSIX],
   AC_REQUIRE([gl_PRINTF_DIRECTIVE_N])
   AC_REQUIRE([gl_PRINTF_POSITIONS])
   AC_REQUIRE([gl_PRINTF_FLAG_GROUPING])
+  AC_REQUIRE([gl_PRINTF_FLAG_ZERO])
   gl_cv_func_fprintf_posix=no
   case "$gl_cv_func_printf_sizes_c99" in
     *yes)
@@ -26,8 +27,12 @@ AC_DEFUN([gl_FUNC_FPRINTF_POSIX],
                     *yes)
                       case "$gl_cv_func_printf_flag_grouping" in
                         *yes)
-                          # fprintf exists and is already POSIX compliant.
-                          gl_cv_func_fprintf_posix=yes
+                          case "$gl_cv_func_printf_flag_zero" in
+                            *yes)
+                              # fprintf exists and is already POSIX compliant.
+                              gl_cv_func_fprintf_posix=yes
+                              ;;
+                          esac
                           ;;
                       esac
                       ;;
@@ -44,6 +49,7 @@ AC_DEFUN([gl_FUNC_FPRINTF_POSIX],
     gl_PREREQ_VASNPRINTF_DIRECTIVE_A
     gl_PREREQ_VASNPRINTF_DIRECTIVE_F
     gl_PREREQ_VASNPRINTF_FLAG_GROUPING
+    gl_PREREQ_VASNPRINTF_FLAG_ZERO
     gl_REPLACE_VASNPRINTF
     gl_REPLACE_FPRINTF
   fi
index e09c9d8..d1d6fe6 100644 (file)
@@ -1,4 +1,4 @@
-# printf.m4 serial 8
+# printf.m4 serial 9
 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,
@@ -318,6 +318,45 @@ 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.
 
@@ -625,11 +664,12 @@ dnl 3 = gl_PRINTF_DIRECTIVE_F
 dnl 4 = gl_PRINTF_DIRECTIVE_N
 dnl 5 = gl_PRINTF_POSITIONS
 dnl 6 = gl_PRINTF_FLAG_GROUPING
-dnl 7 = gl_SNPRINTF_PRESENCE
-dnl 8 = gl_SNPRINTF_TRUNCATION_C99
-dnl 9 = gl_SNPRINTF_RETVAL_C99
-dnl 10 = gl_SNPRINTF_DIRECTIVE_N
-dnl 11 = gl_VSNPRINTF_ZEROSIZE_C99
+dnl 7 = gl_PRINTF_FLAG_ZERO
+dnl 8 = gl_SNPRINTF_PRESENCE
+dnl 9 = gl_SNPRINTF_TRUNCATION_C99
+dnl 10 = gl_SNPRINTF_RETVAL_C99
+dnl 11 = gl_SNPRINTF_DIRECTIVE_N
+dnl 12 = 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...
@@ -637,33 +677,34 @@ dnl 3 = checking whether printf supports the 'F' directive...
 dnl 4 = checking whether printf supports the 'n' directive...
 dnl 5 = checking whether printf supports POSIX/XSI format strings with positions...
 dnl 6 = checking whether printf supports the grouping flag...
-dnl 7 = checking for snprintf...
-dnl 8 = checking whether snprintf truncates the result as in C99...
-dnl 9 = checking whether snprintf returns a byte count as in C99...
-dnl 10 = checking whether snprintf fully supports the 'n' directive...
-dnl 11 = checking whether vsnprintf respects a zero size as in C99...
+dnl 7 = checking whether printf supports the zero flag correctly...
+dnl 8 = checking for snprintf...
+dnl 9 = checking whether snprintf truncates the result as in C99...
+dnl 10 = checking whether snprintf returns a byte count as in C99...
+dnl 11 = checking whether snprintf fully supports the 'n' directive...
+dnl 12 = 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
-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                          .  #  #  .  .  ?  .  .  .  .  ?
-dnl   Cygwin 2006                          #  #  #  .  .  ?  .  .  .  .  ?
-dnl   Solaris 10                           .  #  .  .  .  .  .  .  .  .  .
-dnl   Solaris 2.6 ... 9                    #  #  #  .  .  .  .  .  .  .  .
-dnl   Solaris 2.5.1                        #  #  #  .  .  .  #  #  #  #  #
-dnl   AIX 5.2                              .  #  .  .  .  .  .  .  .  .  .
-dnl   AIX 4.3.2, 5.1                       #  #  #  .  .  .  .  .  .  .  .
-dnl   HP-UX 11.31                          .  #  .  .  .  .  .  .  #  #  .
-dnl   HP-UX 10.20, 11.00, 11.11, 11.23     #  #  #  .  .  .  .  .  #  #  #
-dnl   IRIX 6.5                             #  #  #  .  .  .  .  .  #  .  .
-dnl   OSF/1 5.1                            #  #  #  .  .  .  .  .  #  .  #
-dnl   OSF/1 4.0d                           #  #  #  .  .  .  #  #  #  #  #
-dnl   NetBSD 4.0                           .  ?  ?  .  .  ?  .  .  .  ?  ?
-dnl   NetBSD 3.0                           .  #  #  .  #  #  .  .  .  .  .
-dnl   BeOS                                 #  #  #  .  #  .  .  .  .  .  .
-dnl   mingw                                #  #  #  .  #  #  .  #  #  #  .
+dnl                                        1  2  3  4  5  6  7  8  9 10 11 12
+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                          .  #  #  .  .  ?  ?  .  .  .  .  ?
+dnl   Cygwin 2006                          #  #  #  .  .  ?  ?  .  .  .  .  ?
+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                                #  #  #  .  #  #  #  .  #  #  #  .
index 6208adc..e32e408 100644 (file)
@@ -1,4 +1,4 @@
-# snprintf-posix.m4 serial 5
+# snprintf-posix.m4 serial 6
 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,
@@ -13,6 +13,7 @@ AC_DEFUN([gl_FUNC_SNPRINTF_POSIX],
   AC_REQUIRE([gl_PRINTF_DIRECTIVE_N])
   AC_REQUIRE([gl_PRINTF_POSITIONS])
   AC_REQUIRE([gl_PRINTF_FLAG_GROUPING])
+  AC_REQUIRE([gl_PRINTF_FLAG_ZERO])
   gl_cv_func_snprintf_posix=no
   AC_CHECK_FUNCS([snprintf])
   if test $ac_cv_func_snprintf = yes; then
@@ -32,17 +33,21 @@ AC_DEFUN([gl_FUNC_SNPRINTF_POSIX],
                       *yes)
                         case "$gl_cv_func_printf_flag_grouping" in
                           *yes)
-                            case "$gl_cv_func_snprintf_truncation_c99" in
+                            case "$gl_cv_func_printf_flag_zero" in
                               *yes)
-                                case "$gl_cv_func_snprintf_retval_c99" in
+                                case "$gl_cv_func_snprintf_truncation_c99" in
                                   *yes)
-                                    case "$gl_cv_func_snprintf_directive_n" in
+                                    case "$gl_cv_func_snprintf_retval_c99" in
                                       *yes)
-                                        case "$gl_cv_func_vsnprintf_zerosize_c99" in
+                                        case "$gl_cv_func_snprintf_directive_n" in
                                           *yes)
-                                            # snprintf exists and is already
-                                            # POSIX compliant.
-                                            gl_cv_func_snprintf_posix=yes
+                                            case "$gl_cv_func_vsnprintf_zerosize_c99" in
+                                              *yes)
+                                                # snprintf exists and is already
+                                                # POSIX compliant.
+                                                gl_cv_func_snprintf_posix=yes
+                                                ;;
+                                            esac
                                             ;;
                                         esac
                                         ;;
@@ -68,6 +73,7 @@ AC_DEFUN([gl_FUNC_SNPRINTF_POSIX],
     gl_PREREQ_VASNPRINTF_DIRECTIVE_A
     gl_PREREQ_VASNPRINTF_DIRECTIVE_F
     gl_PREREQ_VASNPRINTF_FLAG_GROUPING
+    gl_PREREQ_VASNPRINTF_FLAG_ZERO
     gl_REPLACE_VASNPRINTF
     gl_REPLACE_SNPRINTF
   fi
index bb354d1..7aadf07 100644 (file)
@@ -1,4 +1,4 @@
-# sprintf-posix.m4 serial 4
+# sprintf-posix.m4 serial 5
 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,
@@ -13,6 +13,7 @@ AC_DEFUN([gl_FUNC_SPRINTF_POSIX],
   AC_REQUIRE([gl_PRINTF_DIRECTIVE_N])
   AC_REQUIRE([gl_PRINTF_POSITIONS])
   AC_REQUIRE([gl_PRINTF_FLAG_GROUPING])
+  AC_REQUIRE([gl_PRINTF_FLAG_ZERO])
   gl_cv_func_sprintf_posix=no
   case "$gl_cv_func_printf_sizes_c99" in
     *yes)
@@ -26,8 +27,12 @@ AC_DEFUN([gl_FUNC_SPRINTF_POSIX],
                     *yes)
                       case "$gl_cv_func_printf_flag_grouping" in
                         *yes)
-                          # sprintf exists and is already POSIX compliant.
-                          gl_cv_func_sprintf_posix=yes
+                          case "$gl_cv_func_printf_flag_zero" in
+                            *yes)
+                              # sprintf exists and is already POSIX compliant.
+                              gl_cv_func_sprintf_posix=yes
+                              ;;
+                          esac
                           ;;
                       esac
                       ;;
@@ -44,6 +49,7 @@ AC_DEFUN([gl_FUNC_SPRINTF_POSIX],
     gl_PREREQ_VASNPRINTF_DIRECTIVE_A
     gl_PREREQ_VASNPRINTF_DIRECTIVE_F
     gl_PREREQ_VASNPRINTF_FLAG_GROUPING
+    gl_PREREQ_VASNPRINTF_FLAG_ZERO
     gl_REPLACE_VASNPRINTF
     gl_REPLACE_SPRINTF
   fi
index 34eee29..68634bf 100644 (file)
@@ -1,4 +1,4 @@
-# vasnprintf-posix.m4 serial 5
+# vasnprintf-posix.m4 serial 6
 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,
@@ -13,6 +13,7 @@ AC_DEFUN([gl_FUNC_VASNPRINTF_POSIX],
   AC_REQUIRE([gl_PRINTF_DIRECTIVE_N])
   AC_REQUIRE([gl_PRINTF_POSITIONS])
   AC_REQUIRE([gl_PRINTF_FLAG_GROUPING])
+  AC_REQUIRE([gl_PRINTF_FLAG_ZERO])
   gl_cv_func_vasnprintf_posix=no
   AC_CHECK_FUNCS_ONCE([vasnprintf])
   case "$gl_cv_func_printf_sizes_c99" in
@@ -27,10 +28,15 @@ AC_DEFUN([gl_FUNC_VASNPRINTF_POSIX],
                     *yes)
                       case "$gl_cv_func_printf_flag_grouping" in
                         *yes)
-                          if test $ac_cv_func_vasnprintf = yes; then
-                            # vasnprintf exists and is already POSIX compliant.
-                            gl_cv_func_vasnprintf_posix=yes
-                          fi
+                          case "$gl_cv_func_printf_flag_zero" in
+                            *yes)
+                              if test $ac_cv_func_vasnprintf = yes; then
+                                # vasnprintf exists and is already POSIX
+                                # compliant.
+                                gl_cv_func_vasnprintf_posix=yes
+                              fi
+                              ;;
+                          esac
                           ;;
                       esac
                       ;;
@@ -47,6 +53,7 @@ AC_DEFUN([gl_FUNC_VASNPRINTF_POSIX],
     gl_PREREQ_VASNPRINTF_DIRECTIVE_A
     gl_PREREQ_VASNPRINTF_DIRECTIVE_F
     gl_PREREQ_VASNPRINTF_FLAG_GROUPING
+    gl_PREREQ_VASNPRINTF_FLAG_ZERO
     gl_REPLACE_VASNPRINTF
   fi
 ])
index 773c92f..41a5ce1 100644 (file)
@@ -1,4 +1,4 @@
-# vasnprintf.m4 serial 14
+# vasnprintf.m4 serial 15
 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,
@@ -105,6 +105,21 @@ AC_DEFUN([gl_PREREQ_VASNPRINTF_FLAG_GROUPING],
   esac
 ])
 
+# Extra prerequisites of lib/vasnprintf.c for supporting the 0 flag.
+AC_DEFUN([gl_PREREQ_VASNPRINTF_FLAG_ZERO],
+[
+  AC_REQUIRE([gl_PRINTF_FLAG_ZERO])
+  case "$gl_cv_func_printf_flag_zero" in
+    *yes)
+      ;;
+    *)
+      AC_DEFINE([NEED_PRINTF_FLAG_ZERO], 1,
+        [Define if the vasnprintf implementation needs special code for the
+         0 flag.])
+      ;;
+  esac
+])
+
 # Prerequisites of lib/asnprintf.c.
 AC_DEFUN([gl_PREREQ_ASNPRINTF],
 [
index 4315163..6cec101 100644 (file)
@@ -1,4 +1,4 @@
-# vasprintf-posix.m4 serial 5
+# vasprintf-posix.m4 serial 6
 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,
@@ -13,6 +13,7 @@ AC_DEFUN([gl_FUNC_VASPRINTF_POSIX],
   AC_REQUIRE([gl_PRINTF_DIRECTIVE_N])
   AC_REQUIRE([gl_PRINTF_POSITIONS])
   AC_REQUIRE([gl_PRINTF_FLAG_GROUPING])
+  AC_REQUIRE([gl_PRINTF_FLAG_ZERO])
   gl_cv_func_vasprintf_posix=no
   AC_CHECK_FUNCS([vasprintf])
   case "$gl_cv_func_printf_sizes_c99" in
@@ -27,10 +28,15 @@ AC_DEFUN([gl_FUNC_VASPRINTF_POSIX],
                     *yes)
                       case "$gl_cv_func_printf_flag_grouping" in
                         *yes)
-                          if test $ac_cv_func_vasprintf = yes; then
-                            # vasprintf exists and is already POSIX compliant.
-                            gl_cv_func_vasprintf_posix=yes
-                          fi
+                          case "$gl_cv_func_printf_flag_zero" in
+                            *yes)
+                              if test $ac_cv_func_vasprintf = yes; then
+                                # vasprintf exists and is already POSIX
+                                # compliant.
+                                gl_cv_func_vasprintf_posix=yes
+                              fi
+                              ;;
+                          esac
                           ;;
                       esac
                       ;;
@@ -47,6 +53,7 @@ AC_DEFUN([gl_FUNC_VASPRINTF_POSIX],
     gl_PREREQ_VASNPRINTF_DIRECTIVE_A
     gl_PREREQ_VASNPRINTF_DIRECTIVE_F
     gl_PREREQ_VASNPRINTF_FLAG_GROUPING
+    gl_PREREQ_VASNPRINTF_FLAG_ZERO
     gl_REPLACE_VASNPRINTF
     gl_REPLACE_VASPRINTF
   fi
index 669ae20..60098a2 100644 (file)
@@ -1,4 +1,4 @@
-# vfprintf-posix.m4 serial 4
+# vfprintf-posix.m4 serial 5
 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,
@@ -13,6 +13,7 @@ AC_DEFUN([gl_FUNC_VFPRINTF_POSIX],
   AC_REQUIRE([gl_PRINTF_DIRECTIVE_N])
   AC_REQUIRE([gl_PRINTF_POSITIONS])
   AC_REQUIRE([gl_PRINTF_FLAG_GROUPING])
+  AC_REQUIRE([gl_PRINTF_FLAG_ZERO])
   gl_cv_func_vfprintf_posix=no
   case "$gl_cv_func_printf_sizes_c99" in
     *yes)
@@ -26,8 +27,12 @@ AC_DEFUN([gl_FUNC_VFPRINTF_POSIX],
                     *yes)
                       case "$gl_cv_func_printf_flag_grouping" in
                         *yes)
-                          # vfprintf exists and is already POSIX compliant.
-                          gl_cv_func_vfprintf_posix=yes
+                          case "$gl_cv_func_printf_flag_zero" in
+                            *yes)
+                              # vfprintf exists and is already POSIX compliant.
+                              gl_cv_func_vfprintf_posix=yes
+                              ;;
+                          esac
                           ;;
                       esac
                       ;;
@@ -44,6 +49,7 @@ AC_DEFUN([gl_FUNC_VFPRINTF_POSIX],
     gl_PREREQ_VASNPRINTF_DIRECTIVE_A
     gl_PREREQ_VASNPRINTF_DIRECTIVE_F
     gl_PREREQ_VASNPRINTF_FLAG_GROUPING
+    gl_PREREQ_VASNPRINTF_FLAG_ZERO
     gl_REPLACE_VASNPRINTF
     gl_REPLACE_VFPRINTF
   fi
index 941cf51..29af67f 100644 (file)
@@ -1,4 +1,4 @@
-# vsnprintf-posix.m4 serial 5
+# vsnprintf-posix.m4 serial 6
 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,
@@ -13,6 +13,7 @@ AC_DEFUN([gl_FUNC_VSNPRINTF_POSIX],
   AC_REQUIRE([gl_PRINTF_DIRECTIVE_N])
   AC_REQUIRE([gl_PRINTF_POSITIONS])
   AC_REQUIRE([gl_PRINTF_FLAG_GROUPING])
+  AC_REQUIRE([gl_PRINTF_FLAG_ZERO])
   gl_cv_func_vsnprintf_posix=no
   AC_CHECK_FUNCS([vsnprintf])
   if test $ac_cv_func_vsnprintf = yes; then
@@ -33,17 +34,21 @@ AC_DEFUN([gl_FUNC_VSNPRINTF_POSIX],
                       *yes)
                         case "$gl_cv_func_printf_flag_grouping" in
                           *yes)
-                            case "$gl_cv_func_snprintf_truncation_c99" in
+                            case "$gl_cv_func_printf_flag_zero" in
                               *yes)
-                                case "$gl_cv_func_snprintf_retval_c99" in
+                                case "$gl_cv_func_snprintf_truncation_c99" in
                                   *yes)
-                                    case "$gl_cv_func_snprintf_directive_n" in
+                                    case "$gl_cv_func_snprintf_retval_c99" in
                                       *yes)
-                                        case "$gl_cv_func_vsnprintf_zerosize_c99" in
+                                        case "$gl_cv_func_snprintf_directive_n" in
                                           *yes)
-                                            # vsnprintf exists and is already
-                                            # POSIX compliant.
-                                            gl_cv_func_vsnprintf_posix=yes
+                                            case "$gl_cv_func_vsnprintf_zerosize_c99" in
+                                              *yes)
+                                                # vsnprintf exists and is
+                                                # already POSIX compliant.
+                                                gl_cv_func_vsnprintf_posix=yes
+                                                ;;
+                                            esac
                                             ;;
                                         esac
                                         ;;
@@ -69,6 +74,7 @@ AC_DEFUN([gl_FUNC_VSNPRINTF_POSIX],
     gl_PREREQ_VASNPRINTF_DIRECTIVE_A
     gl_PREREQ_VASNPRINTF_DIRECTIVE_F
     gl_PREREQ_VASNPRINTF_FLAG_GROUPING
+    gl_PREREQ_VASNPRINTF_FLAG_ZERO
     gl_REPLACE_VASNPRINTF
     gl_REPLACE_VSNPRINTF
   fi
index 626da1e..9507d81 100644 (file)
@@ -1,4 +1,4 @@
-# vsprintf-posix.m4 serial 4
+# vsprintf-posix.m4 serial 5
 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,
@@ -13,6 +13,7 @@ AC_DEFUN([gl_FUNC_VSPRINTF_POSIX],
   AC_REQUIRE([gl_PRINTF_DIRECTIVE_N])
   AC_REQUIRE([gl_PRINTF_POSITIONS])
   AC_REQUIRE([gl_PRINTF_FLAG_GROUPING])
+  AC_REQUIRE([gl_PRINTF_FLAG_ZERO])
   gl_cv_func_vsprintf_posix=no
   case "$gl_cv_func_printf_sizes_c99" in
     *yes)
@@ -26,8 +27,12 @@ AC_DEFUN([gl_FUNC_VSPRINTF_POSIX],
                     *yes)
                       case "$gl_cv_func_printf_flag_grouping" in
                         *yes)
-                          # vsprintf exists and is already POSIX compliant.
-                          gl_cv_func_vsprintf_posix=yes
+                          case "$gl_cv_func_printf_flag_zero" in
+                            *yes)
+                              # vsprintf exists and is already POSIX compliant.
+                              gl_cv_func_vsprintf_posix=yes
+                              ;;
+                          esac
                           ;;
                       esac
                       ;;
@@ -44,6 +49,7 @@ AC_DEFUN([gl_FUNC_VSPRINTF_POSIX],
     gl_PREREQ_VASNPRINTF_DIRECTIVE_A
     gl_PREREQ_VASNPRINTF_DIRECTIVE_F
     gl_PREREQ_VASNPRINTF_FLAG_GROUPING
+    gl_PREREQ_VASNPRINTF_FLAG_ZERO
     gl_REPLACE_VASNPRINTF
     gl_REPLACE_VSPRINTF
   fi
index 7b1370b..8803edf 100644 (file)
@@ -683,7 +683,61 @@ test_function (int (*my_snprintf) (char *, size_t, const char *, ...))
     ASSERT (retval == strlen (result));
   }
 
-  { /* FLAG_ZERO.  */
+  { /* Width.  */
+    char result[100];
+    int retval =
+      my_snprintf (result, sizeof (result), "%10f %d", 1.75, 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (strcmp (result, "  1.750000 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  { /* FLAG_LEFT.  */
+    char result[100];
+    int retval =
+      my_snprintf (result, sizeof (result), "%-10f %d", 1.75, 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (strcmp (result, "1.750000   33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  { /* FLAG_SHOWSIGN.  */
+    char result[100];
+    int retval =
+      my_snprintf (result, sizeof (result), "%+f %d", 1.75, 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (strcmp (result, "+1.750000 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  { /* FLAG_SPACE.  */
+    char result[100];
+    int retval =
+      my_snprintf (result, sizeof (result), "% f %d", 1.75, 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (strcmp (result, " 1.750000 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  { /* FLAG_ALT.  */
+    char result[100];
+    int retval =
+      my_snprintf (result, sizeof (result), "%#f %d", 1.75, 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (strcmp (result, "1.750000 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  { /* FLAG_ALT.  */
+    char result[100];
+    int retval =
+      my_snprintf (result, sizeof (result), "%#.f %d", 1.75, 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (strcmp (result, "2. 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  { /* FLAG_ZERO with finite number.  */
     char result[100];
     int retval =
       my_snprintf (result, sizeof (result), "%015f %d", 1234.0, 33, 44, 55);
@@ -700,6 +754,14 @@ test_function (int (*my_snprintf) (char *, size_t, const char *, ...))
     ASSERT (retval == strlen (result));
   }
 
+  { /* FLAG_ZERO with NaN.  */
+    char result[100];
+    int retval =
+      my_snprintf (result, sizeof (result), "%015f %d", NaN (), 33, 44, 55);
+    ASSERT (strcmp (result, "            nan 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
   { /* Precision.  */
     char result[100];
     int retval =
@@ -775,7 +837,61 @@ test_function (int (*my_snprintf) (char *, size_t, const char *, ...))
     ASSERT (retval == strlen (result));
   }
 
-  { /* FLAG_ZERO.  */
+  { /* Width.  */
+    char result[100];
+    int retval =
+      my_snprintf (result, sizeof (result), "%10Lf %d", 1.75L, 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (strcmp (result, "  1.750000 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  { /* FLAG_LEFT.  */
+    char result[100];
+    int retval =
+      my_snprintf (result, sizeof (result), "%-10Lf %d", 1.75L, 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (strcmp (result, "1.750000   33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  { /* FLAG_SHOWSIGN.  */
+    char result[100];
+    int retval =
+      my_snprintf (result, sizeof (result), "%+Lf %d", 1.75L, 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (strcmp (result, "+1.750000 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  { /* FLAG_SPACE.  */
+    char result[100];
+    int retval =
+      my_snprintf (result, sizeof (result), "% Lf %d", 1.75L, 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (strcmp (result, " 1.750000 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  { /* FLAG_ALT.  */
+    char result[100];
+    int retval =
+      my_snprintf (result, sizeof (result), "%#Lf %d", 1.75L, 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (strcmp (result, "1.750000 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  { /* FLAG_ALT.  */
+    char result[100];
+    int retval =
+      my_snprintf (result, sizeof (result), "%#.Lf %d", 1.75L, 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (strcmp (result, "2. 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  { /* FLAG_ZERO with finite number.  */
     char result[100];
     int retval =
       my_snprintf (result, sizeof (result), "%015Lf %d", 1234.0L, 33, 44, 55);
@@ -792,6 +908,15 @@ test_function (int (*my_snprintf) (char *, size_t, const char *, ...))
     ASSERT (retval == strlen (result));
   }
 
+  { /* FLAG_ZERO with NaN.  */
+    static long double zero = 0.0L;
+    char result[100];
+    int retval =
+      my_snprintf (result, sizeof (result), "%015Lf %d", zero / zero, 33, 44, 55);
+    ASSERT (strcmp (result, "            nan 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
   { /* Precision.  */
     char result[100];
     int retval =
index f6d70e6..2de6d0f 100644 (file)
@@ -669,7 +669,55 @@ test_function (int (*my_sprintf) (char *, const char *, ...))
     ASSERT (retval == strlen (result));
   }
 
-  { /* FLAG_ZERO.  */
+  { /* Width.  */
+    char result[1000];
+    int retval =
+      my_sprintf (result, "%10f %d", 1.75, 33, 44, 55);
+    ASSERT (strcmp (result, "  1.750000 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  { /* FLAG_LEFT.  */
+    char result[1000];
+    int retval =
+      my_sprintf (result, "%-10f %d", 1.75, 33, 44, 55);
+    ASSERT (strcmp (result, "1.750000   33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  { /* FLAG_SHOWSIGN.  */
+    char result[1000];
+    int retval =
+      my_sprintf (result, "%+f %d", 1.75, 33, 44, 55);
+    ASSERT (strcmp (result, "+1.750000 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  { /* FLAG_SPACE.  */
+    char result[1000];
+    int retval =
+      my_sprintf (result, "% f %d", 1.75, 33, 44, 55);
+    ASSERT (strcmp (result, " 1.750000 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  { /* FLAG_ALT.  */
+    char result[1000];
+    int retval =
+      my_sprintf (result, "%#f %d", 1.75, 33, 44, 55);
+    ASSERT (strcmp (result, "1.750000 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  { /* FLAG_ALT.  */
+    char result[1000];
+    int retval =
+      my_sprintf (result, "%#.f %d", 1.75, 33, 44, 55);
+    ASSERT (strcmp (result, "2. 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  { /* FLAG_ZERO with finite number.  */
     char result[1000];
     int retval =
       my_sprintf (result, "%015f %d", 1234.0, 33, 44, 55);
@@ -686,6 +734,14 @@ test_function (int (*my_sprintf) (char *, const char *, ...))
     ASSERT (retval == strlen (result));
   }
 
+  { /* FLAG_ZERO with NaN.  */
+    char result[1000];
+    int retval =
+      my_sprintf (result, "%015f %d", NaN (), 33, 44, 55);
+    ASSERT (strcmp (result, "            nan 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
   { /* Precision.  */
     char result[1000];
     int retval =
@@ -761,7 +817,55 @@ test_function (int (*my_sprintf) (char *, const char *, ...))
     ASSERT (retval == strlen (result));
   }
 
-  { /* FLAG_ZERO.  */
+  { /* Width.  */
+    char result[1000];
+    int retval =
+      my_sprintf (result, "%10Lf %d", 1.75L, 33, 44, 55);
+    ASSERT (strcmp (result, "  1.750000 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  { /* FLAG_LEFT.  */
+    char result[1000];
+    int retval =
+      my_sprintf (result, "%-10Lf %d", 1.75L, 33, 44, 55);
+    ASSERT (strcmp (result, "1.750000   33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  { /* FLAG_SHOWSIGN.  */
+    char result[1000];
+    int retval =
+      my_sprintf (result, "%+Lf %d", 1.75L, 33, 44, 55);
+    ASSERT (strcmp (result, "+1.750000 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  { /* FLAG_SPACE.  */
+    char result[1000];
+    int retval =
+      my_sprintf (result, "% Lf %d", 1.75L, 33, 44, 55);
+    ASSERT (strcmp (result, " 1.750000 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  { /* FLAG_ALT.  */
+    char result[1000];
+    int retval =
+      my_sprintf (result, "%#Lf %d", 1.75L, 33, 44, 55);
+    ASSERT (strcmp (result, "1.750000 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  { /* FLAG_ALT.  */
+    char result[1000];
+    int retval =
+      my_sprintf (result, "%#.Lf %d", 1.75L, 33, 44, 55);
+    ASSERT (strcmp (result, "2. 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  { /* FLAG_ZERO with finite number.  */
     char result[1000];
     int retval =
       my_sprintf (result, "%015Lf %d", 1234.0L, 33, 44, 55);
@@ -778,6 +882,15 @@ test_function (int (*my_sprintf) (char *, const char *, ...))
     ASSERT (retval == strlen (result));
   }
 
+  { /* FLAG_ZERO with NaN.  */
+    static long double zero = 0.0L;
+    char result[1000];
+    int retval =
+      my_sprintf (result, "%015Lf %d", zero / zero, 33, 44, 55);
+    ASSERT (strcmp (result, "            nan 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
   { /* Precision.  */
     char result[1000];
     int retval =
index 4162d3b..a058fc9 100644 (file)
@@ -837,7 +837,67 @@ test_function (char * (*my_asnprintf) (char *, size_t *, const char *, ...))
     free (result);
   }
 
-  { /* FLAG_ZERO.  */
+  { /* Width.  */
+    size_t length;
+    char *result =
+      my_asnprintf (NULL, &length, "%10f %d", 1.75, 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (strcmp (result, "  1.750000 33") == 0);
+    ASSERT (length == strlen (result));
+    free (result);
+  }
+
+  { /* FLAG_LEFT.  */
+    size_t length;
+    char *result =
+      my_asnprintf (NULL, &length, "%-10f %d", 1.75, 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (strcmp (result, "1.750000   33") == 0);
+    ASSERT (length == strlen (result));
+    free (result);
+  }
+
+  { /* FLAG_SHOWSIGN.  */
+    size_t length;
+    char *result =
+      my_asnprintf (NULL, &length, "%+f %d", 1.75, 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (strcmp (result, "+1.750000 33") == 0);
+    ASSERT (length == strlen (result));
+    free (result);
+  }
+
+  { /* FLAG_SPACE.  */
+    size_t length;
+    char *result =
+      my_asnprintf (NULL, &length, "% f %d", 1.75, 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (strcmp (result, " 1.750000 33") == 0);
+    ASSERT (length == strlen (result));
+    free (result);
+  }
+
+  { /* FLAG_ALT.  */
+    size_t length;
+    char *result =
+      my_asnprintf (NULL, &length, "%#f %d", 1.75, 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (strcmp (result, "1.750000 33") == 0);
+    ASSERT (length == strlen (result));
+    free (result);
+  }
+
+  { /* FLAG_ALT.  */
+    size_t length;
+    char *result =
+      my_asnprintf (NULL, &length, "%#.f %d", 1.75, 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (strcmp (result, "2. 33") == 0);
+    ASSERT (length == strlen (result));
+    free (result);
+  }
+
+  { /* FLAG_ZERO with finite number.  */
     size_t length;
     char *result =
       my_asnprintf (NULL, &length, "%015f %d", 1234.0, 33, 44, 55);
@@ -858,6 +918,16 @@ test_function (char * (*my_asnprintf) (char *, size_t *, const char *, ...))
     free (result);
   }
 
+  { /* FLAG_ZERO with NaN.  */
+    size_t length;
+    char *result =
+      my_asnprintf (NULL, &length, "%015f %d", NaN (), 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (strcmp (result, "            nan 33") == 0);
+    ASSERT (length == strlen (result));
+    free (result);
+  }
+
   { /* Precision.  */
     size_t length;
     char *result =
@@ -951,7 +1021,67 @@ test_function (char * (*my_asnprintf) (char *, size_t *, const char *, ...))
     free (result);
   }
 
-  { /* FLAG_ZERO.  */
+  { /* Width.  */
+    size_t length;
+    char *result =
+      my_asnprintf (NULL, &length, "%10Lf %d", 1.75L, 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (strcmp (result, "  1.750000 33") == 0);
+    ASSERT (length == strlen (result));
+    free (result);
+  }
+
+  { /* FLAG_LEFT.  */
+    size_t length;
+    char *result =
+      my_asnprintf (NULL, &length, "%-10Lf %d", 1.75L, 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (strcmp (result, "1.750000   33") == 0);
+    ASSERT (length == strlen (result));
+    free (result);
+  }
+
+  { /* FLAG_SHOWSIGN.  */
+    size_t length;
+    char *result =
+      my_asnprintf (NULL, &length, "%+Lf %d", 1.75L, 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (strcmp (result, "+1.750000 33") == 0);
+    ASSERT (length == strlen (result));
+    free (result);
+  }
+
+  { /* FLAG_SPACE.  */
+    size_t length;
+    char *result =
+      my_asnprintf (NULL, &length, "% Lf %d", 1.75L, 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (strcmp (result, " 1.750000 33") == 0);
+    ASSERT (length == strlen (result));
+    free (result);
+  }
+
+  { /* FLAG_ALT.  */
+    size_t length;
+    char *result =
+      my_asnprintf (NULL, &length, "%#Lf %d", 1.75L, 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (strcmp (result, "1.750000 33") == 0);
+    ASSERT (length == strlen (result));
+    free (result);
+  }
+
+  { /* FLAG_ALT.  */
+    size_t length;
+    char *result =
+      my_asnprintf (NULL, &length, "%#.Lf %d", 1.75L, 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (strcmp (result, "2. 33") == 0);
+    ASSERT (length == strlen (result));
+    free (result);
+  }
+
+  { /* FLAG_ZERO with finite number.  */
     size_t length;
     char *result =
       my_asnprintf (NULL, &length, "%015Lf %d", 1234.0L, 33, 44, 55);
@@ -972,6 +1102,17 @@ test_function (char * (*my_asnprintf) (char *, size_t *, const char *, ...))
     free (result);
   }
 
+  { /* FLAG_ZERO with NaN.  */
+    static long double zero = 0.0L;
+    size_t length;
+    char *result =
+      my_asnprintf (NULL, &length, "%015Lf %d", zero / zero, 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (strcmp (result, "            nan 33") == 0);
+    ASSERT (length == strlen (result));
+    free (result);
+  }
+
   { /* Precision.  */
     size_t length;
     char *result =
index e26b8a5..ca9dbab 100644 (file)
@@ -818,7 +818,67 @@ test_function (int (*my_asprintf) (char **, const char *, ...))
     free (result);
   }
 
-  { /* FLAG_ZERO.  */
+  { /* Width.  */
+    char *result;
+    int retval =
+      my_asprintf (&result, "%10f %d", 1.75, 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (strcmp (result, "  1.750000 33") == 0);
+    ASSERT (retval == strlen (result));
+    free (result);
+  }
+
+  { /* FLAG_LEFT.  */
+    char *result;
+    int retval =
+      my_asprintf (&result, "%-10f %d", 1.75, 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (strcmp (result, "1.750000   33") == 0);
+    ASSERT (retval == strlen (result));
+    free (result);
+  }
+
+  { /* FLAG_SHOWSIGN.  */
+    char *result;
+    int retval =
+      my_asprintf (&result, "%+f %d", 1.75, 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (strcmp (result, "+1.750000 33") == 0);
+    ASSERT (retval == strlen (result));
+    free (result);
+  }
+
+  { /* FLAG_SPACE.  */
+    char *result;
+    int retval =
+      my_asprintf (&result, "% f %d", 1.75, 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (strcmp (result, " 1.750000 33") == 0);
+    ASSERT (retval == strlen (result));
+    free (result);
+  }
+
+  { /* FLAG_ALT.  */
+    char *result;
+    int retval =
+      my_asprintf (&result, "%#f %d", 1.75, 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (strcmp (result, "1.750000 33") == 0);
+    ASSERT (retval == strlen (result));
+    free (result);
+  }
+
+  { /* FLAG_ALT.  */
+    char *result;
+    int retval =
+      my_asprintf (&result, "%#.f %d", 1.75, 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (strcmp (result, "2. 33") == 0);
+    ASSERT (retval == strlen (result));
+    free (result);
+  }
+
+  { /* FLAG_ZERO with finite number.  */
     char *result;
     int retval =
       my_asprintf (&result, "%015f %d", 1234.0, 33, 44, 55);
@@ -839,6 +899,16 @@ test_function (int (*my_asprintf) (char **, const char *, ...))
     free (result);
   }
 
+  { /* FLAG_ZERO with NaN.  */
+    char *result;
+    int retval =
+      my_asprintf (&result, "%015f %d", NaN (), 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (strcmp (result, "            nan 33") == 0);
+    ASSERT (retval == strlen (result));
+    free (result);
+  }
+
   { /* Precision.  */
     char *result;
     int retval =
@@ -932,7 +1002,67 @@ test_function (int (*my_asprintf) (char **, const char *, ...))
     free (result);
   }
 
-  { /* FLAG_ZERO.  */
+  { /* Width.  */
+    char *result;
+    int retval =
+      my_asprintf (&result, "%10Lf %d", 1.75L, 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (strcmp (result, "  1.750000 33") == 0);
+    ASSERT (retval == strlen (result));
+    free (result);
+  }
+
+  { /* FLAG_LEFT.  */
+    char *result;
+    int retval =
+      my_asprintf (&result, "%-10Lf %d", 1.75L, 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (strcmp (result, "1.750000   33") == 0);
+    ASSERT (retval == strlen (result));
+    free (result);
+  }
+
+  { /* FLAG_SHOWSIGN.  */
+    char *result;
+    int retval =
+      my_asprintf (&result, "%+Lf %d", 1.75L, 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (strcmp (result, "+1.750000 33") == 0);
+    ASSERT (retval == strlen (result));
+    free (result);
+  }
+
+  { /* FLAG_SPACE.  */
+    char *result;
+    int retval =
+      my_asprintf (&result, "% Lf %d", 1.75L, 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (strcmp (result, " 1.750000 33") == 0);
+    ASSERT (retval == strlen (result));
+    free (result);
+  }
+
+  { /* FLAG_ALT.  */
+    char *result;
+    int retval =
+      my_asprintf (&result, "%#Lf %d", 1.75L, 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (strcmp (result, "1.750000 33") == 0);
+    ASSERT (retval == strlen (result));
+    free (result);
+  }
+
+  { /* FLAG_ALT.  */
+    char *result;
+    int retval =
+      my_asprintf (&result, "%#.Lf %d", 1.75L, 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (strcmp (result, "2. 33") == 0);
+    ASSERT (retval == strlen (result));
+    free (result);
+  }
+
+  { /* FLAG_ZERO with finite number.  */
     char *result;
     int retval =
       my_asprintf (&result, "%015Lf %d", 1234.0L, 33, 44, 55);
@@ -953,6 +1083,17 @@ test_function (int (*my_asprintf) (char **, const char *, ...))
     free (result);
   }
 
+  { /* FLAG_ZERO with NaN.  */
+    static long double zero = 0.0L;
+    char *result;
+    int retval =
+      my_asprintf (&result, "%015Lf %d", zero / zero, 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (strcmp (result, "            nan 33") == 0);
+    ASSERT (retval == strlen (result));
+    free (result);
+  }
+
   { /* Precision.  */
     char *result;
     int retval =