Skip to content

Bump the minimum ICU version to 60 #112713

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Feb 20, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions src/native/libs/System.Globalization.Native/config.h.in
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
#pragma once

#cmakedefine01 HAVE_UDAT_STANDALONE_SHORTER_WEEKDAYS
#cmakedefine01 HAVE_SET_MAX_VARIABLE
#cmakedefine01 HAVE_UCOL_CLONE
#cmakedefine01 HAVE_UCOL_CLONE
7 changes: 0 additions & 7 deletions src/native/libs/System.Globalization.Native/configure.cmake
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
if(CLR_CMAKE_TARGET_ANDROID OR CLR_CMAKE_TARGET_APPLE OR CLR_CMAKE_TARGET_BROWSER OR CLR_CMAKE_TARGET_WASI)
set(HAVE_SET_MAX_VARIABLE 1)
set(HAVE_UDAT_STANDALONE_SHORTER_WEEKDAYS 1)
set(HAVE_UCOL_CLONE 0)
else()
Expand All @@ -15,12 +14,6 @@ else()
" HAVE_UDAT_STANDALONE_SHORTER_WEEKDAYS)

set(CMAKE_REQUIRED_LIBRARIES ${ICUUC} ${ICUI18N})

check_symbol_exists(
ucol_setMaxVariable
"unicode/ucol.h"
HAVE_SET_MAX_VARIABLE)

check_symbol_exists(
ucol_clone
"unicode/ucol.h"
Expand Down
28 changes: 0 additions & 28 deletions src/native/libs/System.Globalization.Native/pal_collation.c
Original file line number Diff line number Diff line change
Expand Up @@ -384,38 +384,10 @@ static UCollator* CloneCollatorWithOptions(const UCollator* pCollator, int32_t o
{
ucol_setAttribute(pClonedCollator, UCOL_ALTERNATE_HANDLING, UCOL_SHIFTED, pErr);

#if !defined(STATIC_ICU)
if (ucol_setMaxVariable_ptr != NULL)
{
// by default, ICU alternate shifted handling only ignores punctuation, but
// IgnoreSymbols needs symbols and currency as well, so change the "variable top"
// to include all symbols and currency
ucol_setMaxVariable(pClonedCollator, UCOL_REORDER_CODE_CURRENCY, pErr);
}
else
{
assert(ucol_setVariableTop_ptr != NULL);
// 0xfdfc is the last currency character before the first digit character
// in http://source.icu-project.org/repos/icu/icu/tags/release-52-1/source/data/unidata/FractionalUCA.txt
const UChar ignoreSymbolsVariableTop[] = { 0xfdfc };
ucol_setVariableTop_ptr(pClonedCollator, ignoreSymbolsVariableTop, 1, pErr);
}

#else // !defined(STATIC_ICU)

// by default, ICU alternate shifted handling only ignores punctuation, but
// IgnoreSymbols needs symbols and currency as well, so change the "variable top"
// to include all symbols and currency
#if HAVE_SET_MAX_VARIABLE
ucol_setMaxVariable(pClonedCollator, UCOL_REORDER_CODE_CURRENCY, pErr);
#else
// 0xfdfc is the last currency character before the first digit character
// in http://source.icu-project.org/repos/icu/icu/tags/release-52-1/source/data/unidata/FractionalUCA.txt
const UChar ignoreSymbolsVariableTop[] = { 0xfdfc };
ucol_setVariableTop(pClonedCollator, ignoreSymbolsVariableTop, 1, pErr);
#endif

#endif //!defined(STATIC_ICU)
}

ucol_setAttribute(pClonedCollator, UCOL_STRENGTH, strength, pErr);
Expand Down
34 changes: 1 addition & 33 deletions src/native/libs/System.Globalization.Native/pal_icushim.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@ FOR_ALL_ICU_FUNCTIONS

static void* libicuuc = NULL;
static void* libicui18n = NULL;
ucol_setVariableTop_func ucol_setVariableTop_ptr = NULL;
ucol_safeClone_func ucol_safeClone_ptr = NULL;

#if defined (TARGET_UNIX)
Expand Down Expand Up @@ -240,7 +239,7 @@ static int FindICULibs(char* symbolName, char* symbolVersion)
// a year.
// On some platforms (mainly Alpine Linux) we want to make our minimum version
// an earlier version than what we build that we know we support.
#define MinICUVersion 50
#define MinICUVersion 60
#define MaxICUVersion (U_ICU_VERSION_MAJOR_NUM + 30)
#define MinMinorICUVersion 1
#define MaxMinorICUVersion 5
Expand Down Expand Up @@ -443,35 +442,6 @@ static void InitializeUColClonePointers(char* symbolVersion)
}
}

