return cd;
}
+ if (cultureName.Length == 1 && (cultureName[0] == 'C' || cultureName[0] == 'c'))
+ {
+ // Always map the "C" locale to Invariant to avoid mapping it to en_US_POSIX on Linux because POSIX
+ // locale collation doesn't support case insensitive comparisons.
+ // We do the same mapping on Windows for the sake of consistency.
+ return CultureData.Invariant;
+ }
+
CultureData culture = new CultureData();
culture._bUseOverrides = useUserOverride;
culture._sRealName = cultureName;
return i;
}
-static int IsEnvVarSet(const char* name)
-{
- const char* value = getenv(name);
-
- return (value != NULL) && (strcmp("", value) != 0);
-}
-
-// The behavior of uloc_getDefault() on POSIX systems is to query
-// setlocale(LC_MESSAGES) and use that value, unless it is C or
-// POSIX. In that case it tries to read LC_ALL, LC_MESSAGES and LANG
-// and then falls back to en_US_POSIX if none of them are set.
-//
-// en_US_POSIX is a weird locale since the collation rules treat 'a'
-// and 'A' as different letters even when ignoring case. Furthermore
-// it's common for LC_ALL, LC_MESSAGES and LANG to be unset when
-// running under Docker.
-//
-// We'd rather default to invariant in this case. If any of these
-// are set, we'll just call into ICU and let it do whatever
-// normalization it would do.
+// We use whatever ICU give us as the default locale except if it is en_US_POSIX. We'll map
+// this POSIX locale to Invariant instead. The reason is POSIX locale collation behavior
+// is not desirable at all because it doesn't support case insensitive string comparisons.
const char* DetectDefaultLocaleName()
{
- char* loc = setlocale(LC_MESSAGES, NULL);
-
- if (loc != NULL && (strcmp("C", loc) == 0 || strcmp("POSIX", loc) == 0))
+ const char* icuLocale = uloc_getDefault();
+ if (strcmp(icuLocale, "en_US_POSIX") == 0)
{
- if (!IsEnvVarSet("LC_ALL") && !IsEnvVarSet("LC_MESSAGES") && !IsEnvVarSet("LANG"))
- {
- return "";
- }
+ return "";
}
- return uloc_getDefault();
+ return icuLocale;
}
// GlobalizationNative_GetLocales gets all locale names and store it in the value buffer