# # * src/command.c src/mouse.c src/scanner.c src/set.c src/show.c # src.unset.c src/variable.c src/variable.h: Instead of immediately # applying the locale requested by "set decimal locale {foo}", save the # requested locale string and apply it only during execution of gprintf(). # This prevents leakage of the numeric locale into terminal driver code # (Bug #1692541), and simplifies the code used in save and show. # diff -urNP gnuplot/src/command.c gnuplot-cvs/src/command.c --- gnuplot/src/command.c 2007-02-12 20:29:36.000000000 -0800 +++ gnuplot-cvs/src/command.c 2007-04-05 22:30:28.000000000 -0700 @@ -85,6 +85,7 @@ #include "tables.h" #include "term_api.h" #include "util.h" +#include "variable.h" #ifdef USE_MOUSE # include "mouse.h" @@ -1364,7 +1365,6 @@ { FILE *fp; char *save_file = NULL; - char *save_locale = NULL; int what; c_token++; @@ -1397,14 +1397,6 @@ if (!fp) os_error(c_token, "Cannot open save file"); -#ifdef HAVE_LOCALE_H - /* Make sure that numbers in the saved gnuplot commands use standard form */ - if (strcmp(localeconv()->decimal_point,".")) { - save_locale = gp_strdup(setlocale(LC_NUMERIC,NULL)); - setlocale(LC_NUMERIC,"C"); - } -#endif - switch (what) { case SAVE_FUNCS: save_functions(fp); @@ -1423,12 +1415,9 @@ } #ifdef HAVE_LOCALE_H - if (save_locale) { - setlocale(LC_NUMERIC,save_locale); - free(save_locale); - fprintf(fp, "set decimalsign locale \"%s\"\n", setlocale(LC_NUMERIC,NULL)); - fprintf(fp, "set decimalsign '%s'\n", decimalsign); - } + if (numeric_locale) + fprintf(fp, "set decimalsign locale \"%s\"\n", numeric_locale); + fprintf(fp, "set decimalsign '%s'\n", decimalsign); #endif if (stdout != fp) { @@ -1532,7 +1521,6 @@ TBOOLEAN save_is_cb_plot; #endif FILE *f = tmpfile(); - char *save_locale = NULL; c_token++; /* parse optional option */ @@ -1552,14 +1540,6 @@ if (!f) int_error(NO_CARET, "cannot write temporary file"); -#ifdef HAVE_LOCALE_H - /* Make sure that numbers in the saved gnuplot commands use standard form */ - if (strcmp(localeconv()->decimal_point,".")) { - save_locale = gp_strdup(setlocale(LC_NUMERIC,NULL)); - setlocale(LC_NUMERIC,"C"); - } -#endif - /* generate r,g,b curves */ for (i = 0; i < test_palette_colors; i++) { /* colours equidistantly from [0,1] */ @@ -1618,12 +1598,9 @@ save_set(f); #ifdef HAVE_LOCALE_H - if (save_locale) { - setlocale(LC_NUMERIC,save_locale); - free(save_locale); - fprintf(f, "set decimalsign locale \"%s\"\n", setlocale(LC_NUMERIC,NULL)); - fprintf(f, "set decimalsign '%s'\n", decimalsign); - } + if (numeric_locale) + fprintf(f, "set decimalsign locale \"%s\"\n", numeric_locale); + fprintf(f, "set decimalsign '%s'\n", decimalsign); #endif /* execute all commands from the temporary file */ diff -urNP gnuplot/src/mouse.c gnuplot-cvs/src/mouse.c --- gnuplot/src/mouse.c 2007-02-09 19:53:20.000000000 -0800 +++ gnuplot-cvs/src/mouse.c 2007-04-05 22:27:31.000000000 -0700 @@ -653,19 +653,7 @@ } flip = (is_splot_map && zoom_now->was_splot_map); -#ifdef HAVE_LOCALE_H - if (strcmp(localeconv()->decimal_point,".")) { - char *save_locale = gp_strdup(setlocale(LC_NUMERIC,NULL)); - setlocale(LC_NUMERIC,"C"); - sprintf(s, "set xr[%.12g:%.12g]; set yr[%.12g:%.12g]", - zoom_now->xmin, zoom_now->xmax, - (flip) ? zoom_now->ymax : zoom_now->ymin, - (flip) ? zoom_now->ymin : zoom_now->ymax); - setlocale(LC_NUMERIC,save_locale); - free(save_locale); - } else -#endif - sprintf(s, "set xr[%.12g:%.12g]; set yr[%.12g:%.12g]", + sprintf(s, "set xr[%.12g:%.12g]; set yr[%.12g:%.12g]", zoom_now->xmin, zoom_now->xmax, (flip) ? zoom_now->ymax : zoom_now->ymin, (flip) ? zoom_now->ymin : zoom_now->ymax); @@ -703,18 +691,7 @@ } if (!is_3d_plot) { -#ifdef HAVE_LOCALE_H - if (strcmp(localeconv()->decimal_point,".")) { - char *save_locale = gp_strdup(setlocale(LC_NUMERIC,NULL)); - setlocale(LC_NUMERIC,"C"); - sprintf(s + strlen(s), "; set x2r[% #g:% #g]; set y2r[% #g:% #g]", - zoom_now->x2min, zoom_now->x2max, - zoom_now->y2min, zoom_now->y2max); - setlocale(LC_NUMERIC,save_locale); - free(save_locale); - } else -#endif - sprintf(s + strlen(s), "; set x2r[% #g:% #g]; set y2r[% #g:% #g]", + sprintf(s + strlen(s), "; set x2r[% #g:% #g]; set y2r[% #g:% #g]", zoom_now->x2min, zoom_now->x2max, zoom_now->y2min, zoom_now->y2max); if (zoom_now == zoom_head) { diff -urNP gnuplot/src/scanner.c gnuplot-cvs/src/scanner.c --- gnuplot/src/scanner.c 2005-11-23 15:33:37.000000000 -0800 +++ gnuplot-cvs/src/scanner.c 2007-04-05 22:27:31.000000000 -0700 @@ -285,17 +285,7 @@ int_error(t_num, "integer overflow; change to floating point"); } else { token[t_num].l_val.v.cmplx_val.imag = 0.0; -#ifdef HAVE_LOCALE_H - /* Always read numbers on command line as C locale */ - if (strcmp(localeconv()->decimal_point,".")) { - char *save_locale = gp_strdup(setlocale(LC_NUMERIC,NULL)); - setlocale(LC_NUMERIC,"C"); - token[t_num].l_val.v.cmplx_val.real = atof(str); - setlocale(LC_NUMERIC,save_locale); - free(save_locale); - } else -#endif - token[t_num].l_val.v.cmplx_val.real = atof(str); + token[t_num].l_val.v.cmplx_val.real = atof(str); } return (count); } diff -urNP gnuplot/src/set.c gnuplot-cvs/src/set.c --- gnuplot/src/set.c 2007-02-23 12:42:04.000000000 -0800 +++ gnuplot-cvs/src/set.c 2007-04-05 22:27:31.000000000 -0700 @@ -1157,16 +1157,23 @@ if (END_OF_COMMAND) { #ifdef HAVE_LOCALE_H + free(numeric_locale); + numeric_locale = NULL; setlocale(LC_NUMERIC,"C"); } else if (equals(c_token,"locale")) { char *newlocale = NULL; c_token++; newlocale = try_to_get_string(); + if (!newlocale) + newlocale = getenv("LC_NUMERIC"); if (!setlocale(LC_NUMERIC, newlocale ? newlocale : "")) int_error(c_token-1, "Could not find requested locale"); - free(newlocale); decimalsign = gp_strdup(localeconv()->decimal_point); fprintf(stderr,"decimal_sign in locale is %s\n", decimalsign); + /* Save this locale for later use, but return to "C" for now */ + free(numeric_locale); + numeric_locale = newlocale; + setlocale(LC_NUMERIC,"C"); #endif } else if (!(decimalsign = try_to_get_string())) int_error(c_token, "expecting string"); diff -urNP gnuplot/src/show.c gnuplot-cvs/src/show.c --- gnuplot/src/show.c 2007-02-06 15:56:39.000000000 -0800 +++ gnuplot-cvs/src/show.c 2007-04-05 22:30:33.000000000 -0700 @@ -164,8 +164,6 @@ static int var_show_all = 0; -static char *save_locale = NULL; - /* following code segment appears over and over again */ #define SHOW_NUM_OR_TIME(x, axis) SAVE_NUM_OR_TIME(stderr, x, axis) @@ -198,12 +196,6 @@ token_found = lookup_table(&set_tbl[0],c_token); -#ifdef HAVE_LOCALE_H - /* Report internal values in C locale (dot for decimal sign) */ - save_locale = gp_strdup(setlocale(LC_NUMERIC,NULL)); - setlocale(LC_NUMERIC,"C"); -#endif - /* rationalize c_token advancement stuff a bit: */ if (token_found != S_INVALID) c_token++; @@ -640,14 +632,6 @@ break; } -#ifdef HAVE_LOCALE_H - if (save_locale) { - setlocale(LC_NUMERIC,save_locale); - free(save_locale); - save_locale = NULL; - } -#endif - if (error_message) int_error(c_token,error_message); @@ -2381,9 +2365,10 @@ { SHOW_ALL_NL; #ifdef HAVE_LOCALE_H - if (save_locale) { - setlocale(LC_NUMERIC,save_locale); + if (numeric_locale) { + setlocale(LC_NUMERIC,numeric_locale); fprintf(stderr, "\tdecimalsign for input is %s \n", localeconv()->decimal_point); + setlocale(LC_NUMERIC,"C"); } #endif if (decimalsign!=NULL) @@ -2764,8 +2749,8 @@ SHOW_ALL_NL; locale_handler(ACTION_SHOW,NULL); #ifdef HAVE_LOCALE_H - /* We reset LC_NUMERIC locale explicitly to C, so we must undo it here */ - fprintf(stderr, "\tLC_NUMERIC is %s\n", setlocale(LC_NUMERIC,save_locale)); + if (numeric_locale) + fprintf(stderr, "\tLC_NUMERIC is %s\n", numeric_locale); #endif } diff -urNP gnuplot/src/unset.c gnuplot-cvs/src/unset.c --- gnuplot/src/unset.c 2007-02-23 12:35:42.000000000 -0800 +++ gnuplot-cvs/src/unset.c 2007-04-05 22:27:31.000000000 -0700 @@ -761,7 +761,8 @@ free(decimalsign); decimalsign = NULL; #ifdef HAVE_LOCALE_H - setlocale(LC_NUMERIC,"C"); + free(numeric_locale); + numeric_locale = NULL; #endif } diff -urNP gnuplot/src/util.c gnuplot-cvs/src/util.c --- gnuplot/src/util.c 2007-04-01 21:04:27.000000000 -0700 +++ gnuplot-cvs/src/util.c 2007-04-05 22:27:31.000000000 -0700 @@ -44,6 +44,10 @@ /* #include "setshow.h" */ /* for month names etc */ #include "term_api.h" /* for term_end_plot() used by graph_error() */ +#if defined(HAVE_LOCALE_H) +#include "variable.h" +#endif + #if defined(HAVE_DIRENT_H) # include # include @@ -547,11 +551,21 @@ int stored_power = 0; /* power that matches the mantissa output earlier */ +#ifdef HAVE_LOCALE_H + if (numeric_locale) + setlocale(LC_NUMERIC,numeric_locale); +#endif + for (;;) { /*{{{ copy to dest until % */ while (*format != '%') - if (!(*dest++ = *format++)) + if (!(*dest++ = *format++)) { +#ifdef HAVE_LOCALE_H + if (numeric_locale) + setlocale(LC_NUMERIC,"C"); +#endif return; /* end of format */ + } /*}}} */ /*{{{ check for %% */ @@ -725,6 +739,10 @@ } /*}}} */ default: +#ifdef HAVE_LOCALE_H + if (numeric_locale) + setlocale(LC_NUMERIC,"C"); +#endif int_error(NO_CARET, "Bad format character"); } /* switch */ /*}}} */ @@ -765,6 +783,11 @@ dest += strlen(dest); ++format; } /* for ever */ + +#ifdef HAVE_LOCALE_H + if (numeric_locale) + setlocale(LC_NUMERIC,"C"); +#endif } /*}}} */ diff -urNP gnuplot/src/variable.c gnuplot-cvs/src/variable.c --- gnuplot/src/variable.c 2006-06-26 19:36:30.000000000 -0700 +++ gnuplot-cvs/src/variable.c 2007-04-05 22:27:31.000000000 -0700 @@ -44,6 +44,9 @@ #include "command.h" #include "util.h" +/* Holds the name of the current locale from LC_NUMERIC */ +/* as set by "set decimal locale" */ +char *numeric_locale = NULL; #define PATHSEP_TO_NUL(arg) \ do { \ diff -urNP gnuplot/src/variable.h gnuplot-cvs/src/variable.h --- gnuplot/src/variable.h 2004-04-13 10:24:03.000000000 -0700 +++ gnuplot-cvs/src/variable.h 2007-04-05 22:27:31.000000000 -0700 @@ -117,4 +117,6 @@ extern char full_day_names[7][32]; extern char abbrev_day_names[7][8]; +extern char *numeric_locale; + #endif /* VARIABLE_H */