static void InitializeVariableMaxAndTopPointers(char* symbolVersion)
{
if (ucol_setMaxVariable_ptr != NULL)
{
return;
}

#if defined(TARGET_OSX) || defined(TARGET_ANDROID)
// OSX and Android always run against ICU version which has ucol_setMaxVariable.
// We shouldn't come here.
(void)symbolVersion;
assert(false);
#elif defined(TARGET_WINDOWS)
char symbolName[SYMBOL_NAME_SIZE];
sprintf_s(symbolName, SYMBOL_NAME_SIZE, "ucol_setVariableTop%s", symbolVersion);
ucol_setVariableTop_ptr = (ucol_setVariableTop_func)GetProcAddress((HMODULE)libicui18n, symbolName);
#else
char symbolName[SYMBOL_NAME_SIZE];
snprintf(symbolName, SYMBOL_NAME_SIZE, "ucol_setVariableTop%s", symbolVersion);
ucol_setVariableTop_ptr = (ucol_setVariableTop_func)dlsym(libicui18n, symbolName);
#endif // defined(TARGET_OSX) || defined(TARGET_ANDROID)

if (ucol_setVariableTop_ptr == NULL)
{
fprintf(stderr, "Cannot get the symbols of ICU APIs ucol_setMaxVariable or ucol_setVariableTop.\n");
abort();
}
}

// GlobalizationNative_LoadICU
// This method get called from the managed side during the globalization initialization.
// This method shouldn't get called at all if we are running in globalization invariant mode
Expand Down Expand Up @@ -509,7 +479,6 @@ int32_t GlobalizationNative_LoadICU(void)
FOR_ALL_ICU_FUNCTIONS
ValidateICUDataCanLoad();

InitializeVariableMaxAndTopPointers(symbolVersion);
InitializeUColClonePointers(symbolVersion);

return true;
Expand Down Expand Up @@ -566,7 +535,6 @@ void GlobalizationNative_InitICUFunctions(void* icuuc, void* icuin, const char*
FOR_ALL_ICU_FUNCTIONS
ValidateICUDataCanLoad();

InitializeVariableMaxAndTopPointers(symbolVersion);
InitializeUColClonePointers(symbolVersion);
}

Expand Down
26 changes: 4 additions & 22 deletions src/native/libs/System.Globalization.Native/pal_icushim_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,6 @@

#include "icu.h"

#define HAVE_SET_MAX_VARIABLE 1
#define UDAT_STANDALONE_SHORTER_WEEKDAYS 1

#endif
Expand All @@ -63,34 +62,20 @@
#if !defined(STATIC_ICU)

#if !defined(TARGET_ANDROID)
// (U_ICU_VERSION_MAJOR_NUM < 52)
// The following APIs are not supported in the ICU versions less than 52. We need to define them manually.
// We have to do runtime check before using the pointers to these APIs. That is why these are listed in the FOR_ALL_OPTIONAL_ICU_FUNCTIONS list.
U_CAPI void U_EXPORT2 ucol_setMaxVariable(UCollator* coll, UColReorderCode group, UErrorCode* pErrorCode);
U_CAPI int32_t U_EXPORT2 ucal_getTimeZoneIDForWindowsID(const UChar* winid, int32_t len, const char* region, UChar* id, int32_t idCapacity, UErrorCode* status);
U_CAPI int32_t U_EXPORT2 ucal_getWindowsTimeZoneID(const UChar* id, int32_t len, UChar* winid, int32_t winidCapacity, UErrorCode* status);

// (U_ICU_VERSION_MAJOR_NUM < 71)
// The following API is not supported in the ICU versions less than 71. We need to define it manually.
// We have to do runtime check before using the pointers to this API. That is why these are listed in the FOR_ALL_OPTIONAL_ICU_FUNCTIONS list.
U_CAPI UCollator* U_EXPORT2 ucol_clone(const UCollator* coll, UErrorCode* status);

// ucol_setVariableTop is a deprecated function on the newer ICU versions and ucol_setMaxVariable should be used instead.
// As we can run against ICU versions which do not support ucol_setMaxVariable, we will dynamically try to get the pointer
// to ucol_setVariableTop when we could not get a pointer to ucol_setMaxVariable.
typedef uint32_t (U_EXPORT2 *ucol_setVariableTop_func)(UCollator* coll, const UChar* varTop, int32_t len, UErrorCode* status);

// ucol_safeClone is deprecated in ICU version 71. We have to handle it manually to avoid getting a build break when referencing it in the code.
typedef UCollator* (U_EXPORT2 *ucol_safeClone_func)(const UCollator* coll, void* stackBuffer, int32_t* pBufferSize, UErrorCode* status);

#else // !defined(TARGET_ANDROID)

typedef uint32_t (*ucol_setVariableTop_func)(UCollator* coll, const UChar* varTop, int32_t len, UErrorCode* status);
typedef UCollator* (*ucol_safeClone_func)(const UCollator* coll, void* stackBuffer, int32_t* pBufferSize, UErrorCode* status);

#endif // !defined(TARGET_ANDROID)

extern ucol_setVariableTop_func ucol_setVariableTop_ptr;
extern ucol_safeClone_func ucol_safeClone_ptr;

