From: Karl Williamson Date: Thu, 12 Dec 2013 06:04:40 +0000 (-0700) Subject: POSIX:strtod() should restore the locale it changed X-Git-Tag: upstream/5.20.0~844^2~6 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=371d5d44b054ca1540da57f7be95194f1d92f449;p=platform%2Fupstream%2Fperl.git POSIX:strtod() should restore the locale it changed Prior to this commit, the locale remained as strtod() set it to. I could not find a case where this actually was a problem, as the other code is good about checking for and changing the locale where needed. But uses of atoi(), strtol() in locales where there are spaces in numbers likely would break. --- diff --git a/ext/POSIX/POSIX.xs b/ext/POSIX/POSIX.xs index 3e77eb4..08e459c 100644 --- a/ext/POSIX/POSIX.xs +++ b/ext/POSIX/POSIX.xs @@ -1482,7 +1482,7 @@ strtod(str) double num; char *unparsed; PPCODE: - SET_NUMERIC_LOCAL(); + STORE_NUMERIC_STANDARD_FORCE_LOCAL(); num = strtod(str, &unparsed); PUSHs(sv_2mortal(newSVnv(num))); if (GIMME == G_ARRAY) { @@ -1492,6 +1492,7 @@ strtod(str) else PUSHs(&PL_sv_undef); } + RESTORE_NUMERIC_STANDARD(); void strtol(str, base = 0) diff --git a/ext/POSIX/lib/POSIX.pm b/ext/POSIX/lib/POSIX.pm index 0dd8475..d0bc3fd 100644 --- a/ext/POSIX/lib/POSIX.pm +++ b/ext/POSIX/lib/POSIX.pm @@ -4,7 +4,7 @@ use warnings; our ($AUTOLOAD, %SIGRT); -our $VERSION = '1.37'; +our $VERSION = '1.38'; require XSLoader; diff --git a/perl.h b/perl.h index c777b1b..b6e0c3e 100644 --- a/perl.h +++ b/perl.h @@ -5288,6 +5288,12 @@ typedef struct am_table_short AMTS; bool was_standard = PL_numeric_standard && IN_SOME_LOCALE_FORM; \ if (was_standard) SET_NUMERIC_LOCAL(); +/* Rarely, we want to change to the underlying locale even outside of 'use + * locale'. This is principally in the POSIX:: functions */ +#define STORE_NUMERIC_STANDARD_FORCE_LOCAL() \ + bool was_standard = PL_numeric_standard; \ + if (was_standard) SET_NUMERIC_LOCAL(); + #define RESTORE_NUMERIC_LOCAL() \ if (was_local) SET_NUMERIC_LOCAL(); diff --git a/t/run/locale.t b/t/run/locale.t index d4419ca..d61fbb9 100644 --- a/t/run/locale.t +++ b/t/run/locale.t @@ -20,6 +20,7 @@ BEGIN { } use Config; my $have_setlocale = $Config{d_setlocale} eq 'define'; +my $have_strtod = $Config{d_strtod} eq 'define'; $have_setlocale = 0 if $@; # Visual C's CRT goes silly on strings of the form "en_US.ISO8859-1" # and mingw32 uses said silly CRT @@ -221,8 +222,22 @@ EOF print \$i, "\n"; EOF "1,5\n2,5", {}, "Can do math when radix is a comma"); # [perl 115800] + + unless ($have_strtod) { + skip("no strtod()", 1); + } + else { + fresh_perl_is(<<"EOF", + use POSIX; + POSIX::setlocale(POSIX::LC_NUMERIC(),"$comma"); + my \$one_point_5 = POSIX::strtod("1,5"); + \$one_point_5 =~ s/0+\$//; # Remove any trailing zeros + print \$one_point_5, "\n"; +EOF + "1.5", {}, "POSIX::strtod() uses underlying locale"); + } } } # SKIP -sub last { 12 } +sub last { 13 }