locale.c: Handle case where LC_ALL isn't "all"
authorKarl Williamson <public@khwilliamson.com>
Mon, 17 Feb 2014 05:06:03 +0000 (22:06 -0700)
committerKarl Williamson <public@khwilliamson.com>
Mon, 17 Feb 2014 05:47:10 +0000 (22:47 -0700)
Setting the LC_ALL locale category on NetBSD does not necessarily change
all the categories to the requested locale.  Sometimes the LC_COLLATE
category is set to POSIX.  I presume that is because collation has not
been defined for the given locale, so it uses a basic locale instead.
The code in locale.c that does locale initialization for the Perl
program at start-up, depended on LC_ALL setting all categories to the
same locale.

locale.c

index bf55d04..d22d2ab 100644 (file)
--- a/locale.c
+++ b/locale.c
@@ -578,8 +578,19 @@ Perl_init_i18nl10n(pTHX_ int printwarn)
         }
 
 #ifdef LC_ALL
-        if (! my_setlocale(LC_ALL, trial_locale))
+        if (! my_setlocale(LC_ALL, trial_locale)) {
             setlocale_failure = TRUE;
+        }
+        else {
+            /* Since LC_ALL succeeded, it should have changed all the other
+             * categories it can to its value; so we massage things so that the
+             * setlocales below just return their category's current values.
+             * This adequately handles the case in NetBSD where LC_COLLATE may
+             * not be defined for a locale, and setting it individually will
+             * fail, whereas setting LC_ALL suceeds, leaving LC_COLLATE set to
+             * the POSIX locale. */
+            trial_locale = NULL;
+        }
 #endif /* LC_ALL */
 
         if (!setlocale_failure) {