diff --git a/icu4c/source/i18n/plurfmt.cpp b/icu4c/source/i18n/plurfmt.cpp index 7ea83882875..46459e31d3c 100644 --- a/icu4c/source/i18n/plurfmt.cpp +++ b/icu4c/source/i18n/plurfmt.cpp @@ -155,8 +155,7 @@ PluralFormat::applyPattern(const UnicodeString& newPattern, UErrorCode& status) status = U_PATTERN_SYNTAX_ERROR; return; } - if (!pluralRules->isKeyword(token) && - pluralRules->getKeywordOther()!=token) { + if (!pluralRules->isKeyword(token)) { status = U_UNDEFINED_KEYWORD; return; } @@ -353,11 +352,23 @@ PluralFormat::clone() const return new PluralFormat(*this); } -/* -Format* -PluralFormat::clone() const { +PluralFormat& +PluralFormat::operator=(const PluralFormat& other) { + if (this != &other) { + UErrorCode status = U_ZERO_ERROR; + delete pluralRules; + delete fParsedValuesHash; + delete numberFormat; + locale = other.locale; + pluralRules = other.pluralRules->clone(); + pattern = other.pattern; + copyHashtable(other.fParsedValuesHash, status); + numberFormat=NumberFormat::createInstance(locale, status); + replacedNumberFormat=other.replacedNumberFormat; + } + + return *this; } -*/ UBool PluralFormat::operator==(const Format& other) const { diff --git a/icu4c/source/i18n/plurrule.cpp b/icu4c/source/i18n/plurrule.cpp index e36665a5ae8..bf4f0df52e2 100644 --- a/icu4c/source/i18n/plurrule.cpp +++ b/icu4c/source/i18n/plurrule.cpp @@ -163,7 +163,12 @@ PluralRules::operator=(const PluralRules& other) { if (this != &other) { fLocaleStringsHash=other.fLocaleStringsHash; delete mRules; - mRules = new RuleChain(*other.mRules); + if (other.mRules==NULL) { + mRules = NULL; + } + else { + mRules = new RuleChain(*other.mRules); + } delete mParser; mParser = new RuleParser(); } @@ -213,11 +218,12 @@ PluralRules::forLocale(const Locale& locale, UErrorCode& status) { } if (locRules == NULL) { // Check parent locales. - char parentLocale[ULOC_FULLNAME_CAPACITY]; + char parentLocaleName[ULOC_FULLNAME_CAPACITY]; const char *curLocaleName=locale.getName(); int32_t localeNameLen=0; - uprv_strcpy(parentLocale, curLocaleName); - while ((localeNameLen=uloc_getParent(parentLocale, parentLocale, ULOC_FULLNAME_CAPACITY, &status)) > 0) { + while ((localeNameLen=uloc_getParent(curLocaleName, parentLocaleName, + ULOC_FULLNAME_CAPACITY, &status)) > 0) { + localeName = UnicodeString(parentLocaleName, -1, US_INV); Mutex lock; locRules = (RuleChain *) (newRules->fLocaleStringsHash->get(localeName)); if (locRules != NULL) { @@ -247,18 +253,23 @@ PluralRules::select(int32_t number) const { StringEnumeration* PluralRules::getKeywords(UErrorCode& status) const { if (U_FAILURE(status)) return NULL; - StringEnumeration* nameEnumerator = new PluralKeywordEnumeration(status); + StringEnumeration* nameEnumerator = new PluralKeywordEnumeration(mRules, status); return nameEnumerator; } UBool PluralRules::isKeyword(const UnicodeString& keyword) const { - if ( mRules == NULL) { - return (UBool)( keyword == PLURAL_DEFAULT_RULE ); + if ( keyword == PLURAL_KEYWORD_OTHER ) { + return true; } else { - return mRules->isKeyword(keyword); + if (mRules==NULL) { + return false; + } + else { + return mRules->isKeyword(keyword); + } } } @@ -463,7 +474,12 @@ PluralRules::getNextLocale(const UnicodeString& localeData, int32_t* curIndex, U int32_t PluralRules::getRepeatLimit() const { - return mRules->getRepeatLimit(); + if (mRules!=NULL) { + return mRules->getRepeatLimit(); + } + else { + return 0; + } } void @@ -675,7 +691,6 @@ RuleChain::RuleChain() { } RuleChain::RuleChain(const RuleChain& other) { - this->repeatLimit = other.repeatLimit; this->keyword=other.keyword; if (other.ruleHeader != NULL) { @@ -1108,10 +1123,25 @@ RuleParser::isValidKeyword(const UnicodeString& token) { } } -PluralKeywordEnumeration::PluralKeywordEnumeration(UErrorCode& status) : +PluralKeywordEnumeration::PluralKeywordEnumeration(RuleChain *header, UErrorCode& status) : fKeywordNames(status) { + RuleChain *node=header; + UBool addKeywordOther=true; + pos=0; + fKeywordNames.removeAllElements(); + while(node!=NULL) { + fKeywordNames.addElement(new UnicodeString(node->keyword), status); + if (node->keyword == PLURAL_KEYWORD_OTHER) { + addKeywordOther= false; + } + node=node->next; + } + + if (addKeywordOther) { + fKeywordNames.addElement(new UnicodeString(PLURAL_KEYWORD_OTHER), status); + } } const UnicodeString* diff --git a/icu4c/source/i18n/plurrule_impl.h b/icu4c/source/i18n/plurrule_impl.h index ca79b482595..59d842cbb2c 100644 --- a/icu4c/source/i18n/plurrule_impl.h +++ b/icu4c/source/i18n/plurrule_impl.h @@ -199,7 +199,7 @@ private: class PluralKeywordEnumeration : public StringEnumeration { public: - PluralKeywordEnumeration(UErrorCode& status); + PluralKeywordEnumeration(RuleChain *header, UErrorCode& status); virtual ~PluralKeywordEnumeration(); static UClassID U_EXPORT2 getStaticClassID(void); virtual UClassID getDynamicClassID(void) const; diff --git a/icu4c/source/test/intltest/plurfmts.cpp b/icu4c/source/test/intltest/plurfmts.cpp index ce658b36cda..9acac7c6ff1 100644 --- a/icu4c/source/test/intltest/plurfmts.cpp +++ b/icu4c/source/test/intltest/plurfmts.cpp @@ -1,6 +1,6 @@ /******************************************************************** * COPYRIGHT: - * Copyright (c) 2007-2007, International Business Machines Corporation and + * Copyright (c) 2007-2008, International Business Machines Corporation and * others. All Rights Reserved. ********************************************************************/ @@ -85,6 +85,25 @@ void PluralFormatTest::pluralFormatBasicTest(/*char *par*/) } delete plFmt[i]; } + // ======= Test clone, assignment operator && == operator. + plFmt[0]= new PluralFormat(status[0]); + plFmt[1]= new PluralFormat(locale, status[1]); + *plFmt[1] = *plFmt[0]; + if (plFmt[1]!=NULL) { + if ( *plFmt[1] != *plFmt[0] ) { + errln("ERROR: clone plural format test failed!"); + } + } + plFmt[2]= new PluralFormat(locale, status[1]); + *plFmt[1] = *plFmt[2]; + if (plFmt[1]!=NULL) { + if ( *plFmt[1] != *plFmt[2] ) { + errln("ERROR: assignment operator test failed!"); + } + delete plFmt[1]; + } + delete plFmt[0]; + delete plFmt[2]; delete numFmt; delete plRules; } diff --git a/icu4c/source/test/intltest/plurults.cpp b/icu4c/source/test/intltest/plurults.cpp index 2f4a030ce06..a634ad2116d 100644 --- a/icu4c/source/test/intltest/plurults.cpp +++ b/icu4c/source/test/intltest/plurults.cpp @@ -86,6 +86,22 @@ void PluralRulesTest::testAPI(/*char *par*/) delete test; return; } + + // ======= Test clone, assignment operator && == operator. + PluralRules *dupRule = defRule.clone(); + if (dupRule!=NULL) { + if ( *dupRule != defRule ) { + errln("ERROR: clone plural rules test failed!"); + } + } + *dupRule = *newEnPlural; + if (dupRule!=NULL) { + if ( *dupRule != *newEnPlural ) { + errln("ERROR: clone plural rules test failed!"); + } + delete dupRule; + } + delete newEnPlural; // ======= Test empty plural rules