This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Localeconv() should be independent of 'use locale'
authorKarl Williamson <khw@cpan.org>
Thu, 15 May 2014 21:40:51 +0000 (15:40 -0600)
committerKarl Williamson <khw@cpan.org>
Thu, 5 Jun 2014 17:22:59 +0000 (11:22 -0600)
localeconv() should return the values for the underlying locale of
the program regardless of whether the calling place is within the
scope of "use locale" or not.  Otherwise, it makes no sense to call it
from outside such scope, and a pure perl module that calls it on behalf
of a caller would likely get it wrong.

In earlier versions of Perl the LC_NUMERIC category was initialized to
C, but was changed by the first setlocale() anywhere in the process.  It
is rare to call localeconv() without first having done a setlocale().
But to solve other bugs, future commits will keep LC_NUMERIC in the C
locale except during such operations where it should be the underlying
locale.  localeconv() is such a place, so this commit is being done
before the later ones so it doesn't break.

ext/POSIX/POSIX.xs
ext/POSIX/lib/POSIX.pm
ext/POSIX/lib/POSIX.pod
pod/perldelta.pod
pod/perllocale.pod
t/run/locale.t

index 85c7fc3..b6056d6 100644 (file)
@@ -901,6 +901,11 @@ localeconv()
     CODE:
 #ifdef HAS_LOCALECONV
        struct lconv *lcbuf;
+
+        /* localeconv() deals with both LC_NUMERIC and LC_MONETARY, but
+         * LC_MONETARY is already in the correct locale */
+        STORE_NUMERIC_STANDARD_FORCE_LOCAL();
+
        RETVAL = newHV();
        sv_2mortal((SV*)RETVAL);
        if ((lcbuf = localeconv())) {
@@ -924,6 +929,7 @@ localeconv()
                                    strlen(integers->name), newSViv(value), 0);
            } while ((++integers)->name);
        }
+        RESTORE_NUMERIC_STANDARD();
 #else
        localeconv(); /* A stub to call not_here(). */
 #endif
index 4eecb91..510df22 100644 (file)
@@ -4,7 +4,7 @@ use warnings;
 
 our ($AUTOLOAD, %SIGRT);
 
-our $VERSION = '1.39';
+our $VERSION = '1.40';
 
 require XSLoader;
 
index ee1e77a..59cbd22 100644 (file)
@@ -819,7 +819,7 @@ for creating hard links into files, see L<perlfunc/link>.
 =item C<localeconv>
 
 Get numeric formatting information.  Returns a reference to a hash
-containing the current locale formatting values.  Users of this function
+containing the current underlying locale's formatting values.  Users of this function
 should also read L<perllocale>, which provides a comprehensive
 discussion of Perl locale handling, including
 L<a section devoted to this function|perllocale/The localeconv function>.
index e64cc61..dcd656d 100644 (file)
@@ -492,6 +492,11 @@ A small previously intentional memory leak in PERL_SYS_INIT/PERL_SYS_INIT3 on
 Win32 builds was fixed. This might affect embedders who repeatedly create and
 destroy perl engines within the same process.
 
+=item *
+
+C<POSIX::localeconv()> now returns the data for the program's underlying
+locale even when called from outside the scope of S<C<use locale>>.
+
 =back
 
 =head1 Known Problems
index cb36640..3a5c811 100644 (file)
@@ -621,7 +621,9 @@ because these things are not that standardized.
 
 The C<POSIX::localeconv()> function allows you to get particulars of the
 locale-dependent numeric formatting information specified by the current
-C<LC_NUMERIC> and C<LC_MONETARY> locales.  (If you just want the name of
+underlying C<LC_NUMERIC> and C<LC_MONETARY> locales (regardless of
+whether called from within the scope of C<S<use locale>> or not).  (If
+you just want the name of
 the current locale for a particular category, use C<POSIX::setlocale()>
 with a single parameter--see L<The setlocale function>.)
 
index 6301734..c32fdc8 100644 (file)
@@ -106,6 +106,16 @@ EOF
         }
 
         {
+           fresh_perl_is(<<'EOF', ",,", {},
+print localeconv()->{decimal_point};
+use POSIX;
+use locale;
+print localeconv()->{decimal_point};
+EOF
+           "localeconv() looks at LC_NUMERIC with and without 'use locale'");
+        }
+
+        {
            fresh_perl_is(<<'EOF', $difference, {},
 use locale ":not_characters";
 format STDOUT =
@@ -348,4 +358,4 @@ EOF
 
     }
 
-sub last { 19 }
+sub last { 20 }