diff --git a/src/libraries/Common/src/Interop/Interop.Casing.OSX.cs b/src/libraries/Common/src/Interop/Interop.Casing.iOS.cs similarity index 100% rename from src/libraries/Common/src/Interop/Interop.Casing.OSX.cs rename to src/libraries/Common/src/Interop/Interop.Casing.iOS.cs diff --git a/src/libraries/Common/src/Interop/Interop.Collation.OSX.cs b/src/libraries/Common/src/Interop/Interop.Collation.iOS.cs similarity index 100% rename from src/libraries/Common/src/Interop/Interop.Collation.OSX.cs rename to src/libraries/Common/src/Interop/Interop.Collation.iOS.cs diff --git a/src/libraries/Common/src/Interop/Interop.Locale.OSX.cs b/src/libraries/Common/src/Interop/Interop.Locale.iOS.cs similarity index 100% rename from src/libraries/Common/src/Interop/Interop.Locale.OSX.cs rename to src/libraries/Common/src/Interop/Interop.Locale.iOS.cs diff --git a/src/libraries/System.Globalization/tests/CultureInfo/CultureInfoEnglishName.cs b/src/libraries/System.Globalization/tests/CultureInfo/CultureInfoEnglishName.cs index 67a19e61401164..a1b5cf9445caa7 100644 --- a/src/libraries/System.Globalization/tests/CultureInfo/CultureInfoEnglishName.cs +++ b/src/libraries/System.Globalization/tests/CultureInfo/CultureInfoEnglishName.cs @@ -15,7 +15,7 @@ public static IEnumerable EnglishName_TestData() { yield return new object[] { CultureInfo.CurrentCulture.Name, CultureInfo.CurrentCulture.EnglishName }; - if (SupportFullGlobalizationData) + if (SupportFullGlobalizationData || PlatformDetection.IsHybridGlobalizationOnOSX) { yield return new object[] { "en-US", "English (United States)" }; yield return new object[] { "fr-FR", "French (France)" }; diff --git a/src/libraries/System.Globalization/tests/CultureInfo/CultureInfoNativeName.cs b/src/libraries/System.Globalization/tests/CultureInfo/CultureInfoNativeName.cs index 8293613177688c..35ecb0039df563 100644 --- a/src/libraries/System.Globalization/tests/CultureInfo/CultureInfoNativeName.cs +++ b/src/libraries/System.Globalization/tests/CultureInfo/CultureInfoNativeName.cs @@ -13,10 +13,11 @@ public static IEnumerable NativeName_TestData() yield return new object[] { CultureInfo.CurrentCulture.Name, CultureInfo.CurrentCulture.NativeName }; // Android has its own ICU, which doesn't 100% map to UsingLimitedCultures - if (PlatformDetection.IsNotUsingLimitedCultures || PlatformDetection.IsAndroid) + if (PlatformDetection.IsNotUsingLimitedCultures || PlatformDetection.IsAndroid || PlatformDetection.IsHybridGlobalizationOnOSX) { yield return new object[] { "en-US", "English (United States)" }; yield return new object[] { "en-CA", "English (Canada)" }; + yield return new object[] { "en-GB", "English (United Kingdom)" }; } else { diff --git a/src/libraries/System.Globalization/tests/CultureInfo/CultureInfoThreeLetterISOInfo.cs b/src/libraries/System.Globalization/tests/CultureInfo/CultureInfoThreeLetterISOInfo.cs new file mode 100644 index 00000000000000..4801d9d9d14287 --- /dev/null +++ b/src/libraries/System.Globalization/tests/CultureInfo/CultureInfoThreeLetterISOInfo.cs @@ -0,0 +1,31 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using Xunit; +using System.Collections.Generic; + +namespace System.Globalization.Tests +{ + public class CultureInfoThreeLetterISOInfo + { + public static IEnumerable RegionInfo_TestData() + { + yield return new object[] { 0x409, 244, "en-US", "USA", "eng" }; + yield return new object[] { 0x411, 122, "ja-JP", "JPN", "jpn" }; + yield return new object[] { 0x804, 45, "zh-CN", "CHN", "zho" }; + yield return new object[] { 0x401, 205, "ar-SA", "SAU", "ara" }; + yield return new object[] { 0x412, 134, "ko-KR", "KOR", "kor" }; + yield return new object[] { 0x40d, 117, "he-IL", "ISR", "heb" }; + } + + [Theory] + [MemberData(nameof(RegionInfo_TestData))] + public void MiscTest(int lcid, int geoId, string name, string threeLetterISORegionName, string threeLetterISOLanguageName) + { + RegionInfo ri = new RegionInfo(lcid); // create it with lcid + Assert.Equal(geoId, ri.GeoId); + Assert.Equal(threeLetterISORegionName, ri.ThreeLetterISORegionName); + Assert.Equal(threeLetterISOLanguageName, new CultureInfo(name).ThreeLetterISOLanguageName); + } + } +} diff --git a/src/libraries/System.Globalization/tests/Hybrid/HybridMode.cs b/src/libraries/System.Globalization/tests/Hybrid/HybridMode.cs deleted file mode 100644 index f5443f8c2c3c01..00000000000000 --- a/src/libraries/System.Globalization/tests/Hybrid/HybridMode.cs +++ /dev/null @@ -1,48 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Collections.Generic; -using Xunit; - -namespace System.Globalization.Tests -{ - public class HybridModeTests - { - public static IEnumerable EnglishName_TestData() - { - yield return new object[] { "en-US", "English (United States)" }; - yield return new object[] { "fr-FR", "French (France)" }; - } - - public static IEnumerable NativeName_TestData() - { - yield return new object[] { "en-US", "English (United States)" }; - yield return new object[] { "fr-FR", "français (France)" }; - yield return new object[] { "en-CA", "English (Canada)" }; - } - - [Theory] - [MemberData(nameof(EnglishName_TestData))] - public void TestEnglishName(string cultureName, string expected) - { - CultureInfo myTestCulture = new CultureInfo(cultureName); - Assert.Equal(expected, myTestCulture.EnglishName); - } - - [Theory] - [MemberData(nameof(NativeName_TestData))] - public void TestNativeName(string cultureName, string expected) - { - CultureInfo myTestCulture = new CultureInfo(cultureName); - Assert.Equal(expected, myTestCulture.NativeName); - } - - [Theory] - [InlineData("de-DE", "de")] - [InlineData("en-US", "en")] - public void TwoLetterISOLanguageName(string name, string expected) - { - Assert.Equal(expected, new CultureInfo(name).TwoLetterISOLanguageName); - } - } -} diff --git a/src/libraries/System.Globalization/tests/Hybrid/System.Globalization.IOS.Tests.csproj b/src/libraries/System.Globalization/tests/Hybrid/System.Globalization.IOS.Tests.csproj index da9a1a79c18f02..f21ff6dafff2b8 100644 --- a/src/libraries/System.Globalization/tests/Hybrid/System.Globalization.IOS.Tests.csproj +++ b/src/libraries/System.Globalization/tests/Hybrid/System.Globalization.IOS.Tests.csproj @@ -5,39 +5,44 @@ true - + + + + + + + + + + + + - - - + - - - - - - - - - - + + + - + + + + - - - - - - + + + + + + diff --git a/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems b/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems index 65d65ff797e22c..82eb84609a6f09 100644 --- a/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems +++ b/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems @@ -332,11 +332,11 @@ - + - + @@ -391,7 +391,7 @@ - + @@ -1290,14 +1290,14 @@ Common\Interop\Interop.Casing.cs - - Common\Interop\Interop.Casing.OSX.cs + + Common\Interop\Interop.Casing.iOS.cs Common\Interop\Interop.Collation.cs - - Common\Interop\Interop.Collation.OSX.cs + + Common\Interop\Interop.Collation.iOS.cs Common\Interop\Interop.ICU.cs @@ -1311,8 +1311,8 @@ Common\Interop\Interop.Locale.cs - - Common\Interop\Interop.Locale.OSX.cs + + Common\Interop\Interop.Locale.iOS.cs Common\Interop\Interop.Normalization.cs diff --git a/src/libraries/System.Private.CoreLib/src/System/Globalization/CompareInfo.Icu.cs b/src/libraries/System.Private.CoreLib/src/System/Globalization/CompareInfo.Icu.cs index ee4c0758456375..15d8ee0ed3a551 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Globalization/CompareInfo.Icu.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Globalization/CompareInfo.Icu.cs @@ -24,7 +24,7 @@ private void IcuInitSortHandle(string interopCultureName) _isAsciiEqualityOrdinal = GetIsAsciiEqualityOrdinal(interopCultureName); if (!GlobalizationMode.Invariant) { -#if TARGET_OSX || TARGET_MACCATALYST || TARGET_IOS || TARGET_TVOS || TARGET_BROWSER +#if TARGET_MACCATALYST || TARGET_IOS || TARGET_TVOS || TARGET_BROWSER if (GlobalizationMode.Hybrid) return; #endif @@ -84,7 +84,7 @@ private unsafe int IcuIndexOfCore(ReadOnlySpan source, ReadOnlySpan fixed (char* pSource = &MemoryMarshal.GetReference(source)) fixed (char* pTarget = &MemoryMarshal.GetReference(target)) { -#if TARGET_OSX || TARGET_MACCATALYST || TARGET_IOS || TARGET_TVOS +#if TARGET_MACCATALYST || TARGET_IOS || TARGET_TVOS if (GlobalizationMode.Hybrid) return IndexOfCoreNative(pTarget, target.Length, pSource, source.Length, options, fromBeginning, matchLengthPtr); #endif @@ -203,7 +203,7 @@ private unsafe int IndexOfOrdinalIgnoreCaseHelper(ReadOnlySpan source, Rea throw new Exception((string)ex_result); return result; } -#elif TARGET_OSX || TARGET_MACCATALYST || TARGET_IOS || TARGET_TVOS +#elif TARGET_MACCATALYST || TARGET_IOS || TARGET_TVOS if (GlobalizationMode.Hybrid) return IndexOfCoreNative(b, target.Length, a, source.Length, options, fromBeginning, matchLengthPtr); #endif @@ -305,7 +305,7 @@ private unsafe int IndexOfOrdinalHelper(ReadOnlySpan source, ReadOnlySpan< throw new Exception((string)ex_result); return result; } -#elif TARGET_OSX || TARGET_MACCATALYST || TARGET_IOS || TARGET_TVOS +#elif TARGET_MACCATALYST || TARGET_IOS || TARGET_TVOS if (GlobalizationMode.Hybrid) return IndexOfCoreNative(b, target.Length, a, source.Length, options, fromBeginning, matchLengthPtr); #endif @@ -337,7 +337,7 @@ private unsafe bool IcuStartsWith(ReadOnlySpan source, ReadOnlySpan fixed (char* pSource = &MemoryMarshal.GetReference(source)) // could be null (or otherwise unable to be dereferenced) fixed (char* pPrefix = &MemoryMarshal.GetReference(prefix)) { -#if TARGET_OSX || TARGET_MACCATALYST || TARGET_IOS || TARGET_TVOS +#if TARGET_MACCATALYST || TARGET_IOS || TARGET_TVOS if (GlobalizationMode.Hybrid) return NativeStartsWith(pPrefix, prefix.Length, pSource, source.Length, options); #endif @@ -420,7 +420,7 @@ private unsafe bool StartsWithOrdinalIgnoreCaseHelper(ReadOnlySpan source, return true; InteropCall: -#if TARGET_OSX || TARGET_MACCATALYST || TARGET_IOS || TARGET_TVOS +#if TARGET_MACCATALYST || TARGET_IOS || TARGET_TVOS if (GlobalizationMode.Hybrid) return NativeStartsWith(bp, prefix.Length, ap, source.Length, options); #endif @@ -492,7 +492,7 @@ private unsafe bool StartsWithOrdinalHelper(ReadOnlySpan source, ReadOnlyS return true; InteropCall: -#if TARGET_OSX || TARGET_MACCATALYST || TARGET_IOS || TARGET_TVOS +#if TARGET_MACCATALYST || TARGET_IOS || TARGET_TVOS if (GlobalizationMode.Hybrid) return NativeStartsWith(bp, prefix.Length, ap, source.Length, options); #endif @@ -521,7 +521,7 @@ private unsafe bool IcuEndsWith(ReadOnlySpan source, ReadOnlySpan su fixed (char* pSource = &MemoryMarshal.GetReference(source)) // could be null (or otherwise unable to be dereferenced) fixed (char* pSuffix = &MemoryMarshal.GetReference(suffix)) { -#if TARGET_OSX || TARGET_MACCATALYST || TARGET_IOS || TARGET_TVOS +#if TARGET_MACCATALYST || TARGET_IOS || TARGET_TVOS if (GlobalizationMode.Hybrid) return NativeEndsWith(pSuffix, suffix.Length, pSource, source.Length, options); #endif @@ -605,7 +605,7 @@ private unsafe bool EndsWithOrdinalIgnoreCaseHelper(ReadOnlySpan source, R return true; InteropCall: -#if TARGET_OSX || TARGET_MACCATALYST || TARGET_IOS || TARGET_TVOS +#if TARGET_MACCATALYST || TARGET_IOS || TARGET_TVOS if (GlobalizationMode.Hybrid) return NativeEndsWith(bp, suffix.Length, ap, source.Length, options); #endif @@ -677,7 +677,7 @@ private unsafe bool EndsWithOrdinalHelper(ReadOnlySpan source, ReadOnlySpa return true; InteropCall: -#if TARGET_OSX || TARGET_MACCATALYST || TARGET_IOS || TARGET_TVOS +#if TARGET_MACCATALYST || TARGET_IOS || TARGET_TVOS if (GlobalizationMode.Hybrid) return NativeEndsWith(bp, suffix.Length, ap, source.Length, options); #endif diff --git a/src/libraries/System.Private.CoreLib/src/System/Globalization/CompareInfo.cs b/src/libraries/System.Private.CoreLib/src/System/Globalization/CompareInfo.cs index 05bb9f758883d0..1d7a313d14addf 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Globalization/CompareInfo.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Globalization/CompareInfo.cs @@ -490,7 +490,7 @@ private unsafe int CompareStringCore(ReadOnlySpan string1, ReadOnlySpan source, ReadOnlySpan prefix else { // Linguistic comparison requested and we don't need to special-case any args. -#if TARGET_BROWSER || TARGET_OSX || TARGET_MACCATALYST || TARGET_IOS || TARGET_TVOS +#if TARGET_BROWSER || TARGET_MACCATALYST || TARGET_IOS || TARGET_TVOS if (GlobalizationMode.Hybrid) { throw new PlatformNotSupportedException(SR.PlatformNotSupported_HybridGlobalizationWithMatchLength); @@ -762,7 +762,7 @@ public unsafe bool IsSuffix(ReadOnlySpan source, ReadOnlySpan suffix else { // Linguistic comparison requested and we don't need to special-case any args. -#if TARGET_BROWSER || TARGET_OSX || TARGET_MACCATALYST || TARGET_IOS || TARGET_TVOS +#if TARGET_BROWSER || TARGET_MACCATALYST || TARGET_IOS || TARGET_TVOS if (GlobalizationMode.Hybrid) { throw new PlatformNotSupportedException(SR.PlatformNotSupported_HybridGlobalizationWithMatchLength); @@ -1450,7 +1450,7 @@ public SortKey GetSortKey(string source) private SortKey CreateSortKeyCore(string source, CompareOptions options) => GlobalizationMode.UseNls ? NlsCreateSortKey(source, options) : -#if TARGET_BROWSER || TARGET_OSX || TARGET_MACCATALYST || TARGET_IOS || TARGET_TVOS +#if TARGET_BROWSER || TARGET_MACCATALYST || TARGET_IOS || TARGET_TVOS GlobalizationMode.Hybrid ? throw new PlatformNotSupportedException(GetPNSEText("SortKey")) : #endif @@ -1493,7 +1493,7 @@ public int GetSortKey(ReadOnlySpan source, Span destination, Compare private int GetSortKeyCore(ReadOnlySpan source, Span destination, CompareOptions options) => GlobalizationMode.UseNls ? NlsGetSortKey(source, destination, options) : -#if TARGET_BROWSER || TARGET_OSX || TARGET_MACCATALYST || TARGET_IOS || TARGET_TVOS +#if TARGET_BROWSER || TARGET_MACCATALYST || TARGET_IOS || TARGET_TVOS GlobalizationMode.Hybrid ? throw new PlatformNotSupportedException(GetPNSEText("SortKey")) : #endif @@ -1530,7 +1530,7 @@ public int GetSortKeyLength(ReadOnlySpan source, CompareOptions options = private int GetSortKeyLengthCore(ReadOnlySpan source, CompareOptions options) => GlobalizationMode.UseNls ? NlsGetSortKeyLength(source, options) : -#if TARGET_BROWSER || TARGET_OSX || TARGET_MACCATALYST || TARGET_IOS || TARGET_TVOS +#if TARGET_BROWSER || TARGET_MACCATALYST || TARGET_IOS || TARGET_TVOS GlobalizationMode.Hybrid ? throw new PlatformNotSupportedException(GetPNSEText("SortKey")) : #endif @@ -1607,7 +1607,7 @@ public int GetHashCode(ReadOnlySpan source, CompareOptions options) private unsafe int GetHashCodeOfStringCore(ReadOnlySpan source, CompareOptions options) => GlobalizationMode.UseNls ? NlsGetHashCodeOfString(source, options) : -#if TARGET_BROWSER || TARGET_OSX || TARGET_MACCATALYST || TARGET_IOS || TARGET_TVOS +#if TARGET_BROWSER || TARGET_MACCATALYST || TARGET_IOS || TARGET_TVOS GlobalizationMode.Hybrid ? throw new PlatformNotSupportedException(GetPNSEText("HashCode")) : #endif @@ -1631,7 +1631,7 @@ public SortVersion Version } else { -#if TARGET_BROWSER || TARGET_OSX || TARGET_MACCATALYST || TARGET_IOS || TARGET_TVOS +#if TARGET_BROWSER || TARGET_MACCATALYST || TARGET_IOS || TARGET_TVOS if (GlobalizationMode.Hybrid) { throw new PlatformNotSupportedException(GetPNSEText("SortVersion")); @@ -1647,7 +1647,7 @@ public SortVersion Version public int LCID => CultureInfo.GetCultureInfo(Name).LCID; -#if TARGET_BROWSER || TARGET_OSX || TARGET_MACCATALYST || TARGET_IOS || TARGET_TVOS +#if TARGET_BROWSER || TARGET_MACCATALYST || TARGET_IOS || TARGET_TVOS private static string GetPNSEText(string funcName) => SR.Format(SR.PlatformNotSupported_HybridGlobalization, funcName); #endif } diff --git a/src/libraries/System.Private.CoreLib/src/System/Globalization/CompareInfo.OSX.cs b/src/libraries/System.Private.CoreLib/src/System/Globalization/CompareInfo.iOS.cs similarity index 100% rename from src/libraries/System.Private.CoreLib/src/System/Globalization/CompareInfo.OSX.cs rename to src/libraries/System.Private.CoreLib/src/System/Globalization/CompareInfo.iOS.cs diff --git a/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureData.Unix.cs b/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureData.Unix.cs index 76c009beb6466f..533e97b3127d35 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureData.Unix.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureData.Unix.cs @@ -8,7 +8,7 @@ namespace System.Globalization internal sealed partial class CultureData { private bool InitCultureDataCore() => -#if TARGET_OSX || TARGET_MACCATALYST || TARGET_IOS || TARGET_TVOS +#if TARGET_MACCATALYST || TARGET_IOS || TARGET_TVOS GlobalizationMode.Hybrid ? InitAppleCultureDataCore() : InitIcuCultureDataCore(); #else InitIcuCultureDataCore(); @@ -25,7 +25,7 @@ private bool InitCultureDataCore() => private string[]? GetTimeFormatsCore(bool shortFormat) { -#if TARGET_OSX || TARGET_MACCATALYST || TARGET_IOS || TARGET_TVOS +#if TARGET_MACCATALYST || TARGET_IOS || TARGET_TVOS string format = GlobalizationMode.Hybrid ? GetTimeFormatStringNative(shortFormat) : IcuGetTimeFormatString(shortFormat); #else string format = IcuGetTimeFormatString(shortFormat); diff --git a/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureData.cs b/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureData.cs index 0aa517ef6990f7..51cda682a38133 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureData.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureData.cs @@ -1551,7 +1551,7 @@ internal int FirstDayOfWeek { if (_iFirstDayOfWeek == undef && !GlobalizationMode.Invariant) { -#if TARGET_OSX || TARGET_MACCATALYST || TARGET_IOS || TARGET_TVOS +#if TARGET_MACCATALYST || TARGET_IOS || TARGET_TVOS _iFirstDayOfWeek = GlobalizationMode.Hybrid ? GetLocaleInfoNative(LocaleNumberData.FirstDayOfWeek) : IcuGetLocaleInfo(LocaleNumberData.FirstDayOfWeek); #else _iFirstDayOfWeek = ShouldUseUserOverrideNlsData ? NlsGetFirstDayOfWeek() : IcuGetLocaleInfo(LocaleNumberData.FirstDayOfWeek); @@ -1963,7 +1963,7 @@ internal string TimeSeparator } else { -#if TARGET_OSX || TARGET_MACCATALYST || TARGET_IOS || TARGET_TVOS +#if TARGET_MACCATALYST || TARGET_IOS || TARGET_TVOS string? longTimeFormat = GlobalizationMode.Hybrid ? GetTimeFormatStringNative() : IcuGetTimeFormatString(); #else string? longTimeFormat = ShouldUseUserOverrideNlsData ? NlsGetTimeFormatString() : IcuGetTimeFormatString(); @@ -2303,7 +2303,7 @@ private int GetLocaleInfoCore(LocaleNumberData type) // This is never reached but helps illinker statically remove dependencies if (GlobalizationMode.Invariant) return 0; -#if TARGET_OSX || TARGET_MACCATALYST || TARGET_IOS || TARGET_TVOS +#if TARGET_MACCATALYST || TARGET_IOS || TARGET_TVOS return GlobalizationMode.Hybrid ? GetLocaleInfoNative(type) : IcuGetLocaleInfo(type); #else return GlobalizationMode.UseNls ? NlsGetLocaleInfo(type) : IcuGetLocaleInfo(type); @@ -2315,7 +2315,7 @@ private int GetLocaleInfoCoreUserOverride(LocaleNumberData type) // This is never reached but helps illinker statically remove dependencies if (GlobalizationMode.Invariant) return 0; -#if TARGET_OSX || TARGET_MACCATALYST || TARGET_IOS || TARGET_TVOS +#if TARGET_MACCATALYST || TARGET_IOS || TARGET_TVOS return GlobalizationMode.Hybrid ? GetLocaleInfoNative(type) : IcuGetLocaleInfo(type); #else return ShouldUseUserOverrideNlsData ? NlsGetLocaleInfo(type) : IcuGetLocaleInfo(type); @@ -2328,7 +2328,7 @@ private string GetLocaleInfoCoreUserOverride(LocaleStringData type) if (GlobalizationMode.Invariant) return null!; -#if TARGET_OSX || TARGET_MACCATALYST || TARGET_IOS || TARGET_TVOS +#if TARGET_MACCATALYST || TARGET_IOS || TARGET_TVOS return GlobalizationMode.Hybrid ? GetLocaleInfoNative(type) : IcuGetLocaleInfo(type); #else return ShouldUseUserOverrideNlsData ? NlsGetLocaleInfo(type) : IcuGetLocaleInfo(type); @@ -2341,7 +2341,7 @@ private string GetLocaleInfoCore(LocaleStringData type, string? uiCultureName = if (GlobalizationMode.Invariant) return null!; -#if TARGET_OSX || TARGET_MACCATALYST || TARGET_IOS || TARGET_TVOS +#if TARGET_MACCATALYST || TARGET_IOS || TARGET_TVOS return GlobalizationMode.Hybrid ? GetLocaleInfoNative(type) : IcuGetLocaleInfo(type, uiCultureName); #else return GlobalizationMode.UseNls ? NlsGetLocaleInfo(type) : IcuGetLocaleInfo(type, uiCultureName); @@ -2354,7 +2354,7 @@ private string GetLocaleInfoCore(string localeName, LocaleStringData type, strin if (GlobalizationMode.Invariant) return null!; -#if TARGET_OSX || TARGET_MACCATALYST || TARGET_IOS || TARGET_TVOS +#if TARGET_MACCATALYST || TARGET_IOS || TARGET_TVOS return GlobalizationMode.Hybrid ? GetLocaleInfoNative(localeName, type) : IcuGetLocaleInfo(localeName, type, uiCultureName); #else return GlobalizationMode.UseNls ? NlsGetLocaleInfo(localeName, type) : IcuGetLocaleInfo(localeName, type, uiCultureName); @@ -2367,7 +2367,7 @@ private int[] GetLocaleInfoCoreUserOverride(LocaleGroupingData type) if (GlobalizationMode.Invariant) return null!; -#if TARGET_OSX || TARGET_MACCATALYST || TARGET_IOS || TARGET_TVOS +#if TARGET_MACCATALYST || TARGET_IOS || TARGET_TVOS return GlobalizationMode.Hybrid ? GetLocaleInfoNative(type) : IcuGetLocaleInfo(type); #else return ShouldUseUserOverrideNlsData ? NlsGetLocaleInfo(type) : IcuGetLocaleInfo(type); diff --git a/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureData.OSX.cs b/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureData.iOS.cs similarity index 100% rename from src/libraries/System.Private.CoreLib/src/System/Globalization/CultureData.OSX.cs rename to src/libraries/System.Private.CoreLib/src/System/Globalization/CultureData.iOS.cs diff --git a/src/libraries/System.Private.CoreLib/src/System/Globalization/GlobalizationMode.cs b/src/libraries/System.Private.CoreLib/src/System/Globalization/GlobalizationMode.cs index 56be02927c6e8d..a81023eedccc25 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Globalization/GlobalizationMode.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Globalization/GlobalizationMode.cs @@ -13,7 +13,7 @@ internal static partial class GlobalizationMode private static partial class Settings { internal static bool Invariant { get; } = AppContextConfigHelper.GetBooleanConfig("System.Globalization.Invariant", "DOTNET_SYSTEM_GLOBALIZATION_INVARIANT"); -#if TARGET_OSX || TARGET_MACCATALYST || TARGET_IOS || TARGET_TVOS || TARGET_BROWSER +#if TARGET_MACCATALYST || TARGET_IOS || TARGET_TVOS || TARGET_BROWSER internal static bool Hybrid { get; } = AppContextConfigHelper.GetBooleanConfig("System.Globalization.Hybrid", "DOTNET_SYSTEM_GLOBALIZATION_HYBRID"); #endif internal static bool PredefinedCulturesOnly { get; } = AppContextConfigHelper.GetBooleanConfig("System.Globalization.PredefinedCulturesOnly", "DOTNET_SYSTEM_GLOBALIZATION_PREDEFINED_CULTURES_ONLY", GlobalizationMode.Invariant); @@ -23,7 +23,7 @@ private static partial class Settings // This allows for the whole Settings nested class to be trimmed when Invariant=true, and allows for the Settings // static cctor (on Unix) to be preserved when Invariant=false. internal static bool Invariant => Settings.Invariant; -#if TARGET_OSX || TARGET_MACCATALYST || TARGET_IOS || TARGET_TVOS || TARGET_BROWSER +#if TARGET_MACCATALYST || TARGET_IOS || TARGET_TVOS || TARGET_BROWSER internal static bool Hybrid => Settings.Hybrid; #endif internal static bool PredefinedCulturesOnly => Settings.PredefinedCulturesOnly; diff --git a/src/libraries/System.Private.CoreLib/src/System/Globalization/TextInfo.cs b/src/libraries/System.Private.CoreLib/src/System/Globalization/TextInfo.cs index d868e0dfca8cac..28b9458abed473 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Globalization/TextInfo.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Globalization/TextInfo.cs @@ -692,7 +692,7 @@ private unsafe void ChangeCaseCore(char* src, int srcLen, char* dstBuffer, int d JsChangeCase(src, srcLen, dstBuffer, dstBufferCapacity, bToUpper); return; } -#elif TARGET_OSX || TARGET_MACCATALYST || TARGET_IOS || TARGET_TVOS +#elif TARGET_MACCATALYST || TARGET_IOS || TARGET_TVOS if (GlobalizationMode.Hybrid) { ChangeCaseNative(src, srcLen, dstBuffer, dstBufferCapacity, bToUpper); diff --git a/src/libraries/System.Private.CoreLib/src/System/Globalization/TextInfo.OSX.cs b/src/libraries/System.Private.CoreLib/src/System/Globalization/TextInfo.iOS.cs similarity index 100% rename from src/libraries/System.Private.CoreLib/src/System/Globalization/TextInfo.OSX.cs rename to src/libraries/System.Private.CoreLib/src/System/Globalization/TextInfo.iOS.cs diff --git a/src/native/libs/System.Globalization.Native/entrypoints.c b/src/native/libs/System.Globalization.Native/entrypoints.c index 37246e1bfbdd89..1ba348b910b5ff 100644 --- a/src/native/libs/System.Globalization.Native/entrypoints.c +++ b/src/native/libs/System.Globalization.Native/entrypoints.c @@ -58,7 +58,7 @@ static const Entry s_globalizationNative[] = DllImportEntry(GlobalizationNative_ToAscii) DllImportEntry(GlobalizationNative_ToUnicode) DllImportEntry(GlobalizationNative_WindowsIdToIanaId) -#ifdef __APPLE__ +#if defined(TARGET_MACCATALYST) || defined(TARGET_IOS) || defined(TARGET_TVOS) DllImportEntry(GlobalizationNative_ChangeCaseInvariantNative) DllImportEntry(GlobalizationNative_ChangeCaseNative) DllImportEntry(GlobalizationNative_CompareStringNative) diff --git a/src/native/libs/System.Globalization.Native/pal_casing.m b/src/native/libs/System.Globalization.Native/pal_casing.m index e0bd0f80805c96..eec471f9ab6295 100644 --- a/src/native/libs/System.Globalization.Native/pal_casing.m +++ b/src/native/libs/System.Globalization.Native/pal_casing.m @@ -7,7 +7,7 @@ #import -#if defined(TARGET_OSX) || defined(TARGET_MACCATALYST) || defined(TARGET_IOS) || defined(TARGET_TVOS) +#if defined(TARGET_MACCATALYST) || defined(TARGET_IOS) || defined(TARGET_TVOS) /** * Is this code unit a lead surrogate (U+d800..U+dbff)? diff --git a/src/native/libs/System.Globalization.Native/pal_collation.m b/src/native/libs/System.Globalization.Native/pal_collation.m index 4c755ab475685d..ac59a428aa4c2f 100644 --- a/src/native/libs/System.Globalization.Native/pal_collation.m +++ b/src/native/libs/System.Globalization.Native/pal_collation.m @@ -7,7 +7,7 @@ #import -#if defined(TARGET_OSX) || defined(TARGET_MACCATALYST) || defined(TARGET_IOS) || defined(TARGET_TVOS) +#if defined(TARGET_MACCATALYST) || defined(TARGET_IOS) || defined(TARGET_TVOS) // Enum that corresponds to C# CompareOptions typedef enum diff --git a/src/native/libs/System.Globalization.Native/pal_locale.m b/src/native/libs/System.Globalization.Native/pal_locale.m index fb4e2ab9db7e48..4f31e359e94324 100644 --- a/src/native/libs/System.Globalization.Native/pal_locale.m +++ b/src/native/libs/System.Globalization.Native/pal_locale.m @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. #include +#include #include "pal_locale_internal.h" #include "pal_localeStringData.h" #include "pal_localeNumberData.h" @@ -31,7 +32,7 @@ return strdup([localeName UTF8String]); } -#if defined(TARGET_OSX) || defined(TARGET_MACCATALYST) || defined(TARGET_IOS) || defined(TARGET_TVOS) +#if defined(TARGET_MACCATALYST) || defined(TARGET_IOS) || defined(TARGET_TVOS) const char* GlobalizationNative_GetLocaleNameNative(const char* localeName) { @@ -41,6 +42,50 @@ return strdup(value); } +/** + * Useful constant for the maximum size of the whole locale ID + * (including the terminating NULL and all keywords). + */ +#define FULLNAME_CAPACITY 157 + +static void GetParent(const char* localeID, char* parent, int32_t parentCapacity) +{ + const char *lastUnderscore; + int32_t i; + + if (localeID == NULL) + localeID = [NSLocale systemLocale].localeIdentifier.UTF8String; + + lastUnderscore = strrchr(localeID, '-'); + if (lastUnderscore != NULL) + { + i = (int32_t)(lastUnderscore - localeID); + } + else + { + i = 0; + } + + if (i > 0) + { + // primary lang subtag und (undefined). + if (strncasecmp(localeID, "und-", 4) == 0) + { + localeID += 3; + i -= 3; + memmove(parent, localeID, MIN(i, parentCapacity)); + } + else if (parent != localeID) + { + memcpy(parent, localeID, MIN(i, parentCapacity)); + } + } + + // terminate chars + if (i >= 0 && i < parentCapacity) + parent[i] = 0; +} + const char* GlobalizationNative_GetLocaleInfoStringNative(const char* localeName, LocaleStringData localeStringData) { const char* value; @@ -89,6 +134,16 @@ value = [currentLocale.decimalSeparator UTF8String]; // or value = [[currentLocale objectForKey:NSLocaleDecimalSeparator] UTF8String]; break; + case LocaleString_Digits: + { + NSString *digitsString = @"0123456789"; + NSNumberFormatter *nf1 = [[NSNumberFormatter alloc] init]; + [nf1 setLocale:currentLocale]; + + NSNumber *newNum = [nf1 numberFromString:digitsString]; + value = [[newNum stringValue] UTF8String]; + break; + } case LocaleString_MonetarySymbol: value = [currentLocale.currencySymbol UTF8String]; break; @@ -102,6 +157,12 @@ case LocaleString_CurrencyNativeName: value = [[currentLocale localizedStringForCurrencyCode:currentLocale.currencyCode] UTF8String]; break; + case LocaleString_MonetaryDecimalSeparator: + value = [numberFormatter.currencyDecimalSeparator UTF8String]; + break; + case LocaleString_MonetaryThousandSeparator: + value = [numberFormatter.currencyGroupingSeparator UTF8String]; + break; case LocaleString_AMDesignator: value = [dateFormatter.AMSymbol UTF8String]; break; @@ -115,12 +176,23 @@ value = [numberFormatter.minusSign UTF8String]; break; case LocaleString_Iso639LanguageTwoLetterName: - // check if this is correct value = [[currentLocale objectForKey:NSLocaleLanguageCode] UTF8String]; break; + case LocaleString_Iso639LanguageThreeLetterName: + { + NSString *iso639_2 = [currentLocale objectForKey:NSLocaleLanguageCode]; + value = uloc_getISO3LanguageByLangCode([iso639_2 UTF8String]); + break; + } case LocaleString_Iso3166CountryName: - value = [currentLocale.countryCode UTF8String]; + value = [[currentLocale objectForKey:NSLocaleCountryCode] UTF8String]; + break; + case LocaleString_Iso3166CountryName2: + { + const char *countryCode = strdup([[currentLocale objectForKey:NSLocaleCountryCode] UTF8String]); + value = uloc_getISO3CountryByCountryCode(countryCode); break; + } case LocaleString_NaNSymbol: value = [numberFormatter.notANumberSymbol UTF8String]; break; @@ -136,19 +208,20 @@ case LocaleString_PerMilleSymbol: value = [numberFormatter.perMillSymbol UTF8String]; break; - // TODO find mapping for below cases - // https://github.com/dotnet/runtime/issues/83514 - case LocaleString_Digits: - case LocaleString_MonetaryDecimalSeparator: - case LocaleString_MonetaryThousandSeparator: - case LocaleString_Iso639LanguageThreeLetterName: case LocaleString_ParentName: - case LocaleString_Iso3166CountryName2: + { + char localeNameTemp[FULLNAME_CAPACITY]; + const char* lName = [currentLocale.localeIdentifier UTF8String]; + GetParent(lName, localeNameTemp, FULLNAME_CAPACITY); + value = strdup(localeNameTemp); + break; + } default: value = ""; break; } - return strdup(value); + + return value ? strdup(value) : ""; } // invariant character definitions diff --git a/src/tests/build.proj b/src/tests/build.proj index 8737c34181070a..13e3c0f189de71 100644 --- a/src/tests/build.proj +++ b/src/tests/build.proj @@ -427,7 +427,10 @@ <_LinkerFlagsToDrop Include="@(NativeFramework->'-framework %(Identity)')" /> - +