mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-09-08 00:38:39 +09:00
Issue #1971 - Part 2: Update ICU source to 63.2.
This commit is contained in:
parent
8df84683be
commit
1e69214382
3160 changed files with 275815 additions and 234203 deletions
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright (C) 2016 and later: Unicode, Inc. and others.
|
||||
// © 2016 and later: Unicode, Inc. and others.
|
||||
// License & terms of use: http://www.unicode.org/copyright.html
|
||||
/*
|
||||
******************************************************************************
|
||||
|
|
@ -43,8 +43,24 @@
|
|||
// Must be before any other #includes.
|
||||
#include "uposixdefs.h"
|
||||
|
||||
/* include ICU headers */
|
||||
#include "unicode/utypes.h"
|
||||
// First, the platform type. Need this for U_PLATFORM.
|
||||
#include "unicode/platform.h"
|
||||
|
||||
#if U_PLATFORM == U_PF_MINGW && defined __STRICT_ANSI__
|
||||
/* tzset isn't defined in strict ANSI on MinGW. */
|
||||
#undef __STRICT_ANSI__
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Cygwin with GCC requires inclusion of time.h after the above disabling strict asci mode statement.
|
||||
*/
|
||||
#include <time.h>
|
||||
|
||||
#if !U_PLATFORM_USES_ONLY_WIN32_API
|
||||
#include <sys/time.h>
|
||||
#endif
|
||||
|
||||
/* include the rest of the ICU headers */
|
||||
#include "unicode/putil.h"
|
||||
#include "unicode/ustring.h"
|
||||
#include "putilimp.h"
|
||||
|
|
@ -76,14 +92,28 @@
|
|||
* Should Cygwin be included as well (U_PLATFORM_HAS_WIN32_API)
|
||||
* to use native APIs as much as possible?
|
||||
*/
|
||||
#ifndef WIN32_LEAN_AND_MEAN
|
||||
# define WIN32_LEAN_AND_MEAN
|
||||
#endif
|
||||
# define VC_EXTRALEAN
|
||||
# define NOUSER
|
||||
# define NOSERVICE
|
||||
# define NOIME
|
||||
# define NOMCX
|
||||
# include <windows.h>
|
||||
# include "unicode/uloc.h"
|
||||
# include "wintz.h"
|
||||
#if U_PLATFORM_HAS_WINUWP_API
|
||||
typedef PVOID LPMSG; // TODO: figure out how to get rid of this typedef
|
||||
#include <Windows.Globalization.h>
|
||||
#include <windows.system.userprofile.h>
|
||||
#include <wrl/wrappers/corewrappers.h>
|
||||
#include <wrl/client.h>
|
||||
|
||||
using namespace ABI::Windows::Foundation;
|
||||
using namespace Microsoft::WRL;
|
||||
using namespace Microsoft::WRL::Wrappers;
|
||||
#endif
|
||||
#elif U_PLATFORM == U_PF_OS400
|
||||
# include <float.h>
|
||||
# include <qusec.h> /* error code structure */
|
||||
|
|
@ -104,20 +134,6 @@
|
|||
# include <sys/neutrino.h>
|
||||
#endif
|
||||
|
||||
#if (U_PF_MINGW <= U_PLATFORM && U_PLATFORM <= U_PF_CYGWIN) && defined(__STRICT_ANSI__)
|
||||
/* tzset isn't defined in strict ANSI on Cygwin and MinGW. */
|
||||
#undef __STRICT_ANSI__
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Cygwin with GCC requires inclusion of time.h after the above disabling strict asci mode statement.
|
||||
*/
|
||||
#include <time.h>
|
||||
|
||||
#if !U_PLATFORM_USES_ONLY_WIN32_API
|
||||
#include <sys/time.h>
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Only include langinfo.h if we have a way to get the codeset. If we later
|
||||
* depend on more feature, we can test on U_HAVE_NL_LANGINFO.
|
||||
|
|
@ -516,6 +532,28 @@ uprv_fmin(double x, double y)
|
|||
return (x > y ? y : x);
|
||||
}
|
||||
|
||||
U_CAPI UBool U_EXPORT2
|
||||
uprv_add32_overflow(int32_t a, int32_t b, int32_t* res) {
|
||||
// NOTE: Some compilers (GCC, Clang) have primitives available, like __builtin_add_overflow.
|
||||
// This function could be optimized by calling one of those primitives.
|
||||
auto a64 = static_cast<int64_t>(a);
|
||||
auto b64 = static_cast<int64_t>(b);
|
||||
int64_t res64 = a64 + b64;
|
||||
*res = static_cast<int32_t>(res64);
|
||||
return res64 != *res;
|
||||
}
|
||||
|
||||
U_CAPI UBool U_EXPORT2
|
||||
uprv_mul32_overflow(int32_t a, int32_t b, int32_t* res) {
|
||||
// NOTE: Some compilers (GCC, Clang) have primitives available, like __builtin_mul_overflow.
|
||||
// This function could be optimized by calling one of those primitives.
|
||||
auto a64 = static_cast<int64_t>(a);
|
||||
auto b64 = static_cast<int64_t>(b);
|
||||
int64_t res64 = a64 * b64;
|
||||
*res = static_cast<int32_t>(res64);
|
||||
return res64 != *res;
|
||||
}
|
||||
|
||||
/**
|
||||
* Truncates the given double.
|
||||
* trunc(3.3) = 3.0, trunc (-3.3) = -3.0
|
||||
|
|
@ -651,13 +689,23 @@ uprv_timezone()
|
|||
/* Note that U_TZNAME does *not* have to be tzname, but if it is,
|
||||
some platforms need to have it declared here. */
|
||||
|
||||
#if defined(U_TZNAME) && (U_PLATFORM == U_PF_IRIX || U_PLATFORM_IS_DARWIN_BASED || (U_PLATFORM == U_PF_CYGWIN && !U_PLATFORM_USES_ONLY_WIN32_API))
|
||||
#if defined(U_TZNAME) && (U_PLATFORM == U_PF_IRIX || U_PLATFORM_IS_DARWIN_BASED)
|
||||
/* RS6000 and others reject char **tzname. */
|
||||
extern U_IMPORT char *U_TZNAME[];
|
||||
#endif
|
||||
|
||||
#if !UCONFIG_NO_FILE_IO && ((U_PLATFORM_IS_DARWIN_BASED && (U_PLATFORM != U_PF_IPHONE || defined(U_TIMEZONE))) || U_PLATFORM_IS_LINUX_BASED || U_PLATFORM == U_PF_BSD || U_PLATFORM == U_PF_SOLARIS)
|
||||
/* These platforms are likely to use Olson timezone IDs. */
|
||||
/* common targets of the symbolic link at TZDEFAULT are:
|
||||
* "/usr/share/zoneinfo/<olsonID>" default, older Linux distros, macOS to 10.12
|
||||
* "../usr/share/zoneinfo/<olsonID>" newer Linux distros: Red Hat Enterprise Linux 7, Ubuntu 16, SuSe Linux 12
|
||||
* "/usr/share/lib/zoneinfo/<olsonID>" Solaris
|
||||
* "../usr/share/lib/zoneinfo/<olsonID>" Solaris
|
||||
* "/var/db/timezone/zoneinfo/<olsonID>" macOS 10.13
|
||||
* To avoid checking lots of paths, just check that the target path
|
||||
* before the <olsonID> ends with "/zoneinfo/", and the <olsonID> is valid.
|
||||
*/
|
||||
|
||||
#define CHECK_LOCALTIME_LINK 1
|
||||
#if U_PLATFORM_IS_DARWIN_BASED
|
||||
#include <tzfile.h>
|
||||
|
|
@ -665,12 +713,12 @@ extern U_IMPORT char *U_TZNAME[];
|
|||
#elif U_PLATFORM == U_PF_SOLARIS
|
||||
#define TZDEFAULT "/etc/localtime"
|
||||
#define TZZONEINFO "/usr/share/lib/zoneinfo/"
|
||||
#define TZZONEINFO2 "../usr/share/lib/zoneinfo/"
|
||||
#define TZ_ENV_CHECK "localtime"
|
||||
#else
|
||||
#define TZDEFAULT "/etc/localtime"
|
||||
#define TZZONEINFO "/usr/share/zoneinfo/"
|
||||
#endif
|
||||
#define TZZONEINFOTAIL "/zoneinfo/"
|
||||
#if U_HAVE_DIRENT_H
|
||||
#define TZFILE_SKIP "posixrules" /* tz file to skip when searching. */
|
||||
/* Some Linux distributions have 'localtime' in /usr/share/zoneinfo
|
||||
|
|
@ -922,30 +970,30 @@ static CharString *gSearchTZFileResult = NULL;
|
|||
* This function is not thread safe - it uses a global, gSearchTZFileResult, to hold its results.
|
||||
*/
|
||||
static char* searchForTZFile(const char* path, DefaultTZInfo* tzInfo) {
|
||||
DIR* dirp = opendir(path);
|
||||
DIR* subDirp = NULL;
|
||||
DIR* dirp = NULL;
|
||||
struct dirent* dirEntry = NULL;
|
||||
|
||||
char* result = NULL;
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
|
||||
/* Save the current path */
|
||||
CharString curpath(path, -1, status);
|
||||
if (U_FAILURE(status)) {
|
||||
goto cleanupAndReturn;
|
||||
}
|
||||
|
||||
dirp = opendir(path);
|
||||
if (dirp == NULL) {
|
||||
return result;
|
||||
goto cleanupAndReturn;
|
||||
}
|
||||
|
||||
if (gSearchTZFileResult == NULL) {
|
||||
gSearchTZFileResult = new CharString;
|
||||
if (gSearchTZFileResult == NULL) {
|
||||
return NULL;
|
||||
goto cleanupAndReturn;
|
||||
}
|
||||
ucln_common_registerCleanup(UCLN_COMMON_PUTIL, putil_cleanup);
|
||||
}
|
||||
|
||||
/* Save the current path */
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
CharString curpath(path, -1, status);
|
||||
if (U_FAILURE(status)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Check each entry in the directory. */
|
||||
while((dirEntry = readdir(dirp)) != NULL) {
|
||||
const char* dirName = dirEntry->d_name;
|
||||
|
|
@ -954,15 +1002,16 @@ static char* searchForTZFile(const char* path, DefaultTZInfo* tzInfo) {
|
|||
CharString newpath(curpath, status);
|
||||
newpath.append(dirName, -1, status);
|
||||
if (U_FAILURE(status)) {
|
||||
return NULL;
|
||||
break;
|
||||
}
|
||||
|
||||
DIR* subDirp = NULL;
|
||||
if ((subDirp = opendir(newpath.data())) != NULL) {
|
||||
/* If this new path is a directory, make a recursive call with the newpath. */
|
||||
closedir(subDirp);
|
||||
newpath.append('/', status);
|
||||
if (U_FAILURE(status)) {
|
||||
return NULL;
|
||||
break;
|
||||
}
|
||||
result = searchForTZFile(newpath.data(), tzInfo);
|
||||
/*
|
||||
|
|
@ -986,7 +1035,7 @@ static char* searchForTZFile(const char* path, DefaultTZInfo* tzInfo) {
|
|||
gSearchTZFileResult->clear();
|
||||
gSearchTZFileResult->append(zoneid, -1, status);
|
||||
if (U_FAILURE(status)) {
|
||||
return NULL;
|
||||
break;
|
||||
}
|
||||
result = gSearchTZFileResult->data();
|
||||
/* Get out after the first one found. */
|
||||
|
|
@ -995,7 +1044,11 @@ static char* searchForTZFile(const char* path, DefaultTZInfo* tzInfo) {
|
|||
}
|
||||
}
|
||||
}
|
||||
closedir(dirp);
|
||||
|
||||
cleanupAndReturn:
|
||||
if (dirp) {
|
||||
closedir(dirp);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
|
|
@ -1011,6 +1064,7 @@ uprv_tzname_clear_cache()
|
|||
U_CAPI const char* U_EXPORT2
|
||||
uprv_tzname(int n)
|
||||
{
|
||||
(void)n; // Avoid unreferenced parameter warning.
|
||||
const char *tzid = NULL;
|
||||
#if U_PLATFORM_USES_ONLY_WIN32_API
|
||||
tzid = uprv_detectWindowsTimeZone();
|
||||
|
|
@ -1018,6 +1072,15 @@ uprv_tzname(int n)
|
|||
if (tzid != NULL) {
|
||||
return tzid;
|
||||
}
|
||||
|
||||
#ifndef U_TZNAME
|
||||
// The return value is free'd in timezone.cpp on Windows because
|
||||
// the other code path returns a pointer to a heap location.
|
||||
// If we don't have a name already, then tzname wouldn't be any
|
||||
// better, so just fall back.
|
||||
return uprv_strdup("Etc/UTC");
|
||||
#endif // !U_TZNAME
|
||||
|
||||
#else
|
||||
|
||||
/*#if U_PLATFORM_IS_DARWIN_BASED
|
||||
|
|
@ -1059,24 +1122,15 @@ uprv_tzname(int n)
|
|||
*/
|
||||
int32_t ret = (int32_t)readlink(TZDEFAULT, gTimeZoneBuffer, sizeof(gTimeZoneBuffer)-1);
|
||||
if (0 < ret) {
|
||||
int32_t tzZoneInfoLen = uprv_strlen(TZZONEINFO);
|
||||
int32_t tzZoneInfoTailLen = uprv_strlen(TZZONEINFOTAIL);
|
||||
gTimeZoneBuffer[ret] = 0;
|
||||
if (uprv_strncmp(gTimeZoneBuffer, TZZONEINFO, tzZoneInfoLen) == 0
|
||||
&& isValidOlsonID(gTimeZoneBuffer + tzZoneInfoLen))
|
||||
char * tzZoneInfoTailPtr = uprv_strstr(gTimeZoneBuffer, TZZONEINFOTAIL);
|
||||
|
||||
if (tzZoneInfoTailPtr != NULL
|
||||
&& isValidOlsonID(tzZoneInfoTailPtr + tzZoneInfoTailLen))
|
||||
{
|
||||
return (gTimeZoneBufferPtr = gTimeZoneBuffer + tzZoneInfoLen);
|
||||
return (gTimeZoneBufferPtr = tzZoneInfoTailPtr + tzZoneInfoTailLen);
|
||||
}
|
||||
#if U_PLATFORM == U_PF_SOLARIS
|
||||
else
|
||||
{
|
||||
tzZoneInfoLen = uprv_strlen(TZZONEINFO2);
|
||||
if (uprv_strncmp(gTimeZoneBuffer, TZZONEINFO2, tzZoneInfoLen) == 0
|
||||
&& isValidOlsonID(gTimeZoneBuffer + tzZoneInfoLen))
|
||||
{
|
||||
return (gTimeZoneBufferPtr = gTimeZoneBuffer + tzZoneInfoLen);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
#if defined(SEARCH_TZFILE)
|
||||
DefaultTZInfo* tzInfo = (DefaultTZInfo*)uprv_malloc(sizeof(DefaultTZInfo));
|
||||
|
|
@ -1162,7 +1216,8 @@ UInitOnce gTimeZoneFilesInitOnce = U_INITONCE_INITIALIZER;
|
|||
static CharString *gTimeZoneFilesDirectory = NULL;
|
||||
|
||||
#if U_POSIX_LOCALE || U_PLATFORM_USES_ONLY_WIN32_API
|
||||
static char *gCorrectedPOSIXLocale = NULL; /* Heap allocated */
|
||||
static const char *gCorrectedPOSIXLocale = NULL; /* Sometimes heap allocated */
|
||||
static bool gCorrectedPOSIXLocaleHeapAllocated = false;
|
||||
#endif
|
||||
|
||||
static UBool U_CALLCONV putil_cleanup(void)
|
||||
|
|
@ -1183,9 +1238,10 @@ static UBool U_CALLCONV putil_cleanup(void)
|
|||
#endif
|
||||
|
||||
#if U_POSIX_LOCALE || U_PLATFORM_USES_ONLY_WIN32_API
|
||||
if (gCorrectedPOSIXLocale) {
|
||||
uprv_free(gCorrectedPOSIXLocale);
|
||||
if (gCorrectedPOSIXLocale && gCorrectedPOSIXLocaleHeapAllocated) {
|
||||
uprv_free(const_cast<char *>(gCorrectedPOSIXLocale));
|
||||
gCorrectedPOSIXLocale = NULL;
|
||||
gCorrectedPOSIXLocaleHeapAllocated = false;
|
||||
}
|
||||
#endif
|
||||
return TRUE;
|
||||
|
|
@ -1219,7 +1275,7 @@ u_setDataDirectory(const char *directory) {
|
|||
#if (U_FILE_SEP_CHAR != U_FILE_ALT_SEP_CHAR)
|
||||
{
|
||||
char *p;
|
||||
while(p = uprv_strchr(newDataDir, U_FILE_ALT_SEP_CHAR)) {
|
||||
while((p = uprv_strchr(newDataDir, U_FILE_ALT_SEP_CHAR)) != NULL) {
|
||||
*p = U_FILE_SEP_CHAR;
|
||||
}
|
||||
}
|
||||
|
|
@ -1269,6 +1325,43 @@ uprv_pathIsAbsolute(const char *path)
|
|||
# endif
|
||||
#endif
|
||||
|
||||
#if U_PLATFORM_HAS_WINUWP_API != 0
|
||||
// Helper function to get the ICU Data Directory under the Windows directory location.
|
||||
static BOOL U_CALLCONV getIcuDataDirectoryUnderWindowsDirectory(char* directoryBuffer, UINT bufferLength)
|
||||
{
|
||||
#if defined(ICU_DATA_DIR_WINDOWS)
|
||||
wchar_t windowsPath[MAX_PATH];
|
||||
char windowsPathUtf8[MAX_PATH];
|
||||
|
||||
UINT length = GetSystemWindowsDirectoryW(windowsPath, UPRV_LENGTHOF(windowsPath));
|
||||
if ((length > 0) && (length < (UPRV_LENGTHOF(windowsPath) - 1))) {
|
||||
// Convert UTF-16 to a UTF-8 string.
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
int32_t windowsPathUtf8Len = 0;
|
||||
u_strToUTF8(windowsPathUtf8, static_cast<int32_t>(UPRV_LENGTHOF(windowsPathUtf8)),
|
||||
&windowsPathUtf8Len, reinterpret_cast<const UChar*>(windowsPath), -1, &status);
|
||||
|
||||
if (U_SUCCESS(status) && (status != U_STRING_NOT_TERMINATED_WARNING) &&
|
||||
(windowsPathUtf8Len < (UPRV_LENGTHOF(windowsPathUtf8) - 1))) {
|
||||
// Ensure it always has a separator, so we can append the ICU data path.
|
||||
if (windowsPathUtf8[windowsPathUtf8Len - 1] != U_FILE_SEP_CHAR) {
|
||||
windowsPathUtf8[windowsPathUtf8Len++] = U_FILE_SEP_CHAR;
|
||||
windowsPathUtf8[windowsPathUtf8Len] = '\0';
|
||||
}
|
||||
// Check if the concatenated string will fit.
|
||||
if ((windowsPathUtf8Len + UPRV_LENGTHOF(ICU_DATA_DIR_WINDOWS)) < bufferLength) {
|
||||
uprv_strcpy(directoryBuffer, windowsPathUtf8);
|
||||
uprv_strcat(directoryBuffer, ICU_DATA_DIR_WINDOWS);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void U_CALLCONV dataDirectoryInitFn() {
|
||||
/* If we already have the directory, then return immediately. Will happen if user called
|
||||
* u_setDataDirectory().
|
||||
|
|
@ -1297,7 +1390,9 @@ static void U_CALLCONV dataDirectoryInitFn() {
|
|||
*/
|
||||
# if !defined(ICU_NO_USER_DATA_OVERRIDE) && !UCONFIG_NO_FILE_IO
|
||||
/* First try to get the environment variable */
|
||||
path=getenv("ICU_DATA");
|
||||
# if U_PLATFORM_HAS_WINUWP_API == 0 // Windows UWP does not support getenv
|
||||
path=getenv("ICU_DATA");
|
||||
# endif
|
||||
# endif
|
||||
|
||||
/* ICU_DATA_DIR may be set as a compile option.
|
||||
|
|
@ -1326,9 +1421,21 @@ static void U_CALLCONV dataDirectoryInitFn() {
|
|||
}
|
||||
#endif
|
||||
|
||||
#if U_PLATFORM_HAS_WINUWP_API != 0 && defined(ICU_DATA_DIR_WINDOWS)
|
||||
char datadir_path_buffer[MAX_PATH];
|
||||
if (getIcuDataDirectoryUnderWindowsDirectory(datadir_path_buffer, UPRV_LENGTHOF(datadir_path_buffer))) {
|
||||
path = datadir_path_buffer;
|
||||
}
|
||||
#endif
|
||||
|
||||
if(path==NULL) {
|
||||
/* It looks really bad, set it to something. */
|
||||
#if U_PLATFORM_HAS_WIN32_API
|
||||
// Windows UWP will require icudtl.dat file in same directory as icuuc.dll
|
||||
path = ".\\";
|
||||
#else
|
||||
path = "";
|
||||
#endif
|
||||
}
|
||||
|
||||
u_setDataDirectory(path);
|
||||
|
|
@ -1349,7 +1456,7 @@ static void setTimeZoneFilesDir(const char *path, UErrorCode &status) {
|
|||
gTimeZoneFilesDirectory->append(path, status);
|
||||
#if (U_FILE_SEP_CHAR != U_FILE_ALT_SEP_CHAR)
|
||||
char *p = gTimeZoneFilesDirectory->data();
|
||||
while (p = uprv_strchr(p, U_FILE_ALT_SEP_CHAR)) {
|
||||
while ((p = uprv_strchr(p, U_FILE_ALT_SEP_CHAR)) != NULL) {
|
||||
*p = U_FILE_SEP_CHAR;
|
||||
}
|
||||
#endif
|
||||
|
|
@ -1366,15 +1473,30 @@ static void U_CALLCONV TimeZoneDataDirInitFn(UErrorCode &status) {
|
|||
status = U_MEMORY_ALLOCATION_ERROR;
|
||||
return;
|
||||
}
|
||||
const char *dir = getenv("ICU_TIMEZONE_FILES_DIR");
|
||||
|
||||
const char *dir = "";
|
||||
|
||||
#if U_PLATFORM_HAS_WINUWP_API != 0
|
||||
// The UWP version does not support the environment variable setting, but can possibly pick them up from the Windows directory.
|
||||
char datadir_path_buffer[MAX_PATH];
|
||||
if (getIcuDataDirectoryUnderWindowsDirectory(datadir_path_buffer, UPRV_LENGTHOF(datadir_path_buffer))) {
|
||||
dir = datadir_path_buffer;
|
||||
}
|
||||
#else
|
||||
dir = getenv("ICU_TIMEZONE_FILES_DIR");
|
||||
#endif // U_PLATFORM_HAS_WINUWP_API
|
||||
|
||||
#if defined(U_TIMEZONE_FILES_DIR)
|
||||
if (dir == NULL) {
|
||||
// Build time configuration setting.
|
||||
dir = TO_STRING(U_TIMEZONE_FILES_DIR);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (dir == NULL) {
|
||||
dir = "";
|
||||
}
|
||||
|
||||
setTimeZoneFilesDir(dir, status);
|
||||
}
|
||||
|
||||
|
|
@ -1546,7 +1668,8 @@ The leftmost codepage (.xxx) wins.
|
|||
/* Note that we scan the *uncorrected* ID. */
|
||||
if ((p = uprv_strrchr(posixID, '@')) != NULL) {
|
||||
if (correctedPOSIXLocale == NULL) {
|
||||
correctedPOSIXLocale = static_cast<char *>(uprv_malloc(uprv_strlen(posixID)+1));
|
||||
/* new locale can be 1 char longer than old one if @ -> __ */
|
||||
correctedPOSIXLocale = static_cast<char *>(uprv_malloc(uprv_strlen(posixID)+2));
|
||||
/* Exit on memory allocation error. */
|
||||
if (correctedPOSIXLocale == NULL) {
|
||||
return NULL;
|
||||
|
|
@ -1563,7 +1686,7 @@ The leftmost codepage (.xxx) wins.
|
|||
}
|
||||
|
||||
if (uprv_strchr(correctedPOSIXLocale,'_') == NULL) {
|
||||
uprv_strcat(correctedPOSIXLocale, "__"); /* aa@b -> aa__b */
|
||||
uprv_strcat(correctedPOSIXLocale, "__"); /* aa@b -> aa__b (note this can make the new locale 1 char longer) */
|
||||
}
|
||||
else {
|
||||
uprv_strcat(correctedPOSIXLocale, "_"); /* aa_CC@b -> aa_CC_b */
|
||||
|
|
@ -1603,6 +1726,7 @@ The leftmost codepage (.xxx) wins.
|
|||
|
||||
if (gCorrectedPOSIXLocale == NULL) {
|
||||
gCorrectedPOSIXLocale = correctedPOSIXLocale;
|
||||
gCorrectedPOSIXLocaleHeapAllocated = true;
|
||||
ucln_common_registerCleanup(UCLN_COMMON_PUTIL, putil_cleanup);
|
||||
correctedPOSIXLocale = NULL;
|
||||
}
|
||||
|
|
@ -1616,27 +1740,71 @@ The leftmost codepage (.xxx) wins.
|
|||
#elif U_PLATFORM_USES_ONLY_WIN32_API
|
||||
#define POSIX_LOCALE_CAPACITY 64
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
char *correctedPOSIXLocale = 0;
|
||||
char *correctedPOSIXLocale = nullptr;
|
||||
|
||||
if (gCorrectedPOSIXLocale != NULL) {
|
||||
// If we have already figured this out just use the cached value
|
||||
if (gCorrectedPOSIXLocale != nullptr) {
|
||||
return gCorrectedPOSIXLocale;
|
||||
}
|
||||
|
||||
LCID id = GetThreadLocale();
|
||||
correctedPOSIXLocale = static_cast<char *>(uprv_malloc(POSIX_LOCALE_CAPACITY + 1));
|
||||
if (correctedPOSIXLocale) {
|
||||
int32_t posixLen = uprv_convertToPosix(id, correctedPOSIXLocale, POSIX_LOCALE_CAPACITY, &status);
|
||||
if (U_SUCCESS(status)) {
|
||||
*(correctedPOSIXLocale + posixLen) = 0;
|
||||
gCorrectedPOSIXLocale = correctedPOSIXLocale;
|
||||
ucln_common_registerCleanup(UCLN_COMMON_PUTIL, putil_cleanup);
|
||||
} else {
|
||||
uprv_free(correctedPOSIXLocale);
|
||||
// No cached value, need to determine the current value
|
||||
static WCHAR windowsLocale[LOCALE_NAME_MAX_LENGTH] = {};
|
||||
int length = GetLocaleInfoEx(LOCALE_NAME_USER_DEFAULT, LOCALE_SNAME, windowsLocale, LOCALE_NAME_MAX_LENGTH);
|
||||
|
||||
// Now we should have a Windows locale name that needs converted to the POSIX style.
|
||||
if (length > 0) // If length is 0, then the GetLocaleInfoEx failed.
|
||||
{
|
||||
// First we need to go from UTF-16 to char (and also convert from _ to - while we're at it.)
|
||||
char modifiedWindowsLocale[LOCALE_NAME_MAX_LENGTH] = {};
|
||||
|
||||
int32_t i;
|
||||
for (i = 0; i < UPRV_LENGTHOF(modifiedWindowsLocale); i++)
|
||||
{
|
||||
if (windowsLocale[i] == '_')
|
||||
{
|
||||
modifiedWindowsLocale[i] = '-';
|
||||
}
|
||||
else
|
||||
{
|
||||
modifiedWindowsLocale[i] = static_cast<char>(windowsLocale[i]);
|
||||
}
|
||||
|
||||
if (modifiedWindowsLocale[i] == '\0')
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (i >= UPRV_LENGTHOF(modifiedWindowsLocale))
|
||||
{
|
||||
// Ran out of room, can't really happen, maybe we'll be lucky about a matching
|
||||
// locale when tags are dropped
|
||||
modifiedWindowsLocale[UPRV_LENGTHOF(modifiedWindowsLocale) - 1] = '\0';
|
||||
}
|
||||
|
||||
// Now normalize the resulting name
|
||||
correctedPOSIXLocale = static_cast<char *>(uprv_malloc(POSIX_LOCALE_CAPACITY + 1));
|
||||
/* TODO: Should we just exit on memory allocation failure? */
|
||||
if (correctedPOSIXLocale)
|
||||
{
|
||||
int32_t posixLen = uloc_canonicalize(modifiedWindowsLocale, correctedPOSIXLocale, POSIX_LOCALE_CAPACITY, &status);
|
||||
if (U_SUCCESS(status))
|
||||
{
|
||||
*(correctedPOSIXLocale + posixLen) = 0;
|
||||
gCorrectedPOSIXLocale = correctedPOSIXLocale;
|
||||
gCorrectedPOSIXLocaleHeapAllocated = true;
|
||||
ucln_common_registerCleanup(UCLN_COMMON_PUTIL, putil_cleanup);
|
||||
}
|
||||
else
|
||||
{
|
||||
uprv_free(correctedPOSIXLocale);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (gCorrectedPOSIXLocale == NULL) {
|
||||
return "en_US";
|
||||
// If unable to find a locale we can agree upon, use en-US by default
|
||||
if (gCorrectedPOSIXLocale == nullptr) {
|
||||
gCorrectedPOSIXLocale = "en_US";
|
||||
}
|
||||
return gCorrectedPOSIXLocale;
|
||||
|
||||
|
|
@ -1923,8 +2091,34 @@ int_getDefaultCodepage()
|
|||
|
||||
#elif U_PLATFORM_USES_ONLY_WIN32_API
|
||||
static char codepage[64];
|
||||
sprintf(codepage, "windows-%d", GetACP());
|
||||
return codepage;
|
||||
DWORD codepageNumber = 0;
|
||||
|
||||
#if U_PLATFORM_HAS_WINUWP_API > 0
|
||||
// UWP doesn't have a direct API to get the default ACP as Microsoft would rather
|
||||
// have folks use Unicode than a "system" code page, however this is the same
|
||||
// codepage as the system default locale codepage. (FWIW, the system locale is
|
||||
// ONLY used for codepage, it should never be used for anything else)
|
||||
GetLocaleInfoEx(LOCALE_NAME_SYSTEM_DEFAULT, LOCALE_IDEFAULTANSICODEPAGE | LOCALE_RETURN_NUMBER,
|
||||
(LPWSTR)&codepageNumber, sizeof(codepageNumber) / sizeof(WCHAR));
|
||||
#else
|
||||
// Win32 apps can call GetACP
|
||||
codepageNumber = GetACP();
|
||||
#endif
|
||||
// Special case for UTF-8
|
||||
if (codepageNumber == 65001)
|
||||
{
|
||||
return "UTF-8";
|
||||
}
|
||||
// Windows codepages can look like windows-1252, so format the found number
|
||||
// the numbers are eclectic, however all valid system code pages, besides UTF-8
|
||||
// are between 3 and 19999
|
||||
if (codepageNumber > 0 && codepageNumber < 20000)
|
||||
{
|
||||
sprintf(codepage, "windows-%ld", codepageNumber);
|
||||
return codepage;
|
||||
}
|
||||
// If the codepage number call failed then return UTF-8
|
||||
return "UTF-8";
|
||||
|
||||
#elif U_POSIX_LOCALE
|
||||
static char codesetName[100];
|
||||
|
|
@ -2108,19 +2302,16 @@ u_getVersion(UVersionInfo versionArray) {
|
|||
* icucfg.h dependent code
|
||||
*/
|
||||
|
||||
#if U_ENABLE_DYLOAD
|
||||
|
||||
#if HAVE_DLOPEN && !U_PLATFORM_USES_ONLY_WIN32_API
|
||||
#if U_ENABLE_DYLOAD && HAVE_DLOPEN && !U_PLATFORM_USES_ONLY_WIN32_API
|
||||
|
||||
#if HAVE_DLFCN_H
|
||||
|
||||
#ifdef __MVS__
|
||||
#ifndef __SUSV3
|
||||
#define __SUSV3 1
|
||||
#endif
|
||||
#endif
|
||||
#include <dlfcn.h>
|
||||
#endif
|
||||
#endif /* HAVE_DLFCN_H */
|
||||
|
||||
U_INTERNAL void * U_EXPORT2
|
||||
uprv_dl_open(const char *libName, UErrorCode *status) {
|
||||
|
|
@ -2160,38 +2351,10 @@ uprv_dlsym_func(void *lib, const char* sym, UErrorCode *status) {
|
|||
return uret.fp;
|
||||
}
|
||||
|
||||
#else
|
||||
#elif U_ENABLE_DYLOAD && U_PLATFORM_USES_ONLY_WIN32_API && !U_PLATFORM_HAS_WINUWP_API
|
||||
|
||||
/* null (nonexistent) implementation. */
|
||||
|
||||
U_INTERNAL void * U_EXPORT2
|
||||
uprv_dl_open(const char *libName, UErrorCode *status) {
|
||||
if(U_FAILURE(*status)) return NULL;
|
||||
*status = U_UNSUPPORTED_ERROR;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
U_INTERNAL void U_EXPORT2
|
||||
uprv_dl_close(void *lib, UErrorCode *status) {
|
||||
if(U_FAILURE(*status)) return;
|
||||
*status = U_UNSUPPORTED_ERROR;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
U_INTERNAL UVoidFunction* U_EXPORT2
|
||||
uprv_dlsym_func(void *lib, const char* sym, UErrorCode *status) {
|
||||
if(U_SUCCESS(*status)) {
|
||||
*status = U_UNSUPPORTED_ERROR;
|
||||
}
|
||||
return (UVoidFunction*)NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
#elif U_PLATFORM_USES_ONLY_WIN32_API
|
||||
/* Windows API implementation. */
|
||||
// Note: UWP does not expose/allow these APIs, so the UWP version gets the null implementation. */
|
||||
|
||||
U_INTERNAL void * U_EXPORT2
|
||||
uprv_dl_open(const char *libName, UErrorCode *status) {
|
||||
|
|
@ -2218,7 +2381,6 @@ uprv_dl_close(void *lib, UErrorCode *status) {
|
|||
return;
|
||||
}
|
||||
|
||||
|
||||
U_INTERNAL UVoidFunction* U_EXPORT2
|
||||
uprv_dlsym_func(void *lib, const char* sym, UErrorCode *status) {
|
||||
HMODULE handle = (HMODULE)lib;
|
||||
|
|
@ -2240,10 +2402,9 @@ uprv_dlsym_func(void *lib, const char* sym, UErrorCode *status) {
|
|||
return addr;
|
||||
}
|
||||
|
||||
|
||||
#else
|
||||
|
||||
/* No dynamic loading set. */
|
||||
/* No dynamic loading, null (nonexistent) implementation. */
|
||||
|
||||
U_INTERNAL void * U_EXPORT2
|
||||
uprv_dl_open(const char *libName, UErrorCode *status) {
|
||||
|
|
@ -2261,7 +2422,6 @@ uprv_dl_close(void *lib, UErrorCode *status) {
|
|||
return;
|
||||
}
|
||||
|
||||
|
||||
U_INTERNAL UVoidFunction* U_EXPORT2
|
||||
uprv_dlsym_func(void *lib, const char* sym, UErrorCode *status) {
|
||||
(void)lib;
|
||||
|
|
@ -2272,7 +2432,7 @@ uprv_dlsym_func(void *lib, const char* sym, UErrorCode *status) {
|
|||
return (UVoidFunction*)NULL;
|
||||
}
|
||||
|
||||
#endif /* U_ENABLE_DYLOAD */
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Hey, Emacs, please set the following:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue