summaryrefslogtreecommitdiff
path: root/locale.c
diff options
context:
space:
mode:
authorKarl Williamson <public@khwilliamson.com>2014-02-19 14:55:29 -0700
committerKarl Williamson <public@khwilliamson.com>2014-02-19 15:07:36 -0700
commit89f7b9aac23a02ff8140b277b76eb7a70b0b04cc (patch)
tree254cace89b2a0458c1f6c69282299afded2e1281 /locale.c
parent63baef57e83f77e202ae14ef902a6615cf69c8a2 (diff)
downloadperl-89f7b9aac23a02ff8140b277b76eb7a70b0b04cc.tar.gz
.locale.c: Better emulate POSIX locale setting on Windows
Commit b385bb4ddcb252e69a1044d702646741e2e489fb introduced my_setlocale() compiled only under Windows which emulates the POSIX rules for setting the locale. It differs from Windows only if the locale passed in is "". Unfortunately it was buggy if the category being set was LC_ALL, and there is a LANG environment variable. LANG has lower precedence than the other environment variables, like LC_NUMERIC, but my_setlocale() was giving it higher priority when set through LC_ALL. This should solve the problems being seen since 7cd8b56846670e577e1f62479eab8f38fb11da14
Diffstat (limited to 'locale.c')
-rw-r--r--locale.c60
1 files changed, 58 insertions, 2 deletions
diff --git a/locale.c b/locale.c
index 9557a17bdf..b8bfe4ab96 100644
--- a/locale.c
+++ b/locale.c
@@ -348,6 +348,9 @@ Perl_my_setlocale(pTHX_ int category, const char* locale)
* otherwise to use the particular category's variable if set; otherwise to
* use the LANG variable. */
+ unsigned override_LANG = 0;
+ char * result;
+
if (locale && strEQ(locale, "")) {
# ifdef LC_ALL
locale = PerlEnv_getenv("LC_ALL");
@@ -356,6 +359,7 @@ Perl_my_setlocale(pTHX_ int category, const char* locale)
switch (category) {
# ifdef LC_ALL
case LC_ALL:
+ override_LANG++;
break; /* We already know its variable isn't set */
# endif
# ifdef USE_LOCALE_TIME
@@ -395,7 +399,10 @@ Perl_my_setlocale(pTHX_ int category, const char* locale)
}
if (! locale) {
locale = PerlEnv_getenv("LANG");
- if (! locale) {
+ if (locale) {
+ override_LANG++;
+ }
+ else {
locale = "";
}
}
@@ -404,7 +411,56 @@ Perl_my_setlocale(pTHX_ int category, const char* locale)
# endif
}
- return setlocale(category, locale);
+ result = setlocale(category, locale);
+
+ if (override_LANG < 2) {
+ return result;
+ }
+
+ /* Here the input locale was LC_ALL, and we have set it to what is in the
+ * LANG variable. But LANG has lower priority than the other LC_foo
+ * variables, so override it for each one that is set. (If they are set to
+ * "", it means to use the same thing we just set LC_ALL to, so can skip)
+ * */
+# ifdef USE_LOCALE_TIME
+ result = PerlEnv_getenv("LC_TIME");
+ if (result and strNE(result, "")) {
+ setlocale(LC_TIME, result);
+ }
+# endif
+# ifdef USE_LOCALE_CTYPE
+ result = PerlEnv_getenv("LC_CTYPE");
+ if (result and strNE(result, "")) {
+ setlocale(LC_CTYPE, result);
+ }
+# endif
+# ifdef USE_LOCALE_COLLATE
+ result = PerlEnv_getenv("LC_COLLATE");
+ if (result and strNE(result, "")) {
+ setlocale(LC_COLLATE, result);
+ }
+# endif
+# ifdef USE_LOCALE_MONETARY
+ result = PerlEnv_getenv("LC_MONETARY");
+ if (result and strNE(result, "")) {
+ setlocale(LC_MONETARY, result);
+ }
+# endif
+# ifdef USE_LOCALE_NUMERIC
+ result = PerlEnv_getenv("LC_NUMERIC");
+ if (result and strNE(result, "")) {
+ setlocale(LC_NUMERIC, result);
+ }
+# endif
+# ifdef USE_LOCALE_MESSAGES
+ result = PerlEnv_getenv("LC_MESSAGES");
+ if (result and strNE(result, "")) {
+ setlocale(LC_MESSAGES, result);
+ }
+# endif
+
+ return setlocale(LC_ALL, NULL);
+
}
#endif