]> Savannah Git Hosting - gnulib.git/commitdiff
unistdio/u*-vasnprintf: Fix handling of grouping rule.
authorBruno Haible <bruno@clisp.org>
Fri, 25 Apr 2025 21:26:25 +0000 (23:26 +0200)
committerBruno Haible <bruno@clisp.org>
Fri, 25 Apr 2025 21:30:04 +0000 (23:30 +0200)
Reported by Collin Funk in
<https://lists.gnu.org/archive/html/bug-gnulib/2025-04/msg00180.html>.

* lib/unistdio/u8-vasnprintf.c (DCHAR_STRLEN): New macro.
* lib/unistdio/u8-u8-vasnprintf.c (DCHAR_STRLEN): Likewise.
* lib/unistdio/u16-vasnprintf.c (DCHAR_STRLEN): Likewise.
* lib/unistdio/u16-u16-vasnprintf.c (DCHAR_STRLEN): Likewise.
* lib/unistdio/u32-vasnprintf.c (DCHAR_STRLEN): Likewise.
* lib/unistdio/u32-u32-vasnprintf.c (DCHAR_STRLEN): Likewise.
* lib/unistdio/ulc-vasnprintf.c (DCHAR_STRLEN): Likewise.
* lib/vasnprintf.c (DCHAR_STRLEN): Define fallback.
(thousands_separator_DCHAR): New function.
(VASNPRINTF): Use it when DCHAR_T is uintN_t. Use DCHAR_CPY instead of
memcpy.

ChangeLog
lib/unistdio/u16-u16-vasnprintf.c
lib/unistdio/u16-vasnprintf.c
lib/unistdio/u32-u32-vasnprintf.c
lib/unistdio/u32-vasnprintf.c
lib/unistdio/u8-u8-vasnprintf.c
lib/unistdio/u8-vasnprintf.c
lib/unistdio/ulc-vasnprintf.c
lib/vasnprintf.c

index e01f8745374b2c7dfdc3086881c6fa1937a9c084..99c2c9c8930c60b90fcf083c9130f9cbb89d65ba 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,20 @@
+2025-04-25  Bruno Haible  <bruno@clisp.org>
+
+       unistdio/u*-vasnprintf: Fix handling of grouping rule.
+       Reported by Collin Funk in
+       <https://lists.gnu.org/archive/html/bug-gnulib/2025-04/msg00180.html>.
+       * lib/unistdio/u8-vasnprintf.c (DCHAR_STRLEN): New macro.
+       * lib/unistdio/u8-u8-vasnprintf.c (DCHAR_STRLEN): Likewise.
+       * lib/unistdio/u16-vasnprintf.c (DCHAR_STRLEN): Likewise.
+       * lib/unistdio/u16-u16-vasnprintf.c (DCHAR_STRLEN): Likewise.
+       * lib/unistdio/u32-vasnprintf.c (DCHAR_STRLEN): Likewise.
+       * lib/unistdio/u32-u32-vasnprintf.c (DCHAR_STRLEN): Likewise.
+       * lib/unistdio/ulc-vasnprintf.c (DCHAR_STRLEN): Likewise.
+       * lib/vasnprintf.c (DCHAR_STRLEN): Define fallback.
+       (thousands_separator_DCHAR): New function.
+       (VASNPRINTF): Use it when DCHAR_T is uintN_t. Use DCHAR_CPY instead of
+       memcpy.
+
 2025-04-24  Bruno Haible  <bruno@clisp.org>
 
        modula2comp-script: New module.
index 473e56540ce161bf2705e564da2ad665cc520503..e38c39067d888d183ad815f56ae4642d9acab53a 100644 (file)
@@ -48,6 +48,7 @@
 #define DCHAR_T uint16_t
 #define DCHAR_CPY u16_cpy
 #define DCHAR_SET u16_set
+#define DCHAR_STRLEN u16_strlen
 #define DCHAR_MBSNLEN u16_mbsnlen
 #define DCHAR_IS_UINT16_T 1
 #define U8_TO_DCHAR u8_to_u16
index 8b1b3659dcdcb152b8b24b31352d8fcbba274e22..be857749d6bb19372ff9213d331a36aabe2b1957 100644 (file)
@@ -49,6 +49,7 @@
 #define DCHAR_T uint16_t
 #define DCHAR_CPY u16_cpy
 #define DCHAR_SET u16_set
+#define DCHAR_STRLEN u16_strlen
 #define DCHAR_MBSNLEN u16_mbsnlen
 #define DCHAR_IS_UINT16_T 1
 #define U8_TO_DCHAR u8_to_u16
