From: <ai...@us...> - 2009-09-06 23:52:44
|
Revision: 10378 http://plplot.svn.sourceforge.net/plplot/?rev=10378&view=rev Author: airwin Date: 2009-09-06 23:52:38 +0000 (Sun, 06 Sep 2009) Log Message: ----------- Implement a pair of functions, plsave_set_locale and plrestore_locale that provide infrastructure to protect the parts of PLplot that absolutely require the LC_NUMERIC "C" locale without forcing that locale for all parts of PLplot. Use these functions to protect colour palette reading. Modified Paths: -------------- trunk/include/plplotP.h trunk/src/plcore.c trunk/src/plctrl.c Modified: trunk/include/plplotP.h =================================================================== --- trunk/include/plplotP.h 2009-09-06 21:04:55 UTC (rev 10377) +++ trunk/include/plplotP.h 2009-09-06 23:52:38 UTC (rev 10378) @@ -120,7 +120,7 @@ #include <unistd.h> #endif -/*#include <locale.h> */ +#include <locale.h> /* (AM) Define M_PI if the platform does not include it (MSVC for instance) */ @@ -426,14 +426,6 @@ /* Greek character translation array (defined in plcore.c) */ extern const char plP_greek_mnemonic[]; -/* plinit calls setlocale to establish this pointer to a character string - that stores the LC_NUMERIC locale set by any library or application before - it calls plinit. This character string is used to restore the LC_NUMERIC - locale to the original one after anything (such as colour palette file - reading) within PLplot that temporarily changes the locale. - extern PLDLLIMPEXP_DATA(char *) plplot_default_lc_numeric_locale; */ - - /*--------------------------------------------------------------------------*\ * Function Prototypes * @@ -574,6 +566,20 @@ plP_text(PLINT base, PLFLT just, PLFLT *xform, PLINT x, PLINT y, PLINT refx, PLINT refy, const char *string); + /* Used to save locale string to be used for later restore of locale. */ +extern PLDLLIMPEXP_DATA(char *)plsaved_lc_numeric_locale; + + /* For LC_NUMERIC save current locale string, then set "C" locale to protect + parts of PLplot which absolutely demand the LC_NUMERIC "C" locale. */ + +PLDLLIMPEXP void +plsave_set_locale(void); + + /* Restore LC_NUMERIC locale that was determined by plsave_set_locale. */ + +PLDLLIMPEXP void +plrestore_locale(void); + /* where should structure definitions that must be seen by drivers and core source files, be? */ /* structure to be used by plcore.c and anydriver.c, related to plP_text() */ Modified: trunk/src/plcore.c =================================================================== --- trunk/src/plcore.c 2009-09-06 21:04:55 UTC (rev 10377) +++ trunk/src/plcore.c 2009-09-06 23:52:38 UTC (rev 10378) @@ -128,9 +128,6 @@ */ const char plP_greek_mnemonic[] = "ABGDEZYHIKLMNCOPRSTUFXQWabgdezyhiklmncoprstufxqw"; -/* Must define this pointer once. Corresponding declaration is in plplotP.h - char * plplot_default_lc_numeric_locale; */ - void plP_init(void) { @@ -1804,15 +1801,7 @@ PLFLT def_arrow_y[6] = {0.0, 0.0, 0.2, 0.0, -0.2, 0.0}; PLFLT lx, ly, xpmm_loc, ypmm_loc, aspect_old, aspect_new; PLINT mk = 0, sp = 0, inc = 0, del = 2000; - /* Save current LC_NUMERIC locale string pointer in - plplot_default_lc_numeric_locale for purposes of restoring the - current LC_NUMERIC locale after the PLplot library temporarily - fiddles with it. - if(!(plplot_default_lc_numeric_locale = setlocale(LC_NUMERIC, NULL))) { - plexit("plinit: LC_NUMERIC has no default name of locale"); - } */ - pllib_init(); if (plsc->level != 0) Modified: trunk/src/plctrl.c =================================================================== --- trunk/src/plctrl.c 2009-09-06 21:04:55 UTC (rev 10377) +++ trunk/src/plctrl.c 2009-09-06 23:52:38 UTC (rev 10378) @@ -51,6 +51,10 @@ #include <errno.h> #endif +/* extern declaration in plplotP.h, but defined here once for all of + libplplot. */ +char * plsaved_lc_numeric_locale; + /* Random number generator (Mersenne Twister) */ #include "mt19937ar.h" @@ -1207,9 +1211,8 @@ char msgbuf[1024]; FILE *fp; - /* if(!(setlocale(LC_NUMERIC, "C"))) { - plexit("cmap0_palette_read: LC_NUMERIC locale could not be set for \"C\""); - } */ + plsave_set_locale(); + if(strlen(filename) == 0) { fp = plLibOpen(PL_DEFAULT_CMAP0_FILE); if (fp == NULL) { @@ -1307,11 +1310,7 @@ } } - /* Restore default LC_NUMERIC locale since we fiddled with it above. - if(!(setlocale(LC_NUMERIC, plplot_default_lc_numeric_locale))) { - snprintf(msgbuf,1024,"cmap0_palette_read: LC_NUMERIC could not be restored to the default \"%s\" locale.\n", *plplot_default_lc_numeric_locale); - plexit(msgbuf); - } */ + plrestore_locale(); } /*--------------------------------------------------------------------------*\ @@ -1382,9 +1381,8 @@ FILE *fp; char msgbuf[1024]; - /* if(!(setlocale(LC_NUMERIC, "C"))) { - plexit("plspal1: LC_NUMERIC locale could not be set for \"C\""); - }*/ + plsave_set_locale(); + rgb = TRUE; err = 0; format_version = 0; @@ -1393,14 +1391,14 @@ if (fp == NULL) { snprintf(msgbuf,1024,"Unable to open cmap1 .pal file %s\n",PL_DEFAULT_CMAP1_FILE); plwarn(msgbuf); - return; + goto finish; } } else { fp = plLibOpen(filename); if (fp == NULL) { snprintf(msgbuf,1024,"Unable to open cmap1 .pal file %s\n",filename); plwarn(msgbuf); - return; + goto finish; } } /* Check for new file format */ @@ -1423,7 +1421,7 @@ snprintf(msgbuf,1024,"Unrecognized cmap1 format (wrong number of colors) %s\n", color_info); plwarn(msgbuf); fclose(fp); - return; + goto finish; } r = (PLFLT *)malloc(number_colors * sizeof(PLFLT)); @@ -1551,6 +1549,8 @@ free(a); free(pos); free(rev); + +finish: plrestore_locale(); } /*--------------------------------------------------------------------------*\ @@ -1936,7 +1936,7 @@ free_mem(fs); return NULL; - done: +done: pldebug("plLibOpenPdfstr", "Found file %s\n", fs); free_mem(fs); return (file); @@ -2552,3 +2552,59 @@ { return (PLFLT)(genrand_real1()); } + +/*--------------------------------------------------------------------------*\ + * plsave_set_locale() + * + * For LC_NUMERIC save current locale string in the global + * pointer, plsaved_lc_numeric_locale, then set "C" locale. + * n.b. plsave_set_locale and plrestore_locale should always be used as + * a pair to surround PLplot code that absolutely requires the + * LC_NUMERIC "C" locale to be in effect. It is one of plrestore_locale's + * responsibilities to free the memory allocated here for the locale + * string. +\*--------------------------------------------------------------------------*/ + +void +plsave_set_locale(void) { + char * setlocale_ptr; + char msgbuf[1024]; + + if(!(plsaved_lc_numeric_locale = (char *) malloc(100*sizeof(char)))) { + plexit("plsave_set_locale: out of memory"); + } + + /*save original LC_NUMERIC locale for restore below. */ + if(!(setlocale_ptr = setlocale(LC_NUMERIC, NULL))) { + snprintf(msgbuf,1024,"plsave_set_locale: LC_NUMERIC locale could not be determined for NULL locale.\n"); + plexit(msgbuf); + } + strncpy(plsaved_lc_numeric_locale, setlocale_ptr, 100); + plsaved_lc_numeric_locale[99] = '\0'; + pldebug("plsave_set_locale", "LC_NUMERIC locale to be restored is \"%s\"\n", plsaved_lc_numeric_locale); + if(!(setlocale(LC_NUMERIC, "C"))) { + plexit("plsave_set_locale: LC_NUMERIC locale could not be set to \"C\""); + } +} + +/*--------------------------------------------------------------------------*\ + * plrestore_locale() + * + * For LC_NUMERIC restore the locale string that was determined by + * plsave_set_locale with a pointer to that string stored in the global + * variable plsaved_lc_numeric_locale and free the memory for that string. +\*--------------------------------------------------------------------------*/ + +void +plrestore_locale(void) { + char msgbuf[1024]; + + pldebug("plrestore_locale", "LC_NUMERIC locale to be restored is \"%s\"\n", plsaved_lc_numeric_locale); + + if(!(setlocale(LC_NUMERIC, plsaved_lc_numeric_locale))) { + snprintf(msgbuf,1024,"plrestore_locale: LC_NUMERIC could not be restored to the default \"%s\" locale.\n", plsaved_lc_numeric_locale); + plexit(msgbuf); + } + free(plsaved_lc_numeric_locale); +} + This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |