• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // © 2023 and later: Unicode, Inc. and others.
2 // License & terms of use: http://www.unicode.org/copyright.html
3 
4 #include "unicode/ctest.h"
5 #include "unicode/uloc.h"
6 #include "unicode/ulocale.h"
7 #include "cintltst.h"
8 #include "cmemory.h"
9 #include "cstring.h"
10 
11 #define WHERE __FILE__ ":" XLINE(__LINE__) " "
12 #define XLINE(s) LINE(s)
13 #define LINE(s) #s
14 
15 #define TESTCASE(name) addTest(root, &name, "tsutil/ulocaletst/" #name)
16 
17 enum {
18     LANGUAGE = 0,
19     SCRIPT,
20     REGION,
21     VAR,
22     NAME,
23     BASENAME,
24 };
25 static const char* const rawData[][6] = {
26     { "en", "", "US", "", "en_US", "en_US"},
27     { "fr", "", "FR", "", "fr_FR", "fr_FR"},
28     { "ca", "", "ES", "", "ca_ES", "ca_ES"},
29     { "el", "", "GR", "", "el_GR", "el_GR"},
30     { "no", "", "NO", "NY", "no_NO_NY", "no_NO_NY"},
31     { "it", "", "", "", "it", "it"},
32     { "xx", "", "YY", "", "xx_YY", "xx_YY"},
33     { "zh", "Hans", "CN", "", "zh_Hans_CN", "zh_Hans_CN"},
34     { "zh", "Hans", "CN", "", "zh_Hans_CN", "zh_Hans_CN"},
35     { "x-klingon", "Latn", "ZX", "", "x-klingon_Latn_ZX.utf32be@special", "x-klingon_Latn_ZX.utf32be@special"},
36 };
37 
TestBasicGetters(void)38 static void TestBasicGetters(void) {
39     for (int32_t i = 0; i < UPRV_LENGTHOF(rawData); i++)  {
40         UErrorCode status = U_ZERO_ERROR;
41         ULocale* l = ulocale_openForLocaleID(rawData[i][NAME], -1, &status);
42         if (assertSuccess(WHERE "ulocale_openForLocaleID()", &status)) {
43             assertEquals(WHERE "ulocale_getLanguage()", rawData[i][LANGUAGE], ulocale_getLanguage(l));
44             assertEquals(WHERE "ulocale_getScript()", rawData[i][SCRIPT], ulocale_getScript(l));
45             assertEquals(WHERE "ulocale_getRegion()", rawData[i][REGION], ulocale_getRegion(l));
46             assertEquals(WHERE "ulocale_getVariant()", rawData[i][VAR], ulocale_getVariant(l));
47             assertEquals(WHERE "ulocale_getLocaleID()", rawData[i][NAME], ulocale_getLocaleID(l));
48             assertEquals(WHERE "ulocale_getBaseName()", rawData[i][BASENAME], ulocale_getBaseName(l));
49             ulocale_close(l);
50         }
51     }
52 }
53 
VerifyMatch(const char * localeID,const char * tag)54 static void VerifyMatch(const char* localeID, const char* tag) {
55     UErrorCode status = U_ZERO_ERROR;
56     ULocale* fromID = ulocale_openForLocaleID(localeID, -1, &status);
57     if (assertSuccess(WHERE "ulocale_openForLocaleID()", &status)) {
58         ULocale* fromTag = ulocale_openForLanguageTag(tag, -1, &status);
59         if (assertSuccess(WHERE "ulocale_openForLanguageTag()", &status)) {
60             assertEquals(tag, ulocale_getLocaleID(fromID), ulocale_getLocaleID(fromTag));
61             ulocale_close(fromTag);
62         }
63         ulocale_close(fromID);
64     }
65 }
66 
TestForLanguageTag(void)67 static void TestForLanguageTag(void) {
68     VerifyMatch("en_US", "en-US");
69     VerifyMatch("en_GB_OXENDICT", "en-GB-oed");
70     VerifyMatch("af@calendar=coptic;t=ar-i0-handwrit;x=foo", "af-t-ar-i0-handwrit-u-ca-coptic-x-foo");
71     VerifyMatch("en_GB", "en-GB");
72     VerifyMatch("en_GB@1=abc-efg;a=xyz", "en-GB-1-abc-efg-a-xyz"); // ext
73     VerifyMatch("sl__1994_BISKE_ROZAJ", "sl-rozaj-biske-1994"); // var
74 
75     UErrorCode status = U_ZERO_ERROR;
76     ULocale* result_ill = ulocale_openForLanguageTag("!", -1, &status);
77     assertIntEquals("!", U_ILLEGAL_ARGUMENT_ERROR, status);
78     assertPtrEquals("!", NULL, result_ill);
79     ulocale_close(result_ill);
80 
81     VerifyMatch("", NULL);
82 
83     // ICU-21433
84     VerifyMatch("__1994_BISKE_ROZAJ", "und-1994-biske-rozaj");
85     VerifyMatch("de__1994_BISKE_ROZAJ", "de-1994-biske-rozaj");
86     VerifyMatch("@x=private", "und-x-private");
87     VerifyMatch("de__1994_BISKE_ROZAJ@x=private", "de-1994-biske-rozaj-x-private");
88     VerifyMatch("__1994_BISKE_ROZAJ@x=private", "und-1994-biske-rozaj-x-private");
89 }
90 
TestGetKeywords(void)91 static void TestGetKeywords(void) {
92     UErrorCode status = U_ZERO_ERROR;
93     ULocale* l = ulocale_openForLocaleID("de@calendar=buddhist;collation=phonebook", -1, &status);
94     if (assertSuccess(WHERE "ulocale_openForLocaleID()", &status)) {
95         UEnumeration* en = ulocale_getKeywords(l, &status);
96         if (assertSuccess(WHERE "ulocale_getKeywords()", &status)) {
97             assertIntEquals("uenum_count()", 2, uenum_count(en, &status));
98             bool hasCalendar = false;
99             bool hasCollation = false;
100             const char* key = NULL;
101             while ((key = uenum_next(en, NULL, &status)) != NULL) {
102                 if (uprv_strcmp(key, "calendar") == 0) {
103                     hasCalendar = true;
104                 } else if (uprv_strcmp(key, "collation") == 0) {
105                     hasCollation = true;
106                 }
107             }
108             assertTrue(
109                 WHERE "ulocale_getKeywords() should return UEnumeration that has \"calendar\"",
110                 hasCalendar);
111             assertTrue(
112                 WHERE "ulocale_getKeywords() should return UEnumeration that has \"collation\"",
113                 hasCollation);
114             uenum_close(en);
115         }
116         ulocale_close(l);
117     }
118 }
119 
TestGetKeywordsEmpty(void)120 static void TestGetKeywordsEmpty(void) {
121     UErrorCode status = U_ZERO_ERROR;
122     ULocale* l = ulocale_openForLocaleID("de", -1, &status);
123     if (assertSuccess(WHERE "ulocale_openForLocaleID()", &status)) {
124         UEnumeration* en = ulocale_getKeywords(l, &status);
125         if (assertSuccess(WHERE "ulocale_getKeywords()", &status)) {
126             assertPtrEquals(WHERE "ulocale_getKeyword()", NULL, en);
127             uenum_close(en);
128         }
129         ulocale_close(l);
130     }
131 }
132 
TestGetKeywordsWithPrivateUse(void)133 static void TestGetKeywordsWithPrivateUse(void) {
134     UErrorCode status = U_ZERO_ERROR;
135     ULocale* l = ulocale_openForLanguageTag("en-US-u-ca-gregory-x-foo", -1, &status);
136     if (assertSuccess(WHERE "ulocale_openForLanguageTag()", &status)) {
137         UEnumeration* en = ulocale_getKeywords(l, &status);
138         if (assertSuccess(WHERE "ulocale_getKeywords()", &status)) {
139             assertIntEquals("uenum_count()", 2, uenum_count(en, &status));
140             bool hasCalendar = false;
141             bool hasX = false;
142             const char* key = NULL;
143             while ((key = uenum_next(en, NULL, &status)) != NULL) {
144                 if (uprv_strcmp(key, "calendar") == 0) {
145                     hasCalendar = true;
146                 } else if (uprv_strcmp(key, "x") == 0) {
147                     hasX = true;
148                 }
149             }
150             assertTrue(WHERE "ulocale_getKeywords() should return UEnumeration that has \"calendar\"",
151                        hasCalendar);
152             assertTrue(WHERE "ulocale_getKeywords() should return UEnumeration that has \"x\"",
153                        hasX);
154             uenum_close(en);
155         }
156         ulocale_close(l);
157     }
158 }
159 
TestGetUnicodeKeywords(void)160 static void TestGetUnicodeKeywords(void) {
161     UErrorCode status = U_ZERO_ERROR;
162     ULocale* l = ulocale_openForLocaleID("de@calendar=buddhist;collation=phonebook", -1, &status);
163     if (assertSuccess(WHERE "ulocale_openForLocaleID()", &status)) {
164         UEnumeration* en = ulocale_getUnicodeKeywords(l, &status);
165         if (assertSuccess(WHERE "ulocale_getUnicodeKeywords()", &status)) {
166             assertIntEquals("uenum_count()", 2, uenum_count(en, &status));
167             bool hasCa = false;
168             bool hasCo = false;
169             const char* key = NULL;
170             while ((key = uenum_next(en, NULL, &status)) != NULL) {
171                 if (uprv_strcmp(key, "ca") == 0) {
172                     hasCa = true;
173                 } else if (uprv_strcmp(key, "co") == 0) {
174                     hasCo = true;
175                 }
176             }
177             assertTrue(
178                 WHERE "ulocale_getUnicodeKeywords() should return UEnumeration that has \"ca\"",
179                 hasCa);
180             assertTrue(
181                 WHERE "ulocale_getUnicodeKeywords() should return UEnumeration that has \"co\"",
182                 hasCo);
183             uenum_close(en);
184         }
185         ulocale_close(l);
186     }
187 }
188 
TestGetUnicodeKeywordsEmpty(void)189 static void TestGetUnicodeKeywordsEmpty(void) {
190     UErrorCode status = U_ZERO_ERROR;
191     ULocale* l = ulocale_openForLocaleID("de", -1, &status);
192     if (assertSuccess(WHERE "ulocale_openForLocaleID()", &status)) {
193         UEnumeration* en = ulocale_getUnicodeKeywords(l, &status);
194         if (assertSuccess(WHERE "ulocale_getUnicodeKeywords()", &status)) {
195             assertPtrEquals("ulocale_getUnicodeKeyword()", NULL, en);
196             uenum_close(en);
197         }
198         ulocale_close(l);
199     }
200 }
201 
TestGetUnicodeKeywordsWithPrivateUse(void)202 static void TestGetUnicodeKeywordsWithPrivateUse(void) {
203     UErrorCode status = U_ZERO_ERROR;
204     ULocale* l = ulocale_openForLanguageTag("en-US-u-ca-gregory-x-foo", -1, &status);
205     if (assertSuccess(WHERE "ulocale_openForLanguageTag()", &status)) {
206         UEnumeration* en = ulocale_getUnicodeKeywords(l, &status);
207         if (assertSuccess(WHERE "ulocale_getUnicodeKeywords()", &status)) {
208             int32_t count = uenum_count(en, &status);
209             if (count != 1) {
210                 log_knownIssue("ICU-22457", "uenum_count() should be 1 but get %d\n", count);
211             }
212             const char* key = uenum_next(en, NULL, &status);
213             if (assertSuccess(WHERE "uenum_next()", &status)) {
214                 assertEquals(WHERE "ulocale_getUnicodeKeywords() should return UEnumeration that has \"ca\"",
215                              "ca", key);
216             }
217             uenum_close(en);
218         }
219         ulocale_close(l);
220     }
221 }
222 
TestGetKeywordValue(void)223 static void TestGetKeywordValue(void) {
224     UErrorCode status = U_ZERO_ERROR;
225     ULocale* l = ulocale_openForLanguageTag("fa-u-nu-thai", -1, &status);
226     if (assertSuccess(WHERE "ulocale_openForLanguageTag()", &status)) {
227         char buffer[ULOC_FULLNAME_CAPACITY];
228         ulocale_getKeywordValue(l, "numbers", -1, buffer, ULOC_FULLNAME_CAPACITY, &status);
229         if (assertSuccess(WHERE "ulocale_getKeywordValue()", &status)) {
230             assertEquals(WHERE "ulocale_getKeywordValue(\"numbers\")", "thai", buffer);
231         }
232 
233         ulocale_getKeywordValue(l, "calendar", -1, buffer, ULOC_FULLNAME_CAPACITY, &status);
234         if (assertSuccess(WHERE "ulocale_getKeywordValue()", &status)) {
235             assertEquals(WHERE "ulocale_getKeywordValue(\"calendar\")", "", buffer);
236         }
237         ulocale_getKeywordValue(l, "collation", -1, buffer, ULOC_FULLNAME_CAPACITY, &status);
238         if (assertSuccess(WHERE "ulocale_getKeywordValue()", &status)) {
239             assertEquals(WHERE "ulocale_getKeywordValue(\"collation\")", "", buffer);
240         }
241         ulocale_close(l);
242     }
243 }
244 
TestGetUnicodeKeywordValue(void)245 static void TestGetUnicodeKeywordValue(void) {
246     UErrorCode status = U_ZERO_ERROR;
247     ULocale* l = ulocale_openForLanguageTag("fa-u-nu-thai", -1, &status);
248     if (assertSuccess(WHERE "ulocale_openForLanguageTag()", &status)) {
249         char buffer[ULOC_FULLNAME_CAPACITY];
250         ulocale_getUnicodeKeywordValue(l, "nu", -1, buffer, ULOC_FULLNAME_CAPACITY, &status);
251         if (assertSuccess(WHERE "ulocale_getUnicodeKeywordValue()", &status)) {
252             assertEquals(WHERE "ulocale_getUnicodeKeywordValue(\"nu\")", "thai", buffer);
253         }
254 
255         ulocale_getUnicodeKeywordValue(l, "ca", -1, buffer, ULOC_FULLNAME_CAPACITY, &status);
256         if (U_FAILURE(status) || buffer[0] != '\0') {
257             log_knownIssue(
258                 "ICU-22459",
259                 WHERE "ulocale_getUnicodeKeywordValue(\"fa-u-nu-thai\", \"ca\") should not return error and should return empty string.");
260         }
261         ulocale_getUnicodeKeywordValue(l, "co", -1, buffer, ULOC_FULLNAME_CAPACITY, &status);
262         if (U_FAILURE(status) || buffer[0] != '\0') {
263             log_knownIssue(
264                 "ICU-22459",
265                 WHERE "ulocale_getUnicodeKeywordValue(\"fa-u-nu-thai\", \"co\") should not return error and should return empty string.");
266         }
267         ulocale_close(l);
268     }
269 }
270 
271 void addULocaleTest(TestNode** root);
addULocaleTest(TestNode ** root)272 void addULocaleTest(TestNode** root)
273 {
274     TESTCASE(TestBasicGetters);
275     TESTCASE(TestForLanguageTag);
276     TESTCASE(TestGetKeywords);
277     TESTCASE(TestGetKeywordsEmpty);
278     TESTCASE(TestGetKeywordsWithPrivateUse);
279     TESTCASE(TestGetUnicodeKeywords);
280     TESTCASE(TestGetUnicodeKeywordsEmpty);
281     TESTCASE(TestGetUnicodeKeywordsWithPrivateUse);
282     TESTCASE(TestGetKeywordValue);
283     TESTCASE(TestGetUnicodeKeywordValue);
284 }
285 
286