Ejemplo n.º 1
0
// @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;
}
Ejemplo n.º 2
0
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);
}
Ejemplo n.º 3
0
// @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;
}
Ejemplo n.º 4
0
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();
}
Ejemplo n.º 5
0
// @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;
}
Ejemplo n.º 6
0
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;
}
Ejemplo n.º 7
0
// @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;
}
Ejemplo n.º 8
0
// @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;
}
Ejemplo n.º 9
0
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 );

    }
}
Ejemplo n.º 10
0
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);
}
Ejemplo n.º 11
0
    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;
        }
    }
Ejemplo n.º 12
0
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;
}
Ejemplo n.º 13
0
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));
}
Ejemplo n.º 14
0
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;
}
Ejemplo n.º 15
0
// @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);
}
Ejemplo n.º 16
0
 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;
 }
Ejemplo n.º 17
0
 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_;
 }
Ejemplo n.º 18
0
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;
  */
}
Ejemplo n.º 19
0
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
    }
}
Ejemplo n.º 20
0
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
}
Ejemplo n.º 21
0
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
}
Ejemplo n.º 22
0
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;
}