X-Git-Url: https://git.saurik.com/apple/icu.git/blobdiff_plain/51004dcb01e06fef634b61be77ed73dd61cb6db9..b331163bffd790ced0e88b73f44f86d49ccc48a5:/icuSources/i18n/identifier_info.cpp diff --git a/icuSources/i18n/identifier_info.cpp b/icuSources/i18n/identifier_info.cpp index 369a0678..0c0706f1 100644 --- a/icuSources/i18n/identifier_info.cpp +++ b/icuSources/i18n/identifier_info.cpp @@ -1,6 +1,6 @@ /* ********************************************************************** -* Copyright (C) 2012-2013, International Business Machines +* Copyright (C) 2012-2014, International Business Machines * Corporation and others. All Rights Reserved. ********************************************************************** */ @@ -18,18 +18,17 @@ U_NAMESPACE_BEGIN -#define LENGTHOF(array) (int32_t)(sizeof(array)/sizeof((array)[0])) +static UnicodeSet *ASCII; +static ScriptSet *JAPANESE; +static ScriptSet *CHINESE; +static ScriptSet *KOREAN; +static ScriptSet *CONFUSABLE_WITH_LATIN; +static UInitOnce gIdentifierInfoInitOnce = U_INITONCE_INITIALIZER; -static UMutex gInitMutex = U_MUTEX_INITIALIZER; -static UBool gStaticsAreInitialized = FALSE; -UnicodeSet *IdentifierInfo::ASCII; -ScriptSet *IdentifierInfo::JAPANESE; -ScriptSet *IdentifierInfo::CHINESE; -ScriptSet *IdentifierInfo::KOREAN; -ScriptSet *IdentifierInfo::CONFUSABLE_WITH_LATIN; - -UBool IdentifierInfo::cleanup() { +U_CDECL_BEGIN +static UBool U_CALLCONV +IdentifierInfo_cleanup(void) { delete ASCII; ASCII = NULL; delete JAPANESE; @@ -40,14 +39,30 @@ UBool IdentifierInfo::cleanup() { KOREAN = NULL; delete CONFUSABLE_WITH_LATIN; CONFUSABLE_WITH_LATIN = NULL; - gStaticsAreInitialized = FALSE; + gIdentifierInfoInitOnce.reset(); return TRUE; } -U_CDECL_BEGIN -static UBool U_CALLCONV -IdentifierInfo_cleanup(void) { - return IdentifierInfo::cleanup(); +static void U_CALLCONV +IdentifierInfo_init(UErrorCode &status) { + ASCII = new UnicodeSet(0, 0x7f); + JAPANESE = new ScriptSet(); + CHINESE = new ScriptSet(); + KOREAN = new ScriptSet(); + CONFUSABLE_WITH_LATIN = new ScriptSet(); + if (ASCII == NULL || JAPANESE == NULL || CHINESE == NULL || KOREAN == NULL + || CONFUSABLE_WITH_LATIN == NULL) { + status = U_MEMORY_ALLOCATION_ERROR; + return; + } + ASCII->freeze(); + JAPANESE->set(USCRIPT_LATIN, status).set(USCRIPT_HAN, status).set(USCRIPT_HIRAGANA, status) + .set(USCRIPT_KATAKANA, status); + CHINESE->set(USCRIPT_LATIN, status).set(USCRIPT_HAN, status).set(USCRIPT_BOPOMOFO, status); + KOREAN->set(USCRIPT_LATIN, status).set(USCRIPT_HAN, status).set(USCRIPT_HANGUL, status); + CONFUSABLE_WITH_LATIN->set(USCRIPT_CYRILLIC, status).set(USCRIPT_GREEK, status) + .set(USCRIPT_CHEROKEE, status); + ucln_i18n_registerCleanup(UCLN_I18N_IDENTIFIER_INFO, IdentifierInfo_cleanup); } U_CDECL_END @@ -55,33 +70,11 @@ U_CDECL_END IdentifierInfo::IdentifierInfo(UErrorCode &status): fIdentifier(NULL), fRequiredScripts(NULL), fScriptSetSet(NULL), fCommonAmongAlternates(NULL), fNumerics(NULL), fIdentifierProfile(NULL) { + umtx_initOnce(gIdentifierInfoInitOnce, &IdentifierInfo_init, status); if (U_FAILURE(status)) { return; } - { - Mutex lock(&gInitMutex); - if (!gStaticsAreInitialized) { - ASCII = new UnicodeSet(0, 0x7f); - JAPANESE = new ScriptSet(); - CHINESE = new ScriptSet(); - KOREAN = new ScriptSet(); - CONFUSABLE_WITH_LATIN = new ScriptSet(); - if (ASCII == NULL || JAPANESE == NULL || CHINESE == NULL || KOREAN == NULL - || CONFUSABLE_WITH_LATIN == NULL) { - status = U_MEMORY_ALLOCATION_ERROR; - return; - } - ASCII->freeze(); - JAPANESE->set(USCRIPT_LATIN, status).set(USCRIPT_HAN, status).set(USCRIPT_HIRAGANA, status) - .set(USCRIPT_KATAKANA, status); - CHINESE->set(USCRIPT_LATIN, status).set(USCRIPT_HAN, status).set(USCRIPT_BOPOMOFO, status); - KOREAN->set(USCRIPT_LATIN, status).set(USCRIPT_HAN, status).set(USCRIPT_HANGUL, status); - CONFUSABLE_WITH_LATIN->set(USCRIPT_CYRILLIC, status).set(USCRIPT_GREEK, status) - .set(USCRIPT_CHEROKEE, status); - ucln_i18n_registerCleanup(UCLN_I18N_IDENTIFIER_INFO, IdentifierInfo_cleanup); - gStaticsAreInitialized = TRUE; - } - } + fIdentifier = new UnicodeString(); fRequiredScripts = new ScriptSet(); fScriptSetSet = uhash_open(uhash_hashScriptSet, uhash_compareScriptSet, NULL, &status); @@ -142,7 +135,7 @@ IdentifierInfo &IdentifierInfo::setIdentifier(const UnicodeString &identifier, U fNumerics->add(cp - (UChar32)u_getNumericValue(cp)); } UScriptCode extensions[500]; - int32_t extensionsCount = uscript_getScriptExtensions(cp, extensions, LENGTHOF(extensions), &status); + int32_t extensionsCount = uscript_getScriptExtensions(cp, extensions, UPRV_LENGTHOF(extensions), &status); if (U_FAILURE(status)) { return *this; } @@ -174,7 +167,7 @@ IdentifierInfo &IdentifierInfo::setIdentifier(const UnicodeString &identifier, U // We also compute any commonalities among the alternates. if (uhash_count(fScriptSetSet) > 0) { fCommonAmongAlternates->setAll(); - for (int32_t it = -1;;) { + for (int32_t it = UHASH_FIRST;;) { const UHashElement *nextHashEl = uhash_nextElement(fScriptSetSet, &it); if (nextHashEl == NULL) { break; @@ -186,7 +179,7 @@ IdentifierInfo &IdentifierInfo::setIdentifier(const UnicodeString &identifier, U } else { fCommonAmongAlternates->intersect(*next); // [[Arab Syrc Thaa]; [Arab Syrc]] => [[Arab Syrc]] - for (int32_t otherIt = -1;;) { + for (int32_t otherIt = UHASH_FIRST;;) { const UHashElement *otherHashEl = uhash_nextElement(fScriptSetSet, &otherIt); if (otherHashEl == NULL) { break; @@ -247,7 +240,7 @@ URestrictionLevel IdentifierInfo::getRestrictionLevel(UErrorCode &status) const int32_t cardinalityPlus = fRequiredScripts->countMembers() + (fCommonAmongAlternates->countMembers() == 0 ? uhash_count(fScriptSetSet) : 1); if (cardinalityPlus < 2) { - return USPOOF_HIGHLY_RESTRICTIVE; + return USPOOF_SINGLE_SCRIPT_RESTRICTIVE; } if (containsWithAlternates(*JAPANESE, *fRequiredScripts) || containsWithAlternates(*CHINESE, *fRequiredScripts) || containsWithAlternates(*KOREAN, *fRequiredScripts)) { @@ -276,7 +269,7 @@ UBool IdentifierInfo::containsWithAlternates(const ScriptSet &container, const S if (!container.contains(containee)) { return FALSE; } - for (int32_t iter = -1; ;) { + for (int32_t iter = UHASH_FIRST; ;) { const UHashElement *hashEl = uhash_nextElement(fScriptSetSet, &iter); if (hashEl == NULL) { break; @@ -294,7 +287,7 @@ UnicodeString &IdentifierInfo::displayAlternates(UnicodeString &dest, const UHas if (U_FAILURE(status)) { return dest; } - for (int32_t pos = -1; ;) { + for (int32_t pos = UHASH_FIRST; ;) { const UHashElement *el = uhash_nextElement(alternates, &pos); if (el == NULL) { break;