/* Function: GetCalendars Returns the list of CalendarIds that are available for the specified locale. */ int32_t GlobalizationNative_GetCalendars( const UChar* localeName, CalendarId* calendars, int32_t calendarsCapacity) { UErrorCode err = U_ZERO_ERROR; char locale[ULOC_FULLNAME_CAPACITY]; GetLocale(localeName, locale, ULOC_FULLNAME_CAPACITY, FALSE, &err); UEnumeration* pEnum = ucal_getKeywordValuesForLocale("calendar", locale, TRUE, &err); int stringEnumeratorCount = uenum_count(pEnum, &err); int calendarsReturned = 0; for (int i = 0; i < stringEnumeratorCount && calendarsReturned < calendarsCapacity; i++) { int32_t calendarNameLength = 0; const char* calendarName = uenum_next(pEnum, &calendarNameLength, &err); if (U_SUCCESS(err)) { CalendarId calendarId = GetCalendarId(calendarName); if (calendarId != UNINITIALIZED_VALUE) { calendars[calendarsReturned] = calendarId; calendarsReturned++; } } } uenum_close(pEnum); return calendarsReturned; }
/* * The list of detectable encodings supported by this library * * Returns: an list of strings */ PyObject * charlockholmes_get_supported_encodings(PyObject *self) { UCharsetDetector *csd; UErrorCode status = U_ZERO_ERROR; UEnumeration *encoding_list; PyObject *result; int32_t enc_count; int32_t i; const char *enc_name; int32_t enc_name_len; csd = ucsdet_open(&status); encoding_list = ucsdet_getAllDetectableCharsets(csd, &status); enc_count = uenum_count(encoding_list, &status); result = PyTuple_New(enc_count); if (!result) return NULL; for(i=0; i < enc_count; i++) { enc_name = uenum_next(encoding_list, &enc_name_len, &status); PyTuple_SetItem(result, i, PyString_FromStringAndSize(enc_name, enc_name_len)); } ucsdet_close(csd); return result; }
static int32_t checkItemCount(uint32_t currencyType) { UErrorCode status = U_ZERO_ERROR; int32_t originalCount, count; UEnumeration *en = ucurr_openISOCurrencies(currencyType, &status); int32_t expectedLen = 3, len; if (U_FAILURE(status)) { log_err("Error: ucurr_openISOCurrencies returned %s\n", myErrorName(status)); return -1; } originalCount = uenum_count(en, &status); for (count=0;;count++) { const char *str = uenum_next(en, &len, &status); if (str == NULL || len != expectedLen || strlen(str) != expectedLen) { break; } } if (originalCount != count) { log_err("Error: uenum_count returned the wrong value (type = 0x%X). Got: %d Expected %d\n", currencyType, count, originalCount); } if (U_FAILURE(status)) { log_err("Error: uenum_next got an error: %s\n", u_errorName(status)); } uenum_close(en); return count; }
static jobject ICU_getAvailableCurrencyCodes(JNIEnv* env, jclass) { UErrorCode status = U_ZERO_ERROR; UEnumeration* e(ucurr_openISOCurrencies(UCURR_COMMON|UCURR_NON_DEPRECATED, &status)); EnumerationCounter counter(uenum_count(e, &status)); EnumerationGetter getter(e, &status); jobject result = toStringArray16(env, &counter, &getter); maybeThrowIcuException(env, status); uenum_close(e); return result; }
static UBool doTestNames(const char *name, const char *standard, const char **expected, int32_t size) { UErrorCode err = U_ZERO_ERROR; UEnumeration *myEnum = ucnv_openStandardNames(name, standard, &err); const char *enumName, *testName; int32_t enumCount = uenum_count(myEnum, &err); int32_t idx, len, repeatTimes = 3; if (err == U_FILE_ACCESS_ERROR) { log_data_err("Unable to open standard names for %s of standard: %s\n", name, standard); return 0; } if (size != enumCount) { log_err("FAIL: different size arrays for %s. Got %d. Expected %d\n", name, enumCount, size); return 0; } if (size < 0 && myEnum) { log_err("FAIL: size < 0, but recieved an actual object\n"); return 0; } log_verbose("\n%s %s\n", name, standard); while (repeatTimes-- > 0) { for (idx = 0; idx < enumCount; idx++) { enumName = uenum_next(myEnum, &len, &err); testName = expected[idx]; if (uprv_strcmp(enumName, testName) != 0 || U_FAILURE(err) || len != (int32_t)uprv_strlen(expected[idx])) { log_err("FAIL: uenum_next(%d) == \"%s\". expected \"%s\", len=%d, error=%s\n", idx, enumName, testName, len, u_errorName(err)); } log_verbose("%s\n", enumName); err = U_ZERO_ERROR; } if (enumCount >= 0) { /* one past the list of all names must return NULL */ enumName = uenum_next(myEnum, &len, &err); if (enumName != NULL || len != 0 || U_FAILURE(err)) { log_err("FAIL: uenum_next(past the list) did not return NULL[0] with U_SUCCESS(). name=%s standard=%s len=%d err=%s\n", name, standard, len, u_errorName(err)); } } log_verbose("\n reset\n"); uenum_reset(myEnum, &err); if (U_FAILURE(err)) { log_err("FAIL: uenum_reset() for %s{%s} failed with %s\n", name, standard, u_errorName(err)); err = U_ZERO_ERROR; } } uenum_close(myEnum); return 1; }
static UBool doTestUCharNames(const char *name, const char *standard, const char **expected, int32_t size) { UErrorCode err = U_ZERO_ERROR; UEnumeration *myEnum = ucnv_openStandardNames(name, standard, &err); int32_t enumCount = uenum_count(myEnum, &err); int32_t idx, repeatTimes = 3; if (err == U_FILE_ACCESS_ERROR) { log_data_err("Unable to open standard names for %s of standard: %s\n", name, standard); return 0; } if (size != enumCount) { log_err("FAIL: different size arrays. Got %d. Expected %d\n", enumCount, size); return 0; } if (size < 0 && myEnum) { log_err("FAIL: size < 0, but recieved an actual object\n"); return 0; } log_verbose("\n%s %s\n", name, standard); while (repeatTimes-- > 0) { for (idx = 0; idx < enumCount; idx++) { UChar testName[256]; int32_t len; const UChar *enumName = uenum_unext(myEnum, &len, &err); u_uastrncpy(testName, expected[idx], UPRV_LENGTHOF(testName)); if (u_strcmp(enumName, testName) != 0 || U_FAILURE(err) || len != (int32_t)uprv_strlen(expected[idx])) { log_err("FAIL: uenum_next(%d) == \"%s\". expected \"%s\", len=%d, error=%s\n", idx, enumName, testName, len, u_errorName(err)); } log_verbose("%s\n", expected[idx]); err = U_ZERO_ERROR; } log_verbose("\n reset\n"); uenum_reset(myEnum, &err); if (U_FAILURE(err)) { log_err("FAIL: uenum_reset() for %s{%s} failed with %s\n", name, standard, u_errorName(err)); err = U_ZERO_ERROR; } } uenum_close(myEnum); return 1; }
static void EmptyEnumerationTest(void) { UErrorCode status = U_ZERO_ERROR; UEnumeration *emptyEnum = uprv_malloc(sizeof(UEnumeration)); uprv_memcpy(emptyEnum, &emptyEnumerator, sizeof(UEnumeration)); if (uenum_count(emptyEnum, &status) != -1 || status != U_UNSUPPORTED_ERROR) { log_err("uenum_count failed\n"); } status = U_ZERO_ERROR; if (uenum_next(emptyEnum, NULL, &status) != NULL || status != U_UNSUPPORTED_ERROR) { log_err("uenum_next failed\n"); } status = U_ZERO_ERROR; if (uenum_unext(emptyEnum, NULL, &status) != NULL || status != U_UNSUPPORTED_ERROR) { log_err("uenum_unext failed\n"); } status = U_ZERO_ERROR; uenum_reset(emptyEnum, &status); if (status != U_UNSUPPORTED_ERROR) { log_err("uenum_reset failed\n"); } uenum_close(emptyEnum); status = U_ZERO_ERROR; if (uenum_next(NULL, NULL, &status) != NULL || status != U_ZERO_ERROR) { log_err("uenum_next(NULL) failed\n"); } status = U_ZERO_ERROR; if (uenum_unext(NULL, NULL, &status) != NULL || status != U_ZERO_ERROR) { log_err("uenum_unext(NULL) failed\n"); } status = U_ZERO_ERROR; uenum_reset(NULL, &status); if (status != U_ZERO_ERROR) { log_err("uenum_reset(NULL) failed\n"); } emptyEnum = uprv_malloc(sizeof(UEnumeration)); uprv_memcpy(emptyEnum, &emptyPartialEnumerator, sizeof(UEnumeration)); status = U_ZERO_ERROR; if (uenum_unext(emptyEnum, NULL, &status) != NULL || status != U_UNSUPPORTED_ERROR) { log_err("partial uenum_unext failed\n"); } uenum_close(emptyEnum); }
int32_t count(UErrorCode& status) const { return uenum_count(uenum, &status); }
static void TestGetKeywordValuesForLocale(void) { #define PREFERRED_SIZE 15 #define MAX_NUMBER_OF_KEYWORDS 4 const char *PREFERRED[PREFERRED_SIZE][MAX_NUMBER_OF_KEYWORDS] = { { "root", "USD", "USN", NULL }, { "und", "USD", "USN", NULL }, /* { "und_ZZ", "USD", NULL, NULL }, -- temporarily remove as this locale now has 15 entries */ { "en_US", "USD", "USN", NULL }, { "en_029", "USD", "USN", NULL }, { "en_TH", "THB", NULL, NULL }, { "de", "EUR", NULL, NULL }, { "de_DE", "EUR", NULL, NULL }, { "ar", "EGP", NULL, NULL }, { "ar_PS", "ILS", "JOD", NULL }, { "en@currency=CAD", "USD", "USN", NULL }, { "fr@currency=zzz", "EUR", NULL, NULL }, { "de_DE@currency=DEM", "EUR", NULL, NULL }, { "en_US@rg=THZZZZ", "THB", NULL, NULL }, { "de@rg=USZZZZ", "USD", "USN", NULL }, { "en_US@currency=CAD;rg=THZZZZ", "THB", NULL, NULL }, }; const int32_t EXPECTED_SIZE[PREFERRED_SIZE] = { 2, 2, 2, 2, 1, 1, 1, 1, 2, 2, 1, 1, 1, 2, 1 }; /* ucurr_forLocale results for same locales; "" if no result expected */ const char *FORLOCALE[PREFERRED_SIZE] = { "", "", "USD", "", "THB", "", "EUR", "", "ILS", "CAD", "ZZZ", "DEM", "THB", "USD", "CAD" }; UErrorCode status = U_ZERO_ERROR; int32_t i, j, size; UEnumeration *pref, *all; const char *loc = NULL; UBool matchPref, matchAll; const char *value = NULL; int32_t valueLength = 0; UList *ALLList = NULL; UEnumeration *ALL = ucurr_getKeywordValuesForLocale("currency", uloc_getDefault(), FALSE, &status); if (ALL == NULL) { log_err_status(status, "ERROR getting keyword value for default locale. -> %s\n", u_errorName(status)); return; } for (i = 0; i < PREFERRED_SIZE; i++) { UChar getCurrU[4]; int32_t getCurrLen; status = U_ZERO_ERROR; pref = NULL; all = NULL; loc = PREFERRED[i][0]; pref = ucurr_getKeywordValuesForLocale("currency", loc, TRUE, &status); matchPref = FALSE; matchAll = FALSE; size = uenum_count(pref, &status); if (size == EXPECTED_SIZE[i]) { matchPref = TRUE; for (j = 0; j < size; j++) { if ((value = uenum_next(pref, &valueLength, &status)) != NULL && U_SUCCESS(status)) { if (uprv_strcmp(value, PREFERRED[i][j+1]) != 0) { log_err("ERROR: locale %s got keywords #%d %s expected %s\n", loc, j, value, PREFERRED[i][j+1]); matchPref = FALSE; break; } } else { matchPref = FALSE; log_err("ERROR getting keyword value for locale \"%s\"\n", loc); break; } } } else { log_err("FAIL: size of locale \"%s\" %d does not match expected size %d\n", loc, size, EXPECTED_SIZE[i]); } if (!matchPref) { log_err("FAIL: Preferred values for locale \"%s\" does not match expected.\n", loc); break; } uenum_close(pref); all = ucurr_getKeywordValuesForLocale("currency", loc, FALSE, &status); size = uenum_count(all, &status); if (U_SUCCESS(status) && size == uenum_count(ALL, &status)) { matchAll = TRUE; ALLList = ulist_getListFromEnum(ALL); for (j = 0; j < size; j++) { if ((value = uenum_next(all, &valueLength, &status)) != NULL && U_SUCCESS(status)) { if (!ulist_containsString(ALLList, value, uprv_strlen(value))) { log_err("Locale %s have %s not in ALL\n", loc, value); matchAll = FALSE; break; } } else { matchAll = FALSE; log_err("ERROR getting \"all\" keyword value for locale \"%s\"\n", loc); break; } } if (!matchAll) { log_err("FAIL: All values for locale \"%s\" does not match expected.\n", loc); } } else { if(U_FAILURE(status)) { log_err("ERROR: %s\n", u_errorName(status)); } else if(size!=uenum_count(ALL, &status)) { log_err("ERROR: got size of %d, wanted %d\n", size, uenum_count(ALL, &status)); } } uenum_close(all); status = U_ZERO_ERROR; getCurrLen = ucurr_forLocale(loc, getCurrU, 4, &status); if(U_FAILURE(status)) { if (FORLOCALE[i][0] != 0) { log_err("ERROR: ucurr_forLocale %s, status %s\n", loc, u_errorName(status)); } } else if (getCurrLen != 3) { if (FORLOCALE[i][0] != 0 || getCurrLen != -1) { log_err("ERROR: ucurr_forLocale %s, returned len %d\n", loc, getCurrLen); } } else { char getCurrB[4]; u_UCharsToChars(getCurrU, getCurrB, 4); if ( uprv_strncmp(getCurrB, FORLOCALE[i], 4) != 0 ) { log_err("ERROR: ucurr_forLocale %s, expected %s, got %s\n", loc, FORLOCALE[i], getCurrB); } } } uenum_close(ALL); }
static void TestGetKeywordValuesForLocale(void) { #define PREFERRED_SIZE 13 #define MAX_NUMBER_OF_KEYWORDS 3 const char *PREFERRED[PREFERRED_SIZE][MAX_NUMBER_OF_KEYWORDS] = { { "root", "USD", NULL }, { "und", "USD", NULL }, { "und_ZZ", "USD", NULL }, { "en_US", "USD", NULL }, { "en_029", "USD", NULL }, { "en_TH", "THB", NULL }, { "de", "EUR", NULL }, { "de_DE", "EUR", NULL }, { "ar", "EGP", NULL }, { "ar_PS", "JOD", "ILS" }, { "en@currency=CAD", "USD", NULL }, { "fr@currency=zzz", "EUR", NULL }, { "de_DE@currency=DEM", "EUR", NULL }, }; const int32_t EXPECTED_SIZE[PREFERRED_SIZE] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1 }; UErrorCode status = U_ZERO_ERROR; int32_t i, j, size; UEnumeration *pref, *all; const char *loc = NULL; UBool matchPref, matchAll; const char *value = NULL; int32_t valueLength = 0; UList *ALLList = NULL; UEnumeration *ALL = ucurr_getKeywordValuesForLocale("currency", uloc_getDefault(), FALSE, &status); if (ALL == NULL) { log_err_status(status, "ERROR getting keyword value for default locale. -> %s\n", u_errorName(status)); return; } for (i = 0; i < PREFERRED_SIZE; i++) { pref = NULL; all = NULL; loc = PREFERRED[i][0]; pref = ucurr_getKeywordValuesForLocale("currency", loc, TRUE, &status); matchPref = FALSE; matchAll = FALSE; size = uenum_count(pref, &status); if (size == EXPECTED_SIZE[i]) { matchPref = TRUE; for (j = 0; j < size; j++) { if ((value = uenum_next(pref, &valueLength, &status)) != NULL && U_SUCCESS(status)) { if (uprv_strcmp(value, PREFERRED[i][j+1]) != 0) { log_err("ERROR: locale %s got keywords #%d %s expected %s\n", loc, j, value, PREFERRED[i][j+1]); matchPref = FALSE; break; } } else { matchPref = FALSE; log_err("ERROR getting keyword value for locale \"%s\"\n", loc); break; } } } else { log_err("FAIL: size of locale \"%s\" %d does not match expected size %d\n", loc, size, EXPECTED_SIZE[i]); } if (!matchPref) { log_err("FAIL: Preferred values for locale \"%s\" does not match expected.\n", loc); break; } uenum_close(pref); all = ucurr_getKeywordValuesForLocale("currency", loc, FALSE, &status); size = uenum_count(all, &status); if (U_SUCCESS(status) && size == uenum_count(ALL, &status)) { matchAll = TRUE; ALLList = ulist_getListFromEnum(ALL); for (j = 0; j < size; j++) { if ((value = uenum_next(all, &valueLength, &status)) != NULL && U_SUCCESS(status)) { if (!ulist_containsString(ALLList, value, uprv_strlen(value))) { log_err("Locale %s have %s not in ALL\n", loc, value); matchAll = FALSE; break; } } else { matchAll = FALSE; log_err("ERROR getting \"all\" keyword value for locale \"%s\"\n", loc); break; } } if (!matchAll) { log_err("FAIL: All values for locale \"%s\" does not match expected.\n", loc); } } else { if(U_FAILURE(status)) { log_err("ERROR: %s\n", u_errorName(status)); } else if(size!=uenum_count(ALL, &status)) { log_err("ERROR: got size of %d, wanted %d\n", size, uenum_count(ALL, &status)); } } uenum_close(all); } uenum_close(ALL); }
static void print_icu_transliterators(const struct config_t *p_config) { UErrorCode status; UEnumeration *en = utrans_openIDs(&status); int32_t count = uenum_count(en, &status); const char *name; int32_t length; if (p_config->xmloutput) fprintf(p_config->outfile, "<transliterators count=\"%d\">\n", count); else fprintf(p_config->outfile, "Available ICU transliterators: %d\n", count); while ((name = uenum_next(en, &length, &status))) { if (p_config->xmloutput) fprintf(p_config->outfile, "<transliterator id=\"%s\"/>\n", name); else fprintf(p_config->outfile, "%s\n", name); } uenum_close(en); if (p_config->xmloutput) fprintf(p_config->outfile, "</transliterators>\n"); else { fprintf(p_config->outfile, "\n\nUnicode Set Patterns:\n" " Pattern Description\n" " Ranges [a-z] The lower case letters a through z\n" " Named Chars [abc123] The six characters a,b,c,1,2 and 3\n" " String [abc{def}] chars a, b and c, and string 'def'\n" " Categories [\\p{Letter}] Perl General Category 'Letter'.\n" " Categories [:Letter:] Posix General Category 'Letter'.\n" "\n" " Combination Example\n" " Union [[:Greek:] [:letter:]]\n" " Intersection [[:Greek:] & [:letter:]]\n" " Set Complement [[:Greek:] - [:letter:]]\n" " Complement [^[:Greek:] [:letter:]]\n" "\n" "see: http://icu.sourceforge.net/userguide/unicodeSet.html\n" "\n" "Examples:\n" " [:Punctuation:] Any-Remove\n" " [:Cased-Letter:] Any-Upper\n" " [:Control:] Any-Remove\n" " [:Decimal_Number:] Any-Remove\n" " [:Final_Punctuation:] Any-Remove\n" " [:Georgian:] Any-Upper\n" " [:Katakana:] Any-Remove\n" " [:Arabic:] Any-Remove\n" " [:Punctuation:] Remove\n" " [[:Punctuation:]-[.,]] Remove\n" " [:Line_Separator:] Any-Remove\n" " [:Math_Symbol:] Any-Remove\n" " Lower; [:^Letter:] Remove (word tokenization)\n" " [:^Number:] Remove (numeric tokenization)\n" " [:^Katagana:] Remove (remove everything except Katagana)\n" " Lower;[[:WhiteSpace:][:Punctuation:]] Remove (word tokenization)\n" " NFD; [:Nonspacing Mark:] Remove; NFC (removes accents from characters)\n" " [A-Za-z]; Lower(); Latin-Katakana; Katakana-Hiragana (transforms latin and katagana to hiragana)\n" " [[:separator:][:start punctuation:][:initial punctuation:]] Remove \n" "\n" "see http://userguide.icu-project.org/transforms/general\n" " http://www.unicode.org/reports/tr44/\n" ); fprintf(p_config->outfile, "\n\n"); } }
int32_t UStringEnumeration::count(UErrorCode& status) const { return uenum_count(uenum, &status); }
static void TestUnicodeIDs() { UEnumeration *uenum; UTransliterator *utrans; const UChar *id, *id2; int32_t idLength, id2Length, count, count2; UErrorCode errorCode; errorCode=U_ZERO_ERROR; uenum=utrans_openIDs(&errorCode); if(U_FAILURE(errorCode)) { log_err("utrans_openIDs() failed - %s\n", u_errorName(errorCode)); return; } count=uenum_count(uenum, &errorCode); if(U_FAILURE(errorCode) || count<1) { log_err("uenum_count(transliterator IDs)=%d - %s\n", count, u_errorName(errorCode)); } count=0; for(;;) { id=uenum_unext(uenum, &idLength, &errorCode); if(U_FAILURE(errorCode)) { log_err("uenum_unext(transliterator ID %d) failed - %s\n", count, u_errorName(errorCode)); break; } if(id==NULL) { break; } if(++count>10) { /* try to actually open only a few transliterators */ continue; } utrans=utrans_openU(id, idLength, UTRANS_FORWARD, NULL, 0, NULL, &errorCode); if(U_FAILURE(errorCode)) { log_err("utrans_openU(%s) failed - %s\n", aescstrdup(id, idLength), u_errorName(errorCode)); continue; } id2=utrans_getUnicodeID(utrans, &id2Length); if(idLength!=id2Length || 0!=u_memcmp(id, id2, idLength)) { log_err("utrans_getUnicodeID(%s) does not match the original ID\n", aescstrdup(id, idLength)); } utrans_close(utrans); } uenum_reset(uenum, &errorCode); if(U_FAILURE(errorCode) || count<1) { log_err("uenum_reset(transliterator IDs) failed - %s\n", u_errorName(errorCode)); } else { count2=uenum_count(uenum, &errorCode); if(U_FAILURE(errorCode) || count<1) { log_err("2nd uenum_count(transliterator IDs)=%d - %s\n", count2, u_errorName(errorCode)); } else if(count!=count2) { log_err("uenum_unext(transliterator IDs) returned %d IDs but uenum_count() after uenum_reset() claims there are %d\n", count, count2); } } uenum_close(uenum); }
static inline UTransliterator *utrans_find(CFStringRef transform, UTransDirection dir, UErrorCode *error) { UEnumeration *uenum = NULL; UTransliterator *trans = NULL; do { uenum = utrans_openIDs(error); if (U_FAILURE(*error)) { DEBUG_LOG("%s", u_errorName(*error)); break; } int32_t count = uenum_count(uenum, error); if (U_FAILURE(*error)) { DEBUG_LOG("%s", u_errorName(*error)); break; } int32_t trans_idx = 0; while (trans_idx < count && trans == NULL) { int32_t idLen = 0; const UChar *uid = uenum_unext(uenum, &idLen, error); if (U_FAILURE(*error)) { DEBUG_LOG("%s", u_errorName(*error)); break; } // this seems rather unlikely since we should have already broken // by the trans_idx exceeding the count if (uid == NULL) { break; } CFStringRef name = CFStringCreateWithCharactersNoCopy(kCFAllocatorDefault, uid, idLen, kCFAllocatorNull); // It would have been nice if these stirng constants were actually defined somewhere in icu, but sadly they are runtime metadata... if ((CFEqual(name, CFSTR("Any-Remove")) && CFEqual(transform, kCFStringTransformStripCombiningMarks)) || (CFEqual(name, CFSTR("Any-Latin")) && CFEqual(transform, kCFStringTransformToLatin)) || (CFEqual(name, CFSTR("Latin-Katakana")) && CFEqual(transform, kCFStringTransformLatinKatakana)) || (CFEqual(name, CFSTR("Latin-Hiragana")) && CFEqual(transform, kCFStringTransformLatinHiragana)) || (CFEqual(name, CFSTR("Hiragana-Katakana")) && CFEqual(transform, kCFStringTransformHiraganaKatakana)) || (CFEqual(name, CFSTR("Latin-Hangul")) && CFEqual(transform, kCFStringTransformLatinHangul)) || (CFEqual(name, CFSTR("Latin-Arabic")) && CFEqual(transform, kCFStringTransformLatinArabic)) || (CFEqual(name, CFSTR("Latin-Hebrew")) && CFEqual(transform, kCFStringTransformLatinHebrew)) || (CFEqual(name, CFSTR("Latin-Thai")) && CFEqual(transform, kCFStringTransformLatinThai)) || (CFEqual(name, CFSTR("Latin-Cyrillic")) && CFEqual(transform, kCFStringTransformLatinCyrillic)) || (CFEqual(name, CFSTR("Latin-Greek")) && CFEqual(transform, kCFStringTransformLatinGreek)) || (CFEqual(name, CFSTR("Any-Hex/XML")) && CFEqual(transform, kCFStringTransformToXMLHex)) || (CFEqual(name, CFSTR("Any-Name")) && CFEqual(transform, kCFStringTransformToUnicodeName)) || (CFEqual(name, CFSTR("Accents-Any")) && CFEqual(transform, kCFStringTransformStripDiacritics))) { trans = utrans_openU(uid, idLen, dir, NULL, 0, NULL, error); } CFRelease(name); trans_idx++; } } while (0); if (uenum != NULL) { uenum_reset(uenum, error); uenum_close(uenum); } if (trans == NULL && (CFEqual(transform, kCFStringTransformStripCombiningMarks) || CFEqual(transform, kCFStringTransformToLatin) || CFEqual(transform, kCFStringTransformLatinKatakana) || CFEqual(transform, kCFStringTransformLatinHiragana) || CFEqual(transform, kCFStringTransformHiraganaKatakana) || CFEqual(transform, kCFStringTransformLatinHangul) || CFEqual(transform, kCFStringTransformLatinArabic) || CFEqual(transform, kCFStringTransformLatinHebrew) || CFEqual(transform, kCFStringTransformLatinCyrillic) || CFEqual(transform, kCFStringTransformLatinGreek) || CFEqual(transform, kCFStringTransformToXMLHex) || CFEqual(transform, kCFStringTransformToUnicodeName) || CFEqual(transform, kCFStringTransformStripDiacritics))) { static dispatch_once_t once = 0L; dispatch_once(&once, ^{ RELEASE_LOG("Unable to find transliterators in icu data: likely this is from not including the Transliterators section in building your icu.dat file"); }); }
static void verifyEnumeration(int line, UEnumeration *u, const char * const * compareToChar, const UChar * const * compareToUChar, int32_t expect_count) { UErrorCode status = U_ZERO_ERROR; int32_t got_count,i,len; const char *c; UChar buf[1024]; log_verbose("%s:%d: verifying enumeration..\n", __FILE__, line); uenum_reset(u, &status); if(U_FAILURE(status)) { log_err("%s:%d: FAIL: could not reset char strings enumeration: %s\n", __FILE__, line, u_errorName(status)); return; } got_count = uenum_count(u, &status); if(U_FAILURE(status)) { log_err("%s:%d: FAIL: could not count char strings enumeration: %s\n", __FILE__, line, u_errorName(status)); return; } if(got_count!=expect_count) { log_err("%s:%d: FAIL: expect count %d got %d\n", __FILE__, line, expect_count, got_count); } else { log_verbose("%s:%d: OK: got count %d\n", __FILE__, line, got_count); } if(compareToChar!=NULL) { /* else, not invariant */ for(i=0;i<got_count;i++) { c = uenum_next(u,&len, &status); if(U_FAILURE(status)) { log_err("%s:%d: FAIL: could not iterate to next after %d: %s\n", __FILE__, line, i, u_errorName(status)); return; } if(c==NULL) { log_err("%s:%d: FAIL: got NULL for next after %d: %s\n", __FILE__, line, i, u_errorName(status)); return; } if(strcmp(c,compareToChar[i])) { log_err("%s:%d: FAIL: string #%d expected '%s' got '%s'\n", __FILE__, line, i, compareToChar[i], c); } else { log_verbose("%s:%d: OK: string #%d got '%s'\n", __FILE__, line, i, c); } if(len!=strlen(compareToChar[i])) { log_err("%s:%d: FAIL: string #%d expected len %d got %d\n", __FILE__, line, i, strlen(compareToChar[i]), len); } else { log_verbose("%s:%d: OK: string #%d got len %d\n", __FILE__, line, i, len); } } } /* now try U */ uenum_reset(u, &status); if(U_FAILURE(status)) { log_err("%s:%d: FAIL: could not reset again char strings enumeration: %s\n", __FILE__, line, u_errorName(status)); return; } for(i=0;i<got_count;i++) { const UChar *ustr = uenum_unext(u,&len, &status); if(U_FAILURE(status)) { log_err("%s:%d: FAIL: could not iterate to unext after %d: %s\n", __FILE__, line, i, u_errorName(status)); return; } if(ustr==NULL) { log_err("%s:%d: FAIL: got NULL for unext after %d: %s\n", __FILE__, line, i, u_errorName(status)); return; } if(compareToChar!=NULL) { u_charsToUChars(compareToChar[i], buf, strlen(compareToChar[i])+1); if(u_strncmp(ustr,buf,len)) { int j; log_err("%s:%d: FAIL: ustring #%d expected '%s' got '%s'\n", __FILE__, line, i, compareToChar[i], austrdup(ustr)); for(j=0;ustr[j]&&buf[j];j++) { log_verbose(" @ %d\t<U+%04X> vs <U+%04X>\n", j, ustr[j],buf[j]); } } else { log_verbose("%s:%d: OK: ustring #%d got '%s'\n", __FILE__, line, i, compareToChar[i]); } if(len!=strlen(compareToChar[i])) { log_err("%s:%d: FAIL: ustring #%d expected len %d got %d\n", __FILE__, line, i, strlen(compareToChar[i]), len); } else { log_verbose("%s:%d: OK: ustring #%d got len %d\n", __FILE__, line, i, len); } } if(compareToUChar!=NULL) { if(u_strcmp(ustr,compareToUChar[i])) { int j; log_err("%s:%d: FAIL: ustring #%d expected '%s' got '%s'\n", __FILE__, line, i, austrdup(compareToUChar[i]), austrdup(ustr)); for(j=0;ustr[j]&&compareToUChar[j];j++) { log_verbose(" @ %d\t<U+%04X> vs <U+%04X>\n", j, ustr[j],compareToUChar[j]); } } else { log_verbose("%s:%d: OK: ustring #%d got '%s'\n", __FILE__, line, i, austrdup(compareToUChar[i])); } if(len!=u_strlen(compareToUChar[i])) { log_err("%s:%d: FAIL: ustring #%d expected len %d got %d\n", __FILE__, line, i, u_strlen(compareToUChar[i]), len); } else { log_verbose("%s:%d: OK: ustring #%d got len %d\n", __FILE__, line, i, len); } } } }
U_CAPI int32_t U_EXPORT2 uloc_getDisplayName(const char * locale, const char * displayLocale, UChar * dest, int32_t destCapacity, UErrorCode * pErrorCode) { int32_t length, length2, length3 = 0; UBool hasLanguage, hasScript, hasCountry, hasVariant, hasKeywords; UEnumeration * keywordEnum = NULL; int32_t keywordCount = 0; const char * keyword = NULL; int32_t keywordLen = 0; char keywordValue[256]; int32_t keywordValueLen = 0; int32_t locSepLen = 0; int32_t locPatLen = 0; int32_t p0Len = 0; int32_t defaultPatternLen = 9; const UChar * dispLocSeparator; const UChar * dispLocPattern; static const UChar defaultSeparator[3] = { 0x002c, 0x0020 , 0x0000 }; /* comma + space */ static const UChar defaultPattern[10] = { 0x007b, 0x0030, 0x007d, 0x0020, 0x0028, 0x007b, 0x0031, 0x007d, 0x0029, 0x0000 }; /* {0} ({1}) */ static const UChar pat0[4] = { 0x007b, 0x0030, 0x007d , 0x0000 } ; /* {0} */ static const UChar pat1[4] = { 0x007b, 0x0031, 0x007d , 0x0000 } ; /* {1} */ UResourceBundle * bundle = NULL; UResourceBundle * locdsppat = NULL; UErrorCode status = U_ZERO_ERROR; /* argument checking */ if (pErrorCode == NULL || U_FAILURE(*pErrorCode)) { return 0; } if (destCapacity < 0 || (destCapacity > 0 && dest == NULL)) { *pErrorCode = U_ILLEGAL_ARGUMENT_ERROR; return 0; } bundle = ures_open(U_ICUDATA_LANG, displayLocale, &status); locdsppat = ures_getByKeyWithFallback(bundle, _kLocaleDisplayPattern, NULL, &status); dispLocSeparator = ures_getStringByKeyWithFallback(locdsppat, _kSeparator, &locSepLen, &status); dispLocPattern = ures_getStringByKeyWithFallback(locdsppat, _kPattern, &locPatLen, &status); /*close the bundles */ ures_close(locdsppat); ures_close(bundle); /* If we couldn't find any data, then use the defaults */ if (locSepLen == 0) { dispLocSeparator = defaultSeparator; locSepLen = 2; } if (locPatLen == 0) { dispLocPattern = defaultPattern; locPatLen = 9; } /* * if there is a language, then write "language (country, variant)" * otherwise write "country, variant" */ /* write the language */ length = uloc_getDisplayLanguage(locale, displayLocale, dest, destCapacity, pErrorCode); hasLanguage = length > 0; if (hasLanguage) { p0Len = length; /* append " (" */ if (length < destCapacity) { dest[length] = 0x20; } ++length; if (length < destCapacity) { dest[length] = 0x28; } ++length; } if (*pErrorCode == U_BUFFER_OVERFLOW_ERROR) { /* keep preflighting */ *pErrorCode = U_ZERO_ERROR; } /* append the script */ if (length < destCapacity) { length2 = uloc_getDisplayScript(locale, displayLocale, dest + length, destCapacity - length, pErrorCode); } else { length2 = uloc_getDisplayScript(locale, displayLocale, NULL, 0, pErrorCode); } hasScript = length2 > 0; length += length2; if (hasScript) { /* append separator */ if (length + locSepLen <= destCapacity) { u_memcpy(dest + length, dispLocSeparator, locSepLen); } length += locSepLen; } if (*pErrorCode == U_BUFFER_OVERFLOW_ERROR) { /* keep preflighting */ *pErrorCode = U_ZERO_ERROR; } /* append the country */ if (length < destCapacity) { length2 = uloc_getDisplayCountry(locale, displayLocale, dest + length, destCapacity - length, pErrorCode); } else { length2 = uloc_getDisplayCountry(locale, displayLocale, NULL, 0, pErrorCode); } hasCountry = length2 > 0; length += length2; if (hasCountry) { /* append separator */ if (length + locSepLen <= destCapacity) { u_memcpy(dest + length, dispLocSeparator, locSepLen); } length += locSepLen; } if (*pErrorCode == U_BUFFER_OVERFLOW_ERROR) { /* keep preflighting */ *pErrorCode = U_ZERO_ERROR; } /* append the variant */ if (length < destCapacity) { length2 = uloc_getDisplayVariant(locale, displayLocale, dest + length, destCapacity - length, pErrorCode); } else { length2 = uloc_getDisplayVariant(locale, displayLocale, NULL, 0, pErrorCode); } hasVariant = length2 > 0; length += length2; if (hasVariant) { /* append separator */ if (length + locSepLen <= destCapacity) { u_memcpy(dest + length, dispLocSeparator, locSepLen); } length += locSepLen; } keywordEnum = uloc_openKeywords(locale, pErrorCode); for (keywordCount = uenum_count(keywordEnum, pErrorCode); keywordCount > 0 ; keywordCount--) { if (U_FAILURE(*pErrorCode)) { break; } /* the uenum_next returns NUL terminated string */ keyword = uenum_next(keywordEnum, &keywordLen, pErrorCode); if (length + length3 < destCapacity) { length3 += uloc_getDisplayKeyword(keyword, displayLocale, dest + length + length3, destCapacity - length - length3, pErrorCode); } else { length3 += uloc_getDisplayKeyword(keyword, displayLocale, NULL, 0, pErrorCode); } if (*pErrorCode == U_BUFFER_OVERFLOW_ERROR) { /* keep preflighting */ *pErrorCode = U_ZERO_ERROR; } keywordValueLen = uloc_getKeywordValue(locale, keyword, keywordValue, 256, pErrorCode); if (keywordValueLen) { if (length + length3 < destCapacity) { dest[length + length3] = 0x3D; } length3++; if (length + length3 < destCapacity) { length3 += uloc_getDisplayKeywordValue(locale, keyword, displayLocale, dest + length + length3, destCapacity - length - length3, pErrorCode); } else { length3 += uloc_getDisplayKeywordValue(locale, keyword, displayLocale, NULL, 0, pErrorCode); } if (*pErrorCode == U_BUFFER_OVERFLOW_ERROR) { /* keep preflighting */ *pErrorCode = U_ZERO_ERROR; } } if (keywordCount > 1) { if (length + length3 + locSepLen <= destCapacity && keywordCount) { u_memcpy(dest + length + length3, dispLocSeparator, locSepLen); length3 += locSepLen; } } } uenum_close(keywordEnum); hasKeywords = length3 > 0; length += length3; if ((hasScript && !hasCountry) || ((hasScript || hasCountry) && !hasVariant && !hasKeywords) || ((hasScript || hasCountry || hasVariant) && !hasKeywords)) { /* Remove separator */ length -= locSepLen; } else if (hasLanguage && !hasScript && !hasCountry && !hasVariant && !hasKeywords) { /* Remove " (" */ length -= 2; } if (hasLanguage && (hasScript || hasCountry || hasVariant || hasKeywords)) { /* append ")" */ if (length < destCapacity) { dest[length] = 0x29; } ++length; /* If the localized display pattern is something other than the default pattern of "{0} ({1})", then * then we need to do the formatting here. It would be easier to use a messageFormat to do this, but we * can't since we don't have the APIs in the i18n library available to us at this point. */ if (locPatLen != defaultPatternLen || u_strcmp(dispLocPattern, defaultPattern)) /* Something other than the default pattern */ { UChar * p0 = u_strstr(dispLocPattern, pat0); UChar * p1 = u_strstr(dispLocPattern, pat1); u_terminateUChars(dest, destCapacity, length, pErrorCode); if (p0 != NULL && p1 != NULL) /* The pattern is well formed */ { if (dest) { int32_t destLen = 0; UChar * result = (UChar *)uprv_malloc((length + 1) * sizeof(UChar)); UChar * upos = (UChar *)dispLocPattern; u_strcpy(result, dest); dest[0] = 0; while (*upos) { if (upos == p0) /* Handle {0} substitution */ { u_strncat(dest, result, p0Len); destLen += p0Len; dest[destLen] = 0; /* Null terminate */ upos += 3; } else if (upos == p1) /* Handle {1} substitution */ { UChar * p1Start = &result[p0Len + 2]; u_strncat(dest, p1Start, length - p0Len - 3); destLen += (length - p0Len - 3); dest[destLen] = 0; /* Null terminate */ upos += 3; } else /* Something from the pattern not {0} or {1} */ { u_strncat(dest, upos, 1); upos++; destLen++; dest[destLen] = 0; /* Null terminate */ } } length = destLen; uprv_free(result); } } } } if (*pErrorCode == U_BUFFER_OVERFLOW_ERROR) { /* keep preflighting */ *pErrorCode = U_ZERO_ERROR; } return u_terminateUChars(dest, destCapacity, length, pErrorCode); }