mirror of
https://github.com/unicode-org/icu.git
synced 2025-04-14 17:24:01 +00:00
ICU-8940 Ensure the new DecimalFormatSymbols is propagated properly in ICU4C RBNF
X-SVN-Rev: 31417
This commit is contained in:
parent
bae575e95a
commit
1dfe6c4c8b
6 changed files with 114 additions and 10 deletions
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
******************************************************************************
|
||||
* Copyright (C) 1997-2011, International Business Machines
|
||||
* Copyright (C) 1997-2012, International Business Machines
|
||||
* Corporation and others. All Rights Reserved.
|
||||
******************************************************************************
|
||||
* file name: nfrlist.h
|
||||
|
@ -82,6 +82,19 @@ public:
|
|||
fCapacity = 0;
|
||||
return result;
|
||||
}
|
||||
void deleteAll() {
|
||||
NFRule** tmp = NULL;
|
||||
int32_t size = fCount;
|
||||
if (size > 0) {
|
||||
tmp = release();
|
||||
for (int32_t i = 0; i < size; i++) {
|
||||
delete tmp[i];
|
||||
}
|
||||
if (tmp) {
|
||||
uprv_free(tmp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
NFRuleList(const NFRuleList &other); // forbid copying of this class
|
||||
|
|
|
@ -190,6 +190,9 @@ NFRuleSet::parseRules(UnicodeString& description, const RuleBasedNumberFormat* o
|
|||
return;
|
||||
}
|
||||
|
||||
// ensure we are starting with an empty rule list
|
||||
rules.deleteAll();
|
||||
|
||||
// dlf - the original code kept a separate description array for no reason,
|
||||
// so I got rid of it. The loop was too complex so I simplified it.
|
||||
|
||||
|
@ -235,24 +238,36 @@ NFRuleSet::parseRules(UnicodeString& description, const RuleBasedNumberFormat* o
|
|||
// if it's the negative-number rule, copy it into its own
|
||||
// data member and delete it from the list
|
||||
case NFRule::kNegativeNumberRule:
|
||||
if (negativeNumberRule) {
|
||||
delete negativeNumberRule;
|
||||
}
|
||||
negativeNumberRule = rules.remove(i);
|
||||
break;
|
||||
|
||||
// if it's the improper fraction rule, copy it into the
|
||||
// correct element of fractionRules
|
||||
case NFRule::kImproperFractionRule:
|
||||
if (fractionRules[0]) {
|
||||
delete fractionRules[0];
|
||||
}
|
||||
fractionRules[0] = rules.remove(i);
|
||||
break;
|
||||
|
||||
// if it's the proper fraction rule, copy it into the
|
||||
// correct element of fractionRules
|
||||
case NFRule::kProperFractionRule:
|
||||
if (fractionRules[1]) {
|
||||
delete fractionRules[1];
|
||||
}
|
||||
fractionRules[1] = rules.remove(i);
|
||||
break;
|
||||
|
||||
// if it's the master rule, copy it into the
|
||||
// correct element of fractionRules
|
||||
case NFRule::kMasterRule:
|
||||
if (fractionRules[2]) {
|
||||
delete fractionRules[2];
|
||||
}
|
||||
fractionRules[2] = rules.remove(i);
|
||||
break;
|
||||
|
||||
|
|
|
@ -649,6 +649,8 @@ RuleBasedNumberFormat::RuleBasedNumberFormat(const UnicodeString& description,
|
|||
const UnicodeString& locs,
|
||||
const Locale& alocale, UParseError& perror, UErrorCode& status)
|
||||
: ruleSets(NULL)
|
||||
, ruleSetDescriptions(NULL)
|
||||
, numRuleSets(0)
|
||||
, defaultRuleSet(NULL)
|
||||
, locale(alocale)
|
||||
, collator(NULL)
|
||||
|
@ -665,6 +667,8 @@ RuleBasedNumberFormat::RuleBasedNumberFormat(const UnicodeString& description,
|
|||
const UnicodeString& locs,
|
||||
UParseError& perror, UErrorCode& status)
|
||||
: ruleSets(NULL)
|
||||
, ruleSetDescriptions(NULL)
|
||||
, numRuleSets(0)
|
||||
, defaultRuleSet(NULL)
|
||||
, locale(Locale::getDefault())
|
||||
, collator(NULL)
|
||||
|
@ -681,6 +685,8 @@ RuleBasedNumberFormat::RuleBasedNumberFormat(const UnicodeString& description,
|
|||
LocalizationInfo* info,
|
||||
const Locale& alocale, UParseError& perror, UErrorCode& status)
|
||||
: ruleSets(NULL)
|
||||
, ruleSetDescriptions(NULL)
|
||||
, numRuleSets(0)
|
||||
, defaultRuleSet(NULL)
|
||||
, locale(alocale)
|
||||
, collator(NULL)
|
||||
|
@ -696,6 +702,8 @@ RuleBasedNumberFormat::RuleBasedNumberFormat(const UnicodeString& description,
|
|||
UParseError& perror,
|
||||
UErrorCode& status)
|
||||
: ruleSets(NULL)
|
||||
, ruleSetDescriptions(NULL)
|
||||
, numRuleSets(0)
|
||||
, defaultRuleSet(NULL)
|
||||
, locale(Locale::getDefault())
|
||||
, collator(NULL)
|
||||
|
@ -712,6 +720,8 @@ RuleBasedNumberFormat::RuleBasedNumberFormat(const UnicodeString& description,
|
|||
UParseError& perror,
|
||||
UErrorCode& status)
|
||||
: ruleSets(NULL)
|
||||
, ruleSetDescriptions(NULL)
|
||||
, numRuleSets(0)
|
||||
, defaultRuleSet(NULL)
|
||||
, locale(aLocale)
|
||||
, collator(NULL)
|
||||
|
@ -725,6 +735,8 @@ RuleBasedNumberFormat::RuleBasedNumberFormat(const UnicodeString& description,
|
|||
|
||||
RuleBasedNumberFormat::RuleBasedNumberFormat(URBNFRuleSetTag tag, const Locale& alocale, UErrorCode& status)
|
||||
: ruleSets(NULL)
|
||||
, ruleSetDescriptions(NULL)
|
||||
, numRuleSets(0)
|
||||
, defaultRuleSet(NULL)
|
||||
, locale(alocale)
|
||||
, collator(NULL)
|
||||
|
@ -783,6 +795,8 @@ RuleBasedNumberFormat::RuleBasedNumberFormat(URBNFRuleSetTag tag, const Locale&
|
|||
RuleBasedNumberFormat::RuleBasedNumberFormat(const RuleBasedNumberFormat& rhs)
|
||||
: NumberFormat(rhs)
|
||||
, ruleSets(NULL)
|
||||
, ruleSetDescriptions(NULL)
|
||||
, numRuleSets(0)
|
||||
, defaultRuleSet(NULL)
|
||||
, locale(rhs.locale)
|
||||
, collator(NULL)
|
||||
|
@ -1324,7 +1338,7 @@ RuleBasedNumberFormat::init(const UnicodeString& rules, LocalizationInfo* locali
|
|||
// pre-flight parsing the description and count the number of
|
||||
// rule sets (";%" marks the end of one rule set and the beginning
|
||||
// of the next)
|
||||
int numRuleSets = 0;
|
||||
numRuleSets = 0;
|
||||
for (int32_t p = description.indexOf(gSemiPercent, 2, 0); p != -1; p = description.indexOf(gSemiPercent, 2, p)) {
|
||||
++numRuleSets;
|
||||
++p;
|
||||
|
@ -1354,7 +1368,8 @@ RuleBasedNumberFormat::init(const UnicodeString& rules, LocalizationInfo* locali
|
|||
status = U_ILLEGAL_ARGUMENT_ERROR;
|
||||
return;
|
||||
}
|
||||
UnicodeString* ruleSetDescriptions = new UnicodeString[numRuleSets];
|
||||
|
||||
ruleSetDescriptions = new UnicodeString[numRuleSets];
|
||||
if (ruleSetDescriptions == 0) {
|
||||
status = U_MEMORY_ALLOCATION_ERROR;
|
||||
return;
|
||||
|
@ -1368,7 +1383,7 @@ RuleBasedNumberFormat::init(const UnicodeString& rules, LocalizationInfo* locali
|
|||
ruleSets[curRuleSet] = new NFRuleSet(ruleSetDescriptions, curRuleSet, status);
|
||||
if (ruleSets[curRuleSet] == 0) {
|
||||
status = U_MEMORY_ALLOCATION_ERROR;
|
||||
goto cleanup;
|
||||
return;
|
||||
}
|
||||
++curRuleSet;
|
||||
start = p + 1;
|
||||
|
@ -1377,7 +1392,7 @@ RuleBasedNumberFormat::init(const UnicodeString& rules, LocalizationInfo* locali
|
|||
ruleSets[curRuleSet] = new NFRuleSet(ruleSetDescriptions, curRuleSet, status);
|
||||
if (ruleSets[curRuleSet] == 0) {
|
||||
status = U_MEMORY_ALLOCATION_ERROR;
|
||||
goto cleanup;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1424,9 +1439,6 @@ RuleBasedNumberFormat::init(const UnicodeString& rules, LocalizationInfo* locali
|
|||
} else {
|
||||
defaultRuleSet = getDefaultRuleSet();
|
||||
}
|
||||
|
||||
cleanup:
|
||||
delete[] ruleSetDescriptions;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -1481,6 +1493,10 @@ RuleBasedNumberFormat::dispose()
|
|||
ruleSets = NULL;
|
||||
}
|
||||
|
||||
if (ruleSetDescriptions) {
|
||||
delete [] ruleSetDescriptions;
|
||||
}
|
||||
|
||||
#if !UCONFIG_NO_COLLATION
|
||||
delete collator;
|
||||
#endif
|
||||
|
@ -1594,6 +1610,15 @@ RuleBasedNumberFormat::adoptDecimalFormatSymbols(DecimalFormatSymbols* symbolsTo
|
|||
}
|
||||
|
||||
decimalFormatSymbols = symbolsToAdopt;
|
||||
|
||||
{
|
||||
// Apply the new decimalFormatSymbols by reparsing the rulesets
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
|
||||
for (int32_t i = 0; i < numRuleSets; i++) {
|
||||
ruleSets[i]->parseRules(ruleSetDescriptions[i], this, status);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Setting the symbols is equlivalent to adopting a newly created localized symbols.
|
||||
|
|
|
@ -1011,6 +1011,8 @@ private:
|
|||
|
||||
private:
|
||||
NFRuleSet **ruleSets;
|
||||
UnicodeString* ruleSetDescriptions;
|
||||
int32_t numRuleSets;
|
||||
NFRuleSet *defaultRuleSet;
|
||||
Locale locale;
|
||||
Collator* collator;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
*******************************************************************************
|
||||
* Copyright (C) 1996-2011, International Business Machines Corporation and *
|
||||
* Copyright (C) 1996-2012, International Business Machines Corporation and *
|
||||
* others. All Rights Reserved. *
|
||||
*******************************************************************************
|
||||
*/
|
||||
|
@ -66,6 +66,7 @@ void IntlTestRBNF::runIndexedTest(int32_t index, UBool exec, const char* &name,
|
|||
TESTCASE(16, TestHebrewFraction);
|
||||
TESTCASE(17, TestPortugueseSpellout);
|
||||
TESTCASE(18, TestMultiplierSubstitution);
|
||||
TESTCASE(19, TestSetDecimalFormatSymbols);
|
||||
#else
|
||||
TESTCASE(0, TestRBNFDisabled);
|
||||
#endif
|
||||
|
@ -1905,6 +1906,49 @@ IntlTestRBNF::TestMultiplierSubstitution(void) {
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
IntlTestRBNF::TestSetDecimalFormatSymbols() {
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
|
||||
RuleBasedNumberFormat rbnf(URBNF_ORDINAL, Locale::getEnglish(), status);
|
||||
if (U_FAILURE(status)) {
|
||||
errln("Unable to create RuleBasedNumberFormat - " + UnicodeString(u_errorName(status)));
|
||||
return;
|
||||
}
|
||||
|
||||
DecimalFormatSymbols dfs(Locale::getEnglish(), status);
|
||||
if (U_FAILURE(status)) {
|
||||
errln("Unable to create DecimalFormatSymbols - " + UnicodeString(u_errorName(status)));
|
||||
return;
|
||||
}
|
||||
|
||||
UnicodeString expected[] = {
|
||||
UnicodeString("1,001st"),
|
||||
UnicodeString("1&001st")
|
||||
};
|
||||
|
||||
double number = 1001;
|
||||
|
||||
UnicodeString result;
|
||||
|
||||
rbnf.format(number, result);
|
||||
if (result != expected[0]) {
|
||||
errln("Format Error - Got: " + result + " Expected: " + expected[0]);
|
||||
}
|
||||
|
||||
result.remove();
|
||||
|
||||
/* Set new symbol for testing */
|
||||
dfs.setSymbol(DecimalFormatSymbols::kGroupingSeparatorSymbol, UnicodeString("&"), TRUE);
|
||||
rbnf.setDecimalFormatSymbols(dfs);
|
||||
|
||||
rbnf.format(number, result);
|
||||
if (result != expected[1]) {
|
||||
errln("Format Error - Got: " + result + " Expected: " + expected[1]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
IntlTestRBNF::doTest(RuleBasedNumberFormat* formatter, const char* const testData[][2], UBool testParsing)
|
||||
{
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
*******************************************************************************
|
||||
* Copyright (C) 1996-2007, International Business Machines Corporation and *
|
||||
* Copyright (C) 1996-2012, International Business Machines Corporation and *
|
||||
* others. All Rights Reserved. *
|
||||
*******************************************************************************
|
||||
*/
|
||||
|
@ -128,6 +128,11 @@ class IntlTestRBNF : public IntlTest {
|
|||
*/
|
||||
virtual void TestMultiplierSubstitution();
|
||||
|
||||
/**
|
||||
* Test the setDecimalFormatSymbols in RBNF
|
||||
*/
|
||||
virtual void TestSetDecimalFormatSymbols();
|
||||
|
||||
protected:
|
||||
virtual void doTest(RuleBasedNumberFormat* formatter, const char* const testData[][2], UBool testParsing);
|
||||
virtual void doLenientParseTest(RuleBasedNumberFormat* formatter, const char* testData[][2]);
|
||||
|
|
Loading…
Add table
Reference in a new issue