]> Savannah Git Hosting - gnulib.git/commitdiff
vasnprintf: Follow glibc's behaviour on glibc systems.
authorBruno Haible <bruno@clisp.org>
Fri, 11 Apr 2025 14:59:24 +0000 (16:59 +0200)
committerBruno Haible <bruno@clisp.org>
Fri, 11 Apr 2025 14:59:24 +0000 (16:59 +0200)
* lib/vasnprintf.c (DCHAR_MBSNLEN): Define fallback.
(VASNPRINTF): Use it on for width handling on glibc.
* modules/vasnprintf (Depends-on): Add mbsnlen.
* modules/c-vasnprintf (Depends-on): Likewise.

ChangeLog
lib/vasnprintf.c
modules/c-vasnprintf
modules/vasnprintf

index adad6ce81bb599851ac60a920b98e1e651d70e6f..dedd3ca34ee41c2bfe6335b5e27dd31a30190a01 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2025-04-11  Bruno Haible  <bruno@clisp.org>
+
+       vasnprintf: Follow glibc's behaviour on glibc systems.
+       * lib/vasnprintf.c (DCHAR_MBSNLEN): Define fallback.
+       (VASNPRINTF): Use it on for width handling on glibc.
+       * modules/vasnprintf (Depends-on): Add mbsnlen.
+       * modules/c-vasnprintf (Depends-on): Likewise.
+
 2025-04-11  Bruno Haible  <bruno@clisp.org>
 
        vasnprintf: Fix memory size bound for %g with grouping and precision.
index 559b3c70432b8758a04c53641226d81d3f99cb77..f91300cbd15c9e74d895b3c2964b477a1edf1466 100644 (file)
 #   define TCHAR_T char
 # endif
 #endif
+#ifndef DCHAR_MBSNLEN
+# if WIDE_CHAR_VERSION
+#  define DCHAR_MBSNLEN wcsnlen
+# else
+#  define DCHAR_MBSNLEN mbsnlen
+# endif
+#endif
 #if !WIDE_CHAR_VERSION || !DCHAR_IS_TCHAR
   /* TCHAR_T is char.  */
   /* Use snprintf if it exists under the name 'snprintf' or '_snprintf'.
@@ -7100,6 +7107,23 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
                            against the number of _characters_ of the converted
                            value.  */
                         w = DCHAR_MBSNLEN (result + length, count);
+# elif __GLIBC__ >= 2
+                        /* glibc prefers to compare the width against the number
+                           of characters as well, but only for numeric conversion
+                           specifiers.  See
+                           <https://sourceware.org/bugzilla/show_bug.cgi?id=28943>
+                           <https://sourceware.org/bugzilla/show_bug.cgi?id=30883>
+                           <https://sourceware.org/bugzilla/show_bug.cgi?id=31542>  */
+                        switch (dp->conversion)
+                          {
+                          case 'd': case 'i': case 'u':
+                          case 'f': case 'F': case 'g': case 'G':
+                            w = DCHAR_MBSNLEN (result + length, count);
+                            break;
+                          default:
+                            w = count;
+                            break;
+                          }
 # else
                         /* The width is compared against the number of _bytes_
                            of the converted value, says POSIX.  */
index eebaf3aed8a24454f17ab509d894b86438d09a85..aaa6011809b074941a51b0c6a6f358b8b7361932 100644 (file)
@@ -36,6 +36,7 @@ errno-h
 memchr
 multiarch
 mbszero
+mbsnlen
 
 configure.ac:
 AC_REQUIRE([AC_C_RESTRICT])
index 96fb2088917090af595bc15561ba67c5a1043b07..aa12d79139c9625e22918591a9fcb3957693755e 100644 (file)
@@ -33,6 +33,7 @@ memchr
 assert-h
 wchar-h
 mbszero
+mbsnlen
 
 configure.ac:
 AC_REQUIRE([AC_C_RESTRICT])