static void TestJ5298(void) { UErrorCode status = U_ZERO_ERROR; char input[256], output[256]; UBool isAvailable; int32_t i = 0; UEnumeration* values = NULL; const char *keywordValue = NULL; log_verbose("Number of collator locales returned : %i \n", ucol_countAvailable()); values = ucol_getKeywordValues("collation", &status); while ((keywordValue = uenum_next(values, NULL, &status)) != NULL) { if (strncmp(keywordValue, "private-", 8) == 0) { log_err("ucol_getKeywordValues() returns private collation keyword: %s\n", keywordValue); } } for (i = 0; i < ucol_countAvailable(); i++) { uenum_reset(values, &status); while ((keywordValue = uenum_next(values, NULL, &status)) != NULL) { strcpy(input, ucol_getAvailable(i)); if (strcmp(keywordValue, "standard") != 0) { strcat(input, "@collation="); strcat(input, keywordValue); } ucol_getFunctionalEquivalent(output, 256, "collation", input, &isAvailable, &status); if (strcmp(input, output) == 0) { /* Unique locale, print it out */ log_verbose("%s, \n", output); } } } uenum_close(values); log_verbose("\n"); }
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; }
// Convert a uenum to a QList<QByteArray> static QSet<QByteArray> uenumToIdSet(UEnumeration *uenum) { QSet<QByteArray> set; int32_t size = 0; UErrorCode status = U_ZERO_ERROR; // TODO Perhaps use uenum_unext instead? QByteArray result = uenum_next(uenum, &size, &status); while (U_SUCCESS(status) && !result.isEmpty()) { set << result; status = U_ZERO_ERROR; result = uenum_next(uenum, &size, &status); } return set; }
/* 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; }
static Vector<String> localeData(const String& locale, size_t keyIndex) { Vector<String> keyLocaleData; switch (keyIndex) { case indexOfExtensionKeyCa: { UErrorCode status = U_ZERO_ERROR; UEnumeration* calendars = ucal_getKeywordValuesForLocale("calendar", locale.utf8().data(), false, &status); ASSERT(U_SUCCESS(status)); int32_t nameLength; while (const char* availableName = uenum_next(calendars, &nameLength, &status)) { ASSERT(U_SUCCESS(status)); String calendar = String(availableName, nameLength); keyLocaleData.append(calendar); // Ensure aliases used in language tag are allowed. if (calendar == "gregorian") keyLocaleData.append(ASCIILiteral("gregory")); else if (calendar == "islamic-civil") keyLocaleData.append(ASCIILiteral("islamicc")); else if (calendar == "ethiopic-amete-alem") keyLocaleData.append(ASCIILiteral("ethioaa")); } uenum_close(calendars); break; } case indexOfExtensionKeyNu: keyLocaleData = numberingSystemsForLocale(locale); break; default: ASSERT_NOT_REACHED(); } return keyLocaleData; }
/** * Convert an ICU enum to a list of atoms. * Used by some C++ code, when we need to extract the list of locales. * Used by i18n_trans. */ ERL_NIF_TERM enum_to_term(ErlNifEnv* env, UEnumeration* en) { ERL_NIF_TERM head, tail; UErrorCode status = U_ZERO_ERROR; const char* buf; int32_t len; uenum_reset(en, &status); CHECK(env, status); tail = enif_make_list(env, 0); while (true) { buf = uenum_next(en, &len, &status); CHECK(env, status); if (buf == NULL) return tail; if (len > 255) ERROR_STRING(env, "too_long_enum_element"); head = enif_make_atom(env, buf); tail = enif_make_list_cell(env, head, tail); } }
/* * 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 Array HHVM_STATIC_METHOD(Locale, getKeywords, const String& locale) { UErrorCode error = U_ZERO_ERROR; String locname = localeOrDefault(locale); UEnumeration *e = uloc_openKeywords(locname.c_str(), &error); if (!e) return null_array; Array ret = Array::Create(); const char *key; int key_len; String val(128, ReserveString); char *ptr = val->mutableData(); error = U_ZERO_ERROR; while ((key = uenum_next(e, &key_len, &error))) { tryagain: error = U_ZERO_ERROR; int val_len = uloc_getKeywordValue(locname.c_str(), key, ptr, val->capacity(), &error); if (error == U_BUFFER_OVERFLOW_ERROR) { val = String(val_len + 128, ReserveString); ptr = val->mutableData(); goto tryagain; } if (U_FAILURE(error)) { s_intl_error->setError(error, "locale_get_keywords: Error encountered " "while getting the keyword value for the " " keyword"); return null_array; } ret.set(String(key, key_len, CopyString), String(ptr, val_len, CopyString)); } return ret; }
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 void TestGetContainedRegionsWithType() { const KnownRegion * rd; for (rd = knownRegions; rd->code != NULL ; rd++ ) { UErrorCode status = U_ZERO_ERROR; const URegion *r = uregion_getRegionFromCode(rd->code, &status); if ( U_SUCCESS(status) ) { UEnumeration *containedRegions; const char *crID; if (uregion_getType(r) != URGN_CONTINENT) { continue; } containedRegions = uregion_getContainedRegionsOfType(r, URGN_TERRITORY, &status); if (containedRegions) { while ((crID = uenum_next(containedRegions, NULL, &status)) != NULL && U_SUCCESS(status) ) { const URegion *cr = uregion_getRegionFromCode(crID, &status); const URegion *containingRegion = (cr)? uregion_getContainingRegionOfType(cr, URGN_CONTINENT) : NULL; if ( !containingRegion || !uregion_areEqual(containingRegion, r) ) { log_err("ERROR: Continent: %s contains territory %s. Expected containing continent of this region to be the original region, but got %s\n", uregion_getRegionCode(r), uregion_getRegionCode(cr), (containingRegion)?uregion_getRegionCode(containingRegion):"NULL" ); } } uenum_close(containedRegions); } } else { log_data_err("ERROR: Known region %s was not recognized.\n", rd->code); } } }
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); }
static void TestEnumListReset(void) { UErrorCode status = U_ZERO_ERROR; const char *currency1; const char *currency2; UEnumeration *en = ucurr_openISOCurrencies(UCURR_ALL, &status); if (U_FAILURE(status)) { log_err("Error: ucurr_openISOCurrencies returned %s\n", myErrorName(status)); return; } currency1 = uenum_next(en, NULL, &status); uenum_reset(en, &status); currency2 = uenum_next(en, NULL, &status); if (U_FAILURE(status)) { log_err("Error: uenum_next or uenum_reset returned %s\n", myErrorName(status)); return; } /* The first item's pointer in the list should be the same between resets. */ if (currency1 != currency2) { log_err("Error: reset doesn't work %s != %s\n", currency1, currency2); } uenum_close(en); }
virtual const char* next(int32_t *resultLength, UErrorCode &status) { int32_t length = -1; const char* str = uenum_next(uenum, &length, &status); if (str == 0 || U_FAILURE(status)) { return 0; } if (resultLength) { //the bug is that uenum_next doesn't set the length *resultLength = (length == -1) ? strlen(str) : length; } return str; }
JSObject* IntlPluralRules::resolvedOptions(ExecState& exec) { VM& vm = exec.vm(); auto scope = DECLARE_THROW_SCOPE(vm); // 13.4.4 Intl.PluralRules.prototype.resolvedOptions () // https://tc39.github.io/ecma402/#sec-intl.pluralrules.prototype.resolvedoptions if (UNLIKELY(!m_initializedPluralRules)) { throwTypeError(&exec, scope, "Intl.PluralRules.prototype.resolvedOptions called on value that's not an object initialized as a PluralRules"_s); return nullptr; } JSObject* options = constructEmptyObject(&exec); options->putDirect(vm, vm.propertyNames->locale, jsNontrivialString(&exec, m_locale)); options->putDirect(vm, Identifier::fromString(&vm, "type"), jsNontrivialString(&exec, m_type == UPLURAL_TYPE_ORDINAL ? "ordinal"_s : "cardinal"_s)); options->putDirect(vm, Identifier::fromString(&vm, "minimumIntegerDigits"), jsNumber(m_minimumIntegerDigits)); options->putDirect(vm, Identifier::fromString(&vm, "minimumFractionDigits"), jsNumber(m_minimumFractionDigits)); options->putDirect(vm, Identifier::fromString(&vm, "maximumFractionDigits"), jsNumber(m_maximumFractionDigits)); if (m_minimumSignificantDigits) { options->putDirect(vm, Identifier::fromString(&vm, "minimumSignificantDigits"), jsNumber(m_minimumSignificantDigits.value())); options->putDirect(vm, Identifier::fromString(&vm, "maximumSignificantDigits"), jsNumber(m_maximumSignificantDigits.value())); } #if HAVE(ICU_PLURALRULES_KEYWORDS) JSGlobalObject* globalObject = exec.jsCallee()->globalObject(vm); JSArray* categories = JSArray::tryCreate(vm, globalObject->arrayStructureForIndexingTypeDuringAllocation(ArrayWithContiguous), 0); if (UNLIKELY(!categories)) { throwOutOfMemoryError(&exec, scope); return nullptr; } UErrorCode status = U_ZERO_ERROR; auto keywords = std::unique_ptr<UEnumeration, UEnumerationDeleter>(uplrules_getKeywords(m_pluralRules.get(), &status)); ASSERT(U_SUCCESS(status)); int32_t resultLength; // Category names are always ASCII, so use char[]. unsigned index = 0; while (const char* result = uenum_next(keywords.get(), &resultLength, &status)) { ASSERT(U_SUCCESS(status)); categories->putDirectIndex(&exec, index++, jsNontrivialString(&exec, String(result, resultLength))); RETURN_IF_EXCEPTION(scope, { }); } options->putDirect(vm, Identifier::fromString(&vm, "pluralCategories"), categories); #endif RELEASE_AND_RETURN(scope, options); }
static void EnumerationTest(void) { UErrorCode status = U_ZERO_ERROR; int32_t len = 0; UEnumeration *en = getchArrayEnum(test1, sizeof(test1)/sizeof(test1[0])); const char *string = NULL; const UChar *uString = NULL; while ((string = uenum_next(en, &len, &status))) { log_verbose("read \"%s\", length %i\n", string, len); } uenum_reset(en, &status); while ((uString = uenum_unext(en, &len, &status))) { log_verbose("read \"%s\" (UChar), length %i\n", quikU2C(uString, len), len); } uenum_close(en); }
static Vector<String> sortLocaleData(const String& locale, size_t keyIndex) { // 9.1 Internal slots of Service Constructors & 10.2.3 Internal slots (ECMA-402 2.0) Vector<String> keyLocaleData; switch (keyIndex) { case indexOfExtensionKeyCo: { // 10.2.3 "The first element of [[sortLocaleData]][locale].co and [[searchLocaleData]][locale].co must be null for all locale values." keyLocaleData.append({ }); UErrorCode status = U_ZERO_ERROR; UEnumeration* enumeration = ucol_getKeywordValuesForLocale("collation", locale.utf8().data(), false, &status); if (U_SUCCESS(status)) { const char* collation; while ((collation = uenum_next(enumeration, nullptr, &status)) && U_SUCCESS(status)) { // 10.2.3 "The values "standard" and "search" must not be used as elements in any [[sortLocaleData]][locale].co and [[searchLocaleData]][locale].co array." if (!strcmp(collation, "standard") || !strcmp(collation, "search")) continue; // Map keyword values to BCP 47 equivalents. if (!strcmp(collation, "dictionary")) collation = "dict"; else if (!strcmp(collation, "gb2312han")) collation = "gb2312"; else if (!strcmp(collation, "phonebook")) collation = "phonebk"; else if (!strcmp(collation, "traditional")) collation = "trad"; keyLocaleData.append(collation); } uenum_close(enumeration); } break; } case indexOfExtensionKeyKn: keyLocaleData.reserveInitialCapacity(2); keyLocaleData.uncheckedAppend(ASCIILiteral("false")); keyLocaleData.uncheckedAppend(ASCIILiteral("true")); break; default: ASSERT_NOT_REACHED(); } return keyLocaleData; }
bool PaymentRequestValidator::validateCurrencyCode(const String& currencyCode) const { if (!currencyCode) { m_window.printErrorMessage("Missing currency code."); return false; } UErrorCode errorCode = U_ZERO_ERROR; auto currencyCodes = std::unique_ptr<UEnumeration, void (*)(UEnumeration*)>(ucurr_openISOCurrencies(UCURR_ALL, &errorCode), uenum_close); int32_t length; while (auto *currencyCodePtr = uenum_next(currencyCodes.get(), &length, &errorCode)) { if (currencyCodePtr == currencyCode) return true; } auto message = makeString("\"" + currencyCode, "\" is not a valid currency code."); m_window.printErrorMessage(message); return false; }
/* closes res but does not free resultsManually */ static void verifyResult(UEnumeration* res, const UBool *resultsManually) { UBool* resultsFromSystem = (UBool*) uprv_malloc(gCountAvailable * sizeof(UBool)); const char* name; UErrorCode status = U_ZERO_ERROR; int32_t i; /* fill the bool for the selector results! */ uprv_memset(resultsFromSystem, 0, gCountAvailable); while ((name = uenum_next(res,NULL, &status)) != NULL) { resultsFromSystem[findIndex(name)] = TRUE; } for(i = 0 ; i < gCountAvailable; i++) { if(resultsManually[i] != resultsFromSystem[i]) { log_err("failure in converter selector\n" "converter %s had conflicting results -- manual: %d, system %d\n", gAvailableNames[i], resultsManually[i], resultsFromSystem[i]); } } uprv_free(resultsFromSystem); uenum_close(res); }
static Vector<String> sortLocaleData(const String& locale, const String& key) { // 9.1 Internal slots of Service Constructors & 10.2.3 Internal slots (ECMA-402 2.0) Vector<String> keyLocaleData; if (key == "co") { // 10.2.3 "The first element of [[sortLocaleData]][locale].co and [[searchLocaleData]][locale].co must be null for all locale values." keyLocaleData.append(String()); UErrorCode status = U_ZERO_ERROR; UEnumeration* enumeration = ucol_getKeywordValuesForLocale("collation", locale.utf8().data(), TRUE, &status); if (U_SUCCESS(status)) { const char* keywordValue; while ((keywordValue = uenum_next(enumeration, nullptr, &status)) && U_SUCCESS(status)) { String collation(keywordValue); // 10.2.3 "The values "standard" and "search" must not be used as elements in any [[sortLocaleData]][locale].co and [[searchLocaleData]][locale].co array." if (collation == "standard" || collation == "search") continue; // Map keyword values to BCP 47 equivalents. if (collation == "dictionary") collation = ASCIILiteral("dict"); else if (collation == "gb2312han") collation = ASCIILiteral("gb2312"); else if (collation == "phonebook") collation = ASCIILiteral("phonebk"); else if (collation == "traditional") collation = ASCIILiteral("trad"); keyLocaleData.append(collation); } uenum_close(enumeration); } } else if (key == "kn") { keyLocaleData.append(ASCIILiteral("false")); keyLocaleData.append(ASCIILiteral("true")); } else ASSERT_NOT_REACHED(); return keyLocaleData; }
/* * call-seq: * detectable_charsets * * Get array of names of all detectable charsets that are known to the charset detection service. */ static VALUE UCharsetDetector_get_detectable_charsets(VALUE self) { UCharsetDetector *detector; Data_Get_Struct(self, UCharsetDetector, detector); UErrorCode status = U_ZERO_ERROR; UEnumeration *charsets = ucsdet_getAllDetectableCharsets(detector, &status); ensure(status); VALUE ary = rb_ary_new(); int32_t result_length; const char *charset_name; while (charset_name = uenum_next(charsets, &result_length, &status)) { ensure(status); rb_ary_push(ary, rb_str_new2(charset_name)); } uenum_close(charsets); return ary; }
static void DefaultNextTest(void) { UErrorCode status = U_ZERO_ERROR; int32_t len = 0; UEnumeration *en = getuchArrayEnum(test2, sizeof(test2)/sizeof(test2[0])); const char *string = NULL; const UChar *uString = NULL; while ((uString = uenum_unext(en, &len, &status))) { log_verbose("read \"%s\" (UChar), length %i\n", quikU2C(uString, len), len); } if (U_FAILURE(status)) { log_err("FAIL: uenum_unext => %s\n", u_errorName(status)); } uenum_reset(en, &status); while ((string = uenum_next(en, &len, &status))) { log_verbose("read \"%s\", length %i\n", string, len); } if (U_FAILURE(status)) { log_err("FAIL: uenum_next => %s\n", u_errorName(status)); } uenum_close(en); }
static void expectInList(const char *isoCurrency, uint32_t currencyType, UBool isExpected) { UErrorCode status = U_ZERO_ERROR; const char *foundCurrency = NULL; const char *currentCurrency; UEnumeration *en = ucurr_openISOCurrencies(currencyType, &status); if (U_FAILURE(status)) { log_err("Error: ucurr_openISOCurrencies returned %s\n", myErrorName(status)); return; } while ((currentCurrency = uenum_next(en, NULL, &status)) != NULL) { if (strcmp(isoCurrency, currentCurrency) == 0) { foundCurrency = currentCurrency; break; } } if ((foundCurrency != NULL) != isExpected) { log_err("Error: could not find %s as expected. isExpected = %s type=0x%X\n", isoCurrency, isExpected ? "TRUE" : "FALSE", currencyType); } uenum_close(en); }
static Variant HHVM_STATIC_METHOD(ResourceBundle, getLocales, const String& bundleName) { UErrorCode error = U_ZERO_ERROR; auto le = ures_openAvailableLocales(bundleName.c_str(), &error); if (U_FAILURE(error)) { s_intl_error->setError(error, "Cannot fetch locales list"); return false; } error = U_ZERO_ERROR; uenum_reset(le, &error); if (U_FAILURE(error)) { s_intl_error->setError(error, "Cannot iterate locales list"); return false; } Array ret = Array::Create(); const char *entry; int32_t entry_len; while ((entry = uenum_next(le, &entry_len, &error))) { ret.append(String(entry, entry_len, CopyString)); } return ret; }
static void TestGetPreferredValues() { const char *** testDataPtr = expectPrefRegionsTestData; const char ** regionListPtr; while ( (regionListPtr = *testDataPtr++) != NULL ) { UErrorCode status = U_ZERO_ERROR; const char * deprecatedCode = *regionListPtr++; const URegion *r = uregion_getRegionFromCode(deprecatedCode, &status); if ( U_SUCCESS(status) ) { UEnumeration *preferredRegions = uregion_getPreferredValues(r, &status); if ( U_SUCCESS(status) ) { if (preferredRegions != NULL) { const char * preferredCode; while ( (preferredCode = *regionListPtr++) != NULL ) { const char *check; UBool found = FALSE; uenum_reset(preferredRegions, &status); while ((check = uenum_next(preferredRegions, NULL, &status)) != NULL && U_SUCCESS(status) ) { if ( !uprv_strcmp(check,preferredCode) ) { found = TRUE; break; } } if ( !found ) { log_err("ERROR: uregion_getPreferredValues for region \"%s\" should have contained \"%s\" but it didn't.\n", uregion_getRegionCode(r), preferredCode); } } uenum_close(preferredRegions); } } else { log_err("ERROR: uregion_getPreferredValues failed for region %s.\n", uregion_getRegionCode(r)); } } else { log_data_err("ERROR: Known region %s was not recognized.\n", deprecatedCode); } } }
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 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); } } } }
/* Instead of having a separate pass for 'special' patterns, reintegrate the two * so we don't get bitten by preflight bugs again. We can be reasonably efficient * without two separate code paths, this code isn't that performance-critical. * * This code is general enough to deal with patterns that have a prefix or swap the * language and remainder components, since we gave developers enough rope to do such * things if they futz with the pattern data. But since we don't give them a way to * specify a pattern for arbitrary combinations of components, there's not much use in * that. I don't think our data includes such patterns, the only variable I know if is * whether there is a space before the open paren, or not. Oh, and zh uses different * chars than the standard open/close paren (which ja and ko use, btw). */ U_CAPI int32_t U_EXPORT2 uloc_getDisplayName(const char *locale, const char *displayLocale, UChar *dest, int32_t destCapacity, UErrorCode *pErrorCode) { static const UChar defaultSeparator[9] = { 0x007b, 0x0030, 0x007d, 0x002c, 0x0020, 0x007b, 0x0031, 0x007d, 0x0000 }; /* "{0}, {1}" */ static const UChar sub0[4] = { 0x007b, 0x0030, 0x007d , 0x0000 } ; /* {0} */ static const UChar sub1[4] = { 0x007b, 0x0031, 0x007d , 0x0000 } ; /* {1} */ static const int32_t subLen = 3; static const UChar defaultPattern[10] = { 0x007b, 0x0030, 0x007d, 0x0020, 0x0028, 0x007b, 0x0031, 0x007d, 0x0029, 0x0000 }; /* {0} ({1}) */ static const int32_t defaultPatLen = 9; static const int32_t defaultSub0Pos = 0; static const int32_t defaultSub1Pos = 5; int32_t length; /* of formatted result */ const UChar *separator; int32_t sepLen = 0; const UChar *pattern; int32_t patLen = 0; int32_t sub0Pos, sub1Pos; UChar formatOpenParen = 0x0028; // ( UChar formatReplaceOpenParen = 0x005B; // [ UChar formatCloseParen = 0x0029; // ) UChar formatReplaceCloseParen = 0x005D; // ] UBool haveLang = TRUE; /* assume true, set false if we find we don't have a lang component in the locale */ UBool haveRest = TRUE; /* assume true, set false if we find we don't have any other component in the locale */ UBool retry = FALSE; /* set true if we need to retry, see below */ int32_t langi = 0; /* index of the language substitution (0 or 1), virtually always 0 */ if(pErrorCode==NULL || U_FAILURE(*pErrorCode)) { return 0; } if(destCapacity<0 || (destCapacity>0 && dest==NULL)) { *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR; return 0; } { UErrorCode status = U_ZERO_ERROR; UResourceBundle* locbundle=ures_open(U_ICUDATA_LANG, displayLocale, &status); UResourceBundle* dspbundle=ures_getByKeyWithFallback(locbundle, _kLocaleDisplayPattern, NULL, &status); separator=ures_getStringByKeyWithFallback(dspbundle, _kSeparator, &sepLen, &status); pattern=ures_getStringByKeyWithFallback(dspbundle, _kPattern, &patLen, &status); ures_close(dspbundle); ures_close(locbundle); } /* If we couldn't find any data, then use the defaults */ if(sepLen == 0) { separator = defaultSeparator; } /* #10244: Even though separator is now a pattern, it is awkward to handle it as such * here since we are trying to build the display string in place in the dest buffer, * and to handle it as a pattern would entail having separate storage for the * substrings that need to be combined (the first of which may be the result of * previous such combinations). So for now we continue to treat the portion between * {0} and {1} as a string to be appended when joining substrings, ignoring anything * that is before {0} or after {1} (no existing separator pattern has any such thing). * This is similar to how pattern is handled below. */ { UChar *p0=u_strstr(separator, sub0); UChar *p1=u_strstr(separator, sub1); if (p0==NULL || p1==NULL || p1<p0) { *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR; return 0; } separator = (const UChar *)p0 + subLen; sepLen = p1 - separator; } if(patLen==0 || (patLen==defaultPatLen && !u_strncmp(pattern, defaultPattern, patLen))) { pattern=defaultPattern; patLen=defaultPatLen; sub0Pos=defaultSub0Pos; sub1Pos=defaultSub1Pos; // use default formatOpenParen etc. set above } else { /* non-default pattern */ UChar *p0=u_strstr(pattern, sub0); UChar *p1=u_strstr(pattern, sub1); if (p0==NULL || p1==NULL) { *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR; return 0; } sub0Pos=p0-pattern; sub1Pos=p1-pattern; if (sub1Pos < sub0Pos) { /* a very odd pattern */ int32_t t=sub0Pos; sub0Pos=sub1Pos; sub1Pos=t; langi=1; } if (u_strchr(pattern, 0xFF08) != NULL) { formatOpenParen = 0xFF08; // fullwidth ( formatReplaceOpenParen = 0xFF3B; // fullwidth [ formatCloseParen = 0xFF09; // fullwidth ) formatReplaceCloseParen = 0xFF3D; // fullwidth ] } } /* We loop here because there is one case in which after the first pass we could need to * reextract the data. If there's initial padding before the first element, we put in * the padding and then write that element. If it turns out there's no second element, * we didn't need the padding. If we do need the data (no preflight), and the first element * would have fit but for the padding, we need to reextract. In this case (only) we * adjust the parameters so padding is not added, and repeat. */ do { UChar* p=dest; int32_t patPos=0; /* position in the pattern, used for non-substitution portions */ int32_t langLen=0; /* length of language substitution */ int32_t langPos=0; /* position in output of language substitution */ int32_t restLen=0; /* length of 'everything else' substitution */ int32_t restPos=0; /* position in output of 'everything else' substitution */ UEnumeration* kenum = NULL; /* keyword enumeration */ /* prefix of pattern, extremely likely to be empty */ if(sub0Pos) { if(destCapacity >= sub0Pos) { while (patPos < sub0Pos) { *p++ = pattern[patPos++]; } } else { patPos=sub0Pos; } length=sub0Pos; } else { length=0; } for(int32_t subi=0,resti=0;subi<2;) { /* iterate through patterns 0 and 1*/ UBool subdone = FALSE; /* set true when ready to move to next substitution */ /* prep p and cap for calls to get display components, pin cap to 0 since they complain if cap is negative */ int32_t cap=destCapacity-length; if (cap <= 0) { cap=0; } else { p=dest+length; } if (subi == langi) { /* {0}*/ if(haveLang) { langPos=length; langLen=uloc_getDisplayLanguage(locale, displayLocale, p, cap, pErrorCode); length+=langLen; haveLang=langLen>0; } subdone=TRUE; } else { /* {1} */ if(!haveRest) { subdone=TRUE; } else { int32_t len; /* length of component (plus other stuff) we just fetched */ switch(resti++) { case 0: restPos=length; len=uloc_getDisplayScriptInContext(locale, displayLocale, p, cap, pErrorCode); break; case 1: len=uloc_getDisplayCountry(locale, displayLocale, p, cap, pErrorCode); break; case 2: len=uloc_getDisplayVariant(locale, displayLocale, p, cap, pErrorCode); break; case 3: kenum = uloc_openKeywords(locale, pErrorCode); /* fall through */ default: { const char* kw=uenum_next(kenum, &len, pErrorCode); if (kw == NULL) { uenum_close(kenum); len=0; /* mark that we didn't add a component */ subdone=TRUE; } else { /* incorporating this behavior into the loop made it even more complex, so just special case it here */ len = uloc_getDisplayKeyword(kw, displayLocale, p, cap, pErrorCode); if(len) { if(len < cap) { p[len]=0x3d; /* '=', assume we'll need it */ } len+=1; /* adjust for call to get keyword */ cap-=len; if(cap <= 0) { cap=0; } else { p+=len; } } /* reset for call below */ if(*pErrorCode == U_BUFFER_OVERFLOW_ERROR) { *pErrorCode=U_ZERO_ERROR; } int32_t vlen = uloc_getDisplayKeywordValue(locale, kw, displayLocale, p, cap, pErrorCode); if(len) { if(vlen==0) { --len; /* remove unneeded '=' */ } /* restore cap and p to what they were at start */ cap=destCapacity-length; if(cap <= 0) { cap=0; } else { p=dest+length; } } len+=vlen; /* total we added for key + '=' + value */ } } break; } /* end switch */ if (len>0) { /* we addeed a component, so add separator and write it if there's room. */ if(len+sepLen<=cap) { const UChar * plimit = p + len; for (; p < plimit; p++) { if (*p == formatOpenParen) { *p = formatReplaceOpenParen; } else if (*p == formatCloseParen) { *p = formatReplaceCloseParen; } } for(int32_t i=0;i<sepLen;++i) { *p++=separator[i]; } } length+=len+sepLen; } else if(subdone) { /* remove separator if we added it */ if (length!=restPos) { length-=sepLen; } restLen=length-restPos; haveRest=restLen>0; } } } if(*pErrorCode == U_BUFFER_OVERFLOW_ERROR) { *pErrorCode=U_ZERO_ERROR; } if(subdone) { if(haveLang && haveRest) { /* append internal portion of pattern, the first time, or last portion of pattern the second time */ int32_t padLen; patPos+=subLen; padLen=(subi==0 ? sub1Pos : patLen)-patPos; if(length+padLen < destCapacity) { p=dest+length; for(int32_t i=0;i<padLen;++i) { *p++=pattern[patPos++]; } } else { patPos+=padLen; } length+=padLen; } else if(subi==0) { /* don't have first component, reset for second component */ sub0Pos=0; length=0; } else if(length>0) { /* true length is the length of just the component we got. */ length=haveLang?langLen:restLen; if(dest && sub0Pos!=0) { if (sub0Pos+length<=destCapacity) { /* first component not at start of result, but we have full component in buffer. */ u_memmove(dest, dest+(haveLang?langPos:restPos), length); } else { /* would have fit, but didn't because of pattern prefix. */ sub0Pos=0; /* stops initial padding (and a second retry, so we won't end up here again) */ retry=TRUE; } } } ++subi; /* move on to next substitution */ } } } while(retry); return u_terminateUChars(dest, destCapacity, length, pErrorCode); }
const char *UStringEnumeration::next(int32_t *resultLength, UErrorCode &status) { return uenum_next(uenum, resultLength, &status); }
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"); } }
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); }