]> Savannah Git Hosting - gnulib.git/commitdiff
vasnprintf, vasnwprintf: Make '0' flag handling more ISO C compliant.
authorBruno Haible <bruno@clisp.org>
Wed, 3 May 2023 15:09:20 +0000 (17:09 +0200)
committerBruno Haible <bruno@clisp.org>
Wed, 3 May 2023 15:09:20 +0000 (17:09 +0200)
* lib/vasnprintf.c (VASNPRINTF): When doing the padding ourselves,
ignore the '0' flag if a precision is specified and the conversion is
one of d, i, o, u, x, X, b, B.
* tests/test-vasnprintf-posix.c (test_function): Update expected results
accordingly.
* tests/test-vasprintf-posix.c (test_function): Likewise.
* tests/test-snprintf-posix.h (test_function): Likewise.
* tests/test-sprintf-posix.h (test_function): Likewise.
* tests/test-vasnwprintf-posix.c (test_function): Likewise.

ChangeLog
lib/vasnprintf.c
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 6323068ffd6932d5361963d672b6aeb679e60811..ac0153693e0758e679afb17093555484b60346be 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,16 @@
+2023-05-03  Bruno Haible  <bruno@clisp.org>
+
+       vasnprintf, vasnwprintf: Make '0' flag handling more ISO C compliant.
+       * lib/vasnprintf.c (VASNPRINTF): When doing the padding ourselves,
+       ignore the '0' flag if a precision is specified and the conversion is
+       one of d, i, o, u, x, X, b, B.
+       * tests/test-vasnprintf-posix.c (test_function): Update expected results
+       accordingly.
+       * tests/test-vasprintf-posix.c (test_function): Likewise.
+       * tests/test-snprintf-posix.h (test_function): Likewise.
+       * tests/test-sprintf-posix.h (test_function): Likewise.
+       * tests/test-vasnwprintf-posix.c (test_function): Likewise.
+
 2023-05-02  Paul Eggert  <eggert@cs.ucla.edu>
 
        mktime: include <intprops.h>
index efd610ebe4a1d86bc41bd3c8f571fa5e4cf9fd0f..802790e14e4734a80c4baf8f2ed93a5f0c73fca6 100644 (file)
@@ -5612,7 +5612,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
 #if !USE_SNPRINTF || WIDE_CHAR_VERSION || !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF || !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_LEFTADJUST || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION
                 size_t width;
 #endif
-#if !USE_SNPRINTF || (WIDE_CHAR_VERSION && DCHAR_IS_TCHAR) || !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF || NEED_PRINTF_UNBOUNDED_PRECISION
+#if !USE_SNPRINTF || (WIDE_CHAR_VERSION && DCHAR_IS_TCHAR) || !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF || (WIDE_CHAR_VERSION && MUSL_LIBC) || !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_LEFTADJUST || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION
                 int has_precision;
                 size_t precision;
 #endif
@@ -5669,13 +5669,13 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
                           width = xsum (xtimes (width, 10), *digitp++ - '0');
                         while (digitp != dp->width_end);
                       }
-#if (WIDE_CHAR_VERSION && MUSL_LIBC) || !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_LEFTADJUST || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION
+# if (WIDE_CHAR_VERSION && MUSL_LIBC) || !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_LEFTADJUST || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION
                     has_width = 1;
-#endif
+# endif
                   }
 #endif
 
-#if !USE_SNPRINTF || (WIDE_CHAR_VERSION && DCHAR_IS_TCHAR) || !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF || NEED_PRINTF_UNBOUNDED_PRECISION
+#if !USE_SNPRINTF || (WIDE_CHAR_VERSION && DCHAR_IS_TCHAR) || !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF || (WIDE_CHAR_VERSION && MUSL_LIBC) || !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_LEFTADJUST || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION
                 has_precision = 0;
                 precision = 6;
                 if (dp->precision_start != dp->precision_end)
@@ -6794,7 +6794,22 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
                                   for (; pad > 0; pad--)
                                     *p++ = ' ';
                                 }
-                              else if ((flags & FLAG_ZERO) && pad_ptr != NULL)
+                              else if ((flags & FLAG_ZERO) && pad_ptr != NULL
+                                       /* ISO C says: "For d, i, o, u, x, and X
+                                          conversions, if a precision is
+                                          specified, the 0 flag is ignored.  */
+                                       && !(has_precision
+                                            && (dp->conversion == 'd'
+                                                || dp->conversion == 'i'
+                                                || dp->conversion == 'o'
+                                                || dp->conversion == 'u'
+                                                || dp->conversion == 'x'
+                                                || dp->conversion == 'X'
+                                                /* Although ISO C does not
+                                                   require it, treat 'b' and 'B'
+                                                   like 'x' and 'X'.  */
+                                                || dp->conversion == 'b'
+                                                || dp->conversion == 'B')))
                                 {
                                   /* Pad with zeroes.  */
                                   DCHAR_T *q = end;
index 5b81910ec3e34d3a79978cd00545f86316d85193..482335a3ef54655ce2de5abecaea1f4b3154a28d 100644 (file)
@@ -3187,14 +3187,9 @@ test_function (int (*my_snprintf) (char *, size_t, const char *, ...))
   { /* 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 /* mingw 5 */
-            || strcmp (result, "     000000303c 33") == 0 /* mingw 10 */);
-    #else
+    /* ISO C 99 § 7.19.6.1.(6) says: "For d, i, o, u, x, and X conversions, if a
+       precision is specified, the 0 flag is ignored."  */
     ASSERT (strcmp (result, "     000000303c 33") == 0);
-    #endif
     ASSERT (retval == strlen (result));
   }
 
