]> granicus.if.org Git - icu/commitdiff
ICU-20320 Fix the missing digit singleton extension
authorFrank Tang <ftang@chromium.org>
Fri, 21 Dec 2018 22:45:47 +0000 (14:45 -0800)
committerFrank Yung-Fong Tang <41213225+FrankYFTang@users.noreply.github.com>
Thu, 7 Feb 2019 19:35:55 +0000 (11:35 -0800)
Add space

add test cases for Java and fix Java code

icu4c/source/common/uloc_tag.cpp
icu4c/source/test/cintltst/cloctst.c
icu4c/source/test/intltest/loctest.cpp
icu4j/main/classes/core/src/com/ibm/icu/impl/locale/LanguageTag.java
icu4j/main/tests/core/src/com/ibm/icu/dev/test/util/ULocaleTest.java

index bdc0652df0aff30da27aa6b85ac65961c55bc555..9b5de7f1d9c80934ed4c16af14cc95a3c80ce32e 100644 (file)
@@ -507,11 +507,17 @@ static UBool
 _isExtensionSingleton(const char* s, int32_t len) {
     /*
      * extension     = singleton 1*("-" (2*8alphanum))
+     *
+     * singleton     = DIGIT               ; 0 - 9
+     *               / %x41-57             ; A - W
+     *               / %x59-5A             ; Y - Z
+     *               / %x61-77             ; a - w
+     *               / %x79-7A             ; y - z
      */
     if (len < 0) {
         len = (int32_t)uprv_strlen(s);
     }
-    if (len == 1 && ISALPHA(*s) && (uprv_tolower(*s) != PRIVATEUSE)) {
+    if (len == 1 && (ISALPHA(*s) || ISNUMERIC(*s)) && (uprv_tolower(*s) != PRIVATEUSE)) {
         return TRUE;
     }
     return FALSE;
index 99f9970a82b0bb19ea620478da767dcf34445a31..a5b6fe0988562ae0a8057bfee7057f36a23b8725 100644 (file)
@@ -5968,6 +5968,7 @@ const char* const locale_to_langtag[][3] = {
     {"en@attribute=baz;calendar=islamic-civil", "en-u-baz-ca-islamic-civil",    "en-u-baz-ca-islamic-civil"},
     {"en@a=bar;calendar=islamic-civil;x=u-foo", "en-a-bar-u-ca-islamic-civil-x-u-foo",  "en-a-bar-u-ca-islamic-civil-x-u-foo"},
     {"en@a=bar;attribute=baz;calendar=islamic-civil;x=u-foo",   "en-a-bar-u-baz-ca-islamic-civil-x-u-foo",  "en-a-bar-u-baz-ca-islamic-civil-x-u-foo"},
+    {"en@9=efg;a=baz",    "en-9-efg-a-baz", "en-9-efg-a-baz"},
     {NULL,          NULL,           NULL}
 };
 
@@ -6154,6 +6155,7 @@ static const struct {
     {"sgn-br-u-co-phonebk", "bzs@collation=phonebook", FULL_LENGTH},
     {"ja-latn-hepburn-heploc", "ja_Latn__ALALC97", FULL_LENGTH},
     {"ja-latn-hepburn-heploc-u-ca-japanese", "ja_Latn__ALALC97@calendar=japanese", FULL_LENGTH},
+    {"en-a-bcde-0-fgh", "en@0=fgh;a=bcde", FULL_LENGTH},
 };
 
 static void TestForLanguageTag(void) {
index 08513917babe8fefacd8aaeaf7ef979738d0501d..0a0855ca71adc1c6b361f8d4c9a7946de40bf487 100644 (file)
@@ -2977,12 +2977,14 @@ void LocaleTest::TestForLanguageTag() {
     static const char tag_af[] = "af-t-ar-i0-handwrit-u-ca-coptic-x-foo";
     static const char tag_ill[] = "!";
     static const char tag_no_nul[] = { 'e', 'n', '-', 'G', 'B' };
+    static const char tag_ext[] = "en-GB-1-abc-efg-a-xyz";
 
     static const Locale loc_en("en_US");
     static const Locale loc_oed("en_GB_OXENDICT");
     static const Locale loc_af("af@calendar=coptic;t=ar-i0-handwrit;x=foo");
     static const Locale loc_null("");
     static const Locale loc_gb("en_GB");
+    static const Locale loc_ext("en_GB@1=abc-efg;a=xyz");
 
     Locale result_en = Locale::forLanguageTag(tag_en, status);
     status.errIfFailureAndReset("\"%s\"", tag_en);
@@ -3015,6 +3017,10 @@ void LocaleTest::TestForLanguageTag() {
     status.errIfFailureAndReset("\"%.*s\"", sp_no_nul.size(), sp_no_nul.data());
     assertEquals(CharString(sp_no_nul, status).data(),
             loc_gb.getName(), result_no_nul.getName());
+
+    Locale result_ext = Locale::forLanguageTag(tag_ext, status);
+    status.errIfFailureAndReset("\"%s\"", tag_ext);
+    assertEquals(tag_ext, loc_ext.getName(), result_ext.getName());
 }
 
 void LocaleTest::TestToLanguageTag() {
@@ -3023,12 +3029,14 @@ void LocaleTest::TestToLanguageTag() {
     static const Locale loc_c("C");
     static const Locale loc_en("en_US");
     static const Locale loc_af("af@calendar=coptic;t=ar-i0-handwrit;x=foo");
+    static const Locale loc_ext("en@0=abc;a=xyz");
     static const Locale loc_empty("");
     static const Locale loc_ill("!");
 
     static const char tag_c[] = "en-US-u-va-posix";
     static const char tag_en[] = "en-US";
     static const char tag_af[] = "af-t-ar-i0-handwrit-u-ca-coptic-x-foo";
+    static const char tag_ext[] = "en-0-abc-a-xyz";
     static const char tag_und[] = "und";
 
     std::string result;
@@ -3049,6 +3057,10 @@ void LocaleTest::TestToLanguageTag() {
     status.errIfFailureAndReset("\"%s\"", loc_af.getName());
     assertEquals(loc_af.getName(), tag_af, result_af.c_str());
 
+    std::string result_ext = loc_ext.toLanguageTag<std::string>(status);
+    status.errIfFailureAndReset("\"%s\"", loc_ext.getName());
+    assertEquals(loc_ext.getName(), tag_ext, result_ext.c_str());
+
     std::string result_empty = loc_empty.toLanguageTag<std::string>(status);
     status.errIfFailureAndReset("\"%s\"", loc_empty.getName());
     assertEquals(loc_empty.getName(), tag_und, result_empty.c_str());
index 0b3d532c0e5de12aeefc588054341f6d8dd7cb13..2618b0ee7a4927c175b7349e0cd62838da63d410 100644 (file)
@@ -622,7 +622,7 @@ public class LanguageTag {
         //               / %x79-7A             ; y - z
 
         return (s.length() == 1)
-                && AsciiUtil.isAlphaString(s)
+                && AsciiUtil.isAlphaNumericString(s)
                 && !AsciiUtil.caseIgnoreMatch(PRIVATEUSE, s);
     }
 
index 8ffc478c7ba77bd41f2d8df56176fc85eac53a59..26c419daa9180f2c1c1df4b6c2f960e91be6893a 100644 (file)
@@ -4068,6 +4068,8 @@ public class ULocaleTest extends TestFmwk {
                 {"en@attribute=baz;calendar=islamic-civil", "en-u-baz-ca-islamic-civil"},
                 {"en@a=bar;calendar=islamic-civil;x=u-foo", "en-a-bar-u-ca-islamic-civil-x-u-foo"},
                 {"en@a=bar;attribute=baz;calendar=islamic-civil;x=u-foo",   "en-a-bar-u-baz-ca-islamic-civil-x-u-foo"},
+                /* ICU-20320*/
+                {"en@9=efg;a=baz",   "en-9-efg-a-baz"},
         };
 
         for (int i = 0; i < locale_to_langtag.length; i++) {
@@ -4093,6 +4095,13 @@ public class ULocaleTest extends TestFmwk {
         }
     }
 
+    @Test
+    public void TestDigitSingletonExtensionBug20320() {
+        ULocale uloc = ULocale.forLanguageTag("en-0-abc-a-xyz");
+        assertEquals("getExtension(\'a\')", "xyz", uloc.getExtension('a'));
+        assertEquals("getExtension(\'0\')", "abc", uloc.getExtension('0'));
+    }
+
     @Test
     public void TestForLanguageTag() {
         final Integer NOERROR = Integer.valueOf(-1);