diff --git a/icu4c/source/common/locid.cpp b/icu4c/source/common/locid.cpp index 4fec17d14fd..02cd82a7b8e 100644 --- a/icu4c/source/common/locid.cpp +++ b/icu4c/source/common/locid.cpp @@ -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(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; diff --git a/icu4c/source/test/intltest/loctest.cpp b/icu4c/source/test/intltest/loctest.cpp index 53d5721a98f..ce41a4c00e7 100644 --- a/icu4c/source/test/intltest/loctest.cpp +++ b/icu4c/source/test/intltest/loctest.cpp @@ -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(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 result; + l.getKeywords( + std::insert_iterator(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(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 result; + l.getUnicodeKeywords( + std::insert_iterator(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()"); diff --git a/icu4c/source/test/intltest/loctest.h b/icu4c/source/test/intltest/loctest.h index 1fba6d94f56..05be4037bd6 100644 --- a/icu4c/source/test/intltest/loctest.h +++ b/icu4c/source/test/intltest/loctest.h @@ -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); diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/util/ULocaleTest.java b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/util/ULocaleTest.java index cbd7a4fcbb0..2e3e3b070d9 100644 --- a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/util/ULocaleTest.java +++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/util/ULocaleTest.java @@ -4433,6 +4433,7 @@ public class ULocaleTest extends TestFmwk { //"", ",,...", ",,...", "", "", ...}, {"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"},