/*
**********************************************************************
-* Copyright (C) 2012-2013, International Business Machines
+* Copyright (C) 2012-2014, International Business Machines
* Corporation and others. All Rights Reserved.
**********************************************************************
*/
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;
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
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);
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;
}
// 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;
} 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;
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)) {
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;
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;