[gs-cvs] rev 8548 - trunk/gs/src

alexcher at ghostscript.com alexcher at ghostscript.com
Mon Feb 25 23:12:50 PST 2008


Author: alexcher
Date: 2008-02-25 23:12:49 -0800 (Mon, 25 Feb 2008)
New Revision: 8548

Modified:
   trunk/gs/src/spprint.c
   trunk/gs/src/zdouble.c
Log:
Change the decimal separator in generated strings to '.' effectively selecting
a C numeric locale without calling any locale functions. Bug 689624.

DETAILS:
For most clients Ghostscript is a library. We cannot set C locale before
sprintf() and reset it afterwards because this may affect other threads.

DIFFERENCES:
None


Modified: trunk/gs/src/spprint.c
===================================================================
--- trunk/gs/src/spprint.c	2008-02-25 16:10:43 UTC (rev 8547)
+++ trunk/gs/src/spprint.c	2008-02-26 07:12:49 UTC (rev 8548)
@@ -107,17 +107,25 @@
 pprintg1(stream * s, const char *format, floatp v)
 {
     const char *fp = pprintf_scan(s, format);
-    char str[150];
+    char dot, str[150];
 
 #ifdef DEBUG
     if (*fp == 0 || fp[1] != 'g')	/* shouldn't happen! */
 	lprintf1("Bad format in pprintg: %s\n", format);
 #endif
+    sprintf(str, "%f", 1.5);
+    dot = str[1]; /* locale-dependent */
     sprintf(str, "%g", v);
     if (strchr(str, 'e')) {
 	/* Bad news.  Try again using f-format. */
 	sprintf(str, (fabs(v) > 1 ? "%1.1f" : "%1.8f"), v);
     }
+    /* Juggling locales isn't thread-safe. Posix me harder. */
+    if (dot != '.') {
+        char *pdot = strchr(str, dot); 
+        if (pdot)
+            *pdot = '.';
+    }
     pputs_short(s, str);
     return pprintf_scan(s, fp + 2);
 }

Modified: trunk/gs/src/zdouble.c
===================================================================
--- trunk/gs/src/zdouble.c	2008-02-25 16:10:43 UTC (rev 8547)
+++ trunk/gs/src/zdouble.c	2008-02-26 07:12:49 UTC (rev 8548)
@@ -310,7 +310,7 @@
     os_ptr op = osp;
     int code = double_params_result(op, 0, NULL);
     double num;
-    char buf[MAX_CHARS + 2];
+    char dot, buf[MAX_CHARS + 2];
     char *str = buf;
     uint len;
     char end;
@@ -321,6 +321,8 @@
     len = r_size(op - 1);
     if (len > MAX_CHARS)
 	return_error(e_limitcheck);
+    sprintf(buf, "%f", 1.5);
+    dot = buf[1]; /* locale-dependent */
     memcpy(str, op[-1].value.bytes, len);
     /*
      * We check syntax in the following way: we remove whitespace,
@@ -336,6 +338,11 @@
     if (strspn(str, "0123456789+-.dDeE") != len)
 	return_error(e_syntaxerror);
     strcat(str, "$");
+    if (dot != '.') {
+        char *pdot = strchr(str, '.');
+        if (pdot)
+            *pdot = dot;
+    }
     if (sscanf(str, "%lf%c", &num, &end) != 2 || end != '$')
 	return_error(e_syntaxerror);
     return double_result(i_ctx_p, 1, num);
@@ -391,12 +398,14 @@
     os_ptr op = osp;
     double num;
     int code = double_params(op - 1, 1, &num);
-    char str[MAX_CHARS + 1];
+    char dot, str[MAX_CHARS + 1];
     int len;
 
     if (code < 0)
 	return code;
     check_write_type(*op, t_string);
+    sprintf(str, "%f", 1.5);
+    dot = buf[1]; /* locale-dependent */
     /*
      * To get fully accurate output results for IEEE double-
      * precision floats (53 bits of mantissa), the ANSI
@@ -417,6 +426,12 @@
     len = strlen(str);
     if (len > r_size(op))
 	return_error(e_rangecheck);
+    /* Juggling locales isn't thread-safe. Posix me harder. */
+    if (dot != '.') {
+        char *pdot = strchr(str, dot); 
+        if (pdot)
+            *pdot = '.';
+    }
     memcpy(op->value.bytes, str, len);
     op[-1] = *op;
     r_set_size(op - 1, len);



More information about the gs-cvs mailing list