ICU: replace windows related source files with those from mypal68 (ICU 64.2)

This commit is contained in:
roytam1 2022-07-26 23:55:00 +08:00
commit 3a65ef9ca8
10 changed files with 503 additions and 689 deletions

View file

@ -32,18 +32,9 @@
#include "cmemory.h"
#include "unicode/uloc.h"
#if U_PLATFORM == U_PF_WINDOWS && defined(_MSC_VER) && (_MSC_VER >= 1500)
/*
* TODO: It seems like we should widen this to
* either U_PLATFORM_USES_ONLY_WIN32_API (includes MinGW)
* or U_PLATFORM_HAS_WIN32_API (includes MinGW and Cygwin)
* but those use gcc and won't have defined(_MSC_VER).
* We might need to #include some Windows header and test for some version macro from there.
* Or call some Windows function and see what it returns.
*/
#define USE_WINDOWS_LCID_MAPPING_API
#if U_PLATFORM_HAS_WIN32_API && UCONFIG_USE_WINDOWS_LCID_MAPPING_API
#include <windows.h>
#include <winnls.h>
#include <winnls.h> // LCIDToLocaleName and LocaleNameToLCID
#endif
/*
@ -973,7 +964,7 @@ idCmp(const char* id1, const char* id2)
/**
* Searches for a Windows LCID
*
* @param posixid the Posix style locale id.
* @param posixID the Posix style locale id.
* @param status gets set to U_ILLEGAL_ARGUMENT_ERROR when the Posix ID has
* no equivalent Windows LCID.
* @return the LCID
@ -1035,7 +1026,7 @@ getPosixID(const ILcidPosixMap *this_0, uint32_t hostID)
//
/////////////////////////////////////
*/
#ifdef USE_WINDOWS_LCID_MAPPING_API
#if U_PLATFORM_HAS_WIN32_API && UCONFIG_USE_WINDOWS_LCID_MAPPING_API
/*
* Various language tags needs to be changed:
* quz -> qu
@ -1053,6 +1044,7 @@ getPosixID(const ILcidPosixMap *this_0, uint32_t hostID)
}
#endif
U_CAPI int32_t
uprv_convertToPosix(uint32_t hostid, char *posixID, int32_t posixIDCapacity, UErrorCode* status)
{
@ -1061,8 +1053,10 @@ uprv_convertToPosix(uint32_t hostid, char *posixID, int32_t posixIDCapacity, UEr
UBool bLookup = TRUE;
const char *pPosixID = NULL;
#ifdef USE_WINDOWS_LCID_MAPPING_API
char locName[LOCALE_NAME_MAX_LENGTH] = {}; // ICU name can't be longer than Windows name
#if U_PLATFORM_HAS_WIN32_API && UCONFIG_USE_WINDOWS_LCID_MAPPING_API
static_assert(ULOC_FULLNAME_CAPACITY > LOCALE_NAME_MAX_LENGTH, "Windows locale names have smaller length than ICU locale names.");
char locName[157]; /* ULOC_FULLNAME_CAPACITY */
// Note: Windows primary lang ID 0x92 in LCID is used for Central Kurdish and
// GetLocaleInfo() maps such LCID to "ku". However, CLDR uses "ku" for
@ -1070,47 +1064,37 @@ uprv_convertToPosix(uint32_t hostid, char *posixID, int32_t posixIDCapacity, UEr
// use the Windows API to resolve locale ID for this specific case.
if ((hostid & 0x3FF) != 0x92) {
int32_t tmpLen = 0;
UChar windowsLocaleName[LOCALE_NAME_MAX_LENGTH]; // ULOC_FULLNAME_CAPACITY > LOCALE_NAME_MAX_LENGTH
char16_t windowsLocaleName[LOCALE_NAME_MAX_LENGTH] = {};
#define LOCALE_SNAME 0x0000005c
// Note: LOCALE_ALLOW_NEUTRAL_NAMES was enabled in Windows7+, prior versions did not handle neutral (no-region) locale names.
tmpLen = LCIDToLocaleName(hostid, (PWSTR)windowsLocaleName, UPRV_LENGTHOF(windowsLocaleName), LOCALE_ALLOW_NEUTRAL_NAMES);
tmpLen = GetLocaleInfoA(hostid, LOCALE_SNAME, (LPSTR)locName, UPRV_LENGTHOF(locName));
if (tmpLen > 1) {
int32_t i = 0;
// Only need to look up in table if have _, eg for de-de_phoneb type alternate sort.
bLookup = FALSE;
for (i = 0; i < UPRV_LENGTHOF(locName); i++)
{
locName[i] = (char)(windowsLocaleName[i]);
// Windows locale name may contain sorting variant, such as "es-ES_tradnl".
// In such cases, we need special mapping data found in the hardcoded table
// in this source file.
if (windowsLocaleName[i] == L'_')
{
// Keep the base locale, without variant
// TODO: Should these be mapped from _phoneb to @collation=phonebook, etc.?
locName[i] = '\0';
tmpLen = i;
bLookup = TRUE;
break;
}
else if (windowsLocaleName[i] == L'-')
{
// Windows names use -, ICU uses _
locName[i] = '_';
}
else if (windowsLocaleName[i] == L'\0')
{
// No point in doing more work than necessary
break;
}
/* Windows locale name may contain sorting variant, such as "es-ES_tradnl".
In such case, we need special mapping data found in the hardcoded table
in this source file. */
char *p = uprv_strchr(locName, '_');
if (p) {
/* Keep the base locale, without variant */
*p = 0;
tmpLen = uprv_strlen(locName);
}
// TODO: Need to understand this better, why isn't it an alias?
else {
/* No hardcoded table lookup necessary */
bLookup = FALSE;
}
/* Change the tag separator from '-' to '_' */
p = locName;
while (*p) {
if (*p == '-') {
*p = '_';
}
p++;
}
FIX_LANGUAGE_ID_TAG(locName, tmpLen);
pPosixID = locName;
}
}
#endif // USE_WINDOWS_LCID_MAPPING_API
#endif
if (bLookup) {
const char *pCandidate = NULL;
@ -1132,7 +1116,7 @@ uprv_convertToPosix(uint32_t hostid, char *posixID, int32_t posixIDCapacity, UEr
}
if (pPosixID) {
int32_t resLen = static_cast<int32_t>(uprv_strlen(pPosixID));
int32_t resLen = uprv_strlen(pPosixID);
int32_t copyLen = resLen <= posixIDCapacity ? resLen : posixIDCapacity;
uprv_memcpy(posixID, pPosixID, copyLen);
if (resLen < posixIDCapacity) {
@ -1162,21 +1146,16 @@ uprv_convertToPosix(uint32_t hostid, char *posixID, int32_t posixIDCapacity, UEr
//
/////////////////////////////////////
*/
U_CAPI uint32_t
uprv_convertToLCIDPlatform(const char* localeID)
/*U_CAPI uint32_t
uprv_convertToLCIDPlatform(const char* localeID, UErrorCode* status)
{
// The purpose of this function is to leverage native platform name->lcid
if (U_FAILURE(*status)) {
return 0;
}
// The purpose of this function is to leverage the Windows platform name->lcid
// conversion functionality when available.
#ifdef USE_WINDOWS_LCID_MAPPING_API
DWORD nameLCIDFlags = 0;
UErrorCode myStatus = U_ZERO_ERROR;
// First check for a Windows name->LCID match, fall through to catch
// ICU special cases, but Windows may know it already.
#if LOCALE_ALLOW_NEUTRAL_NAMES
nameLCIDFlags = LOCALE_ALLOW_NEUTRAL_NAMES;
#endif /* LOCALE_ALLOW_NEUTRAL_NAMES */
#if U_PLATFORM_HAS_WIN32_API && UCONFIG_USE_WINDOWS_LCID_MAPPING_API
int32_t len;
char collVal[ULOC_KEYWORDS_CAPACITY] = {};
char baseName[ULOC_FULLNAME_CAPACITY] = {};
@ -1185,8 +1164,8 @@ uprv_convertToLCIDPlatform(const char* localeID)
// Check any for keywords.
if (uprv_strchr(localeID, '@'))
{
len = uloc_getKeywordValue(localeID, "collation", collVal, UPRV_LENGTHOF(collVal) - 1, &myStatus);
if (U_SUCCESS(myStatus) && len > 0)
len = uloc_getKeywordValue(localeID, "collation", collVal, UPRV_LENGTHOF(collVal) - 1, status);
if (U_SUCCESS(*status) && len > 0)
{
// If it contains the keyword collation, return 0 so that the LCID lookup table will be used.
return 0;
@ -1194,9 +1173,9 @@ uprv_convertToLCIDPlatform(const char* localeID)
else
{
// If the locale ID contains keywords other than collation, just use the base name.
len = uloc_getBaseName(localeID, baseName, UPRV_LENGTHOF(baseName) - 1, &myStatus);
len = uloc_getBaseName(localeID, baseName, UPRV_LENGTHOF(baseName) - 1, status);
if (U_SUCCESS(myStatus) && len > 0)
if (U_SUCCESS(*status) && len > 0)
{
baseName[len] = 0;
mylocaleID = baseName;
@ -1206,9 +1185,9 @@ uprv_convertToLCIDPlatform(const char* localeID)
char asciiBCP47Tag[LOCALE_NAME_MAX_LENGTH] = {};
// this will change it from de_DE@collation=phonebook to de-DE-u-co-phonebk form
(void)uloc_toLanguageTag(mylocaleID, asciiBCP47Tag, UPRV_LENGTHOF(asciiBCP47Tag), FALSE, &myStatus);
(void)uloc_toLanguageTag(mylocaleID, asciiBCP47Tag, UPRV_LENGTHOF(asciiBCP47Tag), FALSE, status);
if (U_SUCCESS(myStatus))
if (U_SUCCESS(*status))
{
// Need it to be UTF-16, not 8-bit
wchar_t bcp47Tag[LOCALE_NAME_MAX_LENGTH] = {};
@ -1230,7 +1209,7 @@ uprv_convertToLCIDPlatform(const char* localeID)
{
// Ensure it's null terminated
bcp47Tag[i] = L'\0';
LCID lcid = LocaleNameToLCID(bcp47Tag, nameLCIDFlags);
LCID lcid = LocaleNameToLCID(bcp47Tag, LOCALE_ALLOW_NEUTRAL_NAMES);
if (lcid > 0)
{
// Found LCID from windows, return that one, unless its completely ambiguous
@ -1244,12 +1223,12 @@ uprv_convertToLCIDPlatform(const char* localeID)
}
}
#else
(void)localeID; // Suppress unused variable warning.
#endif /* USE_WINDOWS_LCID_MAPPING_API */
(void) localeID; // Suppress unused variable warning.
#endif
// No found, or not implemented on platforms without native name->lcid conversion
// Nothing found, or not implemented.
return 0;
}
}*/
U_CAPI uint32_t
uprv_convertToLCID(const char *langID, const char* posixID, UErrorCode* status)