Index: common/shared.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/shared.c,v
retrieving revision 1.57
diff -u -r1.57 shared.c
--- shared.c	2000/08/22 08:56:19	1.57
+++ shared.c	2000/08/23 01:00:12
@@ -14,11 +14,12 @@
 #include <config.h>
 #endif
 
+#include <assert.h>
+#include <ctype.h>
+#include <limits.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
-#include <ctype.h>
-#include <assert.h>
 
 #ifdef HAVE_UNISTD_H
 #include <unistd.h>
@@ -46,6 +47,17 @@
                           "~/.freeciv"
 #endif
 
+/* Cached locale numeric formatting information.
+   Defaults are as appropriate for the US. */
+#ifdef ENABLE_NLS
+#define FC_NLS_CONST
+#else
+#define FC_NLS_CONST const
+#endif
+static FC_NLS_CONST char *grouping = "\3";
+static FC_NLS_CONST char *grouping_sep = ",";
+static FC_NLS_CONST size_t grouping_sep_len = 1;
+
 /**************************************************************************
   FIXME:  This is an inelegant, English-specific kludge that fails to
   work correctly even in the limited case of English, e.g. "An hour".
@@ -169,60 +181,55 @@
 
 /***************************************************************
   Returns a statically allocated string containing a nicely-formatted
-  version of the given number.
-  FIXME:  This is not internationalised at all.
+  version of the given number according to the user's locale.
+  (Only works for numbers >= zero.)
 ***************************************************************/
-#define SPLITS 3
-#define N_DIGS 20
 char *int_to_text(int nr)
 {
-  char tmpbuf[N_DIGS+1];
-  static char buf[N_DIGS+((N_DIGS-1)/SPLITS)+1];
-  char *to=buf;
-  char *from=tmpbuf;
-  my_snprintf(tmpbuf, sizeof(tmpbuf), "%d", nr);
-  while (*from) {
-    *to++ = *from++;
-    if (strlen(from)%SPLITS==0 && *from)  
-      *to++=',';
-  }
-  *to=0;
-  return buf;
-#if 0
-  /* FIXME: Some code which may help when i18n'd using localeconv(). */
-  int neg;
-  static char buf[1 + (2 * N_DIGS - 1) + 1];
+  static char buf[64]; /* Note that we'll be filling this in right to left. */
   char *ptr;
-  int inx;
+  char *grp = grouping;
+  int i;
+
+  assert(nr >= 0);
+
 
   if (nr == 0) {
     return "0";
   }
 
-  if ((neg = (nr < 0))) {
-    nr = -nr;
-  }
-
-  ptr = &(buf[sizeof(buf) - 1]);
-  *ptr-- = '\0';
+  ptr = &buf[sizeof(buf) - 1];
+  *ptr-- = 0;
 
-  inx = 0;
+  i = 0;
   while (nr != 0) {
     int dig = nr % 10;
-    *ptr-- = '0' + dig;
+    assert(ptr > buf);
+    
+    *(--ptr) = '0' + dig;
     nr /= 10;
-    inx++;
-    if ((inx % SPLITS == 0) && (nr != 0)) {
-      *ptr-- = ',';
-    }
-  }
 
-  if (neg) {
-    *ptr-- = '-';
+    i++;
+    if (i == *grp && nr != 0) {
+      /* Reached count of digits in group: insert separator
+         and reset count. */
+      i = 0;
+      if (*grp == CHAR_MAX) {
+	/* This test is unlikely to be necessary since we would need at
+	   least 421-bit ints to break the 127 digit barrier, but why not. */
+	break;
+      }
+      ptr -= grouping_sep_len;
+      assert(ptr >= buf);
+      memcpy(ptr, grouping_sep, grouping_sep_len);
+      if (*(grp + 1) != 0) {
+	/* Zero means to repeat the present group-size indefinitely. */
+        grp++;
+      }
+    }
   }
 
-  return ptr + 1;
-#endif
+  return ptr;
 }
 
 /***************************************************************
@@ -700,10 +707,41 @@
 ***************************************************************************/
 void init_nls(void)
 {
-#ifdef ENABLE_NLS
-  setlocale (LC_ALL, "");
-  bindtextdomain (PACKAGE, LOCALEDIR);
+#ifdef ENABLE_NLS
+  setlocale(LC_ALL, "");
+  bindtextdomain(PACKAGE, LOCALEDIR);
   textdomain(PACKAGE);
+
+  /* Don't touch the defaults when LC_NUMERIC == "C".  This is
+     intended to cater for the common case where:
+     1) The user is from North America. ;-)
+     2) The user has not set the proper environment variables.
+	(Most applications are (unfortunately) US-centric
+	by default, so why bother?)
+     This would result in the "C" locale being used, with grouping ""
+     and thousands_sep "", where we really want "\3" and ",". */
+  
+  if (strcmp(setlocale(LC_NUMERIC, NULL), "C")) {
+    size_t i;
+    struct lconv *lc = localeconv();
+    
+    grouping_sep = mystrdup(lc->thousands_sep);
+    grouping_sep_len = strlen(grouping_sep);
+    
+    for (i = 0; lc->grouping[i] && lc->grouping[i] != CHAR_MAX; i++)
+      ;
+    i++;
+
+    if (lc->grouping[0] == 0) {
+      /* This actually indicates no grouping at all. */
+      static char m = CHAR_MAX;
+      grouping = &m;
+      return;
+    }
+
+    grouping = fc_malloc(i);
+    memcpy(grouping, lc->grouping, i);
+  }
 #endif
 }