ICU-7689 start of C default locale
X-SVN-Rev: 29418
diff --git a/source/common/icu4c0.mk b/source/common/icu4c0.mk
index 0a6dcb6..90a1c90 100644
--- a/source/common/icu4c0.mk
+++ b/source/common/icu4c0.mk
@@ -23,7 +23,10 @@
COMMON_TRIE_OBJ=utrie2.o uchar.o ucase.o
COMMON_UTIL_OBJ=putil.o uhash.o ustr_cnv.o ustring.o umutex.o cmemory.o utf_impl.o uinvchar.o ustrfmt.o uenum.o cstring.o ucln_cmn.o uinit.o umath.o icuplug.o uarrsort.o utrace.o utypes.o
COMMON_UCNV_OBJ=ucnv.o ucnv2022.o ucnv_bld.o ucnv_cb.o ucnv_cnv.o ucnv_err.o ucnv_ext.o ucnv_io.o ucnv_lmb.o ucnv_set.o ucnv_u16.o ucnv_u32.o ucnv_u7.o ucnv_u8.o ucnvbocu.o ucnvdisp.o ucnvhz.o ucnvisci.o ucnvlat1.o ucnvmbcs.o ucnvscsu.o
-COMMON_OBJ=$(COMMON_UCNV_OBJ) $(COMMON_UTIL_OBJ) $(COMMON_DATA_OBJ) $(COMMON_TRIE_OBJ)
+COMMON_LOC_OBJ=uloc_tag.o locmap.o uloc.o
+COMMON_RES_OBJ=uresbund.o uresdata.o
+COMMON_STR_OBJ=ustrtrns.o
+COMMON_OBJ=$(COMMON_UCNV_OBJ) $(COMMON_UTIL_OBJ) $(COMMON_DATA_OBJ) $(COMMON_TRIE_OBJ) $(COMMON_LOC_OBJ) $(COMMON_RES_OBJ) $(COMMON_STR_OBJ)
ICU4C0_VERSION=$(VERSION)
endif
diff --git a/source/common/uloc.c b/source/common/uloc.c
index 1357f7b..4ab7d1e 100644
--- a/source/common/uloc.c
+++ b/source/common/uloc.c
@@ -2055,6 +2055,145 @@
/* ### Default locale **************************************************/
+#if defined(ICU4C0)
+char _locid[999] = { 0 };
+
+#if 0
+void locale_set_default_internal(const char *id)
+{
+ UErrorCode status = U_ZERO_ERROR;
+ UBool canonicalize = FALSE;
+
+ /* // If given a NULL string for the locale id, grab the default */
+ /* // name from the system. */
+ /* // (Different from most other locale APIs, where a null name means use */
+ /* // the current ICU default locale.) */
+ if (id == NULL) {
+ umtx_lock(NULL);
+ id = uprv_getDefaultLocaleID();
+ umtx_unlock(NULL);
+ canonicalize = TRUE; // always canonicalize host ID
+ }
+
+ // put the locale id into a canonical form,
+ // in preparation for looking up this locale in the hash table of
+ // already-created locale objects.
+ //
+ status = U_ZERO_ERROR;
+ char localeNameBuf[512];
+
+ if (canonicalize) {
+ uloc_canonicalize(id, localeNameBuf, sizeof(localeNameBuf)-1, &status);
+ } else {
+ uloc_getName(id, localeNameBuf, sizeof(localeNameBuf)-1, &status);
+ }
+ localeNameBuf[sizeof(localeNameBuf)-1] = 0; // Force null termination in event of
+ // a long name filling the buffer.
+ // (long names are truncated.)
+
+ // Lazy creation of the hash table itself, if needed.
+ UBool isOnlyLocale;
+ UMTX_CHECK(NULL, (gDefaultLocale == NULL), isOnlyLocale);
+ if (isOnlyLocale) {
+ // We haven't seen this locale id before.
+ // Create a new Locale object for it.
+ Locale *newFirstDefault = new Locale(Locale::eBOGUS);
+ if (newFirstDefault == NULL) {
+ // No way to report errors from here.
+ return;
+ }
+ newFirstDefault->init(localeNameBuf, FALSE);
+ umtx_lock(NULL);
+ if (gDefaultLocale == NULL) {
+ gDefaultLocale = newFirstDefault; // Assignment to gDefaultLocale must happen inside mutex
+ newFirstDefault = NULL;
+ ucln_common_registerCleanup(UCLN_COMMON_LOCALE, locale_cleanup);
+ }
+ // Else some other thread raced us through here, and set the new Locale.
+ // Use the hash table next.
+ umtx_unlock(NULL);
+ if (newFirstDefault == NULL) {
+ // We were successful in setting the locale, and we were the first one to set it.
+ return;
+ }
+ // else start using the hash table.
+ }
+
+ // Lazy creation of the hash table itself, if needed.
+ UBool hashTableNeedsInit;
+ UMTX_CHECK(NULL, (gDefaultLocalesHashT == NULL), hashTableNeedsInit);
+ if (hashTableNeedsInit) {
+ status = U_ZERO_ERROR;
+ UHashtable *tHashTable = uhash_open(uhash_hashChars, uhash_compareChars, NULL, &status);
+ if (U_FAILURE(status)) {
+ return;
+ }
+ uhash_setValueDeleter(tHashTable, deleteLocale);
+ umtx_lock(NULL);
+ if (gDefaultLocalesHashT == NULL) {
+ gDefaultLocalesHashT = tHashTable;
+ ucln_common_registerCleanup(UCLN_COMMON_LOCALE, locale_cleanup);
+ } else {
+ uhash_close(tHashTable);
+ hashTableNeedsInit = FALSE;
+ }
+ umtx_unlock(NULL);
+ }
+
+ // Hash table lookup, key is the locale full name
+ umtx_lock(NULL);
+ Locale *newDefault = (Locale *)uhash_get(gDefaultLocalesHashT, localeNameBuf);
+ if (newDefault != NULL) {
+ // We have the requested locale in the hash table already.
+ // Just set it as default. Inside the mutex lock, for those troublesome processors.
+ gDefaultLocale = newDefault;
+ umtx_unlock(NULL);
+ } else {
+ umtx_unlock(NULL);
+ // We haven't seen this locale id before.
+ // Create a new Locale object for it.
+ newDefault = new Locale(Locale::eBOGUS);
+ if (newDefault == NULL) {
+ // No way to report errors from here.
+ return;
+ }
+ newDefault->init(localeNameBuf, FALSE);
+
+ // Add newly created Locale to the hash table of default Locales
+ const char *key = newDefault->getName();
+ U_ASSERT(uprv_strcmp(key, localeNameBuf) == 0);
+ umtx_lock(NULL);
+ Locale *hashTableVal = (Locale *)uhash_get(gDefaultLocalesHashT, key);
+ if (hashTableVal == NULL) {
+ if (hashTableNeedsInit) {
+ // This is the second request to set the locale.
+ // Cache the first one.
+ uhash_put(gDefaultLocalesHashT, (void *)gDefaultLocale->getName(), gDefaultLocale, &status);
+ }
+ uhash_put(gDefaultLocalesHashT, (void *)key, newDefault, &status);
+ gDefaultLocale = newDefault;
+ // ignore errors from hash table insert. (Couldn't do anything anyway)
+ // We can still set the default Locale,
+ // it just wont be cached, and will eventually leak.
+ } else {
+ // Some other thread raced us through here, and got the new Locale
+ // into the hash table before us. Use that one.
+ gDefaultLocale = hashTableVal; // Assignment to gDefaultLocale must happen inside mutex
+ delete newDefault;
+ }
+ umtx_unlock(NULL);
+ }
+}
+#endif
+
+const char *locale_get_default() {
+ return _locid;
+}
+void locale_set_default(const char *id) {
+ strcpy(_locid, id);
+}
+#endif
+
U_CAPI const char* U_EXPORT2
uloc_getDefault()
{