]> Savannah Git Hosting - gnulib.git/commitdiff
*printf-posix: Fix implementation of %b directive.
authorBruno Haible <bruno@clisp.org>
Wed, 22 Mar 2023 20:43:23 +0000 (21:43 +0100)
committerBruno Haible <bruno@clisp.org>
Wed, 22 Mar 2023 20:43:23 +0000 (21:43 +0100)
* lib/vasnprintf.c (VASNPRINTF): In the %b directive implementation, fix
the precision handling, and ignore the '0' flag when a width and a
precision are both present.
* tests/test-snprintf-posix.h (test_function): Add test cases for the %x
directive and more test cases for the %b directive.
* tests/test-sprintf-posix.h (test_function): Likewise.
* tests/test-vasnprintf-posix.c (test_function): Likewise.
* tests/test-vasnwprintf-posix.c (test_function): Likewise.
* tests/test-vasprintf-posix.c (test_function): Likewise.
* modules/vasnwprintf-posix-tests (Files): Add m4/musl.m4.
(configure.ac): Invoke gl_MUSL_LIBC.

ChangeLog
lib/vasnprintf.c
modules/vasnwprintf-posix-tests
tests/test-snprintf-posix.h
tests/test-sprintf-posix.h
tests/test-vasnprintf-posix.c
tests/test-vasnwprintf-posix.c
tests/test-vasprintf-posix.c

index 88a8ea4d36c73a851399062cfb23c27e2bef5985..a3b9b8879546df74ef6ef4a705b8ab37b78267e5 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,18 @@
+2023-03-22  Bruno Haible  <bruno@clisp.org>
+
+       *printf-posix: Fix implementation of %b directive.
+       * lib/vasnprintf.c (VASNPRINTF): In the %b directive implementation, fix
+       the precision handling, and ignore the '0' flag when a width and a
+       precision are both present.
+       * tests/test-snprintf-posix.h (test_function): Add test cases for the %x
+       directive and more test cases for the %b directive.
+       * tests/test-sprintf-posix.h (test_function): Likewise.
+       * tests/test-vasnprintf-posix.c (test_function): Likewise.
+       * tests/test-vasnwprintf-posix.c (test_function): Likewise.
+       * tests/test-vasprintf-posix.c (test_function): Likewise.
+       * modules/vasnwprintf-posix-tests (Files): Add m4/musl.m4.
+       (configure.ac): Invoke gl_MUSL_LIBC.
+
 2023-03-22  Bruno Haible  <bruno@clisp.org>
 
        vasnwprintf: Fix a warning: implicit declaration of function ‘wcsnlen’.
index 5cd52b5b6ed4543de2ed774ccb19e6c179f8982f..248444ca23eb95bc768ce0ab379210533b66e61e 100644 (file)
@@ -3217,6 +3217,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
               {
                 arg_type type = a.arg[dp->arg_index].type;
                 int flags = dp->flags;
+                int has_width;
                 size_t width;
                 int has_precision;
                 size_t precision;
@@ -3229,6 +3230,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
                 DCHAR_T *pad_ptr;
                 DCHAR_T *p;
 
+                has_width = 0;
                 width = 0;
                 if (dp->width_start != dp->width_end)
                   {
@@ -3256,10 +3258,11 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
                           width = xsum (xtimes (width, 10), *digitp++ - '0');
                         while (digitp != dp->width_end);
                       }
+                    has_width = 1;
                   }
 
                 has_precision = 0;
-                precision = 0;
+                precision = 1;
                 if (dp->precision_start != dp->precision_end)
                   {
                     if (dp->precision_arg_index != ARG_NONE)
@@ -3333,12 +3336,24 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
                 int need_prefix = ((flags & FLAG_ALT) && arg != 0);
 
                 p = tmp_end;
-                do
+                /* "The result of converting a zero value with a precision
+                   of zero is no characters."  */
+                if (!(has_precision && precision == 0 && arg == 0))
+                  {
+                    do
+                      {
+                        *--p = '0' + (arg & 1);
+                        arg = arg >> 1;
+                      }
+                    while (arg != 0);
+                  }
+
+                if (has_precision)
                   {
-                    *--p = '0' + (arg & 1);
-                    arg = arg >> 1;
+                    DCHAR_T *digits_start = tmp_end - precision;
+                    while (p > digits_start)
+                      *--p = '0';
                   }
-                while (arg != 0);
 
                 pad_ptr = p;
 
@@ -3365,7 +3380,12 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
                         for (p = tmp_end - pad; p < tmp_end; p++)
                           *p = ' ';
                       }
-                    else if (flags & FLAG_ZERO)
+                    else if ((flags & FLAG_ZERO)
+                             /* Neither ISO C nor POSIX specify that the '0'
+                                flag is ignored when a width and a precision
+                                are both present.  But most implementations
+                                do so.  */
+                             && !(has_width && has_precision))
                       {
                         /* Pad with zeroes.  */
                         for (p = tmp_start; p < pad_ptr; p++)
index 667eb61103454aedd22bb934ce4061434203f55f..6354e79f75a9a29264277bfc94a787ad38bf4208 100644 (file)
@@ -7,6 +7,7 @@ tests/minus-zero.h
 tests/infinity.h
 tests/nan.h
 tests/macros.h
+m4/musl.m4
 m4/locale-fr.m4
 m4/codeset.m4
 
@@ -21,6 +22,7 @@ wmemcpy
 
 configure.ac:
 AC_REQUIRE([gl_LONG_DOUBLE_VS_DOUBLE])
+gl_MUSL_LIBC
 gt_LOCALE_FR
 gt_LOCALE_FR_UTF8
 
index 05c7be8059181247cac0b84f0cdc81e415a2ed16..a8993f947a0bed124a7169140e33113274d6e572 100644 (file)
@@ -3091,6 +3091,190 @@ test_function (int (*my_snprintf) (char *, size_t, const char *, ...))
   }
 #endif
 
