From cb34c901684a93546674e81dbd587409f02cd4f3 Mon Sep 17 00:00:00 2001 From: Shane Carr Date: Tue, 15 May 2018 21:14:09 +0000 Subject: [PATCH] ICU-13737 Backpedaling on strict mode scientific parsing behavior change (do NOT require an exponent when parsing). X-SVN-Rev: 41378 --- icu4c/source/i18n/numparse_impl.cpp | 3 --- icu4c/source/i18n/numparse_impl.h | 1 - icu4c/source/i18n/numparse_validators.cpp | 11 --------- icu4c/source/i18n/numparse_validators.h | 8 ------- icu4c/source/io/locbund.cpp | 8 ------- icu4c/source/test/intltest/numfmtst.cpp | 9 ++++++++ icu4c/source/test/intltest/numfmtst.h | 1 + .../numberformattestspecification.txt | 5 ++-- .../impl/number/parse/NumberParserImpl.java | 3 --- .../parse/RequireExponentValidator.java | 23 ------------------- .../data/numberformattestspecification.txt | 5 ++-- .../icu/dev/test/format/NumberFormatTest.java | 15 ++++++++++-- 12 files changed, 29 insertions(+), 63 deletions(-) delete mode 100644 icu4j/main/classes/core/src/com/ibm/icu/impl/number/parse/RequireExponentValidator.java diff --git a/icu4c/source/i18n/numparse_impl.cpp b/icu4c/source/i18n/numparse_impl.cpp index ecb878fbe7..79f02cdfa8 100644 --- a/icu4c/source/i18n/numparse_impl.cpp +++ b/icu4c/source/i18n/numparse_impl.cpp @@ -195,9 +195,6 @@ NumberParserImpl::createParserFromProperties(const number::impl::DecimalFormatPr if (isStrict) { parser->addMatcher(parser->fLocalValidators.affix = {}); } - if (isStrict && properties.minimumExponentDigits > 0) { - parser->addMatcher(parser->fLocalValidators.exponent = {}); - } if (parseCurrency) { parser->addMatcher(parser->fLocalValidators.currency = {}); } diff --git a/icu4c/source/i18n/numparse_impl.h b/icu4c/source/i18n/numparse_impl.h index 63c0480244..0fd58e5492 100644 --- a/icu4c/source/i18n/numparse_impl.h +++ b/icu4c/source/i18n/numparse_impl.h @@ -87,7 +87,6 @@ class U_I18N_API NumberParserImpl : public MutableMatcherCollection { RequireAffixValidator affix; RequireCurrencyValidator currency; RequireDecimalSeparatorValidator decimalSeparator; - RequireExponentValidator exponent; RequireNumberValidator number; MultiplierParseHandler multiplier; } fLocalValidators; diff --git a/icu4c/source/i18n/numparse_validators.cpp b/icu4c/source/i18n/numparse_validators.cpp index 6e9632588b..4fbe07e087 100644 --- a/icu4c/source/i18n/numparse_validators.cpp +++ b/icu4c/source/i18n/numparse_validators.cpp @@ -57,17 +57,6 @@ UnicodeString RequireDecimalSeparatorValidator::toString() const { } -void RequireExponentValidator::postProcess(ParsedNumber& result) const { - if (0 == (result.flags & FLAG_HAS_EXPONENT)) { - result.flags |= FLAG_FAIL; - } -} - -UnicodeString RequireExponentValidator::toString() const { - return u""; -} - - void RequireNumberValidator::postProcess(ParsedNumber& result) const { // Require that a number is matched. if (!result.seenNumber()) { diff --git a/icu4c/source/i18n/numparse_validators.h b/icu4c/source/i18n/numparse_validators.h index 1479d897bb..cf989d5757 100644 --- a/icu4c/source/i18n/numparse_validators.h +++ b/icu4c/source/i18n/numparse_validators.h @@ -61,14 +61,6 @@ class RequireDecimalSeparatorValidator : public ValidationMatcher, public UMemor }; -class RequireExponentValidator : public ValidationMatcher, public UMemory { - public: - void postProcess(ParsedNumber& result) const U_OVERRIDE; - - UnicodeString toString() const U_OVERRIDE; -}; - - class RequireNumberValidator : public ValidationMatcher, public UMemory { public: void postProcess(ParsedNumber& result) const U_OVERRIDE; diff --git a/icu4c/source/io/locbund.cpp b/icu4c/source/io/locbund.cpp index 1b9999854e..8e880b17cf 100644 --- a/icu4c/source/io/locbund.cpp +++ b/icu4c/source/io/locbund.cpp @@ -54,10 +54,6 @@ static inline UNumberFormat * copyInvariantFormatter(ULocaleBundle *result, UNum UErrorCode status = U_ZERO_ERROR; UNumberFormat *formatAlias = unum_open(style, NULL, 0, "en_US_POSIX", NULL, &status); if (U_SUCCESS(status)) { - // ICU 62 requires exponent on strict scientific parser, but we don't want that here - if (style == UNUM_SCIENTIFIC) { - unum_setAttribute(formatAlias, UNUM_LENIENT_PARSE, TRUE); - } gPosixNumberFormat[style-1] = formatAlias; ucln_io_registerCleanup(UCLN_IO_LOCBUND, locbund_cleanup); } @@ -178,10 +174,6 @@ u_locbund_getNumberFormat(ULocaleBundle *bundle, UNumberFormatStyle style) formatAlias = NULL; } else { - // ICU 62 requires exponent on strict scientific parser, but we don't want that here - if (style == UNUM_SCIENTIFIC) { - unum_setAttribute(formatAlias, UNUM_LENIENT_PARSE, TRUE); - } bundle->fNumberFormat[style-1] = formatAlias; } } diff --git a/icu4c/source/test/intltest/numfmtst.cpp b/icu4c/source/test/intltest/numfmtst.cpp index 2d22e20a0b..982b261ab0 100644 --- a/icu4c/source/test/intltest/numfmtst.cpp +++ b/icu4c/source/test/intltest/numfmtst.cpp @@ -652,6 +652,7 @@ void NumberFormatTest::runIndexedTest( int32_t index, UBool exec, const char* &n TESTCASE_AUTO(Test11868); TESTCASE_AUTO(Test11739_ParseLongCurrency); TESTCASE_AUTO(Test13035_MultiCodePointPaddingInPattern); + TESTCASE_AUTO(Test13737_ParseScientificStrict); TESTCASE_AUTO(Test10727_RoundingZero); TESTCASE_AUTO(Test11376_getAndSetPositivePrefix); TESTCASE_AUTO(Test11475_signRecognition); @@ -8845,6 +8846,14 @@ void NumberFormatTest::Test13035_MultiCodePointPaddingInPattern() { assertEquals("Quote should be escapable in padding syntax", "a''12b", result); } +void NumberFormatTest::Test13737_ParseScientificStrict() { + IcuTestErrorCode status(*this, "Test13737_ParseScientificStrict"); + LocalPointer df(NumberFormat::createScientificInstance("en", status)); + df->setLenient(FALSE); + // Parse Test + expect(*df, u"1.2", 1.2); +} + void NumberFormatTest::Test11376_getAndSetPositivePrefix() { { const UChar USD[] = {0x55, 0x53, 0x44, 0x0}; diff --git a/icu4c/source/test/intltest/numfmtst.h b/icu4c/source/test/intltest/numfmtst.h index 57afe131e7..79d55043b1 100644 --- a/icu4c/source/test/intltest/numfmtst.h +++ b/icu4c/source/test/intltest/numfmtst.h @@ -214,6 +214,7 @@ class NumberFormatTest: public CalendarTimeZoneTest { void Test11868(); void Test11739_ParseLongCurrency(); void Test13035_MultiCodePointPaddingInPattern(); + void Test13737_ParseScientificStrict(); void Test10727_RoundingZero(); void Test11376_getAndSetPositivePrefix(); void Test11475_signRecognition(); diff --git a/icu4c/source/test/testdata/numberformattestspecification.txt b/icu4c/source/test/testdata/numberformattestspecification.txt index 3dfe7f7330..23be52502a 100644 --- a/icu4c/source/test/testdata/numberformattestspecification.txt +++ b/icu4c/source/test/testdata/numberformattestspecification.txt @@ -877,15 +877,16 @@ parse output breaks (1,945d1) fail K test parse strict scientific +// See #13737: Old behavior should be retained in this case set locale en set pattern #E0 set lenient 0 begin parse output breaks -123 fail JK +123 123 123E1 1230 123E0 123 -123E fail JK +123E 123 test parse strict without prefix/suffix set locale en diff --git a/icu4j/main/classes/core/src/com/ibm/icu/impl/number/parse/NumberParserImpl.java b/icu4j/main/classes/core/src/com/ibm/icu/impl/number/parse/NumberParserImpl.java index 274cd8847a..9b0cb96d1e 100644 --- a/icu4j/main/classes/core/src/com/ibm/icu/impl/number/parse/NumberParserImpl.java +++ b/icu4j/main/classes/core/src/com/ibm/icu/impl/number/parse/NumberParserImpl.java @@ -242,9 +242,6 @@ public class NumberParserImpl { if (isStrict) { parser.addMatcher(new RequireAffixValidator()); } - if (isStrict && properties.getMinimumExponentDigits() > 0) { - parser.addMatcher(new RequireExponentValidator()); - } if (parseCurrency) { parser.addMatcher(new RequireCurrencyValidator()); } diff --git a/icu4j/main/classes/core/src/com/ibm/icu/impl/number/parse/RequireExponentValidator.java b/icu4j/main/classes/core/src/com/ibm/icu/impl/number/parse/RequireExponentValidator.java deleted file mode 100644 index a9fd72d3d8..0000000000 --- a/icu4j/main/classes/core/src/com/ibm/icu/impl/number/parse/RequireExponentValidator.java +++ /dev/null @@ -1,23 +0,0 @@ -// © 2017 and later: Unicode, Inc. and others. -// License & terms of use: http://www.unicode.org/copyright.html#License -package com.ibm.icu.impl.number.parse; - -/** - * @author sffc - * - */ -public class RequireExponentValidator extends ValidationMatcher { - - @Override - public void postProcess(ParsedNumber result) { - if (0 == (result.flags & ParsedNumber.FLAG_HAS_EXPONENT)) { - result.flags |= ParsedNumber.FLAG_FAIL; - } - } - - @Override - public String toString() { - return ""; - } - -} diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/data/numberformattestspecification.txt b/icu4j/main/tests/core/src/com/ibm/icu/dev/data/numberformattestspecification.txt index d1e71388d3..549550742d 100644 --- a/icu4j/main/tests/core/src/com/ibm/icu/dev/data/numberformattestspecification.txt +++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/data/numberformattestspecification.txt @@ -870,15 +870,16 @@ parse output breaks (1,945d1) fail K test parse strict scientific +// See #13737: Old behavior should be retained in this case set locale en set pattern #E0 set lenient 0 begin parse output breaks -123 fail CJK +123 123 123E1 1230 123E0 123 -123E fail CJK +123E 123 test parse strict without prefix/suffix set locale en diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/format/NumberFormatTest.java b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/format/NumberFormatTest.java index feaf41821b..a5d2aea11c 100644 --- a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/format/NumberFormatTest.java +++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/format/NumberFormatTest.java @@ -5502,10 +5502,13 @@ public class NumberFormatTest extends TestFmwk { assertEquals("Should consume the whole number", 5, ppos.getIndex()); ppos.setIndex(0); result0 = df.parse("123", ppos); - assertNull("Should reject number without exponent", result0); + // #13737: For backwards compatibility, do NOT require the exponent. + assertEquals("Should NOT reject number without exponent", 123L, result0); ppos.setIndex(0); CurrencyAmount result1 = df.parseCurrency("USD123", ppos); - assertNull("Should reject currency without exponent", result1); + assertEquals("Should NOT reject currency without exponent", + new CurrencyAmount(123L, Currency.getInstance("USD")), + result1); } @Test @@ -5573,6 +5576,14 @@ public class NumberFormatTest extends TestFmwk { assertEquals("Quote should be escapable in padding syntax", "a''12b", result); } + @Test + public void Test13737_ParseScientificStrict() { + NumberFormat df = NumberFormat.getScientificInstance(ULocale.ENGLISH); + df.setParseStrict(true); + // Parse Test: exponent is not required, even in strict mode + expect(df, "1.2", 1.2); + } + // TODO: Investigate this test and re-enable if appropriate. @Test @Ignore