} else {
sink.Append("-", 1);
sink.Append(ext->key, static_cast<int32_t>(uprv_strlen(ext->key)));
- sink.Append("-", 1);
- sink.Append(ext->value, static_cast<int32_t>(uprv_strlen(ext->value)));
+ if (uprv_strcmp(ext->value, "true") != 0 &&
+ uprv_strcmp(ext->value, "yes") != 0) {
+ sink.Append("-", 1);
+ sink.Append(ext->value, static_cast<int32_t>(uprv_strlen(ext->value)));
+ }
}
}
}
// The following now uses standard canonicalization.
{"az_AZ_CYRL", "az-AZ-x-lvariant-cyrl", NULL},
+
+ /* ICU-20310 */
+ {"en-u-kn-true", "en-u-kn", "en-u-kn"},
+ {"en-u-kn", "en-u-kn", "en-u-kn"},
+ {"de-u-co-yes", "de-u-co", "de-u-co"},
+ {"de-u-co", "de-u-co", "de-u-co"},
+ {"de@collation=yes", "de-u-co", "de-u-co"},
+ {"cmn-hans-cn-u-ca-t-ca-x-t-u", "cmn-Hans-CN-t-ca-u-ca-x-t-u", "cmn-Hans-CN-t-ca-u-ca-x-t-u"},
{NULL, NULL, NULL}
};
{"U", "ja_JP@calendar=japanese;currency=JPY", "E", "u",
"attr1-ca-gregory", "T", "ja-JP-u-attr1-ca-gregory",
"ja_JP@attribute=attr1;calendar=gregorian"},
- {"U", "en@colnumeric=yes", "K", "kn", "true", "T", "en-u-kn-true",
+ {"U", "en@colnumeric=yes", "K", "kn", "true", "T", "en-u-kn",
"en@colnumeric=yes"},
{"L", "th", "R", "th", "K", "nu", "thai", "T", "th-TH-u-nu-thai",
"th_TH@numbers=thai"},
// However, once the legacy keyword is translated back to BCP 47 u extension, key "0a" is unknown,
// so "yes" is preserved - not mapped to "true". We could change the code to automatically transform
// key = alphanum alpha
- {"L", "en", "E", "u", "bbb-aaa-0a", "T", "en-u-aaa-bbb-0a-yes",
+ {"L", "en", "E", "u", "bbb-aaa-0a", "T", "en-u-aaa-bbb-0a",
"en@0a=yes;attribute=aaa-bbb"},
{"L", "fr", "R", "FR", "P", "Yoshito-ICU", "T", "fr-FR-x-yoshito-icu",
"fr_FR@x=yoshito-icu"},
{"L", "en", "K", "tz", "usnyc", "R", "US", "T", "en-US-u-tz-usnyc",
"en_US@timezone=America/New_York"},
{"L", "de", "K", "co", "phonebk", "K", "ks", "level1", "K", "kk",
- "true", "T", "de-u-co-phonebk-kk-true-ks-level1",
+ "true", "T", "de-u-co-phonebk-kk-ks-level1",
"de@collation=phonebook;colnormalization=yes;colstrength=primary"},
{"L", "en", "R", "US", "K", "ca", "gregory", "T", "en-US-u-ca-gregory",
"en_US@calendar=gregorian"},
{"L", "en", "R", "US", "K", "cal", "gregory", "X"},
{"L", "en", "R", "US", "K", "ca", "gregorian", "X"},
- {"L", "en", "R", "US", "K", "kn", "true", "T", "en-US-u-kn-true",
+ {"L", "en", "R", "US", "K", "kn", "true", "T", "en-US-u-kn",
"en_US@colnumeric=yes"},
{"B", "de-DE-u-co-phonebk", "C", "L", "pt", "T", "pt", "pt"},
{"B", "ja-jp-u-ca-japanese", "N", "T", "ja-JP", "ja_JP"},
TESTCASE_AUTO(TestConstructorAcceptsBCP47);
TESTCASE_AUTO(TestForLanguageTag);
TESTCASE_AUTO(TestToLanguageTag);
+ TESTCASE_AUTO(TestToLanguageTagOmitTrue);
TESTCASE_AUTO(TestMoveAssign);
TESTCASE_AUTO(TestMoveCtor);
TESTCASE_AUTO(TestBug20407iVariantPreferredValue);
assertTrue(result_bogus.c_str(), result_bogus.empty());
}
+/* ICU-20310 */
+void LocaleTest::TestToLanguageTagOmitTrue() {
+ IcuTestErrorCode status(*this, "TestToLanguageTagOmitTrue()");
+ assertEquals("en-u-kn should drop true",
+ "en-u-kn", Locale("en-u-kn-true").toLanguageTag<std::string>(status).c_str());
+ status.errIfFailureAndReset();
+ assertEquals("en-u-kn should drop true",
+ "en-u-kn", Locale("en-u-kn").toLanguageTag<std::string>(status).c_str());
+ status.errIfFailureAndReset();
+
+ assertEquals("de-u-co should drop true",
+ "de-u-co", Locale("de-u-co").toLanguageTag<std::string>(status).c_str());
+ status.errIfFailureAndReset();
+ assertEquals("de-u-co should drop true",
+ "de-u-co", Locale("de-u-co-yes").toLanguageTag<std::string>(status).c_str());
+ status.errIfFailureAndReset();
+ assertEquals("de@collation=yes should drop true",
+ "de-u-co", Locale("de@collation=yes").toLanguageTag<std::string>(status).c_str());
+ status.errIfFailureAndReset();
+
+ assertEquals("cmn-Hans-CN-t-ca-u-ca-x-t-u should drop true",
+ "cmn-Hans-CN-t-ca-u-ca-x-t-u",
+ Locale("cmn-hans-cn-u-ca-t-ca-x-t-u").toLanguageTag<std::string>(status).c_str());
+ status.errIfFailureAndReset();
+}
+
void LocaleTest::TestMoveAssign() {
// ULOC_FULLNAME_CAPACITY == 157 (uloc.h)
Locale l1("de@collation=phonebook;x="
void TestForLanguageTag();
void TestToLanguageTag();
+ void TestToLanguageTagOmitTrue();
void TestMoveAssign();
void TestMoveCtor();
}
public static String canonicalizeExtension(String s) {
- return AsciiUtil.toLowerString(s);
+ s = AsciiUtil.toLowerString(s);
+ int found;
+ while (s.endsWith("-true")) {
+ s = s.substring(0, s.length() - 5); // length of "-true" is 5
+ }
+ while ((found = s.indexOf("-true-")) > 0) {
+ s = s.substring(0, found) + s.substring(found + 5); // length of "-true" is 5
+ }
+ while (s.endsWith("-yes")) {
+ s = s.substring(0, s.length() - 4); // length of "-yes" is 4
+ }
+ while ((found = s.indexOf("-yes-")) > 0) {
+ s = s.substring(0, found) + s.substring(found + 4); // length of "-yes" is 5
+ }
+ return s;
}
public static String canonicalizeExtensionSingleton(String s) {
{"U", "ja_JP@calendar=japanese;currency=JPY", "L", "ko", "T", "ko-JP-u-ca-japanese-cu-jpy", "ko_JP@calendar=japanese;currency=jpy"},
{"U", "ja_JP@calendar=japanese;currency=JPY", "K", "ca", null, "T", "ja-JP-u-cu-jpy", "ja_JP@currency=jpy"},
{"U", "ja_JP@calendar=japanese;currency=JPY", "E", "u", "attr1-ca-gregory", "T", "ja-JP-u-attr1-ca-gregory", "ja_JP@attribute=attr1;calendar=gregorian"},
- {"U", "en@colnumeric=yes", "K", "kn", "", "T", "en-u-kn-true", "en@colnumeric=yes"},
+ {"U", "en@colnumeric=yes", "K", "kn", "", "T", "en-u-kn", "en@colnumeric=yes"},
{"L", "th", "R", "th", "K", "nu", "thai", "T", "th-TH-u-nu-thai", "th_TH@numbers=thai"},
{"U", "zh_Hans", "R", "sg", "K", "ca", "badcalendar", "X"},
{"U", "zh_Hans", "R", "sg", "K", "cal", "gregory", "X"},
// However, once the legacy keyword is translated back to BCP 47 u extension, key "0a" is unknown,
// so "yes" is preserved - not mapped to "true". We could change the code to automatically transform
// "yes" to "true", but it will break roundtrip conversion if BCP 47 u extension has "0a-yes".
- {"L", "en", "E", "u", "bbb-aaa-0a", "T", "en-u-aaa-bbb-0a-yes", "en@0a=yes;attribute=aaa-bbb"},
+ {"L", "en", "E", "u", "bbb-aaa-0a", "T", "en-u-aaa-bbb-0a", "en@0a=yes;attribute=aaa-bbb"},
{"L", "fr", "R", "FR", "P", "Yoshito-ICU", "T", "fr-FR-x-yoshito-icu", "fr_FR@x=yoshito-icu"},
{"L", "ja", "R", "jp", "K", "ca", "japanese", "T", "ja-JP-u-ca-japanese", "ja_JP@calendar=japanese"},
{"K", "co", "PHONEBK", "K", "ca", "gregory", "L", "De", "T", "de-u-ca-gregory-co-phonebk", "de@calendar=gregorian;collation=phonebook"},
{"E", "o", "OPQR", "E", "a", "aBcD", "T", "und-a-abcd-o-opqr", "@a=abcd;o=opqr"},
{"E", "u", "nu-thai-ca-gregory", "L", "TH", "T", "th-u-ca-gregory-nu-thai", "th@calendar=gregorian;numbers=thai"},
{"L", "en", "K", "tz", "usnyc", "R", "US", "T", "en-US-u-tz-usnyc", "en_US@timezone=America/New_York"},
- {"L", "de", "K", "co", "phonebk", "K", "ks", "level1", "K", "kk", "true", "T", "de-u-co-phonebk-kk-true-ks-level1", "de@collation=phonebook;colnormalization=yes;colstrength=primary"},
+ {"L", "de", "K", "co", "phonebk", "K", "ks", "level1", "K", "kk", "true", "T", "de-u-co-phonebk-kk-ks-level1", "de@collation=phonebook;colnormalization=yes;colstrength=primary"},
{"L", "en", "R", "US", "K", "ca", "gregory", "T", "en-US-u-ca-gregory", "en_US@calendar=gregorian"},
{"L", "en", "R", "US", "K", "cal", "gregory", "X"},
{"L", "en", "R", "US", "K", "ca", "gregorian", "X"},
- {"L", "en", "R", "US", "K", "kn", "", "T", "en-US-u-kn-true", "en_US@colnumeric=yes"},
+ {"L", "en", "R", "US", "K", "kn", "", "T", "en-US-u-kn", "en_US@colnumeric=yes"},
{"B", "de-DE-u-co-phonebk", "C", "L", "pt", "T", "pt", "pt"},
{"B", "ja-jp-u-ca-japanese", "N", "T", "ja-JP", "ja_JP"},
{"B", "es-u-def-abc-co-trad", "A", "hij", "D", "def", "T", "es-u-abc-hij-co-trad", "es@attribute=abc-hij;collation=traditional"},
/* ICU-20478 */
{"sl__ROZAJ_BISKE_1994", "sl-1994-biske-rozaj"},
{"en__SCOUSE_FONIPA", "en-fonipa-scouse"},
+ /* ICU-20310 */
+ {"en-u-kn-true", "en-u-kn"},
+ {"en-u-kn", "en-u-kn"},
+ {"de-u-co-yes", "de-u-co"},
+ {"de-u-co", "de-u-co"},
+ {"de@collation=yes", "de-u-co"},
+ {"cmn-hans-cn-u-ca-t-ca-x-t-u", "cmn-Hans-CN-t-ca-u-ca-x-t-u"},
};
for (int i = 0; i < locale_to_langtag.length; i++) {