/*
******************************************************************************
*
-* Copyright (C) 1997-2013, International Business Machines
+* Copyright (C) 1997-2016, International Business Machines
* Corporation and others. All Rights Reserved.
*
******************************************************************************
#include "cstring.h"
#include "locmap.h"
#include "ucln_cmn.h"
+#include "charstr.h"
/* Include standard headers. */
#include <stdio.h>
# include <qusrjobi.h>
# include <qliept.h> /* EPT_CALL macro - this include must be after all other "QSYSINCs" */
# include <mih/testptr.h> /* For uprv_maximumPtr */
-#elif U_PLATFORM == U_PF_CLASSIC_MACOS
-# include <Files.h>
-# include <IntlResources.h>
-# include <Script.h>
-# include <Folders.h>
-# include <MacTypes.h>
-# include <TextUtils.h>
-# define ICU_NO_USER_DATA_OVERRIDE 1
#elif U_PLATFORM == U_PF_OS390
# include "unicode/ucnv.h" /* Needed for UCNV_SWAP_LFNL_OPTION_STRING */
#elif U_PLATFORM_IS_DARWIN_BASED || U_PLATFORM_IS_LINUX_BASED || U_PLATFORM == U_PF_BSD || U_PLATFORM == U_PF_SOLARIS
# define HAVE_GETTIMEOFDAY 0
#endif
-#define LENGTHOF(array) (int32_t)(sizeof(array)/sizeof((array)[0]))
+U_NAMESPACE_USE
/* Define the extension for data files, again... */
#define DATA_TYPE "dat"
functions).
---------------------------------------------------------------------------*/
-#if U_PLATFORM_USES_ONLY_WIN32_API || U_PLATFORM == U_PF_CLASSIC_MACOS || U_PLATFORM == U_PF_OS400
+#if U_PLATFORM_USES_ONLY_WIN32_API || U_PLATFORM == U_PF_OS400
# undef U_POSIX_LOCALE
#else
# define U_POSIX_LOCALE 1
U_CAPI UDate U_EXPORT2
uprv_getRawUTCtime()
{
-#if U_PLATFORM == U_PF_CLASSIC_MACOS
- time_t t, t1, t2;
- struct tm tmrec;
-
- uprv_memset( &tmrec, 0, sizeof(tmrec) );
- tmrec.tm_year = 70;
- tmrec.tm_mon = 0;
- tmrec.tm_mday = 1;
- t1 = mktime(&tmrec); /* seconds of 1/1/1970*/
-
- time(&t);
- uprv_memcpy( &tmrec, gmtime(&t), sizeof(tmrec) );
- t2 = mktime(&tmrec); /* seconds of current GMT*/
- return (UDate)(t2 - t1) * U_MILLIS_PER_SECOND; /* GMT (or UTC) in seconds since 1970*/
-#elif U_PLATFORM_USES_ONLY_WIN32_API
+#if U_PLATFORM_USES_ONLY_WIN32_API
FileTimeConversion winTime;
GetSystemTimeAsFileTime(&winTime.fileTime);
#else
time_t t, t1, t2;
struct tm tmrec;
- UBool dst_checked;
int32_t tdiff = 0;
time(&t);
uprv_memcpy( &tmrec, localtime(&t), sizeof(tmrec) );
- dst_checked = (tmrec.tm_isdst != 0); /* daylight savings time is checked*/
+#if U_PLATFORM != U_PF_IPHONE
+ UBool dst_checked = (tmrec.tm_isdst != 0); /* daylight savings time is checked*/
+#endif
t1 = mktime(&tmrec); /* local time in seconds*/
uprv_memcpy( &tmrec, gmtime(&t), sizeof(tmrec) );
t2 = mktime(&tmrec); /* GMT (or UTC) in seconds*/
tdiff = t2 - t1;
+
+#if U_PLATFORM != U_PF_IPHONE
/* imitate NT behaviour, which returns same timezone offset to GMT for
winter and summer.
This does not work on all platforms. For instance, on glibc on Linux
and on Mac OS 10.5, tdiff calculated above remains the same
- regardless of whether DST is in effect or not. However, U_TIMEZONE
- is defined on those platforms and this code is not reached so that
- we can leave this alone. If there's a platform behaving
- like glibc that uses this code, we need to add platform-dependent
- preprocessor here. */
+ regardless of whether DST is in effect or not. iOS is another
+ platform where this does not work. Linux + glibc and Mac OS 10.5
+ have U_TIMEZONE defined so that this code is not reached.
+ */
if (dst_checked)
tdiff += 3600;
+#endif
return tdiff;
#endif
}
extern U_IMPORT char *U_TZNAME[];
#endif
-#if !UCONFIG_NO_FILE_IO && (U_PLATFORM_IS_DARWIN_BASED || U_PLATFORM_IS_LINUX_BASED || U_PLATFORM == U_PF_BSD || U_PLATFORM == U_PF_SOLARIS)
+#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. */
#define CHECK_LOCALTIME_LINK 1
#if U_PLATFORM_IS_DARWIN_BASED
#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"
#ifdef DEBUG_TZNAME
fprintf(stderr, "TZ=%s std=%s dst=%s daylight=%d offset=%d\n", getenv("TZ"), stdID, dstID, daylightType, offset);
#endif
- for (idx = 0; idx < LENGTHOF(OFFSET_ZONE_MAPPINGS); idx++)
+ for (idx = 0; idx < UPRV_LENGTHOF(OFFSET_ZONE_MAPPINGS); idx++)
{
if (offset == OFFSET_ZONE_MAPPINGS[idx].offsetSeconds
&& daylightType == OFFSET_ZONE_MAPPINGS[idx].daylightType
&& uprv_strcmp(tzid, TZ_ENV_CHECK) != 0
#endif
) {
+ /* The colon forces tzset() to treat the remainder as zoneinfo path */
+ if (tzid[0] == ':') {
+ tzid++;
+ }
/* This might be a good Olson ID. */
skipZoneIDPrefix(&tzid);
return tzid;
{
return (gTimeZoneBufferPtr = gTimeZoneBuffer + tzZoneInfoLen);
}
+#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));
/* Get and set the ICU data directory --------------------------------------- */
+static icu::UInitOnce gDataDirInitOnce = U_INITONCE_INITIALIZER;
static char *gDataDirectory = NULL;
-#if U_POSIX_LOCALE
+
+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 */
#endif
uprv_free(gDataDirectory);
}
gDataDirectory = NULL;
-#if U_POSIX_LOCALE
+ gDataDirInitOnce.reset();
+
+ delete gTimeZoneFilesDirectory;
+ gTimeZoneFilesDirectory = NULL;
+ gTimeZoneFilesInitOnce.reset();
+
+#if U_POSIX_LOCALE || U_PLATFORM_USES_ONLY_WIN32_API
if (gCorrectedPOSIXLocale) {
uprv_free(gCorrectedPOSIXLocale);
gCorrectedPOSIXLocale = NULL;
/*
* Set the data directory.
* Make a copy of the passed string, and set the global data dir to point to it.
- * TODO: see bug #2849, regarding thread safety.
*/
U_CAPI void U_EXPORT2
u_setDataDirectory(const char *directory) {
#endif
}
- umtx_lock(NULL);
if (gDataDirectory && *gDataDirectory) {
uprv_free(gDataDirectory);
}
gDataDirectory = newDataDir;
ucln_common_registerCleanup(UCLN_COMMON_PUTIL, putil_cleanup);
- umtx_unlock(NULL);
}
U_CAPI UBool U_EXPORT2
# endif
#endif
-U_CAPI const char * U_EXPORT2
-u_getDataDirectory(void) {
+static void U_CALLCONV dataDirectoryInitFn() {
+ /* If we already have the directory, then return immediately. Will happen if user called
+ * u_setDataDirectory().
+ */
+ if (gDataDirectory) {
+ return;
+ }
+
const char *path = NULL;
#if defined(ICU_DATA_DIR_PREFIX_ENV_VAR)
char datadir_path_buffer[PATH_MAX];
#endif
- /* if we have the directory, then return it immediately */
- UMTX_CHECK(NULL, gDataDirectory, path);
-
- if(path) {
- return path;
- }
-
/*
When ICU_NO_USER_DATA_OVERRIDE is defined, users aren't allowed to
override ICU's data with the ICU_DATA environment variable. This prevents
}
u_setDataDirectory(path);
+ return;
+}
+
+U_CAPI const char * U_EXPORT2
+u_getDataDirectory(void) {
+ umtx_initOnce(gDataDirInitOnce, &dataDirectoryInitFn);
return gDataDirectory;
}
+static void setTimeZoneFilesDir(const char *path, UErrorCode &status) {
+ if (U_FAILURE(status)) {
+ return;
+ }
+ gTimeZoneFilesDirectory->clear();
+ 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)) {
+ *p = U_FILE_SEP_CHAR;
+ }
+#endif
+}
+
+#if U_PLATFORM_IMPLEMENTS_POSIX
+#include <sys/stat.h>
+#if defined(U_TIMEZONE_FILES_DIR)
+const char tzdirbuf[] = U_TIMEZONE_FILES_DIR;
+enum { kTzfilenamebufLen = UPRV_LENGTHOF(tzdirbuf) + 24 }; // extra room for "/icutz44l.dat" or "/zoneinfo64.res"
+#endif
+#endif
+#define TO_STRING(x) TO_STRING_2(x)
+#define TO_STRING_2(x) #x
+static void U_CALLCONV TimeZoneDataDirInitFn(UErrorCode &status) {
+ U_ASSERT(gTimeZoneFilesDirectory == NULL);
+ ucln_common_registerCleanup(UCLN_COMMON_PUTIL, putil_cleanup);
+ gTimeZoneFilesDirectory = new CharString();
+ if (gTimeZoneFilesDirectory == NULL) {
+ status = U_MEMORY_ALLOCATION_ERROR;
+ return;
+ }
+ const char *dir = getenv("ICU_TIMEZONE_FILES_DIR");
+ UBool usingUTzFilesDir = FALSE;
+#if defined(U_TIMEZONE_FILES_DIR)
+ if (dir == NULL) {
+ // dir = TO_STRING(U_TIMEZONE_FILES_DIR);
+ // Not sure why the above was done for this path only;
+ // it preserves unwanted quotes.
+ dir = tzdirbuf;
+ usingUTzFilesDir = TRUE;
+ }
+#endif
+#if U_PLATFORM_IMPLEMENTS_POSIX
+ if (dir != NULL) {
+ struct stat buf;
+ if (stat(dir, &buf) != 0) {
+ dir = NULL;
+ }
+#if defined(U_TIMEZONE_FILES_DIR)
+ else if (usingUTzFilesDir) {
+ char tzfilenamebuf[kTzfilenamebufLen];
+ uprv_strcpy(tzfilenamebuf, tzdirbuf);
+ uprv_strcat(tzfilenamebuf, U_FILE_SEP_STRING);
+#if defined(U_TIMEZONE_PACKAGE)
+ uprv_strcat(tzfilenamebuf, U_TIMEZONE_PACKAGE);
+ uprv_strcat(tzfilenamebuf, ".dat");
+#else
+ uprv_strcat(tzfilenamebuf, "zoneinfo64.res");
+#endif
+ if (stat(tzfilenamebuf, &buf) != 0) {
+ dir = NULL;
+ }
+ }
+#endif /* defined(U_TIMEZONE_FILES_DIR) */
+ }
+#endif /* U_PLATFORM_IMPLEMENTS_POSIX */
+ if (dir == NULL) {
+ dir = "";
+ }
+ setTimeZoneFilesDir(dir, status);
+}
-/* Macintosh-specific locale information ------------------------------------ */
-#if U_PLATFORM == U_PF_CLASSIC_MACOS
-
-typedef struct {
- int32_t script;
- int32_t region;
- int32_t lang;
- int32_t date_region;
- const char* posixID;
-} mac_lc_rec;
-
-/* Todo: This will be updated with a newer version from www.unicode.org web
- page when it's available.*/
-#define MAC_LC_MAGIC_NUMBER -5
-#define MAC_LC_INIT_NUMBER -9
-
-static const mac_lc_rec mac_lc_recs[] = {
- MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, 0, "en_US",
- /* United States*/
- MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, 1, "fr_FR",
- /* France*/
- MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, 2, "en_GB",
- /* Great Britain*/
- MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, 3, "de_DE",
- /* Germany*/
- MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, 4, "it_IT",
- /* Italy*/
- MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, 5, "nl_NL",
- /* Metherlands*/
- MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, 6, "fr_BE",
- /* French for Belgium or Lxembourg*/
- MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, 7, "sv_SE",
- /* Sweden*/
- MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, 9, "da_DK",
- /* Denmark*/
- MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, 10, "pt_PT",
- /* Portugal*/
- MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, 11, "fr_CA",
- /* French Canada*/
- MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, 13, "is_IS",
- /* Israel*/
- MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, 14, "ja_JP",
- /* Japan*/
- MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, 15, "en_AU",
- /* Australia*/
- MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, 16, "ar_AE",
- /* the Arabic world (?)*/
- MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, 17, "fi_FI",
- /* Finland*/
- MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, 18, "fr_CH",
- /* French for Switzerland*/
- MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, 19, "de_CH",
- /* German for Switzerland*/
- MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, 20, "el_GR",
- /* Greece*/
- MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, 21, "is_IS",
- /* Iceland ===*/
- /*MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, 22, "",*/
- /* Malta ===*/
- /*MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, 23, "",*/
- /* Cyprus ===*/
- MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, 24, "tr_TR",
- /* Turkey ===*/
- MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, 25, "sh_YU",
- /* Croatian system for Yugoslavia*/
- /*MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, 33, "",*/
- /* Hindi system for India*/
- /*MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, 34, "",*/
- /* Pakistan*/
- MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, 41, "lt_LT",
- /* Lithuania*/
- MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, 42, "pl_PL",
- /* Poland*/
- MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, 43, "hu_HU",
- /* Hungary*/
- MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, 44, "et_EE",
- /* Estonia*/
- MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, 45, "lv_LV",
- /* Latvia*/
- /*MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, 46, "",*/
- /* Lapland [Ask Rich for the data. HS]*/
- /*MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, 47, "",*/
- /* Faeroe Islands*/
- MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, 48, "fa_IR",
- /* Iran*/
- MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, 49, "ru_RU",
- /* Russia*/
- MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, 50, "en_IE",
- /* Ireland*/
- MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, 51, "ko_KR",
- /* Korea*/
- MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, 52, "zh_CN",
- /* People's Republic of China*/
- MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, 53, "zh_TW",
- /* Taiwan*/
- MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, 54, "th_TH",
- /* Thailand*/
-
- /* fallback is en_US*/
- MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER,
- MAC_LC_MAGIC_NUMBER, "en_US"
-};
+U_CAPI const char * U_EXPORT2
+u_getTimeZoneFilesDirectory(UErrorCode *status) {
+ umtx_initOnce(gTimeZoneFilesInitOnce, &TimeZoneDataDirInitFn, *status);
+ return U_SUCCESS(*status) ? gTimeZoneFilesDirectory->data() : "";
+}
+
+U_CAPI void U_EXPORT2
+u_setTimeZoneFilesDirectory(const char *path, UErrorCode *status) {
+ umtx_initOnce(gTimeZoneFilesInitOnce, &TimeZoneDataDirInitFn, *status);
+ setTimeZoneFilesDir(path, *status);
+
+ // Note: this function does some extra churn, first setting based on the
+ // environment, then immediately replacing with the value passed in.
+ // The logic is simpler that way, and performance shouldn't be an issue.
+}
-#endif
#if U_POSIX_LOCALE
/* A helper function used by uprv_getPOSIXIDForDefaultLocale and
{
/* Maybe we got some garbage. Try something more reasonable */
posixID = getenv("LC_ALL");
+ /* Solaris speaks POSIX - See IEEE Std 1003.1-2008
+ * This is needed to properly handle empty env. variables
+ */
+#if U_PLATFORM == U_PF_SOLARIS
+ if ((posixID == 0) || (posixID[0] == '\0')) {
+ posixID = getenv(category == LC_MESSAGES ? "LC_MESSAGES" : "LC_CTYPE");
+ if ((posixID == 0) || (posixID[0] == '\0')) {
+#else
if (posixID == 0) {
posixID = getenv(category == LC_MESSAGES ? "LC_MESSAGES" : "LC_CTYPE");
if (posixID == 0) {
+#endif
posixID = getenv("LANG");
}
}
return posixID;
#elif U_PLATFORM_USES_ONLY_WIN32_API
+#define POSIX_LOCALE_CAPACITY 64
UErrorCode status = U_ZERO_ERROR;
- LCID id = GetThreadLocale();
- const char* locID = uprv_convertToPosix(id, &status);
+ char *correctedPOSIXLocale = 0;
- if (U_FAILURE(status)) {
- locID = "en_US";
- }
- return locID;
-
-#elif U_PLATFORM == U_PF_CLASSIC_MACOS
- int32_t script = MAC_LC_INIT_NUMBER;
- /* = IntlScript(); or GetScriptManagerVariable(smSysScript);*/
- int32_t region = MAC_LC_INIT_NUMBER;
- /* = GetScriptManagerVariable(smRegionCode);*/
- int32_t lang = MAC_LC_INIT_NUMBER;
- /* = GetScriptManagerVariable(smScriptLang);*/
- int32_t date_region = MAC_LC_INIT_NUMBER;
- const char* posixID = 0;
- int32_t count = sizeof(mac_lc_recs) / sizeof(mac_lc_rec);
- int32_t i;
- Intl1Hndl ih;
-
- ih = (Intl1Hndl) GetIntlResource(1);
- if (ih)
- date_region = ((uint16_t)(*ih)->intl1Vers) >> 8;
-
- for (i = 0; i < count; i++) {
- if ( ((mac_lc_recs[i].script == MAC_LC_MAGIC_NUMBER)
- || (mac_lc_recs[i].script == script))
- && ((mac_lc_recs[i].region == MAC_LC_MAGIC_NUMBER)
- || (mac_lc_recs[i].region == region))
- && ((mac_lc_recs[i].lang == MAC_LC_MAGIC_NUMBER)
- || (mac_lc_recs[i].lang == lang))
- && ((mac_lc_recs[i].date_region == MAC_LC_MAGIC_NUMBER)
- || (mac_lc_recs[i].date_region == date_region))
- )
- {
- posixID = mac_lc_recs[i].posixID;
- break;
+ if (gCorrectedPOSIXLocale != NULL) {
+ 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);
}
}
- return posixID;
+ if (gCorrectedPOSIXLocale == NULL) {
+ return "en_US";
+ }
+ return gCorrectedPOSIXLocale;
#elif U_PLATFORM == U_PF_OS400
/* locales are process scoped and are by definition thread safe */
return codepage;
-#elif U_PLATFORM == U_PF_CLASSIC_MACOS
- return "macintosh"; /* TODO: Macintosh Roman. There must be a better way. fixme! */
-
#elif U_PLATFORM_USES_ONLY_WIN32_API
static char codepage[64];
sprintf(codepage, "windows-%d", GetACP());
localeName = uprv_getPOSIXIDForDefaultCodepage();
uprv_memset(codesetName, 0, sizeof(codesetName));
-#if U_HAVE_NL_LANGINFO_CODESET
+ /* On Solaris nl_langinfo returns C locale values unless setlocale
+ * was called earlier.
+ */
+#if (U_HAVE_NL_LANGINFO_CODESET && U_PLATFORM != U_PF_SOLARIS)
/* When available, check nl_langinfo first because it usually gives more
useful names. It depends on LC_CTYPE.
nl_langinfo may use the same buffer as setlocale. */
U_CAPI void U_EXPORT2
u_getVersion(UVersionInfo versionArray) {
+ (void)copyright; // Suppress unused variable warning from clang.
u_versionFromString(versionArray, U_ICU_VERSION);
}
U_INTERNAL void * U_EXPORT2
uprv_dl_open(const char *libName, UErrorCode *status) {
+ (void)libName;
if(U_FAILURE(*status)) return NULL;
*status = U_UNSUPPORTED_ERROR;
return NULL;
U_INTERNAL void U_EXPORT2
uprv_dl_close(void *lib, UErrorCode *status) {
+ (void)lib;
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) {
+ (void)lib;
+ (void)sym;
if(U_SUCCESS(*status)) {
*status = U_UNSUPPORTED_ERROR;
}