From 99f9802fec08d1479dc4bfcc0776a8c2a7285c68 Mon Sep 17 00:00:00 2001 From: Hugo van der Merwe <17109322+hugovdm@users.noreply.github.com> Date: Fri, 3 Apr 2020 04:35:29 +0200 Subject: [PATCH] ICU-21060 Fix the foo-per-a-b -> foo-b-per-a bug. --- icu4c/source/i18n/measunit_extra.cpp | 25 ++++++++++++---------- icu4c/source/test/intltest/measfmttest.cpp | 4 +++- 2 files changed, 17 insertions(+), 12 deletions(-) diff --git a/icu4c/source/i18n/measunit_extra.cpp b/icu4c/source/i18n/measunit_extra.cpp index 8af9e4141f3..b997167b311 100644 --- a/icu4c/source/i18n/measunit_extra.cpp +++ b/icu4c/source/i18n/measunit_extra.cpp @@ -42,7 +42,7 @@ constexpr int32_t kCompoundPartOffset = 128; enum CompoundPart { COMPOUND_PART_PER = kCompoundPartOffset, COMPOUND_PART_TIMES, - COMPOUND_PART_PLUS, + COMPOUND_PART_AND, }; constexpr int32_t kPowerPartOffset = 256; @@ -226,7 +226,7 @@ void U_CALLCONV initUnitExtras(UErrorCode& status) { // Add syntax parts (compound, power prefixes) b.add(u"-per-", COMPOUND_PART_PER, status); b.add(u"-", COMPOUND_PART_TIMES, status); - b.add(u"-and-", COMPOUND_PART_PLUS, status); + b.add(u"-and-", COMPOUND_PART_AND, status); b.add(u"square-", POWER_PART_P2, status); b.add(u"cubic-", POWER_PART_P3, status); b.add(u"p2-", POWER_PART_P2, status); @@ -383,8 +383,8 @@ private: return Token(match); } - void nextSingleUnit(SingleUnitImpl& result, bool& sawPlus, UErrorCode& status) { - sawPlus = false; + void nextSingleUnit(SingleUnitImpl& result, bool& sawAnd, UErrorCode& status) { + sawAnd = false; if (U_FAILURE(status)) { return; } @@ -422,10 +422,13 @@ private: break; case COMPOUND_PART_TIMES: + if (fAfterPer) { + result.dimensionality = -1; + } break; - case COMPOUND_PART_PLUS: - sawPlus = true; + case COMPOUND_PART_AND: + sawAnd = true; fAfterPer = false; break; } @@ -462,7 +465,7 @@ private: case Token::TYPE_ONE: // Skip "one" and go to the next unit - return nextSingleUnit(result, sawPlus, status); + return nextSingleUnit(result, sawAnd, status); case Token::TYPE_SIMPLE_UNIT: result.index = token.getSimpleUnitIndex(); @@ -485,9 +488,9 @@ private: } int32_t unitNum = 0; while (hasNext()) { - bool sawPlus; + bool sawAnd; SingleUnitImpl singleUnit; - nextSingleUnit(singleUnit, sawPlus, status); + nextSingleUnit(singleUnit, sawAnd, status); if (U_FAILURE(status)) { return; } @@ -495,13 +498,13 @@ private: continue; } bool added = result.append(singleUnit, status); - if (sawPlus && !added) { + if (sawAnd && !added) { // Two similar units are not allowed in a mixed unit status = kUnitIdentifierSyntaxError; return; } if ((++unitNum) >= 2) { - UMeasureUnitComplexity complexity = sawPlus + UMeasureUnitComplexity complexity = sawAnd ? UMEASURE_UNIT_MIXED : UMEASURE_UNIT_COMPOUND; if (unitNum == 2) { diff --git a/icu4c/source/test/intltest/measfmttest.cpp b/icu4c/source/test/intltest/measfmttest.cpp index 6f6c14cc8df..9306a5660bc 100644 --- a/icu4c/source/test/intltest/measfmttest.cpp +++ b/icu4c/source/test/intltest/measfmttest.cpp @@ -3427,7 +3427,9 @@ void MeasureFormatTest::TestIdentifiers() { const char* id; const char* normalized; } cases[] = { - { true, "square-meter-per-square-meter", "square-meter-per-square-meter" }, + {true, "square-meter-per-square-meter", "square-meter-per-square-meter"}, + {true, "kilogram-meter-per-square-meter-square-second", + "kilogram-meter-per-square-meter-square-second"}, // TODO(ICU-20920): Add more test cases once the proper ranking is available. }; for (const auto& cas : cases) { -- 2.40.0