Tested by rebuilding coreutils with the newest gnulib,
configuring it through
  gl_cv_func_printf_precision=no gl_cv_func_printf_enomem=no ./configure
on a glibc system, and then running
  $ LC_ALL=ta_IN ./printf "%'.0f\\n" 1111111111234567890
Previous (wrong) result:
  1,111,111,111,234,567,890
New (correct) result:
  11,11,11,11,11,23,45,67,890


Additionally, here's a small optimization as a followup.

2025-04-13  Bruno Haible  <br...@clisp.org>

        vasnprintf: Optimize last commit.
        * lib/vasnprintf.c (VASNPRINTF): Optimize a few loops.

diff --git a/lib/vasnprintf.c b/lib/vasnprintf.c
index d7e96ac5a6..949e14fb17 100644
--- a/lib/vasnprintf.c
+++ b/lib/vasnprintf.c
@@ -5247,9 +5247,10 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
                                             int h = *g;
                                             if (h <= 0)
                                               abort ();
-                                            int i;
-                                            for (i = h; i > 0; i--)
+                                            int i = h;
+                                            do
                                               *--p = *digitp++;
+                                            while (--i > 0);
 #   if WIDE_CHAR_VERSION
                                             *--p = thousep[0];
 #   else
@@ -5572,9 +5573,10 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
                                                     int h = *g;
                                                     if (h <= 0)
                                                       abort ();
-                                                    int i;
-                                                    for (i = h; i > 0; i--)
+                                                    int i = h;
+                                                    do
                                                       *--p = *digitp++;
+                                                    while (--i > 0);
 #   if WIDE_CHAR_VERSION
                                                     *--p = thousep[0];
 #   else
@@ -5846,9 +5848,10 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
                                             int h = *g;
                                             if (h <= 0)
                                               abort ();
-                                            int i;
-                                            for (i = h; i > 0; i--)
+                                            int i = h;
+                                            do
                                               *--p = *digitp++;
+                                            while (--i > 0);
 #   if WIDE_CHAR_VERSION
                                             *--p = thousep[0];
 #   else
@@ -6179,9 +6182,10 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
                                                     int h = *g;
                                                     if (h <= 0)
                                                       abort ();
-                                                    int i;
-                                                    for (i = h; i > 0; i--)
+                                                    int i = h;
+                                                    do
                                                       *--p = *digitp++;
+                                                    while (--i > 0);
 #   if WIDE_CHAR_VERSION
                                                     *--p = thousep[0];
 #   else
@@ -7555,14 +7559,15 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
                                         int h = *g;
                                         if (h <= 0)
                                           abort ();
-                                        int i;
-                                        for (i = h; i > 0; i--)
+                                        int i = h;
+                                        do
                                           *--q = *--p;
+                                        while (--i > 0);
 # if WIDE_CHAR_VERSION && DCHAR_IS_TCHAR
-                                          *--q = *thousep;
+                                        *--q = *thousep;
 # else
-                                          q -= thousep_len;
-                                          memcpy (q, thousep, thousep_len);
+                                        q -= thousep_len;
+                                        memcpy (q, thousep, thousep_len);
 # endif
                                         insert--;
                                         if (insert == 0)




Reply via email to