+  /* Test the support of the 'x' conversion specifier for hexadecimal output of
+     integers.  */
+
+  { /* Zero.  */
+    int retval =
+      my_snprintf (result, sizeof (result), "%x %d", 0, 33, 44, 55);
+    ASSERT (strcmp (result, "0 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  { /* A positive number.  */
+    int retval =
+      my_snprintf (result, sizeof (result), "%x %d", 12348, 33, 44, 55);
+    ASSERT (strcmp (result, "303c 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  { /* A large positive number.  */
+    int retval =
+      my_snprintf (result, sizeof (result), "%x %d", 0xFFFFFFFEU, 33, 44, 55);
+    ASSERT (strcmp (result, "fffffffe 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  { /* Width.  */
+    int retval =
+      my_snprintf (result, sizeof (result), "%10x %d", 12348, 33, 44, 55);
+    ASSERT (strcmp (result, "      303c 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  { /* Width given as argument.  */
+    int retval =
+      my_snprintf (result, sizeof (result), "%*x %d", 10, 12348, 33, 44, 55);
+    ASSERT (strcmp (result, "      303c 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  { /* Negative width given as argument (cf. FLAG_LEFT below).  */
+    int retval =
+      my_snprintf (result, sizeof (result), "%*x %d", -10, 12348, 33, 44, 55);
+    ASSERT (strcmp (result, "303c       33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  { /* Precision.  */
+    int retval =
+      my_snprintf (result, sizeof (result), "%.10x %d", 12348, 33, 44, 55);
+    ASSERT (strcmp (result, "000000303c 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  { /* Zero precision and a positive number.  */
+    int retval =
+      my_snprintf (result, sizeof (result), "%.0x %d", 12348, 33, 44, 55);
+    ASSERT (strcmp (result, "303c 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  { /* Zero precision and a zero number.  */
+    int retval =
+      my_snprintf (result, sizeof (result), "%.0x %d", 0, 33, 44, 55);
+    /* ISO C and POSIX specify that "The result of converting a zero value
+       with a precision of zero is no characters."  */
+    ASSERT (strcmp (result, " 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  { /* Width and precision.  */
+    int retval =
+      my_snprintf (result, sizeof (result), "%15.10x %d", 12348, 33, 44, 55);
+    ASSERT (strcmp (result, "     000000303c 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  { /* Padding and precision.  */
+    int retval =
+      my_snprintf (result, sizeof (result), "%015.10x %d", 12348, 33, 44, 55);
+    /* Neither ISO C nor POSIX specify that the '0' flag is ignored when a width
+       and a precision are both present.  But most implementations do so.  */
+    #ifdef __MINGW32__
+    ASSERT (strcmp (result, "00000000000303c 33") == 0);
+    #else
+    ASSERT (strcmp (result, "     000000303c 33") == 0);
+    #endif
+    ASSERT (retval == strlen (result));
+  }
+
+  { /* FLAG_LEFT.  */
+    int retval =
+      my_snprintf (result, sizeof (result), "%-10x %d", 12348, 33, 44, 55);
+    ASSERT (strcmp (result, "303c       33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  { /* FLAG_ALT with zero.  */
+    int retval =
+      my_snprintf (result, sizeof (result), "%#x %d", 0, 33, 44, 55);
+    ASSERT (strcmp (result, "0 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  { /* FLAG_ALT with a positive number.  */
+    int retval =
+      my_snprintf (result, sizeof (result), "%#x %d", 12348, 33, 44, 55);
+    ASSERT (strcmp (result, "0x303c 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  { /* FLAG_ALT with a positive number and width.  */
+    int retval =
+      my_snprintf (result, sizeof (result), "%#10x %d", 12348, 33, 44, 55);
+    ASSERT (strcmp (result, "    0x303c 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  { /* FLAG_ALT with a positive number and padding.  */
+    int retval =
+      my_snprintf (result, sizeof (result), "%0#10x %d", 12348, 33, 44, 55);
+    ASSERT (strcmp (result, "0x0000303c 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  { /* FLAG_ALT with a positive number and precision.  */
+    int retval =
+      my_snprintf (result, sizeof (result), "%0#.10x %d", 12348, 33, 44, 55);
+    ASSERT (strcmp (result, "0x000000303c 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  { /* FLAG_ALT with a positive number and width and precision.  */
+    int retval =
+      my_snprintf (result, sizeof (result), "%#15.10x %d", 12348, 33, 44, 55);
+    ASSERT (strcmp (result, "   0x000000303c 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  { /* FLAG_ALT with a positive number and padding and precision.  */
+    int retval =
+      my_snprintf (result, sizeof (result), "%0#15.10x %d", 12348, 33, 44, 55);
+    /* Neither ISO C nor POSIX specify that the '0' flag is ignored when a width
+       and a precision are both present.  But most implementations do so.  */
+    #ifdef __MINGW32__
+    ASSERT (strcmp (result, "0x000000000303c 33") == 0);
+    #else
+    ASSERT (strcmp (result, "   0x000000303c 33") == 0);
+    #endif
+    ASSERT (retval == strlen (result));
+  }
+
+  { /* FLAG_ALT with a zero precision and a zero number.  */
+    int retval =
+      my_snprintf (result, sizeof (result), "%#.0x %d", 0, 33, 44, 55);
+    /* ISO C and POSIX specify that "The result of converting a zero value
+       with a precision of zero is no characters.", and the prefix is added
+       only for non-zero values.  */
+    ASSERT (strcmp (result, " 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  { /* Uppercase 'X'.  */
+    int retval =
+      my_snprintf (result, sizeof (result), "%X %d", 12348, 33, 44, 55);
+    ASSERT (strcmp (result, "303C 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  { /* Uppercase 'X' with FLAG_ALT.  */
+    int retval =
+      my_snprintf (result, sizeof (result), "%#X %d", 12348, 33, 44, 55);
+    ASSERT (strcmp (result, "0X303C 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  { /* Uppercase 'X' with FLAG_ALT and zero precision and a zero number.  */
+    int retval =
+      my_snprintf (result, sizeof (result), "%#.0X %d", 0, 33, 44, 55);
+    /* ISO C and POSIX specify that "The result of converting a zero value
+       with a precision of zero is no characters.", and the prefix is added
+       only for non-zero values.  */
+    ASSERT (strcmp (result, " 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
   /* Test the support of the 'b' conversion specifier for binary output of
      integers.  */
 
@@ -3136,6 +3320,45 @@ test_function (int (*my_snprintf) (char *, size_t, const char *, ...))
     ASSERT (retval == strlen (result));
   }
 
+  { /* Precision.  */
+    int retval =
+      my_snprintf (result, sizeof (result), "%.20b %d", 12345, 33, 44, 55);
+    ASSERT (strcmp (result, "00000011000000111001 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  { /* Zero precision and a positive number.  */
+    int retval =
+      my_snprintf (result, sizeof (result), "%.0b %d", 12345, 33, 44, 55);
+    ASSERT (strcmp (result, "11000000111001 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  { /* Zero precision and a zero number.  */
+    int retval =
+      my_snprintf (result, sizeof (result), "%.0b %d", 0, 33, 44, 55);
+    /* ISO C and POSIX specify that "The result of converting a zero value
+       with a precision of zero is no characters."  */
+    ASSERT (strcmp (result, " 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  { /* Width and precision.  */
+    int retval =
+      my_snprintf (result, sizeof (result), "%25.20b %d", 12345, 33, 44, 55);
+    ASSERT (strcmp (result, "     00000011000000111001 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  { /* Padding and precision.  */
+    int retval =
+      my_snprintf (result, sizeof (result), "%025.20b %d", 12345, 33, 44, 55);
+    /* Neither ISO C nor POSIX specify that the '0' flag is ignored when
+       a width and a precision are both present.  But implementations do so.  */
+    ASSERT (strcmp (result, "     00000011000000111001 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
   { /* FLAG_LEFT.  */
     int retval =
       my_snprintf (result, sizeof (result), "%-20b %d", 12345, 33, 44, 55);
@@ -3156,4 +3379,51 @@ test_function (int (*my_snprintf) (char *, size_t, const char *, ...))
     ASSERT (strcmp (result, "0b11000000111001 33") == 0);
     ASSERT (retval == strlen (result));
   }
+
+  { /* FLAG_ALT with a positive number and width.  */
+    int retval =
+      my_snprintf (result, sizeof (result), "%#20b %d", 12345, 33, 44, 55);
+    ASSERT (strcmp (result, "    0b11000000111001 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  { /* FLAG_ALT with a positive number and padding.  */
+    int retval =
+      my_snprintf (result, sizeof (result), "%0#20b %d", 12345, 33, 44, 55);
+    ASSERT (strcmp (result, "0b000011000000111001 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  { /* FLAG_ALT with a positive number and precision.  */
+    int retval =
+      my_snprintf (result, sizeof (result), "%0#.20b %d", 12345, 33, 44, 55);
+    ASSERT (strcmp (result, "0b00000011000000111001 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  { /* FLAG_ALT with a positive number and width and precision.  */
+    int retval =
+      my_snprintf (result, sizeof (result), "%#25.20b %d", 12345, 33, 44, 55);
+    ASSERT (strcmp (result, "   0b00000011000000111001 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  { /* FLAG_ALT with a positive number and padding and precision.  */
+    int retval =
+      my_snprintf (result, sizeof (result), "%0#25.20b %d", 12345, 33, 44, 55);
+    /* Neither ISO C nor POSIX specify that the '0' flag is ignored when
+       a width and a precision are both present.  But implementations do so.  */
+    ASSERT (strcmp (result, "   0b00000011000000111001 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  { /* FLAG_ALT with a zero precision and a zero number.  */
+    int retval =
+      my_snprintf (result, sizeof (result), "%#.0b %d", 0, 33, 44, 55);
+    /* ISO C and POSIX specify that "The result of converting a zero value
+       with a precision of zero is no characters.", and the prefix is added
+       only for non-zero values.  */
+    ASSERT (strcmp (result, " 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
 }
index d745a1109ba5af025e903c2e6044e53ee1c25fa9..7f280d3c3239cdfb3fbddfc68e08ea8aff8d5fec 100644 (file)
@@ -3069,6 +3069,190 @@ test_function (int (*my_sprintf) (char *, const char *, ...))
   }
 #endif
 
+  /* Test the support of the 'x' conversion specifier for hexadecimal output of
+     integers.  */
+
+  { /* Zero.  */
+    int retval =
+      my_sprintf (result, "%x %d", 0, 33, 44, 55);
+    ASSERT (strcmp (result, "0 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  { /* A positive number.  */
+    int retval =
+      my_sprintf (result, "%x %d", 12348, 33, 44, 55);
+    ASSERT (strcmp (result, "303c 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  { /* A large positive number.  */
+    int retval =
+      my_sprintf (result, "%x %d", 0xFFFFFFFEU, 33, 44, 55);
+    ASSERT (strcmp (result, "fffffffe 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  { /* Width.  */
+    int retval =
+      my_sprintf (result, "%10x %d", 12348, 33, 44, 55);
+    ASSERT (strcmp (result, "      303c 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  { /* Width given as argument.  */
+    int retval =
+      my_sprintf (result, "%*x %d", 10, 12348, 33, 44, 55);
+    ASSERT (strcmp (result, "      303c 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  { /* Negative width given as argument (cf. FLAG_LEFT below).  */
+    int retval =
+      my_sprintf (result, "%*x %d", -10, 12348, 33, 44, 55);
+    ASSERT (strcmp (result, "303c       33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  { /* Precision.  */
+    int retval =
+      my_sprintf (result, "%.10x %d", 12348, 33, 44, 55);
+    ASSERT (strcmp (result, "000000303c 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  { /* Zero precision and a positive number.  */
+    int retval =
+      my_sprintf (result, "%.0x %d", 12348, 33, 44, 55);
+    ASSERT (strcmp (result, "303c 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  { /* Zero precision and a zero number.  */
+    int retval =
+      my_sprintf (result, "%.0x %d", 0, 33, 44, 55);
+    /* ISO C and POSIX specify that "The result of converting a zero value
+       with a precision of zero is no characters."  */
+    ASSERT (strcmp (result, " 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  { /* Width and precision.  */
+    int retval =
+      my_sprintf (result, "%15.10x %d", 12348, 33, 44, 55);
+    ASSERT (strcmp (result, "     000000303c 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  { /* Padding and precision.  */
+    int retval =
+      my_sprintf (result, "%015.10x %d", 12348, 33, 44, 55);
+    /* Neither ISO C nor POSIX specify that the '0' flag is ignored when a width
+       and a precision are both present.  But most implementations do so.  */
+    #ifdef __MINGW32__
+    ASSERT (strcmp (result, "00000000000303c 33") == 0);
+    #else
+    ASSERT (strcmp (result, "     000000303c 33") == 0);
+    #endif
+    ASSERT (retval == strlen (result));
+  }
+
+  { /* FLAG_LEFT.  */
+    int retval =
+      my_sprintf (result, "%-10x %d", 12348, 33, 44, 55);
+    ASSERT (strcmp (result, "303c       33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  { /* FLAG_ALT with zero.  */
+    int retval =
+      my_sprintf (result, "%#x %d", 0, 33, 44, 55);
+    ASSERT (strcmp (result, "0 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  { /* FLAG_ALT with a positive number.  */
+    int retval =
+      my_sprintf (result, "%#x %d", 12348, 33, 44, 55);
+    ASSERT (strcmp (result, "0x303c 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  { /* FLAG_ALT with a positive number and width.  */
+    int retval =
+      my_sprintf (result, "%#10x %d", 12348, 33, 44, 55);
+    ASSERT (strcmp (result, "    0x303c 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  { /* FLAG_ALT with a positive number and padding.  */
+    int retval =
+      my_sprintf (result, "%0#10x %d", 12348, 33, 44, 55);
+    ASSERT (strcmp (result, "0x0000303c 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  { /* FLAG_ALT with a positive number and precision.  */
+    int retval =
+      my_sprintf (result, "%0#.10x %d", 12348, 33, 44, 55);
+    ASSERT (strcmp (result, "0x000000303c 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  { /* FLAG_ALT with a positive number and width and precision.  */
+    int retval =
+      my_sprintf (result, "%#15.10x %d", 12348, 33, 44, 55);
+    ASSERT (strcmp (result, "   0x000000303c 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  { /* FLAG_ALT with a positive number and padding and precision.  */
+    int retval =
+      my_sprintf (result, "%0#15.10x %d", 12348, 33, 44, 55);
+    /* Neither ISO C nor POSIX specify that the '0' flag is ignored when a width
+       and a precision are both present.  But most implementations do so.  */
+    #ifdef __MINGW32__
+    ASSERT (strcmp (result, "0x000000000303c 33") == 0);
+    #else
+    ASSERT (strcmp (result, "   0x000000303c 33") == 0);
+    #endif
+    ASSERT (retval == strlen (result));
+  }
+
+  { /* FLAG_ALT with a zero precision and a zero number.  */
+    int retval =
+      my_sprintf (result, "%#.0x %d", 0, 33, 44, 55);
+    /* ISO C and POSIX specify that "The result of converting a zero value
+       with a precision of zero is no characters.", and the prefix is added
+       only for non-zero values.  */
+    ASSERT (strcmp (result, " 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  { /* Uppercase 'X'.  */
+    int retval =
+      my_sprintf (result, "%X %d", 12348, 33, 44, 55);
+    ASSERT (strcmp (result, "303C 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  { /* Uppercase 'X' with FLAG_ALT.  */
+    int retval =
+      my_sprintf (result, "%#X %d", 12348, 33, 44, 55);
+    ASSERT (strcmp (result, "0X303C 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  { /* Uppercase 'X' with FLAG_ALT and zero precision and a zero number.  */
+    int retval =
+      my_sprintf (result, "%#.0X %d", 0, 33, 44, 55);
+    /* ISO C and POSIX specify that "The result of converting a zero value
+       with a precision of zero is no characters.", and the prefix is added
+       only for non-zero values.  */
+    ASSERT (strcmp (result, " 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
   /* Test the support of the 'b' conversion specifier for binary output of
      integers.  */
 
@@ -3114,6 +3298,45 @@ test_function (int (*my_sprintf) (char *, const char *, ...))
     ASSERT (retval == strlen (result));
   }
 
+  { /* Precision.  */
+    int retval =
+      my_sprintf (result, "%.20b %d", 12345, 33, 44, 55);
+    ASSERT (strcmp (result, "00000011000000111001 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  { /* Zero precision and a positive number.  */
+    int retval =
+      my_sprintf (result, "%.0b %d", 12345, 33, 44, 55);
+    ASSERT (strcmp (result, "11000000111001 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  { /* Zero precision and a zero number.  */
+    int retval =
+      my_sprintf (result, "%.0b %d", 0, 33, 44, 55);
+    /* ISO C and POSIX specify that "The result of converting a zero value
+       with a precision of zero is no characters."  */
+    ASSERT (strcmp (result, " 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  { /* Width and precision.  */
+    int retval =
+      my_sprintf (result, "%25.20b %d", 12345, 33, 44, 55);
+    ASSERT (strcmp (result, "     00000011000000111001 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  { /* Padding and precision.  */
+    int retval =
+      my_sprintf (result, "%025.20b %d", 12345, 33, 44, 55);
+    /* Neither ISO C nor POSIX specify that the '0' flag is ignored when
+       a width and a precision are both present.  But implementations do so.  */
+    ASSERT (strcmp (result, "     00000011000000111001 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
   { /* FLAG_LEFT.  */
     int retval =
       my_sprintf (result, "%-20b %d", 12345, 33, 44, 55);
@@ -3134,4 +3357,51 @@ test_function (int (*my_sprintf) (char *, const char *, ...))
     ASSERT (strcmp (result, "0b11000000111001 33") == 0);
     ASSERT (retval == strlen (result));
   }
+
+  { /* FLAG_ALT with a positive number and width.  */
+    int retval =
+      my_sprintf (result, "%#20b %d", 12345, 33, 44, 55);
+    ASSERT (strcmp (result, "    0b11000000111001 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  { /* FLAG_ALT with a positive number and padding.  */
+    int retval =
+      my_sprintf (result, "%0#20b %d", 12345, 33, 44, 55);
+    ASSERT (strcmp (result, "0b000011000000111001 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  { /* FLAG_ALT with a positive number and precision.  */
+    int retval =
+      my_sprintf (result, "%0#.20b %d", 12345, 33, 44, 55);
+    ASSERT (strcmp (result, "0b00000011000000111001 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  { /* FLAG_ALT with a positive number and width and precision.  */
+    int retval =
+      my_sprintf (result, "%#25.20b %d", 12345, 33, 44, 55);
+    ASSERT (strcmp (result, "   0b00000011000000111001 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  { /* FLAG_ALT with a positive number and padding and precision.  */
+    int retval =
+      my_sprintf (result, "%0#25.20b %d", 12345, 33, 44, 55);
+    /* Neither ISO C nor POSIX specify that the '0' flag is ignored when
+       a width and a precision are both present.  But implementations do so.  */
+    ASSERT (strcmp (result, "   0b00000011000000111001 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  { /* FLAG_ALT with a zero precision and a zero number.  */
+    int retval =
+      my_sprintf (result, "%#.0b %d", 0, 33, 44, 55);
+    /* ISO C and POSIX specify that "The result of converting a zero value
+       with a precision of zero is no characters.", and the prefix is added
+       only for non-zero values.  */
+    ASSERT (strcmp (result, " 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
 }
index ecbb8bcda009e3cbfef9dd4f1daa20dbe42044c8..87f4fc290beb0e399b6e559b7d4aa60f5c93eb61 100644 (file)
@@ -4017,6 +4017,259 @@ test_function (char * (*my_asnprintf) (char *, size_t *, const char *, ...))
   }
 #endif
 
+  /* Test the support of the 'x' conversion specifier for hexadecimal output of
+     integers.  */
+
+  { /* Zero.  */
+    size_t length;
+    char *result =
+      my_asnprintf (NULL, &length, "%x %d", 0, 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (strcmp (result, "0 33") == 0);
+    ASSERT (length == strlen (result));
+    free (result);
+  }
+
+  { /* A positive number.  */
+    size_t length;
+    char *result =
+      my_asnprintf (NULL, &length, "%x %d", 12348, 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (strcmp (result, "303c 33") == 0);
+    ASSERT (length == strlen (result));
+    free (result);
+  }
+
+  { /* A large positive number.  */
+    size_t length;
+    char *result =
+      my_asnprintf (NULL, &length, "%x %d", 0xFFFFFFFEU, 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (strcmp (result, "fffffffe 33") == 0);
+    ASSERT (length == strlen (result));
+    free (result);
+  }
+
+  { /* Width.  */
+    size_t length;
+    char *result =
+      my_asnprintf (NULL, &length, "%10x %d", 12348, 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (strcmp (result, "      303c 33") == 0);
+    ASSERT (length == strlen (result));
+    free (result);
+  }
+
+  { /* Width given as argument.  */
+    size_t length;
+    char *result =
+      my_asnprintf (NULL, &length, "%*x %d", 10, 12348, 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (strcmp (result, "      303c 33") == 0);
+    ASSERT (length == strlen (result));
+    free (result);
+  }
+
+  { /* Negative width given as argument (cf. FLAG_LEFT below).  */
+    size_t length;
+    char *result =
+      my_asnprintf (NULL, &length, "%*x %d", -10, 12348, 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (strcmp (result, "303c       33") == 0);
+    ASSERT (length == strlen (result));
+    free (result);
+  }
+
+  { /* Precision.  */
+    size_t length;
+    char *result =
+      my_asnprintf (NULL, &length, "%.10x %d", 12348, 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (strcmp (result, "000000303c 33") == 0);
+    ASSERT (length == strlen (result));
+    free (result);
+  }
+
+  { /* Zero precision and a positive number.  */
+    size_t length;
+    char *result =
+      my_asnprintf (NULL, &length, "%.0x %d", 12348, 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (strcmp (result, "303c 33") == 0);
+    ASSERT (length == strlen (result));
+    free (result);
+  }
+
+  { /* Zero precision and a zero number.  */
+    size_t length;
+    char *result =
+      my_asnprintf (NULL, &length, "%.0x %d", 0, 33, 44, 55);
+    ASSERT (result != NULL);
+    /* ISO C and POSIX specify that "The result of converting a zero value
+       with a precision of zero is no characters."  */
+    ASSERT (strcmp (result, " 33") == 0);
+    ASSERT (length == strlen (result));
+    free (result);
+  }
+
+  { /* Width and precision.  */
+    size_t length;
+    char *result =
+      my_asnprintf (NULL, &length, "%15.10x %d", 12348, 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (strcmp (result, "     000000303c 33") == 0);
+    ASSERT (length == strlen (result));
+    free (result);
+  }
+
+  { /* Padding and precision.  */
+    size_t length;
+    char *result =
+      my_asnprintf (NULL, &length, "%015.10x %d", 12348, 33, 44, 55);
+    ASSERT (result != NULL);
+    /* Neither ISO C nor POSIX specify that the '0' flag is ignored when a width
+       and a precision are both present.  But most implementations do so.  */
+    #ifdef __MINGW32__
+    ASSERT (strcmp (result, "00000000000303c 33") == 0);
+    #else
+    ASSERT (strcmp (result, "     000000303c 33") == 0);
+    #endif
+    ASSERT (length == strlen (result));
+    free (result);
+  }
+
+  { /* FLAG_LEFT.  */
+    size_t length;
+    char *result =
+      my_asnprintf (NULL, &length, "%-10x %d", 12348, 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (strcmp (result, "303c       33") == 0);
+    ASSERT (length == strlen (result));
+    free (result);
+  }
+
+  { /* FLAG_ALT with zero.  */
+    size_t length;
+    char *result =
+      my_asnprintf (NULL, &length, "%#x %d", 0, 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (strcmp (result, "0 33") == 0);
+    ASSERT (length == strlen (result));
+    free (result);
+  }
+
+  { /* FLAG_ALT with a positive number.  */
+    size_t length;
+    char *result =
+      my_asnprintf (NULL, &length, "%#x %d", 12348, 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (strcmp (result, "0x303c 33") == 0);
+    ASSERT (length == strlen (result));
+    free (result);
+  }
+
+  { /* FLAG_ALT with a positive number and width.  */
+    size_t length;
+    char *result =
+      my_asnprintf (NULL, &length, "%#10x %d", 12348, 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (strcmp (result, "    0x303c 33") == 0);
+    ASSERT (length == strlen (result));
+    free (result);
+  }
+
+  { /* FLAG_ALT with a positive number and padding.  */
+    size_t length;
+    char *result =
+      my_asnprintf (NULL, &length, "%0#10x %d", 12348, 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (strcmp (result, "0x0000303c 33") == 0);
+    ASSERT (length == strlen (result));
+    free (result);
+  }
+
+  { /* FLAG_ALT with a positive number and precision.  */
+    size_t length;
+    char *result =
+      my_asnprintf (NULL, &length, "%0#.10x %d", 12348, 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (strcmp (result, "0x000000303c 33") == 0);
+    ASSERT (length == strlen (result));
+    free (result);
+  }
+
+  { /* FLAG_ALT with a positive number and width and precision.  */
+    size_t length;
+    char *result =
+      my_asnprintf (NULL, &length, "%#15.10x %d", 12348, 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (strcmp (result, "   0x000000303c 33") == 0);
+    ASSERT (length == strlen (result));
+    free (result);
+  }
+
+  { /* FLAG_ALT with a positive number and padding and precision.  */
+    size_t length;
+    char *result =
+      my_asnprintf (NULL, &length, "%0#15.10x %d", 12348, 33, 44, 55);
+    ASSERT (result != NULL);
+    /* Neither ISO C nor POSIX specify that the '0' flag is ignored when a width
+       and a precision are both present.  But most implementations do so.  */
+    #ifdef __MINGW32__
+    ASSERT (strcmp (result, "0x000000000303c 33") == 0);
+    #else
+    ASSERT (strcmp (result, "   0x000000303c 33") == 0);
+    #endif
+    ASSERT (length == strlen (result));
+    free (result);
+  }
+
+  { /* FLAG_ALT with a zero precision and a zero number.  */
+    size_t length;
+    char *result =
+      my_asnprintf (NULL, &length, "%#.0x %d", 0, 33, 44, 55);
+    ASSERT (result != NULL);
+    /* ISO C and POSIX specify that "The result of converting a zero value
+       with a precision of zero is no characters.", and the prefix is added
+       only for non-zero values.  */
+    ASSERT (strcmp (result, " 33") == 0);
+    ASSERT (length == strlen (result));
+    free (result);
+  }
+
+  { /* Uppercase 'X'.  */
+    size_t length;
+    char *result =
+      my_asnprintf (NULL, &length, "%X %d", 12348, 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (strcmp (result, "303C 33") == 0);
+    ASSERT (length == strlen (result));
+    free (result);
+  }
+
+  { /* Uppercase 'X' with FLAG_ALT.  */
+    size_t length;
+    char *result =
+      my_asnprintf (NULL, &length, "%#X %d", 12348, 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (strcmp (result, "0X303C 33") == 0);
+    ASSERT (length == strlen (result));
+    free (result);
+  }
+
+  { /* Uppercase 'X' with FLAG_ALT and zero precision and a zero number.  */
+    size_t length;
+    char *result =
+      my_asnprintf (NULL, &length, "%#.0X %d", 0, 33, 44, 55);
+    ASSERT (result != NULL);
+    /* ISO C and POSIX specify that "The result of converting a zero value
+       with a precision of zero is no characters.", and the prefix is added
+       only for non-zero values.  */
+    ASSERT (strcmp (result, " 33") == 0);
+    ASSERT (length == strlen (result));
+    free (result);
+  }
+
   /* Test the support of the 'b' conversion specifier for binary output of
      integers.  */
 
@@ -4080,6 +4333,60 @@ test_function (char * (*my_asnprintf) (char *, size_t *, const char *, ...))
     free (result);
   }
 
+  { /* Precision.  */
+    size_t length;
+    char *result =
+      my_asnprintf (NULL, &length, "%.20b %d", 12345, 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (strcmp (result, "00000011000000111001 33") == 0);
+    ASSERT (length == strlen (result));
+    free (result);
+  }
+
+  { /* Zero precision and a positive number.  */
+    size_t length;
+    char *result =
+      my_asnprintf (NULL, &length, "%.0b %d", 12345, 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (strcmp (result, "11000000111001 33") == 0);
+    ASSERT (length == strlen (result));
+    free (result);
+  }
+
+  { /* Zero precision and a zero number.  */
+    size_t length;
+    char *result =
+      my_asnprintf (NULL, &length, "%.0b %d", 0, 33, 44, 55);
+    ASSERT (result != NULL);
+    /* ISO C and POSIX specify that "The result of converting a zero value
+       with a precision of zero is no characters."  */
+    ASSERT (strcmp (result, " 33") == 0);
+    ASSERT (length == strlen (result));
+    free (result);
+  }
+
+  { /* Width and precision.  */
+    size_t length;
+    char *result =
+      my_asnprintf (NULL, &length, "%25.20b %d", 12345, 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (strcmp (result, "     00000011000000111001 33") == 0);
+    ASSERT (length == strlen (result));
+    free (result);
+  }
+
+  { /* Padding and precision.  */
+    size_t length;
+    char *result =
+      my_asnprintf (NULL, &length, "%025.20b %d", 12345, 33, 44, 55);
+    ASSERT (result != NULL);
+    /* Neither ISO C nor POSIX specify that the '0' flag is ignored when
+       a width and a precision are both present.  But implementations do so.  */
+    ASSERT (strcmp (result, "     00000011000000111001 33") == 0);
+    ASSERT (length == strlen (result));
+    free (result);
+  }
+
   { /* FLAG_LEFT.  */
     size_t length;
     char *result =
@@ -4094,6 +4401,7 @@ test_function (char * (*my_asnprintf) (char *, size_t *, const char *, ...))
     size_t length;
     char *result =
       my_asnprintf (NULL, &length, "%#b %d", 0, 33, 44, 55);
+    ASSERT (result != NULL);
     ASSERT (strcmp (result, "0 33") == 0);
     ASSERT (length == strlen (result));
     free (result);
@@ -4103,11 +4411,77 @@ test_function (char * (*my_asnprintf) (char *, size_t *, const char *, ...))
     size_t length;
     char *result =
       my_asnprintf (NULL, &length, "%#b %d", 12345, 33, 44, 55);
+    ASSERT (result != NULL);
     ASSERT (strcmp (result, "0b11000000111001 33") == 0);
     ASSERT (length == strlen (result));
     free (result);
   }
 
+  { /* FLAG_ALT with a positive number and width.  */
+    size_t length;
+    char *result =
+      my_asnprintf (NULL, &length, "%#20b %d", 12345, 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (strcmp (result, "    0b11000000111001 33") == 0);
+    ASSERT (length == strlen (result));
+    free (result);
+  }
+
+  { /* FLAG_ALT with a positive number and padding.  */
+    size_t length;
+    char *result =
+      my_asnprintf (NULL, &length, "%0#20b %d", 12345, 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (strcmp (result, "0b000011000000111001 33") == 0);
+    ASSERT (length == strlen (result));
+    free (result);
+  }
+
+  { /* FLAG_ALT with a positive number and precision.  */
+    size_t length;
+    char *result =
+      my_asnprintf (NULL, &length, "%0#.20b %d", 12345, 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (strcmp (result, "0b00000011000000111001 33") == 0);
+    ASSERT (length == strlen (result));
+    free (result);
+  }
+
+  { /* FLAG_ALT with a positive number and width and precision.  */
+    size_t length;
+    char *result =
+      my_asnprintf (NULL, &length, "%#25.20b %d", 12345, 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (strcmp (result, "   0b00000011000000111001 33") == 0);
+    ASSERT (length == strlen (result));
+    free (result);
+  }
+
+  { /* FLAG_ALT with a positive number and padding and precision.  */
+    size_t length;
+    char *result =
+      my_asnprintf (NULL, &length, "%0#25.20b %d", 12345, 33, 44, 55);
+    ASSERT (result != NULL);
+    /* Neither ISO C nor POSIX specify that the '0' flag is ignored when
+       a width and a precision are both present.  But implementations do so.  */
+    ASSERT (strcmp (result, "   0b00000011000000111001 33") == 0);
+    ASSERT (length == strlen (result));
+    free (result);
+  }
+
+  { /* FLAG_ALT with a zero precision and a zero number.  */
+    size_t length;
+    char *result =
+      my_asnprintf (NULL, &length, "%#.0b %d", 0, 33, 44, 55);
+    ASSERT (result != NULL);
+    /* ISO C and POSIX specify that "The result of converting a zero value
+       with a precision of zero is no characters.", and the prefix is added
+       only for non-zero values.  */
+    ASSERT (strcmp (result, " 33") == 0);
+    ASSERT (length == strlen (result));
+    free (result);
+  }
+
 #if (__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 2)) && !defined __UCLIBC__
   /* Test that the 'I' flag is supported.  */
   {
index e53c6a33f3ca53d40a9587e6106fae8a3f4bef5f..49f5f91ebe89708b8c4e91ae003b5ee971a9c844 100644 (file)
@@ -4022,6 +4022,259 @@ test_function (wchar_t * (*my_asnwprintf) (wchar_t *, size_t *, const wchar_t *,
   }
 #endif
 
+  /* Test the support of the 'x' conversion specifier for hexadecimal output of
+     integers.  */
+
+  { /* Zero.  */
+    size_t length;
+    wchar_t *result =
+      my_asnwprintf (NULL, &length, L"%x %d", 0, 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (wcscmp (result, L"0 33") == 0);
+    ASSERT (length == wcslen (result));
+    free (result);
+  }
+
+  { /* A positive number.  */
+    size_t length;
+    wchar_t *result =
+      my_asnwprintf (NULL, &length, L"%x %d", 12348, 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (wcscmp (result, L"303c 33") == 0);
+    ASSERT (length == wcslen (result));
+    free (result);
+  }
+
+  { /* A large positive number.  */
+    size_t length;
+    wchar_t *result =
+      my_asnwprintf (NULL, &length, L"%x %d", 0xFFFFFFFEU, 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (wcscmp (result, L"fffffffe 33") == 0);
+    ASSERT (length == wcslen (result));
+    free (result);
+  }
+
+  { /* Width.  */
+    size_t length;
+    wchar_t *result =
+      my_asnwprintf (NULL, &length, L"%10x %d", 12348, 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (wcscmp (result, L"      303c 33") == 0);
+    ASSERT (length == wcslen (result));
+    free (result);
+  }
+
+  { /* Width given as argument.  */
+    size_t length;
+    wchar_t *result =
+      my_asnwprintf (NULL, &length, L"%*x %d", 10, 12348, 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (wcscmp (result, L"      303c 33") == 0);
+    ASSERT (length == wcslen (result));
+    free (result);
+  }
+
+  { /* Negative width given as argument (cf. FLAG_LEFT below).  */
+    size_t length;
+    wchar_t *result =
+      my_asnwprintf (NULL, &length, L"%*x %d", -10, 12348, 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (wcscmp (result, L"303c       33") == 0);
+    ASSERT (length == wcslen (result));
+    free (result);
+  }
+
+  { /* Precision.  */
+    size_t length;
+    wchar_t *result =
+      my_asnwprintf (NULL, &length, L"%.10x %d", 12348, 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (wcscmp (result, L"000000303c 33") == 0);
+    ASSERT (length == wcslen (result));
+    free (result);
+  }
+
+  { /* Zero precision and a positive number.  */
+    size_t length;
+    wchar_t *result =
+      my_asnwprintf (NULL, &length, L"%.0x %d", 12348, 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (wcscmp (result, L"303c 33") == 0);
+    ASSERT (length == wcslen (result));
+    free (result);
+  }
+
+  { /* Zero precision and a zero number.  */
+    size_t length;
+    wchar_t *result =
+      my_asnwprintf (NULL, &length, L"%.0x %d", 0, 33, 44, 55);
+    ASSERT (result != NULL);
+    /* ISO C and POSIX specify that "The result of converting a zero value
+       with a precision of zero is no characters."  */
+    ASSERT (wcscmp (result, L" 33") == 0);
+    ASSERT (length == wcslen (result));
+    free (result);
+  }
+
+  { /* Width and precision.  */
+    size_t length;
+    wchar_t *result =
+      my_asnwprintf (NULL, &length, L"%15.10x %d", 12348, 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (wcscmp (result, L"     000000303c 33") == 0);
+    ASSERT (length == wcslen (result));
+    free (result);
+  }
+
+  { /* Padding and precision.  */
+    size_t length;
+    wchar_t *result =
+      my_asnwprintf (NULL, &length, L"%015.10x %d", 12348, 33, 44, 55);
+    ASSERT (result != NULL);
+    /* Neither ISO C nor POSIX specify that the '0' flag is ignored when a width
+       and a precision are both present.  But most implementations do so.  */
+    #if MUSL_LIBC || defined __MINGW32__
+    ASSERT (wcscmp (result, L"00000000000303c 33") == 0);
+    #else
+    ASSERT (wcscmp (result, L"     000000303c 33") == 0);
+    #endif
+    ASSERT (length == wcslen (result));
+    free (result);
+  }
+
+  { /* FLAG_LEFT.  */
+    size_t length;
+    wchar_t *result =
+      my_asnwprintf (NULL, &length, L"%-10x %d", 12348, 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (wcscmp (result, L"303c       33") == 0);
+    ASSERT (length == wcslen (result));
+    free (result);
+  }
+
+  { /* FLAG_ALT with zero.  */
+    size_t length;
+    wchar_t *result =
+      my_asnwprintf (NULL, &length, L"%#x %d", 0, 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (wcscmp (result, L"0 33") == 0);
+    ASSERT (length == wcslen (result));
+    free (result);
+  }
+
+  { /* FLAG_ALT with a positive number.  */
+    size_t length;
+    wchar_t *result =
+      my_asnwprintf (NULL, &length, L"%#x %d", 12348, 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (wcscmp (result, L"0x303c 33") == 0);
+    ASSERT (length == wcslen (result));
+    free (result);
+  }
+
+  { /* FLAG_ALT with a positive number and width.  */
+    size_t length;
+    wchar_t *result =
+      my_asnwprintf (NULL, &length, L"%#10x %d", 12348, 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (wcscmp (result, L"    0x303c 33") == 0);
+    ASSERT (length == wcslen (result));
+    free (result);
+  }
+
+  { /* FLAG_ALT with a positive number and padding.  */
+    size_t length;
+    wchar_t *result =
+      my_asnwprintf (NULL, &length, L"%0#10x %d", 12348, 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (wcscmp (result, L"0x0000303c 33") == 0);
+    ASSERT (length == wcslen (result));
+    free (result);
+  }
+
+  { /* FLAG_ALT with a positive number and precision.  */
+    size_t length;
+    wchar_t *result =
+      my_asnwprintf (NULL, &length, L"%0#.10x %d", 12348, 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (wcscmp (result, L"0x000000303c 33") == 0);
+    ASSERT (length == wcslen (result));
+    free (result);
+  }
+
+  { /* FLAG_ALT with a positive number and width and precision.  */
+    size_t length;
+    wchar_t *result =
+      my_asnwprintf (NULL, &length, L"%#15.10x %d", 12348, 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (wcscmp (result, L"   0x000000303c 33") == 0);
+    ASSERT (length == wcslen (result));
+    free (result);
+  }
+
+  { /* FLAG_ALT with a positive number and padding and precision.  */
+    size_t length;
+    wchar_t *result =
+      my_asnwprintf (NULL, &length, L"%0#15.10x %d", 12348, 33, 44, 55);
+    ASSERT (result != NULL);
+    /* Neither ISO C nor POSIX specify that the '0' flag is ignored when a width
+       and a precision are both present.  But most implementations do so.  */
+    #if MUSL_LIBC || defined __MINGW32__
+    ASSERT (wcscmp (result, L"0x000000000303c 33") == 0);
+    #else
+    ASSERT (wcscmp (result, L"   0x000000303c 33") == 0);
+    #endif
+    ASSERT (length == wcslen (result));
+    free (result);
+  }
+
+  { /* FLAG_ALT with a zero precision and a zero number.  */
+    size_t length;
+    wchar_t *result =
+      my_asnwprintf (NULL, &length, L"%#.0x %d", 0, 33, 44, 55);
+    ASSERT (result != NULL);
+    /* ISO C and POSIX specify that "The result of converting a zero value
+       with a precision of zero is no characters.", and the prefix is added
+       only for non-zero values.  */
+    ASSERT (wcscmp (result, L" 33") == 0);
+    ASSERT (length == wcslen (result));
+    free (result);
+  }
+
+  { /* Uppercase 'X'.  */
+    size_t length;
+    wchar_t *result =
+      my_asnwprintf (NULL, &length, L"%X %d", 12348, 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (wcscmp (result, L"303C 33") == 0);
+    ASSERT (length == wcslen (result));
+    free (result);
+  }
+
+  { /* Uppercase 'X' with FLAG_ALT.  */
+    size_t length;
+    wchar_t *result =
+      my_asnwprintf (NULL, &length, L"%#X %d", 12348, 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (wcscmp (result, L"0X303C 33") == 0);
+    ASSERT (length == wcslen (result));
+    free (result);
+  }
+
+  { /* Uppercase 'X' with FLAG_ALT and zero precision and a zero number.  */
+    size_t length;
+    wchar_t *result =
+      my_asnwprintf (NULL, &length, L"%#.0X %d", 0, 33, 44, 55);
+    ASSERT (result != NULL);
+    /* ISO C and POSIX specify that "The result of converting a zero value
+       with a precision of zero is no characters.", and the prefix is added
+       only for non-zero values.  */
+    ASSERT (wcscmp (result, L" 33") == 0);
+    ASSERT (length == wcslen (result));
+    free (result);
+  }
+
   /* Test the support of the 'b' conversion specifier for binary output of
      integers.  */
 
@@ -4085,6 +4338,60 @@ test_function (wchar_t * (*my_asnwprintf) (wchar_t *, size_t *, const wchar_t *,
     free (result);
   }
 
+  { /* Precision.  */
+    size_t length;
+    wchar_t *result =
+      my_asnwprintf (NULL, &length, L"%.20b %d", 12345, 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (wcscmp (result, L"00000011000000111001 33") == 0);
+    ASSERT (length == wcslen (result));
+    free (result);
+  }
+
+  { /* Zero precision and a positive number.  */
+    size_t length;
+    wchar_t *result =
+      my_asnwprintf (NULL, &length, L"%.0b %d", 12345, 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (wcscmp (result, L"11000000111001 33") == 0);
+    ASSERT (length == wcslen (result));
+    free (result);
+  }
+
+  { /* Zero precision and a zero number.  */
+    size_t length;
+    wchar_t *result =
+      my_asnwprintf (NULL, &length, L"%.0b %d", 0, 33, 44, 55);
+    ASSERT (result != NULL);
+    /* ISO C and POSIX specify that "The result of converting a zero value
+       with a precision of zero is no characters."  */
+    ASSERT (wcscmp (result, L" 33") == 0);
+    ASSERT (length == wcslen (result));
+    free (result);
+  }
+
+  { /* Width and precision.  */
+    size_t length;
+    wchar_t *result =
+      my_asnwprintf (NULL, &length, L"%25.20b %d", 12345, 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (wcscmp (result, L"     00000011000000111001 33") == 0);
+    ASSERT (length == wcslen (result));
+    free (result);
+  }
+
+  { /* Padding and precision.  */
+    size_t length;
+    wchar_t *result =
+      my_asnwprintf (NULL, &length, L"%025.20b %d", 12345, 33, 44, 55);
+    ASSERT (result != NULL);
+    /* Neither ISO C nor POSIX specify that the '0' flag is ignored when
+       a width and a precision are both present.  But implementations do so.  */
+    ASSERT (wcscmp (result, L"     00000011000000111001 33") == 0);
+    ASSERT (length == wcslen (result));
+    free (result);
+  }
+
   { /* FLAG_LEFT.  */
     size_t length;
     wchar_t *result =
@@ -4099,6 +4406,7 @@ test_function (wchar_t * (*my_asnwprintf) (wchar_t *, size_t *, const wchar_t *,
     size_t length;
     wchar_t *result =
       my_asnwprintf (NULL, &length, L"%#b %d", 0, 33, 44, 55);
+    ASSERT (result != NULL);
     ASSERT (wcscmp (result, L"0 33") == 0);
     ASSERT (length == wcslen (result));
     free (result);
@@ -4108,11 +4416,77 @@ test_function (wchar_t * (*my_asnwprintf) (wchar_t *, size_t *, const wchar_t *,
     size_t length;
     wchar_t *result =
       my_asnwprintf (NULL, &length, L"%#b %d", 12345, 33, 44, 55);
+    ASSERT (result != NULL);
     ASSERT (wcscmp (result, L"0b11000000111001 33") == 0);
     ASSERT (length == wcslen (result));
     free (result);
   }
 
+  { /* FLAG_ALT with a positive number and width.  */
+    size_t length;
+    wchar_t *result =
+      my_asnwprintf (NULL, &length, L"%#20b %d", 12345, 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (wcscmp (result, L"    0b11000000111001 33") == 0);
+    ASSERT (length == wcslen (result));
+    free (result);
+  }
+
+  { /* FLAG_ALT with a positive number and padding.  */
+    size_t length;
+    wchar_t *result =
+      my_asnwprintf (NULL, &length, L"%0#20b %d", 12345, 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (wcscmp (result, L"0b000011000000111001 33") == 0);
+    ASSERT (length == wcslen (result));
+    free (result);
+  }
+
+  { /* FLAG_ALT with a positive number and precision.  */
+    size_t length;
+    wchar_t *result =
+      my_asnwprintf (NULL, &length, L"%0#.20b %d", 12345, 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (wcscmp (result, L"0b00000011000000111001 33") == 0);
+    ASSERT (length == wcslen (result));
+    free (result);
+  }
+
+  { /* FLAG_ALT with a positive number and width and precision.  */
+    size_t length;
+    wchar_t *result =
+      my_asnwprintf (NULL, &length, L"%#25.20b %d", 12345, 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (wcscmp (result, L"   0b00000011000000111001 33") == 0);
+    ASSERT (length == wcslen (result));
+    free (result);
+  }
+
+  { /* FLAG_ALT with a positive number and padding and precision.  */
+    size_t length;
+    wchar_t *result =
+      my_asnwprintf (NULL, &length, L"%0#25.20b %d", 12345, 33, 44, 55);
+    ASSERT (result != NULL);
+    /* Neither ISO C nor POSIX specify that the '0' flag is ignored when
+       a width and a precision are both present.  But implementations do so.  */
+    ASSERT (wcscmp (result, L"   0b00000011000000111001 33") == 0);
+    ASSERT (length == wcslen (result));
+    free (result);
+  }
+
+  { /* FLAG_ALT with a zero precision and a zero number.  */
+    size_t length;
+    wchar_t *result =
+      my_asnwprintf (NULL, &length, L"%#.0b %d", 0, 33, 44, 55);
+    ASSERT (result != NULL);
+    /* ISO C and POSIX specify that "The result of converting a zero value
+       with a precision of zero is no characters.", and the prefix is added
+       only for non-zero values.  */
+    ASSERT (wcscmp (result, L" 33") == 0);
+    ASSERT (length == wcslen (result));
+    free (result);
+  }
+
 #if (__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 2)) && !defined __UCLIBC__
   /* Test that the 'I' flag is supported.  */
   {
index 46086ef2512e716da29b0e3324f723078e38d2f9..0da0c7441b1b7a1192082653ec1c7cd6e70220a3 100644 (file)
@@ -3956,6 +3956,259 @@ test_function (int (*my_asprintf) (char **, const char *, ...))
   }
 #endif
 
+  /* Test the support of the 'x' conversion specifier for hexadecimal output of
+     integers.  */
+
+  { /* Zero.  */
+    char *result;
+    int retval =
+      my_asprintf (&result, "%x %d", 0, 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (strcmp (result, "0 33") == 0);
+    ASSERT (retval == strlen (result));
+    free (result);
+  }
+
+  { /* A positive number.  */
+    char *result;
+    int retval =
+      my_asprintf (&result, "%x %d", 12348, 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (strcmp (result, "303c 33") == 0);
+    ASSERT (retval == strlen (result));
+    free (result);
+  }
+
+  { /* A large positive number.  */
+    char *result;
+    int retval =
+      my_asprintf (&result, "%x %d", 0xFFFFFFFEU, 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (strcmp (result, "fffffffe 33") == 0);
+    ASSERT (retval == strlen (result));
+    free (result);
+  }
+
+  { /* Width.  */
+    char *result;
+    int retval =
+      my_asprintf (&result, "%10x %d", 12348, 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (strcmp (result, "      303c 33") == 0);
+    ASSERT (retval == strlen (result));
+    free (result);
+  }
+
+  { /* Width given as argument.  */
+    char *result;
+    int retval =
+      my_asprintf (&result, "%*x %d", 10, 12348, 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (strcmp (result, "      303c 33") == 0);
+    ASSERT (retval == strlen (result));
+    free (result);
+  }
+
+  { /* Negative width given as argument (cf. FLAG_LEFT below).  */
+    char *result;
+    int retval =
+      my_asprintf (&result, "%*x %d", -10, 12348, 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (strcmp (result, "303c       33") == 0);
+    ASSERT (retval == strlen (result));
+    free (result);
+  }
+
+  { /* Precision.  */
+    char *result;
+    int retval =
+      my_asprintf (&result, "%.10x %d", 12348, 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (strcmp (result, "000000303c 33") == 0);
+    ASSERT (retval == strlen (result));
+    free (result);
+  }
+
+  { /* Zero precision and a positive number.  */
+    char *result;
+    int retval =
+      my_asprintf (&result, "%.0x %d", 12348, 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (strcmp (result, "303c 33") == 0);
+    ASSERT (retval == strlen (result));
+    free (result);
+  }
+
+  { /* Zero precision and a zero number.  */
+    char *result;
+    int retval =
+      my_asprintf (&result, "%.0x %d", 0, 33, 44, 55);
+    ASSERT (result != NULL);
+    /* ISO C and POSIX specify that "The result of converting a zero value
+       with a precision of zero is no characters."  */
+    ASSERT (strcmp (result, " 33") == 0);
+    ASSERT (retval == strlen (result));
+    free (result);
+  }
+
+  { /* Width and precision.  */
+    char *result;
+    int retval =
+      my_asprintf (&result, "%15.10x %d", 12348, 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (strcmp (result, "     000000303c 33") == 0);
+    ASSERT (retval == strlen (result));
+    free (result);
+  }
+
+  { /* Padding and precision.  */
+    char *result;
+    int retval =
+      my_asprintf (&result, "%015.10x %d", 12348, 33, 44, 55);
+    ASSERT (result != NULL);
+    /* Neither ISO C nor POSIX specify that the '0' flag is ignored when a width
+       and a precision are both present.  But most implementations do so.  */
+    #ifdef __MINGW32__
+    ASSERT (strcmp (result, "00000000000303c 33") == 0);
+    #else
+    ASSERT (strcmp (result, "     000000303c 33") == 0);
+    #endif
+    ASSERT (retval == strlen (result));
+    free (result);
+  }
+
+  { /* FLAG_LEFT.  */
+    char *result;
+    int retval =
+      my_asprintf (&result, "%-10x %d", 12348, 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (strcmp (result, "303c       33") == 0);
+    ASSERT (retval == strlen (result));
+    free (result);
+  }
+
+  { /* FLAG_ALT with zero.  */
+    char *result;
+    int retval =
+      my_asprintf (&result, "%#x %d", 0, 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (strcmp (result, "0 33") == 0);
+    ASSERT (retval == strlen (result));
+    free (result);
+  }
+
+  { /* FLAG_ALT with a positive number.  */
+    char *result;
+    int retval =
+      my_asprintf (&result, "%#x %d", 12348, 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (strcmp (result, "0x303c 33") == 0);
+    ASSERT (retval == strlen (result));
+    free (result);
+  }
+
+  { /* FLAG_ALT with a positive number and width.  */
+    char *result;
+    int retval =
+      my_asprintf (&result, "%#10x %d", 12348, 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (strcmp (result, "    0x303c 33") == 0);
+    ASSERT (retval == strlen (result));
+    free (result);
+  }
+
+  { /* FLAG_ALT with a positive number and padding.  */
+    char *result;
+    int retval =
+      my_asprintf (&result, "%0#10x %d", 12348, 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (strcmp (result, "0x0000303c 33") == 0);
+    ASSERT (retval == strlen (result));
+    free (result);
+  }
+
+  { /* FLAG_ALT with a positive number and precision.  */
+    char *result;
+    int retval =
+      my_asprintf (&result, "%0#.10x %d", 12348, 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (strcmp (result, "0x000000303c 33") == 0);
+    ASSERT (retval == strlen (result));
+    free (result);
+  }
+
+  { /* FLAG_ALT with a positive number and width and precision.  */
+    char *result;
+    int retval =
+      my_asprintf (&result, "%#15.10x %d", 12348, 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (strcmp (result, "   0x000000303c 33") == 0);
+    ASSERT (retval == strlen (result));
+    free (result);
+  }
+
+  { /* FLAG_ALT with a positive number and padding and precision.  */
+    char *result;
+    int retval =
+      my_asprintf (&result, "%0#15.10x %d", 12348, 33, 44, 55);
+    ASSERT (result != NULL);
+    /* Neither ISO C nor POSIX specify that the '0' flag is ignored when a width
+       and a precision are both present.  But most implementations do so.  */
+    #ifdef __MINGW32__
+    ASSERT (strcmp (result, "0x000000000303c 33") == 0);
+    #else
+    ASSERT (strcmp (result, "   0x000000303c 33") == 0);
+    #endif
+    ASSERT (retval == strlen (result));
+    free (result);
+  }
+
+  { /* FLAG_ALT with a zero precision and a zero number.  */
+    char *result;
+    int retval =
+      my_asprintf (&result, "%#.0x %d", 0, 33, 44, 55);
+    ASSERT (result != NULL);
+    /* ISO C and POSIX specify that "The result of converting a zero value
+       with a precision of zero is no characters.", and the prefix is added
+       only for non-zero values.  */
+    ASSERT (strcmp (result, " 33") == 0);
+    ASSERT (retval == strlen (result));
+    free (result);
+  }
+
+  { /* Uppercase 'X'.  */
+    char *result;
+    int retval =
+      my_asprintf (&result, "%X %d", 12348, 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (strcmp (result, "303C 33") == 0);
+    ASSERT (retval == strlen (result));
+    free (result);
+  }
+
+  { /* Uppercase 'X' with FLAG_ALT.  */
+    char *result;
+    int retval =
+      my_asprintf (&result, "%#X %d", 12348, 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (strcmp (result, "0X303C 33") == 0);
+    ASSERT (retval == strlen (result));
+    free (result);
+  }
+
+  { /* Uppercase 'X' with FLAG_ALT and zero precision and a zero number.  */
+    char *result;
+    int retval =
+      my_asprintf (&result, "%#.0X %d", 0, 33, 44, 55);
+    ASSERT (result != NULL);
+    /* ISO C and POSIX specify that "The result of converting a zero value
+       with a precision of zero is no characters.", and the prefix is added
+       only for non-zero values.  */
+    ASSERT (strcmp (result, " 33") == 0);
+    ASSERT (retval == strlen (result));
+    free (result);
+  }
+
   /* Test the support of the 'b' conversion specifier for binary output of
      integers.  */
 
@@ -4019,6 +4272,60 @@ test_function (int (*my_asprintf) (char **, const char *, ...))
     free (result);
   }
 
+  { /* Precision.  */
+    char *result;
+    int retval =
+      my_asprintf (&result, "%.20b %d", 12345, 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (strcmp (result, "00000011000000111001 33") == 0);
+    ASSERT (retval == strlen (result));
+    free (result);
+  }
+
+  { /* Zero precision and a positive number.  */
+    char *result;
+    int retval =
+      my_asprintf (&result, "%.0b %d", 12345, 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (strcmp (result, "11000000111001 33") == 0);
+    ASSERT (retval == strlen (result));
+    free (result);
+  }
+
+  { /* Zero precision and a zero number.  */
+    char *result;
+    int retval =
+      my_asprintf (&result, "%.0b %d", 0, 33, 44, 55);
+    ASSERT (result != NULL);
+    /* ISO C and POSIX specify that "The result of converting a zero value
+       with a precision of zero is no characters."  */
+    ASSERT (strcmp (result, " 33") == 0);
+    ASSERT (retval == strlen (result));
+    free (result);
+  }
+
+  { /* Width and precision.  */
+    char *result;
+    int retval =
+      my_asprintf (&result, "%25.20b %d", 12345, 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (strcmp (result, "     00000011000000111001 33") == 0);
+    ASSERT (retval == strlen (result));
+    free (result);
+  }
+
+  { /* Padding and precision.  */
+    char *result;
+    int retval =
+      my_asprintf (&result, "%025.20b %d", 12345, 33, 44, 55);
+    ASSERT (result != NULL);
+    /* Neither ISO C nor POSIX specify that the '0' flag is ignored when
+       a width and a precision are both present.  But implementations do so.  */
+    ASSERT (strcmp (result, "     00000011000000111001 33") == 0);
+    ASSERT (retval == strlen (result));
+    free (result);
+  }
+
   { /* FLAG_LEFT.  */
     char *result;
     int retval =
@@ -4033,6 +4340,7 @@ test_function (int (*my_asprintf) (char **, const char *, ...))
     char *result;
     int retval =
       my_asprintf (&result, "%#b %d", 0, 33, 44, 55);
+    ASSERT (result != NULL);
     ASSERT (strcmp (result, "0 33") == 0);
     ASSERT (retval == strlen (result));
     free (result);
@@ -4042,10 +4350,76 @@ test_function (int (*my_asprintf) (char **, const char *, ...))
     char *result;
     int retval =
       my_asprintf (&result, "%#b %d", 12345, 33, 44, 55);
+    ASSERT (result != NULL);
     ASSERT (strcmp (result, "0b11000000111001 33") == 0);
     ASSERT (retval == strlen (result));
     free (result);
   }
+
+  { /* FLAG_ALT with a positive number and width.  */
+    char *result;
+    int retval =
+      my_asprintf (&result, "%#20b %d", 12345, 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (strcmp (result, "    0b11000000111001 33") == 0);
+    ASSERT (retval == strlen (result));
+    free (result);
+  }
+
+  { /* FLAG_ALT with a positive number and padding.  */
+    char *result;
+    int retval =
+      my_asprintf (&result, "%0#20b %d", 12345, 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (strcmp (result, "0b000011000000111001 33") == 0);
+    ASSERT (retval == strlen (result));
+    free (result);
+  }
+
+  { /* FLAG_ALT with a positive number and precision.  */
+    char *result;
+    int retval =
+      my_asprintf (&result, "%0#.20b %d", 12345, 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (strcmp (result, "0b00000011000000111001 33") == 0);
+    ASSERT (retval == strlen (result));
+    free (result);
+  }
+
+  { /* FLAG_ALT with a positive number and width and precision.  */
+    char *result;
+    int retval =
+      my_asprintf (&result, "%#25.20b %d", 12345, 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (strcmp (result, "   0b00000011000000111001 33") == 0);
+    ASSERT (retval == strlen (result));
+    free (result);
+  }
+
+  { /* FLAG_ALT with a positive number and padding and precision.  */
+    char *result;
+    int retval =
+      my_asprintf (&result, "%0#25.20b %d", 12345, 33, 44, 55);
+    ASSERT (result != NULL);
+    /* Neither ISO C nor POSIX specify that the '0' flag is ignored when
+       a width and a precision are both present.  But implementations do so.  */
+    ASSERT (strcmp (result, "   0b00000011000000111001 33") == 0);
+    ASSERT (retval == strlen (result));
+    free (result);
+  }
+
+  { /* FLAG_ALT with a zero precision and a zero number.  */
+    char *result;
+    int retval =
+      my_asprintf (&result, "%#.0b %d", 0, 33, 44, 55);
+    ASSERT (result != NULL);
+    /* ISO C and POSIX specify that "The result of converting a zero value
+       with a precision of zero is no characters.", and the prefix is added
+       only for non-zero values.  */
+    ASSERT (strcmp (result, " 33") == 0);
+    ASSERT (retval == strlen (result));
+    free (result);
+  }
 }
 
 static int