ICU-21539 Fix getUnicodeKeywords to skip non keys

See #1683
This commit is contained in:
Frank Tang 2021-04-07 19:09:39 +00:00 committed by Frank Yung-Fong Tang
parent 7b971a2b23
commit 45b893c1f9
4 changed files with 50 additions and 4 deletions

View file

@ -2515,16 +2515,16 @@ public:
virtual const char* next(int32_t* resultLength, UErrorCode& status) {
const char* legacy_key = KeywordEnumeration::next(nullptr, status);
if (U_SUCCESS(status) && legacy_key != nullptr) {
while (U_SUCCESS(status) && legacy_key != nullptr) {
const char* key = uloc_toUnicodeLocaleKey(legacy_key);
if (key == nullptr) {
status = U_ILLEGAL_ARGUMENT_ERROR;
} else {
if (key != nullptr) {
if (resultLength != nullptr) {
*resultLength = static_cast<int32_t>(uprv_strlen(key));
}
return key;
}
// Not a Unicode keyword, could be a t, x or other, continue to look at the next one.
legacy_key = KeywordEnumeration::next(nullptr, status);
}
if (resultLength != nullptr) *resultLength = 0;
return nullptr;

View file

@ -239,8 +239,10 @@ void LocaleTest::runIndexedTest( int32_t index, UBool exec, const char* &name, c
TESTCASE_AUTO(TestKeywordVariantParsing);
TESTCASE_AUTO(TestCreateKeywordSet);
TESTCASE_AUTO(TestCreateKeywordSetEmpty);
TESTCASE_AUTO(TestCreateKeywordSetWithPrivateUse);
TESTCASE_AUTO(TestCreateUnicodeKeywordSet);
TESTCASE_AUTO(TestCreateUnicodeKeywordSetEmpty);
TESTCASE_AUTO(TestCreateUnicodeKeywordSetWithPrivateUse);
TESTCASE_AUTO(TestGetKeywordValueStdString);
TESTCASE_AUTO(TestGetUnicodeKeywordValueStdString);
TESTCASE_AUTO(TestSetKeywordValue);
@ -4084,6 +4086,27 @@ LocaleTest::TestCreateKeywordSetEmpty(void) {
assertEquals("set::size()", 0, static_cast<int32_t>(result.size()));
}
void
LocaleTest::TestCreateKeywordSetWithPrivateUse(void) {
IcuTestErrorCode status(*this, "TestCreateKeywordSetWithPrivateUse()");
static const char tag[] = "en-US-u-ca-gregory-x-foo";
static const Locale l = Locale::forLanguageTag(tag, status);
std::set<std::string> result;
l.getKeywords<std::string>(
std::insert_iterator<decltype(result)>(result, result.begin()),
status);
status.errIfFailureAndReset("getKeywords \"%s\"", l.getName());
assertTrue("getKeywords set::find(\"calendar\")",
result.find("calendar") != result.end());
assertTrue("getKeywords set::find(\"ca\")",
result.find("ca") == result.end());
assertTrue("getKeywords set::find(\"x\")",
result.find("x") != result.end());
assertTrue("getKeywords set::find(\"foo\")",
result.find("foo") == result.end());
}
void
LocaleTest::TestCreateUnicodeKeywordSet(void) {
IcuTestErrorCode status(*this, "TestCreateUnicodeKeywordSet()");
@ -4118,6 +4141,26 @@ LocaleTest::TestCreateUnicodeKeywordSetEmpty(void) {
assertEquals("set::size()", 0, static_cast<int32_t>(result.size()));
}
void
LocaleTest::TestCreateUnicodeKeywordSetWithPrivateUse(void) {
IcuTestErrorCode status(*this, "TestCreateUnicodeKeywordSetWithPrivateUse()");
static const char tag[] = "en-US-u-ca-gregory-x-foo";
static const Locale l = Locale::forLanguageTag(tag, status);
std::set<std::string> result;
l.getUnicodeKeywords<std::string>(
std::insert_iterator<decltype(result)>(result, result.begin()),
status);
status.errIfFailureAndReset("getUnicodeKeywords \"%s\"", l.getName());
assertTrue("getUnicodeKeywords set::find(\"ca\")",
result.find("ca") != result.end());
assertTrue("getUnicodeKeywords set::find(\"x\")",
result.find("x") == result.end());
assertTrue("getUnicodeKeywords set::find(\"foo\")",
result.find("foo") == result.end());
}
void
LocaleTest::TestGetKeywordValueStdString(void) {
IcuTestErrorCode status(*this, "TestGetKeywordValueStdString()");

View file

@ -82,8 +82,10 @@ public:
void TestKeywordVariantParsing(void);
void TestCreateKeywordSet(void);
void TestCreateKeywordSetEmpty(void);
void TestCreateKeywordSetWithPrivateUse(void);
void TestCreateUnicodeKeywordSet(void);
void TestCreateUnicodeKeywordSetEmpty(void);
void TestCreateUnicodeKeywordSetWithPrivateUse(void);
void TestGetKeywordValueStdString(void);
void TestGetUnicodeKeywordValueStdString(void);

View file

@ -4433,6 +4433,7 @@ public class ULocaleTest extends TestFmwk {
//"<langtag>", "<attr1>,<attr2>,...", "<key1>,<key2>,...", "<type1>", "<type2>", ...},
{"en", null, null},
{"en-a-ext1-x-privuse", null, null},
{"en-a-ext1-u-ca-roc-x-privuse", null, "ca", "roc", null},
{"en-u-attr1-attr2", "attr1,attr2", null},
{"ja-u-ca-japanese-cu-jpy", null, "ca,cu", "japanese", "jpy"},
{"th-TH-u-number-attr-nu-thai-ca-buddhist", "attr,number", "ca,nu", "buddhist", "thai"},