Skip to content

Commit

Permalink
ICU-22457 count() of getUnicodeKeywords is incorrect
Browse files Browse the repository at this point in the history
The count() is incorrect if the Locale contains extension which is not -u-
for example -x-, -t-.

Currently, this PR only contains tests to show the problem.

ICU-22457 Fix the enum_count
  • Loading branch information
FrankYFTang committed Aug 21, 2023
1 parent 52177cc commit 667ee72
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 1 deletion.
14 changes: 13 additions & 1 deletion icu4c/source/common/locid.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2407,8 +2407,9 @@ Locale::getLocaleCache()
}

class KeywordEnumeration : public StringEnumeration {
private:
protected:
char *keywords;
private:
char *current;
int32_t length;
UnicodeString currUSKey;
Expand Down Expand Up @@ -2515,6 +2516,17 @@ class UnicodeKeywordEnumeration : public KeywordEnumeration {
if (resultLength != nullptr) *resultLength = 0;
return nullptr;
}
virtual int32_t count(UErrorCode &/*status*/) const override {
char *kw = keywords;
int32_t result = 0;
while(*kw) {
if (uloc_toUnicodeLocaleKey(kw) != nullptr) {
result++;
}
kw += uprv_strlen(kw)+1;
}
return result;
}
};

// Out-of-line virtual destructor to serve as the "key function".
Expand Down
17 changes: 17 additions & 0 deletions icu4c/source/test/intltest/loctest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3989,6 +3989,8 @@ LocaleTest::TestCreateUnicodeKeywords() {
LocalPointer<StringEnumeration> keys(l.createUnicodeKeywords(status));
status.errIfFailureAndReset("\"%s\"", l.getName());

assertEquals("count", 2, keys->count(status));

const char* key;
int32_t resultLength;

Expand Down Expand Up @@ -4139,6 +4141,11 @@ LocaleTest::TestCreateUnicodeKeywordSet() {
result.find("ca") != result.end());
assertTrue("set::find(\"co\")",
result.find("co") != result.end());

LocalPointer<StringEnumeration> se(l.createUnicodeKeywords(status), status);
status.errIfFailureAndReset("\"%s\" createUnicodeKeywords()", l.getName());
assertEquals("count()", 2, se->count(status));
status.errIfFailureAndReset("\"%s\" count()", l.getName());
}

void
Expand All @@ -4154,6 +4161,10 @@ LocaleTest::TestCreateUnicodeKeywordSetEmpty() {
status.errIfFailureAndReset("\"%s\"", l.getName());

assertEquals("set::size()", 0, static_cast<int32_t>(result.size()));

LocalPointer<StringEnumeration> se(l.createUnicodeKeywords(status), status);
assertTrue("createUnicodeKeywords", se.isNull());
status.expectErrorAndReset(U_MEMORY_ALLOCATION_ERROR);
}

void
Expand All @@ -4174,6 +4185,12 @@ LocaleTest::TestCreateUnicodeKeywordSetWithPrivateUse() {
result.find("x") == result.end());
assertTrue("getUnicodeKeywords set::find(\"foo\")",
result.find("foo") == result.end());
assertEquals("set::size()", 1, static_cast<int32_t>(result.size()));

LocalPointer<StringEnumeration> se(l.createUnicodeKeywords(status), status);
status.errIfFailureAndReset("\"%s\" createUnicodeKeywords()", l.getName());
assertEquals("count()", 1, se->count(status));
status.errIfFailureAndReset("\"%s\" count()", l.getName());
}

void
Expand Down

2 comments on commit 667ee72

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Performance Alert ⚠️

Possible performance regression was detected for benchmark.
Benchmark result of this commit is worse than the previous benchmark result exceeding threshold 2.

Benchmark suite Current: 667ee72 Previous: 52177cc Ratio
TestCharsetDecoderICU 4.548169256941057 ns/iter 2.219041099995573 ns/iter 2.05

This comment was automatically generated by workflow using github-action-benchmark.

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Performance Alert ⚠️

Possible performance regression was detected for benchmark.
Benchmark result of this commit is worse than the previous benchmark result exceeding threshold 2.

Benchmark suite Current: 667ee72 Previous: 52177cc Ratio
TestCharsetDecoderICU 4.6208142756316875 ns/iter 2.219041099995573 ns/iter 2.08

This comment was automatically generated by workflow using github-action-benchmark.

Please sign in to comment.