index a051371647f38521bba9c14e0048888fe739a7f1..3bb7dece590dde2d19e679cf53bb8db65a47b9e6 100644 (file)
@@ -48,6 +48,7 @@
 #define DCHAR_T uint32_t
 #define DCHAR_CPY u32_cpy
 #define DCHAR_SET u32_set
+#define DCHAR_STRLEN u32_strlen
 #define DCHAR_MBSNLEN u32_mbsnlen
 #define DCHAR_IS_UINT32_T 1
 #define U8_TO_DCHAR u8_to_u32
index 56f3b05c31d3ed11045d570e2030a88183ccd3c3..c79f53565f6fc9ccb8d9f00f9829d1e5b3eefaa0 100644 (file)
@@ -49,6 +49,7 @@
 #define DCHAR_T uint32_t
 #define DCHAR_CPY u32_cpy
 #define DCHAR_SET u32_set
+#define DCHAR_STRLEN u32_strlen
 #define DCHAR_MBSNLEN u32_mbsnlen
 #define DCHAR_IS_UINT32_T 1
 #define U8_TO_DCHAR u8_to_u32
index f03fb29ef22e48f33dfa5f9e5c3a6636a88dc076..ad9dc510f713be6f933d4d58f25d4229b228f380 100644 (file)
@@ -48,6 +48,7 @@
 #define DCHAR_T uint8_t
 #define DCHAR_CPY u8_cpy
 #define DCHAR_SET u8_set
+#define DCHAR_STRLEN u8_strlen
 #define DCHAR_MBSNLEN u8_mbsnlen
 #define DCHAR_IS_UINT8_T 1
 #define U16_TO_DCHAR u16_to_u8
index 61fc236dfa756d77418b3d10687eb5dd369dc669..88e59ae4ad730efdfe8cf1979ba894c52666bb42 100644 (file)
@@ -49,6 +49,7 @@
 #define DCHAR_T uint8_t
 #define DCHAR_CPY u8_cpy
 #define DCHAR_SET u8_set
+#define DCHAR_STRLEN u8_strlen
 #define DCHAR_MBSNLEN u8_mbsnlen
 #define DCHAR_IS_UINT8_T 1
 #define U16_TO_DCHAR u16_to_u8
index 50f3b16aa55c4492f67e969ca61c18132f0c02dc..50ae4f7eb7f68f1aa380fb7607cc6d5ba265b33c 100644 (file)
@@ -49,6 +49,7 @@
 #define DCHAR_T char
 #define DCHAR_CPY memcpy
 #define DCHAR_SET memset
+#define DCHAR_STRLEN strlen
 #define DCHAR_MBSNLEN mbsnlen
 #define TCHAR_T char
 #define DCHAR_IS_TCHAR 1
index 4004133ae4763bac2a4b7d03700632beb1d21a16..f1bfcf31616764531fabfd508b29dadd15b48aab 100644 (file)
@@ -29,6 +29,7 @@
                         Depends on FCHAR_T.
      DCHAR_CPY          memcpy like function for DCHAR_T[] arrays.
      DCHAR_SET          memset like function for DCHAR_T[] arrays.
+     DCHAR_STRLEN       strlen like function for DCHAR_T[] arrays.
      DCHAR_MBSNLEN      mbsnlen like function for DCHAR_T[] arrays.
      SNPRINTF           The system's snprintf (or similar) function.
                         This may be either snprintf or swprintf.
 #   define TCHAR_T char
 # endif
 #endif
+#ifndef DCHAR_STRLEN
+# if WIDE_CHAR_VERSION
+#  define DCHAR_STRLEN local_wcslen
+# else
+#  define DCHAR_STRLEN strlen
+# endif
+#endif
 #ifndef DCHAR_MBSNLEN
 # if WIDE_CHAR_VERSION
 #  define DCHAR_MBSNLEN wcsnlen
@@ -439,8 +447,43 @@ thousands_separator_char (char stackbuf[10])
 }
 # endif
 #endif
