From 8943f89a84e60b6d595b6065cdf0aa3de3ebd8f4 Mon Sep 17 00:00:00 2001 From: Peter Edberg Date: Tue, 12 Mar 2019 12:08:26 -0700 Subject: [PATCH] ICU-20471 setFormatWidth to 0 should cause padding to be ignored --- icu4c/source/i18n/number_mapper.cpp | 2 +- icu4c/source/i18n/number_patternstring.cpp | 2 +- icu4c/source/test/cintltst/cnumtst.c | 50 +++++++++++++++++++ .../icu/impl/number/PatternStringUtils.java | 2 +- .../ibm/icu/number/NumberPropertyMapper.java | 2 +- .../icu/dev/test/format/NumberFormatTest.java | 23 +++++++++ 6 files changed, 77 insertions(+), 4 deletions(-) diff --git a/icu4c/source/i18n/number_mapper.cpp b/icu4c/source/i18n/number_mapper.cpp index e439ce7f55..40fd5284b8 100644 --- a/icu4c/source/i18n/number_mapper.cpp +++ b/icu4c/source/i18n/number_mapper.cpp @@ -182,7 +182,7 @@ MacroProps NumberPropertyMapper::oldToNew(const DecimalFormatProperties& propert // PADDING // ///////////// - if (properties.formatWidth != -1) { + if (properties.formatWidth > 0) { macros.padder = Padder::forProperties(properties); } diff --git a/icu4c/source/i18n/number_patternstring.cpp b/icu4c/source/i18n/number_patternstring.cpp index 804832a348..9075424663 100644 --- a/icu4c/source/i18n/number_patternstring.cpp +++ b/icu4c/source/i18n/number_patternstring.cpp @@ -781,7 +781,7 @@ UnicodeString PatternStringUtils::propertiesToPatternString(const DecimalFormatP sb.append(affixes.getString(AffixPatternProvider::AFFIX_POS_SUFFIX)); // Resolve Padding - if (paddingWidth != -1 && !paddingLocation.isNull()) { + if (paddingWidth > 0 && !paddingLocation.isNull()) { while (paddingWidth - sb.length() > 0) { sb.insert(afterPrefixPos, u'#'); beforeSuffixPos++; diff --git a/icu4c/source/test/cintltst/cnumtst.c b/icu4c/source/test/cintltst/cnumtst.c index b4d3a58139..214362cf8f 100644 --- a/icu4c/source/test/cintltst/cnumtst.c +++ b/icu4c/source/test/cintltst/cnumtst.c @@ -72,6 +72,7 @@ static void TestRBNFRounding(void); static void Test12052_NullPointer(void); static void TestParseCases(void); static void TestSetMaxFracAndRoundIncr(void); +static void TestIgnorePadding(void); #define TESTCASE(x) addTest(root, &x, "tsformat/cnumtst/" #x) @@ -110,6 +111,7 @@ void addNumForTest(TestNode** root) TESTCASE(Test12052_NullPointer); TESTCASE(TestParseCases); TESTCASE(TestSetMaxFracAndRoundIncr); + TESTCASE(TestIgnorePadding); } /* test Parse int 64 */ @@ -3386,4 +3388,52 @@ static void TestSetMaxFracAndRoundIncr(void) { } } +static void TestIgnorePadding(void) { + UErrorCode status = U_ZERO_ERROR; + UNumberFormat* unum = unum_open(UNUM_PATTERN_DECIMAL, NULL, 0, "en_US", NULL, &status); + if (U_FAILURE(status)) { + log_data_err("unum_open UNUM_PATTERN_DECIMAL for en_US and NULL pattern fails:%s\n", u_errorName(status)); + } else { + unum_setAttribute(unum, UNUM_GROUPING_USED, 0); + unum_setAttribute(unum, UNUM_FORMAT_WIDTH, 0); + unum_setTextAttribute(unum, UNUM_PADDING_CHARACTER, u"*", 1, &status); + if (U_FAILURE(status)) { + log_err("unum_setTextAttribute UNUM_PADDING_CHARACTER to '*' fails: %s\n", u_errorName(status)); + } else { + unum_setAttribute(unum, UNUM_PADDING_POSITION, 0); + unum_setAttribute(unum, UNUM_MIN_INTEGER_DIGITS, 0); + unum_setAttribute(unum, UNUM_MAX_INTEGER_DIGITS, 8); + unum_setAttribute(unum, UNUM_MIN_FRACTION_DIGITS, 0); + unum_setAttribute(unum, UNUM_MAX_FRACTION_DIGITS, 0); + + UChar ubuf[kUBufMax]; + int32_t ulen = unum_toPattern(unum, FALSE, ubuf, kUBufMax, &status); + if (U_FAILURE(status)) { + log_err("unum_toPattern fails: %s\n", u_errorName(status)); + } else { + char bbuf[kBBufMax]; + if (ulen > 0 && ubuf[0]==u'*') { + ubuf[kUBufMax-1] = 0; // ensure zero termination + u_austrncpy(bbuf, ubuf, kBBufMax); + log_err("unum_toPattern result should ignore padding but get %s\n", bbuf); + } + unum_applyPattern(unum, FALSE, ubuf, ulen, NULL, &status); + if (U_FAILURE(status)) { + log_err("unum_applyPattern fails: %s\n", u_errorName(status)); + } else { + ulen = unum_formatDecimal(unum, "24", -1, ubuf, kUBufMax, NULL, &status); + if (U_FAILURE(status)) { + log_err("unum_formatDecimal fails: %s\n", u_errorName(status)); + } else if (u_strcmp(ubuf, u"24") != 0) { + ubuf[kUBufMax-1] = 0; // ensure zero termination + u_austrncpy(bbuf, ubuf, kBBufMax); + log_err("unum_formatDecimal result expect 24 but get %s\n", bbuf); + } + } + } + } + unum_close(unum); + } +} + #endif /* #if !UCONFIG_NO_FORMATTING */ diff --git a/icu4j/main/classes/core/src/com/ibm/icu/impl/number/PatternStringUtils.java b/icu4j/main/classes/core/src/com/ibm/icu/impl/number/PatternStringUtils.java index 8778646a7a..26eb45779e 100644 --- a/icu4j/main/classes/core/src/com/ibm/icu/impl/number/PatternStringUtils.java +++ b/icu4j/main/classes/core/src/com/ibm/icu/impl/number/PatternStringUtils.java @@ -171,7 +171,7 @@ public class PatternStringUtils { sb.append(affixes.getString(AffixPatternProvider.FLAG_POS_SUFFIX)); // Resolve Padding - if (paddingWidth != -1) { + if (paddingWidth > 0) { while (paddingWidth - sb.length() > 0) { sb.insert(afterPrefixPos, '#'); beforeSuffixPos++; diff --git a/icu4j/main/classes/core/src/com/ibm/icu/number/NumberPropertyMapper.java b/icu4j/main/classes/core/src/com/ibm/icu/number/NumberPropertyMapper.java index f02a75e087..82f75d57fd 100644 --- a/icu4j/main/classes/core/src/com/ibm/icu/number/NumberPropertyMapper.java +++ b/icu4j/main/classes/core/src/com/ibm/icu/number/NumberPropertyMapper.java @@ -219,7 +219,7 @@ final class NumberPropertyMapper { // PADDING // ///////////// - if (properties.getFormatWidth() != -1) { + if (properties.getFormatWidth() > 0) { macros.padder = Padder.forProperties(properties); } 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 cfd6660dd3..cc702950fe 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 @@ -1418,6 +1418,29 @@ public class NumberFormatTest extends TestFmwk { expect2(new DecimalFormat("*'😃'####.00", US), 1.1, "😃😃😃1.10"); } + @Test + public void TestIgnorePadding() { + DecimalFormatSymbols dfs = new DecimalFormatSymbols(Locale.US); + DecimalFormat fmt = new DecimalFormat("", dfs); + fmt.setGroupingUsed(false); + fmt.setFormatWidth(0); + fmt.setPadCharacter('*'); + fmt.setPadPosition(0); + fmt.setMinimumIntegerDigits(0); + fmt.setMaximumIntegerDigits(8); + fmt.setMinimumFractionDigits(0); + fmt.setMaximumFractionDigits(0); + String pattern = fmt.toPattern(); + if (pattern.startsWith("*")) { + errln("ERROR toPattern result should ignore padding but get \"" + pattern + "\""); + } + fmt.applyPattern(pattern); + String format = fmt.format(24); + if (!format.equals("24")) { + errln("ERROR format result expect 24 but get \"" + format + "\""); + } + } + /** * Upgrade to alphaWorks */