toke.c: Set locale for all scan_num() calls; restore instead of reset
authorKarl Williamson <public@khwilliamson.com>
Thu, 12 Dec 2013 06:15:25 +0000 (23:15 -0700)
committerKarl Williamson <public@khwilliamson.com>
Sat, 4 Jan 2014 20:33:06 +0000 (13:33 -0700)
One call of Perl_scan_num changes the locale around it.  However, this
function is called in several places, including from outside the file.
It is better to set the locale within scan_num() at the point where
it matters.  And, instead of setting the locale unconditionally, it is
better to change it only if it needs to be changed, and restore it to
the original.  Otherwise the locale can be changed to something
unexpected.

toke.c

diff --git a/toke.c b/toke.c
index 8ac0f31..f8ebf53 100644 (file)
--- a/toke.c
+++ b/toke.c
@@ -2407,15 +2407,7 @@ S_force_version(pTHX_ char *s, int guessing)
 #endif
         if (*d == ';' || isSPACE(*d) || *d == '{' || *d == '}' || !*d) {
            SV *ver;
-#ifdef USE_LOCALE_NUMERIC
-           char *loc = savepv(setlocale(LC_NUMERIC, NULL));
-           setlocale(LC_NUMERIC, "C");
-#endif
             s = scan_num(s, &pl_yylval);
-#ifdef USE_LOCALE_NUMERIC
-           setlocale(LC_NUMERIC, loc);
-           Safefree(loc);
-#endif
             version = pl_yylval.opval;
            ver = cSVOPx(version)->op_sv;
            if (SvPOK(ver) && !SvNIOK(ver)) {
@@ -11330,9 +11322,11 @@ Perl_scan_num(pTHX_ const char *start, YYSTYPE* lvalp)
               floatit = TRUE;
         }
        if (floatit) {
+            STORE_NUMERIC_LOCAL_SET_STANDARD();
            /* terminate the string */
            *d = '\0';
            nv = Atof(PL_tokenbuf);
+            RESTORE_NUMERIC_LOCAL();
            sv = newSVnv(nv);
        }