-/* Maximum number of 'char' in the char[] representation of the thousands
-   separator.  */
+#if !WIDE_CHAR_VERSION && defined DCHAR_CONV_FROM_ENCODING && (NEED_PRINTF_DOUBLE || NEED_PRINTF_LONG_DOUBLE)
+/* Determine the thousands-separator character, as a DCHAR_T[] array,
+   according to the current locale.
+   It is a single Unicode character.  */
+# ifndef thousands_separator_DCHAR_defined
+#  define thousands_separator_DCHAR_defined 1
+static const DCHAR_T *
+thousands_separator_DCHAR (DCHAR_T stackbuf[10])
+{
+  /* Determine it in a multithread-safe way.  */
+  char tmpbuf[10];
+  const char *tmp = thousands_separator_char (tmpbuf);
+  if (*tmp != '\0')
+    {
+      /* Convert it from char[] to DCHAR_T[].  */
+      size_t converted_len = 10;
+      DCHAR_T *converted =
+        DCHAR_CONV_FROM_ENCODING (locale_charset (),
+                                  iconveh_question_mark,
+                                  tmp, strlen (tmp) + 1,
+                                  NULL,
+                                  stackbuf, &converted_len);
+      if (converted != NULL)
+        {
+          if (converted != stackbuf)
+            /* It should not be so long.  */
+            abort ();
+          return stackbuf;
+        }
+    }
+  stackbuf[0] = 0;
+  return stackbuf;
+}
+# endif
+#endif
+/* Maximum number of 'char' in the char[] or DCHAR_T[] representation of the
+   thousands separator.  */
 #define THOUSEP_CHAR_MAXLEN 3
 
 #if WIDE_CHAR_VERSION && ((NEED_PRINTF_DOUBLE || NEED_PRINTF_LONG_DOUBLE) || ((NEED_PRINTF_FLAG_ALT_PRECISION_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION || NEED_PRINTF_FLAG_GROUPING || NEED_PRINTF_FLAG_GROUPING_INT) && DCHAR_IS_TCHAR))
@@ -5219,6 +5262,10 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
                                         /* DCHAR_T is wchar_t.  */
                                         thousep = thousands_separator_wchar (thousep_buf);
 #                                       define thousep_len 1
+#   elif defined DCHAR_CONV_FROM_ENCODING
+                                        /* DCHAR_T is uintN_t.  */
+                                        thousep = thousands_separator_DCHAR (thousep_buf);
+                                        thousep_len = DCHAR_STRLEN (thousep);
 #   else
                                         /* DCHAR_T is char.  */
                                         thousep = thousands_separator_char (thousep_buf);
@@ -5254,7 +5301,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
                                             *--p = thousep[0];
 #   else
                                             p -= thousep_len;
-                                            memcpy (p, thousep, thousep_len);
+                                            DCHAR_CPY (p, thousep, thousep_len);
 #   endif
                                             insert--;
                                             if (insert == 0)
@@ -5545,6 +5592,10 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
                                                 /* DCHAR_T is wchar_t.  */
                                                 thousep = thousands_separator_wchar (thousep_buf);
 #                                               define thousep_len 1
+#   elif defined DCHAR_CONV_FROM_ENCODING
+                                                /* DCHAR_T is uintN_t.  */
+                                                thousep = thousands_separator_DCHAR (thousep_buf);
+                                                thousep_len = DCHAR_STRLEN (thousep);
 #   else
                                                 /* DCHAR_T is char.  */
                                                 thousep = thousands_separator_char (thousep_buf);
@@ -5580,7 +5631,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
                                                     *--p = thousep[0];
 #   else
                                                     p -= thousep_len;
-                                                    memcpy (p, thousep, thousep_len);
+                                                    DCHAR_CPY (p, thousep, thousep_len);
 #   endif
                                                     insert--;
                                                     if (insert == 0)
@@ -5819,6 +5870,10 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
                                         /* DCHAR_T is wchar_t.  */
                                         thousep = thousands_separator_wchar (thousep_buf);
 #                                       define thousep_len 1
+#   elif defined DCHAR_CONV_FROM_ENCODING
+                                        /* DCHAR_T is uintN_t.  */
+                                        thousep = thousands_separator_DCHAR (thousep_buf);
+                                        thousep_len = DCHAR_STRLEN (thousep);
 #   else
                                         /* DCHAR_T is char.  */
                                         thousep = thousands_separator_char (thousep_buf);
@@ -5854,7 +5909,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
                                             *--p = thousep[0];
 #   else
                                             p -= thousep_len;
-                                            memcpy (p, thousep, thousep_len);
+                                            DCHAR_CPY (p, thousep, thousep_len);
 #   endif
                                             insert--;
                                             if (insert == 0)
@@ -6153,6 +6208,10 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
                                                 /* DCHAR_T is wchar_t.  */
                                                 thousep = thousands_separator_wchar (thousep_buf);
 #                                               define thousep_len 1
+#   elif defined DCHAR_CONV_FROM_ENCODING
+                                                /* DCHAR_T is uintN_t.  */
+                                                thousep = thousands_separator_DCHAR (thousep_buf);
+                                                thousep_len = DCHAR_STRLEN (thousep);
 #   else
                                                 /* DCHAR_T is char.  */
                                                 thousep = thousands_separator_char (thousep_buf);
@@ -6188,7 +6247,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
                                                     *--p = thousep[0];
 #   else
                                                     p -= thousep_len;
-                                                    memcpy (p, thousep, thousep_len);
+                                                    DCHAR_CPY (p, thousep, thousep_len);
 #   endif
                                                     insert--;
                                                     if (insert == 0)