// List of all functions from the ICU libraries that are used in the System.Globalization.Native.so
Expand All @@ -114,6 +99,8 @@ extern ucol_safeClone_func ucol_safeClone_ptr;
PER_FUNCTION_BLOCK(ucal_getLimit, libicui18n, true) \
PER_FUNCTION_BLOCK(ucal_getNow, libicui18n, true) \
PER_FUNCTION_BLOCK(ucal_getTimeZoneDisplayName, libicui18n, true) \
PER_FUNCTION_BLOCK(ucal_getTimeZoneIDForWindowsID, libicui18n, true) \
PER_FUNCTION_BLOCK(ucal_getWindowsTimeZoneID, libicui18n, true) \
PER_FUNCTION_BLOCK(ucal_open, libicui18n, true) \
PER_FUNCTION_BLOCK(ucal_openTimeZoneIDEnumeration, libicui18n, true) \
PER_FUNCTION_BLOCK(ucal_set, libicui18n, true) \
Expand All @@ -131,6 +118,7 @@ extern ucol_safeClone_func ucol_safeClone_ptr;
PER_FUNCTION_BLOCK(ucol_openElements, libicui18n, true) \
PER_FUNCTION_BLOCK(ucol_openRules, libicui18n, true) \
PER_FUNCTION_BLOCK(ucol_setAttribute, libicui18n, true) \
PER_FUNCTION_BLOCK(ucol_setMaxVariable, libicui18n, true) \
PER_FUNCTION_BLOCK(ucol_strcoll, libicui18n, true) \
PER_FUNCTION_BLOCK(udat_close, libicui18n, true) \
PER_FUNCTION_BLOCK(udat_countSymbols, libicui18n, true) \
Expand Down Expand Up @@ -215,9 +203,6 @@ extern ucol_safeClone_func ucol_safeClone_ptr;
// The following are the list of the ICU APIs which are optional. If these APIs exist in the ICU version we load at runtime, then we'll use it.
// Otherwise, we'll just not provide the functionality to users which needed these APIs.
#define FOR_ALL_OPTIONAL_ICU_FUNCTIONS \
PER_FUNCTION_BLOCK(ucal_getWindowsTimeZoneID, libicui18n, false) \
PER_FUNCTION_BLOCK(ucal_getTimeZoneIDForWindowsID, libicui18n, false) \
PER_FUNCTION_BLOCK(ucol_setMaxVariable, libicui18n, false) \
PER_FUNCTION_BLOCK(ucol_clone, libicui18n, false)

#define FOR_ALL_ICU_FUNCTIONS \
Expand Down Expand Up @@ -343,9 +328,6 @@ FOR_ALL_ICU_FUNCTIONS

#else // !defined(STATIC_ICU)

#define ucal_getWindowsTimeZoneID_ptr ucal_getWindowsTimeZoneID
#define ucal_getTimeZoneIDForWindowsID_ptr ucal_getTimeZoneIDForWindowsID

#if defined(TARGET_MACCATALYST) || defined(TARGET_IOS) || defined(TARGET_TVOS)
const char* GlobalizationNative_GetICUDataPathRelativeToAppBundleRoot(const char* path);
const char* GlobalizationNative_GetICUDataPathFallback(void);
Expand All @@ -360,7 +342,7 @@ const char* GlobalizationNative_GetICUDataPathFallback(void);
* "Safe" macro, checks for a valid code point.
* Converts code points outside of Basic Multilingual Plane into
* corresponding surrogate pairs if sufficient space in the string.
* High surrogate range: 0xD800 - 0xDBFF
* High surrogate range: 0xD800 - 0xDBFF
* Low surrogate range: 0xDC00 - 0xDFFF
* If the code point is not valid or a trail surrogate does not fit,
* then isError is set to true.
Expand Down
20 changes: 7 additions & 13 deletions src/native/libs/System.Globalization.Native/pal_timeZoneInfo.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,10 @@ int32_t GlobalizationNative_WindowsIdToIanaId(const UChar* windowsId, const char
{
UErrorCode status = U_ZERO_ERROR;

if (ucal_getTimeZoneIDForWindowsID_ptr != NULL)
int32_t ianaIdFilledLength = ucal_getTimeZoneIDForWindowsID(windowsId, -1, region, ianaId, ianaIdLength, &status);
if (U_SUCCESS(status))
{
int32_t ianaIdFilledLength = ucal_getTimeZoneIDForWindowsID(windowsId, -1, region, ianaId, ianaIdLength, &status);
if (U_SUCCESS(status))
{
return ianaIdFilledLength;
}
return ianaIdFilledLength;
}

// Failed
Expand All @@ -45,14 +42,11 @@ int32_t GlobalizationNative_IanaIdToWindowsId(const UChar* ianaId, UChar* window
{
UErrorCode status = U_ZERO_ERROR;

if (ucal_getWindowsTimeZoneID_ptr != NULL)
{
int32_t windowsIdFilledLength = ucal_getWindowsTimeZoneID(ianaId, -1, windowsId, windowsIdLength, &status);
int32_t windowsIdFilledLength = ucal_getWindowsTimeZoneID(ianaId, -1, windowsId, windowsIdLength, &status);

if (U_SUCCESS(status))
{
return windowsIdFilledLength;
}
if (U_SUCCESS(status))
{
return windowsIdFilledLength;
}

// Failed
Expand Down
Loading