#include "uposixdefs.h"
#include "unicode/platform.h"
#include <time.h>
#if !U_PLATFORM_USES_ONLY_WIN32_API
#include <sys/time.h>
#endif
#include "unicode/putil.h"
#include "unicode/ustring.h"
#include "putilimp.h"
#include "uassert.h"
#include "umutex.h"
#include "cmemory.h"
#include "cstring.h"
#include "locmap.h"
#include "ucln_cmn.h"
#include "charstr.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <locale.h>
#include <float.h>
#ifndef U_COMMON_IMPLEMENTATION
#error U_COMMON_IMPLEMENTATION not set - must be set for all ICU source files in common/ - see https:
#endif
#if U_PLATFORM_USES_ONLY_WIN32_API
#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"
#elif U_PLATFORM == U_PF_OS400
# include <float.h>
# include <qusec.h>
# include <qusrjobi.h>
# include <qliept.h>
# include <mih/testptr.h>
#elif U_PLATFORM == U_PF_OS390
# include "unicode/ucnv.h"
#elif U_PLATFORM_IS_DARWIN_BASED || U_PLATFORM_IS_LINUX_BASED || U_PLATFORM == U_PF_BSD || U_PLATFORM == U_PF_SOLARIS
# include <limits.h>
# include <unistd.h>
# if U_PLATFORM == U_PF_SOLARIS
# ifndef _XPG4_2
#define _XPG4_2
# endif
# elif U_PLATFORM == U_PF_ANDROID
# include <sys/system_properties.h>
# include <dlfcn.h>
# endif
#elif U_PLATFORM == U_PF_QNX
# include <sys/neutrino.h>
#endif
#if U_HAVE_NL_LANGINFO_CODESET
#include <langinfo.h>
#endif
#if U_PLATFORM_IMPLEMENTS_POSIX
# if U_PLATFORM == U_PF_OS400
#define HAVE_DLFCN_H …
#define HAVE_DLOPEN …
# else
# ifndef HAVE_DLFCN_H
#define HAVE_DLFCN_H …
# endif
# ifndef HAVE_DLOPEN
#define HAVE_DLOPEN …
# endif
# endif
# ifndef HAVE_GETTIMEOFDAY
#define HAVE_GETTIMEOFDAY …
# endif
#else
#define HAVE_DLFCN_H …
#define HAVE_DLOPEN …
#define HAVE_GETTIMEOFDAY …
#endif
U_NAMESPACE_USE
#define DATA_TYPE …
static const char copyright[] = …;
#define SIGN …
BitPatternConversion;
static const BitPatternConversion gNan = …;
static const BitPatternConversion gInf = …;
#if U_PLATFORM_USES_ONLY_WIN32_API || U_PLATFORM == U_PF_OS400
# undef U_POSIX_LOCALE
#else
#define U_POSIX_LOCALE …
#endif
#if !IEEE_754
static char*
u_topNBytesOfDouble(double* d, int n)
{
#if U_IS_BIG_ENDIAN
return (char*)d;
#else
return (char*)(d + 1) - n;
#endif
}
static char*
u_bottomNBytesOfDouble(double* d, int n)
{
#if U_IS_BIG_ENDIAN
return (char*)(d + 1) - n;
#else
return (char*)d;
#endif
}
#endif
#if IEEE_754
static UBool
u_signBit(double d) { … }
#endif
#if defined (U_DEBUG_FAKETIME)
UDate fakeClock_t0 = 0;
UDate fakeClock_dt = 0;
UBool fakeClock_set = false;
static UDate getUTCtime_real() {
struct timeval posixTime;
gettimeofday(&posixTime, nullptr);
return (UDate)(((int64_t)posixTime.tv_sec * U_MILLIS_PER_SECOND) + (posixTime.tv_usec/1000));
}
static UDate getUTCtime_fake() {
static UMutex fakeClockMutex;
umtx_lock(&fakeClockMutex);
if(!fakeClock_set) {
UDate real = getUTCtime_real();
const char *fake_start = getenv("U_FAKETIME_START");
if((fake_start!=nullptr) && (fake_start[0]!=0)) {
sscanf(fake_start,"%lf",&fakeClock_t0);
fakeClock_dt = fakeClock_t0 - real;
fprintf(stderr,"U_DEBUG_FAKETIME was set at compile time, so the ICU clock will start at a preset value\n"
"env variable U_FAKETIME_START=%.0f (%s) for an offset of %.0f ms from the current time %.0f\n",
fakeClock_t0, fake_start, fakeClock_dt, real);
} else {
fakeClock_dt = 0;
fprintf(stderr,"U_DEBUG_FAKETIME was set at compile time, but U_FAKETIME_START was not set.\n"
"Set U_FAKETIME_START to the number of milliseconds since 1/1/1970 to set the ICU clock.\n");
}
fakeClock_set = true;
}
umtx_unlock(&fakeClockMutex);
return getUTCtime_real() + fakeClock_dt;
}
#endif
#if U_PLATFORM_USES_ONLY_WIN32_API
typedef union {
int64_t int64;
FILETIME fileTime;
} FileTimeConversion;
#define EPOCH_BIAS …
#define HECTONANOSECOND_PER_MILLISECOND …
#endif
U_CAPI UDate U_EXPORT2
uprv_getUTCtime()
{ … }
U_CAPI UDate U_EXPORT2
uprv_getRawUTCtime()
{ … }
U_CAPI UBool U_EXPORT2
uprv_isNaN(double number)
{ … }
U_CAPI UBool U_EXPORT2
uprv_isInfinite(double number)
{ … }
U_CAPI UBool U_EXPORT2
uprv_isPositiveInfinity(double number)
{ … }
U_CAPI UBool U_EXPORT2
uprv_isNegativeInfinity(double number)
{ … }
U_CAPI double U_EXPORT2
uprv_getNaN()
{ … }
U_CAPI double U_EXPORT2
uprv_getInfinity()
{ … }
U_CAPI double U_EXPORT2
uprv_floor(double x)
{ … }
U_CAPI double U_EXPORT2
uprv_ceil(double x)
{ … }
U_CAPI double U_EXPORT2
uprv_round(double x)
{ … }
U_CAPI double U_EXPORT2
uprv_fabs(double x)
{ … }
U_CAPI double U_EXPORT2
uprv_modf(double x, double* y)
{ … }
U_CAPI double U_EXPORT2
uprv_fmod(double x, double y)
{ … }
U_CAPI double U_EXPORT2
uprv_pow(double x, double y)
{ … }
U_CAPI double U_EXPORT2
uprv_pow10(int32_t x)
{ … }
U_CAPI double U_EXPORT2
uprv_fmax(double x, double y)
{ … }
U_CAPI double U_EXPORT2
uprv_fmin(double x, double y)
{ … }
U_CAPI UBool U_EXPORT2
uprv_add32_overflow(int32_t a, int32_t b, int32_t* res) { … }
U_CAPI UBool U_EXPORT2
uprv_mul32_overflow(int32_t a, int32_t b, int32_t* res) { … }
U_CAPI double U_EXPORT2
uprv_trunc(double d)
{ … }
U_CAPI double U_EXPORT2
uprv_maxMantissa()
{ … }
U_CAPI double U_EXPORT2
uprv_log(double d)
{ … }
U_CAPI void * U_EXPORT2
uprv_maximumPtr(void * base)
{ … }
U_CAPI void U_EXPORT2
uprv_tzset()
{ … }
U_CAPI int32_t U_EXPORT2
uprv_timezone()
{ … }
#if defined(U_TZNAME) && (U_PLATFORM == U_PF_IRIX || U_PLATFORM_IS_DARWIN_BASED)
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)
#define CHECK_LOCALTIME_LINK …
#if U_PLATFORM_IS_DARWIN_BASED
#include <tzfile.h>
#define TZZONEINFO …
#elif U_PLATFORM == U_PF_SOLARIS
#define TZDEFAULT …
#define TZZONEINFO …
#define TZ_ENV_CHECK …
#else
#define TZDEFAULT …
#define TZZONEINFO …
#endif
#define TZZONEINFOTAIL …
#if U_HAVE_DIRENT_H
#define TZFILE_SKIP …
#define TZFILE_SKIP2 …
#define SEARCH_TZFILE
#include <dirent.h>
#endif
static char gTimeZoneBuffer[PATH_MAX];
static const char *gTimeZoneBufferPtr = nullptr;
#endif
#if !U_PLATFORM_USES_ONLY_WIN32_API
#define isNonDigit(ch) …
#define isDigit(ch) …
static UBool isValidOlsonID(const char *id) { … }
static void skipZoneIDPrefix(const char** id) { … }
#endif
#if defined(U_TZNAME) && !U_PLATFORM_USES_ONLY_WIN32_API
#define CONVERT_HOURS_TO_SECONDS(offset) …
OffsetZoneMapping;
enum { … };
static const struct OffsetZoneMapping OFFSET_ZONE_MAPPINGS[] = …;
static const char* remapShortTimeZone(const char *stdID, const char *dstID, int32_t daylightType, int32_t offset)
{ … }
#endif
#ifdef SEARCH_TZFILE
#define MAX_READ_SIZE …
typedef struct DefaultTZInfo {
char* defaultTZBuffer;
int64_t defaultTZFileSize;
FILE* defaultTZFilePtr;
UBool defaultTZstatus;
int32_t defaultTZPosition;
} DefaultTZInfo;
static UBool compareBinaryFiles(const char* defaultTZFileName, const char* TZFileName, DefaultTZInfo* tzInfo) {
FILE* file;
int64_t sizeFile;
int64_t sizeFileLeft;
int32_t sizeFileRead;
int32_t sizeFileToRead;
char bufferFile[MAX_READ_SIZE];
UBool result = true;
if (tzInfo->defaultTZFilePtr == nullptr) {
tzInfo->defaultTZFilePtr = fopen(defaultTZFileName, "r");
}
file = fopen(TZFileName, "r");
tzInfo->defaultTZPosition = 0;
if (file != nullptr && tzInfo->defaultTZFilePtr != nullptr) {
if (tzInfo->defaultTZFileSize == 0) {
fseek(tzInfo->defaultTZFilePtr, 0, SEEK_END);
tzInfo->defaultTZFileSize = ftell(tzInfo->defaultTZFilePtr);
}
fseek(file, 0, SEEK_END);
sizeFile = ftell(file);
sizeFileLeft = sizeFile;
if (sizeFile != tzInfo->defaultTZFileSize) {
result = false;
} else {
if (tzInfo->defaultTZBuffer == nullptr) {
rewind(tzInfo->defaultTZFilePtr);
tzInfo->defaultTZBuffer = static_cast<char*>(uprv_malloc(sizeof(char) * tzInfo->defaultTZFileSize));
sizeFileRead = fread(tzInfo->defaultTZBuffer, 1, tzInfo->defaultTZFileSize, tzInfo->defaultTZFilePtr);
}
rewind(file);
while(sizeFileLeft > 0) {
uprv_memset(bufferFile, 0, MAX_READ_SIZE);
sizeFileToRead = sizeFileLeft < MAX_READ_SIZE ? sizeFileLeft : MAX_READ_SIZE;
sizeFileRead = fread(bufferFile, 1, sizeFileToRead, file);
if (memcmp(tzInfo->defaultTZBuffer + tzInfo->defaultTZPosition, bufferFile, sizeFileRead) != 0) {
result = false;
break;
}
sizeFileLeft -= sizeFileRead;
tzInfo->defaultTZPosition += sizeFileRead;
}
}
} else {
result = false;
}
if (file != nullptr) {
fclose(file);
}
return result;
}
#define SKIP1 …
#define SKIP2 …
static UBool U_CALLCONV putil_cleanup();
static CharString *gSearchTZFileResult = nullptr;
static char* searchForTZFile(const char* path, DefaultTZInfo* tzInfo) {
DIR* dirp = nullptr;
struct dirent* dirEntry = nullptr;
char* result = nullptr;
UErrorCode status = U_ZERO_ERROR;
CharString curpath(path, -1, status);
if (U_FAILURE(status)) {
goto cleanupAndReturn;
}
dirp = opendir(path);
if (dirp == nullptr) {
goto cleanupAndReturn;
}
if (gSearchTZFileResult == nullptr) {
gSearchTZFileResult = new CharString;
if (gSearchTZFileResult == nullptr) {
goto cleanupAndReturn;
}
ucln_common_registerCleanup(UCLN_COMMON_PUTIL, putil_cleanup);
}
while((dirEntry = readdir(dirp)) != nullptr) {
const char* dirName = dirEntry->d_name;
if (uprv_strcmp(dirName, SKIP1) != 0 && uprv_strcmp(dirName, SKIP2) != 0
&& uprv_strcmp(TZFILE_SKIP, dirName) != 0 && uprv_strcmp(TZFILE_SKIP2, dirName) != 0) {
CharString newpath(curpath, status);
newpath.append(dirName, -1, status);
if (U_FAILURE(status)) {
break;
}
DIR* subDirp = nullptr;
if ((subDirp = opendir(newpath.data())) != nullptr) {
closedir(subDirp);
newpath.append('/', status);
if (U_FAILURE(status)) {
break;
}
result = searchForTZFile(newpath.data(), tzInfo);
if (result != nullptr)
break;
} else {
if(compareBinaryFiles(TZDEFAULT, newpath.data(), tzInfo)) {
int32_t amountToSkip = sizeof(TZZONEINFO) - 1;
if (amountToSkip > newpath.length()) {
amountToSkip = newpath.length();
}
const char* zoneid = newpath.data() + amountToSkip;
skipZoneIDPrefix(&zoneid);
gSearchTZFileResult->clear();
gSearchTZFileResult->append(zoneid, -1, status);
if (U_FAILURE(status)) {
break;
}
result = gSearchTZFileResult->data();
break;
}
}
}
}
cleanupAndReturn:
if (dirp) {
closedir(dirp);
}
return result;
}
#endif
#if U_PLATFORM == U_PF_ANDROID
typedef int(system_property_read_callback)(const prop_info* info,
void (*callback)(void* cookie,
const char* name,
const char* value,
uint32_t serial),
void* cookie);
typedef int(system_property_get)(const char*, char*);
static char gAndroidTimeZone[PROP_VALUE_MAX] = { '\0' };
static void u_property_read(void* cookie, const char* name, const char* value,
uint32_t serial) {
uprv_strcpy((char* )cookie, value);
}
#endif
U_CAPI void U_EXPORT2
uprv_tzname_clear_cache()
{ … }
U_CAPI const char* U_EXPORT2
uprv_tzname(int n)
{ … }
static icu::UInitOnce gDataDirInitOnce { … };
static char *gDataDirectory = …;
struct icu_76_godot::UInitOnce gTimeZoneFilesInitOnce {};
static CharString *gTimeZoneFilesDirectory = …;
#if U_POSIX_LOCALE || U_PLATFORM_USES_ONLY_WIN32_API
static const char *gCorrectedPOSIXLocale = …;
static bool gCorrectedPOSIXLocaleHeapAllocated = …;
#endif
static UBool U_CALLCONV putil_cleanup()
{ … }
U_CAPI void U_EXPORT2
u_setDataDirectory(const char *directory) { … }
U_CAPI UBool U_EXPORT2
uprv_pathIsAbsolute(const char *path)
{ … }
#if U_PLATFORM_IS_DARWIN_BASED && defined(TARGET_OS_SIMULATOR) && TARGET_OS_SIMULATOR
# if !defined(ICU_DATA_DIR_PREFIX_ENV_VAR)
#define ICU_DATA_DIR_PREFIX_ENV_VAR …
# endif
#endif
#if defined(ICU_DATA_DIR_WINDOWS)
static BOOL U_CALLCONV getIcuDataDirectoryUnderWindowsDirectory(char* directoryBuffer, UINT bufferLength)
{
wchar_t windowsPath[MAX_PATH];
char windowsPathUtf8[MAX_PATH];
UINT length = GetSystemWindowsDirectoryW(windowsPath, UPRV_LENGTHOF(windowsPath));
if ((length > 0) && (length < (UPRV_LENGTHOF(windowsPath) - 1))) {
UErrorCode status = U_ZERO_ERROR;
int32_t windowsPathUtf8Len = 0;
u_strToUTF8(windowsPathUtf8, static_cast<int32_t>(UPRV_LENGTHOF(windowsPathUtf8)),
&windowsPathUtf8Len, reinterpret_cast<const char16_t*>(windowsPath), -1, &status);
if (U_SUCCESS(status) && (status != U_STRING_NOT_TERMINATED_WARNING) &&
(windowsPathUtf8Len < (UPRV_LENGTHOF(windowsPathUtf8) - 1))) {
if (windowsPathUtf8[windowsPathUtf8Len - 1] != U_FILE_SEP_CHAR) {
windowsPathUtf8[windowsPathUtf8Len++] = U_FILE_SEP_CHAR;
windowsPathUtf8[windowsPathUtf8Len] = '\0';
}
if ((windowsPathUtf8Len + UPRV_LENGTHOF(ICU_DATA_DIR_WINDOWS)) < bufferLength) {
uprv_strcpy(directoryBuffer, windowsPathUtf8);
uprv_strcat(directoryBuffer, ICU_DATA_DIR_WINDOWS);
return true;
}
}
}
return false;
}
#endif
static void U_CALLCONV dataDirectoryInitFn() { … }
U_CAPI const char * U_EXPORT2
u_getDataDirectory() { … }
static void setTimeZoneFilesDir(const char *path, UErrorCode &status) { … }
#define TO_STRING(x) …
#define TO_STRING_2(x) …
static void U_CALLCONV TimeZoneDataDirInitFn(UErrorCode &status) { … }
U_CAPI const char * U_EXPORT2
u_getTimeZoneFilesDirectory(UErrorCode *status) { … }
U_CAPI void U_EXPORT2
u_setTimeZoneFilesDirectory(const char *path, UErrorCode *status) { … }
#if U_POSIX_LOCALE
static const char *uprv_getPOSIXIDForCategory(int category)
{ … }
static const char *uprv_getPOSIXIDForDefaultLocale()
{ … }
#if !U_CHARSET_IS_UTF8
static const char *uprv_getPOSIXIDForDefaultCodepage()
{
static const char* posixID = nullptr;
if (posixID == 0) {
posixID = uprv_getPOSIXIDForCategory(LC_CTYPE);
}
return posixID;
}
#endif
#endif
U_CAPI const char* U_EXPORT2
uprv_getDefaultLocaleID()
{ … }
#if !U_CHARSET_IS_UTF8
#if U_POSIX_LOCALE
static const char*
remapPlatformDependentCodepage(const char *locale, const char *name) {
if (locale != nullptr && *locale == 0) {
locale = nullptr;
}
if (name == nullptr) {
return nullptr;
}
#if U_PLATFORM == U_PF_AIX
if (uprv_strcmp(name, "IBM-943") == 0) {
name = "Shift-JIS";
}
else if (uprv_strcmp(name, "IBM-1252") == 0) {
name = "IBM-5348";
}
#elif U_PLATFORM == U_PF_SOLARIS
if (locale != nullptr && uprv_strcmp(name, "EUC") == 0) {
if (uprv_strcmp(locale, "zh_CN") == 0) {
name = "EUC-CN";
}
else if (uprv_strcmp(locale, "zh_TW") == 0) {
name = "EUC-TW";
}
else if (uprv_strcmp(locale, "ko_KR") == 0) {
name = "EUC-KR";
}
}
else if (uprv_strcmp(name, "eucJP") == 0) {
name = "eucjis";
}
else if (uprv_strcmp(name, "646") == 0) {
name = "ISO-8859-1";
}
#elif U_PLATFORM_IS_DARWIN_BASED
if (locale == nullptr && *name == 0) {
name = "UTF-8";
}
else if (uprv_strcmp(name, "CP949") == 0) {
name = "EUC-KR";
}
else if (locale != nullptr && uprv_strcmp(locale, "en_US_POSIX") != 0 && uprv_strcmp(name, "US-ASCII") == 0) {
name = "UTF-8";
}
#elif U_PLATFORM == U_PF_BSD
if (uprv_strcmp(name, "CP949") == 0) {
name = "EUC-KR";
}
#elif U_PLATFORM == U_PF_HPUX
if (locale != nullptr && uprv_strcmp(locale, "zh_HK") == 0 && uprv_strcmp(name, "big5") == 0) {
name = "hkbig5";
}
else if (uprv_strcmp(name, "eucJP") == 0) {
name = "eucjis";
}
#elif U_PLATFORM == U_PF_LINUX
if (locale != nullptr && uprv_strcmp(name, "euc") == 0) {
if (uprv_strcmp(locale, "korean") == 0) {
name = "EUC-KR";
}
else if (uprv_strcmp(locale, "japanese") == 0) {
name = "eucjis";
}
}
else if (uprv_strcmp(name, "eucjp") == 0) {
name = "eucjis";
}
else if (locale != nullptr && uprv_strcmp(locale, "en_US_POSIX") != 0 &&
(uprv_strcmp(name, "ANSI_X3.4-1968") == 0 || uprv_strcmp(name, "US-ASCII") == 0)) {
name = "UTF-8";
}
#endif
if (*name == 0) {
name = nullptr;
}
return name;
}
static const char*
getCodepageFromPOSIXID(const char *localeName, char * buffer, int32_t buffCapacity)
{
char localeBuf[100];
const char *name = nullptr;
char *variant = nullptr;
if (localeName != nullptr && (name = (uprv_strchr(localeName, '.'))) != nullptr) {
size_t localeCapacity = uprv_min(sizeof(localeBuf), (name-localeName)+1);
uprv_strncpy(localeBuf, localeName, localeCapacity);
localeBuf[localeCapacity-1] = 0;
name = uprv_strncpy(buffer, name+1, buffCapacity);
buffer[buffCapacity-1] = 0;
if ((variant = const_cast<char *>(uprv_strchr(name, '@'))) != nullptr) {
*variant = 0;
}
name = remapPlatformDependentCodepage(localeBuf, name);
}
return name;
}
#endif
static const char*
int_getDefaultCodepage()
{
#if U_PLATFORM == U_PF_OS400
uint32_t ccsid = 37;
static char codepage[64];
Qwc_JOBI0400_t jobinfo;
Qus_EC_t error = { sizeof(Qus_EC_t) };
EPT_CALL(QUSRJOBI)(&jobinfo, sizeof(jobinfo), "JOBI0400",
"* ", " ", &error);
if (error.Bytes_Available == 0) {
if (jobinfo.Coded_Char_Set_ID != 0xFFFF) {
ccsid = (uint32_t)jobinfo.Coded_Char_Set_ID;
}
else if (jobinfo.Default_Coded_Char_Set_Id != 0xFFFF) {
ccsid = (uint32_t)jobinfo.Default_Coded_Char_Set_Id;
}
}
snprintf(codepage, sizeof(codepage), "ibm-%d", ccsid);
return codepage;
#elif U_PLATFORM == U_PF_OS390
static char codepage[64];
strncpy(codepage, nl_langinfo(CODESET),63-strlen(UCNV_SWAP_LFNL_OPTION_STRING));
strcat(codepage,UCNV_SWAP_LFNL_OPTION_STRING);
codepage[63] = 0;
return codepage;
#elif U_PLATFORM_USES_ONLY_WIN32_API
static char codepage[64];
DWORD codepageNumber = 0;
#if U_PLATFORM_HAS_WINUWP_API == 1
GetLocaleInfoEx(LOCALE_NAME_SYSTEM_DEFAULT, LOCALE_IDEFAULTANSICODEPAGE | LOCALE_RETURN_NUMBER,
(LPWSTR)&codepageNumber, sizeof(codepageNumber) / sizeof(WCHAR));
#else
codepageNumber = GetACP();
#endif
if (codepageNumber == 65001)
{
return "UTF-8";
}
if (codepageNumber > 0 && codepageNumber < 20000)
{
snprintf(codepage, sizeof(codepage), "windows-%ld", codepageNumber);
return codepage;
}
return "UTF-8";
#elif U_POSIX_LOCALE
static char codesetName[100];
const char *localeName = nullptr;
const char *name = nullptr;
localeName = uprv_getPOSIXIDForDefaultCodepage();
uprv_memset(codesetName, 0, sizeof(codesetName));
#if (U_HAVE_NL_LANGINFO_CODESET && U_PLATFORM != U_PF_SOLARIS)
{
const char *codeset = nl_langinfo(U_NL_LANGINFO_CODESET);
#if U_PLATFORM_IS_DARWIN_BASED || U_PLATFORM_IS_LINUX_BASED
if (uprv_strcmp(localeName, "en_US_POSIX") != 0) {
codeset = remapPlatformDependentCodepage(localeName, codeset);
} else
#endif
{
codeset = remapPlatformDependentCodepage(nullptr, codeset);
}
if (codeset != nullptr) {
uprv_strncpy(codesetName, codeset, sizeof(codesetName));
codesetName[sizeof(codesetName)-1] = 0;
return codesetName;
}
}
#endif
uprv_memset(codesetName, 0, sizeof(codesetName));
name = getCodepageFromPOSIXID(localeName, codesetName, sizeof(codesetName));
if (name) {
return name;
}
if (*codesetName == 0)
{
(void)uprv_strcpy(codesetName, "US-ASCII");
}
return codesetName;
#else
return "US-ASCII";
#endif
}
U_CAPI const char* U_EXPORT2
uprv_getDefaultCodepage()
{
static char const *name = nullptr;
umtx_lock(nullptr);
if (name == nullptr) {
name = int_getDefaultCodepage();
}
umtx_unlock(nullptr);
return name;
}
#endif
U_CAPI void U_EXPORT2
u_versionFromString(UVersionInfo versionArray, const char *versionString) { … }
U_CAPI void U_EXPORT2
u_versionFromUString(UVersionInfo versionArray, const char16_t *versionString) { … }
U_CAPI void U_EXPORT2
u_versionToString(const UVersionInfo versionArray, char *versionString) { … }
U_CAPI void U_EXPORT2
u_getVersion(UVersionInfo versionArray) { … }
#if U_ENABLE_DYLOAD && HAVE_DLOPEN && !U_PLATFORM_USES_ONLY_WIN32_API
#if HAVE_DLFCN_H
#ifdef __MVS__
#ifndef __SUSV3
#define __SUSV3 …
#endif
#endif
#include <dlfcn.h>
#endif
U_CAPI void * U_EXPORT2
uprv_dl_open(const char *libName, UErrorCode *status) {
void *ret = nullptr;
if(U_FAILURE(*status)) return ret;
ret = dlopen(libName, RTLD_NOW|RTLD_GLOBAL);
if(ret==nullptr) {
#ifdef U_TRACE_DYLOAD
printf("dlerror on dlopen(%s): %s\n", libName, dlerror());
#endif
*status = U_MISSING_RESOURCE_ERROR;
}
return ret;
}
U_CAPI void U_EXPORT2
uprv_dl_close(void *lib, UErrorCode *status) {
if(U_FAILURE(*status)) return;
dlclose(lib);
}
U_CAPI UVoidFunction* U_EXPORT2
uprv_dlsym_func(void *lib, const char* sym, UErrorCode *status) {
union {
UVoidFunction *fp;
void *vp;
} uret;
uret.fp = nullptr;
if(U_FAILURE(*status)) return uret.fp;
uret.vp = dlsym(lib, sym);
if(uret.vp == nullptr) {
#ifdef U_TRACE_DYLOAD
printf("dlerror on dlsym(%p,%s): %s\n", lib,sym, dlerror());
#endif
*status = U_MISSING_RESOURCE_ERROR;
}
return uret.fp;
}
#elif U_ENABLE_DYLOAD && U_PLATFORM_USES_ONLY_WIN32_API && !U_PLATFORM_HAS_WINUWP_API
U_CAPI void * U_EXPORT2
uprv_dl_open(const char *libName, UErrorCode *status) {
HMODULE lib = nullptr;
if(U_FAILURE(*status)) return nullptr;
lib = LoadLibraryA(libName);
if(lib==nullptr) {
*status = U_MISSING_RESOURCE_ERROR;
}
return (void*)lib;
}
U_CAPI void U_EXPORT2
uprv_dl_close(void *lib, UErrorCode *status) {
HMODULE handle = (HMODULE)lib;
if(U_FAILURE(*status)) return;
FreeLibrary(handle);
return;
}
U_CAPI UVoidFunction* U_EXPORT2
uprv_dlsym_func(void *lib, const char* sym, UErrorCode *status) {
HMODULE handle = (HMODULE)lib;
UVoidFunction* addr = nullptr;
if(U_FAILURE(*status) || lib==nullptr) return nullptr;
addr = (UVoidFunction*)GetProcAddress(handle, sym);
if(addr==nullptr) {
DWORD lastError = GetLastError();
if(lastError == ERROR_PROC_NOT_FOUND) {
*status = U_MISSING_RESOURCE_ERROR;
} else {
*status = U_UNSUPPORTED_ERROR;
}
}
return addr;
}
#else
U_CAPI void * U_EXPORT2
uprv_dl_open(const char *libName, UErrorCode *status) { … }
U_CAPI void U_EXPORT2
uprv_dl_close(void *lib, UErrorCode *status) { … }
U_CAPI UVoidFunction* U_EXPORT2
uprv_dlsym_func(void *lib, const char* sym, UErrorCode *status) { … }
#endif