Skip to content

Commit

Permalink
Detect the default locale name during startup on Apple platforms
Browse files Browse the repository at this point in the history
This change adds a function to lookup the current NSLocale and extract the language + country code to load into ICU by default.  Previously, we would defer to uloc_getDefault in ICU, which would return a value we would ignore (en_US_POSIX) and result in falling back to invariant mode.

Fixes #68321
  • Loading branch information
Steve Pfister committed Apr 29, 2022
1 parent 1351ac8 commit 2f780a4
Show file tree
Hide file tree
Showing 6 changed files with 60 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,14 @@ public void CurrentCulture()
}
}

[Fact]
[PlatformSpecific(TestPlatforms.OSX | TestPlatforms.iOS | TestPlatforms.MacCatalyst | TestPlatforms.tvOS)]
public void CurrentCulture_Default_Not_Invariant()
{
Assert.NotEqual(CultureInfo.CurrentCulture, CultureInfo.InvariantCulture);
Assert.NotEqual(CultureInfo.CurrentUICulture, CultureInfo.InvariantCulture);
}

[Fact]
public void CurrentCulture_Set_Null_ThrowsArgumentNullException()
{
Expand Down
7 changes: 7 additions & 0 deletions src/mono/mono/mini/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,13 @@ if(HAVE_SYS_ICU AND NOT HOST_WASI)
pal_timeZoneInfo.c
entrypoints.c
${pal_icushim_sources_base})

if (TARGET_DARWIN)
set(icu_shim_sources_base
${icu_shim_sources_base}
pal_locale.m)
endif()

addprefix(icu_shim_sources "${ICU_SHIM_PATH}" "${icu_shim_sources_base}")
set_source_files_properties(${icu_shim_sources} PROPERTIES COMPILE_DEFINITIONS OSX_ICU_LIBRARY_PATH="${OSX_ICU_LIBRARY_PATH}")
set_source_files_properties(${icu_shim_sources} PROPERTIES COMPILE_FLAGS "-I\"${ICU_INCLUDEDIR}\" -I\"${CLR_SRC_NATIVE_DIR}/libs/System.Globalization.Native/\" -I\"${CLR_SRC_NATIVE_DIR}/libs/Common/\" ${ICU_FLAGS}")
Expand Down
4 changes: 4 additions & 0 deletions src/native/libs/System.Globalization.Native/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,10 @@ set(NATIVEGLOBALIZATION_SOURCES
pal_icushim.c
)

if (CLR_CMAKE_TARGET_OSX OR CLR_CMAKE_TARGET_MACCATALYST OR CLR_CMAKE_TARGET_IOS OR CLR_CMAKE_TARGET_TVOS)
set(NATIVEGLOBALIZATION_SOURCES ${NATIVEGLOBALIZATION_SOURCES} pal_locale.m)
endif()

# time zone names are filtered out of icu data for the browser and associated functionality is disabled
if (NOT CLR_CMAKE_TARGET_BROWSER)
set(NATIVEGLOBALIZATION_SOURCES ${NATIVEGLOBALIZATION_SOURCES} pal_timeZoneInfo.c)
Expand Down
4 changes: 4 additions & 0 deletions src/native/libs/System.Globalization.Native/pal_locale.c
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,11 @@ int32_t FixupLocaleName(UChar* value, int32_t valueLength)
// is not desirable at all because it doesn't support case insensitive string comparisons.
const char* DetectDefaultLocaleName()
{
#ifndef __APPLE__
const char* icuLocale = uloc_getDefault();
#else
const char* icuLocale = DetectDefaultAppleLocaleName();
#endif
if (strcmp(icuLocale, "en_US_POSIX") == 0)
{
return "";
Expand Down
27 changes: 27 additions & 0 deletions src/native/libs/System.Globalization.Native/pal_locale.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

#include "pal_locale_internal.h"
#import <Foundation/Foundation.h>

const char* DetectDefaultAppleLocaleName()
{
NSLocale *currentLocale = [NSLocale currentLocale];
NSString *localeName = @"";

if (!currentLocale)
{
return strdup([localeName UTF8String]);
}

if ([currentLocale.languageCode length] > 0 && [currentLocale.countryCode length] > 0)
{
localeName = [NSString stringWithFormat:@"%@-%@", currentLocale.languageCode, currentLocale.countryCode];
}
else
{
localeName = [currentLocale.localeIdentifier stringByReplacingOccurrencesOfString:@"_" withString:@"-"];
}

return strdup([localeName UTF8String]);
}
10 changes: 10 additions & 0 deletions src/native/libs/System.Globalization.Native/pal_locale_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,3 +51,13 @@ Detect the default locale for the machine, defaulting to Invaraint if
we can't compute one (different from uloc_getDefault()) would do.
*/
const char* DetectDefaultLocaleName(void);

#ifdef __APPLE__
/*
Function:
DetectDefaultSystemLocaleName
Detects the default locale string for Apple platforms
*/
const char* DetectDefaultAppleLocaleName(void);
#endif

0 comments on commit 2f780a4

Please sign in to comment.