mirror of
https://github.com/unicode-org/icu.git
synced 2025-04-21 04:29:31 +00:00
ICU-10258 Parse different variations of '+' and '-' when isLenient is set in C++.
X-SVN-Rev: 33989
This commit is contained in:
parent
75ee6eb19b
commit
41b7ee189d
3 changed files with 94 additions and 1 deletions
|
@ -282,6 +282,61 @@ static const char fgLatn[]="latn";
|
|||
static const char fgPatterns[]="patterns";
|
||||
static const char fgDecimalFormat[]="decimalFormat";
|
||||
static const char fgCurrencyFormat[]="currencyFormat";
|
||||
|
||||
static UChar32 gMinusSigns[] = {
|
||||
0x002D,
|
||||
0x207B,
|
||||
0x208B,
|
||||
0x2212,
|
||||
0x2796,
|
||||
0xFE63,
|
||||
0xFF0D};
|
||||
|
||||
static UChar32 gPlusSigns[] = {
|
||||
0x002B,
|
||||
0x207A,
|
||||
0x208A,
|
||||
0x2795,
|
||||
0xfB29,
|
||||
0xFE62,
|
||||
0xFF0B};
|
||||
|
||||
static UnicodeSet *gMinusSignsSet = NULL;
|
||||
static UnicodeSet *gPlusSignsSet = NULL;
|
||||
|
||||
static UInitOnce gSignsInitOnce = U_INITONCE_INITIALIZER;
|
||||
|
||||
static void initSigns(const UChar32 *raw, int32_t len, UnicodeSet *s) {
|
||||
for (int32_t i = 0; i < len; ++i) {
|
||||
s->add(raw[i]);
|
||||
}
|
||||
}
|
||||
|
||||
static void U_CALLCONV initSigns() {
|
||||
U_ASSERT(gMinusSignsSet == NULL);
|
||||
U_ASSERT(gPlusSignsSet == NULL);
|
||||
gMinusSignsSet = new UnicodeSet();
|
||||
gPlusSignsSet = new UnicodeSet();
|
||||
initSigns(
|
||||
gMinusSigns,
|
||||
sizeof(gMinusSigns) / sizeof(gMinusSigns[0]),
|
||||
gMinusSignsSet);
|
||||
initSigns(
|
||||
gPlusSigns,
|
||||
sizeof(gPlusSigns) / sizeof(gPlusSigns[0]),
|
||||
gPlusSignsSet);
|
||||
}
|
||||
|
||||
static const UnicodeSet* getMinusSigns() {
|
||||
umtx_initOnce(gSignsInitOnce, &initSigns);
|
||||
return gMinusSignsSet;
|
||||
}
|
||||
|
||||
static const UnicodeSet* getPlusSigns() {
|
||||
umtx_initOnce(gSignsInitOnce, &initSigns);
|
||||
return gPlusSignsSet;
|
||||
}
|
||||
|
||||
static const UChar fgTripleCurrencySign[] = {0xA4, 0xA4, 0xA4, 0};
|
||||
|
||||
inline int32_t _min(int32_t a, int32_t b) { return (a<b) ? a : b; }
|
||||
|
@ -2850,6 +2905,12 @@ int32_t DecimalFormat::compareAffix(const UnicodeString& text,
|
|||
return compareSimpleAffix(*patternToCompare, text, pos, isLenient());
|
||||
}
|
||||
|
||||
static UBool equalWithSignCompatibility(UChar32 lhs, UChar32 rhs) {
|
||||
return lhs == rhs
|
||||
|| (getMinusSigns()->contains(lhs) && getMinusSigns()->contains(rhs))
|
||||
|| (getPlusSigns()->contains(lhs) && getPlusSigns()->contains(rhs));
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the length matched by the given affix, or -1 if none.
|
||||
* Runs of white space in the affix, match runs of white space in
|
||||
|
@ -2966,7 +3027,7 @@ int32_t DecimalFormat::compareSimpleAffix(const UnicodeString& affix,
|
|||
UChar32 c = affix.char32At(i);
|
||||
int32_t len = U16_LENGTH(c);
|
||||
|
||||
if (input.char32At(pos) != c) {
|
||||
if (!equalWithSignCompatibility(input.char32At(pos), c)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
|
|
@ -126,6 +126,8 @@ void NumberFormatTest::runIndexedTest( int32_t index, UBool exec, const char* &n
|
|||
TESTCASE_AUTO(TestShowZero);
|
||||
TESTCASE_AUTO(TestCompatibleCurrencies);
|
||||
TESTCASE_AUTO(TestBug9936);
|
||||
TESTCASE_AUTO(TestParseNegativeWithFaLocale);
|
||||
TESTCASE_AUTO(TestParseNegativeWithAlternateMinusSign);
|
||||
TESTCASE_AUTO_END;
|
||||
}
|
||||
|
||||
|
@ -7118,4 +7120,32 @@ void NumberFormatTest::TestBug9936() {
|
|||
|
||||
}
|
||||
|
||||
void NumberFormatTest::TestParseNegativeWithFaLocale() {
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
DecimalFormat *test = (DecimalFormat *) NumberFormat::createInstance("fa", status);
|
||||
test->setLenient(TRUE);
|
||||
Formattable af;
|
||||
ParsePosition ppos;
|
||||
test->parse(UnicodeString("-0.5"), af, ppos);
|
||||
if (ppos.getIndex() == 0) {
|
||||
errln("Expected -0.5 to parse for farse.");
|
||||
}
|
||||
delete test;
|
||||
}
|
||||
|
||||
void NumberFormatTest::TestParseNegativeWithAlternateMinusSign() {
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
DecimalFormat *test = (DecimalFormat *) NumberFormat::createInstance("en", status);
|
||||
test->setLenient(TRUE);
|
||||
Formattable af;
|
||||
ParsePosition ppos;
|
||||
UnicodeString value("\\u208B0.5");
|
||||
value = value.unescape();
|
||||
test->parse(value, af, ppos);
|
||||
if (ppos.getIndex() == 0) {
|
||||
errln(UnicodeString("Expected ") + value + UnicodeString(" to parse."));
|
||||
}
|
||||
delete test;
|
||||
}
|
||||
|
||||
#endif /* #if !UCONFIG_NO_FORMATTING */
|
||||
|
|
|
@ -169,6 +169,8 @@ class NumberFormatTest: public CalendarTimeZoneTest {
|
|||
|
||||
void TestCompatibleCurrencies();
|
||||
void TestBug9936();
|
||||
void TestParseNegativeWithFaLocale();
|
||||
void TestParseNegativeWithAlternateMinusSign();
|
||||
|
||||
private:
|
||||
UBool testFormattableAsUFormattable(const char *file, int line, Formattable &f);
|
||||
|
|
Loading…
Add table
Reference in a new issue