// @bug 4124632 // // Collator::getCollationKey was hanging on certain character sequences // void CollationRegressionTest::Test4124632(/* char* par */) { UErrorCode status = U_ZERO_ERROR; Collator *coll = NULL; coll = Collator::createInstance(Locale::getJapan(), status); if (coll == NULL || U_FAILURE(status)) { errln("Failed to create collator for Locale::JAPAN"); delete coll; return; } static const UChar test[] = {0x41, 0x0308, 0x62, 0x63, 0}; CollationKey key; coll->getCollationKey(test, key, status); if (key.isBogus() || U_FAILURE(status)) { errln("CollationKey creation failed."); } delete coll; }
Collator* U_EXPORT2 Collator::createInstance(const Locale& desiredLocale, UErrorCode& status) { if (U_FAILURE(status)) return 0; #if !UCONFIG_NO_SERVICE if (hasService()) { Locale actualLoc; Collator *result = (Collator*)gService->get(desiredLocale, &actualLoc, status); // Ugly Hack Alert! If the returned locale is empty (not root, // but empty -- getName() == "") then that means the service // returned a default object, not a "real" service object. In // that case, the locale metadata (valid & actual) is setup // correctly already, and we don't want to overwrite it. (TODO // remove in 3.0) [aliu] if (*actualLoc.getName() != 0) { result->setLocales(desiredLocale, actualLoc, actualLoc); } return result; } #endif return makeInstance(desiredLocale, status); }
// @bug 4095316 // void CollationRegressionTest::Test4095316(/* char* par */) { UErrorCode status = U_ZERO_ERROR; Locale el_GR("el", "GR"); Collator *c = Collator::createInstance(el_GR, status); if (c == NULL || U_FAILURE(status)) { errln("Failed to create collator for el_GR locale"); delete c; return; } // These now have tertiary differences in UCA //c->setStrength(Collator::TERTIARY); c->setAttribute(UCOL_STRENGTH, UCOL_SECONDARY, status); static const UChar tests[][CollationRegressionTest::MAX_TOKEN_LEN] = { {0x03D4, 0}, {0x3d, 0}, {0x03AB, 0} }; compareArray(*c, tests, ARRAY_LENGTH(tests)); delete c; }
U_CAPI UCollator* U_EXPORT2 ucol_safeClone(const UCollator *coll, void * /*stackBuffer*/, int32_t * pBufferSize, UErrorCode *status) { if (status == NULL || U_FAILURE(*status)){ return NULL; } if (coll == NULL) { *status = U_ILLEGAL_ARGUMENT_ERROR; return NULL; } if (pBufferSize != NULL) { int32_t inputSize = *pBufferSize; *pBufferSize = 1; if (inputSize == 0) { return NULL; // preflighting for deprecated functionality } } Collator *newColl = Collator::fromUCollator(coll)->clone(); if (newColl == NULL) { *status = U_MEMORY_ALLOCATION_ERROR; } else { *status = U_SAFECLONE_ALLOCATED_WARNING; } return newColl->toUCollator(); }
// @bug 4092260 // // Mu/micro conflict // Micro symbol and greek lowercase letter Mu should sort identically // void CollationRegressionTest::Test4092260(/* char* par */) { UErrorCode status = U_ZERO_ERROR; Locale el("el", ""); Collator *c = NULL; c = Collator::createInstance(el, status); if (c == NULL || U_FAILURE(status)) { errln("Failed to create collator for el locale."); delete c; return; } // These now have tertiary differences in UCA c->setAttribute(UCOL_STRENGTH, UCOL_SECONDARY, status); static const UChar tests[][CollationRegressionTest::MAX_TOKEN_LEN] = { {0x00B5, 0}, {0x3d, 0}, {0x03BC, 0} }; compareArray(*c, tests, UPRV_LENGTHOF(tests)); delete c; }
Collator * Collator::createInstance(const Locale &loc, UVersionInfo version, UErrorCode &status) { Collator *collator; UVersionInfo info; collator=new RuleBasedCollator(loc, status); /* test for NULL */ if (collator == 0) { status = U_MEMORY_ALLOCATION_ERROR; return 0; } if(U_SUCCESS(status)) { collator->getVersion(info); if(0!=uprv_memcmp(version, info, sizeof(UVersionInfo))) { delete collator; status=U_MISSING_RESOURCE_ERROR; return 0; } } return collator; }
// @bug 4132736 // // sort order of french words with multiple accents has errors // void CollationRegressionTest::Test4132736(/* char* par */) { UErrorCode status = U_ZERO_ERROR; Collator *c = NULL; c = Collator::createInstance(Locale::getCanadaFrench(), status); c->setStrength(Collator::TERTIARY); if (c == NULL || U_FAILURE(status)) { errln("Failed to create a collator for Locale::getCanadaFrench()"); delete c; return; } static const UChar test1[][CollationRegressionTest::MAX_TOKEN_LEN] = { {0x65, 0x0300, 0x65, 0x0301, 0}, {0x3c, 0}, {0x65, 0x0301, 0x65, 0x0300, 0}, {0x65, 0x0300, 0x0301, 0}, {0x3c, 0}, {0x65, 0x0301, 0x0300, 0} }; compareArray(*c, test1, ARRAY_LENGTH(test1)); delete c; }
// @bug 4139572 // // getCollationKey throws exception for spanish text // Cannot reproduce this bug on 1.2, however it DOES fail on 1.1.6 // void CollationRegressionTest::Test4139572(/* char* par */) { // // Code pasted straight from the bug report // (and then translated to C++ ;-) // // create spanish locale and collator UErrorCode status = U_ZERO_ERROR; Locale l("es", "es"); Collator *col = NULL; col = Collator::createInstance(l, status); if (col == NULL || U_FAILURE(status)) { errln("Failed to create a collator for es_es locale."); delete col; return; } CollationKey key; // this spanish phrase kills it! col->getCollationKey("Nombre De Objeto", key, status); if (key.isBogus() || U_FAILURE(status)) { errln("Error creating CollationKey for \"Nombre De Ojbeto\""); } delete col; }
void CollationRegressionTest::compareArray(Collator &c, const UChar tests[][CollationRegressionTest::MAX_TOKEN_LEN], int32_t testCount) { int32_t i; Collator::EComparisonResult expectedResult = Collator::EQUAL; for (i = 0; i < testCount; i += 3) { UnicodeString source(tests[i]); UnicodeString comparison(tests[i + 1]); UnicodeString target(tests[i + 2]); if (comparison == "<") { expectedResult = Collator::LESS; } else if (comparison == ">") { expectedResult = Collator::GREATER; } else if (comparison == "=") { expectedResult = Collator::EQUAL; } else { UnicodeString bogus1("Bogus comparison string \""); UnicodeString bogus2("\""); errln(bogus1 + comparison + bogus2); } Collator::EComparisonResult compareResult = c.compare(source, target); CollationKey sourceKey, targetKey; UErrorCode status = U_ZERO_ERROR; c.getCollationKey(source, sourceKey, status); if (U_FAILURE(status)) { errln("Couldn't get collationKey for source"); continue; } c.getCollationKey(target, targetKey, status); if (U_FAILURE(status)) { errln("Couldn't get collationKey for target"); continue; } Collator::EComparisonResult keyResult = sourceKey.compareTo(targetKey); reportCResult( source, target, sourceKey, targetKey, compareResult, keyResult, compareResult, expectedResult ); } }
void UCollationPCE::init(const Collator &coll) { UErrorCode status = U_ZERO_ERROR; strength = coll.getAttribute(UCOL_STRENGTH, status); toShift = coll.getAttribute(UCOL_ALTERNATE_HANDLING, status) == UCOL_SHIFTED; isShifted = FALSE; variableTop = coll.getVariableTop(status); }
virtual void run() { uint8_t sk1[1024], sk2[1024]; uint8_t *oldSk = NULL, *newSk = sk1; int32_t oldLen = 0; int32_t prev = 0; int32_t i = 0; for(i = 0; i < noLines; i++) { if(lines[i].buflen == 0) { continue; } if(skipLineBecauseOfBug(lines[i].buff, lines[i].buflen)) { continue; } int32_t resLen = coll->getSortKey(lines[i].buff, lines[i].buflen, newSk, 1024); if(oldSk != NULL) { int32_t skres = strcmp((char *)oldSk, (char *)newSk); int32_t cmpres = coll->compare(lines[prev].buff, lines[prev].buflen, lines[i].buff, lines[i].buflen); int32_t cmpres2 = coll->compare(lines[i].buff, lines[i].buflen, lines[prev].buff, lines[prev].buflen); if(cmpres != -cmpres2) { IntlTest::gTest->errln(UnicodeString("Compare result not symmetrical on line ") + (i + 1)); break; } if(cmpres != normalizeResult(skres)) { IntlTest::gTest->errln(UnicodeString("Difference between coll->compare and sortkey compare on line ") + (i + 1)); break; } int32_t res = cmpres; if(res == 0 && !isAtLeastUCA62) { // Up to UCA 6.1, the collation test files use a custom tie-breaker, // comparing the raw input strings. res = u_strcmpCodePointOrder(lines[prev].buff, lines[i].buff); // Starting with UCA 6.2, the collation test files use the standard UCA tie-breaker, // comparing the NFD versions of the input strings, // which we do via setting strength=identical. } if(res > 0) { IntlTest::gTest->errln(UnicodeString("Line is not greater or equal than previous line, for line ") + (i + 1)); break; } } oldSk = newSk; oldLen = resLen; (void)oldLen; // Suppress set but not used warning. prev = i; newSk = (newSk == sk1)?sk2:sk1; } }
void Utf8Helper::setCollatorLanguage (const string& lang) { UErrorCode status = U_ZERO_ERROR; if (_coll) { ULocDataLocaleType type = ULOC_ACTUAL_LOCALE; const Locale& locale = _coll->getLocale(type, status); if(U_FAILURE(status)) { LOG_ERROR("error in Collator::getLocale(...): %s", u_errorName(status)); return; } if (lang == locale.getName()) { return; } } Collator* coll; if (lang == "") { // get default collator for empty language coll = Collator::createInstance(status); } else { Locale locale(lang.c_str()); coll = Collator::createInstance(locale, status); } if(U_FAILURE(status)) { LOG_ERROR("error in Collator::createInstance(): %s", u_errorName(status)); if (coll) { delete coll; } return; } // set the default attributes for sorting: coll->setAttribute(UCOL_CASE_FIRST, UCOL_UPPER_FIRST, status); // A < a coll->setAttribute(UCOL_NORMALIZATION_MODE, UCOL_OFF, status); // no normalization coll->setAttribute(UCOL_STRENGTH, UCOL_IDENTICAL, status); // UCOL_IDENTICAL, UCOL_PRIMARY, UCOL_SECONDARY, UCOL_TERTIARY if(U_FAILURE(status)) { LOG_ERROR("error in Collator::setAttribute(...): %s", u_errorName(status)); delete coll; return; } if (_coll) { delete _coll; } _coll = coll; }
int ColumnString::compareAtWithCollation(size_t n, size_t m, const IColumn & rhs_, const Collator & collator) const { const ColumnString & rhs = static_cast<const ColumnString &>(rhs_); return collator.compare( reinterpret_cast<const char *>(&chars[offsetAt(n)]), sizeAt(n), reinterpret_cast<const char *>(&rhs.chars[rhs.offsetAt(m)]), rhs.sizeAt(m)); }
UCollator* Collator::createUCollator(const char *loc, UErrorCode *status) { UCollator *result = 0; if (status && U_SUCCESS(*status) && hasService()) { Locale desiredLocale(loc); Collator *col = (Collator*)gService->get(desiredLocale, *status); if (col && col->getDynamicClassID() == RuleBasedCollator::getStaticClassID()) { RuleBasedCollator *rbc = (RuleBasedCollator *)col; if (!rbc->dataIsOwned) { result = ucol_safeClone(rbc->ucollator, NULL, NULL, status); } else { result = rbc->ucollator; rbc->ucollator = NULL; // to prevent free on delete } } delete col; } return result; }
// @bug 4058613 // // Collator::createInstance() causes an ArrayIndexOutofBoundsException for Korean // void CollationRegressionTest::Test4058613(/* char* par */) { // Creating a default collator doesn't work when Korean is the default // locale Locale oldDefault = Locale::getDefault(); UErrorCode status = U_ZERO_ERROR; Locale::setDefault(Locale::getKorean(), status); if (U_FAILURE(status)) { errln("Could not set default locale to Locale::KOREAN"); return; } Collator *c = NULL; c = Collator::createInstance("en_US", status); if (c == NULL || U_FAILURE(status)) { errln("Could not create a Korean collator"); Locale::setDefault(oldDefault, status); delete c; return; } // Since the fix to this bug was to turn off decomposition for Korean collators, // ensure that's what we got if (c->getAttribute(UCOL_NORMALIZATION_MODE, status) != UCOL_OFF) { errln("Decomposition is not set to NO_DECOMPOSITION for Korean collator"); } delete c; Locale::setDefault(oldDefault, status); }
virtual UObject* getKey(ICUServiceKey& key, UnicodeString* actualReturn, UErrorCode& status) const { UnicodeString ar; if (actualReturn == NULL) { actualReturn = &ar; } Collator* result = (Collator*)ICULocaleService::getKey(key, actualReturn, status); // Ugly Hack Alert! If the actualReturn length is zero, this // means we got a default object, not a "real" service-created // object. We don't call setLocales() on a default object, // because that will overwrite its correct built-in locale // metadata (valid & actual) with our incorrect data (all we // have is the requested locale). (TODO remove in 3.0) [aliu] if (result && actualReturn->length() > 0) { const LocaleKey& lkey = (const LocaleKey&)key; Locale canonicalLocale(""); Locale currentLocale(""); LocaleUtility::initLocaleFromName(*actualReturn, currentLocale); result->setLocales(lkey.canonicalLocale(canonicalLocale), currentLocale, currentLocale); } return result; }
int32_t getBucketIndex(const UnicodeString &name, const Collator &collatorPrimaryOnly, UErrorCode &errorCode) { // binary search int32_t start = 0; int32_t limit = bucketList_->size(); while ((start + 1) < limit) { int32_t i = (start + limit) / 2; const AlphabeticIndex::Bucket *bucket = getBucket(*bucketList_, i); UCollationResult nameVsBucket = collatorPrimaryOnly.compare(name, bucket->lowerBoundary_, errorCode); if (nameVsBucket < 0) { limit = i; } else { start = i; } } const AlphabeticIndex::Bucket *bucket = getBucket(*bucketList_, start); if (bucket->displayBucket_ != NULL) { bucket = bucket->displayBucket_; } return bucket->displayIndex_; }
UBool RuleBasedCollator::operator==(const Collator& that) const { /* only checks for address equals here */ if (Collator::operator==(that)) return TRUE; if (getDynamicClassID() != that.getDynamicClassID()) return FALSE; /* not the same class */ RuleBasedCollator& thatAlias = (RuleBasedCollator&)that; // weiv: use C function, commented code below is wrong return ucol_equals(this->ucollator, thatAlias.ucollator); /* synwee : orginal code does not check for data compatibility */ /* if (ucollator != thatAlias.ucollator) return FALSE; return TRUE; */ }
void CollationThaiTest::compareArray(Collator& c, const char* tests[], int32_t testsLength) { for (int32_t i = 0; i < testsLength; i += 3) { Collator::EComparisonResult expect; if (tests[i+1][0] == '<') { expect = Collator::LESS; } else if (tests[i+1][0] == '>') { expect = Collator::GREATER; } else if (tests[i+1][0] == '=') { expect = Collator::EQUAL; } else { // expect = Integer.decode(tests[i+1]).intValue(); errln((UnicodeString)"Error: unknown operator " + tests[i+1]); return; } UnicodeString s1, s2; parseChars(s1, tests[i]); parseChars(s2, tests[i+2]); doTest(&c, s1, s2, expect); #if 0 UErrorCode status = U_ZERO_ERROR; int32_t result = c.compare(s1, s2); if (sign(result) != sign(expect)) { UnicodeString t1, t2; errln(UnicodeString("") + i/3 + ": compare(" + IntlTest::prettify(s1, t1) + " , " + IntlTest::prettify(s2, t2) + ") got " + result + "; expected " + expect); CollationKey k1, k2; c.getCollationKey(s1, k1, status); c.getCollationKey(s2, k2, status); if (U_FAILURE(status)) { errln((UnicodeString)"Fail: getCollationKey returned " + u_errorName(status)); return; } errln((UnicodeString)" key1: " + prettify(k1, t1) ); errln((UnicodeString)" key2: " + prettify(k2, t2) ); } else { // Collator.compare worked OK; now try the collation keys CollationKey k1, k2; c.getCollationKey(s1, k1, status); c.getCollationKey(s2, k2, status); if (U_FAILURE(status)) { errln((UnicodeString)"Fail: getCollationKey returned " + u_errorName(status)); return; } result = k1.compareTo(k2); if (sign(result) != sign(expect)) { UnicodeString t1, t2; errln(UnicodeString("") + i/3 + ": key(" + IntlTest::prettify(s1, t1) + ").compareTo(key(" + IntlTest::prettify(s2, t2) + ")) got " + result + "; expected " + expect); errln((UnicodeString)" " + prettify(k1, t1) + " vs. " + prettify(k2, t2)); } } #endif } }
void CollationServiceTest::TestRegisterFactory(void) { #if !UCONFIG_NO_SERVICE int32_t n1, n2, n3; Locale fu_FU("fu", "FU", ""); Locale fu_FU_FOO("fu", "FU", "FOO"); UErrorCode status = U_ZERO_ERROR; Hashtable* fuFUNames = new Hashtable(FALSE, status); if (!fuFUNames) { errln("memory allocation error"); return; } fuFUNames->setValueDeleter(uhash_deleteUnicodeString); fuFUNames->put(fu_FU.getName(), new UnicodeString("ze leetle bunny Fu-Fu"), status); fuFUNames->put(fu_FU_FOO.getName(), new UnicodeString("zee leetel bunny Foo-Foo"), status); fuFUNames->put(Locale::getDefault().getName(), new UnicodeString("little bunny Foo Foo"), status); Collator* frcol = Collator::createInstance(Locale::getFrance(), status); Collator* gecol = Collator::createInstance(Locale::getGermany(), status); Collator* jpcol = Collator::createInstance(Locale::getJapan(), status); if(U_FAILURE(status)) { errcheckln(status, "Failed to create collators with %s", u_errorName(status)); delete frcol; delete gecol; delete jpcol; delete fuFUNames; return; } CollatorInfo** info = new CollatorInfo*[4]; if (!info) { errln("memory allocation error"); return; } info[0] = new CollatorInfo(Locale::getUS(), frcol, NULL); info[1] = new CollatorInfo(Locale::getFrance(), gecol, NULL); info[2] = new CollatorInfo(fu_FU, jpcol, fuFUNames); info[3] = NULL; TestFactory* factory = new TestFactory(info); if (!factory) { errln("memory allocation error"); return; } Collator* uscol = Collator::createInstance(Locale::getUS(), status); Collator* fucol = Collator::createInstance(fu_FU, status); { n1 = checkAvailable("before registerFactory"); URegistryKey key = Collator::registerFactory(factory, status); n2 = checkAvailable("after registerFactory"); assertTrue("count after > count before", n2 > n1); Collator* ncol = Collator::createInstance(Locale::getUS(), status); if (*frcol != *ncol) { errln("frcoll for en_US failed"); } delete ncol; ncol = NULL; ncol = Collator::createInstance(fu_FU_FOO, status); if (*jpcol != *ncol) { errln("jpcol for fu_FU_FOO failed"); } Locale loc = ncol->getLocale(ULOC_REQUESTED_LOCALE, status); if (loc != fu_FU_FOO) { errln(UnicodeString("requested locale for fu_FU_FOO is not fu_FU_FOO but ") + loc.getName()); } loc = ncol->getLocale(ULOC_VALID_LOCALE, status); if (loc != fu_FU) { errln(UnicodeString("valid locale for fu_FU_FOO is not fu_FU but ") + loc.getName()); } delete ncol; ncol = NULL; UnicodeString locName = fu_FU.getName(); StringEnumeration* localeEnum = Collator::getAvailableLocales(); UBool found = FALSE; const UnicodeString* locStr; for (locStr = localeEnum->snext(status); !found && locStr != NULL; locStr = localeEnum->snext(status)) { if (locName == *locStr) { found = TRUE; } } delete localeEnum; if (!found) { errln("new locale fu_FU not reported as supported locale"); } UnicodeString name; Collator::getDisplayName(fu_FU, name); if (name != "little bunny Foo Foo") { errln(UnicodeString("found ") + name + " for fu_FU"); } Collator::getDisplayName(fu_FU, fu_FU_FOO, name); if (name != "zee leetel bunny Foo-Foo") { errln(UnicodeString("found ") + name + " for fu_FU in fu_FU_FOO"); } if (!Collator::unregister(key, status)) { errln("failed to unregister factory"); } // ja, fr, ge collators no longer valid ncol = Collator::createInstance(fu_FU, status); if (*fucol != *ncol) { errln("collator after unregister does not match original fu_FU"); } delete ncol; n3 = checkAvailable("after unregister"); assertTrue("count after unregister == count before register", n3 == n1); } delete fucol; delete uscol; #endif }
void CollationServiceTest::TestRegister() { #if !UCONFIG_NO_SERVICE // register a singleton const Locale& FR = Locale::getFrance(); const Locale& US = Locale::getUS(); const Locale US_FOO("en", "US", "FOO"); UErrorCode status = U_ZERO_ERROR; Collator* frcol = Collator::createInstance(FR, status); Collator* uscol = Collator::createInstance(US, status); if(U_FAILURE(status)) { errcheckln(status, "Failed to create collators with %s", u_errorName(status)); delete frcol; delete uscol; return; } { // try override en_US collator URegistryKey key = Collator::registerInstance(frcol, US, status); Collator* ncol = Collator::createInstance(US_FOO, status); if (*frcol != *ncol) { errln("register of french collator for en_US failed on request for en_US_FOO"); } // ensure original collator's params not touched Locale loc = frcol->getLocale(ULOC_REQUESTED_LOCALE, status); if (loc != FR) { errln(UnicodeString("fr collator's requested locale changed to ") + loc.getName()); } loc = frcol->getLocale(ULOC_VALID_LOCALE, status); if (loc != FR) { errln(UnicodeString("fr collator's valid locale changed to ") + loc.getName()); } loc = ncol->getLocale(ULOC_REQUESTED_LOCALE, status); if (loc != US_FOO) { errln(UnicodeString("requested locale for en_US_FOO is not en_US_FOO but ") + loc.getName()); } loc = ncol->getLocale(ULOC_VALID_LOCALE, status); if (loc != US) { errln(UnicodeString("valid locale for en_US_FOO is not en_US but ") + loc.getName()); } loc = ncol->getLocale(ULOC_ACTUAL_LOCALE, status); if (loc != US) { errln(UnicodeString("actual locale for en_US_FOO is not en_US but ") + loc.getName()); } delete ncol; ncol = NULL; if (!Collator::unregister(key, status)) { errln("failed to unregister french collator"); } // !!! frcol pointer is now invalid !!! ncol = Collator::createInstance(US, status); if (*uscol != *ncol) { errln("collator after unregister does not match original"); } delete ncol; ncol = NULL; } // recreate frcol frcol = Collator::createInstance(FR, status); LocalUCollatorPointer frFR(ucol_open("fr_FR", &status)); { // try create collator for new locale Locale fu_FU_FOO("fu", "FU", "FOO"); Locale fu_FU("fu", "FU", ""); Collator* fucol = Collator::createInstance(fu_FU, status); URegistryKey key = Collator::registerInstance(frcol, fu_FU, status); Collator* ncol = Collator::createInstance(fu_FU_FOO, status); if (*frcol != *ncol) { errln("register of fr collator for fu_FU failed"); } UnicodeString locName = fu_FU.getName(); StringEnumeration* localeEnum = Collator::getAvailableLocales(); UBool found = FALSE; const UnicodeString* locStr, *ls2; for (locStr = localeEnum->snext(status); !found && locStr != NULL; locStr = localeEnum->snext(status)) { // if (locName == *locStr) { found = TRUE; } } StringEnumeration *le2 = NULL; localeEnum->reset(status); int32_t i, count; count = localeEnum->count(status); for(i = 0; i < count; ++i) { if(i == count / 2) { le2 = localeEnum->clone(); if(le2 == NULL || count != le2->count(status)) { errln("ServiceEnumeration.clone() failed"); break; } } if(i >= count / 2) { locStr = localeEnum->snext(status); ls2 = le2->snext(status); if(*locStr != *ls2) { errln("ServiceEnumeration.clone() failed for item %d", i); } } else { localeEnum->snext(status); } } delete localeEnum; delete le2; if (!found) { errln("new locale fu_FU not reported as supported locale"); } UnicodeString displayName; Collator::getDisplayName(fu_FU, displayName); /* The locale display pattern for the locale ja, ko, and zh are different. */ const UChar zh_fuFU_Array[] = { 0x0066, 0x0075, 0xff08, 0x0046, 0x0055, 0xff09, 0 }; const UnicodeString zh_fuFU(zh_fuFU_Array); const Locale& defaultLocale = Locale::getDefault(); if (displayName != "fu (FU)" && ((defaultLocale == Locale::getKorean() && defaultLocale == Locale::getJapanese()) && displayName == "fu(FU)") && ((defaultLocale == Locale::getChinese()) && displayName != zh_fuFU)) { errln(UnicodeString("found ") + displayName + " for fu_FU"); } Collator::getDisplayName(fu_FU, fu_FU, displayName); if (displayName != "fu (FU)" && ((defaultLocale == Locale::getKorean() && defaultLocale == Locale::getJapanese()) && displayName == "fu(FU)") && ((defaultLocale == Locale::getChinese()) && displayName != zh_fuFU)) { errln(UnicodeString("found ") + displayName + " for fu_FU"); } // test ucol_open LocalUCollatorPointer fufu(ucol_open("fu_FU_FOO", &status)); if (fufu.isNull()) { errln("could not open fu_FU_FOO with ucol_open"); } else { if (!ucol_equals(fufu.getAlias(), frFR.getAlias())) { errln("collator fufu != collator frFR"); } } if (!Collator::unregister(key, status)) { errln("failed to unregister french collator"); } // !!! note frcoll invalid again, but we're no longer using it // other collators should still work ok Locale nloc = ncol->getLocale(ULOC_VALID_LOCALE, status); if (nloc != fu_FU) { errln(UnicodeString("asked for nloc valid locale after close and got") + nloc.getName()); } delete ncol; ncol = NULL; if (fufu.isValid()) { const char* nlocstr = ucol_getLocaleByType(fufu.getAlias(), ULOC_VALID_LOCALE, &status); if (uprv_strcmp(nlocstr, "fu_FU") != 0) { errln(UnicodeString("asked for uloc valid locale after close and got ") + nlocstr); } } ncol = Collator::createInstance(fu_FU, status); if (*fucol != *ncol) { errln("collator after unregister does not match original fu_FU"); } delete uscol; uscol = NULL; delete ncol; ncol = NULL; delete fucol; fucol = NULL; } #endif }
int main(int /* argc*/ , const char * /*argv*/ []) { UErrorCode status = U_ZERO_ERROR; int diffs = 0; int gbaddiffs =0; setup(status); if(U_FAILURE(status)) return 1; int expected = PROVIDER_COUNT; for(int l=0;l<LOCALE_COUNT;l++) { printf("\n"); uint8_t oldBytes[200]; int32_t oldLen = -1; for(int v=0;v<=expected;v++) { // Construct the locale ID char locID[200]; strcpy(locID, locale[l]); if((v!=expected)) { // -1 = no version strcat(locID, "@sp=icu"); strcat(locID, provider_version[v]); } printf("%-28s = ", locID); UErrorCode subStatus = U_ZERO_ERROR; uint8_t bytes[200]; uint8_t bytesb[200]; #define USE_CXX 0 #if USE_CXX Collator *col = Collator::createInstance(Locale(locID),subStatus); if(U_FAILURE(subStatus)) { printf("ERR: %s\n", u_errorName(subStatus)); continue; } int32_t len = col->getSortKey(stuff, -1, bytes, 200); #else #if 1 char xbuf2[200]; strcpy(xbuf2,"X/"); strcat(xbuf2,locID); strcat(xbuf2,"/"); //printf(" -> %s\n", xbuf2); UCollator *col = ucol_openFromShortString(xbuf2, FALSE,NULL, &subStatus); #else UCollator *col = ucol_open(locID, &subStatus); #endif if(U_FAILURE(subStatus)) { printf("ERR: %s\n", u_errorName(subStatus)); continue; } char xbuf3[200]; { int32_t def = ucol_getShortDefinitionString(col,locID/*NULL*/,xbuf3,200,&subStatus); if(U_FAILURE(subStatus)) { printf("Err getting short string name: %s\n", u_errorName(subStatus)); } else { printf(" --> %s\n", xbuf3); } } int32_t len = ucol_getSortKey(col, stuff, -1, bytes, 200); #endif printf(" "); int tdiffs=0; for(int i=0;i<len;i++) { if(i<oldLen&&bytes[i]!=oldBytes[i]) { diffs++; printf("*"); } else { printf(" "); } printf("%02X", (0xFF&bytes[i])); } printf("\n"); char xbuf4[200]; UCollator *col2 = ucol_openFromShortString(xbuf3, FALSE, NULL, &subStatus); if(U_FAILURE(subStatus)) { printf("Err opening from new short string : %s\n", u_errorName(subStatus)); continue; } else { int32_t def4 = ucol_getShortDefinitionString(col,locID/*NULL*/,xbuf4,200,&subStatus); if(strcmp(xbuf4,xbuf3)) { printf(" --> reopened = %s (%s)\n", xbuf4, u_errorName(subStatus)); } } int32_t len2 = ucol_getSortKey(col2, stuff, -1, bytesb, 200); int baddiffs=0; for(int i=0;i<len;i++) { if(i<len&&bytes[i]!=bytesb[i]) { baddiffs++; printf("!"); } else { // printf(" "); } // printf("%02X", (0xFF&bytesb[i])); } if(baddiffs>0) { printf(" - ERR! Diffs from %s in %d places\n", xbuf2,baddiffs); gbaddiffs+=baddiffs; } else { //printf(" OK.\n"); } // printf("\n"); #if USE_CXX delete col; #else ucol_close(col); #endif oldLen = len; memcpy(oldBytes, bytes, len); } } if(diffs==0) { #if (U_ICU_VERSION_MAJOR_NUM < 49) printf("ERROR: 0 differences found between platforms. ICU " U_ICU_VERSION " does not support collator plugins properly (not until 49)\n"); #else printf("ERROR: 0 differences found between platforms.. are the platforms installed? Try 'icuinfo -L'\n"); #endif return 1; } else { printf("%d differences found among provider versions!\n", diffs); } if(gbaddiffs>0) { printf("ERROR: %d diffs found between a collator and it's reopened (from shortstring) variant.\n", gbaddiffs); return 2; } else { printf("Collator and reopened (shortstring) are OK.\n"); } printf("Success!\n"); return 0; }