/*
******************************************************************************
*
-* Copyright (C) 1997-2012, 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
+#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
+# endif
#elif U_PLATFORM == U_PF_QNX
# include <sys/neutrino.h>
-#elif U_PLATFORM == U_PF_SOLARIS
-# ifndef _XPG4_2
-# define _XPG4_2
-# endif
#endif
#if (U_PF_MINGW <= U_PLATFORM && U_PLATFORM <= U_PF_CYGWIN) && defined(__STRICT_ANSI__)
# 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
UDate fakeClock_t0 = 0; /** Time to start the clock from **/
UDate fakeClock_dt = 0; /** Offset (fake time - real time) **/
UBool fakeClock_set = FALSE; /** True if fake clock has spun up **/
-static UMTX fakeClockMutex = NULL;
+static UMutex fakeClockMutex = U_MUTEX_INTIALIZER;
static UDate getUTCtime_real() {
struct timeval posixTime;
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*/
+ 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. 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)
+#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
#include <tzfile.h>
#define TZZONEINFO (TZDIR "/")
+#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/"
#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
/* This code can be temporarily disabled to test tzname resolution later on. */
#ifndef DEBUG_TZNAME
tzid = getenv("TZ");
- if (tzid != NULL && isValidOlsonID(tzid))
- {
+ if (tzid != NULL && isValidOlsonID(tzid)
+#if U_PLATFORM == U_PF_SOLARIS
+ /* When TZ equals localtime on Solaris, check the /etc/localtime file. */
+ && 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"
-};
-#endif
+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.
+}
+
#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;
}
+#if !U_CHARSET_IS_UTF8
/* Return just the POSIX id for the default codepage, whatever happens to be in
* it. It gets the value from LC_CTYPE and indirectly from LC_ALL and LANG.
*/
return posixID;
}
#endif
+#endif
/* NOTE: The caller should handle thread safety */
U_CAPI const char* U_EXPORT2
if ((p = uprv_strchr(posixID, '.')) != NULL) {
/* assume new locale can't be larger than old one? */
- correctedPOSIXLocale = reinterpret_cast<char *>(uprv_malloc(uprv_strlen(posixID)+1));
+ correctedPOSIXLocale = static_cast<char *>(uprv_malloc(uprv_strlen(posixID)+1));
/* Exit on memory allocation error. */
if (correctedPOSIXLocale == NULL) {
return NULL;
/* Note that we scan the *uncorrected* ID. */
if ((p = uprv_strrchr(posixID, '@')) != NULL) {
if (correctedPOSIXLocale == NULL) {
- correctedPOSIXLocale = reinterpret_cast<char *>(uprv_malloc(uprv_strlen(posixID)+1));
+ correctedPOSIXLocale = static_cast<char *>(uprv_malloc(uprv_strlen(posixID)+1));
/* Exit on memory allocation error. */
if (correctedPOSIXLocale == NULL) {
return NULL;
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);
}
#if U_ENABLE_DYLOAD
-#if HAVE_DLOPEN && !U_PLATFORM_HAS_WIN32_API
+#if HAVE_DLOPEN && !U_PLATFORM_USES_ONLY_WIN32_API
#if HAVE_DLFCN_H
#endif
-#elif U_PLATFORM_HAS_WIN32_API
+#elif U_PLATFORM_USES_ONLY_WIN32_API
U_INTERNAL void * U_EXPORT2
uprv_dl_open(const char *libName, UErrorCode *status) {
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;
}