]> sjero.net Git - wget/commitdiff
[svn] Correctly implement thousand seps of more than one character.
authorhniksic <devnull@localhost>
Sun, 26 Jun 2005 18:06:11 +0000 (11:06 -0700)
committerhniksic <devnull@localhost>
Sun, 26 Jun 2005 18:06:11 +0000 (11:06 -0700)
src/ChangeLog
src/utils.c

index d85fba6f338f2c4af76abd17001c7c3df229629f..926bc88cddabe25a71eee98fecbba24e984ae51f 100644 (file)
@@ -1,3 +1,8 @@
+2005-06-26  Hrvoje Niksic  <hniksic@xemacs.org>
+
+       * utils.c (with_thousand_seps): Correctly implement thousand seps
+       consisting of more than one character.
+
 2005-06-26  Hrvoje Niksic  <hniksic@xemacs.org>
 
        * main.c (secs_to_human_time): Ditto.
index 31598348103685b4de50f4b70c5924cb2f8bdbcf..6461200622e5aa0ebe67fb15467b0ef777ca0f10 100644 (file)
@@ -1164,6 +1164,35 @@ free_keys_and_values (struct hash_table *ht)
 }
 
 \f
+static void
+get_grouping_data (const char **sep, const char **grouping)
+{
+  static const char *cached_sep;
+  static const char *cached_grouping;
+  static bool initialized;
+  if (!initialized)
+    {
+#ifdef LC_NUMERIC
+      /* Get the grouping info from the locale. */
+      struct lconv *lconv;
+      const char *oldlocale = setlocale (LC_NUMERIC, "");
+      lconv = localeconv ();
+      cached_sep = xstrdup (lconv->thousands_sep);
+      cached_grouping = xstrdup (lconv->grouping);
+      /* Restore the locale to previous settings. */
+      setlocale (LC_NUMERIC, oldlocale);
+      if (!cached_sep)
+#endif
+       /* Force separator for locales that specify no separators
+          ("C", "hr", and probably many more.) */
+       cached_sep = ",", cached_grouping = "\x03";
+      initialized = true;
+    }
+  *sep = cached_sep;
+  *grouping = cached_grouping;
+}
+
+
 /* Return a printed representation of N with thousand separators.
    This should respect locale settings, with the exception of the "C"
    locale which mandates no separator, but we use one anyway.
@@ -1177,47 +1206,38 @@ const char *
 with_thousand_seps (wgint n)
 {
   static char outbuf[48];
+  char *p = outbuf + sizeof outbuf;
 
-  static char loc_sepchar;
-  static const char *loc_grouping;
+  /* Info received from locale */
+  const char *grouping, *sep;
+  int seplen;
 
+  /* State information */
   int i = 0, groupsize;
-  char *p;
   const char *atgroup;
 
-  if (!loc_sepchar)
-    {
-#ifdef LC_NUMERIC
-      /* Get the grouping character from the locale. */
-      struct lconv *lconv;
-      const char *oldlocale = setlocale (LC_NUMERIC, "");
-      lconv = localeconv ();
-      loc_sepchar = *lconv->thousands_sep;
-      loc_grouping = xstrdup (lconv->grouping);
-      /* Restore the C locale semantics of printing and reading numbers */
-      setlocale (LC_NUMERIC, oldlocale);
-      if (!loc_sepchar)
-#endif
-       /* defaults for C locale or no locale */
-       loc_sepchar = ',', loc_grouping = "\x03";
-    }
-  atgroup = loc_grouping;
-
-  p = outbuf + sizeof outbuf;
-  *--p = '\0';
+  /* Initialize grouping data. */
+  get_grouping_data (&sep, &grouping);
+  seplen = strlen (sep);
+  atgroup = grouping;
   groupsize = *atgroup++;
 
+  /* Write the number into the buffer, backwards, inserting the
+     separators as necessary.  */
+  *--p = '\0';
   while (1)
     {
       *--p = n % 10 + '0';
       n /= 10;
       if (n == 0)
        break;
-      /* Insert the separator on every groupsize'd digit, and get the
-        new groupsize.  */
+      /* Prepend SEP to every groupsize'd digit and get new groupsize.  */
       if (++i == groupsize)
        {
-         *--p = loc_sepchar;
+         if (seplen == 1)
+           *--p = *sep;
+         else
+           memcpy (p -= seplen, sep, seplen);
          i = 0;
          if (*atgroup)
            groupsize = *atgroup++;