@@ -3250,14 +3245,9 @@ test_function (int (*my_snprintf) (char *, size_t, const char *, ...))
   { /* 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 /* mingw 5 */
-            || strcmp (result, "   0x000000303c 33") == 0 /* mingw 10 */);
-    #else
+    /* ISO C 99 § 7.19.6.1.(6) says: "For d, i, o, u, x, and X conversions, if a
+       precision is specified, the 0 flag is ignored."  */
     ASSERT (strcmp (result, "   0x000000303c 33") == 0);
-    #endif
     ASSERT (retval == strlen (result));
   }
 
index a0b5eb3391636e7792c9f741b552f58eeb528592..c0957a69677e22805419cf0eece9e51750490bdf 100644 (file)
@@ -3163,14 +3163,9 @@ test_function (int (*my_sprintf) (char *, const char *, ...))
   { /* 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 /* mingw 5 */
-            || strcmp (result, "     000000303c 33") == 0 /* mingw 10 */);
-    #else
+    /* ISO C 99 § 7.19.6.1.(6) says: "For d, i, o, u, x, and X conversions, if a
+       precision is specified, the 0 flag is ignored."  */
     ASSERT (strcmp (result, "     000000303c 33") == 0);
-    #endif
     ASSERT (retval == strlen (result));
   }
 
@@ -3226,14 +3221,9 @@ test_function (int (*my_sprintf) (char *, const char *, ...))
   { /* 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 /* mingw 5 */
-            || strcmp (result, "   0x000000303c 33") == 0 /* mingw 10 */);
-    #else
+    /* ISO C 99 § 7.19.6.1.(6) says: "For d, i, o, u, x, and X conversions, if a
+       precision is specified, the 0 flag is ignored."  */
     ASSERT (strcmp (result, "   0x000000303c 33") == 0);
-    #endif
     ASSERT (retval == strlen (result));
   }
 
index 51b1d26a337dff16f18fb3570964a4d6989a99ef..33387c32e7a39a3b4cbd3b4744d2cb07c1eb84a1 100644 (file)
@@ -4145,14 +4145,9 @@ test_function (char * (*my_asnprintf) (char *, size_t *, const char *, ...))
     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 /* mingw 5 */
-            || strcmp (result, "     000000303c 33") == 0 /* mingw 10 */);
-    #else
+    /* ISO C 99 § 7.19.6.1.(6) says: "For d, i, o, u, x, and X conversions, if a
+       precision is specified, the 0 flag is ignored."  */
     ASSERT (strcmp (result, "     000000303c 33") == 0);
-    #endif
     ASSERT (length == strlen (result));
     free (result);
   }
@@ -4232,14 +4227,9 @@ test_function (char * (*my_asnprintf) (char *, size_t *, const char *, ...))
     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 /* mingw 5 */
-            || strcmp (result, "   0x000000303c 33") == 0 /* mingw 10 */);
-    #else
+    /* ISO C 99 § 7.19.6.1.(6) says: "For d, i, o, u, x, and X conversions, if a
+       precision is specified, the 0 flag is ignored."  */
     ASSERT (strcmp (result, "   0x000000303c 33") == 0);
-    #endif
     ASSERT (length == strlen (result));
     free (result);
   }
index 67e6654e5c9cec30118ba53f92e39f9b04198cc4..351fc8b8c22d2855add7352a9edbdeabb1b50030 100644 (file)
@@ -4203,13 +4203,9 @@ test_function (wchar_t * (*my_asnwprintf) (wchar_t *, size_t *, const wchar_t *,
     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
-    ASSERT (wcscmp (result, L"00000000000303c 33") == 0);
-    #else
+    /* ISO C 99 § 7.24.2.1.(6) says: "For d, i, o, u, x, and X conversions, if a
+       precision is specified, the 0 flag is ignored."  */
     ASSERT (wcscmp (result, L"     000000303c 33") == 0);
-    #endif
     ASSERT (length == wcslen (result));
     free (result);
   }
@@ -4289,13 +4285,9 @@ test_function (wchar_t * (*my_asnwprintf) (wchar_t *, size_t *, const wchar_t *,
     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
-    ASSERT (wcscmp (result, L"0x000000000303c 33") == 0);
-    #else
+    /* ISO C 99 § 7.24.2.1.(6) says: "For d, i, o, u, x, and X conversions, if a
+       precision is specified, the 0 flag is ignored."  */
     ASSERT (wcscmp (result, L"   0x000000303c 33") == 0);
-    #endif
     ASSERT (length == wcslen (result));
     free (result);
   }
index 858a477a439e7545e1270e826d8c599e7720e31c..897109537ff73e8d36ce9b5a64df8e298528752e 100644 (file)
@@ -4086,14 +4086,9 @@ test_function (int (*my_asprintf) (char **, const char *, ...))
     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 /* mingw 5 */
-            || strcmp (result, "     000000303c 33") == 0 /* mingw 10 */);
-    #else
+    /* ISO C 99 § 7.19.6.1.(6) says: "For d, i, o, u, x, and X conversions, if a
+       precision is specified, the 0 flag is ignored."  */
     ASSERT (strcmp (result, "     000000303c 33") == 0);
-    #endif
     ASSERT (retval == strlen (result));
     free (result);
   }
@@ -4173,14 +4168,9 @@ test_function (int (*my_asprintf) (char **, const char *, ...))
     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 /* mingw 5 */
-            || strcmp (result, "   0x000000303c 33") == 0 /* mingw 10 */);
-    #else
+    /* ISO C 99 § 7.19.6.1.(6) says: "For d, i, o, u, x, and X conversions, if a
+       precision is specified, the 0 flag is ignored."  */
     ASSERT (strcmp (result, "   0x000000303c 33") == 0);
-    #endif
     ASSERT (retval == strlen (result));
     free (result);
   }