1 // © 2016 and later: Unicode, Inc. and others.
2 // License & terms of use: http://www.unicode.org/copyright.html
3 /********************************************************************
5 * Copyright (c) 1997-2016, International Business Machines Corporation and
6 * others. All Rights Reserved.
7 ********************************************************************/
8 /*****************************************************************************
12 * Modification History:
14 * Madhu Katragadda Ported for C API
15 ******************************************************************************
28 #include "unicode/putil.h"
29 #include "unicode/ubrk.h"
30 #include "unicode/uchar.h"
31 #include "unicode/ucol.h"
32 #include "unicode/udat.h"
33 #include "unicode/uloc.h"
34 #include "unicode/umsg.h"
35 #include "unicode/ures.h"
36 #include "unicode/uset.h"
37 #include "unicode/ustring.h"
38 #include "unicode/utypes.h"
39 #include "unicode/ulocdata.h"
40 #include "unicode/uldnames.h"
41 #include "unicode/parseerr.h" /* may not be included with some uconfig switches */
43 #include "unicode/ualoc.h" /* Apple-specific */
45 static void TestNullDefault(void);
46 static void TestNonexistentLanguageExemplars(void);
47 static void TestLocDataErrorCodeChaining(void);
48 static void TestLocDataWithRgTag(void);
49 static void TestLanguageExemplarsFallbacks(void);
50 static void TestDisplayNameBrackets(void);
52 static void TestUnicodeDefines(void);
54 static void TestIsRightToLeft(void);
55 static void TestBadLocaleIDs(void);
57 static void TestUldnNameVariants(void);
58 static void TestGetLanguagesForRegion(void);
59 static void TestGetAppleParent(void);
60 static void TestAppleLocalizationsToUse(void);
62 void PrintDataTable();
64 /*---------------------------------------------------
66 --------------------------------------------------- */
68 #define LOCALE_INFO_SIZE 28
70 static const char* const rawData2
[LOCALE_INFO_SIZE
][LOCALE_SIZE
] = {
72 { "en", "fr", "ca", "el", "no", "zh", "de", "es", "ja" },
74 { "", "", "", "", "", "", "", "", "" },
76 { "US", "FR", "ES", "GR", "NO", "CN", "DE", "", "JP" },
78 { "", "", "", "", "NY", "", "", "", "" },
80 { "en_US", "fr_FR", "ca_ES",
81 "el_GR", "no_NO_NY", "zh_Hans_CN",
82 "de_DE@collation=phonebook", "es@collation=traditional", "ja_JP@calendar=japanese" },
84 { "eng", "fra", "cat", "ell", "nor", "zho", "deu", "spa", "jpn" },
86 { "USA", "FRA", "ESP", "GRC", "NOR", "CHN", "DEU", "", "JPN" },
88 { "409", "40c", "403", "408", "814", "804", "10407", "40a", "411" },
90 /* display language (English) */
91 { "English", "French", "Catalan", "Greek", "Norwegian", "Chinese", "German", "Spanish", "Japanese" },
92 /* display script code (English) */
93 { "", "", "", "", "", "Simplified Han", "", "", "" },
94 /* display country (English) */
95 { "United States", "France", "Spain", "Greece", "Norway", "China", "Germany", "", "Japan" },
96 /* display variant (English) */
97 { "", "", "", "", "NY", "", "", "", "" },
98 /* display name (English) */
99 { "English (United States)", "French (France)", "Catalan (Spain)",
100 "Greek (Greece)", "Norwegian (Norway, NY)", "Chinese (Simplified, China)",
101 "German (Germany, Sort Order=Phonebook Sort Order)", "Spanish (Sort Order=Traditional Sort Order)", "Japanese (Japan, Calendar=Japanese Calendar)" },
103 /* display language (French) */
104 { "anglais", "fran\\u00E7ais", "catalan", "grec", "norv\\u00E9gien", "chinois", "allemand", "espagnol", "japonais" },
105 /* display script code (French) */
106 { "", "", "", "", "", "sinogrammes simplifi\\u00e9s", "", "", "" },
107 /* display country (French) */
108 { "\\u00C9tats-Unis", "France", "Espagne", "Gr\\u00E8ce", "Norv\\u00E8ge", "Chine", "Allemagne", "", "Japon" },
109 /* display variant (French) */
110 { "", "", "", "", "NY", "", "", "", "" },
111 /* display name (French) */
112 { "anglais (\\u00C9tats-Unis)", "fran\\u00E7ais (France)", "catalan (Espagne)",
113 "grec (Gr\\u00E8ce)", "norv\\u00E9gien (Norv\\u00E8ge, NY)", "chinois (simplifi\\u00e9, Chine)",
114 "allemand (Allemagne, ordre de tri=ordre de l\\u2019annuaire)", "espagnol (ordre de tri=ordre traditionnel)", "japonais (Japon, calendrier=calendrier japonais)" },
116 /* display language (Catalan) */
117 { "angl\\u00E8s", "franc\\u00E8s", "catal\\u00E0", "grec", "noruec", "xin\\u00E8s", "alemany", "espanyol", "japon\\u00E8s" },
118 /* display script code (Catalan) */
119 { "", "", "", "", "", "han simplificat", "", "", "" },
120 /* display country (Catalan) */
121 { "Estats Units", "Fran\\u00E7a", "Espanya", "Gr\\u00E8cia", "Noruega", "Xina", "Alemanya", "", "Jap\\u00F3" },
122 /* display variant (Catalan) */
123 { "", "", "", "", "NY", "", "", "", "" },
124 /* display name (Catalan) */
125 { "angl\\u00E8s (Estats Units)", "franc\\u00E8s (Fran\\u00E7a)", "catal\\u00E0 (Espanya)",
126 "grec (Gr\\u00E8cia)", "noruec (Noruega, NY)", "xin\\u00E8s (simplificat, Xina)",
127 "alemany (Alemanya, ordenaci\\u00F3=ordre de la guia telef\\u00F2nica)", "espanyol (ordenaci\\u00F3=ordre tradicional)", "japon\\u00E8s (Jap\\u00F3, calendari=calendari japon\\u00e8s)" },
129 /* display language (Greek) */
131 "\\u0391\\u03b3\\u03b3\\u03bb\\u03b9\\u03ba\\u03ac",
132 "\\u0393\\u03b1\\u03bb\\u03bb\\u03b9\\u03ba\\u03ac",
133 "\\u039a\\u03b1\\u03c4\\u03b1\\u03bb\\u03b1\\u03bd\\u03b9\\u03ba\\u03ac",
134 "\\u0395\\u03bb\\u03bb\\u03b7\\u03bd\\u03b9\\u03ba\\u03ac",
135 "\\u039d\\u03bf\\u03c1\\u03b2\\u03b7\\u03b3\\u03b9\\u03ba\\u03ac",
136 "\\u039A\\u03B9\\u03BD\\u03B5\\u03B6\\u03B9\\u03BA\\u03AC",
137 "\\u0393\\u03B5\\u03C1\\u03BC\\u03B1\\u03BD\\u03B9\\u03BA\\u03AC",
138 "\\u0399\\u03C3\\u03C0\\u03B1\\u03BD\\u03B9\\u03BA\\u03AC",
139 "\\u0399\\u03B1\\u03C0\\u03C9\\u03BD\\u03B9\\u03BA\\u03AC"
141 /* display script code (Greek) */
143 { "", "", "", "", "", "\\u0391\\u03c0\\u03bb\\u03bf\\u03c0\\u03bf\\u03b9\\u03b7\\u03bc\\u03ad\\u03bd\\u03bf \\u03a7\\u03b1\\u03bd", "", "", "" },
144 /* display country (Greek) */
146 "\\u0397\\u03BD\\u03C9\\u03BC\\u03AD\\u03BD\\u03B5\\u03C2 \\u03A0\\u03BF\\u03BB\\u03B9\\u03C4\\u03B5\\u03AF\\u03B5\\u03C2",
147 "\\u0393\\u03b1\\u03bb\\u03bb\\u03af\\u03b1",
148 "\\u0399\\u03c3\\u03c0\\u03b1\\u03bd\\u03af\\u03b1",
149 "\\u0395\\u03bb\\u03bb\\u03ac\\u03b4\\u03b1",
150 "\\u039d\\u03bf\\u03c1\\u03b2\\u03b7\\u03b3\\u03af\\u03b1",
151 "\\u039A\\u03AF\\u03BD\\u03B1",
152 "\\u0393\\u03B5\\u03C1\\u03BC\\u03B1\\u03BD\\u03AF\\u03B1",
154 "\\u0399\\u03B1\\u03C0\\u03C9\\u03BD\\u03AF\\u03B1"
156 /* display variant (Greek) */
157 { "", "", "", "", "NY", "", "", "", "" }, /* TODO: currently there is no translation for NY in Greek fix this test when we have it */
158 /* display name (Greek) */
160 "\\u0391\\u03b3\\u03b3\\u03bb\\u03b9\\u03ba\\u03ac (\\u0397\\u03BD\\u03C9\\u03BC\\u03AD\\u03BD\\u03B5\\u03C2 \\u03A0\\u03BF\\u03BB\\u03B9\\u03C4\\u03B5\\u03AF\\u03B5\\u03C2)",
161 "\\u0393\\u03b1\\u03bb\\u03bb\\u03b9\\u03ba\\u03ac (\\u0393\\u03b1\\u03bb\\u03bb\\u03af\\u03b1)",
162 "\\u039a\\u03b1\\u03c4\\u03b1\\u03bb\\u03b1\\u03bd\\u03b9\\u03ba\\u03ac (\\u0399\\u03c3\\u03c0\\u03b1\\u03bd\\u03af\\u03b1)",
163 "\\u0395\\u03bb\\u03bb\\u03b7\\u03bd\\u03b9\\u03ba\\u03ac (\\u0395\\u03bb\\u03bb\\u03ac\\u03b4\\u03b1)",
164 "\\u039d\\u03bf\\u03c1\\u03b2\\u03b7\\u03b3\\u03b9\\u03ba\\u03ac (\\u039d\\u03bf\\u03c1\\u03b2\\u03b7\\u03b3\\u03af\\u03b1, NY)",
165 "\\u039A\\u03B9\\u03BD\\u03B5\\u03B6\\u03B9\\u03BA\\u03AC (\\u0391\\u03c0\\u03bb\\u03bf\\u03c0\\u03bf\\u03b9\\u03b7\\u03bc\\u03ad\\u03bd\\u03b1, \\u039A\\u03AF\\u03BD\\u03B1)",
166 "\\u0393\\u03b5\\u03c1\\u03bc\\u03b1\\u03bd\\u03b9\\u03ba\\u03ac (\\u0393\\u03b5\\u03c1\\u03bc\\u03b1\\u03bd\\u03af\\u03b1, \\u03a3\\u03b5\\u03b9\\u03c1\\u03ac \\u03c4\\u03b1\\u03be\\u03b9\\u03bd\\u03cc\\u03bc\\u03b7\\u03c3\\u03b7\\u03c2=\\u03a3\\u03b5\\u03b9\\u03c1\\u03ac \\u03c4\\u03b1\\u03be\\u03b9\\u03bd\\u03cc\\u03bc\\u03b7\\u03c3\\u03b7\\u03c2 \\u03c4\\u03b7\\u03bb\\u03b5\\u03c6\\u03c9\\u03bd\\u03b9\\u03ba\\u03bf\\u03cd \\u03ba\\u03b1\\u03c4\\u03b1\\u03bb\\u03cc\\u03b3\\u03bf\\u03c5)",
167 "\\u0399\\u03c3\\u03c0\\u03b1\\u03bd\\u03b9\\u03ba\\u03ac (\\u03a3\\u03b5\\u03b9\\u03c1\\u03ac \\u03c4\\u03b1\\u03be\\u03b9\\u03bd\\u03cc\\u03bc\\u03b7\\u03c3\\u03b7\\u03c2=\\u03a0\\u03b1\\u03c1\\u03b1\\u03b4\\u03bf\\u03c3\\u03b9\\u03b1\\u03ba\\u03ae \\u03c3\\u03b5\\u03b9\\u03c1\\u03ac \\u03c4\\u03b1\\u03be\\u03b9\\u03bd\\u03cc\\u03bc\\u03b7\\u03c3\\u03b7\\u03c2)",
168 "\\u0399\\u03b1\\u03c0\\u03c9\\u03bd\\u03b9\\u03ba\\u03ac (\\u0399\\u03b1\\u03c0\\u03c9\\u03bd\\u03af\\u03b1, \\u0397\\u03bc\\u03b5\\u03c1\\u03bf\\u03bb\\u03cc\\u03b3\\u03b9\\u03bf=\\u0399\\u03b1\\u03c0\\u03c9\\u03bd\\u03b9\\u03ba\\u03cc \\u03b7\\u03bc\\u03b5\\u03c1\\u03bf\\u03bb\\u03cc\\u03b3\\u03b9\\u03bf)"
172 static UChar
*** dataTable
=0;
212 #define TESTCASE(name) addTest(root, &name, "tsutil/cloctst/" #name)
214 void addLocaleTest(TestNode
** root
);
216 void addLocaleTest(TestNode
** root
)
218 TESTCASE(TestObsoleteNames
); /* srl- move */
219 TESTCASE(TestBasicGetters
);
220 TESTCASE(TestNullDefault
);
221 TESTCASE(TestPrefixes
);
222 TESTCASE(TestSimpleResourceInfo
);
223 TESTCASE(TestDisplayNames
);
224 TESTCASE(TestGetAvailableLocales
);
225 TESTCASE(TestDataDirectory
);
226 #if !UCONFIG_NO_FILE_IO && !UCONFIG_NO_LEGACY_CONVERSION
227 TESTCASE(TestISOFunctions
);
229 TESTCASE(TestISO3Fallback
);
230 TESTCASE(TestUninstalledISO3Names
);
231 TESTCASE(TestSimpleDisplayNames
);
232 TESTCASE(TestVariantParsing
);
233 TESTCASE(TestKeywordVariants
);
234 TESTCASE(TestKeywordVariantParsing
);
235 TESTCASE(TestCanonicalization
);
236 TESTCASE(TestKeywordSet
);
237 TESTCASE(TestKeywordSetError
);
238 TESTCASE(TestDisplayKeywords
);
239 TESTCASE(TestDisplayKeywordValues
);
240 TESTCASE(TestGetBaseName
);
241 #if !UCONFIG_NO_FILE_IO
242 TESTCASE(TestGetLocale
);
244 TESTCASE(TestDisplayNameWarning
);
245 TESTCASE(TestNonexistentLanguageExemplars
);
246 TESTCASE(TestLocDataErrorCodeChaining
);
247 TESTCASE(TestLocDataWithRgTag
);
248 TESTCASE(TestLanguageExemplarsFallbacks
);
249 TESTCASE(TestCalendar
);
250 TESTCASE(TestDateFormat
);
251 TESTCASE(TestCollation
);
252 TESTCASE(TestULocale
);
253 TESTCASE(TestUResourceBundle
);
254 TESTCASE(TestDisplayName
);
255 TESTCASE(TestAcceptLanguage
);
256 TESTCASE(TestGetLocaleForLCID
);
257 TESTCASE(TestOrientation
);
258 TESTCASE(TestLikelySubtags
);
259 TESTCASE(TestToLanguageTag
);
260 TESTCASE(TestForLanguageTag
);
261 TESTCASE(TestTrailingNull
);
262 TESTCASE(TestUnicodeDefines
);
263 TESTCASE(TestEnglishExemplarCharacters
);
264 TESTCASE(TestDisplayNameBrackets
);
265 TESTCASE(TestIsRightToLeft
);
266 TESTCASE(TestToUnicodeLocaleKey
);
267 TESTCASE(TestToLegacyKey
);
268 TESTCASE(TestToUnicodeLocaleType
);
269 TESTCASE(TestToLegacyType
);
270 TESTCASE(TestBadLocaleIDs
);
271 TESTCASE(TestUldnNameVariants
);
272 TESTCASE(TestGetLanguagesForRegion
);
273 TESTCASE(TestGetAppleParent
);
274 TESTCASE(TestAppleLocalizationsToUse
);
278 /* testing uloc(), uloc_getName(), uloc_getLanguage(), uloc_getVariant(), uloc_getCountry() */
279 static void TestBasicGetters() {
282 UErrorCode status
= U_ZERO_ERROR
;
283 char *testLocale
= 0;
284 char *temp
= 0, *name
= 0;
285 log_verbose("Testing Basic Getters\n");
286 for (i
= 0; i
< LOCALE_SIZE
; i
++) {
287 testLocale
=(char*)malloc(sizeof(char) * (strlen(rawData2
[NAME
][i
])+1));
288 strcpy(testLocale
,rawData2
[NAME
][i
]);
290 log_verbose("Testing %s .....\n", testLocale
);
291 cap
=uloc_getLanguage(testLocale
, NULL
, 0, &status
);
292 if(status
==U_BUFFER_OVERFLOW_ERROR
){
294 temp
=(char*)malloc(sizeof(char) * (cap
+1));
295 uloc_getLanguage(testLocale
, temp
, cap
+1, &status
);
297 if(U_FAILURE(status
)){
298 log_err("ERROR: in uloc_getLanguage %s\n", myErrorName(status
));
300 if (0 !=strcmp(temp
,rawData2
[LANG
][i
])) {
301 log_err(" Language code mismatch: %s versus %s\n", temp
, rawData2
[LANG
][i
]);
305 cap
=uloc_getCountry(testLocale
, temp
, cap
, &status
);
306 if(status
==U_BUFFER_OVERFLOW_ERROR
){
308 temp
=(char*)realloc(temp
, sizeof(char) * (cap
+1));
309 uloc_getCountry(testLocale
, temp
, cap
+1, &status
);
311 if(U_FAILURE(status
)){
312 log_err("ERROR: in uloc_getCountry %s\n", myErrorName(status
));
314 if (0 != strcmp(temp
, rawData2
[CTRY
][i
])) {
315 log_err(" Country code mismatch: %s versus %s\n", temp
, rawData2
[CTRY
][i
]);
319 cap
=uloc_getVariant(testLocale
, temp
, cap
, &status
);
320 if(status
==U_BUFFER_OVERFLOW_ERROR
){
322 temp
=(char*)realloc(temp
, sizeof(char) * (cap
+1));
323 uloc_getVariant(testLocale
, temp
, cap
+1, &status
);
325 if(U_FAILURE(status
)){
326 log_err("ERROR: in uloc_getVariant %s\n", myErrorName(status
));
328 if (0 != strcmp(temp
, rawData2
[VAR
][i
])) {
329 log_err("Variant code mismatch: %s versus %s\n", temp
, rawData2
[VAR
][i
]);
332 cap
=uloc_getName(testLocale
, NULL
, 0, &status
);
333 if(status
==U_BUFFER_OVERFLOW_ERROR
){
335 name
=(char*)malloc(sizeof(char) * (cap
+1));
336 uloc_getName(testLocale
, name
, cap
+1, &status
);
337 } else if(status
==U_ZERO_ERROR
) {
338 log_err("ERROR: in uloc_getName(%s,NULL,0,..), expected U_BUFFER_OVERFLOW_ERROR!\n", testLocale
);
340 if(U_FAILURE(status
)){
341 log_err("ERROR: in uloc_getName %s\n", myErrorName(status
));
343 if (0 != strcmp(name
, rawData2
[NAME
][i
])){
344 log_err(" Mismatch in getName: %s versus %s\n", name
, rawData2
[NAME
][i
]);
354 static void TestNullDefault() {
355 UErrorCode status
= U_ZERO_ERROR
;
356 char original
[ULOC_FULLNAME_CAPACITY
];
358 uprv_strcpy(original
, uloc_getDefault());
359 uloc_setDefault("qq_BLA", &status
);
360 if (uprv_strcmp(uloc_getDefault(), "qq_BLA") != 0) {
361 log_err(" Mismatch in uloc_setDefault: qq_BLA versus %s\n", uloc_getDefault());
363 uloc_setDefault(NULL
, &status
);
364 if (uprv_strcmp(uloc_getDefault(), original
) != 0) {
365 log_err(" uloc_setDefault(NULL, &status) didn't get the default locale back!\n");
369 /* Test that set & get of default locale work, and that
370 * default locales are cached and reused, and not overwritten.
374 const char *n2_en_US
;
376 status
= U_ZERO_ERROR
;
377 uloc_setDefault("en_US", &status
);
378 n_en_US
= uloc_getDefault();
379 if (strcmp(n_en_US
, "en_US") != 0) {
380 log_err("Wrong result from uloc_getDefault(). Expected \"en_US\", got \"%s\"\n", n_en_US
);
383 uloc_setDefault("fr_FR", &status
);
384 n_fr_FR
= uloc_getDefault();
385 if (strcmp(n_en_US
, "en_US") != 0) {
386 log_err("uloc_setDefault altered previously default string."
387 "Expected \"en_US\", got \"%s\"\n", n_en_US
);
389 if (strcmp(n_fr_FR
, "fr_FR") != 0) {
390 log_err("Wrong result from uloc_getDefault(). Expected \"fr_FR\", got %s\n", n_fr_FR
);
393 uloc_setDefault("en_US", &status
);
394 n2_en_US
= uloc_getDefault();
395 if (strcmp(n2_en_US
, "en_US") != 0) {
396 log_err("Wrong result from uloc_getDefault(). Expected \"en_US\", got \"%s\"\n", n_en_US
);
398 if (n2_en_US
!= n_en_US
) {
399 log_err("Default locale cache failed to reuse en_US locale.\n");
402 if (U_FAILURE(status
)) {
403 log_err("Failure returned from uloc_setDefault - \"%s\"\n", u_errorName(status
));
409 /* Test the i- and x- and @ and . functionality
412 #define PREFIXBUFSIZ 128
414 static void TestPrefixes() {
417 const char *loc
, *expected
;
419 static const char * const testData
[][7] =
421 /* NULL canonicalize() column means "expect same as getName()" */
422 {"sv", "", "FI", "AL", "sv-fi-al", "sv_FI_AL", NULL
},
423 {"en", "", "GB", "", "en-gb", "en_GB", NULL
},
424 {"i-hakka", "", "MT", "XEMXIJA", "i-hakka_MT_XEMXIJA", "i-hakka_MT_XEMXIJA", NULL
},
425 {"i-hakka", "", "CN", "", "i-hakka_CN", "i-hakka_CN", NULL
},
426 {"i-hakka", "", "MX", "", "I-hakka_MX", "i-hakka_MX", NULL
},
427 {"x-klingon", "", "US", "SANJOSE", "X-KLINGON_us_SANJOSE", "x-klingon_US_SANJOSE", NULL
},
429 {"zh", "Hans", "", "PINYIN", "zh-Hans-pinyin", "zh_Hans__PINYIN", "zh_Hans@collation=pinyin"},
430 {"hy", "", "", "AREVMDA", "hy_AREVMDA", "hy__AREVMDA", NULL
},
432 {"de", "", "", "1901", "de-1901", "de__1901", NULL
},
433 {"mr", "", "", "", "mr.utf8", "mr.utf8", "mr"},
434 {"de", "", "TV", "", "de-tv.koi8r", "de_TV.koi8r", "de_TV"},
435 {"x-piglatin", "", "ML", "", "x-piglatin_ML.MBE", "x-piglatin_ML.MBE", "x-piglatin_ML"}, /* Multibyte English */
436 {"i-cherokee", "","US", "", "i-Cherokee_US.utf7", "i-cherokee_US.utf7", "i-cherokee_US"},
437 {"x-filfli", "", "MT", "FILFLA", "x-filfli_MT_FILFLA.gb-18030", "x-filfli_MT_FILFLA.gb-18030", "x-filfli_MT_FILFLA"},
438 {"no", "", "NO", "NY", "no-no-ny.utf32@B", "no_NO_NY.utf32@B", "no_NO_NY_B"},
439 {"no", "", "NO", "", "no-no.utf32@B", "no_NO.utf32@B", "no_NO_B"},
440 {"no", "", "", "NY", "no__ny", "no__NY", NULL
},
441 {"no", "", "", "", "no@ny", "no@ny", "no__NY"},
442 {"el", "Latn", "", "", "el-latn", "el_Latn", NULL
},
443 {"en", "Cyrl", "RU", "", "en-cyrl-ru", "en_Cyrl_RU", NULL
},
444 {"zh", "Hant", "TW", "STROKE", "zh-hant_TW_STROKE", "zh_Hant_TW_STROKE", "zh_Hant_TW@collation=stroke"},
445 {"qq", "Qqqq", "QQ", "QQ", "qq_Qqqq_QQ_QQ", "qq_Qqqq_QQ_QQ", NULL
},
446 {"qq", "Qqqq", "", "QQ", "qq_Qqqq__QQ", "qq_Qqqq__QQ", NULL
},
447 {"ab", "Cdef", "GH", "IJ", "ab_cdef_gh_ij", "ab_Cdef_GH_IJ", NULL
}, /* total garbage */
449 {NULL
,NULL
,NULL
,NULL
,NULL
,NULL
,NULL
}
452 static const char * const testTitles
[] = {
453 "uloc_getLanguage()",
459 "uloc_canonicalize()"
462 char buf
[PREFIXBUFSIZ
];
467 for(row
=0;testData
[row
][0] != NULL
;row
++) {
468 loc
= testData
[row
][NAME
];
469 log_verbose("Test #%d: %s\n", row
, loc
);
474 for(n
=0;n
<=(NAME
+2);n
++) {
475 if(n
==NAME
) continue;
477 for(len
=0;len
<PREFIXBUFSIZ
;len
++) {
478 buf
[len
] = '%'; /* Set a tripwire.. */
484 len
= uloc_getLanguage(loc
, buf
, PREFIXBUFSIZ
, &err
);
488 len
= uloc_getScript(loc
, buf
, PREFIXBUFSIZ
, &err
);
492 len
= uloc_getCountry(loc
, buf
, PREFIXBUFSIZ
, &err
);
496 len
= uloc_getVariant(loc
, buf
, PREFIXBUFSIZ
, &err
);
500 len
= uloc_getName(loc
, buf
, PREFIXBUFSIZ
, &err
);
504 len
= uloc_canonicalize(loc
, buf
, PREFIXBUFSIZ
, &err
);
513 log_err("#%d: %s on %s: err %s\n",
514 row
, testTitles
[n
], loc
, u_errorName(err
));
516 log_verbose("#%d: %s on %s: -> [%s] (length %d)\n",
517 row
, testTitles
[n
], loc
, buf
, len
);
519 if(len
!= (int32_t)strlen(buf
)) {
520 log_err("#%d: %s on %s: -> [%s] (length returned %d, actual %d!)\n",
521 row
, testTitles
[n
], loc
, buf
, len
, strlen(buf
)+1);
525 /* see if they smashed something */
526 if(buf
[len
+1] != '%') {
527 log_err("#%d: %s on %s: -> [%s] - wrote [%X] out ofbounds!\n",
528 row
, testTitles
[n
], loc
, buf
, buf
[len
+1]);
531 expected
= testData
[row
][n
];
532 if (expected
== NULL
&& n
== (NAME
+2)) {
533 /* NULL expected canonicalize() means "expect same as getName()" */
534 expected
= testData
[row
][NAME
+1];
536 if(strcmp(buf
, expected
)) {
537 log_err("#%d: %s on %s: -> [%s] (expected '%s'!)\n",
538 row
, testTitles
[n
], loc
, buf
, expected
);
547 /* testing uloc_getISO3Language(), uloc_getISO3Country(), */
548 static void TestSimpleResourceInfo() {
550 char* testLocale
= 0;
555 testLocale
=(char*)malloc(sizeof(char) * 1);
556 expected
=(UChar
*)malloc(sizeof(UChar
) * 1);
559 log_verbose("Testing getISO3Language and getISO3Country\n");
560 for (i
= 0; i
< LOCALE_SIZE
; i
++) {
562 testLocale
=(char*)realloc(testLocale
, sizeof(char) * (u_strlen(dataTable
[NAME
][i
])+1));
563 u_austrcpy(testLocale
, dataTable
[NAME
][i
]);
565 log_verbose("Testing %s ......\n", testLocale
);
567 temp
=uloc_getISO3Language(testLocale
);
568 expected
=(UChar
*)realloc(expected
, sizeof(UChar
) * (strlen(temp
) + 1));
569 u_uastrcpy(expected
,temp
);
570 if (0 != u_strcmp(expected
, dataTable
[LANG3
][i
])) {
571 log_err(" ISO-3 language code mismatch: %s versus %s\n", austrdup(expected
),
572 austrdup(dataTable
[LANG3
][i
]));
575 temp
=uloc_getISO3Country(testLocale
);
576 expected
=(UChar
*)realloc(expected
, sizeof(UChar
) * (strlen(temp
) + 1));
577 u_uastrcpy(expected
,temp
);
578 if (0 != u_strcmp(expected
, dataTable
[CTRY3
][i
])) {
579 log_err(" ISO-3 Country code mismatch: %s versus %s\n", austrdup(expected
),
580 austrdup(dataTable
[CTRY3
][i
]));
582 sprintf(temp2
, "%x", (int)uloc_getLCID(testLocale
));
583 if (strcmp(temp2
, rawData2
[LCID
][i
]) != 0) {
584 log_err("LCID mismatch: %s versus %s\n", temp2
, rawData2
[LCID
][i
]);
593 /* if len < 0, we convert until we hit UChar 0x0000, which is not output. will add trailing null
594 * if there's room but won't be included in result. result < 0 indicates an error.
595 * Returns the number of chars written (not those that would be written if there's enough room.*/
596 static int32_t UCharsToEscapedAscii(const UChar
* utext
, int32_t len
, char* resultChars
, int32_t buflen
) {
597 static const struct {
610 static const int32_t ESCAPE_MAP_LENGTH
= UPRV_LENGTHOF(ESCAPE_MAP
);
611 static const char HEX_DIGITS
[] = {
612 '0', '1', '2', '3', '4', '5', '6', '7',
613 '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'
616 int32_t resultLen
= 0;
617 const int32_t limit
= len
<0 ? buflen
: len
; /* buflen is long enough to hit the buffer limit */
618 const int32_t escapeLimit1
= buflen
-2;
619 const int32_t escapeLimit2
= buflen
-6;
622 if(utext
==NULL
|| resultChars
==NULL
|| buflen
<0) {
626 for(i
=0;i
<limit
&& resultLen
<buflen
;++i
) {
632 for(j
=0;j
<ESCAPE_MAP_LENGTH
&& uc
!=ESCAPE_MAP
[j
].sourceVal
;j
++) {
634 if(j
<ESCAPE_MAP_LENGTH
) {
635 if(resultLen
>escapeLimit1
) {
638 resultChars
[resultLen
++]='\\';
639 resultChars
[resultLen
++]=ESCAPE_MAP
[j
].escapedChar
;
643 u_austrncpy(resultChars
+ resultLen
, &uc
, 1);
648 if(resultLen
>escapeLimit2
) {
652 /* have to escape the uchar */
653 resultChars
[resultLen
++]='\\';
654 resultChars
[resultLen
++]='u';
655 resultChars
[resultLen
++]=HEX_DIGITS
[(uc
>>12)&0xff];
656 resultChars
[resultLen
++]=HEX_DIGITS
[(uc
>>8)&0xff];
657 resultChars
[resultLen
++]=HEX_DIGITS
[(uc
>>4)&0xff];
658 resultChars
[resultLen
++]=HEX_DIGITS
[uc
&0xff];
661 if(resultLen
<buflen
) {
662 resultChars
[resultLen
] = 0;
669 * Jitterbug 2439 -- markus 20030425
671 * The lookup of display names must not fall back through the default
672 * locale because that yields useless results.
674 static void TestDisplayNames()
677 UErrorCode errorCode
=U_ZERO_ERROR
;
679 log_verbose("Testing getDisplayName for different locales\n");
681 log_verbose(" In locale = en_US...\n");
682 doTestDisplayNames("en_US", DLANG_EN
);
683 log_verbose(" In locale = fr_FR....\n");
684 doTestDisplayNames("fr_FR", DLANG_FR
);
685 log_verbose(" In locale = ca_ES...\n");
686 doTestDisplayNames("ca_ES", DLANG_CA
);
687 log_verbose(" In locale = gr_EL..\n");
688 doTestDisplayNames("el_GR", DLANG_EL
);
690 /* test that the default locale has a display name for its own language */
691 errorCode
=U_ZERO_ERROR
;
692 length
=uloc_getDisplayLanguage(NULL
, NULL
, buffer
, UPRV_LENGTHOF(buffer
), &errorCode
);
693 if(U_FAILURE(errorCode
) || (length
<=3 && buffer
[0]<=0x7f)) {
694 /* check <=3 to reject getting the language code as a display name */
695 log_data_err("unable to get a display string for the language of the default locale - %s (Are you missing data?)\n", u_errorName(errorCode
));
698 /* test that we get the language code itself for an unknown language, and a default warning */
699 errorCode
=U_ZERO_ERROR
;
700 length
=uloc_getDisplayLanguage("qq", "rr", buffer
, UPRV_LENGTHOF(buffer
), &errorCode
);
701 if(errorCode
!=U_USING_DEFAULT_WARNING
|| length
!=2 || buffer
[0]!=0x71 || buffer
[1]!=0x71) {
702 log_err("error getting the display string for an unknown language - %s\n", u_errorName(errorCode
));
705 /* test that we get a default warning for a display name where one component is unknown (4255) */
706 errorCode
=U_ZERO_ERROR
;
707 length
=uloc_getDisplayName("qq_US_POSIX", "en_US", buffer
, UPRV_LENGTHOF(buffer
), &errorCode
);
708 if(errorCode
!=U_USING_DEFAULT_WARNING
) {
709 log_err("error getting the display name for a locale with an unknown language - %s\n", u_errorName(errorCode
));
714 static const char *aLocale
= "es@collation=traditional;calendar=japanese";
715 static const char *testL
[] = { "en_US",
719 static const char *expect
[] = { "Spanish (Calendar=Japanese Calendar, Sort Order=Traditional Sort Order)", /* note sorted order of keywords */
720 "espagnol (calendrier=calendrier japonais, ordre de tri=ordre traditionnel)",
721 "espanyol (calendari=calendari japon\\u00e8s, ordenaci\\u00f3=ordre tradicional)",
722 "\\u0399\\u03c3\\u03c0\\u03b1\\u03bd\\u03b9\\u03ba\\u03ac (\\u0397\\u03bc\\u03b5\\u03c1\\u03bf\\u03bb\\u03cc\\u03b3\\u03b9\\u03bf=\\u0399\\u03b1\\u03c0\\u03c9\\u03bd\\u03b9\\u03ba\\u03cc \\u03b7\\u03bc\\u03b5\\u03c1\\u03bf\\u03bb\\u03cc\\u03b3\\u03b9\\u03bf, \\u03a3\\u03b5\\u03b9\\u03c1\\u03ac \\u03c4\\u03b1\\u03be\\u03b9\\u03bd\\u03cc\\u03bc\\u03b7\\u03c3\\u03b7\\u03c2=\\u03a0\\u03b1\\u03c1\\u03b1\\u03b4\\u03bf\\u03c3\\u03b9\\u03b1\\u03ba\\u03ae \\u03c3\\u03b5\\u03b9\\u03c1\\u03ac \\u03c4\\u03b1\\u03be\\u03b9\\u03bd\\u03cc\\u03bc\\u03b7\\u03c3\\u03b7\\u03c2)" };
725 for(i
=0;i
<UPRV_LENGTHOF(testL
);i
++) {
726 errorCode
= U_ZERO_ERROR
;
727 uloc_getDisplayName(aLocale
, testL
[i
], buffer
, UPRV_LENGTHOF(buffer
), &errorCode
);
728 if(U_FAILURE(errorCode
)) {
729 log_err("FAIL in uloc_getDisplayName(%s,%s,..) -> %s\n", aLocale
, testL
[i
], u_errorName(errorCode
));
731 expectBuffer
= CharsToUChars(expect
[i
]);
732 if(u_strcmp(buffer
,expectBuffer
)) {
733 log_data_err("FAIL in uloc_getDisplayName(%s,%s,..) expected '%s' got '%s' (Are you missing data?)\n", aLocale
, testL
[i
], expect
[i
], austrdup(buffer
));
735 log_verbose("pass in uloc_getDisplayName(%s,%s,..) got '%s'\n", aLocale
, testL
[i
], expect
[i
]);
742 /* test that we properly preflight and return data when there's a non-default pattern,
746 static const char *locale
="az_Cyrl";
747 static const char *displayLocale
="ja";
748 static const char *expectedChars
=
749 "\\u30a2\\u30bc\\u30eb\\u30d0\\u30a4\\u30b8\\u30e3\\u30f3\\u8a9e "
750 "(\\u30ad\\u30ea\\u30eb\\u6587\\u5b57)";
751 UErrorCode ec
=U_ZERO_ERROR
;
754 int32_t preflightLen
=uloc_getDisplayName(locale
, displayLocale
, NULL
, 0, &ec
);
755 /* inconvenient semantics when preflighting, this condition is expected... */
756 if(ec
==U_BUFFER_OVERFLOW_ERROR
) {
759 len
=uloc_getDisplayName(locale
, displayLocale
, result
, UPRV_LENGTHOF(result
), &ec
);
761 log_err("uloc_getDisplayName(%s, %s...) returned error: %s",
762 locale
, displayLocale
, u_errorName(ec
));
764 UChar
*expected
=CharsToUChars(expectedChars
);
765 int32_t expectedLen
=u_strlen(expected
);
767 if(len
!=expectedLen
) {
768 log_data_err("uloc_getDisplayName(%s, %s...) returned string of length %d, expected length %d",
769 locale
, displayLocale
, len
, expectedLen
);
770 } else if(preflightLen
!=expectedLen
) {
771 log_err("uloc_getDisplayName(%s, %s...) returned preflight length %d, expected length %d",
772 locale
, displayLocale
, preflightLen
, expectedLen
);
773 } else if(u_strncmp(result
, expected
, len
)) {
774 int32_t cap
=len
*6+1; /* worst case + space for trailing null */
775 char* resultChars
=(char*)malloc(cap
);
776 int32_t resultCharsLen
=UCharsToEscapedAscii(result
, len
, resultChars
, cap
);
777 if(resultCharsLen
<0 || resultCharsLen
<cap
-1) {
778 log_err("uloc_getDisplayName(%s, %s...) mismatch", locale
, displayLocale
);
780 log_err("uloc_getDisplayName(%s, %s...) returned '%s' but expected '%s'",
781 locale
, displayLocale
, resultChars
, expectedChars
);
786 /* test all buffer sizes */
787 for(i
=len
+1;i
>=0;--i
) {
788 len
=uloc_getDisplayName(locale
, displayLocale
, result
, i
, &ec
);
789 if(ec
==U_BUFFER_OVERFLOW_ERROR
) {
793 log_err("using buffer of length %d returned error %s", i
, u_errorName(ec
));
796 if(len
!=expectedLen
) {
797 log_err("with buffer of length %d, expected length %d but got %d", i
, expectedLen
, len
);
800 /* There's no guarantee about what's in the buffer if we've overflowed, in particular,
801 * we don't know that it's been filled, so no point in checking. */
811 /* test for uloc_getAvialable() and uloc_countAvilable()*/
812 static void TestGetAvailableLocales()
818 log_verbose("Testing the no of avialable locales\n");
819 locCount
=uloc_countAvailable();
821 log_data_err("countAvailable() returned an empty list!\n");
823 /* use something sensible w/o hardcoding the count */
824 else if(locCount
< 0){
825 log_data_err("countAvailable() returned a wrong value!= %d\n", locCount
);
828 log_info("Number of locales returned = %d\n", locCount
);
830 for(i
=0;i
<locCount
;i
++){
831 locList
=uloc_getAvailable(i
);
833 log_verbose(" %s\n", locList
);
837 /* test for u_getDataDirectory, u_setDataDirectory, uloc_getISO3Language */
838 static void TestDataDirectory()
841 char oldDirectory
[512];
842 const char *temp
,*testValue1
,*testValue2
,*testValue3
;
843 const char path
[40] ="d:\\icu\\source\\test\\intltest" U_FILE_SEP_STRING
; /*give the required path */
845 log_verbose("Testing getDataDirectory()\n");
846 temp
= u_getDataDirectory();
847 strcpy(oldDirectory
, temp
);
849 testValue1
=uloc_getISO3Language("en_US");
850 log_verbose("first fetch of language retrieved %s\n", testValue1
);
852 if (0 != strcmp(testValue1
,"eng")){
853 log_err("Initial check of ISO3 language failed: expected \"eng\", got %s \n", testValue1
);
856 /*defining the path for DataDirectory */
857 log_verbose("Testing setDataDirectory\n");
858 u_setDataDirectory( path
);
859 if(strcmp(path
, u_getDataDirectory())==0)
860 log_verbose("setDataDirectory working fine\n");
862 log_err("Error in setDataDirectory. Directory not set correctly - came back as [%s], expected [%s]\n", u_getDataDirectory(), path
);
864 testValue2
=uloc_getISO3Language("en_US");
865 log_verbose("second fetch of language retrieved %s \n", testValue2
);
867 u_setDataDirectory(oldDirectory
);
868 testValue3
=uloc_getISO3Language("en_US");
869 log_verbose("third fetch of language retrieved %s \n", testValue3
);
871 if (0 != strcmp(testValue3
,"eng")) {
872 log_err("get/setDataDirectory() failed: expected \"eng\", got \" %s \" \n", testValue3
);
878 /*=========================================================== */
882 static void doTestDisplayNames(const char* displayLocale
, int32_t compareIndex
)
884 UErrorCode status
= U_ZERO_ERROR
;
886 int32_t maxresultsize
;
888 const char *testLocale
;
892 UChar
*testScript
= 0;
898 UChar
* expectedLang
= 0;
899 UChar
* expectedScript
= 0;
900 UChar
* expectedCtry
= 0;
901 UChar
* expectedVar
= 0;
902 UChar
* expectedName
= 0;
906 for(i
=0;i
<LOCALE_SIZE
; ++i
)
908 testLocale
=rawData2
[NAME
][i
];
910 log_verbose("Testing..... %s\n", testLocale
);
913 maxresultsize
=uloc_getDisplayLanguage(testLocale
, displayLocale
, NULL
, maxresultsize
, &status
);
914 if(status
==U_BUFFER_OVERFLOW_ERROR
)
917 testLang
=(UChar
*)malloc(sizeof(UChar
) * (maxresultsize
+1));
918 uloc_getDisplayLanguage(testLocale
, displayLocale
, testLang
, maxresultsize
+ 1, &status
);
924 if(U_FAILURE(status
)){
925 log_err("Error in getDisplayLanguage() %s\n", myErrorName(status
));
929 maxresultsize
=uloc_getDisplayScript(testLocale
, displayLocale
, NULL
, maxresultsize
, &status
);
930 if(status
==U_BUFFER_OVERFLOW_ERROR
)
933 testScript
=(UChar
*)malloc(sizeof(UChar
) * (maxresultsize
+1));
934 uloc_getDisplayScript(testLocale
, displayLocale
, testScript
, maxresultsize
+ 1, &status
);
940 if(U_FAILURE(status
)){
941 log_err("Error in getDisplayScript() %s\n", myErrorName(status
));
945 maxresultsize
=uloc_getDisplayCountry(testLocale
, displayLocale
, NULL
, maxresultsize
, &status
);
946 if(status
==U_BUFFER_OVERFLOW_ERROR
)
949 testCtry
=(UChar
*)malloc(sizeof(UChar
) * (maxresultsize
+1));
950 uloc_getDisplayCountry(testLocale
, displayLocale
, testCtry
, maxresultsize
+ 1, &status
);
956 if(U_FAILURE(status
)){
957 log_err("Error in getDisplayCountry() %s\n", myErrorName(status
));
961 maxresultsize
=uloc_getDisplayVariant(testLocale
, displayLocale
, NULL
, maxresultsize
, &status
);
962 if(status
==U_BUFFER_OVERFLOW_ERROR
)
965 testVar
=(UChar
*)malloc(sizeof(UChar
) * (maxresultsize
+1));
966 uloc_getDisplayVariant(testLocale
, displayLocale
, testVar
, maxresultsize
+ 1, &status
);
972 if(U_FAILURE(status
)){
973 log_err("Error in getDisplayVariant() %s\n", myErrorName(status
));
977 maxresultsize
=uloc_getDisplayName(testLocale
, displayLocale
, NULL
, maxresultsize
, &status
);
978 if(status
==U_BUFFER_OVERFLOW_ERROR
)
981 testName
=(UChar
*)malloc(sizeof(UChar
) * (maxresultsize
+1));
982 uloc_getDisplayName(testLocale
, displayLocale
, testName
, maxresultsize
+ 1, &status
);
988 if(U_FAILURE(status
)){
989 log_err("Error in getDisplayName() %s\n", myErrorName(status
));
992 expectedLang
=dataTable
[compareIndex
][i
];
993 if(u_strlen(expectedLang
)== 0)
994 expectedLang
=dataTable
[DLANG_EN
][i
];
996 expectedScript
=dataTable
[compareIndex
+ 1][i
];
997 if(u_strlen(expectedScript
)== 0)
998 expectedScript
=dataTable
[DSCRIPT_EN
][i
];
1000 expectedCtry
=dataTable
[compareIndex
+ 2][i
];
1001 if(u_strlen(expectedCtry
)== 0)
1002 expectedCtry
=dataTable
[DCTRY_EN
][i
];
1004 expectedVar
=dataTable
[compareIndex
+ 3][i
];
1005 if(u_strlen(expectedVar
)== 0)
1006 expectedVar
=dataTable
[DVAR_EN
][i
];
1008 expectedName
=dataTable
[compareIndex
+ 4][i
];
1009 if(u_strlen(expectedName
) == 0)
1010 expectedName
=dataTable
[DNAME_EN
][i
];
1012 if (0 !=u_strcmp(testLang
,expectedLang
)) {
1013 log_data_err(" Display Language mismatch: got %s expected %s displayLocale=%s (Are you missing data?)\n", austrdup(testLang
), austrdup(expectedLang
), displayLocale
);
1016 if (0 != u_strcmp(testScript
,expectedScript
)) {
1017 log_data_err(" Display Script mismatch: got %s expected %s displayLocale=%s (Are you missing data?)\n", austrdup(testScript
), austrdup(expectedScript
), displayLocale
);
1020 if (0 != u_strcmp(testCtry
,expectedCtry
)) {
1021 log_data_err(" Display Country mismatch: got %s expected %s displayLocale=%s (Are you missing data?)\n", austrdup(testCtry
), austrdup(expectedCtry
), displayLocale
);
1024 if (0 != u_strcmp(testVar
,expectedVar
)) {
1025 log_data_err(" Display Variant mismatch: got %s expected %s displayLocale=%s (Are you missing data?)\n", austrdup(testVar
), austrdup(expectedVar
), displayLocale
);
1028 if(0 != u_strcmp(testName
, expectedName
)) {
1029 log_data_err(" Display Name mismatch: got %s expected %s displayLocale=%s (Are you missing data?)\n", austrdup(testName
), austrdup(expectedName
), displayLocale
);
1032 if(testName
!=&_NUL
) {
1035 if(testLang
!=&_NUL
) {
1038 if(testScript
!=&_NUL
) {
1041 if(testCtry
!=&_NUL
) {
1044 if(testVar
!=&_NUL
) {
1051 /*------------------------------
1052 * TestDisplayNameBrackets
1056 const char * displayLocale
;
1057 const char * namedRegion
;
1058 const char * namedLocale
;
1059 const char * regionName
;
1060 const char * ulocLocaleName
;
1061 const char * uldnLocaleName
;
1062 } DisplayNameBracketsItem
;
1064 static const DisplayNameBracketsItem displayNameBracketsItems
[] = {
1065 { "en", "CC", "en_CC", "Cocos (Keeling) Islands", "English (Cocos [Keeling] Islands)", "English (Cocos [Keeling] Islands)" },
1066 { "en", "MM", "my_MM", "Myanmar (Burma)", "Burmese (Myanmar [Burma])", "Burmese (Myanmar)" },
1067 { "en", "MM", "my_Mymr_MM", "Myanmar (Burma)", "Burmese (Myanmar, Myanmar [Burma])", "Burmese (Myanmar, Myanmar)" },
1068 { "zh", "CC", "en_CC", "\\u79D1\\u79D1\\u65AF\\uFF08\\u57FA\\u6797\\uFF09\\u7FA4\\u5C9B",
1069 "\\u82F1\\u6587\\uFF08\\u79D1\\u79D1\\u65AF\\uFF3B\\u57FA\\u6797\\uFF3D\\u7FA4\\u5C9B\\uFF09",
1070 "\\u82F1\\u6587\\uFF08\\u79D1\\u79D1\\u65AF\\uFF3B\\u57FA\\u6797\\uFF3D\\u7FA4\\u5C9B\\uFF09" },
1071 { "zh", "CG", "fr_CG", "\\u521A\\u679C\\uFF08\\u5E03\\uFF09",
1072 "\\u6CD5\\u6587\\uFF08\\u521A\\u679C\\uFF3B\\u5E03\\uFF3D\\uFF09",
1073 "\\u6CD5\\u6587\\uFF08\\u521A\\u679C\\uFF3B\\u5E03\\uFF3D\\uFF09" },
1074 { NULL
, NULL
, NULL
, NULL
, NULL
, NULL
}
1077 enum { kDisplayNameBracketsMax
= 128 };
1079 static void TestDisplayNameBrackets()
1081 const DisplayNameBracketsItem
* itemPtr
= displayNameBracketsItems
;
1082 for (; itemPtr
->displayLocale
!= NULL
; itemPtr
++) {
1083 ULocaleDisplayNames
* uldn
;
1085 UChar expectRegionName
[kDisplayNameBracketsMax
];
1086 UChar expectUlocLocaleName
[kDisplayNameBracketsMax
];
1087 UChar expectUldnLocaleName
[kDisplayNameBracketsMax
];
1088 UChar getName
[kDisplayNameBracketsMax
];
1091 (void) u_unescape(itemPtr
->regionName
, expectRegionName
, kDisplayNameBracketsMax
);
1092 (void) u_unescape(itemPtr
->ulocLocaleName
, expectUlocLocaleName
, kDisplayNameBracketsMax
);
1093 (void) u_unescape(itemPtr
->uldnLocaleName
, expectUldnLocaleName
, kDisplayNameBracketsMax
);
1095 status
= U_ZERO_ERROR
;
1096 ulen
= uloc_getDisplayCountry(itemPtr
->namedLocale
, itemPtr
->displayLocale
, getName
, kDisplayNameBracketsMax
, &status
);
1097 if ( U_FAILURE(status
) || u_strcmp(getName
, expectRegionName
) != 0 ) {
1098 log_data_err("uloc_getDisplayCountry for displayLocale %s and namedLocale %s returns unexpected name or status %s\n", itemPtr
->displayLocale
, itemPtr
->namedLocale
, myErrorName(status
));
1101 status
= U_ZERO_ERROR
;
1102 ulen
= uloc_getDisplayName(itemPtr
->namedLocale
, itemPtr
->displayLocale
, getName
, kDisplayNameBracketsMax
, &status
);
1103 if ( U_FAILURE(status
) || u_strcmp(getName
, expectUlocLocaleName
) != 0 ) {
1104 log_data_err("uloc_getDisplayName for displayLocale %s and namedLocale %s returns unexpected name or status %s\n", itemPtr
->displayLocale
, itemPtr
->namedLocale
, myErrorName(status
));
1106 if ( U_FAILURE(status
) ) {
1107 log_data_err("uloc_getDisplayName for displayLocale %s and namedLocale %-10s returns unexpected status %s\n", itemPtr
->displayLocale
, itemPtr
->namedLocale
, myErrorName(status
));
1108 } else if ( u_strcmp(getName
, expectUlocLocaleName
) != 0 ) {
1110 u_strToUTF8(bbuf
, 128, NULL
, getName
, ulen
, &status
);
1111 log_data_err("uloc_getDisplayName for displayLocale %s and namedLocale %-10s returns unexpected name (len %d): \"%s\"\n", itemPtr
->displayLocale
, itemPtr
->namedLocale
, ulen
, bbuf
);
1114 #if !UCONFIG_NO_FORMATTING
1115 status
= U_ZERO_ERROR
;
1116 uldn
= uldn_open(itemPtr
->displayLocale
, ULDN_STANDARD_NAMES
, &status
);
1117 if (U_SUCCESS(status
)) {
1118 status
= U_ZERO_ERROR
;
1119 ulen
= uldn_regionDisplayName(uldn
, itemPtr
->namedRegion
, getName
, kDisplayNameBracketsMax
, &status
);
1120 if ( U_FAILURE(status
) || u_strcmp(getName
, expectRegionName
) != 0 ) {
1121 log_data_err("uldn_regionDisplayName for displayLocale %s and namedRegion %s returns unexpected name or status %s\n", itemPtr
->displayLocale
, itemPtr
->namedRegion
, myErrorName(status
));
1124 status
= U_ZERO_ERROR
;
1125 ulen
= uldn_localeDisplayName(uldn
, itemPtr
->namedLocale
, getName
, kDisplayNameBracketsMax
, &status
);
1126 if ( U_FAILURE(status
) ) {
1127 log_data_err("uldn_localeDisplayName for displayLocale %s and namedLocale %-10s returns unexpected status %s\n", itemPtr
->displayLocale
, itemPtr
->namedLocale
, myErrorName(status
));
1128 } else if ( u_strcmp(getName
, expectUldnLocaleName
) != 0 ) {
1130 u_strToUTF8(bbuf
, 128, NULL
, getName
, ulen
, &status
);
1131 log_data_err("uldn_localeDisplayName for displayLocale %s and namedLocale %-10s returns unexpected name (len %d): \"%s\"\n", itemPtr
->displayLocale
, itemPtr
->namedLocale
, ulen
, bbuf
);
1136 log_data_err("uldn_open fails for displayLocale %s, status=%s\n", itemPtr
->displayLocale
, u_errorName(status
));
1139 (void)ulen
; /* Suppress variable not used warning */
1143 /*------------------------------
1147 #if !UCONFIG_NO_FILE_IO && !UCONFIG_NO_LEGACY_CONVERSION
1148 /* test for uloc_getISOLanguages, uloc_getISOCountries */
1149 static void TestISOFunctions()
1151 const char* const* str
=uloc_getISOLanguages();
1152 const char* const* str1
=uloc_getISOCountries();
1154 const char *key
= NULL
;
1155 int32_t count
= 0, skipped
= 0;
1157 UResourceBundle
*res
;
1158 UResourceBundle
*subRes
;
1159 UErrorCode status
= U_ZERO_ERROR
;
1161 /* test getISOLanguages*/
1162 /*str=uloc_getISOLanguages(); */
1163 log_verbose("Testing ISO Languages: \n");
1165 /* use structLocale - this data is no longer in root */
1166 res
= ures_openDirect(loadTestData(&status
), "structLocale", &status
);
1167 subRes
= ures_getByKey(res
, "Languages", NULL
, &status
);
1168 if (U_FAILURE(status
)) {
1169 log_data_err("There is an error in structLocale's ures_getByKey(\"Languages\"), status=%s\n", u_errorName(status
));
1173 expect
= ures_getSize(subRes
);
1174 for(count
= 0; *(str
+count
) != 0; count
++)
1177 test
= *(str
+count
);
1178 status
= U_ZERO_ERROR
;
1181 /* Skip over language tags. This API only returns language codes. */
1182 skipped
+= (key
!= NULL
);
1183 ures_getNextString(subRes
, NULL
, &key
, &status
);
1185 while (key
!= NULL
&& strchr(key
, '_'));
1189 /* TODO: Consider removing sh, which is deprecated */
1190 if(strcmp(key
,"root") == 0 || strcmp(key
,"Fallback") == 0 || strcmp(key
,"sh") == 0) {
1191 ures_getNextString(subRes
, NULL
, &key
, &status
);
1194 #if U_CHARSET_FAMILY==U_ASCII_FAMILY
1195 /* This code only works on ASCII machines where the keys are stored in ASCII order */
1196 if(strcmp(test
,key
)) {
1197 /* The first difference usually implies the place where things get out of sync */
1198 log_err("FAIL Language diff at offset %d, \"%s\" != \"%s\"\n", count
, test
, key
);
1202 if(!strcmp(test
,"in"))
1203 log_err("FAIL getISOLanguages() has obsolete language code %s\n", test
);
1204 if(!strcmp(test
,"iw"))
1205 log_err("FAIL getISOLanguages() has obsolete language code %s\n", test
);
1206 if(!strcmp(test
,"ji"))
1207 log_err("FAIL getISOLanguages() has obsolete language code %s\n", test
);
1208 if(!strcmp(test
,"jw"))
1209 log_err("FAIL getISOLanguages() has obsolete language code %s\n", test
);
1210 if(!strcmp(test
,"sh"))
1211 log_err("FAIL getISOLanguages() has obsolete language code %s\n", test
);
1214 expect
-= skipped
; /* Ignore the skipped resources from structLocale */
1217 log_err("There is an error in getISOLanguages, got %d, expected %d (as per structLocale)\n", count
, expect
);
1220 subRes
= ures_getByKey(res
, "Countries", subRes
, &status
);
1221 log_verbose("Testing ISO Countries");
1223 expect
= ures_getSize(subRes
) - 1; /* Skip ZZ */
1224 for(count
= 0; *(str1
+count
) != 0; count
++)
1227 test
= *(str1
+count
);
1229 /* Skip over numeric UN tags. This API only returns ISO-3166 codes. */
1230 skipped
+= (key
!= NULL
);
1231 ures_getNextString(subRes
, NULL
, &key
, &status
);
1233 while (key
!= NULL
&& strlen(key
) != 2);
1237 /* TODO: Consider removing CS, which is deprecated */
1238 while(strcmp(key
,"QO") == 0 || strcmp(key
,"QU") == 0 || strcmp(key
,"CS") == 0) {
1239 ures_getNextString(subRes
, NULL
, &key
, &status
);
1242 #if U_CHARSET_FAMILY==U_ASCII_FAMILY
1243 /* This code only works on ASCII machines where the keys are stored in ASCII order */
1244 if(strcmp(test
,key
)) {
1245 /* The first difference usually implies the place where things get out of sync */
1246 log_err("FAIL Country diff at offset %d, \"%s\" != \"%s\"\n", count
, test
, key
);
1249 if(!strcmp(test
,"FX"))
1250 log_err("FAIL getISOCountries() has obsolete country code %s\n", test
);
1251 if(!strcmp(test
,"YU"))
1252 log_err("FAIL getISOCountries() has obsolete country code %s\n", test
);
1253 if(!strcmp(test
,"ZR"))
1254 log_err("FAIL getISOCountries() has obsolete country code %s\n", test
);
1257 ures_getNextString(subRes
, NULL
, &key
, &status
);
1258 if (strcmp(key
, "ZZ") != 0) {
1259 log_err("ZZ was expected to be the last entry in structLocale, but got %s\n", key
);
1261 #if U_CHARSET_FAMILY==U_EBCDIC_FAMILY
1262 /* On EBCDIC machines, the numbers are sorted last. Account for those in the skipped value too. */
1265 /* Skip over numeric UN tags. uloc_getISOCountries only returns ISO-3166 codes. */
1266 skipped
+= (key
!= NULL
);
1267 ures_getNextString(subRes
, NULL
, &key
, &status
);
1269 while (U_SUCCESS(status
) && key
!= NULL
&& strlen(key
) != 2);
1271 expect
-= skipped
; /* Ignore the skipped resources from structLocale */
1274 log_err("There is an error in getISOCountries, got %d, expected %d \n", count
, expect
);
1281 static void setUpDataTable()
1284 dataTable
= (UChar
***)(calloc(sizeof(UChar
**),LOCALE_INFO_SIZE
));
1286 for (i
= 0; i
< LOCALE_INFO_SIZE
; i
++) {
1287 dataTable
[i
] = (UChar
**)(calloc(sizeof(UChar
*),LOCALE_SIZE
));
1288 for (j
= 0; j
< LOCALE_SIZE
; j
++){
1289 dataTable
[i
][j
] = CharsToUChars(rawData2
[i
][j
]);
1294 static void cleanUpDataTable()
1297 if(dataTable
!= NULL
) {
1298 for (i
=0; i
<LOCALE_INFO_SIZE
; i
++) {
1299 for(j
= 0; j
< LOCALE_SIZE
; j
++) {
1300 free(dataTable
[i
][j
]);
1310 * @bug 4011756 4011380
1312 static void TestISO3Fallback()
1314 const char* test
="xx_YY";
1316 const char * result
;
1318 result
= uloc_getISO3Language(test
);
1320 /* Conform to C API usage */
1322 if (!result
|| (result
[0] != 0))
1323 log_err("getISO3Language() on xx_YY returned %s instead of \"\"");
1325 result
= uloc_getISO3Country(test
);
1327 if (!result
|| (result
[0] != 0))
1328 log_err("getISO3Country() on xx_YY returned %s instead of \"\"");
1334 static void TestSimpleDisplayNames()
1337 This test is different from TestDisplayNames because TestDisplayNames checks
1338 fallback behavior, combination of language and country names to form locale
1339 names, and other stuff like that. This test just checks specific language
1340 and country codes to make sure we have the correct names for them.
1342 char languageCodes
[] [4] = { "he", "id", "iu", "ug", "yi", "za", "419" };
1343 const char* languageNames
[] = { "Hebrew", "Indonesian", "Inuktitut", "Uyghur", "Yiddish",
1345 const char* inLocale
[] = { "en_US", "zh_Hant"};
1346 UErrorCode status
=U_ZERO_ERROR
;
1349 int32_t localeIndex
= 0;
1350 for (i
= 0; i
< 7; i
++) {
1352 UChar
*expectedLang
=0;
1356 localeIndex
= 1; /* Use the second locale for the rest of the test. */
1359 size
=uloc_getDisplayLanguage(languageCodes
[i
], inLocale
[localeIndex
], NULL
, size
, &status
);
1360 if(status
==U_BUFFER_OVERFLOW_ERROR
) {
1361 status
=U_ZERO_ERROR
;
1362 testLang
=(UChar
*)malloc(sizeof(UChar
) * (size
+ 1));
1363 uloc_getDisplayLanguage(languageCodes
[i
], inLocale
[localeIndex
], testLang
, size
+ 1, &status
);
1365 expectedLang
=(UChar
*)malloc(sizeof(UChar
) * (strlen(languageNames
[i
])+1));
1366 u_uastrcpy(expectedLang
, languageNames
[i
]);
1367 if (u_strcmp(testLang
, expectedLang
) != 0)
1368 log_data_err("Got wrong display name for %s : Expected \"%s\", got \"%s\".\n",
1369 languageCodes
[i
], languageNames
[i
], austrdup(testLang
));
1379 static void TestUninstalledISO3Names()
1381 /* This test checks to make sure getISO3Language and getISO3Country work right
1382 even for locales that are not installed. */
1383 static const char iso2Languages
[][4] = { "am", "ba", "fy", "mr", "rn",
1385 static const char iso3Languages
[][5] = { "amh", "bak", "fry", "mar", "run",
1386 "ssw", "twi", "zul" };
1387 static const char iso2Countries
[][6] = { "am_AF", "ba_BW", "fy_KZ", "mr_MO", "rn_MN",
1388 "ss_SB", "tw_TC", "zu_ZW" };
1389 static const char iso3Countries
[][4] = { "AFG", "BWA", "KAZ", "MAC", "MNG",
1390 "SLB", "TCA", "ZWE" };
1393 for (i
= 0; i
< 8; i
++) {
1394 UErrorCode err
= U_ZERO_ERROR
;
1396 test
= uloc_getISO3Language(iso2Languages
[i
]);
1397 if(strcmp(test
, iso3Languages
[i
]) !=0 || U_FAILURE(err
))
1398 log_err("Got wrong ISO3 code for %s : Expected \"%s\", got \"%s\". %s\n",
1399 iso2Languages
[i
], iso3Languages
[i
], test
, myErrorName(err
));
1401 for (i
= 0; i
< 8; i
++) {
1402 UErrorCode err
= U_ZERO_ERROR
;
1404 test
= uloc_getISO3Country(iso2Countries
[i
]);
1405 if(strcmp(test
, iso3Countries
[i
]) !=0 || U_FAILURE(err
))
1406 log_err("Got wrong ISO3 code for %s : Expected \"%s\", got \"%s\". %s\n",
1407 iso2Countries
[i
], iso3Countries
[i
], test
, myErrorName(err
));
1412 static void TestVariantParsing()
1414 static const char* en_US_custom
="en_US_De Anza_Cupertino_California_United States_Earth";
1415 static const char* dispName
="English (United States, DE ANZA_CUPERTINO_CALIFORNIA_UNITED STATES_EARTH)";
1416 static const char* dispVar
="DE ANZA_CUPERTINO_CALIFORNIA_UNITED STATES_EARTH";
1417 static const char* shortVariant
="fr_FR_foo";
1418 static const char* bogusVariant
="fr_FR__foo";
1419 static const char* bogusVariant2
="fr_FR_foo_";
1420 static const char* bogusVariant3
="fr_FR__foo_";
1423 UChar displayVar
[100];
1424 UChar displayName
[100];
1425 UErrorCode status
=U_ZERO_ERROR
;
1428 size
=uloc_getDisplayVariant(en_US_custom
, "en_US", NULL
, size
, &status
);
1429 if(status
==U_BUFFER_OVERFLOW_ERROR
) {
1430 status
=U_ZERO_ERROR
;
1431 got
=(UChar
*)realloc(got
, sizeof(UChar
) * (size
+1));
1432 uloc_getDisplayVariant(en_US_custom
, "en_US", got
, size
+ 1, &status
);
1435 log_err("FAIL: Didn't get U_BUFFER_OVERFLOW_ERROR\n");
1437 u_uastrcpy(displayVar
, dispVar
);
1438 if(u_strcmp(got
,displayVar
)!=0) {
1439 log_err("FAIL: getDisplayVariant() Wanted %s, got %s\n", dispVar
, austrdup(got
));
1442 size
=uloc_getDisplayName(en_US_custom
, "en_US", NULL
, size
, &status
);
1443 if(status
==U_BUFFER_OVERFLOW_ERROR
) {
1444 status
=U_ZERO_ERROR
;
1445 got
=(UChar
*)realloc(got
, sizeof(UChar
) * (size
+1));
1446 uloc_getDisplayName(en_US_custom
, "en_US", got
, size
+ 1, &status
);
1449 log_err("FAIL: Didn't get U_BUFFER_OVERFLOW_ERROR\n");
1451 u_uastrcpy(displayName
, dispName
);
1452 if(u_strcmp(got
,displayName
)!=0) {
1453 if (status
== U_USING_DEFAULT_WARNING
) {
1454 log_data_err("FAIL: getDisplayName() got %s. Perhaps you are missing data?\n", u_errorName(status
));
1456 log_err("FAIL: getDisplayName() Wanted %s, got %s\n", dispName
, austrdup(got
));
1461 status
=U_ZERO_ERROR
;
1462 size
=uloc_getDisplayVariant(shortVariant
, NULL
, NULL
, size
, &status
);
1463 if(status
==U_BUFFER_OVERFLOW_ERROR
) {
1464 status
=U_ZERO_ERROR
;
1465 got
=(UChar
*)realloc(got
, sizeof(UChar
) * (size
+1));
1466 uloc_getDisplayVariant(shortVariant
, NULL
, got
, size
+ 1, &status
);
1469 log_err("FAIL: Didn't get U_BUFFER_OVERFLOW_ERROR\n");
1471 if(strcmp(austrdup(got
),"FOO")!=0) {
1472 log_err("FAIL: getDisplayVariant() Wanted: foo Got: %s\n", austrdup(got
));
1475 status
=U_ZERO_ERROR
;
1476 size
=uloc_getDisplayVariant(bogusVariant
, NULL
, NULL
, size
, &status
);
1477 if(status
==U_BUFFER_OVERFLOW_ERROR
) {
1478 status
=U_ZERO_ERROR
;
1479 got
=(UChar
*)realloc(got
, sizeof(UChar
) * (size
+1));
1480 uloc_getDisplayVariant(bogusVariant
, NULL
, got
, size
+ 1, &status
);
1483 log_err("FAIL: Didn't get U_BUFFER_OVERFLOW_ERROR\n");
1485 if(strcmp(austrdup(got
),"_FOO")!=0) {
1486 log_err("FAIL: getDisplayVariant() Wanted: _FOO Got: %s\n", austrdup(got
));
1489 status
=U_ZERO_ERROR
;
1490 size
=uloc_getDisplayVariant(bogusVariant2
, NULL
, NULL
, size
, &status
);
1491 if(status
==U_BUFFER_OVERFLOW_ERROR
) {
1492 status
=U_ZERO_ERROR
;
1493 got
=(UChar
*)realloc(got
, sizeof(UChar
) * (size
+1));
1494 uloc_getDisplayVariant(bogusVariant2
, NULL
, got
, size
+ 1, &status
);
1497 log_err("FAIL: Didn't get U_BUFFER_OVERFLOW_ERROR\n");
1499 if(strcmp(austrdup(got
),"FOO_")!=0) {
1500 log_err("FAIL: getDisplayVariant() Wanted: FOO_ Got: %s\n", austrdup(got
));
1503 status
=U_ZERO_ERROR
;
1504 size
=uloc_getDisplayVariant(bogusVariant3
, NULL
, NULL
, size
, &status
);
1505 if(status
==U_BUFFER_OVERFLOW_ERROR
) {
1506 status
=U_ZERO_ERROR
;
1507 got
=(UChar
*)realloc(got
, sizeof(UChar
) * (size
+1));
1508 uloc_getDisplayVariant(bogusVariant3
, NULL
, got
, size
+ 1, &status
);
1511 log_err("FAIL: Didn't get U_BUFFER_OVERFLOW_ERROR\n");
1513 if(strcmp(austrdup(got
),"_FOO_")!=0) {
1514 log_err("FAIL: getDisplayVariant() Wanted: _FOO_ Got: %s\n", austrdup(got
));
1520 static void TestObsoleteNames(void)
1523 UErrorCode status
= U_ZERO_ERROR
;
1535 { "eng_USA", "eng", "en", "USA", "US" },
1536 { "kok", "kok", "kok", "", "" },
1537 { "in", "ind", "in", "", "" },
1538 { "id", "ind", "id", "", "" }, /* NO aliasing */
1539 { "sh", "srp", "sh", "", "" },
1540 { "zz_CS", "", "zz", "SCG", "CS" },
1541 { "zz_FX", "", "zz", "FXX", "FX" },
1542 { "zz_RO", "", "zz", "ROU", "RO" },
1543 { "zz_TP", "", "zz", "TMP", "TP" },
1544 { "zz_TL", "", "zz", "TLS", "TL" },
1545 { "zz_ZR", "", "zz", "ZAR", "ZR" },
1546 { "zz_FXX", "", "zz", "FXX", "FX" }, /* no aliasing. Doesn't go to PS(PSE). */
1547 { "zz_ROM", "", "zz", "ROU", "RO" },
1548 { "zz_ROU", "", "zz", "ROU", "RO" },
1549 { "zz_ZAR", "", "zz", "ZAR", "ZR" },
1550 { "zz_TMP", "", "zz", "TMP", "TP" },
1551 { "zz_TLS", "", "zz", "TLS", "TL" },
1552 { "zz_YUG", "", "zz", "YUG", "YU" },
1553 { "mlt_PSE", "mlt", "mt", "PSE", "PS" },
1554 { "iw", "heb", "iw", "", "" },
1555 { "ji", "yid", "ji", "", "" },
1556 { "jw", "jaw", "jw", "", "" },
1557 { "sh", "srp", "sh", "", "" },
1558 { "", "", "", "", "" }
1561 for(i
=0;tests
[i
].locale
[0];i
++)
1565 locale
= tests
[i
].locale
;
1566 log_verbose("** %s:\n", locale
);
1568 status
= U_ZERO_ERROR
;
1569 if(strcmp(tests
[i
].lang3
,uloc_getISO3Language(locale
)))
1571 log_err("FAIL: uloc_getISO3Language(%s)==\t\"%s\",\t expected \"%s\"\n",
1572 locale
, uloc_getISO3Language(locale
), tests
[i
].lang3
);
1576 log_verbose(" uloc_getISO3Language()==\t\"%s\"\n",
1577 uloc_getISO3Language(locale
) );
1580 status
= U_ZERO_ERROR
;
1581 uloc_getLanguage(locale
, buff
, 256, &status
);
1582 if(U_FAILURE(status
))
1584 log_err("FAIL: error getting language from %s\n", locale
);
1588 if(strcmp(buff
,tests
[i
].lang
))
1590 log_err("FAIL: uloc_getLanguage(%s)==\t\"%s\"\t expected \"%s\"\n",
1591 locale
, buff
, tests
[i
].lang
);
1595 log_verbose(" uloc_getLanguage(%s)==\t%s\n", locale
, buff
);
1598 if(strcmp(tests
[i
].lang3
,uloc_getISO3Language(locale
)))
1600 log_err("FAIL: uloc_getISO3Language(%s)==\t\"%s\",\t expected \"%s\"\n",
1601 locale
, uloc_getISO3Language(locale
), tests
[i
].lang3
);
1605 log_verbose(" uloc_getISO3Language()==\t\"%s\"\n",
1606 uloc_getISO3Language(locale
) );
1609 if(strcmp(tests
[i
].ctry3
,uloc_getISO3Country(locale
)))
1611 log_err("FAIL: uloc_getISO3Country(%s)==\t\"%s\",\t expected \"%s\"\n",
1612 locale
, uloc_getISO3Country(locale
), tests
[i
].ctry3
);
1616 log_verbose(" uloc_getISO3Country()==\t\"%s\"\n",
1617 uloc_getISO3Country(locale
) );
1620 status
= U_ZERO_ERROR
;
1621 uloc_getCountry(locale
, buff
, 256, &status
);
1622 if(U_FAILURE(status
))
1624 log_err("FAIL: error getting country from %s\n", locale
);
1628 if(strcmp(buff
,tests
[i
].ctry
))
1630 log_err("FAIL: uloc_getCountry(%s)==\t\"%s\"\t expected \"%s\"\n",
1631 locale
, buff
, tests
[i
].ctry
);
1635 log_verbose(" uloc_getCountry(%s)==\t%s\n", locale
, buff
);
1640 if (uloc_getLCID("iw_IL") != uloc_getLCID("he_IL")) {
1641 log_err("he,iw LCID mismatch: %X versus %X\n", uloc_getLCID("iw_IL"), uloc_getLCID("he_IL"));
1644 if (uloc_getLCID("iw") != uloc_getLCID("he")) {
1645 log_err("he,iw LCID mismatch: %X versus %X\n", uloc_getLCID("iw"), uloc_getLCID("he"));
1650 i
= uloc_getLanguage("kok",NULL
,0,&icu_err
);
1651 if(U_FAILURE(icu_err
))
1653 log_err("FAIL: Got %s trying to do uloc_getLanguage(kok)\n", u_errorName(icu_err
));
1656 icu_err
= U_ZERO_ERROR
;
1657 uloc_getLanguage("kok",r1_buff
,12,&icu_err
);
1658 if(U_FAILURE(icu_err
))
1660 log_err("FAIL: Got %s trying to do uloc_getLanguage(kok, buff)\n", u_errorName(icu_err
));
1663 r1_addr
= (char *)uloc_getISO3Language("kok");
1665 icu_err
= U_ZERO_ERROR
;
1666 if (strcmp(r1_buff
,"kok") != 0)
1668 log_err("FAIL: uloc_getLanguage(kok)==%s not kok\n",r1_buff
);
1671 r1_addr
= (char *)uloc_getISO3Language("in");
1672 i
= uloc_getLanguage(r1_addr
,r1_buff
,12,&icu_err
);
1673 if (strcmp(r1_buff
,"id") != 0)
1675 printf("uloc_getLanguage error (%s)\n",r1_buff
);
1678 r1_addr
= (char *)uloc_getISO3Language("sh");
1679 i
= uloc_getLanguage(r1_addr
,r1_buff
,12,&icu_err
);
1680 if (strcmp(r1_buff
,"sr") != 0)
1682 printf("uloc_getLanguage error (%s)\n",r1_buff
);
1686 r1_addr
= (char *)uloc_getISO3Country("zz_ZR");
1687 strcpy(p1_buff
,"zz_");
1688 strcat(p1_buff
,r1_addr
);
1689 i
= uloc_getCountry(p1_buff
,r1_buff
,12,&icu_err
);
1690 if (strcmp(r1_buff
,"ZR") != 0)
1692 printf("uloc_getCountry error (%s)\n",r1_buff
);
1695 r1_addr
= (char *)uloc_getISO3Country("zz_FX");
1696 strcpy(p1_buff
,"zz_");
1697 strcat(p1_buff
,r1_addr
);
1698 i
= uloc_getCountry(p1_buff
,r1_buff
,12,&icu_err
);
1699 if (strcmp(r1_buff
,"FX") != 0)
1701 printf("uloc_getCountry error (%s)\n",r1_buff
);
1709 static void TestKeywordVariants(void)
1711 static const struct {
1712 const char *localeID
;
1713 const char *expectedLocaleID
; /* uloc_getName */
1714 const char *expectedLocaleIDNoKeywords
; /* uloc_getBaseName */
1715 const char *expectedCanonicalID
; /* uloc_canonicalize */
1716 const char *expectedKeywords
[10];
1717 int32_t numKeywords
;
1718 UErrorCode expectedStatus
; /* from uloc_openKeywords */
1721 "de_DE@ currency = euro; C o ll A t i o n = Phonebook ; C alen dar = buddhist ",
1722 "de_DE@calendar=buddhist;collation=Phonebook;currency=euro",
1724 "de_DE@calendar=buddhist;collation=Phonebook;currency=euro",
1725 {"calendar", "collation", "currency"},
1732 "de_DE@euro", /* we probably should strip off the POSIX style variant @euro see #11690 */
1733 "de_DE@currency=EUR",
1734 {"","","","","","",""},
1736 U_INVALID_FORMAT_ERROR
/* must have '=' after '@' */
1739 "de_DE@euro;collation=phonebook", /* The POSIX style variant @euro cannot be combined with key=value? */
1740 "de_DE", /* getName returns de_DE - should be INVALID_FORMAT_ERROR? */
1741 "de_DE", /* getBaseName returns de_DE - should be INVALID_FORMAT_ERROR? see #11690 */
1742 "de_DE", /* canonicalize returns de_DE - should be INVALID_FORMAT_ERROR? */
1743 {"","","","","","",""},
1745 U_INVALID_FORMAT_ERROR
1749 0, /* expected getName to fail */
1750 "de_DE", /* getBaseName returns de_DE - should be INVALID_FORMAT_ERROR? see #11690 */
1751 0, /* expected canonicalize to fail */
1752 {"","","","","","",""},
1754 U_INVALID_FORMAT_ERROR
/* must have '=' after '@' */
1757 UErrorCode status
= U_ZERO_ERROR
;
1759 int32_t i
= 0, j
= 0;
1760 int32_t resultLen
= 0;
1762 UEnumeration
*keywords
;
1763 int32_t keyCount
= 0;
1764 const char *keyword
= NULL
;
1765 int32_t keywordLen
= 0;
1767 for(i
= 0; i
< UPRV_LENGTHOF(testCases
); i
++) {
1768 status
= U_ZERO_ERROR
;
1770 keywords
= uloc_openKeywords(testCases
[i
].localeID
, &status
);
1772 if(status
!= testCases
[i
].expectedStatus
) {
1773 log_err("Expected to uloc_openKeywords(\"%s\") => status %s. Got %s instead\n",
1774 testCases
[i
].localeID
,
1775 u_errorName(testCases
[i
].expectedStatus
), u_errorName(status
));
1777 status
= U_ZERO_ERROR
;
1779 if((keyCount
= uenum_count(keywords
, &status
)) != testCases
[i
].numKeywords
) {
1780 log_err("Expected to get %i keywords, got %i\n", testCases
[i
].numKeywords
, keyCount
);
1784 while((keyword
= uenum_next(keywords
, &keywordLen
, &status
))) {
1785 if(strcmp(keyword
, testCases
[i
].expectedKeywords
[j
]) != 0) {
1786 log_err("Expected to get keyword value %s, got %s\n", testCases
[i
].expectedKeywords
[j
], keyword
);
1791 uenum_reset(keywords
, &status
);
1792 while((keyword
= uenum_next(keywords
, &keywordLen
, &status
))) {
1793 if(strcmp(keyword
, testCases
[i
].expectedKeywords
[j
]) != 0) {
1794 log_err("Expected to get keyword value %s, got %s\n", testCases
[i
].expectedKeywords
[j
], keyword
);
1799 uenum_close(keywords
);
1802 status
= U_ZERO_ERROR
;
1803 resultLen
= uloc_getName(testCases
[i
].localeID
, buffer
, 256, &status
);
1804 if (U_SUCCESS(status
)) {
1805 if (testCases
[i
].expectedLocaleID
== 0) {
1806 log_err("Expected uloc_getName(\"%s\") to fail; got \"%s\"\n",
1807 testCases
[i
].localeID
, buffer
);
1808 } else if (uprv_strcmp(testCases
[i
].expectedLocaleID
, buffer
) != 0) {
1809 log_err("Expected uloc_getName(\"%s\") => \"%s\"; got \"%s\"\n",
1810 testCases
[i
].localeID
, testCases
[i
].expectedLocaleID
, buffer
);
1813 if (testCases
[i
].expectedLocaleID
!= 0) {
1814 log_err("Expected uloc_getName(\"%s\") => \"%s\"; but returned error: %s\n",
1815 testCases
[i
].localeID
, testCases
[i
].expectedLocaleID
, buffer
, u_errorName(status
));
1819 status
= U_ZERO_ERROR
;
1820 resultLen
= uloc_getBaseName(testCases
[i
].localeID
, buffer
, 256, &status
);
1821 if (U_SUCCESS(status
)) {
1822 if (testCases
[i
].expectedLocaleIDNoKeywords
== 0) {
1823 log_err("Expected uloc_getBaseName(\"%s\") to fail; got \"%s\"\n",
1824 testCases
[i
].localeID
, buffer
);
1825 } else if (uprv_strcmp(testCases
[i
].expectedLocaleIDNoKeywords
, buffer
) != 0) {
1826 log_err("Expected uloc_getBaseName(\"%s\") => \"%s\"; got \"%s\"\n",
1827 testCases
[i
].localeID
, testCases
[i
].expectedLocaleIDNoKeywords
, buffer
);
1830 if (testCases
[i
].expectedLocaleIDNoKeywords
!= 0) {
1831 log_err("Expected uloc_getBaseName(\"%s\") => \"%s\"; but returned error: %s\n",
1832 testCases
[i
].localeID
, testCases
[i
].expectedLocaleIDNoKeywords
, buffer
, u_errorName(status
));
1836 status
= U_ZERO_ERROR
;
1837 resultLen
= uloc_canonicalize(testCases
[i
].localeID
, buffer
, 256, &status
);
1838 if (U_SUCCESS(status
)) {
1839 if (testCases
[i
].expectedCanonicalID
== 0) {
1840 log_err("Expected uloc_canonicalize(\"%s\") to fail; got \"%s\"\n",
1841 testCases
[i
].localeID
, buffer
);
1842 } else if (uprv_strcmp(testCases
[i
].expectedCanonicalID
, buffer
) != 0) {
1843 log_err("Expected uloc_canonicalize(\"%s\") => \"%s\"; got \"%s\"\n",
1844 testCases
[i
].localeID
, testCases
[i
].expectedCanonicalID
, buffer
);
1847 if (testCases
[i
].expectedCanonicalID
!= 0) {
1848 log_err("Expected uloc_canonicalize(\"%s\") => \"%s\"; but returned error: %s\n",
1849 testCases
[i
].localeID
, testCases
[i
].expectedCanonicalID
, buffer
, u_errorName(status
));
1855 static void TestKeywordVariantParsing(void)
1857 static const struct {
1858 const char *localeID
;
1859 const char *keyword
;
1860 const char *expectedValue
; /* NULL if failure is expected */
1862 { "de_DE@ C o ll A t i o n = Phonebook ", "c o ll a t i o n", NULL
}, /* malformed key name */
1863 { "de_DE", "collation", ""},
1864 { "de_DE@collation=PHONEBOOK", "collation", "PHONEBOOK" },
1865 { "de_DE@currency = euro; CoLLaTion = PHONEBOOk", "collatiON", "PHONEBOOk" },
1870 int32_t resultLen
= 0;
1873 for(i
= 0; i
< UPRV_LENGTHOF(testCases
); i
++) {
1875 status
= U_ZERO_ERROR
;
1876 resultLen
= uloc_getKeywordValue(testCases
[i
].localeID
, testCases
[i
].keyword
, buffer
, 256, &status
);
1877 (void)resultLen
; /* Suppress set but not used warning. */
1878 if (testCases
[i
].expectedValue
) {
1879 /* expect success */
1880 if (U_FAILURE(status
)) {
1881 log_err("Expected to extract \"%s\" from \"%s\" for keyword \"%s\". Instead got status %s\n",
1882 testCases
[i
].expectedValue
, testCases
[i
].localeID
, testCases
[i
].keyword
, u_errorName(status
));
1883 } else if (uprv_strcmp(testCases
[i
].expectedValue
, buffer
) != 0) {
1884 log_err("Expected to extract \"%s\" from \"%s\" for keyword \"%s\". Instead got \"%s\"\n",
1885 testCases
[i
].expectedValue
, testCases
[i
].localeID
, testCases
[i
].keyword
, buffer
);
1887 } else if (U_SUCCESS(status
)) {
1888 /* expect failure */
1889 log_err("Expected failure but got success from \"%s\" for keyword \"%s\". Got \"%s\"\n",
1890 testCases
[i
].localeID
, testCases
[i
].keyword
, buffer
);
1896 static const struct {
1897 const char *l
; /* locale */
1898 const char *k
; /* kw */
1899 const char *v
; /* value */
1900 const char *x
; /* expected */
1901 } kwSetTestCases
[] = {
1903 { "en_US", "calendar", "japanese", "en_US@calendar=japanese" },
1904 { "en_US@", "calendar", "japanese", "en_US@calendar=japanese" },
1905 { "en_US@calendar=islamic", "calendar", "japanese", "en_US@calendar=japanese" },
1906 { "en_US@calendar=slovakian", "calendar", "gregorian", "en_US@calendar=gregorian" }, /* don't know what this means, but it has the same # of chars as gregorian */
1907 { "en_US@calendar=gregorian", "calendar", "japanese", "en_US@calendar=japanese" },
1908 { "de", "Currency", "CHF", "de@currency=CHF" },
1909 { "de", "Currency", "CHF", "de@currency=CHF" },
1911 { "en_US@collation=phonebook", "calendar", "japanese", "en_US@calendar=japanese;collation=phonebook" },
1912 { "en_US@calendar=japanese", "collation", "phonebook", "en_US@calendar=japanese;collation=phonebook" },
1913 { "de@collation=phonebook", "Currency", "CHF", "de@collation=phonebook;currency=CHF" },
1914 { "en_US@calendar=gregorian;collation=phonebook", "calendar", "japanese", "en_US@calendar=japanese;collation=phonebook" },
1915 { "en_US@calendar=slovakian;collation=phonebook", "calendar", "gregorian", "en_US@calendar=gregorian;collation=phonebook" }, /* don't know what this means, but it has the same # of chars as gregorian */
1916 { "en_US@calendar=slovakian;collation=videobook", "collation", "phonebook", "en_US@calendar=slovakian;collation=phonebook" }, /* don't know what this means, but it has the same # of chars as gregorian */
1917 { "en_US@calendar=islamic;collation=phonebook", "calendar", "japanese", "en_US@calendar=japanese;collation=phonebook" },
1918 { "de@collation=phonebook", "Currency", "CHF", "de@collation=phonebook;currency=CHF" },
1921 { "mt@a=0;b=1;c=2;d=3", "c","j", "mt@a=0;b=1;c=j;d=3" },
1922 { "mt@a=0;b=1;c=2;d=3", "x","j", "mt@a=0;b=1;c=2;d=3;x=j" },
1923 { "mt@a=0;b=1;c=2;d=3", "a","f", "mt@a=f;b=1;c=2;d=3" },
1924 { "mt@a=0;aa=1;aaa=3", "a","x", "mt@a=x;aa=1;aaa=3" },
1925 { "mt@a=0;aa=1;aaa=3", "aa","x", "mt@a=0;aa=x;aaa=3" },
1926 { "mt@a=0;aa=1;aaa=3", "aaa","x", "mt@a=0;aa=1;aaa=x" },
1927 { "mt@a=0;aa=1;aaa=3", "a","yy", "mt@a=yy;aa=1;aaa=3" },
1928 { "mt@a=0;aa=1;aaa=3", "aa","yy", "mt@a=0;aa=yy;aaa=3" },
1929 { "mt@a=0;aa=1;aaa=3", "aaa","yy", "mt@a=0;aa=1;aaa=yy" },
1933 /* 1. removal of item at end */
1934 { "de@collation=phonebook;currency=CHF", "currency", "", "de@collation=phonebook" },
1935 { "de@collation=phonebook;currency=CHF", "currency", NULL
, "de@collation=phonebook" },
1936 /* 2. removal of item at beginning */
1937 { "de@collation=phonebook;currency=CHF", "collation", "", "de@currency=CHF" },
1938 { "de@collation=phonebook;currency=CHF", "collation", NULL
, "de@currency=CHF" },
1939 /* 3. removal of an item not there */
1940 { "de@collation=phonebook;currency=CHF", "calendar", NULL
, "de@collation=phonebook;currency=CHF" },
1941 /* 4. removal of only item */
1942 { "de@collation=phonebook", "collation", NULL
, "de" },
1944 { "de@collation=phonebook", "Currency", "CHF", "de@collation=phonebook;currency=CHF" },
1945 /* cases with legal extra spacing */
1946 /*31*/{ "en_US@ calendar = islamic", "calendar", "japanese", "en_US@calendar=japanese" },
1947 /*32*/{ "en_US@ calendar = gregorian ; collation = phonebook", "calendar", "japanese", "en_US@calendar=japanese;collation=phonebook" },
1948 /*33*/{ "en_US@ calendar = islamic", "currency", "CHF", "en_US@calendar=islamic;currency=CHF" },
1949 /*34*/{ "en_US@ currency = CHF", "calendar", "japanese", "en_US@calendar=japanese;currency=CHF" },
1950 /* cases in which setKeywordValue expected to fail (implied by NULL for expected); locale need not be canonical */
1951 /*35*/{ "en_US@calendar=gregorian;", "calendar", "japanese", NULL
},
1952 /*36*/{ "en_US@calendar=gregorian;=", "calendar", "japanese", NULL
},
1953 /*37*/{ "en_US@calendar=gregorian;currency=", "calendar", "japanese", NULL
},
1954 /*38*/{ "en_US@=", "calendar", "japanese", NULL
},
1955 /*39*/{ "en_US@=;", "calendar", "japanese", NULL
},
1956 /*40*/{ "en_US@= ", "calendar", "japanese", NULL
},
1957 /*41*/{ "en_US@ =", "calendar", "japanese", NULL
},
1958 /*42*/{ "en_US@ = ", "calendar", "japanese", NULL
},
1959 /*43*/{ "en_US@=;calendar=gregorian", "calendar", "japanese", NULL
},
1960 /*44*/{ "en_US@= calen dar = gregorian", "calendar", "japanese", NULL
},
1961 /*45*/{ "en_US@= calendar = greg orian", "calendar", "japanese", NULL
},
1962 /*46*/{ "en_US@=;cal...endar=gregorian", "calendar", "japanese", NULL
},
1963 /*47*/{ "en_US@=;calendar=greg...orian", "calendar", "japanese", NULL
},
1964 /*48*/{ "en_US@calendar=gregorian", "cale ndar", "japanese", NULL
},
1965 /*49*/{ "en_US@calendar=gregorian", "calendar", "japa..nese", NULL
},
1966 /* cases in which getKeywordValue and setKeyword expected to fail (implied by NULL for value and expected) */
1967 /*50*/{ "en_US@=", "calendar", NULL
, NULL
},
1968 /*51*/{ "en_US@=;", "calendar", NULL
, NULL
},
1969 /*52*/{ "en_US@= ", "calendar", NULL
, NULL
},
1970 /*53*/{ "en_US@ =", "calendar", NULL
, NULL
},
1971 /*54*/{ "en_US@ = ", "calendar", NULL
, NULL
},
1972 /*55*/{ "en_US@=;calendar=gregorian", "calendar", NULL
, NULL
},
1973 /*56*/{ "en_US@= calen dar = gregorian", "calendar", NULL
, NULL
},
1974 /*57*/{ "en_US@= calendar = greg orian", "calendar", NULL
, NULL
},
1975 /*58*/{ "en_US@=;cal...endar=gregorian", "calendar", NULL
, NULL
},
1976 /*59*/{ "en_US@=;calendar=greg...orian", "calendar", NULL
, NULL
},
1977 /*60*/{ "en_US@calendar=gregorian", "cale ndar", NULL
, NULL
},
1981 static void TestKeywordSet(void)
1984 int32_t resultLen
= 0;
1989 for(i
= 0; i
< UPRV_LENGTHOF(kwSetTestCases
); i
++) {
1990 UErrorCode status
= U_ZERO_ERROR
;
1991 memset(buffer
,'%',1023);
1992 strcpy(buffer
, kwSetTestCases
[i
].l
);
1994 if (kwSetTestCases
[i
].x
!= NULL
) {
1995 uloc_canonicalize(kwSetTestCases
[i
].l
, cbuffer
, 1023, &status
);
1996 if(strcmp(buffer
,cbuffer
)) {
1997 log_verbose("note: [%d] wasn't canonical, should be: '%s' not '%s'. Won't check for canonicity in output.\n", i
, cbuffer
, buffer
);
1999 /* sanity check test case results for canonicity */
2000 uloc_canonicalize(kwSetTestCases
[i
].x
, cbuffer
, 1023, &status
);
2001 if(strcmp(kwSetTestCases
[i
].x
,cbuffer
)) {
2002 log_err("%s:%d: ERROR: kwSetTestCases[%d].x = '%s', should be %s (must be canonical)\n", __FILE__
, __LINE__
, i
, kwSetTestCases
[i
].x
, cbuffer
);
2005 status
= U_ZERO_ERROR
;
2006 resultLen
= uloc_setKeywordValue(kwSetTestCases
[i
].k
, kwSetTestCases
[i
].v
, buffer
, 1023, &status
);
2007 if(U_FAILURE(status
)) {
2008 log_err("Err on test case %d for setKeywordValue: got error %s\n", i
, u_errorName(status
));
2009 } else if(strcmp(buffer
,kwSetTestCases
[i
].x
) || ((int32_t)strlen(buffer
)!=resultLen
)) {
2010 log_err("FAIL: #%d setKeywordValue: %s + [%s=%s] -> %s (%d) expected %s (%d)\n", i
, kwSetTestCases
[i
].l
, kwSetTestCases
[i
].k
,
2011 kwSetTestCases
[i
].v
, buffer
, resultLen
, kwSetTestCases
[i
].x
, strlen(buffer
));
2013 log_verbose("pass: #%d: %s + [%s=%s] -> %s\n", i
, kwSetTestCases
[i
].l
, kwSetTestCases
[i
].k
, kwSetTestCases
[i
].v
,buffer
);
2016 if (kwSetTestCases
[i
].v
!= NULL
&& kwSetTestCases
[i
].v
[0] != 0) {
2017 status
= U_ZERO_ERROR
;
2018 resultLen
= uloc_getKeywordValue(kwSetTestCases
[i
].x
, kwSetTestCases
[i
].k
, buffer
, 1023, &status
);
2019 if(U_FAILURE(status
)) {
2020 log_err("Err on test case %d for getKeywordValue: got error %s\n", i
, u_errorName(status
));
2021 } else if (resultLen
!= uprv_strlen(kwSetTestCases
[i
].v
) || uprv_strcmp(buffer
, kwSetTestCases
[i
].v
) != 0) {
2022 log_err("FAIL: #%d getKeywordValue: got %s (%d) expected %s (%d)\n", i
, buffer
, resultLen
,
2023 kwSetTestCases
[i
].v
, uprv_strlen(kwSetTestCases
[i
].v
));
2027 /* test cases expected to result in error */
2028 status
= U_ZERO_ERROR
;
2029 resultLen
= uloc_setKeywordValue(kwSetTestCases
[i
].k
, kwSetTestCases
[i
].v
, buffer
, 1023, &status
);
2030 if(U_SUCCESS(status
)) {
2031 log_err("Err on test case %d for setKeywordValue: expected to fail but succeeded, got %s (%d)\n", i
, buffer
, resultLen
);
2034 if (kwSetTestCases
[i
].v
== NULL
) {
2035 status
= U_ZERO_ERROR
;
2036 strcpy(cbuffer
, kwSetTestCases
[i
].l
);
2037 resultLen
= uloc_getKeywordValue(cbuffer
, kwSetTestCases
[i
].k
, buffer
, 1023, &status
);
2038 if(U_SUCCESS(status
)) {
2039 log_err("Err on test case %d for getKeywordValue: expected to fail but succeeded\n", i
);
2046 static void TestKeywordSetError(void)
2054 /* 0-test whether an error condition modifies the buffer at all */
2057 memset(buffer
,'%',1023);
2058 status
= U_ZERO_ERROR
;
2059 res
= uloc_setKeywordValue(kwSetTestCases
[i
].k
, kwSetTestCases
[i
].v
, buffer
, blen
, &status
);
2060 if(status
!= U_ILLEGAL_ARGUMENT_ERROR
) {
2061 log_err("expected illegal err got %s\n", u_errorName(status
));
2064 /* if(res!=strlen(kwSetTestCases[i].x)) {
2065 log_err("expected result %d got %d\n", strlen(kwSetTestCases[i].x), res);
2068 if(buffer
[blen
]!='%') {
2069 log_err("Buffer byte %d was modified: now %c\n", blen
, buffer
[blen
]);
2072 log_verbose("0-buffer modify OK\n");
2075 /* 1- test a short buffer with growing text */
2076 blen
=(int32_t)strlen(kwSetTestCases
[i
].l
)+1;
2077 memset(buffer
,'%',1023);
2078 strcpy(buffer
,kwSetTestCases
[i
].l
);
2079 status
= U_ZERO_ERROR
;
2080 res
= uloc_setKeywordValue(kwSetTestCases
[i
].k
, kwSetTestCases
[i
].v
, buffer
, blen
, &status
);
2081 if(status
!= U_BUFFER_OVERFLOW_ERROR
) {
2082 log_err("expected buffer overflow on buffer %d got %s, len %d (%s + [%s=%s])\n", blen
, u_errorName(status
), res
, kwSetTestCases
[i
].l
, kwSetTestCases
[i
].k
, kwSetTestCases
[i
].v
);
2085 if(res
!=(int32_t)strlen(kwSetTestCases
[i
].x
)) {
2086 log_err("expected result %d got %d\n", strlen(kwSetTestCases
[i
].x
), res
);
2089 if(buffer
[blen
]!='%') {
2090 log_err("Buffer byte %d was modified: now %c\n", blen
, buffer
[blen
]);
2093 log_verbose("1/%d-buffer modify OK\n",i
);
2097 /* 2- test a short buffer - text the same size or shrinking */
2098 blen
=(int32_t)strlen(kwSetTestCases
[i
].l
)+1;
2099 memset(buffer
,'%',1023);
2100 strcpy(buffer
,kwSetTestCases
[i
].l
);
2101 status
= U_ZERO_ERROR
;
2102 res
= uloc_setKeywordValue(kwSetTestCases
[i
].k
, kwSetTestCases
[i
].v
, buffer
, blen
, &status
);
2103 if(status
!= U_ZERO_ERROR
) {
2104 log_err("expected zero error got %s\n", u_errorName(status
));
2107 if(buffer
[blen
+1]!='%') {
2108 log_err("Buffer byte %d was modified: now %c\n", blen
+1, buffer
[blen
+1]);
2111 if(res
!=(int32_t)strlen(kwSetTestCases
[i
].x
)) {
2112 log_err("expected result %d got %d\n", strlen(kwSetTestCases
[i
].x
), res
);
2115 if(strcmp(buffer
,kwSetTestCases
[i
].x
) || ((int32_t)strlen(buffer
)!=res
)) {
2116 log_err("FAIL: #%d: %s + [%s=%s] -> %s (%d) expected %s (%d)\n", i
, kwSetTestCases
[i
].l
, kwSetTestCases
[i
].k
,
2117 kwSetTestCases
[i
].v
, buffer
, res
, kwSetTestCases
[i
].x
, strlen(buffer
));
2119 log_verbose("pass: #%d: %s + [%s=%s] -> %s\n", i
, kwSetTestCases
[i
].l
, kwSetTestCases
[i
].k
, kwSetTestCases
[i
].v
,
2122 log_verbose("2/%d-buffer modify OK\n",i
);
2126 static int32_t _canonicalize(int32_t selector
, /* 0==getName, 1==canonicalize */
2127 const char* localeID
,
2129 int32_t resultCapacity
,
2131 /* YOU can change this to use function pointers if you like */
2134 return uloc_getName(localeID
, result
, resultCapacity
, ec
);
2136 return uloc_canonicalize(localeID
, result
, resultCapacity
, ec
);
2142 static void TestCanonicalization(void)
2144 static const struct {
2145 const char *localeID
; /* input */
2146 const char *getNameID
; /* expected getName() result */
2147 const char *canonicalID
; /* expected canonicalize() result */
2149 { "ca_ES_PREEURO-with-extra-stuff-that really doesn't make any sense-unless-you're trying to increase code coverage",
2150 "ca_ES_PREEURO_WITH_EXTRA_STUFF_THAT REALLY DOESN'T MAKE ANY SENSE_UNLESS_YOU'RE TRYING TO INCREASE CODE COVERAGE",
2151 "ca_ES_PREEURO_WITH_EXTRA_STUFF_THAT REALLY DOESN'T MAKE ANY SENSE_UNLESS_YOU'RE TRYING TO INCREASE CODE COVERAGE"},
2152 { "ca_ES_PREEURO", "ca_ES_PREEURO", "ca_ES@currency=ESP" },
2153 { "de_AT_PREEURO", "de_AT_PREEURO", "de_AT@currency=ATS" },
2154 { "de_DE_PREEURO", "de_DE_PREEURO", "de_DE@currency=DEM" },
2155 { "de_LU_PREEURO", "de_LU_PREEURO", "de_LU@currency=LUF" },
2156 { "el_GR_PREEURO", "el_GR_PREEURO", "el_GR@currency=GRD" },
2157 { "en_BE_PREEURO", "en_BE_PREEURO", "en_BE@currency=BEF" },
2158 { "en_IE_PREEURO", "en_IE_PREEURO", "en_IE@currency=IEP" },
2159 { "es_ES_PREEURO", "es_ES_PREEURO", "es_ES@currency=ESP" },
2160 { "eu_ES_PREEURO", "eu_ES_PREEURO", "eu_ES@currency=ESP" },
2161 { "fi_FI_PREEURO", "fi_FI_PREEURO", "fi_FI@currency=FIM" },
2162 { "fr_BE_PREEURO", "fr_BE_PREEURO", "fr_BE@currency=BEF" },
2163 { "fr_FR_PREEURO", "fr_FR_PREEURO", "fr_FR@currency=FRF" },
2164 { "fr_LU_PREEURO", "fr_LU_PREEURO", "fr_LU@currency=LUF" },
2165 { "ga_IE_PREEURO", "ga_IE_PREEURO", "ga_IE@currency=IEP" },
2166 { "gl_ES_PREEURO", "gl_ES_PREEURO", "gl_ES@currency=ESP" },
2167 { "it_IT_PREEURO", "it_IT_PREEURO", "it_IT@currency=ITL" },
2168 { "nl_BE_PREEURO", "nl_BE_PREEURO", "nl_BE@currency=BEF" },
2169 { "nl_NL_PREEURO", "nl_NL_PREEURO", "nl_NL@currency=NLG" },
2170 { "pt_PT_PREEURO", "pt_PT_PREEURO", "pt_PT@currency=PTE" },
2171 { "de__PHONEBOOK", "de__PHONEBOOK", "de@collation=phonebook" },
2172 { "en_GB_EURO", "en_GB_EURO", "en_GB@currency=EUR" },
2173 { "en_GB@EURO", "en_GB@EURO", "en_GB@currency=EUR" }, /* POSIX ID */
2174 { "es__TRADITIONAL", "es__TRADITIONAL", "es@collation=traditional" },
2175 { "hi__DIRECT", "hi__DIRECT", "hi@collation=direct" },
2176 { "ja_JP_TRADITIONAL", "ja_JP_TRADITIONAL", "ja_JP@calendar=japanese" },
2177 { "th_TH_TRADITIONAL", "th_TH_TRADITIONAL", "th_TH@calendar=buddhist" },
2178 { "zh_TW_STROKE", "zh_TW_STROKE", "zh_TW@collation=stroke" },
2179 { "zh__PINYIN", "zh__PINYIN", "zh@collation=pinyin" },
2180 { "zh@collation=pinyin", "zh@collation=pinyin", "zh@collation=pinyin" },
2181 { "zh_CN@collation=pinyin", "zh_CN@collation=pinyin", "zh_CN@collation=pinyin" },
2182 { "zh_CN_STROKE", "zh_CN_STROKE", "zh_CN@collation=stroke" },
2183 { "zh_CN_CA@collation=pinyin", "zh_CN_CA@collation=pinyin", "zh_CN_CA@collation=pinyin" },
2184 { "en_US_POSIX", "en_US_POSIX", "en_US_POSIX" },
2185 { "hy_AM_REVISED", "hy_AM_REVISED", "hy_AM_REVISED" },
2186 { "no_NO_NY", "no_NO_NY", "no_NO_NY" /* not: "nn_NO" [alan ICU3.0] */ },
2187 { "no@ny", "no@ny", "no__NY" /* not: "nn" [alan ICU3.0] */ }, /* POSIX ID */
2188 { "no-no.utf32@B", "no_NO.utf32@B", "no_NO_B" /* not: "nb_NO_B" [alan ICU3.0] */ }, /* POSIX ID */
2189 { "qz-qz@Euro", "qz_QZ@Euro", "qz_QZ@currency=EUR" }, /* qz-qz uses private use iso codes */
2190 { "en-BOONT", "en__BOONT", "en__BOONT" }, /* registered name */
2191 { "de-1901", "de__1901", "de__1901" }, /* registered name */
2192 { "de-1906", "de__1906", "de__1906" }, /* registered name */
2193 { "sr-SP-Cyrl", "sr_SP_CYRL", "sr_Cyrl_RS" }, /* .NET name */
2194 { "sr-SP-Latn", "sr_SP_LATN", "sr_Latn_RS" }, /* .NET name */
2195 { "sr_YU_CYRILLIC", "sr_YU_CYRILLIC", "sr_Cyrl_RS" }, /* Linux name */
2196 { "uz-UZ-Cyrl", "uz_UZ_CYRL", "uz_Cyrl_UZ" }, /* .NET name */
2197 { "uz-UZ-Latn", "uz_UZ_LATN", "uz_Latn_UZ" }, /* .NET name */
2198 { "zh-CHS", "zh_CHS", "zh_Hans" }, /* .NET name */
2199 { "zh-CHT", "zh_CHT", "zh_Hant" }, /* .NET name This may change back to zh_Hant */
2201 /* posix behavior that used to be performed by getName */
2202 { "mr.utf8", "mr.utf8", "mr" },
2203 { "de-tv.koi8r", "de_TV.koi8r", "de_TV" },
2204 { "x-piglatin_ML.MBE", "x-piglatin_ML.MBE", "x-piglatin_ML" },
2205 { "i-cherokee_US.utf7", "i-cherokee_US.utf7", "i-cherokee_US" },
2206 { "x-filfli_MT_FILFLA.gb-18030", "x-filfli_MT_FILFLA.gb-18030", "x-filfli_MT_FILFLA" },
2207 { "no-no-ny.utf8@B", "no_NO_NY.utf8@B", "no_NO_NY_B" /* not: "nn_NO" [alan ICU3.0] */ }, /* @ ignored unless variant is empty */
2209 /* fleshing out canonicalization */
2210 /* trim space and sort keywords, ';' is separator so not present at end in canonical form */
2211 { "en_Hant_IL_VALLEY_GIRL@ currency = EUR; calendar = Japanese ;", "en_Hant_IL_VALLEY_GIRL@calendar=Japanese;currency=EUR", "en_Hant_IL_VALLEY_GIRL@calendar=Japanese;currency=EUR" },
2212 /* already-canonical ids are not changed */
2213 { "en_Hant_IL_VALLEY_GIRL@calendar=Japanese;currency=EUR", "en_Hant_IL_VALLEY_GIRL@calendar=Japanese;currency=EUR", "en_Hant_IL_VALLEY_GIRL@calendar=Japanese;currency=EUR" },
2214 /* PRE_EURO and EURO conversions don't affect other keywords */
2215 { "es_ES_PREEURO@CALendar=Japanese", "es_ES_PREEURO@calendar=Japanese", "es_ES@calendar=Japanese;currency=ESP" },
2216 { "es_ES_EURO@SHOUT=zipeedeedoodah", "es_ES_EURO@shout=zipeedeedoodah", "es_ES@currency=EUR;shout=zipeedeedoodah" },
2217 /* currency keyword overrides PRE_EURO and EURO currency */
2218 { "es_ES_PREEURO@currency=EUR", "es_ES_PREEURO@currency=EUR", "es_ES@currency=EUR" },
2219 { "es_ES_EURO@currency=ESP", "es_ES_EURO@currency=ESP", "es_ES@currency=ESP" },
2220 /* norwegian is just too weird, if we handle things in their full generality */
2221 { "no-Hant-GB_NY@currency=$$$", "no_Hant_GB_NY@currency=$$$", "no_Hant_GB_NY@currency=$$$" /* not: "nn_Hant_GB@currency=$$$" [alan ICU3.0] */ },
2223 /* test cases reflecting internal resource bundle usage */
2224 { "root@kw=foo", "root@kw=foo", "root@kw=foo" },
2225 { "@calendar=gregorian", "@calendar=gregorian", "@calendar=gregorian" },
2226 { "ja_JP@calendar=Japanese", "ja_JP@calendar=Japanese", "ja_JP@calendar=Japanese" },
2227 { "ja_JP", "ja_JP", "ja_JP" },
2229 /* test case for "i-default" */
2230 { "i-default", "en@x=i-default", "en@x=i-default" }
2233 static const char* label
[] = { "getName", "canonicalize" };
2235 UErrorCode status
= U_ZERO_ERROR
;
2236 int32_t i
, j
, resultLen
= 0, origResultLen
;
2239 for (i
=0; i
< UPRV_LENGTHOF(testCases
); i
++) {
2240 for (j
=0; j
<2; ++j
) {
2241 const char* expected
= (j
==0) ? testCases
[i
].getNameID
: testCases
[i
].canonicalID
;
2243 status
= U_ZERO_ERROR
;
2245 if (expected
== NULL
) {
2246 expected
= uloc_getDefault();
2249 /* log_verbose("testing %s -> %s\n", testCases[i], testCases[i].canonicalID); */
2250 origResultLen
= _canonicalize(j
, testCases
[i
].localeID
, NULL
, 0, &status
);
2251 if (status
!= U_BUFFER_OVERFLOW_ERROR
) {
2252 log_err("FAIL: uloc_%s(%s) => %s, expected U_BUFFER_OVERFLOW_ERROR\n",
2253 label
[j
], testCases
[i
].localeID
, u_errorName(status
));
2256 status
= U_ZERO_ERROR
;
2257 resultLen
= _canonicalize(j
, testCases
[i
].localeID
, buffer
, sizeof(buffer
), &status
);
2258 if (U_FAILURE(status
)) {
2259 log_err("FAIL: uloc_%s(%s) => %s, expected U_ZERO_ERROR\n",
2260 label
[j
], testCases
[i
].localeID
, u_errorName(status
));
2263 if(uprv_strcmp(expected
, buffer
) != 0) {
2264 log_err("FAIL: uloc_%s(%s) => \"%s\", expected \"%s\"\n",
2265 label
[j
], testCases
[i
].localeID
, buffer
, expected
);
2267 log_verbose("Ok: uloc_%s(%s) => \"%s\"\n",
2268 label
[j
], testCases
[i
].localeID
, buffer
);
2270 if (resultLen
!= (int32_t)strlen(buffer
)) {
2271 log_err("FAIL: uloc_%s(%s) => len %d, expected len %d\n",
2272 label
[j
], testCases
[i
].localeID
, resultLen
, strlen(buffer
));
2274 if (origResultLen
!= resultLen
) {
2275 log_err("FAIL: uloc_%s(%s) => preflight len %d != actual len %d\n",
2276 label
[j
], testCases
[i
].localeID
, origResultLen
, resultLen
);
2282 static void TestDisplayKeywords(void)
2286 static const struct {
2287 const char *localeID
;
2288 const char *displayLocale
;
2289 UChar displayKeyword
[200];
2291 { "ca_ES@currency=ESP", "de_AT",
2292 {0x0057, 0x00e4, 0x0068, 0x0072, 0x0075, 0x006e, 0x0067, 0x0000},
2294 { "ja_JP@calendar=japanese", "de",
2295 { 0x004b, 0x0061, 0x006c, 0x0065, 0x006e, 0x0064, 0x0065, 0x0072, 0x0000}
2297 { "de_DE@collation=traditional", "de_DE",
2298 {0x0053, 0x006f, 0x0072, 0x0074, 0x0069, 0x0065, 0x0072, 0x0075, 0x006e, 0x0067, 0x0000}
2301 for(i
= 0; i
< UPRV_LENGTHOF(testCases
); i
++) {
2302 UErrorCode status
= U_ZERO_ERROR
;
2303 const char* keyword
=NULL
;
2304 int32_t keywordLen
= 0;
2305 int32_t keywordCount
= 0;
2306 UChar
*displayKeyword
=NULL
;
2307 int32_t displayKeywordLen
= 0;
2308 UEnumeration
* keywordEnum
= uloc_openKeywords(testCases
[i
].localeID
, &status
);
2309 for(keywordCount
= uenum_count(keywordEnum
, &status
); keywordCount
> 0 ; keywordCount
--){
2310 if(U_FAILURE(status
)){
2311 log_err("uloc_getKeywords failed for locale id: %s with error : %s \n", testCases
[i
].localeID
, u_errorName(status
));
2314 /* the uenum_next returns NUL terminated string */
2315 keyword
= uenum_next(keywordEnum
, &keywordLen
, &status
);
2316 /* fetch the displayKeyword */
2317 displayKeywordLen
= uloc_getDisplayKeyword(keyword
, testCases
[i
].displayLocale
, displayKeyword
, displayKeywordLen
, &status
);
2318 if(status
==U_BUFFER_OVERFLOW_ERROR
){
2319 status
= U_ZERO_ERROR
;
2320 displayKeywordLen
++; /* for null termination */
2321 displayKeyword
= (UChar
*) malloc(displayKeywordLen
* U_SIZEOF_UCHAR
);
2322 displayKeywordLen
= uloc_getDisplayKeyword(keyword
, testCases
[i
].displayLocale
, displayKeyword
, displayKeywordLen
, &status
);
2323 if(U_FAILURE(status
)){
2324 log_err("uloc_getDisplayKeyword filed for keyword : %s in locale id: %s for display locale: %s \n", testCases
[i
].localeID
, keyword
, testCases
[i
].displayLocale
, u_errorName(status
));
2327 if(u_strncmp(displayKeyword
, testCases
[i
].displayKeyword
, displayKeywordLen
)!=0){
2328 if (status
== U_USING_DEFAULT_WARNING
) {
2329 log_data_err("uloc_getDisplayKeyword did not get the expected value for keyword : %s in locale id: %s for display locale: %s . Got error: %s. Perhaps you are missing data?\n", testCases
[i
].localeID
, keyword
, testCases
[i
].displayLocale
, u_errorName(status
));
2331 log_err("uloc_getDisplayKeyword did not get the expected value for keyword : %s in locale id: %s for display locale: %s \n", testCases
[i
].localeID
, keyword
, testCases
[i
].displayLocale
);
2336 log_err("uloc_getDisplayKeyword did not return the expected error. Error: %s\n", u_errorName(status
));
2339 free(displayKeyword
);
2342 uenum_close(keywordEnum
);
2346 static void TestDisplayKeywordValues(void){
2349 static const struct {
2350 const char *localeID
;
2351 const char *displayLocale
;
2352 UChar displayKeywordValue
[500];
2354 { "ca_ES@currency=ESP", "de_AT",
2355 {0x0053, 0x0070, 0x0061, 0x006e, 0x0069, 0x0073, 0x0063, 0x0068, 0x0065, 0x0020, 0x0050, 0x0065, 0x0073, 0x0065, 0x0074, 0x0061, 0x0000}
2357 { "de_AT@currency=ATS", "fr_FR",
2358 {0x0073, 0x0063, 0x0068, 0x0069, 0x006c, 0x006c, 0x0069, 0x006e, 0x0067, 0x0020, 0x0061, 0x0075, 0x0074, 0x0072, 0x0069, 0x0063, 0x0068, 0x0069, 0x0065, 0x006e, 0x0000}
2360 { "de_DE@currency=DEM", "it",
2361 {0x006d, 0x0061, 0x0072, 0x0063, 0x006f, 0x0020, 0x0074, 0x0065, 0x0064, 0x0065, 0x0073, 0x0063, 0x006f, 0x0000}
2363 { "el_GR@currency=GRD", "en",
2364 {0x0047, 0x0072, 0x0065, 0x0065, 0x006b, 0x0020, 0x0044, 0x0072, 0x0061, 0x0063, 0x0068, 0x006d, 0x0061, 0x0000}
2366 { "eu_ES@currency=ESP", "it_IT",
2367 {0x0070, 0x0065, 0x0073, 0x0065, 0x0074, 0x0061, 0x0020, 0x0073, 0x0070, 0x0061, 0x0067, 0x006e, 0x006f, 0x006c, 0x0061, 0x0000}
2369 { "de@collation=phonebook", "es",
2370 {0x006F, 0x0072, 0x0064, 0x0065, 0x006E, 0x0020, 0x0064, 0x0065, 0x0020, 0x006C, 0x0069, 0x0073, 0x0074, 0x00ED, 0x006E, 0x0020, 0x0074, 0x0065, 0x006C, 0x0065, 0x0066, 0x00F3, 0x006E, 0x0069, 0x0063, 0x006F, 0x0000}
2373 { "de_DE@collation=phonebook", "es",
2374 {0x006F, 0x0072, 0x0064, 0x0065, 0x006E, 0x0020, 0x0064, 0x0065, 0x0020, 0x006C, 0x0069, 0x0073, 0x0074, 0x00ED, 0x006E, 0x0020, 0x0074, 0x0065, 0x006C, 0x0065, 0x0066, 0x00F3, 0x006E, 0x0069, 0x0063, 0x006F, 0x0000}
2376 { "es_ES@collation=traditional","de",
2377 {0x0054, 0x0072, 0x0061, 0x0064, 0x0069, 0x0074, 0x0069, 0x006f, 0x006e, 0x0065, 0x006c, 0x006c, 0x0065, 0x0020, 0x0053, 0x006f, 0x0072, 0x0074, 0x0069, 0x0065, 0x0072, 0x0072, 0x0065, 0x0067, 0x0065, 0x006c, 0x006e, 0x0000}
2379 { "ja_JP@calendar=japanese", "de",
2380 {0x004a, 0x0061, 0x0070, 0x0061, 0x006e, 0x0069, 0x0073, 0x0063, 0x0068, 0x0065, 0x0072, 0x0020, 0x004b, 0x0061, 0x006c, 0x0065, 0x006e, 0x0064, 0x0065, 0x0072, 0x0000}
2383 for(i
= 0; i
< UPRV_LENGTHOF(testCases
); i
++) {
2384 UErrorCode status
= U_ZERO_ERROR
;
2385 const char* keyword
=NULL
;
2386 int32_t keywordLen
= 0;
2387 int32_t keywordCount
= 0;
2388 UChar
*displayKeywordValue
= NULL
;
2389 int32_t displayKeywordValueLen
= 0;
2390 UEnumeration
* keywordEnum
= uloc_openKeywords(testCases
[i
].localeID
, &status
);
2391 for(keywordCount
= uenum_count(keywordEnum
, &status
); keywordCount
> 0 ; keywordCount
--){
2392 if(U_FAILURE(status
)){
2393 log_err("uloc_getKeywords failed for locale id: %s in display locale: % with error : %s \n", testCases
[i
].localeID
, testCases
[i
].displayLocale
, u_errorName(status
));
2396 /* the uenum_next returns NUL terminated string */
2397 keyword
= uenum_next(keywordEnum
, &keywordLen
, &status
);
2399 /* fetch the displayKeywordValue */
2400 displayKeywordValueLen
= uloc_getDisplayKeywordValue(testCases
[i
].localeID
, keyword
, testCases
[i
].displayLocale
, displayKeywordValue
, displayKeywordValueLen
, &status
);
2401 if(status
==U_BUFFER_OVERFLOW_ERROR
){
2402 status
= U_ZERO_ERROR
;
2403 displayKeywordValueLen
++; /* for null termination */
2404 displayKeywordValue
= (UChar
*)malloc(displayKeywordValueLen
* U_SIZEOF_UCHAR
);
2405 displayKeywordValueLen
= uloc_getDisplayKeywordValue(testCases
[i
].localeID
, keyword
, testCases
[i
].displayLocale
, displayKeywordValue
, displayKeywordValueLen
, &status
);
2406 if(U_FAILURE(status
)){
2407 log_err("uloc_getDisplayKeywordValue failed for keyword : %s in locale id: %s for display locale: %s with error : %s \n", testCases
[i
].localeID
, keyword
, testCases
[i
].displayLocale
, u_errorName(status
));
2410 if(u_strncmp(displayKeywordValue
, testCases
[i
].displayKeywordValue
, displayKeywordValueLen
)!=0){
2411 if (status
== U_USING_DEFAULT_WARNING
) {
2412 log_data_err("uloc_getDisplayKeywordValue did not return the expected value keyword : %s in locale id: %s for display locale: %s with error : %s Perhaps you are missing data\n", testCases
[i
].localeID
, keyword
, testCases
[i
].displayLocale
, u_errorName(status
));
2414 log_err("uloc_getDisplayKeywordValue did not return the expected value keyword : %s in locale id: %s for display locale: %s with error : %s \n", testCases
[i
].localeID
, keyword
, testCases
[i
].displayLocale
, u_errorName(status
));
2419 log_err("uloc_getDisplayKeywordValue did not return the expected error. Error: %s\n", u_errorName(status
));
2421 free(displayKeywordValue
);
2423 uenum_close(keywordEnum
);
2426 /* test a multiple keywords */
2427 UErrorCode status
= U_ZERO_ERROR
;
2428 const char* keyword
=NULL
;
2429 int32_t keywordLen
= 0;
2430 int32_t keywordCount
= 0;
2431 const char* localeID
= "es@collation=phonebook;calendar=buddhist;currency=DEM";
2432 const char* displayLocale
= "de";
2433 static const UChar expected
[][50] = {
2434 {0x0042, 0x0075, 0x0064, 0x0064, 0x0068, 0x0069, 0x0073, 0x0074, 0x0069, 0x0073, 0x0063, 0x0068, 0x0065, 0x0072, 0x0020, 0x004b, 0x0061, 0x006c, 0x0065, 0x006e, 0x0064, 0x0065, 0x0072, 0x0000},
2436 {0x0054, 0x0065, 0x006c, 0x0065, 0x0066, 0x006f, 0x006e, 0x0062, 0x0075, 0x0063, 0x0068, 0x002d, 0x0053, 0x006f, 0x0072, 0x0074, 0x0069, 0x0065, 0x0072, 0x0075, 0x006e, 0x0067, 0x0000},
2437 {0x0044, 0x0065, 0x0075, 0x0074, 0x0073, 0x0063, 0x0068, 0x0065, 0x0020, 0x004d, 0x0061, 0x0072, 0x006b, 0x0000},
2440 UEnumeration
* keywordEnum
= uloc_openKeywords(localeID
, &status
);
2442 for(keywordCount
= 0; keywordCount
< uenum_count(keywordEnum
, &status
) ; keywordCount
++){
2443 UChar
*displayKeywordValue
= NULL
;
2444 int32_t displayKeywordValueLen
= 0;
2445 if(U_FAILURE(status
)){
2446 log_err("uloc_getKeywords failed for locale id: %s in display locale: % with error : %s \n", localeID
, displayLocale
, u_errorName(status
));
2449 /* the uenum_next returns NUL terminated string */
2450 keyword
= uenum_next(keywordEnum
, &keywordLen
, &status
);
2452 /* fetch the displayKeywordValue */
2453 displayKeywordValueLen
= uloc_getDisplayKeywordValue(localeID
, keyword
, displayLocale
, displayKeywordValue
, displayKeywordValueLen
, &status
);
2454 if(status
==U_BUFFER_OVERFLOW_ERROR
){
2455 status
= U_ZERO_ERROR
;
2456 displayKeywordValueLen
++; /* for null termination */
2457 displayKeywordValue
= (UChar
*)malloc(displayKeywordValueLen
* U_SIZEOF_UCHAR
);
2458 displayKeywordValueLen
= uloc_getDisplayKeywordValue(localeID
, keyword
, displayLocale
, displayKeywordValue
, displayKeywordValueLen
, &status
);
2459 if(U_FAILURE(status
)){
2460 log_err("uloc_getDisplayKeywordValue failed for keyword : %s in locale id: %s for display locale: %s with error : %s \n", localeID
, keyword
, displayLocale
, u_errorName(status
));
2463 if(u_strncmp(displayKeywordValue
, expected
[keywordCount
], displayKeywordValueLen
)!=0){
2464 if (status
== U_USING_DEFAULT_WARNING
) {
2465 log_data_err("uloc_getDisplayKeywordValue did not return the expected value keyword : %s in locale id: %s for display locale: %s got error: %s. Perhaps you are missing data?\n", localeID
, keyword
, displayLocale
, u_errorName(status
));
2467 log_err("uloc_getDisplayKeywordValue did not return the expected value keyword : %s in locale id: %s for display locale: %s \n", localeID
, keyword
, displayLocale
);
2472 log_err("uloc_getDisplayKeywordValue did not return the expected error. Error: %s\n", u_errorName(status
));
2474 free(displayKeywordValue
);
2476 uenum_close(keywordEnum
);
2480 /* Test non existent keywords */
2481 UErrorCode status
= U_ZERO_ERROR
;
2482 const char* localeID
= "es";
2483 const char* displayLocale
= "de";
2484 UChar
*displayKeywordValue
= NULL
;
2485 int32_t displayKeywordValueLen
= 0;
2487 /* fetch the displayKeywordValue */
2488 displayKeywordValueLen
= uloc_getDisplayKeywordValue(localeID
, "calendar", displayLocale
, displayKeywordValue
, displayKeywordValueLen
, &status
);
2489 if(U_FAILURE(status
)) {
2490 log_err("uloc_getDisplaykeywordValue returned error status %s\n", u_errorName(status
));
2491 } else if(displayKeywordValueLen
!= 0) {
2492 log_err("uloc_getDisplaykeywordValue returned %d should be 0 \n", displayKeywordValueLen
);
2498 static void TestGetBaseName(void) {
2499 static const struct {
2500 const char *localeID
;
2501 const char *baseName
;
2503 { "de_DE@ C o ll A t i o n = Phonebook ", "de_DE" },
2504 { "de@currency = euro; CoLLaTion = PHONEBOOk", "de" },
2505 { "ja@calendar = buddhist", "ja" }
2508 int32_t i
= 0, baseNameLen
= 0;
2510 UErrorCode status
= U_ZERO_ERROR
;
2512 for(i
= 0; i
< UPRV_LENGTHOF(testCases
); i
++) {
2513 baseNameLen
= uloc_getBaseName(testCases
[i
].localeID
, baseName
, 256, &status
);
2514 (void)baseNameLen
; /* Suppress set but not used warning. */
2515 if(strcmp(testCases
[i
].baseName
, baseName
)) {
2516 log_err("For locale \"%s\" expected baseName \"%s\", but got \"%s\"\n",
2517 testCases
[i
].localeID
, testCases
[i
].baseName
, baseName
);
2523 static void TestTrailingNull(void) {
2524 const char* localeId
= "zh_Hans";
2525 UChar buffer
[128]; /* sufficient for this test */
2527 UErrorCode status
= U_ZERO_ERROR
;
2530 len
= uloc_getDisplayName(localeId
, localeId
, buffer
, 128, &status
);
2532 log_err("buffer too small");
2536 for (i
= 0; i
< len
; ++i
) {
2537 if (buffer
[i
] == 0) {
2538 log_err("name contained null");
2544 /* Jitterbug 4115 */
2545 static void TestDisplayNameWarning(void) {
2548 UErrorCode status
= U_ZERO_ERROR
;
2550 size
= uloc_getDisplayLanguage("qqq", "kl", name
, UPRV_LENGTHOF(name
), &status
);
2551 (void)size
; /* Suppress set but not used warning. */
2552 if (status
!= U_USING_DEFAULT_WARNING
) {
2553 log_err("For language \"qqq\" in locale \"kl\", expecting U_USING_DEFAULT_WARNING, but got %s\n",
2554 u_errorName(status
));
2560 * Compare two locale IDs. If they are equal, return 0. If `string'
2561 * starts with `prefix' plus an additional element, that is, string ==
2562 * prefix + '_' + x, then return 1. Otherwise return a value < 0.
2564 static UBool
_loccmp(const char* string
, const char* prefix
) {
2565 int32_t slen
= (int32_t)uprv_strlen(string
),
2566 plen
= (int32_t)uprv_strlen(prefix
);
2567 int32_t c
= uprv_strncmp(string
, prefix
, plen
);
2568 /* 'root' is less than everything */
2569 if (uprv_strcmp(prefix
, "root") == 0) {
2570 return (uprv_strcmp(string
, "root") == 0) ? 0 : 1;
2572 if (c
) return -1; /* mismatch */
2573 if (slen
== plen
) return 0;
2574 if (string
[plen
] == '_') return 1;
2575 return -2; /* false match, e.g. "en_USX" cmp "en_US" */
2578 static void _checklocs(const char* label
,
2581 const char* actual
) {
2582 /* We want the valid to be strictly > the bogus requested locale,
2583 and the valid to be >= the actual. */
2584 if (_loccmp(req
, valid
) > 0 &&
2585 _loccmp(valid
, actual
) >= 0) {
2586 log_verbose("%s; req=%s, valid=%s, actual=%s\n",
2587 label
, req
, valid
, actual
);
2589 log_err("FAIL: %s; req=%s, valid=%s, actual=%s\n",
2590 label
, req
, valid
, actual
);
2594 static void TestGetLocale(void) {
2595 UErrorCode ec
= U_ZERO_ERROR
;
2597 UChar EMPTY
[1] = {0};
2600 #if !UCONFIG_NO_FORMATTING
2603 const char *req
= "en_US_REDWOODSHORES", *valid
, *actual
;
2604 obj
= udat_open(UDAT_DEFAULT
, UDAT_DEFAULT
,
2608 if (U_FAILURE(ec
)) {
2609 log_data_err("udat_open failed.Error %s\n", u_errorName(ec
));
2612 valid
= udat_getLocaleByType(obj
, ULOC_VALID_LOCALE
, &ec
);
2613 actual
= udat_getLocaleByType(obj
, ULOC_ACTUAL_LOCALE
, &ec
);
2614 if (U_FAILURE(ec
)) {
2615 log_err("udat_getLocaleByType() failed\n");
2618 _checklocs("udat", req
, valid
, actual
);
2624 #if !UCONFIG_NO_FORMATTING
2627 const char *req
= "fr_FR_PROVENCAL", *valid
, *actual
;
2628 obj
= ucal_open(NULL
, 0,
2632 if (U_FAILURE(ec
)) {
2633 log_err("ucal_open failed with error: %s\n", u_errorName(ec
));
2636 valid
= ucal_getLocaleByType(obj
, ULOC_VALID_LOCALE
, &ec
);
2637 actual
= ucal_getLocaleByType(obj
, ULOC_ACTUAL_LOCALE
, &ec
);
2638 if (U_FAILURE(ec
)) {
2639 log_err("ucal_getLocaleByType() failed\n");
2642 _checklocs("ucal", req
, valid
, actual
);
2648 #if !UCONFIG_NO_FORMATTING
2651 const char *req
= "zh_Hant_TW_TAINAN", *valid
, *actual
;
2652 obj
= unum_open(UNUM_DECIMAL
,
2656 if (U_FAILURE(ec
)) {
2657 log_err("unum_open failed\n");
2660 valid
= unum_getLocaleByType(obj
, ULOC_VALID_LOCALE
, &ec
);
2661 actual
= unum_getLocaleByType(obj
, ULOC_ACTUAL_LOCALE
, &ec
);
2662 if (U_FAILURE(ec
)) {
2663 log_err("unum_getLocaleByType() failed\n");
2666 _checklocs("unum", req
, valid
, actual
);
2673 /* commented out by weiv 01/12/2005. umsg_getLocaleByType is to be removed */
2674 #if !UCONFIG_NO_FORMATTING
2676 UMessageFormat
*obj
;
2677 const char *req
= "ja_JP_TAKAYAMA", *valid
, *actual
;
2679 obj
= umsg_open(EMPTY
, 0,
2682 if (U_FAILURE(ec
)) {
2683 log_err("umsg_open failed\n");
2686 valid
= umsg_getLocaleByType(obj
, ULOC_VALID_LOCALE
, &ec
);
2687 actual
= umsg_getLocaleByType(obj
, ULOC_ACTUAL_LOCALE
, &ec
);
2688 if (U_FAILURE(ec
)) {
2689 log_err("umsg_getLocaleByType() failed\n");
2692 /* We want the valid to be strictly > the bogus requested locale,
2693 and the valid to be >= the actual. */
2694 /* TODO MessageFormat is currently just storing the locale it is given.
2695 As a result, it will return whatever it was given, even if the
2696 locale is invalid. */
2697 test
= (_cmpversion("3.2") <= 0) ?
2698 /* Here is the weakened test for 3.0: */
2699 (_loccmp(req
, valid
) >= 0) :
2700 /* Here is what the test line SHOULD be: */
2701 (_loccmp(req
, valid
) > 0);
2704 _loccmp(valid
, actual
) >= 0) {
2705 log_verbose("umsg; req=%s, valid=%s, actual=%s\n", req
, valid
, actual
);
2707 log_err("FAIL: umsg; req=%s, valid=%s, actual=%s\n", req
, valid
, actual
);
2715 #if !UCONFIG_NO_BREAK_ITERATION
2717 UBreakIterator
*obj
;
2718 const char *req
= "ar_KW_ABDALI", *valid
, *actual
;
2719 obj
= ubrk_open(UBRK_WORD
,
2724 if (U_FAILURE(ec
)) {
2725 log_err("ubrk_open failed. Error: %s \n", u_errorName(ec
));
2728 valid
= ubrk_getLocaleByType(obj
, ULOC_VALID_LOCALE
, &ec
);
2729 actual
= ubrk_getLocaleByType(obj
, ULOC_ACTUAL_LOCALE
, &ec
);
2730 if (U_FAILURE(ec
)) {
2731 log_err("ubrk_getLocaleByType() failed\n");
2734 _checklocs("ubrk", req
, valid
, actual
);
2740 #if !UCONFIG_NO_COLLATION
2743 const char *req
= "es_AR_BUENOSAIRES", *valid
, *actual
;
2744 obj
= ucol_open(req
, &ec
);
2745 if (U_FAILURE(ec
)) {
2746 log_err("ucol_open failed - %s\n", u_errorName(ec
));
2749 valid
= ucol_getLocaleByType(obj
, ULOC_VALID_LOCALE
, &ec
);
2750 actual
= ucol_getLocaleByType(obj
, ULOC_ACTUAL_LOCALE
, &ec
);
2751 if (U_FAILURE(ec
)) {
2752 log_err("ucol_getLocaleByType() failed\n");
2755 _checklocs("ucol", req
, valid
, actual
);
2760 static void TestEnglishExemplarCharacters(void) {
2761 UErrorCode status
= U_ZERO_ERROR
;
2764 UChar testChars
[] = {
2765 0x61, /* standard */
2766 0xE1, /* auxiliary */
2768 0x2D /* punctuation */
2770 ULocaleData
*uld
= ulocdata_open("en", &status
);
2771 if (U_FAILURE(status
)) {
2772 log_data_err("ulocdata_open() failed : %s - (Are you missing data?)\n", u_errorName(status
));
2776 for (i
= 0; i
< ULOCDATA_ES_COUNT
; i
++) {
2777 exSet
= ulocdata_getExemplarSet(uld
, exSet
, 0, (ULocaleDataExemplarSetType
)i
, &status
);
2778 if (U_FAILURE(status
)) {
2779 log_err_status(status
, "ulocdata_getExemplarSet() for type %d failed\n", i
);
2780 status
= U_ZERO_ERROR
;
2783 if (!uset_contains(exSet
, (UChar32
)testChars
[i
])) {
2784 log_err("Character U+%04X is not included in exemplar type %d\n", testChars
[i
], i
);
2789 ulocdata_close(uld
);
2792 static void TestNonexistentLanguageExemplars(void) {
2793 /* JB 4068 - Nonexistent language */
2794 UErrorCode ec
= U_ZERO_ERROR
;
2795 ULocaleData
*uld
= ulocdata_open("qqq",&ec
);
2796 if (ec
!= U_USING_DEFAULT_WARNING
) {
2797 log_err_status(ec
, "Exemplar set for \"qqq\", expecting U_USING_DEFAULT_WARNING, but got %s\n",
2800 uset_close(ulocdata_getExemplarSet(uld
, NULL
, 0, ULOCDATA_ES_STANDARD
, &ec
));
2801 ulocdata_close(uld
);
2804 static void TestLocDataErrorCodeChaining(void) {
2805 UErrorCode ec
= U_USELESS_COLLATOR_ERROR
;
2806 ulocdata_open(NULL
, &ec
);
2807 ulocdata_getExemplarSet(NULL
, NULL
, 0, ULOCDATA_ES_STANDARD
, &ec
);
2808 ulocdata_getDelimiter(NULL
, ULOCDATA_DELIMITER_COUNT
, NULL
, -1, &ec
);
2809 ulocdata_getMeasurementSystem(NULL
, &ec
);
2810 ulocdata_getPaperSize(NULL
, NULL
, NULL
, &ec
);
2811 if (ec
!= U_USELESS_COLLATOR_ERROR
) {
2812 log_err("ulocdata API changed the error code to %s\n", u_errorName(ec
));
2818 UMeasurementSystem measureSys
;
2821 static const LocToMeasureSys locToMeasures
[] = {
2822 { "fr_FR", UMS_SI
},
2824 { "en_GB", UMS_UK
},
2825 { "fr_FR@rg=GBZZZZ", UMS_UK
},
2826 { "en@rg=frzzzz", UMS_SI
},
2827 { "en_GB@rg=USZZZZ", UMS_US
},
2828 { NULL
, (UMeasurementSystem
)0 } /* terminator */
2831 static void TestLocDataWithRgTag(void) {
2832 const LocToMeasureSys
* locToMeasurePtr
= locToMeasures
;
2833 for (; locToMeasurePtr
->locale
!= NULL
; locToMeasurePtr
++) {
2834 UErrorCode status
= U_ZERO_ERROR
;
2835 UMeasurementSystem measureSys
= ulocdata_getMeasurementSystem(locToMeasurePtr
->locale
, &status
);
2836 if (U_FAILURE(status
)) {
2837 log_data_err("ulocdata_getMeasurementSystem(\"%s\", ...) failed: %s - Are you missing data?\n",
2838 locToMeasurePtr
->locale
, u_errorName(status
));
2839 } else if (measureSys
!= locToMeasurePtr
->measureSys
) {
2840 log_err("ulocdata_getMeasurementSystem(\"%s\", ...), expected %d, got %d\n",
2841 locToMeasurePtr
->locale
, (int) locToMeasurePtr
->measureSys
, (int)measureSys
);
2846 static void TestLanguageExemplarsFallbacks(void) {
2847 /* Test that en_US fallsback, but en doesn't fallback. */
2848 UErrorCode ec
= U_ZERO_ERROR
;
2849 ULocaleData
*uld
= ulocdata_open("en_US",&ec
);
2850 uset_close(ulocdata_getExemplarSet(uld
, NULL
, 0, ULOCDATA_ES_STANDARD
, &ec
));
2851 if (ec
!= U_USING_FALLBACK_WARNING
) {
2852 log_err_status(ec
, "Exemplar set for \"en_US\", expecting U_USING_FALLBACK_WARNING, but got %s\n",
2855 ulocdata_close(uld
);
2857 uld
= ulocdata_open("en",&ec
);
2858 uset_close(ulocdata_getExemplarSet(uld
, NULL
, 0, ULOCDATA_ES_STANDARD
, &ec
));
2859 if (ec
!= U_ZERO_ERROR
) {
2860 log_err_status(ec
, "Exemplar set for \"en\", expecting U_ZERO_ERROR, but got %s\n",
2863 ulocdata_close(uld
);
2866 static const char *acceptResult(UAcceptResult uar
) {
2867 return udbg_enumName(UDBG_UAcceptResult
, uar
);
2870 static void TestAcceptLanguage(void) {
2871 UErrorCode status
= U_ZERO_ERROR
;
2872 UAcceptResult outResult
;
2873 UEnumeration
*available
;
2879 int32_t httpSet
; /**< Which of http[] should be used? */
2880 const char *icuSet
; /**< ? */
2881 const char *expect
; /**< The expected locale result */
2882 UAcceptResult res
; /**< The expected error code */
2883 UErrorCode expectStatus
; /**< expected status */
2885 /*0*/{ 0, NULL
, "mt_MT", ULOC_ACCEPT_VALID
, U_ZERO_ERROR
},
2886 /*1*/{ 1, NULL
, "en", ULOC_ACCEPT_VALID
, U_ZERO_ERROR
},
2887 /*2*/{ 2, NULL
, "en", ULOC_ACCEPT_FALLBACK
, U_ZERO_ERROR
},
2888 /*3*/{ 3, NULL
, "", ULOC_ACCEPT_FAILED
, U_ZERO_ERROR
},
2889 /*4*/{ 4, NULL
, "es", ULOC_ACCEPT_VALID
, U_ZERO_ERROR
},
2890 /*5*/{ 5, NULL
, "en", ULOC_ACCEPT_VALID
, U_ZERO_ERROR
}, /* XF */
2891 /*6*/{ 6, NULL
, "ja", ULOC_ACCEPT_FALLBACK
, U_ZERO_ERROR
}, /* XF */
2892 /*7*/{ 7, NULL
, "zh", ULOC_ACCEPT_FALLBACK
, U_ZERO_ERROR
}, /* XF */
2893 /*8*/{ 8, NULL
, "", ULOC_ACCEPT_FAILED
, U_ZERO_ERROR
}, /* */
2894 /*9*/{ 9, NULL
, "", ULOC_ACCEPT_FAILED
, U_ZERO_ERROR
}, /* */
2895 /*10*/{10, NULL
, "", ULOC_ACCEPT_FAILED
, U_BUFFER_OVERFLOW_ERROR
}, /* */
2896 /*11*/{11, NULL
, "", ULOC_ACCEPT_FAILED
, U_BUFFER_OVERFLOW_ERROR
}, /* */
2898 const int32_t numTests
= UPRV_LENGTHOF(tests
);
2899 static const char *http
[] = {
2900 /*0*/ "mt-mt, ja;q=0.76, en-us;q=0.95, en;q=0.92, en-gb;q=0.89, fr;q=0.87, iu-ca;q=0.84, iu;q=0.82, ja-jp;q=0.79, mt;q=0.97, de-de;q=0.74, de;q=0.71, es;q=0.68, it-it;q=0.66, it;q=0.63, vi-vn;q=0.61, vi;q=0.58, nl-nl;q=0.55, nl;q=0.53, th-th-traditional;q=.01",
2901 /*1*/ "ja;q=0.5, en;q=0.8, tlh",
2902 /*2*/ "en-wf, de-lx;q=0.8",
2903 /*3*/ "mga-ie;q=0.9, tlh",
2904 /*4*/ "xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, "
2905 "xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, "
2906 "xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, "
2907 "xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, "
2908 "xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, "
2909 "xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, "
2910 "xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, xx-yy;q=.1, "
2912 /*5*/ "zh-xx;q=0.9, en;q=0.6",
2914 /*7*/ "zh-xx;q=0.9",
2915 /*08*/ "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
2916 "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
2917 "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
2918 "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", // 156
2919 /*09*/ "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
2920 "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
2921 "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
2922 "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB", // 157 (this hits U_STRING_NOT_TERMINATED_WARNING )
2923 /*10*/ "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
2924 "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
2925 "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
2926 "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABC", // 158
2927 /*11*/ "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
2928 "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
2929 "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
2930 "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", // 163 bytes
2933 for(i
=0;i
<numTests
;i
++) {
2935 status
=U_ZERO_ERROR
;
2936 log_verbose("test #%d: http[%s], ICU[%s], expect %s, %s\n",
2937 i
, http
[tests
[i
].httpSet
], tests
[i
].icuSet
, tests
[i
].expect
, acceptResult(tests
[i
].res
));
2939 available
= ures_openAvailableLocales(tests
[i
].icuSet
, &status
);
2941 rc
= uloc_acceptLanguageFromHTTP(tmp
, 199, &outResult
, http
[tests
[i
].httpSet
], available
, &status
);
2942 (void)rc
; /* Suppress set but not used warning. */
2943 uenum_close(available
);
2944 log_verbose(" got %s, %s [%s]\n", tmp
[0]?tmp
:"(EMPTY)", acceptResult(outResult
), u_errorName(status
));
2945 if(status
!= tests
[i
].expectStatus
) {
2946 log_err_status(status
, "FAIL: expected status %s but got %s\n", u_errorName(tests
[i
].expectStatus
), u_errorName(status
));
2947 } else if(U_SUCCESS(tests
[i
].expectStatus
)) {
2948 /* don't check content if expected failure */
2949 if(outResult
!= tests
[i
].res
) {
2950 log_err_status(status
, "FAIL: #%d: expected outResult of %s but got %s\n", i
,
2951 acceptResult( tests
[i
].res
),
2952 acceptResult( outResult
));
2953 log_info("test #%d: http[%s], ICU[%s], expect %s, %s\n",
2954 i
, http
[tests
[i
].httpSet
], tests
[i
].icuSet
, tests
[i
].expect
,acceptResult(tests
[i
].res
));
2956 if((outResult
>0)&&uprv_strcmp(tmp
, tests
[i
].expect
)) {
2957 log_err_status(status
, "FAIL: #%d: expected %s but got %s\n", i
, tests
[i
].expect
, tmp
);
2958 log_info("test #%d: http[%s], ICU[%s], expect %s, %s\n",
2959 i
, http
[tests
[i
].httpSet
], tests
[i
].icuSet
, tests
[i
].expect
, acceptResult(tests
[i
].res
));
2965 static const char* LOCALE_ALIAS
[][2] = {
2979 static UBool
isLocaleAvailable(UResourceBundle
* resIndex
, const char* loc
){
2980 UErrorCode status
= U_ZERO_ERROR
;
2982 ures_getStringByKey(resIndex
, loc
,&len
, &status
);
2983 if(U_FAILURE(status
)){
2989 static void TestCalendar() {
2990 #if !UCONFIG_NO_FORMATTING
2992 UErrorCode status
= U_ZERO_ERROR
;
2993 UResourceBundle
*resIndex
= ures_open(NULL
,"res_index", &status
);
2994 if(U_FAILURE(status
)){
2995 log_err_status(status
, "Could not open res_index.res. Exiting. Error: %s\n", u_errorName(status
));
2998 for (i
=0; i
<UPRV_LENGTHOF(LOCALE_ALIAS
); i
++) {
2999 const char* oldLoc
= LOCALE_ALIAS
[i
][0];
3000 const char* newLoc
= LOCALE_ALIAS
[i
][1];
3001 UCalendar
* c1
= NULL
;
3002 UCalendar
* c2
= NULL
;
3004 /*Test function "getLocale(ULocale.VALID_LOCALE)"*/
3005 const char* l1
= ucal_getLocaleByType(c1
, ULOC_VALID_LOCALE
, &status
);
3006 const char* l2
= ucal_getLocaleByType(c2
, ULOC_VALID_LOCALE
, &status
);
3008 if(!isLocaleAvailable(resIndex
, newLoc
)){
3011 c1
= ucal_open(NULL
, -1, oldLoc
, UCAL_GREGORIAN
, &status
);
3012 c2
= ucal_open(NULL
, -1, newLoc
, UCAL_GREGORIAN
, &status
);
3014 if (strcmp(newLoc
,l1
)!=0 || strcmp(l1
,l2
)!=0 || status
!=U_ZERO_ERROR
) {
3015 log_err("The locales are not equal!.Old: %s, New: %s \n", oldLoc
, newLoc
);
3017 log_verbose("ucal_getLocaleByType old:%s new:%s\n", l1
, l2
);
3021 ures_close(resIndex
);
3025 static void TestDateFormat() {
3026 #if !UCONFIG_NO_FORMATTING
3028 UErrorCode status
= U_ZERO_ERROR
;
3029 UResourceBundle
*resIndex
= ures_open(NULL
,"res_index", &status
);
3030 if(U_FAILURE(status
)){
3031 log_err_status(status
, "Could not open res_index.res. Exiting. Error: %s\n", u_errorName(status
));
3034 for (i
=0; i
<UPRV_LENGTHOF(LOCALE_ALIAS
); i
++) {
3035 const char* oldLoc
= LOCALE_ALIAS
[i
][0];
3036 const char* newLoc
= LOCALE_ALIAS
[i
][1];
3037 UDateFormat
* df1
= NULL
;
3038 UDateFormat
* df2
= NULL
;
3039 const char* l1
= NULL
;
3040 const char* l2
= NULL
;
3042 if(!isLocaleAvailable(resIndex
, newLoc
)){
3045 df1
= udat_open(UDAT_FULL
, UDAT_FULL
,oldLoc
, NULL
, 0, NULL
, -1, &status
);
3046 df2
= udat_open(UDAT_FULL
, UDAT_FULL
,newLoc
, NULL
, 0, NULL
, -1, &status
);
3047 if(U_FAILURE(status
)){
3048 log_err("Creation of date format failed %s\n", u_errorName(status
));
3051 /*Test function "getLocale"*/
3052 l1
= udat_getLocaleByType(df1
, ULOC_VALID_LOCALE
, &status
);
3053 l2
= udat_getLocaleByType(df2
, ULOC_VALID_LOCALE
, &status
);
3054 if(U_FAILURE(status
)){
3055 log_err("Fetching the locale by type failed. %s\n", u_errorName(status
));
3057 if (strcmp(newLoc
,l1
)!=0 || strcmp(l1
,l2
)!=0) {
3058 log_err("The locales are not equal!.Old: %s, New: %s \n", oldLoc
, newLoc
);
3060 log_verbose("udat_getLocaleByType old:%s new:%s\n", l1
, l2
);
3064 ures_close(resIndex
);
3068 static void TestCollation() {
3069 #if !UCONFIG_NO_COLLATION
3071 UErrorCode status
= U_ZERO_ERROR
;
3072 UResourceBundle
*resIndex
= ures_open(NULL
,"res_index", &status
);
3073 if(U_FAILURE(status
)){
3074 log_err_status(status
, "Could not open res_index.res. Exiting. Error: %s\n", u_errorName(status
));
3077 for (i
=0; i
<UPRV_LENGTHOF(LOCALE_ALIAS
); i
++) {
3078 const char* oldLoc
= LOCALE_ALIAS
[i
][0];
3079 const char* newLoc
= LOCALE_ALIAS
[i
][1];
3080 UCollator
* c1
= NULL
;
3081 UCollator
* c2
= NULL
;
3082 const char* l1
= NULL
;
3083 const char* l2
= NULL
;
3085 status
= U_ZERO_ERROR
;
3086 if(!isLocaleAvailable(resIndex
, newLoc
)){
3089 if(U_FAILURE(status
)){
3090 log_err("Creation of collators failed %s\n", u_errorName(status
));
3093 c1
= ucol_open(oldLoc
, &status
);
3094 c2
= ucol_open(newLoc
, &status
);
3095 l1
= ucol_getLocaleByType(c1
, ULOC_VALID_LOCALE
, &status
);
3096 l2
= ucol_getLocaleByType(c2
, ULOC_VALID_LOCALE
, &status
);
3097 if(U_FAILURE(status
)){
3098 log_err("Fetching the locale names failed failed %s\n", u_errorName(status
));
3100 if (strcmp(newLoc
,l1
)!=0 || strcmp(l1
,l2
)!=0) {
3101 log_err("The locales are not equal!.Old: %s, New: %s \n", oldLoc
, newLoc
);
3103 log_verbose("ucol_getLocaleByType old:%s new:%s\n", l1
, l2
);
3107 ures_close(resIndex
);
3111 typedef struct OrientationStructTag
{
3112 const char* localeId
;
3113 ULayoutType character
;
3115 } OrientationStruct
;
3117 static const char* ULayoutTypeToString(ULayoutType type
)
3121 case ULOC_LAYOUT_LTR
:
3122 return "ULOC_LAYOUT_LTR";
3124 case ULOC_LAYOUT_RTL
:
3125 return "ULOC_LAYOUT_RTL";
3127 case ULOC_LAYOUT_TTB
:
3128 return "ULOC_LAYOUT_TTB";
3130 case ULOC_LAYOUT_BTT
:
3131 return "ULOC_LAYOUT_BTT";
3133 case ULOC_LAYOUT_UNKNOWN
:
3137 return "Unknown enum value for ULayoutType!";
3140 static void TestOrientation()
3142 static const OrientationStruct toTest
[] = {
3143 { "ar", ULOC_LAYOUT_RTL
, ULOC_LAYOUT_TTB
},
3144 { "aR", ULOC_LAYOUT_RTL
, ULOC_LAYOUT_TTB
},
3145 { "ar_Arab", ULOC_LAYOUT_RTL
, ULOC_LAYOUT_TTB
},
3146 { "fa", ULOC_LAYOUT_RTL
, ULOC_LAYOUT_TTB
},
3147 { "Fa", ULOC_LAYOUT_RTL
, ULOC_LAYOUT_TTB
},
3148 { "he", ULOC_LAYOUT_RTL
, ULOC_LAYOUT_TTB
},
3149 { "ps", ULOC_LAYOUT_RTL
, ULOC_LAYOUT_TTB
},
3150 { "ur", ULOC_LAYOUT_RTL
, ULOC_LAYOUT_TTB
},
3151 { "UR", ULOC_LAYOUT_RTL
, ULOC_LAYOUT_TTB
},
3152 { "en", ULOC_LAYOUT_LTR
, ULOC_LAYOUT_TTB
}
3156 for (; i
< UPRV_LENGTHOF(toTest
); ++i
) {
3157 UErrorCode statusCO
= U_ZERO_ERROR
;
3158 UErrorCode statusLO
= U_ZERO_ERROR
;
3159 const char* const localeId
= toTest
[i
].localeId
;
3160 const ULayoutType co
= uloc_getCharacterOrientation(localeId
, &statusCO
);
3161 const ULayoutType expectedCO
= toTest
[i
].character
;
3162 const ULayoutType lo
= uloc_getLineOrientation(localeId
, &statusLO
);
3163 const ULayoutType expectedLO
= toTest
[i
].line
;
3164 if (U_FAILURE(statusCO
)) {
3165 log_err_status(statusCO
,
3166 " unexpected failure for uloc_getCharacterOrientation(), with localId \"%s\" and status %s\n",
3168 u_errorName(statusCO
));
3170 else if (co
!= expectedCO
) {
3172 " unexpected result for uloc_getCharacterOrientation(), with localeId \"%s\". Expected %s but got result %s\n",
3174 ULayoutTypeToString(expectedCO
),
3175 ULayoutTypeToString(co
));
3177 if (U_FAILURE(statusLO
)) {
3178 log_err_status(statusLO
,
3179 " unexpected failure for uloc_getLineOrientation(), with localId \"%s\" and status %s\n",
3181 u_errorName(statusLO
));
3183 else if (lo
!= expectedLO
) {
3185 " unexpected result for uloc_getLineOrientation(), with localeId \"%s\". Expected %s but got result %s\n",
3187 ULayoutTypeToString(expectedLO
),
3188 ULayoutTypeToString(lo
));
3193 static void TestULocale() {
3195 UErrorCode status
= U_ZERO_ERROR
;
3196 UResourceBundle
*resIndex
= ures_open(NULL
,"res_index", &status
);
3197 if(U_FAILURE(status
)){
3198 log_err_status(status
, "Could not open res_index.res. Exiting. Error: %s\n", u_errorName(status
));
3201 for (i
=0; i
<UPRV_LENGTHOF(LOCALE_ALIAS
); i
++) {
3202 const char* oldLoc
= LOCALE_ALIAS
[i
][0];
3203 const char* newLoc
= LOCALE_ALIAS
[i
][1];
3204 UChar name1
[256], name2
[256];
3205 char names1
[256], names2
[256];
3206 int32_t capacity
= 256;
3208 status
= U_ZERO_ERROR
;
3209 if(!isLocaleAvailable(resIndex
, newLoc
)){
3212 uloc_getDisplayName(oldLoc
, ULOC_US
, name1
, capacity
, &status
);
3213 if(U_FAILURE(status
)){
3214 log_err("uloc_getDisplayName(%s) failed %s\n", oldLoc
, u_errorName(status
));
3217 uloc_getDisplayName(newLoc
, ULOC_US
, name2
, capacity
, &status
);
3218 if(U_FAILURE(status
)){
3219 log_err("uloc_getDisplayName(%s) failed %s\n", newLoc
, u_errorName(status
));
3222 if (u_strcmp(name1
, name2
)!=0) {
3223 log_err("The locales are not equal!.Old: %s, New: %s \n", oldLoc
, newLoc
);
3225 u_austrcpy(names1
, name1
);
3226 u_austrcpy(names2
, name2
);
3227 log_verbose("uloc_getDisplayName old:%s new:%s\n", names1
, names2
);
3229 ures_close(resIndex
);
3233 static void TestUResourceBundle() {
3237 UResourceBundle
* rb1
= NULL
;
3238 UResourceBundle
* rb2
= NULL
;
3239 UErrorCode status
= U_ZERO_ERROR
;
3241 UResourceBundle
*resIndex
= NULL
;
3242 if(U_FAILURE(status
)){
3243 log_err("Could not open res_index.res. Exiting. Error: %s\n", u_errorName(status
));
3246 resIndex
= ures_open(NULL
,"res_index", &status
);
3247 for (i
=0; i
<UPRV_LENGTHOF(LOCALE_ALIAS
); i
++) {
3249 const char* oldLoc
= LOCALE_ALIAS
[i
][0];
3250 const char* newLoc
= LOCALE_ALIAS
[i
][1];
3251 if(!isLocaleAvailable(resIndex
, newLoc
)){
3254 rb1
= ures_open(NULL
, oldLoc
, &status
);
3255 if (U_FAILURE(status
)) {
3256 log_err("ures_open(%s) failed %s\n", oldLoc
, u_errorName(status
));
3259 us1
= ures_getLocaleByType(rb1
, ULOC_ACTUAL_LOCALE
, &status
);
3261 status
= U_ZERO_ERROR
;
3262 rb2
= ures_open(NULL
, newLoc
, &status
);
3263 if (U_FAILURE(status
)) {
3264 log_err("ures_open(%s) failed %s\n", oldLoc
, u_errorName(status
));
3266 us2
= ures_getLocaleByType(rb2
, ULOC_ACTUAL_LOCALE
, &status
);
3268 if (strcmp(us1
,newLoc
)!=0 || strcmp(us1
,us2
)!=0 ) {
3269 log_err("The locales are not equal!.Old: %s, New: %s \n", oldLoc
, newLoc
);
3272 log_verbose("ures_getStringByKey old:%s new:%s\n", us1
, us2
);
3278 ures_close(resIndex
);
3281 static void TestDisplayName() {
3283 UChar oldCountry
[256] = {'\0'};
3284 UChar newCountry
[256] = {'\0'};
3285 UChar oldLang
[256] = {'\0'};
3286 UChar newLang
[256] = {'\0'};
3287 char country
[256] ={'\0'};
3288 char language
[256] ={'\0'};
3289 int32_t capacity
= 256;
3292 for (i
=0; i
<UPRV_LENGTHOF(LOCALE_ALIAS
); i
++) {
3293 const char* oldLoc
= LOCALE_ALIAS
[i
][0];
3294 const char* newLoc
= LOCALE_ALIAS
[i
][1];
3295 UErrorCode status
= U_ZERO_ERROR
;
3296 int32_t available
= uloc_countAvailable();
3298 for(j
=0; j
<available
; j
++){
3300 const char* dispLoc
= uloc_getAvailable(j
);
3301 int32_t oldCountryLen
= uloc_getDisplayCountry(oldLoc
,dispLoc
, oldCountry
, capacity
, &status
);
3302 int32_t newCountryLen
= uloc_getDisplayCountry(newLoc
, dispLoc
, newCountry
, capacity
, &status
);
3303 int32_t oldLangLen
= uloc_getDisplayLanguage(oldLoc
, dispLoc
, oldLang
, capacity
, &status
);
3304 int32_t newLangLen
= uloc_getDisplayLanguage(newLoc
, dispLoc
, newLang
, capacity
, &status
);
3306 int32_t countryLen
= uloc_getCountry(newLoc
, country
, capacity
, &status
);
3307 int32_t langLen
= uloc_getLanguage(newLoc
, language
, capacity
, &status
);
3308 /* there is a display name for the current country ID */
3309 if(countryLen
!= newCountryLen
){
3310 if(u_strncmp(oldCountry
,newCountry
,oldCountryLen
)!=0){
3311 log_err("uloc_getDisplayCountry() failed for %s in display locale %s \n", oldLoc
, dispLoc
);
3314 /* there is a display name for the current lang ID */
3315 if(langLen
!=newLangLen
){
3316 if(u_strncmp(oldLang
,newLang
,oldLangLen
)){
3317 log_err("uloc_getDisplayLanguage() failed for %s in display locale %s \n", oldLoc
, dispLoc
); }
3323 static void TestGetLocaleForLCID() {
3324 int32_t i
, length
, lengthPre
;
3325 const char* testLocale
= 0;
3326 UErrorCode status
= U_ZERO_ERROR
;
3327 char temp2
[40], temp3
[40];
3330 lcid
= uloc_getLCID("en_US");
3331 if (lcid
!= 0x0409) {
3332 log_err(" uloc_getLCID(\"en_US\") = %d, expected 0x0409\n", lcid
);
3335 lengthPre
= uloc_getLocaleForLCID(lcid
, temp2
, 4, &status
);
3336 if (status
!= U_BUFFER_OVERFLOW_ERROR
) {
3337 log_err(" unexpected result from uloc_getLocaleForLCID with small buffer: %s\n", u_errorName(status
));
3340 status
= U_ZERO_ERROR
;
3343 length
= uloc_getLocaleForLCID(lcid
, temp2
, UPRV_LENGTHOF(temp2
), &status
);
3344 if (U_FAILURE(status
)) {
3345 log_err(" unexpected result from uloc_getLocaleForLCID(0x0409): %s\n", u_errorName(status
));
3346 status
= U_ZERO_ERROR
;
3349 if (length
!= lengthPre
) {
3350 log_err(" uloc_getLocaleForLCID(0x0409): returned length %d does not match preflight length %d\n", length
, lengthPre
);
3353 length
= uloc_getLocaleForLCID(0x12345, temp2
, UPRV_LENGTHOF(temp2
), &status
);
3354 if (U_SUCCESS(status
)) {
3355 log_err(" unexpected result from uloc_getLocaleForLCID(0x12345): %s, status %s\n", temp2
, u_errorName(status
));
3357 status
= U_ZERO_ERROR
;
3359 log_verbose("Testing getLocaleForLCID vs. locale data\n");
3360 for (i
= 0; i
< LOCALE_SIZE
; i
++) {
3362 testLocale
=rawData2
[NAME
][i
];
3364 log_verbose("Testing %s ......\n", testLocale
);
3366 sscanf(rawData2
[LCID
][i
], "%x", &lcid
);
3367 length
= uloc_getLocaleForLCID(lcid
, temp2
, UPRV_LENGTHOF(temp2
), &status
);
3368 if (U_FAILURE(status
)) {
3369 log_err(" unexpected failure of uloc_getLocaleForLCID(%#04x), status %s\n", lcid
, u_errorName(status
));
3370 status
= U_ZERO_ERROR
;
3374 if (length
!= uprv_strlen(temp2
)) {
3375 log_err(" returned length %d not correct for uloc_getLocaleForLCID(%#04x), expected %d\n", length
, lcid
, uprv_strlen(temp2
));
3378 /* Compare language, country, script */
3379 length
= uloc_getLanguage(temp2
, temp3
, UPRV_LENGTHOF(temp3
), &status
);
3380 if (U_FAILURE(status
)) {
3381 log_err(" couldn't get language in uloc_getLocaleForLCID(%#04x) = %s, status %s\n", lcid
, temp2
, u_errorName(status
));
3382 status
= U_ZERO_ERROR
;
3384 else if (uprv_strcmp(temp3
, rawData2
[LANG
][i
]) && !(uprv_strcmp(temp3
, "nn") == 0 && uprv_strcmp(rawData2
[VAR
][i
], "NY") == 0)) {
3385 log_err(" language doesn't match expected %s in in uloc_getLocaleForLCID(%#04x) = %s\n", rawData2
[LANG
][i
], lcid
, temp2
);
3388 length
= uloc_getScript(temp2
, temp3
, UPRV_LENGTHOF(temp3
), &status
);
3389 if (U_FAILURE(status
)) {
3390 log_err(" couldn't get script in uloc_getLocaleForLCID(%#04x) = %s, status %s\n", lcid
, temp2
, u_errorName(status
));
3391 status
= U_ZERO_ERROR
;
3393 else if (uprv_strcmp(temp3
, rawData2
[SCRIPT
][i
])) {
3394 log_err(" script doesn't match expected %s in in uloc_getLocaleForLCID(%#04x) = %s\n", rawData2
[SCRIPT
][i
], lcid
, temp2
);
3397 length
= uloc_getCountry(temp2
, temp3
, UPRV_LENGTHOF(temp3
), &status
);
3398 if (U_FAILURE(status
)) {
3399 log_err(" couldn't get country in uloc_getLocaleForLCID(%#04x) = %s, status %s\n", lcid
, temp2
, u_errorName(status
));
3400 status
= U_ZERO_ERROR
;
3402 else if (uprv_strlen(rawData2
[CTRY
][i
]) && uprv_strcmp(temp3
, rawData2
[CTRY
][i
])) {
3403 log_err(" country doesn't match expected %s in in uloc_getLocaleForLCID(%#04x) = %s\n", rawData2
[CTRY
][i
], lcid
, temp2
);
3409 const char* const basic_maximize_data
[][2] = {
3454 "en_Latn_US_POSIX_1901"
3456 "en_Latn__POSIX_1901",
3457 "en_Latn_US_POSIX_1901"
3460 "en_Latn_US_POSIX_1901"
3463 "de_Latn_DE_POSIX_1901"
3468 "th@calendar=buddhist",
3469 "th_Thai_TH@calendar=buddhist"
3499 "de_Latn_DE_U_CO_PHONEBK"
3501 "de_Latn_u_co_phonebk",
3502 "de_Latn_DE_U_CO_PHONEBK"
3504 "de_Latn_DE_u_co_phonebk",
3505 "de_Latn_DE_U_CO_PHONEBK"
3508 "ar_Arab_EG@em=emoji"
3511 "en_Latn_US@em=emoji"
3513 "_Latn_DE@em=emoji",
3514 "de_Latn_DE@em=emoji"
3516 "_Zzzz_DE@em=emoji",
3517 "de_Latn_DE@em=emoji"
3520 "de_Latn_DE@em=emoji"
3524 const char* const basic_minimize_data
[][2] = {
3529 "en_Latn_US_POSIX_1901",
3532 "EN_Latn_US_POSIX_1901",
3535 "en_Zzzz_US_POSIX_1901",
3538 "de_Latn_DE_POSIX_1901",
3544 "en_Latn_US@calendar=gregorian",
3545 "en@calendar=gregorian"
3549 const char* const full_data
[][3] = {
3553 /* "REMOVE-LIKELY" */
5036 "zh_Hani_CN", /* changed due to cldrbug 6204, may be an error */
5037 "zh_Hani", /* changed due to cldrbug 6204, may be an error */
5623 "de@collation=phonebook",
5624 "de_Latn_DE@collation=phonebook",
5625 "de@collation=phonebook"
5629 typedef struct errorDataTag
{
5631 const char* expected
;
5636 const errorData maximizeErrors
[] = {
5640 U_ILLEGAL_ARGUMENT_ERROR
,
5644 "en_THUJIOGIURJHGJFURYHFJGURYYYHHGJURHG",
5646 U_ILLEGAL_ARGUMENT_ERROR
,
5650 "en_THUJIOGIURJHGJFURYHFJGURYYYHHGJURHG",
5652 U_ILLEGAL_ARGUMENT_ERROR
,
5656 "en_Latn_US_POSIX@currency=EURO",
5657 "en_Latn_US_POSIX@currency=EURO",
5658 U_BUFFER_OVERFLOW_ERROR
,
5662 "en_Latn_US_POSIX@currency=EURO",
5663 "en_Latn_US_POSIX@currency=EURO",
5664 U_STRING_NOT_TERMINATED_WARNING
,
5669 const errorData minimizeErrors
[] = {
5673 U_ILLEGAL_ARGUMENT_ERROR
,
5677 "en_THUJIOGIURJHGJFURYHFJGURYYYHHGJURHG",
5679 U_ILLEGAL_ARGUMENT_ERROR
,
5683 "en_Latn_US_POSIX@currency=EURO",
5684 "en__POSIX@currency=EURO",
5685 U_BUFFER_OVERFLOW_ERROR
,
5689 "en_Latn_US_POSIX@currency=EURO",
5690 "en__POSIX@currency=EURO",
5691 U_STRING_NOT_TERMINATED_WARNING
,
5696 static int32_t getExpectedReturnValue(const errorData
* data
)
5698 if (data
->uerror
== U_BUFFER_OVERFLOW_ERROR
||
5699 data
->uerror
== U_STRING_NOT_TERMINATED_WARNING
)
5701 return strlen(data
->expected
);
5709 static int32_t getBufferSize(const errorData
* data
, int32_t actualSize
)
5711 if (data
->expected
== NULL
)
5715 else if (data
->bufferSize
< 0)
5717 return strlen(data
->expected
) + 1;
5721 return data
->bufferSize
;
5725 static void TestLikelySubtags()
5727 char buffer
[ULOC_FULLNAME_CAPACITY
+ ULOC_KEYWORD_AND_VALUES_CAPACITY
+ 1];
5730 for (; i
< UPRV_LENGTHOF(basic_maximize_data
); ++i
)
5732 UErrorCode status
= U_ZERO_ERROR
;
5733 const char* const minimal
= basic_maximize_data
[i
][0];
5734 const char* const maximal
= basic_maximize_data
[i
][1];
5736 /* const int32_t length = */
5737 uloc_addLikelySubtags(
5742 if (U_FAILURE(status
)) {
5743 log_err_status(status
, " unexpected failure of uloc_addLikelySubtags(), minimal \"%s\" status %s\n", minimal
, u_errorName(status
));
5744 status
= U_ZERO_ERROR
;
5746 else if (uprv_strlen(maximal
) == 0) {
5747 if (uprv_stricmp(minimal
, buffer
) != 0) {
5748 log_err(" unexpected maximal value \"%s\" in uloc_addLikelySubtags(), minimal \"%s\" = \"%s\"\n", maximal
, minimal
, buffer
);
5751 else if (uprv_stricmp(maximal
, buffer
) != 0) {
5752 log_err(" maximal doesn't match expected %s in uloc_addLikelySubtags(), minimal \"%s\" = %s\n", maximal
, minimal
, buffer
);
5756 for (i
= 0; i
< UPRV_LENGTHOF(basic_minimize_data
); ++i
) {
5758 UErrorCode status
= U_ZERO_ERROR
;
5759 const char* const maximal
= basic_minimize_data
[i
][0];
5760 const char* const minimal
= basic_minimize_data
[i
][1];
5762 /* const int32_t length = */
5763 uloc_minimizeSubtags(
5769 if (U_FAILURE(status
)) {
5770 log_err_status(status
, " unexpected failure of uloc_MinimizeSubtags(), maximal \"%s\" status %s\n", maximal
, u_errorName(status
));
5771 status
= U_ZERO_ERROR
;
5773 else if (uprv_strlen(minimal
) == 0) {
5774 if (uprv_stricmp(maximal
, buffer
) != 0) {
5775 log_err(" unexpected minimal value \"%s\" in uloc_minimizeSubtags(), maximal \"%s\" = \"%s\"\n", minimal
, maximal
, buffer
);
5778 else if (uprv_stricmp(minimal
, buffer
) != 0) {
5779 log_err(" minimal doesn't match expected %s in uloc_MinimizeSubtags(), maximal \"%s\" = %s\n", minimal
, maximal
, buffer
);
5783 for (i
= 0; i
< UPRV_LENGTHOF(full_data
); ++i
) {
5785 UErrorCode status
= U_ZERO_ERROR
;
5786 const char* const minimal
= full_data
[i
][0];
5787 const char* const maximal
= full_data
[i
][1];
5789 /* const int32_t length = */
5790 uloc_addLikelySubtags(
5795 if (U_FAILURE(status
)) {
5796 log_err_status(status
, " unexpected failure of uloc_addLikelySubtags(), minimal \"%s\" status \"%s\"\n", minimal
, u_errorName(status
));
5797 status
= U_ZERO_ERROR
;
5799 else if (uprv_strlen(maximal
) == 0) {
5800 if (uprv_stricmp(minimal
, buffer
) != 0) {
5801 log_err(" unexpected maximal value \"%s\" in uloc_addLikelySubtags(), minimal \"%s\" = \"%s\"\n", maximal
, minimal
, buffer
);
5804 else if (uprv_stricmp(maximal
, buffer
) != 0) {
5805 log_err(" maximal doesn't match expected \"%s\" in uloc_addLikelySubtags(), minimal \"%s\" = \"%s\"\n", maximal
, minimal
, buffer
);
5809 for (i
= 0; i
< UPRV_LENGTHOF(full_data
); ++i
) {
5811 UErrorCode status
= U_ZERO_ERROR
;
5812 const char* const maximal
= full_data
[i
][1];
5813 const char* const minimal
= full_data
[i
][2];
5815 if (strlen(maximal
) > 0) {
5817 /* const int32_t length = */
5818 uloc_minimizeSubtags(
5824 if (U_FAILURE(status
)) {
5825 log_err_status(status
, " unexpected failure of uloc_minimizeSubtags(), maximal \"%s\" status %s\n", maximal
, u_errorName(status
));
5826 status
= U_ZERO_ERROR
;
5828 else if (uprv_strlen(minimal
) == 0) {
5829 if (uprv_stricmp(maximal
, buffer
) != 0) {
5830 log_err(" unexpected minimal value \"%s\" in uloc_minimizeSubtags(), maximal \"%s\" = \"%s\"\n", minimal
, maximal
, buffer
);
5833 else if (uprv_stricmp(minimal
, buffer
) != 0) {
5834 log_err(" minimal doesn't match expected %s in uloc_MinimizeSubtags(), maximal \"%s\" = %s\n", minimal
, maximal
, buffer
);
5839 for (i
= 0; i
< UPRV_LENGTHOF(maximizeErrors
); ++i
) {
5841 UErrorCode status
= U_ZERO_ERROR
;
5842 const char* const minimal
= maximizeErrors
[i
].tag
;
5843 const char* const maximal
= maximizeErrors
[i
].expected
;
5844 const UErrorCode expectedStatus
= maximizeErrors
[i
].uerror
;
5845 const int32_t expectedLength
= getExpectedReturnValue(&maximizeErrors
[i
]);
5846 const int32_t bufferSize
= getBufferSize(&maximizeErrors
[i
], sizeof(buffer
));
5848 const int32_t length
=
5849 uloc_addLikelySubtags(
5855 if (status
== U_ZERO_ERROR
) {
5856 log_err(" unexpected U_ZERO_ERROR for uloc_addLikelySubtags(), minimal \"%s\" expected status %s\n", minimal
, u_errorName(expectedStatus
));
5857 status
= U_ZERO_ERROR
;
5859 else if (status
!= expectedStatus
) {
5860 log_err_status(status
, " unexpected status for uloc_addLikelySubtags(), minimal \"%s\" expected status %s, but got %s\n", minimal
, u_errorName(expectedStatus
), u_errorName(status
));
5862 else if (length
!= expectedLength
) {
5863 log_err(" unexpected length for uloc_addLikelySubtags(), minimal \"%s\" expected length %d, but got %d\n", minimal
, expectedLength
, length
);
5865 else if (status
== U_BUFFER_OVERFLOW_ERROR
|| status
== U_STRING_NOT_TERMINATED_WARNING
) {
5866 if (uprv_strnicmp(maximal
, buffer
, bufferSize
) != 0) {
5867 log_err(" maximal doesn't match expected %s in uloc_addLikelySubtags(), minimal \"%s\" = %*s\n",
5868 maximal
, minimal
, (int)sizeof(buffer
), buffer
);
5873 for (i
= 0; i
< UPRV_LENGTHOF(minimizeErrors
); ++i
) {
5875 UErrorCode status
= U_ZERO_ERROR
;
5876 const char* const maximal
= minimizeErrors
[i
].tag
;
5877 const char* const minimal
= minimizeErrors
[i
].expected
;
5878 const UErrorCode expectedStatus
= minimizeErrors
[i
].uerror
;
5879 const int32_t expectedLength
= getExpectedReturnValue(&minimizeErrors
[i
]);
5880 const int32_t bufferSize
= getBufferSize(&minimizeErrors
[i
], sizeof(buffer
));
5882 const int32_t length
=
5883 uloc_minimizeSubtags(
5889 if (status
== U_ZERO_ERROR
) {
5890 log_err(" unexpected U_ZERO_ERROR for uloc_minimizeSubtags(), maximal \"%s\" expected status %s\n", maximal
, u_errorName(expectedStatus
));
5891 status
= U_ZERO_ERROR
;
5893 else if (status
!= expectedStatus
) {
5894 log_err_status(status
, " unexpected status for uloc_minimizeSubtags(), maximal \"%s\" expected status %s, but got %s\n", maximal
, u_errorName(expectedStatus
), u_errorName(status
));
5896 else if (length
!= expectedLength
) {
5897 log_err(" unexpected length for uloc_minimizeSubtags(), maximal \"%s\" expected length %d, but got %d\n", maximal
, expectedLength
, length
);
5899 else if (status
== U_BUFFER_OVERFLOW_ERROR
|| status
== U_STRING_NOT_TERMINATED_WARNING
) {
5900 if (uprv_strnicmp(minimal
, buffer
, bufferSize
) != 0) {
5901 log_err(" minimal doesn't match expected \"%s\" in uloc_minimizeSubtags(), minimal \"%s\" = \"%*s\"\n",
5902 minimal
, maximal
, (int)sizeof(buffer
), buffer
);
5908 const char* const locale_to_langtag
[][3] = {
5911 {"en_US", "en-US", "en-US"},
5912 {"iw_IL", "he-IL", "he-IL"},
5913 {"sr_Latn_SR", "sr-Latn-SR", "sr-Latn-SR"},
5914 {"en__POSIX", "en-u-va-posix", "en-u-va-posix"},
5915 {"en_POSIX", "en-u-va-posix", "en-u-va-posix"},
5916 {"en_US_POSIX_VAR", "en-US-posix-x-lvariant-var", NULL
}, /* variant POSIX_VAR is processed as regular variant */
5917 {"en_US_VAR_POSIX", "en-US-x-lvariant-var-posix", NULL
}, /* variant VAR_POSIX is processed as regular variant */
5918 {"en_US_POSIX@va=posix2", "en-US-u-va-posix2", "en-US-u-va-posix2"}, /* if keyword va=xxx already exists, variant POSIX is simply dropped */
5919 {"en_US_POSIX@ca=japanese", "en-US-u-ca-japanese-va-posix", "en-US-u-ca-japanese-va-posix"},
5920 {"und_555", "und-555", "und-555"},
5921 {"123", "und", NULL
},
5922 {"%$#&", "und", NULL
},
5923 {"_Latn", "und-Latn", "und-Latn"},
5924 {"_DE", "und-DE", "und-DE"},
5925 {"und_FR", "und-FR", "und-FR"},
5926 {"th_TH_TH", "th-TH-x-lvariant-th", NULL
},
5927 {"bogus", "bogus", "bogus"},
5928 {"foooobarrr", "und", NULL
},
5929 {"az_AZ_CYRL", "az-Cyrl-AZ", "az-Cyrl-AZ"},
5930 {"aa_BB_CYRL", "aa-BB-x-lvariant-cyrl", NULL
},
5931 {"en_US_1234", "en-US-1234", "en-US-1234"},
5932 {"en_US_VARIANTA_VARIANTB", "en-US-varianta-variantb", "en-US-varianta-variantb"},
5933 {"ja__9876_5432", "ja-9876-5432", "ja-9876-5432"},
5934 {"zh_Hant__VAR", "zh-Hant-x-lvariant-var", NULL
},
5935 {"es__BADVARIANT_GOODVAR", "es-goodvar", NULL
},
5936 {"en@calendar=gregorian", "en-u-ca-gregory", "en-u-ca-gregory"},
5937 {"de@collation=phonebook;calendar=gregorian", "de-u-ca-gregory-co-phonebk", "de-u-ca-gregory-co-phonebk"},
5938 {"th@numbers=thai;z=extz;x=priv-use;a=exta", "th-a-exta-u-nu-thai-z-extz-x-priv-use", "th-a-exta-u-nu-thai-z-extz-x-priv-use"},
5939 {"en@timezone=America/New_York;calendar=japanese", "en-u-ca-japanese-tz-usnyc", "en-u-ca-japanese-tz-usnyc"},
5940 {"en@timezone=US/Eastern", "en-u-tz-usnyc", "en-u-tz-usnyc"},
5941 {"en@x=x-y-z;a=a-b-c", "en-x-x-y-z", NULL
},
5942 {"it@collation=badcollationtype;colStrength=identical;cu=usd-eur", "it-u-cu-usd-eur-ks-identic", NULL
},
5943 {"en_US_POSIX", "en-US-u-va-posix", "en-US-u-va-posix"},
5944 {"en_US_POSIX@calendar=japanese;currency=EUR","en-US-u-ca-japanese-cu-eur-va-posix", "en-US-u-ca-japanese-cu-eur-va-posix"},
5945 {"@x=elmer", "x-elmer", "x-elmer"},
5946 {"en@x=elmer", "en-x-elmer", "en-x-elmer"},
5947 {"@x=elmer;a=exta", "und-a-exta-x-elmer", "und-a-exta-x-elmer"},
5948 {"en_US@attribute=attr1-attr2;calendar=gregorian", "en-US-u-attr1-attr2-ca-gregory", "en-US-u-attr1-attr2-ca-gregory"},
5950 {"en@a=bar;attribute=baz", "en-a-bar-u-baz", "en-a-bar-u-baz"},
5951 {"en@a=bar;attribute=baz;x=u-foo", "en-a-bar-u-baz-x-u-foo", "en-a-bar-u-baz-x-u-foo"},
5952 {"en@attribute=baz", "en-u-baz", "en-u-baz"},
5953 {"en@attribute=baz;calendar=islamic-civil", "en-u-baz-ca-islamic-civil", "en-u-baz-ca-islamic-civil"},
5954 {"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"},
5955 {"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"},
5959 static void TestToLanguageTag(void) {
5965 const char *expected
;
5967 for (i
= 0; locale_to_langtag
[i
][0] != NULL
; i
++) {
5968 inloc
= locale_to_langtag
[i
][0];
5970 /* testing non-strict mode */
5971 status
= U_ZERO_ERROR
;
5973 expected
= locale_to_langtag
[i
][1];
5975 len
= uloc_toLanguageTag(inloc
, langtag
, sizeof(langtag
), FALSE
, &status
);
5976 (void)len
; /* Suppress set but not used warning. */
5977 if (U_FAILURE(status
)) {
5978 if (expected
!= NULL
) {
5979 log_err("Error returned by uloc_toLanguageTag for locale id [%s] - error: %s\n",
5980 inloc
, u_errorName(status
));
5983 if (expected
== NULL
) {
5984 log_err("Error should be returned by uloc_toLanguageTag for locale id [%s], but [%s] is returned without errors\n",
5986 } else if (uprv_strcmp(langtag
, expected
) != 0) {
5987 log_data_err("uloc_toLanguageTag returned language tag [%s] for input locale [%s] - expected: [%s]. Are you missing data?\n",
5988 langtag
, inloc
, expected
);
5992 /* testing strict mode */
5993 status
= U_ZERO_ERROR
;
5995 expected
= locale_to_langtag
[i
][2];
5997 len
= uloc_toLanguageTag(inloc
, langtag
, sizeof(langtag
), TRUE
, &status
);
5998 if (U_FAILURE(status
)) {
5999 if (expected
!= NULL
) {
6000 log_data_err("Error returned by uloc_toLanguageTag {strict} for locale id [%s] - error: %s Are you missing data?\n",
6001 inloc
, u_errorName(status
));
6004 if (expected
== NULL
) {
6005 log_err("Error should be returned by uloc_toLanguageTag {strict} for locale id [%s], but [%s] is returned without errors\n",
6007 } else if (uprv_strcmp(langtag
, expected
) != 0) {
6008 log_err("uloc_toLanguageTag {strict} returned language tag [%s] for input locale [%s] - expected: [%s]\n",
6009 langtag
, inloc
, expected
);
6015 #define FULL_LENGTH -1
6016 static const struct {
6020 } langtag_to_locale
[] = {
6021 {"en", "en", FULL_LENGTH
},
6022 {"en-us", "en_US", FULL_LENGTH
},
6023 {"und-US", "_US", FULL_LENGTH
},
6024 {"und-latn", "_Latn", FULL_LENGTH
},
6025 {"en-US-posix", "en_US_POSIX", FULL_LENGTH
},
6026 {"de-de_euro", "de", 2},
6027 {"kok-IN", "kok_IN", FULL_LENGTH
},
6030 {"en-latn-x", "en_Latn", 7},
6031 {"art-lojban", "jbo", FULL_LENGTH
},
6032 {"zh-hakka", "hak", FULL_LENGTH
},
6033 {"zh-cmn-CH", "cmn_CH", FULL_LENGTH
},
6034 {"xxx-yy", "xxx_YY", FULL_LENGTH
},
6035 {"fr-234", "fr_234", FULL_LENGTH
},
6036 {"i-default", "en@x=i-default", FULL_LENGTH
},
6038 {"ja-jp-jp", "ja_JP", 5},
6039 {"bogus", "bogus", FULL_LENGTH
},
6040 {"boguslang", "", 0},
6041 {"EN-lATN-us", "en_Latn_US", FULL_LENGTH
},
6042 {"und-variant-1234", "__VARIANT_1234", FULL_LENGTH
},
6043 {"und-varzero-var1-vartwo", "__VARZERO", 11},
6044 {"en-u-ca-gregory", "en@calendar=gregorian", FULL_LENGTH
},
6045 {"en-U-cu-USD", "en@currency=usd", FULL_LENGTH
},
6046 {"en-US-u-va-posix", "en_US_POSIX", FULL_LENGTH
},
6047 {"en-us-u-ca-gregory-va-posix", "en_US_POSIX@calendar=gregorian", FULL_LENGTH
},
6048 {"en-us-posix-u-va-posix", "en_US_POSIX@va=posix", FULL_LENGTH
},
6049 {"en-us-u-va-posix2", "en_US@va=posix2", FULL_LENGTH
},
6050 {"en-us-vari1-u-va-posix", "en_US_VARI1@va=posix", FULL_LENGTH
},
6051 {"ar-x-1-2-3", "ar@x=1-2-3", FULL_LENGTH
},
6052 {"fr-u-nu-latn-cu-eur", "fr@currency=eur;numbers=latn", FULL_LENGTH
},
6053 {"de-k-kext-u-co-phonebk-nu-latn", "de@collation=phonebook;k=kext;numbers=latn", FULL_LENGTH
},
6054 {"ja-u-cu-jpy-ca-jp", "ja@calendar=yes;currency=jpy;jp=yes", FULL_LENGTH
},
6055 {"en-us-u-tz-usnyc", "en_US@timezone=America/New_York", FULL_LENGTH
},
6056 {"und-a-abc-def", "und@a=abc-def", FULL_LENGTH
},
6057 {"zh-u-ca-chinese-x-u-ca-chinese", "zh@calendar=chinese;x=u-ca-chinese", FULL_LENGTH
},
6058 {"x-elmer", "@x=elmer", FULL_LENGTH
},
6059 {"en-US-u-attr1-attr2-ca-gregory", "en_US@attribute=attr1-attr2;calendar=gregorian", FULL_LENGTH
},
6060 {"sr-u-kn", "sr@colnumeric=yes", FULL_LENGTH
},
6061 {"de-u-kn-co-phonebk", "de@collation=phonebook;colnumeric=yes", FULL_LENGTH
},
6062 {"en-u-attr2-attr1-kn-kb", "en@attribute=attr1-attr2;colbackwards=yes;colnumeric=yes", FULL_LENGTH
},
6063 {"ja-u-ijkl-efgh-abcd-ca-japanese-xx-yyy-zzz-kn", "ja@attribute=abcd-efgh-ijkl;calendar=japanese;colnumeric=yes;xx=yyy-zzz", FULL_LENGTH
},
6064 {"de-u-xc-xphonebk-co-phonebk-ca-buddhist-mo-very-lo-extensi-xd-that-de-should-vc-probably-xz-killthebuffer",
6065 "de@calendar=buddhist;collation=phonebook;de=should;lo=extensi;mo=very;vc=probably;xc=xphonebk;xd=that;xz=yes", 91},
6067 {"en-a-bar-u-baz", "en@a=bar;attribute=baz", FULL_LENGTH
},
6068 {"en-a-bar-u-baz-x-u-foo", "en@a=bar;attribute=baz;x=u-foo", FULL_LENGTH
},
6069 {"en-u-baz", "en@attribute=baz", FULL_LENGTH
},
6070 {"en-u-baz-ca-islamic-civil", "en@attribute=baz;calendar=islamic-civil", FULL_LENGTH
},
6071 {"en-a-bar-u-ca-islamic-civil-x-u-foo", "en@a=bar;calendar=islamic-civil;x=u-foo", FULL_LENGTH
},
6072 {"en-a-bar-u-baz-ca-islamic-civil-x-u-foo", "en@a=bar;attribute=baz;calendar=islamic-civil;x=u-foo", FULL_LENGTH
},
6073 {"und-Arab-u-em-emoji", "_Arab@em=emoji", FULL_LENGTH
},
6074 {"und-Latn-u-em-emoji", "_Latn@em=emoji", FULL_LENGTH
},
6075 {"und-Latn-DE-u-em-emoji", "_Latn_DE@em=emoji", FULL_LENGTH
},
6076 {"und-Zzzz-DE-u-em-emoji", "_Zzzz_DE@em=emoji", FULL_LENGTH
},
6077 {"und-DE-u-em-emoji", "_DE@em=emoji", FULL_LENGTH
},
6081 static void TestForLanguageTag(void) {
6086 int32_t expParsedLen
;
6088 for (i
= 0; langtag_to_locale
[i
].bcpID
!= NULL
; i
++) {
6089 status
= U_ZERO_ERROR
;
6091 expParsedLen
= langtag_to_locale
[i
].len
;
6092 if (expParsedLen
== FULL_LENGTH
) {
6093 expParsedLen
= uprv_strlen(langtag_to_locale
[i
].bcpID
);
6095 uloc_forLanguageTag(langtag_to_locale
[i
].bcpID
, locale
, sizeof(locale
), &parsedLen
, &status
);
6096 if (U_FAILURE(status
)) {
6097 log_err_status(status
, "Error returned by uloc_forLanguageTag for language tag [%s] - error: %s\n",
6098 langtag_to_locale
[i
].bcpID
, u_errorName(status
));
6100 if (uprv_strcmp(langtag_to_locale
[i
].locID
, locale
) != 0) {
6101 log_data_err("uloc_forLanguageTag returned locale [%s] for input language tag [%s] - expected: [%s]\n",
6102 locale
, langtag_to_locale
[i
].bcpID
, langtag_to_locale
[i
].locID
);
6104 if (parsedLen
!= expParsedLen
) {
6105 log_err("uloc_forLanguageTag parsed length of %d for input language tag [%s] - expected parsed length: %d\n",
6106 parsedLen
, langtag_to_locale
[i
].bcpID
, expParsedLen
);
6112 static void TestToUnicodeLocaleKey(void)
6114 /* $IN specifies the result should be the input pointer itself */
6115 static const char* DATA
[][2] = {
6117 {"CALEndar", "ca"}, /* difference casing */
6118 {"ca", "ca"}, /* bcp key itself */
6119 {"kv", "kv"}, /* no difference between legacy and bcp */
6120 {"foo", NULL
}, /* unknown, bcp ill-formed */
6121 {"ZZ", "$IN"}, /* unknown, bcp well-formed - */
6126 for (i
= 0; DATA
[i
][0] != NULL
; i
++) {
6127 const char* keyword
= DATA
[i
][0];
6128 const char* expected
= DATA
[i
][1];
6129 const char* bcpKey
= NULL
;
6131 bcpKey
= uloc_toUnicodeLocaleKey(keyword
);
6132 if (expected
== NULL
) {
6133 if (bcpKey
!= NULL
) {
6134 log_err("toUnicodeLocaleKey: keyword=%s => %s, expected=NULL\n", keyword
, bcpKey
);
6136 } else if (bcpKey
== NULL
) {
6137 log_data_err("toUnicodeLocaleKey: keyword=%s => NULL, expected=%s\n", keyword
, expected
);
6138 } else if (uprv_strcmp(expected
, "$IN") == 0) {
6139 if (bcpKey
!= keyword
) {
6140 log_err("toUnicodeLocaleKey: keyword=%s => %s, expected=%s(input pointer)\n", keyword
, bcpKey
, keyword
);
6142 } else if (uprv_strcmp(bcpKey
, expected
) != 0) {
6143 log_err("toUnicodeLocaleKey: keyword=%s => %s, expected=%s\n", keyword
, bcpKey
, expected
);
6148 static void TestToLegacyKey(void)
6150 /* $IN specifies the result should be the input pointer itself */
6151 static const char* DATA
[][2] = {
6152 {"kb", "colbackwards"},
6153 {"kB", "colbackwards"}, /* different casing */
6154 {"Collation", "collation"}, /* keyword itself with different casing */
6155 {"kv", "kv"}, /* no difference between legacy and bcp */
6156 {"foo", "$IN"}, /* unknown, bcp ill-formed */
6157 {"ZZ", "$IN"}, /* unknown, bcp well-formed */
6158 {"e=mc2", NULL
}, /* unknown, bcp/legacy ill-formed */
6163 for (i
= 0; DATA
[i
][0] != NULL
; i
++) {
6164 const char* keyword
= DATA
[i
][0];
6165 const char* expected
= DATA
[i
][1];
6166 const char* legacyKey
= NULL
;
6168 legacyKey
= uloc_toLegacyKey(keyword
);
6169 if (expected
== NULL
) {
6170 if (legacyKey
!= NULL
) {
6171 log_err("toLegacyKey: keyword=%s => %s, expected=NULL\n", keyword
, legacyKey
);
6173 } else if (legacyKey
== NULL
) {
6174 log_err("toLegacyKey: keyword=%s => NULL, expected=%s\n", keyword
, expected
);
6175 } else if (uprv_strcmp(expected
, "$IN") == 0) {
6176 if (legacyKey
!= keyword
) {
6177 log_err("toLegacyKey: keyword=%s => %s, expected=%s(input pointer)\n", keyword
, legacyKey
, keyword
);
6179 } else if (uprv_strcmp(legacyKey
, expected
) != 0) {
6180 log_data_err("toUnicodeLocaleKey: keyword=%s, %s, expected=%s\n", keyword
, legacyKey
, expected
);
6185 static void TestToUnicodeLocaleType(void)
6187 /* $IN specifies the result should be the input pointer itself */
6188 static const char* DATA
[][3] = {
6189 {"tz", "Asia/Kolkata", "inccu"},
6190 {"calendar", "gregorian", "gregory"},
6191 {"ca", "gregorian", "gregory"},
6192 {"ca", "Gregorian", "gregory"},
6193 {"ca", "buddhist", "buddhist"},
6194 {"Calendar", "Japanese", "japanese"},
6195 {"calendar", "Islamic-Civil", "islamic-civil"},
6196 {"calendar", "islamicc", "islamic-civil"}, /* bcp type alias */
6197 {"colalternate", "NON-IGNORABLE", "noignore"},
6198 {"colcaselevel", "yes", "true"},
6199 {"rg", "GBzzzz", "$IN"},
6200 {"tz", "america/new_york", "usnyc"},
6201 {"tz", "Asia/Kolkata", "inccu"},
6202 {"timezone", "navajo", "usden"},
6203 {"ca", "aaaa", "$IN"}, /* unknown type, well-formed type */
6204 {"ca", "gregory-japanese-islamic", "$IN"}, /* unknown type, well-formed type */
6205 {"zz", "gregorian", NULL
}, /* unknown key, ill-formed type */
6206 {"co", "foo-", NULL
}, /* unknown type, ill-formed type */
6207 {"variableTop", "00A0", "$IN"}, /* valid codepoints type */
6208 {"variableTop", "wxyz", "$IN"}, /* invalid codepoints type - return as is for now */
6209 {"kr", "space-punct", "space-punct"}, /* valid reordercode type */
6210 {"kr", "digit-spacepunct", NULL
}, /* invalid (bcp ill-formed) reordercode type */
6215 for (i
= 0; DATA
[i
][0] != NULL
; i
++) {
6216 const char* keyword
= DATA
[i
][0];
6217 const char* value
= DATA
[i
][1];
6218 const char* expected
= DATA
[i
][2];
6219 const char* bcpType
= NULL
;
6221 bcpType
= uloc_toUnicodeLocaleType(keyword
, value
);
6222 if (expected
== NULL
) {
6223 if (bcpType
!= NULL
) {
6224 log_err("toUnicodeLocaleType: keyword=%s, value=%s => %s, expected=NULL\n", keyword
, value
, bcpType
);
6226 } else if (bcpType
== NULL
) {
6227 log_data_err("toUnicodeLocaleType: keyword=%s, value=%s => NULL, expected=%s\n", keyword
, value
, expected
);
6228 } else if (uprv_strcmp(expected
, "$IN") == 0) {
6229 if (bcpType
!= value
) {
6230 log_err("toUnicodeLocaleType: keyword=%s, value=%s => %s, expected=%s(input pointer)\n", keyword
, value
, bcpType
, value
);
6232 } else if (uprv_strcmp(bcpType
, expected
) != 0) {
6233 log_data_err("toUnicodeLocaleType: keyword=%s, value=%s => %s, expected=%s\n", keyword
, value
, bcpType
, expected
);
6238 static void TestToLegacyType(void)
6240 /* $IN specifies the result should be the input pointer itself */
6241 static const char* DATA
[][3] = {
6242 {"calendar", "gregory", "gregorian"},
6243 {"ca", "gregory", "gregorian"},
6244 {"ca", "Gregory", "gregorian"},
6245 {"ca", "buddhist", "buddhist"},
6246 {"Calendar", "Japanese", "japanese"},
6247 {"calendar", "Islamic-Civil", "islamic-civil"},
6248 {"calendar", "islamicc", "islamic-civil"}, /* bcp type alias */
6249 {"colalternate", "noignore", "non-ignorable"},
6250 {"colcaselevel", "true", "yes"},
6251 {"rg", "gbzzzz", "gbzzzz"},
6252 {"tz", "usnyc", "America/New_York"},
6253 {"tz", "inccu", "Asia/Calcutta"},
6254 {"timezone", "usden", "America/Denver"},
6255 {"timezone", "usnavajo", "America/Denver"}, /* bcp type alias */
6256 {"colstrength", "quarternary", "quaternary"}, /* type alias */
6257 {"ca", "aaaa", "$IN"}, /* unknown type */
6258 {"calendar", "gregory-japanese-islamic", "$IN"}, /* unknown type, well-formed type */
6259 {"zz", "gregorian", "$IN"}, /* unknown key, bcp ill-formed type */
6260 {"ca", "gregorian-calendar", "$IN"}, /* known key, bcp ill-formed type */
6261 {"co", "e=mc2", NULL
}, /* known key, ill-formed bcp/legacy type */
6262 {"variableTop", "00A0", "$IN"}, /* valid codepoints type */
6263 {"variableTop", "wxyz", "$IN"}, /* invalid codepoints type - return as is for now */
6264 {"kr", "space-punct", "space-punct"}, /* valid reordercode type */
6265 {"kr", "digit-spacepunct", "digit-spacepunct"}, /* invalid reordercode type, but ok for legacy syntax */
6270 for (i
= 0; DATA
[i
][0] != NULL
; i
++) {
6271 const char* keyword
= DATA
[i
][0];
6272 const char* value
= DATA
[i
][1];
6273 const char* expected
= DATA
[i
][2];
6274 const char* legacyType
= NULL
;
6276 legacyType
= uloc_toLegacyType(keyword
, value
);
6277 if (expected
== NULL
) {
6278 if (legacyType
!= NULL
) {
6279 log_err("toLegacyType: keyword=%s, value=%s => %s, expected=NULL\n", keyword
, value
, legacyType
);
6281 } else if (legacyType
== NULL
) {
6282 log_err("toLegacyType: keyword=%s, value=%s => NULL, expected=%s\n", keyword
, value
, expected
);
6283 } else if (uprv_strcmp(expected
, "$IN") == 0) {
6284 if (legacyType
!= value
) {
6285 log_err("toLegacyType: keyword=%s, value=%s => %s, expected=%s(input pointer)\n", keyword
, value
, legacyType
, value
);
6287 } else if (uprv_strcmp(legacyType
, expected
) != 0) {
6288 log_data_err("toLegacyType: keyword=%s, value=%s => %s, expected=%s\n", keyword
, value
, legacyType
, expected
);
6290 log_verbose("toLegacyType: keyword=%s, value=%s => %s\n", keyword
, value
, legacyType
);
6297 static void test_unicode_define(const char *namech
, char ch
, const char *nameu
, UChar uch
)
6301 log_verbose("Testing whether %s[\\x%02x,'%c'] == %s[U+%04X]\n", namech
, ch
,(int)ch
, nameu
, (int) uch
);
6302 u_charsToUChars(&ch
, asUch
, 1);
6303 if(asUch
[0] != uch
) {
6304 log_err("FAIL: %s[\\x%02x,'%c'] maps to U+%04X, but %s = U+%04X\n", namech
, ch
, (int)ch
, (int)asUch
[0], nameu
, (int)uch
);
6306 log_verbose(" .. OK, == U+%04X\n", (int)asUch
[0]);
6310 #define TEST_UNICODE_DEFINE(x,y) test_unicode_define(#x, (char)(x), #y, (UChar)(y))
6312 static void TestUnicodeDefines(void) {
6313 TEST_UNICODE_DEFINE(ULOC_KEYWORD_SEPARATOR
, ULOC_KEYWORD_SEPARATOR_UNICODE
);
6314 TEST_UNICODE_DEFINE(ULOC_KEYWORD_ASSIGN
, ULOC_KEYWORD_ASSIGN_UNICODE
);
6315 TEST_UNICODE_DEFINE(ULOC_KEYWORD_ITEM_SEPARATOR
, ULOC_KEYWORD_ITEM_SEPARATOR_UNICODE
);
6318 static void TestIsRightToLeft() {
6319 // API test only. More test cases in intltest/LocaleTest.
6320 if(uloc_isRightToLeft("root") || !uloc_isRightToLeft("EN-HEBR")) {
6321 log_err("uloc_isRightToLeft() failed");
6326 const char * badLocaleID
;
6327 const char * displayLocale
;
6328 const char * expectedName
;
6329 UErrorCode expectedStatus
;
6332 static const BadLocaleItem badLocaleItems
[] = {
6333 { "-9223372036854775808", "en", "9223372036854775808", U_USING_DEFAULT_WARNING
},
6334 /* add more in the future */
6335 { NULL
, NULL
, NULL
, U_ZERO_ERROR
} /* terminator */
6338 enum { kUBufDispNameMax
= 128, kBBufDispNameMax
= 256 };
6340 static void TestBadLocaleIDs() {
6341 const BadLocaleItem
* itemPtr
;
6342 for (itemPtr
= badLocaleItems
; itemPtr
->badLocaleID
!= NULL
; itemPtr
++) {
6343 UChar ubufExpect
[kUBufDispNameMax
], ubufGet
[kUBufDispNameMax
];
6344 UErrorCode status
= U_ZERO_ERROR
;
6345 int32_t ulenExpect
= u_unescape(itemPtr
->expectedName
, ubufExpect
, kUBufDispNameMax
);
6346 int32_t ulenGet
= uloc_getDisplayName(itemPtr
->badLocaleID
, itemPtr
->displayLocale
, ubufGet
, kUBufDispNameMax
, &status
);
6347 if (status
!= itemPtr
->expectedStatus
||
6348 (U_SUCCESS(status
) && (ulenGet
!= ulenExpect
|| u_strncmp(ubufGet
, ubufExpect
, ulenExpect
) != 0))) {
6349 char bbufExpect
[kBBufDispNameMax
], bbufGet
[kBBufDispNameMax
];
6350 u_austrncpy(bbufExpect
, ubufExpect
, ulenExpect
);
6351 u_austrncpy(bbufGet
, ubufGet
, ulenGet
);
6352 log_err("FAIL: For localeID %s, displayLocale %s, calling uloc_getDisplayName:\n"
6353 " expected status %-26s, name (len %2d): %s\n"
6354 " got status %-26s, name (len %2d): %s\n",
6355 itemPtr
->badLocaleID
, itemPtr
->displayLocale
,
6356 u_errorName(itemPtr
->expectedStatus
), ulenExpect
, bbufExpect
,
6357 u_errorName(status
), ulenGet
, bbufGet
);
6362 typedef enum UldnNameType
{
6370 const char * localeToName
; // NULL to terminate a list of these
6371 UldnNameType nameType
;
6372 const char * expectResult
;
6376 const char * displayLocale
;
6377 const UDisplayContext
* displayOptions
; // set of 3 UDisplayContext items
6378 const UldnItem
* testItems
;
6382 static const UDisplayContext optStdMidLong
[3] = {UDISPCTX_STANDARD_NAMES
, UDISPCTX_CAPITALIZATION_FOR_MIDDLE_OF_SENTENCE
, UDISPCTX_LENGTH_FULL
};
6383 static const UDisplayContext optStdMidShrt
[3] = {UDISPCTX_STANDARD_NAMES
, UDISPCTX_CAPITALIZATION_FOR_MIDDLE_OF_SENTENCE
, UDISPCTX_LENGTH_SHORT
};
6384 static const UDisplayContext optDiaMidLong
[3] = {UDISPCTX_DIALECT_NAMES
, UDISPCTX_CAPITALIZATION_FOR_MIDDLE_OF_SENTENCE
, UDISPCTX_LENGTH_FULL
};
6385 static const UDisplayContext optDiaMidShrt
[3] = {UDISPCTX_DIALECT_NAMES
, UDISPCTX_CAPITALIZATION_FOR_MIDDLE_OF_SENTENCE
, UDISPCTX_LENGTH_SHORT
};
6387 static const UDisplayContext optStdBegLong
[3] = {UDISPCTX_STANDARD_NAMES
, UDISPCTX_CAPITALIZATION_FOR_BEGINNING_OF_SENTENCE
, UDISPCTX_LENGTH_FULL
};
6388 static const UDisplayContext optStdBegShrt
[3] = {UDISPCTX_STANDARD_NAMES
, UDISPCTX_CAPITALIZATION_FOR_BEGINNING_OF_SENTENCE
, UDISPCTX_LENGTH_SHORT
};
6389 static const UDisplayContext optDiaBegLong
[3] = {UDISPCTX_DIALECT_NAMES
, UDISPCTX_CAPITALIZATION_FOR_BEGINNING_OF_SENTENCE
, UDISPCTX_LENGTH_FULL
};
6390 static const UDisplayContext optDiaBegShrt
[3] = {UDISPCTX_DIALECT_NAMES
, UDISPCTX_CAPITALIZATION_FOR_BEGINNING_OF_SENTENCE
, UDISPCTX_LENGTH_SHORT
};
6392 static const UDisplayContext optStdLstLong
[3] = {UDISPCTX_STANDARD_NAMES
, UDISPCTX_CAPITALIZATION_FOR_UI_LIST_OR_MENU
, UDISPCTX_LENGTH_FULL
};
6393 static const UDisplayContext optStdLstShrt
[3] = {UDISPCTX_STANDARD_NAMES
, UDISPCTX_CAPITALIZATION_FOR_UI_LIST_OR_MENU
, UDISPCTX_LENGTH_SHORT
};
6394 static const UDisplayContext optDiaLstLong
[3] = {UDISPCTX_DIALECT_NAMES
, UDISPCTX_CAPITALIZATION_FOR_UI_LIST_OR_MENU
, UDISPCTX_LENGTH_FULL
};
6395 static const UDisplayContext optDiaLstShrt
[3] = {UDISPCTX_DIALECT_NAMES
, UDISPCTX_CAPITALIZATION_FOR_UI_LIST_OR_MENU
, UDISPCTX_LENGTH_SHORT
};
6397 static const UldnItem en_StdMidLong
[] = {
6398 { "en_US", TEST_ULDN_LOCALE
, "English (US)" },
6399 { "en_US_POSIX", TEST_ULDN_LOCALE
, "English (US, Computer)" },
6400 { "en_US@calendar=chinese", TEST_ULDN_LOCALE
, "English (US, Chinese Calendar)" },
6401 { "en_CA", TEST_ULDN_LOCALE
, "English (Canada)" },
6402 { "pt", TEST_ULDN_LOCALE
, "Portuguese" },
6403 { "pt_BR", TEST_ULDN_LOCALE
, "Portuguese (Brazil)" },
6404 { "pt_PT", TEST_ULDN_LOCALE
, "Portuguese (Portugal)" },
6405 { "zh_Hans", TEST_ULDN_LOCALE
, "Chinese (Simplified)" },
6406 { "zh_Hant_HK", TEST_ULDN_LOCALE
, "Chinese (Traditional, Hong Kong)" },
6407 { "zh_HK", TEST_ULDN_LOCALE
, "Chinese (Hong Kong)" },
6408 { "Latn", TEST_ULDN_SCRIPT
, "Latin" },
6409 { "Hans", TEST_ULDN_SCRIPT
, "Simplified Han" },
6410 { "Hant", TEST_ULDN_SCRIPT
, "Traditional Han" },
6411 { "US", TEST_ULDN_REGION
, "United States" },
6412 { "CA", TEST_ULDN_REGION
, "Canada" },
6413 { "GB", TEST_ULDN_REGION
, "United Kingdom" },
6414 { "HK", TEST_ULDN_REGION
, "Hong Kong (China)" },
6417 static const UldnItem en_StdMidShrt
[] = {
6418 { "en_US", TEST_ULDN_LOCALE
, "English (US)" },
6419 { "en_US_POSIX", TEST_ULDN_LOCALE
, "English (US, Computer)" },
6420 { "en_US@calendar=chinese", TEST_ULDN_LOCALE
, "English (US, Calendar: chinese)" },
6421 { "en_CA", TEST_ULDN_LOCALE
, "English (Canada)" },
6422 { "pt", TEST_ULDN_LOCALE
, "Portuguese" },
6423 { "pt_BR", TEST_ULDN_LOCALE
, "Portuguese (Brazil)" },
6424 { "pt_PT", TEST_ULDN_LOCALE
, "Portuguese (Portugal)" },
6425 { "zh_Hans", TEST_ULDN_LOCALE
, "Chinese (Simplified)" },
6426 { "zh_Hant_HK", TEST_ULDN_LOCALE
, "Chinese (Traditional, Hong Kong)" },
6427 { "zh_HK", TEST_ULDN_LOCALE
, "Chinese (Hong Kong)" },
6428 { "Latn", TEST_ULDN_SCRIPT
, "Latin" },
6429 { "Hans", TEST_ULDN_SCRIPT
, "Simplified Han" },
6430 { "Hant", TEST_ULDN_SCRIPT
, "Traditional Han" },
6431 { "US", TEST_ULDN_REGION
, "US" },
6432 { "CA", TEST_ULDN_REGION
, "Canada" },
6433 { "GB", TEST_ULDN_REGION
, "UK" },
6434 { "HK", TEST_ULDN_REGION
, "Hong Kong" },
6437 static const UldnItem en_DiaMidLong
[] = {
6438 { "en_US", TEST_ULDN_LOCALE
, "American English" },
6439 { "en_US_POSIX", TEST_ULDN_LOCALE
, "American English (Computer)" },
6440 { "en_US@calendar=chinese", TEST_ULDN_LOCALE
, "American English (Chinese Calendar)" },
6441 { "en_CA", TEST_ULDN_LOCALE
, "Canadian English" },
6442 { "pt", TEST_ULDN_LOCALE
, "Portuguese" },
6443 { "pt_BR", TEST_ULDN_LOCALE
, "Brazilian Portuguese" },
6444 { "pt_PT", TEST_ULDN_LOCALE
, "European Portuguese" },
6445 { "zh_Hans", TEST_ULDN_LOCALE
, "Simplified Chinese" },
6446 { "zh_Hant_HK", TEST_ULDN_LOCALE
, "Traditional Chinese (Hong Kong)" },
6447 { "zh_HK", TEST_ULDN_LOCALE
, "Chinese (Hong Kong)" },
6448 { "Latn", TEST_ULDN_SCRIPT
, "Latin" },
6449 { "Hans", TEST_ULDN_SCRIPT
, "Simplified Han" },
6450 { "Hant", TEST_ULDN_SCRIPT
, "Traditional Han" },
6451 { "US", TEST_ULDN_REGION
, "United States" },
6452 { "CA", TEST_ULDN_REGION
, "Canada" },
6453 { "GB", TEST_ULDN_REGION
, "United Kingdom" },
6454 { "HK", TEST_ULDN_REGION
, "Hong Kong (China)" },
6457 static const UldnItem en_DiaMidShrt
[] = {
6458 { "en_US", TEST_ULDN_LOCALE
, "US English" },
6459 { "en_US_POSIX", TEST_ULDN_LOCALE
, "US English (Computer)" },
6460 { "en_US@calendar=chinese", TEST_ULDN_LOCALE
, "US English (Calendar: chinese)" },
6461 { "en_CA", TEST_ULDN_LOCALE
, "Canadian English" },
6462 { "pt", TEST_ULDN_LOCALE
, "Portuguese" },
6463 { "pt_BR", TEST_ULDN_LOCALE
, "Brazilian Portuguese" },
6464 { "pt_PT", TEST_ULDN_LOCALE
, "European Portuguese" },
6465 { "zh_Hans", TEST_ULDN_LOCALE
, "Simplified Chinese" },
6466 { "zh_Hant_HK", TEST_ULDN_LOCALE
, "Traditional Chinese (Hong Kong)" },
6467 { "zh_HK", TEST_ULDN_LOCALE
, "Chinese (Hong Kong)" },
6468 { "Latn", TEST_ULDN_SCRIPT
, "Latin" },
6469 { "Hans", TEST_ULDN_SCRIPT
, "Simplified Han" },
6470 { "Hant", TEST_ULDN_SCRIPT
, "Traditional Han" },
6471 { "US", TEST_ULDN_REGION
, "US" },
6472 { "CA", TEST_ULDN_REGION
, "Canada" },
6473 { "GB", TEST_ULDN_REGION
, "UK" },
6474 { "HK", TEST_ULDN_REGION
, "Hong Kong" },
6477 static const UldnItem fr_StdMidLong
[] = {
6478 { "en_US", TEST_ULDN_LOCALE
, "anglais (\\u00C9.-U.)" },
6479 { "US", TEST_ULDN_REGION
, "\\u00C9tats-Unis" },
6480 { "HK", TEST_ULDN_REGION
, "Hong Kong (Chine)" },
6483 static const UldnItem fr_StdMidShrt
[] = {
6484 { "en_US", TEST_ULDN_LOCALE
, "anglais (\\u00C9.-U.)" },
6485 { "US", TEST_ULDN_REGION
, "\\u00C9.-U." },
6486 { "HK", TEST_ULDN_REGION
, "Hong Kong" },
6489 static const UldnItem fr_StdBegLong
[] = {
6490 { "en_US", TEST_ULDN_LOCALE
, "Anglais (\\u00C9.-U.)" },
6493 static const UldnItem fr_StdLstLong
[] = {
6494 { "en_US", TEST_ULDN_LOCALE
, "Anglais (\\u00C9.-U.)" },
6495 { "PS", TEST_ULDN_REGION
, "Territoires palestiniens" },
6498 static const UldnItem fr_DiaMidLong
[] = {
6499 { "en_US", TEST_ULDN_LOCALE
, "anglais am\\u00E9ricain" },
6502 static const UldnItem ca_StdLstLong
[] = {
6503 { "PS", TEST_ULDN_REGION
, "Territoris palestins" },
6506 static const UldnLocAndOpts uldnLocAndOpts
[] = {
6507 { "en", optStdMidLong
, en_StdMidLong
, UPRV_LENGTHOF(en_StdMidLong
) },
6508 { "en", optStdMidShrt
, en_StdMidShrt
, UPRV_LENGTHOF(en_StdMidShrt
) },
6509 { "en", optDiaMidLong
, en_DiaMidLong
, UPRV_LENGTHOF(en_DiaMidLong
) },
6510 { "en", optDiaMidShrt
, en_DiaMidShrt
, UPRV_LENGTHOF(en_DiaMidShrt
) },
6511 { "fr", optStdMidLong
, fr_StdMidLong
, UPRV_LENGTHOF(fr_StdMidLong
) },
6512 { "fr", optStdMidShrt
, fr_StdMidShrt
, UPRV_LENGTHOF(fr_StdMidShrt
) },
6513 { "fr", optStdBegLong
, fr_StdBegLong
, UPRV_LENGTHOF(fr_StdBegLong
) },
6514 { "fr", optStdLstLong
, fr_StdLstLong
, UPRV_LENGTHOF(fr_StdLstLong
) },
6515 { "fr_CA", optStdLstLong
, fr_StdLstLong
, UPRV_LENGTHOF(fr_StdLstLong
) },
6516 { "fr", optDiaMidLong
, fr_DiaMidLong
, UPRV_LENGTHOF(fr_DiaMidLong
) },
6517 { "ca", optStdLstLong
, ca_StdLstLong
, UPRV_LENGTHOF(ca_StdLstLong
) },
6518 { NULL
, NULL
, NULL
, 0 }
6521 enum { kUNameBuf
= 128, kBNameBuf
= 256 };
6523 static void TestUldnNameVariants() {
6524 const UldnLocAndOpts
* uloPtr
;
6525 for (uloPtr
= uldnLocAndOpts
; uloPtr
->displayLocale
!= NULL
; uloPtr
++) {
6526 UErrorCode status
= U_ZERO_ERROR
;
6527 ULocaleDisplayNames
* uldn
= uldn_openForContext(uloPtr
->displayLocale
, (UDisplayContext
*)uloPtr
->displayOptions
, 3, &status
);
6528 if (U_FAILURE(status
)) {
6529 log_data_err("uldn_openForContext fails, displayLocale %s, contexts %03X %03X %03X: %s - Are you missing data?\n",
6530 uloPtr
->displayLocale
, uloPtr
->displayOptions
[0], uloPtr
->displayOptions
[1], uloPtr
->displayOptions
[2],
6531 u_errorName(status
) );
6534 const UldnItem
* itemPtr
= uloPtr
->testItems
;
6535 int32_t itemCount
= uloPtr
->countItems
;
6536 for (; itemCount
-- > 0; itemPtr
++) {
6537 UChar uget
[kUNameBuf
], uexp
[kUNameBuf
];
6538 int32_t ulenget
, ulenexp
;
6539 const char* typeString
;
6541 status
= U_ZERO_ERROR
;
6542 switch (itemPtr
->nameType
) {
6543 case TEST_ULDN_LOCALE
:
6544 ulenget
= uldn_localeDisplayName(uldn
, itemPtr
->localeToName
, uget
, kUNameBuf
, &status
);
6545 typeString
= "locale";
6547 case TEST_ULDN_LANGUAGE
:
6548 ulenget
= uldn_languageDisplayName(uldn
, itemPtr
->localeToName
, uget
, kUNameBuf
, &status
);
6549 typeString
= "language";
6551 case TEST_ULDN_SCRIPT
:
6552 ulenget
= uldn_scriptDisplayName(uldn
, itemPtr
->localeToName
, uget
, kUNameBuf
, &status
);
6553 typeString
= "script";
6555 case TEST_ULDN_REGION
:
6556 ulenget
= uldn_regionDisplayName(uldn
, itemPtr
->localeToName
, uget
, kUNameBuf
, &status
);
6557 typeString
= "region";
6562 if (U_FAILURE(status
)) {
6563 log_data_err("uldn_%sDisplayName fails, displayLocale %s, contexts %03X %03X %03X, localeToName %s: %s\n",
6564 typeString
, uloPtr
->displayLocale
, uloPtr
->displayOptions
[0], uloPtr
->displayOptions
[1], uloPtr
->displayOptions
[2],
6565 itemPtr
->localeToName
, u_errorName(status
) );
6568 ulenexp
= u_unescape(itemPtr
->expectResult
, uexp
, kUNameBuf
);
6569 if (ulenget
!= ulenexp
|| u_strncmp(uget
, uexp
, ulenexp
) != 0) {
6570 char bexp
[kBNameBuf
], bget
[kBNameBuf
];
6571 u_strToUTF8(bexp
, kBNameBuf
, NULL
, uexp
, ulenexp
, &status
);
6572 u_strToUTF8(bget
, kBNameBuf
, NULL
, uget
, ulenget
, &status
);
6573 log_data_err("uldn_%sDisplayName fails, displayLocale %s, contexts %03X %03X %03X, localeToName %s:\n expect %2d: %s\n get %2d: %s\n",
6574 typeString
, uloPtr
->displayLocale
, uloPtr
->displayOptions
[0], uloPtr
->displayOptions
[1], uloPtr
->displayOptions
[2],
6575 itemPtr
->localeToName
, ulenexp
, bexp
, ulenget
, bget
);
6583 /* Apple-specific, test for Apple-specific function ualoc_getAppleParent */
6584 static const char* localesAndAppleParent
[] = {
6655 "zh_HK", "zh_Hant_HK",
6656 "zh-HK", "zh_Hant_HK",
6658 "zh-Hant-HK", "zh_Hant",
6659 "zh_Hant_HK", "zh_Hant",
6660 "zh-Hant-MO", "zh_Hant_HK",
6661 "zh-Hans-HK", "zh_Hans",
6664 "en-Latn-US", "en_Latn",
6665 "en_US_POSIX", "en_US",
6666 "en_Latn_US_POSIX", "en_Latn_US",
6667 "en-u-ca-hebrew", "root",
6668 "en@calendar=hebrew", "root",
6669 "en_@calendar=hebrew", "root",
6672 "Default@2x", "root",
6674 NULL
/* terminator */
6677 static void TestGetAppleParent() {
6678 const char **localesPtr
= localesAndAppleParent
;
6679 const char * locale
;
6680 while ((locale
= *localesPtr
++) != NULL
) {
6681 const char * expectParent
= *localesPtr
++;
6682 UErrorCode status
= U_ZERO_ERROR
;
6683 char getParent
[ULOC_FULLNAME_CAPACITY
];
6684 int32_t plen
= ualoc_getAppleParent(locale
, getParent
, ULOC_FULLNAME_CAPACITY
, &status
);
6685 if (U_FAILURE(status
)) {
6686 log_err("FAIL: ualoc_getAppleParent input \"%s\", status %s\n", locale
, u_errorName(status
));
6687 } else if (uprv_strcmp(expectParent
, getParent
) != 0) {
6688 log_err("FAIL: ualoc_getAppleParent input \"%s\", expected parent \"%s\", got parent \"%s\"\n", locale
, expectParent
, getParent
);
6693 /* Apple-specific, test for Apple-specific function ualoc_getLanguagesForRegion */
6694 enum { kUALanguageEntryMax
= 10 };
6696 static void TestGetLanguagesForRegion() {
6697 UALanguageEntry entries
[kUALanguageEntryMax
];
6700 const char * region
;
6702 status
= U_ZERO_ERROR
;
6704 entryCount
= ualoc_getLanguagesForRegion(region
, 0.001, entries
, kUALanguageEntryMax
, &status
);
6705 if (U_FAILURE(status
)) {
6706 log_err("FAIL: ualoc_getLanguagesForRegion %s, status %s\n", region
, u_errorName(status
));
6708 // Expect approximately:
6709 // zh_Hans 0.90 UALANGSTATUS_OFFICIAL
6712 // yue 0.043 Yue including Cantonese
6717 // ug_Arab 0.0055 Uighur UALANGSTATUS_REGIONAL_OFFICIAL
6718 // ...at least 4 more with fractions >= 0.001
6719 if (entryCount
< kUALanguageEntryMax
) {
6720 log_err("FAIL: ualoc_getLanguagesForRegion %s, entryCount %d is too small\n", region
, entryCount
);
6722 UALanguageEntry
* entryPtr
= entries
;
6723 if (uprv_strcmp(entryPtr
->languageCode
, "zh_Hans") != 0 || entryPtr
->userFraction
< 0.8 || entryPtr
->userFraction
> 1.0 || entryPtr
->status
!= UALANGSTATUS_OFFICIAL
) {
6724 log_err("FAIL: ualoc_getLanguagesForRegion %s, invalid entries[0] { %s, %.3f, %d }\n", region
, entryPtr
->languageCode
, entryPtr
->userFraction
, (int)entryPtr
->status
);
6726 for (entryPtr
++; entryPtr
< entries
+ kUALanguageEntryMax
&& uprv_strcmp(entryPtr
->languageCode
, "ug_Arab") != 0; entryPtr
++)
6728 if (entryPtr
< entries
+ kUALanguageEntryMax
) {
6729 // we found ug_Arab, make sure it has correct status
6730 if (entryPtr
->status
!= UALANGSTATUS_REGIONAL_OFFICIAL
) {
6731 log_err("FAIL: ualoc_getLanguagesForRegion %s, ug_Arab had incorrect status %d\n", (int)entryPtr
->status
);
6734 // did not find ug_Arab
6735 log_err("FAIL: ualoc_getLanguagesForRegion %s, entries did not include ug_Arab\n", region
);
6740 status
= U_ZERO_ERROR
;
6742 entryCount
= ualoc_getLanguagesForRegion(region
, 0.001, entries
, kUALanguageEntryMax
, &status
);
6743 if (U_FAILURE(status
)) {
6744 log_err("FAIL: ualoc_getLanguagesForRegion %s, status %s\n", region
, u_errorName(status
));
6746 // Expect approximately:
6747 // en 0.85 UALANGSTATUS_OFFICIAL
6748 // fr 0.22 UALANGSTATUS_OFFICIAL
6750 if (entryCount
< 2) {
6751 log_err("FAIL: ualoc_getLanguagesForRegion %s, entryCount %d is too small\n", region
, entryCount
);
6753 if (uprv_strcmp(entries
[0].languageCode
, "en") != 0 || entries
[0].userFraction
< 0.7 || entries
[0].userFraction
> 1.0 || entries
[0].status
!= UALANGSTATUS_OFFICIAL
) {
6754 log_err("FAIL: ualoc_getLanguagesForRegion %s, invalid entries[0] { %s, %.3f, %d }\n", region
, entries
[0].languageCode
, entries
[0].userFraction
, (int)entries
[0].status
);
6756 if (uprv_strcmp(entries
[1].languageCode
, "fr") != 0 || entries
[1].userFraction
< 0.1 || entries
[1].userFraction
> 1.0 || entries
[1].status
!= UALANGSTATUS_OFFICIAL
) {
6757 log_err("FAIL: ualoc_getLanguagesForRegion %s, invalid entries[1] { %s, %.3f, %d }\n", region
, entries
[1].languageCode
, entries
[1].userFraction
, (int)entries
[1].status
);
6762 status
= U_ZERO_ERROR
;
6764 entryCount
= ualoc_getLanguagesForRegion(region
, 0.001, NULL
, 0, &status
);
6765 if (U_FAILURE(status
)) {
6766 log_err("FAIL: ualoc_getLanguagesForRegion %s, status %s\n", region
, u_errorName(status
));
6768 if (entryCount
< 40) {
6769 log_err("FAIL: ualoc_getLanguagesForRegion %s, entryCount %d is too small\n", region
, entryCount
);
6774 /* data for TestAppleLocalizationsToUse */
6777 const char * const *locs
;
6779 } AppleLocsAndCount
;
6781 enum { kNumLocSets
= 6 };
6784 const char * language
;
6785 const char ** expLocsForSets
[kNumLocSets
];
6789 static const char * appleLocs1
[] = {
6823 static const char * appleLocs2
[] = {
6830 "en", "en_AU", "en_GB",
6854 "zh_CN", "zh_HK", "zh_TW",
6857 static const char * appleLocs3
[] = {
6864 "en", "en_AU", "en_CA", "en_GB",
6867 "fr", "fr_CA", "fr_FR",
6879 "pt", "pt_BR", "pt_PT",
6888 "zh_CN", "zh_HK", "zh_MO", "zh_TW",
6891 static const char * appleLocs4
[] = {
6892 "en", "en_AU", "en_CA", "en_GB", "en_IN", "en_US",
6893 "es", "es_419", "es_MX",
6894 "fr", "fr_CA", "fr_CH", "fr_FR",
6895 "nl", "nl_BE", "nl_NL",
6897 "ro", "ro_MD", "ro_RO",
6898 "zh_Hans", "zh_Hant", "zh_Hant_HK",
6901 static const char * appleLocs5
[] = {
6902 "en", "en_001", "en_AU", "en_GB",
6903 "es", "es_ES", "es_MX",
6904 "zh_CN", "zh_Hans", "zh_Hant", "zh_TW",
6914 static const char * appleLocs6
[] = {
6915 "en", "en_001", "en_150", "en_AU", "en_GB",
6916 "es", "es_419", "es_ES", "es_MX",
6917 "zh_CN", "zh_Hans", "zh_Hant", "zh_Hant_HK", "zh_HK", "zh_TW",
6924 static const AppleLocsAndCount locAndCountEntries
[kNumLocSets
] = {
6925 { appleLocs1
, UPRV_LENGTHOF(appleLocs1
) },
6926 { appleLocs2
, UPRV_LENGTHOF(appleLocs2
) },
6927 { appleLocs3
, UPRV_LENGTHOF(appleLocs3
) },
6928 { appleLocs4
, UPRV_LENGTHOF(appleLocs4
) },
6929 { appleLocs5
, UPRV_LENGTHOF(appleLocs5
) },
6930 { appleLocs6
, UPRV_LENGTHOF(appleLocs6
) },
6934 static const char* l1_ar
[] = { "ar", NULL
};
6935 static const char* l1_Ara
[] = { "Arabic", NULL
};
6936 static const char* l1_ca
[] = { "ca", NULL
};
6937 static const char* l1_cs
[] = { "cs", NULL
};
6938 static const char* l1_da
[] = { "da", NULL
};
6939 static const char* l1_Dan
[] = { "Danish", NULL
};
6940 static const char* l1_de
[] = { "de", NULL
};
6941 static const char* l1_Ger
[] = { "German", NULL
};
6942 static const char* l1_el
[] = { "el", NULL
};
6943 static const char* l1_en
[] = { "en", NULL
};
6944 static const char* l1_Eng
[] = { "English", NULL
};
6945 static const char* l2_en_001_
[] = { "en_001", "en", NULL
};
6946 static const char* l2_en_CA_
[] = { "en_CA", "en", NULL
};
6947 static const char* l2_en_GB_
[] = { "en_GB", "en", NULL
};
6948 static const char* l2_en_US_
[] = { "en_US", "en", NULL
};
6949 static const char* l2_en_GB_Eng
[] = { "en_GB", "English", NULL
};
6950 static const char* l3_en_GB001_
[] = { "en_GB", "en_001", "en", NULL
};
6951 static const char* l3_en_AUGB_
[] = { "en_AU", "en_GB", "en", NULL
};
6952 static const char* l3_en_INGB_
[] = { "en_IN", "en_GB", "en", NULL
};
6953 static const char* l4_en_150GB001_
[] = { "en_150", "en_GB", "en_001", "en", NULL
};
6954 static const char* l4_en_AUGB001_
[] = { "en_AU", "en_GB", "en_001", "en", NULL
};
6955 static const char* l1_es
[] = { "es", NULL
};
6956 static const char* l1_Spa
[] = { "Spanish", NULL
};
6957 static const char* l2_es_419_
[] = { "es_419", "es", NULL
};
6958 static const char* l2_es_ES_
[] = { "es_ES", "es", NULL
};
6959 static const char* l2_es_MX_
[] = { "es_MX", "es", NULL
};
6960 static const char* l2_es_MX_Spa
[] = { "es_MX", "Spanish", NULL
};
6961 static const char* l3_es_MX419_
[] = { "es_MX", "es_419", "es", NULL
};
6962 static const char* l1_fi
[] = { "fi", NULL
};
6963 static const char* l1_Fin
[] = { "Finnish", NULL
};
6964 static const char* l1_fil
[] = { "fil", NULL
};
6965 static const char* l1_tl
[] = { "tl", NULL
};
6966 static const char* l1_fr
[] = { "fr", NULL
};
6967 static const char* l1_Fre
[] = { "French", NULL
};
6968 static const char* l2_fr_CA_
[] = { "fr_CA", "fr", NULL
};
6969 static const char* l2_fr_CH_
[] = { "fr_CH", "fr", NULL
};
6970 static const char* l2_fr_FR_
[] = { "fr_FR", "fr", NULL
};
6971 static const char* l1_haw
[] = { "haw", NULL
};
6972 static const char* l1_he
[] = { "he", NULL
};
6973 static const char* l1_hr
[] = { "hr", NULL
};
6974 static const char* l1_hu
[] = { "hu", NULL
};
6975 static const char* l1_id
[] = { "id", NULL
};
6976 static const char* l1_in
[] = { "in", NULL
};
6977 static const char* l1_it
[] = { "it", NULL
};
6978 static const char* l1_Ita
[] = { "Italian", NULL
};
6979 static const char* l1_ja
[] = { "ja", NULL
};
6980 static const char* l1_Japn
[] = { "Japanese", NULL
};
6981 static const char* l1_ko
[] = { "ko", NULL
};
6982 static const char* l1_Kor
[] = { "Korean", NULL
};
6983 static const char* l1_ms
[] = { "ms", NULL
};
6984 static const char* l1_nb
[] = { "nb", NULL
};
6985 static const char* l1_no
[] = { "no", NULL
};
6986 static const char* l1_Nor
[] = { "Norwegian", NULL
};
6987 static const char* l2_no_NO_
[] = { "no_NO", "no", NULL
};
6988 static const char* l1_nl
[] = { "nl", NULL
};
6989 static const char* l1_Dut
[] = { "Dutch", NULL
};
6990 static const char* l2_nl_BE_
[] = { "nl_BE", "nl", NULL
};
6991 static const char* l1_pl
[] = { "pl", NULL
};
6992 static const char* l1_Pol
[] = { "Polish", NULL
};
6993 static const char* l1_pt
[] = { "pt", NULL
};
6994 static const char* l1_pt_PT
[] = { "pt_PT", NULL
};
6995 static const char* l1_Port
[] = { "Portuguese", NULL
};
6996 static const char* l2_pt_BR_
[] = { "pt_BR", "pt", NULL
};
6997 static const char* l2_pt_PT_
[] = { "pt_PT", "pt", NULL
};
6998 static const char* l1_ro
[] = { "ro", NULL
};
6999 static const char* l2_ro_MD_
[] = { "ro_MD", "ro", NULL
};
7000 static const char* l1_mo
[] = { "mo", NULL
};
7001 static const char* l1_ru
[] = { "ru", NULL
};
7002 static const char* l1_Rus
[] = { "Russian", NULL
};
7003 static const char* l1_sk
[] = { "sk", NULL
};
7004 static const char* l1_sr
[] = { "sr", NULL
};
7005 static const char* l1_srLatn
[] = { "sr-Latn", NULL
};
7006 static const char* l1_sv
[] = { "sv", NULL
};
7007 static const char* l1_Swe
[] = { "Swedish", NULL
};
7008 static const char* l1_th
[] = { "th", NULL
};
7009 static const char* l1_Thai
[] = { "Thai", NULL
};
7010 static const char* l1_tlh
[] = { "tlh", NULL
};
7011 static const char* l1_tr
[] = { "tr", NULL
};
7012 static const char* l1_Tur
[] = { "Turkish", NULL
};
7013 static const char* l1_uk
[] = { "uk", NULL
};
7014 static const char* l1_vi
[] = { "vi", NULL
};
7015 static const char* l1_yi
[] = { "yi", NULL
};
7016 static const char* l1_iw
[] = { "iw", NULL
};
7017 static const char* l1_zh_CN
[] = { "zh_CN", NULL
};
7018 static const char* l1_zh_TW
[] = { "zh_TW", NULL
};
7019 static const char* l1_zh_Hans
[] = { "zh_Hans", NULL
};
7020 static const char* l1_zh_Hant
[] = { "zh_Hant", NULL
};
7021 static const char* l1_zhHant
[] = { "zh-Hant", NULL
};
7022 static const char* l2_zh_HKTW
[] = { "zh_HK", "zh_TW", NULL
};
7023 static const char* l2_zh_Hant_HK_
[] = { "zh_Hant_HK", "zh_Hant", NULL
};
7024 static const char* l2_zh_CN_Hans
[] = { "zh_CN", "zh_Hans", NULL
};
7025 static const char* l2_zh_TW_Hant
[] = { "zh_TW", "zh_Hant", NULL
};
7026 static const char* l3_zh_MOHKTW
[] = { "zh_MO", "zh_HK", "zh_TW", NULL
};
7027 static const char* l3_zh_HK_HantHK_Hant
[] = { "zh_HK", "zh_Hant_HK", "zh_Hant", NULL
};
7029 static const LangAndExpLocs appleLangAndLoc
[] = {
7030 // language\ result for appleLocs1 appleLocs2 appleLocs3 appleLocs4 appleLocs5 appleLocs6
7031 { "zh", { l1_zh_CN
, l1_zh_CN
, l1_zh_CN
, l1_zh_Hans
, l1_zh_Hans
, l1_zh_Hans
} },
7032 { "zh-Hans", { l1_zh_CN
, l1_zh_CN
, l1_zh_CN
, l1_zh_Hans
, l1_zh_Hans
, l1_zh_Hans
} },
7033 { "zh-Hant", { l1_zh_TW
, l1_zh_TW
, l1_zh_TW
, l1_zh_Hant
, l1_zh_Hant
, l1_zh_Hant
} },
7034 { "zh-Hans-CN", { l1_zh_CN
, l1_zh_CN
, l1_zh_CN
, l1_zh_Hans
, l2_zh_CN_Hans
, l2_zh_CN_Hans
} },
7035 { "zh-Hans-SG", { l1_zh_CN
, l1_zh_CN
, l1_zh_CN
, l1_zh_Hans
, l1_zh_Hans
, l1_zh_Hans
} },
7036 { "zh-Hant-TW", { l1_zh_TW
, l1_zh_TW
, l1_zh_TW
, l1_zh_Hant
, l2_zh_TW_Hant
, l2_zh_TW_Hant
} },
7037 { "zh-Hant-HK", { l1_zh_TW
, l2_zh_HKTW
, l2_zh_HKTW
, l2_zh_Hant_HK_
, l1_zh_Hant
, l2_zh_Hant_HK_
} },
7038 { "zh-Hant-MO", { l1_zh_TW
, l2_zh_HKTW
, l3_zh_MOHKTW
, l2_zh_Hant_HK_
, l1_zh_Hant
, l2_zh_Hant_HK_
} },
7039 { "zh-Hans-HK", { l1_zh_CN
, l1_zh_CN
, l1_zh_CN
, l1_zh_Hans
, l1_zh_Hans
, l1_zh_Hans
} },
7040 { "zh-CN", { l1_zh_CN
, l1_zh_CN
, l1_zh_CN
, l1_zh_Hans
, l2_zh_CN_Hans
, l2_zh_CN_Hans
} },
7041 { "zh-SG", { l1_zh_CN
, l1_zh_CN
, l1_zh_CN
, l1_zh_Hans
, l1_zh_Hans
, l1_zh_Hans
} },
7042 { "zh-TW", { l1_zh_TW
, l1_zh_TW
, l1_zh_TW
, l1_zh_Hant
, l2_zh_TW_Hant
, l2_zh_TW_Hant
} },
7043 { "zh-HK", { l1_zh_TW
, l2_zh_HKTW
, l2_zh_HKTW
, l2_zh_Hant_HK_
, l1_zh_Hant
, l3_zh_HK_HantHK_Hant
} },
7044 { "zh-MO", { l1_zh_TW
, l2_zh_HKTW
, l3_zh_MOHKTW
, l2_zh_Hant_HK_
, l1_zh_Hant
, l2_zh_Hant_HK_
} },
7045 { "en", { l1_Eng
, l1_en
, l1_en
, l1_en
, l1_en
, l1_en
} },
7046 { "en-US", { l1_Eng
, l1_en
, l1_en
, l2_en_US_
, l1_en
, l1_en
} },
7047 { "en_US", { l1_Eng
, l1_en
, l1_en
, l2_en_US_
, l1_en
, l1_en
} },
7048 { "en-CN", { l1_Eng
, l1_en
, l1_en
, l1_en
, l1_en
, l1_en
} },
7049 { "en-JP", { l1_Eng
, l1_en
, l1_en
, l1_en
, l1_en
, l1_en
} },
7050 { "en-TW", { l1_Eng
, l1_en
, l1_en
, l1_en
, l1_en
, l1_en
} },
7051 { "en-TR", { l1_Eng
, l1_en
, l1_en
, l1_en
, l1_en
, l1_en
} },
7052 { "en-001", { l1_Eng
, l1_en
, l1_en
, l1_en
, l2_en_001_
, l2_en_001_
} },
7053 { "en-CA", { l1_Eng
, l1_en
, l2_en_CA_
, l2_en_CA_
, l2_en_001_
, l2_en_001_
} },
7054 { "en-IL", { l1_Eng
, l1_en
, l1_en
, l1_en
, l2_en_001_
, l2_en_001_
} },
7055 { "en-GB", { l1_Eng
, l2_en_GB_
, l2_en_GB_
, l2_en_GB_
, l3_en_GB001_
, l3_en_GB001_
} },
7056 { "en-IN", { l1_Eng
, l2_en_GB_
, l2_en_GB_
, l3_en_INGB_
, l3_en_GB001_
, l3_en_GB001_
} },
7057 { "en-BD", { l1_Eng
, l2_en_GB_
, l2_en_GB_
, l2_en_GB_
, l3_en_GB001_
, l3_en_GB001_
} },
7058 { "en-GG", { l1_Eng
, l2_en_GB_
, l2_en_GB_
, l2_en_GB_
, l3_en_GB001_
, l3_en_GB001_
} },
7059 { "en-HK", { l1_Eng
, l2_en_GB_
, l2_en_GB_
, l2_en_GB_
, l3_en_GB001_
, l3_en_GB001_
} },
7060 { "en-IE", { l1_Eng
, l2_en_GB_
, l2_en_GB_
, l2_en_GB_
, l3_en_GB001_
, l3_en_GB001_
} },
7061 { "en-JM", { l1_Eng
, l2_en_GB_
, l2_en_GB_
, l2_en_GB_
, l3_en_GB001_
, l3_en_GB001_
} },
7062 { "en-MO", { l1_Eng
, l2_en_GB_
, l2_en_GB_
, l2_en_GB_
, l3_en_GB001_
, l3_en_GB001_
} },
7063 { "en-MT", { l1_Eng
, l2_en_GB_
, l2_en_GB_
, l2_en_GB_
, l3_en_GB001_
, l3_en_GB001_
} },
7064 { "en-PK", { l1_Eng
, l2_en_GB_
, l2_en_GB_
, l2_en_GB_
, l3_en_GB001_
, l3_en_GB001_
} },
7065 { "en-SG", { l1_Eng
, l2_en_GB_
, l2_en_GB_
, l2_en_GB_
, l3_en_GB001_
, l3_en_GB001_
} },
7066 { "en-VG", { l1_Eng
, l2_en_GB_
, l2_en_GB_
, l2_en_GB_
, l3_en_GB001_
, l3_en_GB001_
} },
7067 { "en-ZA", { l1_Eng
, l2_en_GB_
, l2_en_GB_
, l2_en_GB_
, l3_en_GB001_
, l3_en_GB001_
} },
7068 { "en-AU", { l1_Eng
, l3_en_AUGB_
, l3_en_AUGB_
, l3_en_AUGB_
, l4_en_AUGB001_
, l4_en_AUGB001_
} },
7069 { "en-NZ", { l1_Eng
, l3_en_AUGB_
, l3_en_AUGB_
, l3_en_AUGB_
, l4_en_AUGB001_
, l4_en_AUGB001_
} },
7070 { "en-WS", { l1_Eng
, l3_en_AUGB_
, l3_en_AUGB_
, l3_en_AUGB_
, l4_en_AUGB001_
, l4_en_AUGB001_
} },
7071 { "en-150", { l1_Eng
, l2_en_GB_
, l2_en_GB_
, l2_en_GB_
, l3_en_GB001_
, l4_en_150GB001_
} },
7072 { "en-FR", { l1_Eng
, l2_en_GB_
, l2_en_GB_
, l2_en_GB_
, l3_en_GB001_
, l4_en_150GB001_
} },
7073 { "en-BE", { l1_Eng
, l2_en_GB_
, l2_en_GB_
, l2_en_GB_
, l3_en_GB001_
, l4_en_150GB001_
} },
7074 { "en-Latn", { l1_Eng
, l1_en
, l1_en
, l1_en
, l1_en
, l1_en
} },
7075 { "en-Latn-US", { l1_Eng
, l1_en
, l1_en
, l1_en
,/*TODO*/ l1_en
, l1_en
} },
7076 { "en-US-POSIX", { l1_Eng
, l1_en
, l1_en
, l2_en_US_
, l1_en
, l1_en
} },
7077 { "en-Latn-US-POSIX", { l1_Eng
, l1_en
, l1_en
, l1_en
, l1_en
, l1_en
} },
7078 { "en-u-ca-hebrew", { l1_Eng
, l1_en
, l1_en
, l1_en
, l1_en
, l1_en
} },
7079 { "en@calendar=hebrew", { l1_Eng
, l1_en
, l1_en
, l1_en
, l1_en
, l1_en
} },
7080 { "en-", { l1_Eng
, l1_en
, l1_en
, l1_en
, l1_en
, l1_en
} },
7081 { "en_", { l1_Eng
, l1_en
, l1_en
, l1_en
, l1_en
, l1_en
} },
7082 { "es", { l1_Spa
, l1_es
, l1_es
, l1_es
, l1_es
, l1_es
} },
7083 { "es-ES", { l1_Spa
, l1_es
, l1_es
, l1_es
, l2_es_ES_
, l2_es_ES_
} },
7084 { "es-419", { l1_Spa
, l1_es
, l2_es_419_
, l2_es_419_
, l1_es
, l2_es_419_
} },
7085 { "es-MX", { l1_Spa
, l2_es_MX_
, l2_es_419_
, l3_es_MX419_
, l2_es_MX_
, l3_es_MX419_
} },
7086 { "es-AR", { l1_Spa
, l1_es
, l2_es_419_
, l2_es_419_
, l1_es
, l2_es_419_
} },
7087 { "es-BR", { l1_Spa
, l1_es
, l2_es_419_
, l2_es_419_
, l1_es
, l2_es_419_
} },
7088 { "es-BZ", { l1_Spa
, l1_es
, l2_es_419_
, l2_es_419_
, l1_es
, l2_es_419_
} },
7089 { "es-AG", { l1_Spa
, l1_es
, l2_es_419_
, l2_es_419_
, l1_es
, l2_es_419_
} },
7090 { "es-AW", { l1_Spa
, l1_es
, l2_es_419_
, l2_es_419_
, l1_es
, l2_es_419_
} },
7091 { "es-CA", { l1_Spa
, l1_es
, l2_es_419_
, l2_es_419_
, l1_es
, l2_es_419_
} },
7092 { "es-CW", { l1_Spa
, l1_es
, l2_es_419_
, l2_es_419_
, l1_es
, l2_es_419_
} },
7093 { "es-SX", { l1_Spa
, l1_es
, l2_es_419_
, l2_es_419_
, l1_es
, l2_es_419_
} },
7094 { "es-TT", { l1_Spa
, l1_es
, l2_es_419_
, l2_es_419_
, l1_es
, l2_es_419_
} },
7095 { "es-Latn", { l1_Spa
, l1_es
, l1_es
, l1_es
, l1_es
, l1_es
} },
7096 { "es-Latn-MX", { l1_Spa
, l1_es
, l1_es
, l1_es
, l1_es
, l1_es
} },
7097 { "pt", { l1_Port
, l1_pt
, l1_pt
, l1_pt
, NULL
, NULL
} },
7098 { "pt-BR", { l1_Port
, l1_pt
, l2_pt_BR_
, l2_pt_BR_
, NULL
, NULL
} },
7099 { "pt-PT", { l1_Port
, l2_pt_PT_
, l2_pt_PT_
, l1_pt
, NULL
, NULL
} },
7100 { "pt-MO", { l1_Port
, l2_pt_PT_
, l2_pt_PT_
, l1_pt
, NULL
, NULL
} },
7101 { "pt-CH", { l1_Port
, l2_pt_PT_
, l2_pt_PT_
, l1_pt
, NULL
, NULL
} },
7102 { "pt-FR", { l1_Port
, l2_pt_PT_
, l2_pt_PT_
, l1_pt
, NULL
, NULL
} },
7103 { "pt-GQ", { l1_Port
, l2_pt_PT_
, l2_pt_PT_
, l1_pt
, NULL
, NULL
} },
7104 { "pt-LU", { l1_Port
, l2_pt_PT_
, l2_pt_PT_
, l1_pt
, NULL
, NULL
} },
7105 { "fr", { l1_Fre
, l1_fr
, l1_fr
, l1_fr
, NULL
, NULL
} },
7106 { "fr-FR", { l1_Fre
, l1_fr
, l2_fr_FR_
, l2_fr_FR_
, NULL
, NULL
} },
7107 { "fr-CA", { l1_Fre
, l2_fr_CA_
, l2_fr_CA_
, l2_fr_CA_
, NULL
, NULL
} },
7108 { "fr-CH", { l1_Fre
, l1_fr
, l1_fr
, l2_fr_CH_
, NULL
, NULL
} },
7109 { "ar", { l1_Ara
, l1_ar
, l1_ar
, NULL
, NULL
, NULL
} },
7110 { "da", { l1_Dan
, l1_da
, l1_da
, NULL
, NULL
, NULL
} },
7111 { "nl", { l1_Dut
, l1_nl
, l1_nl
, l1_nl
, NULL
, NULL
} },
7112 { "nl-BE", { l1_Dut
, l1_nl
, l1_nl
, l2_nl_BE_
, NULL
, NULL
} },
7113 { "fi", { l1_Fin
, l1_fi
, l1_fi
, NULL
, NULL
, NULL
} },
7114 { "de", { l1_Ger
, l1_de
, l1_de
, NULL
, NULL
, NULL
} },
7115 { "it", { l1_Ita
, l1_it
, l1_it
, NULL
, NULL
, NULL
} },
7116 { "ja", { l1_Japn
, l1_ja
, l1_ja
, NULL
, NULL
, NULL
} },
7117 { "ko", { l1_Kor
, l1_ko
, l1_ko
, NULL
, NULL
, NULL
} },
7118 { "nb", { l1_Nor
, l1_no
, l1_nb
, NULL
, NULL
, NULL
} },
7119 { "no", { l1_Nor
, l1_no
, l1_nb
, NULL
, NULL
, NULL
} },
7120 { "pl", { l1_Pol
, l1_pl
, l1_pl
, NULL
, NULL
, NULL
} },
7121 { "ru", { l1_Rus
, l1_ru
, l1_ru
, NULL
, NULL
, NULL
} },
7122 { "sv", { l1_Swe
, l1_sv
, l1_sv
, NULL
, NULL
, NULL
} },
7123 { "th", { l1_Thai
, l1_th
, l1_th
, NULL
, NULL
, NULL
} },
7124 { "tr", { l1_Tur
, l1_tr
, l1_tr
, NULL
, NULL
, NULL
} },
7125 { "ca", { l1_ca
, l1_ca
, l1_ca
, NULL
, NULL
, NULL
} },
7126 { "cs", { l1_cs
, l1_cs
, l1_cs
, NULL
, NULL
, NULL
} },
7127 { "el", { l1_el
, l1_el
, l1_el
, NULL
, NULL
, NULL
} },
7128 { "he", { l1_he
, l1_he
, l1_he
, NULL
, NULL
, l1_iw
} },
7129 { "iw", { l1_he
, l1_he
, l1_he
, NULL
, NULL
, l1_iw
} },
7130 { "hr", { l1_hr
, l1_hr
, l1_hr
, NULL
, NULL
, NULL
} },
7131 { "hu", { l1_hu
, l1_hu
, l1_hu
, NULL
, NULL
, NULL
} },
7132 { "id", { l1_id
, l1_id
, l1_id
, NULL
, NULL
, l1_in
} },
7133 { "in", { l1_id
, l1_id
, l1_id
, NULL
, NULL
, l1_in
} },
7134 { "ms", { l1_ms
, l1_ms
, l1_ms
, NULL
, NULL
, NULL
} },
7135 { "ro", { l1_ro
, l1_ro
, l1_ro
, l1_ro
, NULL
, l1_mo
} },
7136 { "mo", { l1_ro
, l1_ro
, l1_ro
, l2_ro_MD_
, NULL
, l1_mo
} },
7137 { "sk", { l1_sk
, l1_sk
, l1_sk
, NULL
, NULL
, NULL
} },
7138 { "uk", { l1_uk
, l1_uk
, l1_uk
, NULL
, NULL
, NULL
} },
7139 { "vi", { l1_vi
, l1_vi
, l1_vi
, NULL
, NULL
, NULL
} },
7140 { "yi", { NULL
, NULL
, NULL
, NULL
, l1_yi
, NULL
} },
7141 { "ji", { NULL
, NULL
, NULL
, NULL
, l1_yi
, NULL
} },
7142 { "fil", { NULL
, NULL
, NULL
, NULL
, l1_fil
, l1_tl
} },
7143 { "tl", { NULL
, NULL
, NULL
, NULL
, l1_fil
, l1_tl
} },
7144 { "haw", { NULL
, NULL
, NULL
, NULL
, l1_haw
, NULL
} },
7145 { "sr", { NULL
, NULL
, NULL
, NULL
, l1_sr
, NULL
} },
7146 { "sr-Cyrl", { NULL
, NULL
, NULL
, NULL
, l1_sr
, NULL
} },
7147 { "sr-Latn", { NULL
, NULL
, NULL
, NULL
, l1_srLatn
, NULL
} },
7148 { "tlh", { NULL
, NULL
, NULL
, NULL
, l1_tlh
, NULL
} },
7149 { "Default@2x", { NULL
, NULL
, NULL
, NULL
, NULL
, NULL
} },
7150 { "default", { NULL
, NULL
, NULL
, NULL
, NULL
, NULL
} },
7151 { "root", { NULL
, NULL
, NULL
, NULL
, NULL
, NULL
} },
7152 { "", { NULL
, NULL
, NULL
, NULL
, NULL
, NULL
} },
7153 { "_US", { NULL
, NULL
, NULL
, NULL
, NULL
, NULL
} },
7154 { "-US", { NULL
, NULL
, NULL
, NULL
, NULL
, NULL
} },
7155 { "-u-ca-hebrew", { NULL
, NULL
, NULL
, NULL
, NULL
, NULL
} },
7156 { "-u-ca-hebrew", { NULL
, NULL
, NULL
, NULL
, NULL
, NULL
} },
7157 { "@calendar=hebrew", { NULL
, NULL
, NULL
, NULL
, NULL
, NULL
} },
7159 enum { kNumAppleLangAndLoc
= UPRV_LENGTHOF(appleLangAndLoc
) };
7161 /* tests from <rdar://problem/21518031> */
7163 static const char * appleLocsA1
[] = { "en", "fr", "no", "zh-Hant" };
7164 static const char * appleLocsA2
[] = { "en", "fr", "nb", "zh_TW", "zh_CN", "zh-Hant" };
7165 static const char * appleLocsA3
[] = { "en", "en_IN", "en_GB", "fr", "de", "zh_TW" };
7166 static const char * appleLocsA4
[] = { "Spanish", "es_MX", "English", "en_GB" };
7167 static const char * appleLocsA5
[] = { "en", "fr", "de", "pt", "pt_PT" };
7168 static const char * appleLocsA6
[] = { "en", "no", "no_NO", "pt_PT" };
7170 static const AppleLocsAndCount locAndCountEntriesA
[kNumLocSets
] = {
7171 { appleLocsA1
, UPRV_LENGTHOF(appleLocsA1
) },
7172 { appleLocsA2
, UPRV_LENGTHOF(appleLocsA2
) },
7173 { appleLocsA3
, UPRV_LENGTHOF(appleLocsA3
) },
7174 { appleLocsA4
, UPRV_LENGTHOF(appleLocsA4
) },
7175 { appleLocsA5
, UPRV_LENGTHOF(appleLocsA5
) },
7176 { appleLocsA6
, UPRV_LENGTHOF(appleLocsA6
) },
7179 static const LangAndExpLocs appleLangAndLocA
[] = {
7180 // language\ result for appleLocsA1 appleLocsA2 appleLocsA3 appleLocsA4 appleLocsA5 appleLocsA6
7181 { "zh-Hant", { l1_zhHant
,/*0*/ l1_zhHant
,/*zh_TW*/ l1_zh_TW
, NULL
, NULL
, NULL
} },
7182 { "zh_Hant", { l1_zhHant
, l1_zhHant
,/*zh_TW*/ l1_zh_TW
, NULL
, NULL
, NULL
} },
7183 { "zh_HK", { l1_zhHant
, l1_zhHant
,/*zh_TW*/ l1_zh_TW
, NULL
, NULL
, NULL
} },
7184 { "en_IN", { l1_en
, l1_en
, l3_en_INGB_
, l2_en_GB_Eng
, l1_en
, l1_en
} },
7185 { "es_MX", { NULL
, NULL
, NULL
, l2_es_MX_Spa
, NULL
, NULL
} },
7186 { "pt_PT", { NULL
, NULL
, NULL
, NULL
, l2_pt_PT_
, l1_pt_PT
} },
7187 { "pt", { NULL
, NULL
, NULL
, NULL
, l1_pt
, l1_pt_PT
} },
7188 { "no", { l1_no
, l1_nb
, NULL
, NULL
, NULL
, l1_no
} },
7189 { "no_NO", { l1_no
, l1_nb
, NULL
, NULL
, NULL
, l2_no_NO_
} },
7190 { "nb", { l1_no
, l1_nb
, NULL
, NULL
, NULL
, l1_no
} },
7191 { "nb_NO", { l1_no
, l1_nb
, NULL
, NULL
, NULL
, l2_no_NO_
} },
7193 enum { kNumAppleLangAndLocA
= UPRV_LENGTHOF(appleLangAndLocA
) };
7195 /* tests from log attached to 21682790 */
7197 static const char * appleLocsB1
[] = {
7198 "ar", "Base", "ca", "cs",
7199 "da", "Dutch", "el", "English",
7200 "es_MX", "fi", "French", "German",
7201 "he", "hr", "hu", "id",
7202 "Italian", "Japanese", "ko", "ms",
7203 "no", "pl", "pt", "pt_PT",
7204 "ro", "ru", "sk", "Spanish",
7205 "sv", "th", "tr", "uk",
7206 "vi", "zh_CN", "zh_TW"
7209 static const char * appleLocsB2
[] = {
7211 "da", "Dutch", "el", "English",
7212 "es_MX", "fi", "French", "German",
7213 "he", "hr", "hu", "id",
7214 "Italian", "Japanese", "ko", "ms",
7215 "no", "pl", "pt", "pt_PT",
7216 "ro", "ru", "sk", "Spanish",
7217 "sv", "th", "tr", "uk",
7218 "vi", "zh_CN", "zh_TW"
7221 static const char * appleLocsB3
[] = {
7222 "ar", "ca", "cs", "da",
7223 "de", "el", "en", "es",
7224 "es_MX", "fi", "French", "he",
7225 "hr", "hu", "id", "Italian",
7226 "ja", "ko", "ms", "nl",
7227 "no", "pl", "pt", "pt_PT",
7228 "ro", "ru", "sk", "sv",
7229 "th", "tr", "uk", "vi",
7233 static const char * appleLocsB4
[] = {
7234 "ar", "ca", "cs", "da",
7235 "de", "el", "en", "es",
7236 "es_MX", "fi", "fr", "he",
7237 "hr", "hu", "id", "it",
7238 "ja", "ko", "ms", "nl",
7239 "no", "pl", "pt", "pt_PT",
7240 "ro", "ru", "sk", "sv",
7241 "th", "tr", "uk", "vi",
7245 static const char * appleLocsB5
[] = { "en" };
7247 static const char * appleLocsB6
[] = { "English" };
7249 static const AppleLocsAndCount locAndCountEntriesB
[kNumLocSets
] = {
7250 { appleLocsB1
, UPRV_LENGTHOF(appleLocsB1
) },
7251 { appleLocsB2
, UPRV_LENGTHOF(appleLocsB2
) },
7252 { appleLocsB3
, UPRV_LENGTHOF(appleLocsB3
) },
7253 { appleLocsB4
, UPRV_LENGTHOF(appleLocsB4
) },
7254 { appleLocsB5
, UPRV_LENGTHOF(appleLocsB5
) },
7255 { appleLocsB6
, UPRV_LENGTHOF(appleLocsB6
) },
7258 static const LangAndExpLocs appleLangAndLocB
[] = {
7259 // language\ result for appleLocsB1 appleLocsB2 appleLocsB3 appleLocsB4 appleLocsB5 appleLocsB6
7260 // Prefs 1, logged with sets B1-B3
7261 { "en", { l1_Eng
, l1_Eng
, l1_en
, l1_en
, l1_en
, l1_Eng
} },
7262 { "es", { l1_Spa
, l1_Spa
, l1_es
, l1_es
, NULL
, NULL
} },
7263 // Prefs 2, logged with sets B1-B6
7264 { "English", { l1_Eng
, l1_Eng
, l1_en
, l1_en
, l1_en
, l1_Eng
} },
7265 { "Spanish", { l1_Spa
, l1_Spa
, l1_es
, l1_es
, NULL
, NULL
} },
7267 enum { kNumAppleLangAndLocB
= UPRV_LENGTHOF(appleLangAndLocB
) };
7270 const AppleLocsAndCount
* locAndCountEntriesPtr
;
7271 const LangAndExpLocs
* appleLangAndLocPtr
;
7272 int32_t appleLangAndLocCount
;
7273 } AppleLocToUseTestSet
;
7275 static const AppleLocToUseTestSet altuTestSets
[] = {
7276 { locAndCountEntries
, appleLangAndLoc
, kNumAppleLangAndLoc
},
7277 { locAndCountEntriesA
, appleLangAndLocA
, kNumAppleLangAndLocA
},
7278 { locAndCountEntriesB
, appleLangAndLocB
, kNumAppleLangAndLocB
},
7282 /* tests for multiple prefs sets */
7284 static const char * appleLocsM1
[] = { "en", "en_GB", "pt", "pt_PT", "zh_CN", "zh_Hant" };
7285 static const char * prefLangsM1
[] = { "tlh", "zh_HK", "zh_SG", "zh_Hans", "pt_BR", "pt_PT", "en_IN", "en" };
7286 static const char * locsToUseM1
[] = { "zh_Hant" };
7288 // Tests from first pass at <rdar://problem/22012864>, 2015-11-18
7290 static const char * appleLocsM2
[] = { "fr-FR", "en-US", "en-GB" };
7291 static const char * prefLangsM2
[] = { "fr-CH" };
7292 static const char * locsToUseM2
[] = { "fr-FR" };
7294 static const char * appleLocsM3
[] = { "es-es", "fr-fr" };
7295 static const char * prefLangsM3
[] = { "fr-US", "fr", "en-US" };
7296 static const char * locsToUseM3
[] = { "fr-fr" };
7298 static const char * appleLocsM4
[] = { "es-es", "fr-fr", "fr" };
7299 static const char * prefLangsM4
[] = { "fr-US", "fr", "en-US" };
7300 static const char * locsToUseM4
[] = { "fr" };
7302 // Tests from second pass at <rdar://problem/22012864>, 2015-12-08
7304 static const char * appleLocsM5
[] = { "en-US", "fr-FR", "de-DE", "es-ES", "es-419", "pt-PT", "pt-BR", "zh-CN", "zh-TW", "zh-HK", "ja-JP", "ko-KR" };
7305 static const char * prefLangsM5
[] = { "fr-US", "en-US" };
7306 static const char * locsToUseM5
[] = { "fr-FR" };
7307 // Per Peter E; expected result changed from "en-US" to "de-CH" per <rdar://problem/26559053>
7308 static const char * appleLocsM6
[] = { "de-CH", "en-US" };
7309 static const char * prefLangsM6
[] = { "de-DE", "en-US" };
7310 static const char * locsToUseM6
[] = { "de-CH" };
7311 // The following is used for M7-MD
7312 static const char * appleLocsMx
[] = { "de-DE", "en-AU", "es-ES", "fr-FR", "hi-IN", "pt-BR", "zh-HK", "zh-TW" };
7314 static const char * prefLangsM7
[] = { "fr-ES", "en-AU" };
7315 static const char * locsToUseM7
[] = { "fr-FR" };
7317 static const char * prefLangsM8
[] = { "de-IT", "en-AU" };
7318 static const char * locsToUseM8
[] = { "de-DE" };
7320 static const char * prefLangsM9
[] = { "hi-US", "en-AU" };
7321 static const char * locsToUseM9
[] = { "hi-IN" };
7323 static const char * prefLangsMA
[] = { "en-IN", "zh-HK" };
7324 static const char * locsToUseMA
[] = { "en-AU" };
7326 static const char * prefLangsMB
[] = { "pt-PT", "en-AU" };
7327 static const char * locsToUseMB
[] = { "en-AU" };
7329 static const char * prefLangsMC
[] = { "pt-PT", "ar" };
7330 static const char * locsToUseMC
[] = { "pt-BR" };
7332 static const char * prefLangsMD
[] = { "zh-CN", "en-AU" };
7333 static const char * locsToUseMD
[] = { "en-AU" };
7335 static const char * appleLocsME
[] = { "de-DE", "en-AU", "es-ES", "fr-FR", "hi-IN", "pt-BR", "zh-CN", "zh-HK" };
7336 static const char * prefLangsME
[] = { "zh-TW", "en-AU" };
7337 static const char * locsToUseME
[] = { "zh-HK" };
7338 // Per Peter E in diagnosis for <rdar://problem/22012864> and <rdar://problem/23815194>
7339 static const char * appleLocsMF
[] = { "en", "en-GB", "fr", "es" };
7340 static const char * prefLangsMF
[] = { "en-IN", "en-GB", "de", "fr" };
7341 static const char * locsToUseMF
[] = { "en-GB", "en" };
7342 // Per Karan M in <rdar://problem/23982460>
7343 static const char * appleLocsMG
[] = { "zh-Hans", "zh-Hant", "zh-HK" };
7344 static const char * prefLangsMG
[] = { "zh-Hans-US", "zh-HK", "en-US" };
7345 static const char * locsToUseMG
[] = { "zh-Hans" };
7346 // Per <rdar://problem/25903891>
7347 static const char * appleLocsMH
[] = { "zh-TW", "zh-CN", "zh-HK" };
7348 static const char * prefLangsMH
[] = { "zh-Hans-HK", "zh-HK", "en" };
7349 static const char * locsToUseMH
[] = { "zh-CN" };
7350 // Per <rdar://problem/26559053>
7351 static const char * appleLocsMI
[] = { "unk", "en-US", "ar-SA" };
7352 static const char * prefLangsMI
[] = { "ar-US" };
7353 static const char * locsToUseMI
[] = { "ar-SA" };
7354 // Per <rdar://problem/30501523> - first for comparison with zh, then real test
7355 static const char * appleLocsMJ
[] = { "zh-CN", "en-US" };
7356 static const char * prefLangsMJ
[] = { "zh", "zh_AC" };
7357 static const char * locsToUseMJ
[] = { "zh-CN" };
7358 static const char * appleLocsMK
[] = { "yue-CN", "en-US" };
7359 static const char * prefLangsMK
[] = { "yue", "yue_AC" };
7360 static const char * locsToUseMK
[] = { "yue-CN" };
7361 // Per <rdar://problem/30433534>
7362 static const char * appleLocsML
[] = { "nl_NL", "es_MX", "fr_FR", "zh_TW", "it_IT", "vi_VN", "fr_CH", "es_CL",
7363 "en_ZA", "ko_KR", "ca_ES", "ro_RO", "en_PH", "en_CA", "en_SG", "en_IN",
7364 "en_NZ", "it_CH", "fr_CA", "da_DK", "de_AT", "pt_BR", "yue_CN", "zh_CN",
7365 "sv_SE", "es_ES", "ar_SA", "hu_HU", "fr_BE", "en_GB", "ja_JP", "zh_HK",
7366 "fi_FI", "tr_TR", "nb_NO", "en_ID", "en_SA", "pl_PL", "ms_MY", "cs_CZ",
7367 "el_GR", "id_ID", "hr_HR", "en_AE", "he_IL", "ru_RU", "wuu_CN", "de_DE",
7368 "de_CH", "en_AU", "nl_BE", "th_TH", "pt_PT", "sk_SK", "en_US", "en_IE",
7369 "es_CO", "uk_UA", "es_US" };
7370 static const char * prefLangsML
[] = { "en-JP" };
7371 static const char * locsToUseML
[] = { "en_US" };
7372 // Per <rdar://problem/32421203>
7373 static const char * appleLocsMM1
[] = { "pt-PT" };
7374 static const char * appleLocsMM2
[] = { "pt-BR" };
7375 static const char * appleLocsMM3
[] = { "pt-PT", "pt-BR" };
7376 static const char * appleLocsMM4
[] = { "en", "pt-PT" };
7377 static const char * appleLocsMM5
[] = { "en", "pt-BR" };
7378 static const char * appleLocsMM6
[] = { "en", "pt-PT", "pt-BR" };
7379 static const char * prefLangsMM1
[] = { "pt-PT" };
7380 static const char * prefLangsMM2
[] = { "pt-BR" };
7381 static const char * prefLangsMM3
[] = { "pt" };
7382 static const char * prefLangsMM4
[] = { "pt-PT", "en" };
7383 static const char * prefLangsMM5
[] = { "pt-BR", "en" };
7384 static const char * prefLangsMM6
[] = { "pt", "en" };
7385 static const char * locsToUseMMptPT
[] = { "pt-PT" };
7386 static const char * locsToUseMMptBR
[] = { "pt-BR" };
7387 static const char * locsToUseMMen
[] = { "en" };
7388 // Per <rdar://problem/32658828>
7389 static const char * appleLocsMN
[] = { "en-US", "en-GB" };
7390 static const char * prefLangsMN1
[] = { "en-KR" };
7391 static const char * prefLangsMN2
[] = { "en-SA" };
7392 static const char * prefLangsMN3
[] = { "en-TW" };
7393 static const char * prefLangsMN4
[] = { "en-JP" };
7394 static const char * locsToUseMN_U
[] = { "en-US" };
7395 // Per <rdar://problem/36010857>
7396 static const char * appleLocsMO
[] = { "Dutch", "French", "German", "Italian", "Japanese", "Spanish",
7397 "ar", "ca", "cs", "da", "el", "en_AU", "en_GB", "en_IN",
7398 "es_419", "fi", "fr_CA", "he", "hi", "hr", "hu", "id", "ko",
7399 "ms", "no", "pl", "pt", "pt_PT", "ro", "ru", "sk", "sv",
7400 "th", "tr", "uk", "vi", "zh_CN", "zh_HK", "zh_TW" };
7401 static const char * prefLangsMO1
[] = { "en-US" };
7402 static const char * locsToUseMO1
[] = { "en_GB" };
7406 const char ** availLocs
;
7407 int32_t availLocsCount
;
7408 const char ** prefLangs
;
7409 int32_t prefLangsCount
;
7410 const char ** locsToUse
;
7411 int32_t locsToUseCount
;
7414 static const MultiPrefTest multiTestSets
[] = {
7415 { "M1", appleLocsM1
, UPRV_LENGTHOF(appleLocsM1
), prefLangsM1
, UPRV_LENGTHOF(prefLangsM1
), locsToUseM1
, UPRV_LENGTHOF(locsToUseM1
) },
7417 { "M2", appleLocsM2
, UPRV_LENGTHOF(appleLocsM2
), prefLangsM2
, UPRV_LENGTHOF(prefLangsM2
), locsToUseM2
, UPRV_LENGTHOF(locsToUseM2
) },
7418 { "M3", appleLocsM3
, UPRV_LENGTHOF(appleLocsM3
), prefLangsM3
, UPRV_LENGTHOF(prefLangsM3
), locsToUseM3
, UPRV_LENGTHOF(locsToUseM3
) },
7419 { "M4", appleLocsM4
, UPRV_LENGTHOF(appleLocsM4
), prefLangsM4
, UPRV_LENGTHOF(prefLangsM4
), locsToUseM4
, UPRV_LENGTHOF(locsToUseM4
) },
7421 { "M5", appleLocsM5
, UPRV_LENGTHOF(appleLocsM5
), prefLangsM5
, UPRV_LENGTHOF(prefLangsM5
), locsToUseM5
, UPRV_LENGTHOF(locsToUseM5
) },
7422 { "M6", appleLocsM6
, UPRV_LENGTHOF(appleLocsM6
), prefLangsM6
, UPRV_LENGTHOF(prefLangsM6
), locsToUseM6
, UPRV_LENGTHOF(locsToUseM6
) },
7423 { "M7", appleLocsMx
, UPRV_LENGTHOF(appleLocsMx
), prefLangsM7
, UPRV_LENGTHOF(prefLangsM7
), locsToUseM7
, UPRV_LENGTHOF(locsToUseM7
) },
7424 { "M8", appleLocsMx
, UPRV_LENGTHOF(appleLocsMx
), prefLangsM8
, UPRV_LENGTHOF(prefLangsM8
), locsToUseM8
, UPRV_LENGTHOF(locsToUseM8
) },
7425 { "M9", appleLocsMx
, UPRV_LENGTHOF(appleLocsMx
), prefLangsM9
, UPRV_LENGTHOF(prefLangsM9
), locsToUseM9
, UPRV_LENGTHOF(locsToUseM9
) },
7426 { "MA", appleLocsMx
, UPRV_LENGTHOF(appleLocsMx
), prefLangsMA
, UPRV_LENGTHOF(prefLangsMA
), locsToUseMA
, UPRV_LENGTHOF(locsToUseMA
) },
7427 { "MB", appleLocsMx
, UPRV_LENGTHOF(appleLocsMx
), prefLangsMB
, UPRV_LENGTHOF(prefLangsMB
), locsToUseMB
, UPRV_LENGTHOF(locsToUseMB
) },
7428 { "MC", appleLocsMx
, UPRV_LENGTHOF(appleLocsMx
), prefLangsMC
, UPRV_LENGTHOF(prefLangsMC
), locsToUseMC
, UPRV_LENGTHOF(locsToUseMC
) },
7429 { "MD", appleLocsMx
, UPRV_LENGTHOF(appleLocsMx
), prefLangsMD
, UPRV_LENGTHOF(prefLangsMD
), locsToUseMD
, UPRV_LENGTHOF(locsToUseMD
) },
7430 { "ME", appleLocsME
, UPRV_LENGTHOF(appleLocsME
), prefLangsME
, UPRV_LENGTHOF(prefLangsME
), locsToUseME
, UPRV_LENGTHOF(locsToUseME
) },
7431 { "MF", appleLocsMF
, UPRV_LENGTHOF(appleLocsMF
), prefLangsMF
, UPRV_LENGTHOF(prefLangsMF
), locsToUseMF
, UPRV_LENGTHOF(locsToUseMF
) },
7432 { "MG", appleLocsMG
, UPRV_LENGTHOF(appleLocsMG
), prefLangsMG
, UPRV_LENGTHOF(prefLangsMG
), locsToUseMG
, UPRV_LENGTHOF(locsToUseMG
) },
7433 { "MH", appleLocsMH
, UPRV_LENGTHOF(appleLocsMH
), prefLangsMH
, UPRV_LENGTHOF(prefLangsMH
), locsToUseMH
, UPRV_LENGTHOF(locsToUseMH
) },
7434 { "MI", appleLocsMI
, UPRV_LENGTHOF(appleLocsMI
), prefLangsMI
, UPRV_LENGTHOF(prefLangsMI
), locsToUseMI
, UPRV_LENGTHOF(locsToUseMI
) },
7435 { "MJ", appleLocsMJ
, UPRV_LENGTHOF(appleLocsMJ
), prefLangsMJ
, UPRV_LENGTHOF(prefLangsMJ
), locsToUseMJ
, UPRV_LENGTHOF(locsToUseMJ
) },
7436 { "MK", appleLocsMK
, UPRV_LENGTHOF(appleLocsMK
), prefLangsMK
, UPRV_LENGTHOF(prefLangsMK
), locsToUseMK
, UPRV_LENGTHOF(locsToUseMK
) },
7437 { "ML", appleLocsML
, UPRV_LENGTHOF(appleLocsML
), prefLangsML
, UPRV_LENGTHOF(prefLangsML
), locsToUseML
, UPRV_LENGTHOF(locsToUseML
) },
7438 { "MM11", appleLocsMM1
, UPRV_LENGTHOF(appleLocsMM1
), prefLangsMM1
, UPRV_LENGTHOF(prefLangsMM1
), locsToUseMMptPT
, UPRV_LENGTHOF(locsToUseMMptPT
) },
7439 { "MM21", appleLocsMM2
, UPRV_LENGTHOF(appleLocsMM2
), prefLangsMM1
, UPRV_LENGTHOF(prefLangsMM1
), locsToUseMMptBR
, UPRV_LENGTHOF(locsToUseMMptBR
) },
7440 { "MM31", appleLocsMM3
, UPRV_LENGTHOF(appleLocsMM3
), prefLangsMM1
, UPRV_LENGTHOF(prefLangsMM1
), locsToUseMMptPT
, UPRV_LENGTHOF(locsToUseMMptPT
) },
7441 { "MM41", appleLocsMM4
, UPRV_LENGTHOF(appleLocsMM4
), prefLangsMM1
, UPRV_LENGTHOF(prefLangsMM1
), locsToUseMMptPT
, UPRV_LENGTHOF(locsToUseMMptPT
) },
7442 { "MM51", appleLocsMM5
, UPRV_LENGTHOF(appleLocsMM5
), prefLangsMM1
, UPRV_LENGTHOF(prefLangsMM1
), locsToUseMMptBR
, UPRV_LENGTHOF(locsToUseMMptBR
) },
7443 { "MM61", appleLocsMM6
, UPRV_LENGTHOF(appleLocsMM6
), prefLangsMM1
, UPRV_LENGTHOF(prefLangsMM1
), locsToUseMMptPT
, UPRV_LENGTHOF(locsToUseMMptPT
) },
7444 { "MM12", appleLocsMM1
, UPRV_LENGTHOF(appleLocsMM1
), prefLangsMM2
, UPRV_LENGTHOF(prefLangsMM2
), locsToUseMMptPT
, UPRV_LENGTHOF(locsToUseMMptPT
) },
7445 { "MM22", appleLocsMM2
, UPRV_LENGTHOF(appleLocsMM2
), prefLangsMM2
, UPRV_LENGTHOF(prefLangsMM2
), locsToUseMMptBR
, UPRV_LENGTHOF(locsToUseMMptBR
) },
7446 { "MM32", appleLocsMM3
, UPRV_LENGTHOF(appleLocsMM3
), prefLangsMM2
, UPRV_LENGTHOF(prefLangsMM2
), locsToUseMMptBR
, UPRV_LENGTHOF(locsToUseMMptBR
) },
7447 { "MM42", appleLocsMM4
, UPRV_LENGTHOF(appleLocsMM4
), prefLangsMM2
, UPRV_LENGTHOF(prefLangsMM2
), locsToUseMMptPT
, UPRV_LENGTHOF(locsToUseMMptPT
) },
7448 { "MM52", appleLocsMM5
, UPRV_LENGTHOF(appleLocsMM5
), prefLangsMM2
, UPRV_LENGTHOF(prefLangsMM2
), locsToUseMMptBR
, UPRV_LENGTHOF(locsToUseMMptBR
) },
7449 { "MM62", appleLocsMM6
, UPRV_LENGTHOF(appleLocsMM6
), prefLangsMM2
, UPRV_LENGTHOF(prefLangsMM2
), locsToUseMMptBR
, UPRV_LENGTHOF(locsToUseMMptBR
) },
7450 { "MM13", appleLocsMM1
, UPRV_LENGTHOF(appleLocsMM1
), prefLangsMM3
, UPRV_LENGTHOF(prefLangsMM3
), locsToUseMMptPT
, UPRV_LENGTHOF(locsToUseMMptPT
) },
7451 { "MM23", appleLocsMM2
, UPRV_LENGTHOF(appleLocsMM2
), prefLangsMM3
, UPRV_LENGTHOF(prefLangsMM3
), locsToUseMMptBR
, UPRV_LENGTHOF(locsToUseMMptBR
) },
7452 { "MM33", appleLocsMM3
, UPRV_LENGTHOF(appleLocsMM3
), prefLangsMM3
, UPRV_LENGTHOF(prefLangsMM3
), locsToUseMMptBR
, UPRV_LENGTHOF(locsToUseMMptBR
) },
7453 { "MM43", appleLocsMM4
, UPRV_LENGTHOF(appleLocsMM4
), prefLangsMM3
, UPRV_LENGTHOF(prefLangsMM3
), locsToUseMMptPT
, UPRV_LENGTHOF(locsToUseMMptPT
) },
7454 { "MM53", appleLocsMM5
, UPRV_LENGTHOF(appleLocsMM5
), prefLangsMM3
, UPRV_LENGTHOF(prefLangsMM3
), locsToUseMMptBR
, UPRV_LENGTHOF(locsToUseMMptBR
) },
7455 { "MM63", appleLocsMM6
, UPRV_LENGTHOF(appleLocsMM6
), prefLangsMM3
, UPRV_LENGTHOF(prefLangsMM3
), locsToUseMMptBR
, UPRV_LENGTHOF(locsToUseMMptBR
) },
7456 { "MM14", appleLocsMM1
, UPRV_LENGTHOF(appleLocsMM1
), prefLangsMM4
, UPRV_LENGTHOF(prefLangsMM4
), locsToUseMMptPT
, UPRV_LENGTHOF(locsToUseMMptPT
) },
7457 { "MM24", appleLocsMM2
, UPRV_LENGTHOF(appleLocsMM2
), prefLangsMM4
, UPRV_LENGTHOF(prefLangsMM4
), locsToUseMMptBR
, UPRV_LENGTHOF(locsToUseMMptBR
) },
7458 { "MM34", appleLocsMM3
, UPRV_LENGTHOF(appleLocsMM3
), prefLangsMM4
, UPRV_LENGTHOF(prefLangsMM4
), locsToUseMMptPT
, UPRV_LENGTHOF(locsToUseMMptPT
) },
7459 { "MM44", appleLocsMM4
, UPRV_LENGTHOF(appleLocsMM4
), prefLangsMM4
, UPRV_LENGTHOF(prefLangsMM4
), locsToUseMMptPT
, UPRV_LENGTHOF(locsToUseMMptPT
) },
7460 { "MM54", appleLocsMM5
, UPRV_LENGTHOF(appleLocsMM5
), prefLangsMM4
, UPRV_LENGTHOF(prefLangsMM4
), locsToUseMMen
, UPRV_LENGTHOF(locsToUseMMen
) }, // want en, see <rdar://problem/22012864>
7461 { "MM64", appleLocsMM6
, UPRV_LENGTHOF(appleLocsMM6
), prefLangsMM4
, UPRV_LENGTHOF(prefLangsMM4
), locsToUseMMptPT
, UPRV_LENGTHOF(locsToUseMMptPT
) },
7462 { "MM15", appleLocsMM1
, UPRV_LENGTHOF(appleLocsMM1
), prefLangsMM5
, UPRV_LENGTHOF(prefLangsMM5
), locsToUseMMptPT
, UPRV_LENGTHOF(locsToUseMMptPT
) },
7463 { "MM25", appleLocsMM2
, UPRV_LENGTHOF(appleLocsMM2
), prefLangsMM5
, UPRV_LENGTHOF(prefLangsMM5
), locsToUseMMptBR
, UPRV_LENGTHOF(locsToUseMMptBR
) },
7464 { "MM35", appleLocsMM3
, UPRV_LENGTHOF(appleLocsMM3
), prefLangsMM5
, UPRV_LENGTHOF(prefLangsMM5
), locsToUseMMptBR
, UPRV_LENGTHOF(locsToUseMMptBR
) },
7465 { "MM45", appleLocsMM4
, UPRV_LENGTHOF(appleLocsMM4
), prefLangsMM5
, UPRV_LENGTHOF(prefLangsMM5
), locsToUseMMptPT
, UPRV_LENGTHOF(locsToUseMMptPT
) },
7466 { "MM55", appleLocsMM5
, UPRV_LENGTHOF(appleLocsMM5
), prefLangsMM5
, UPRV_LENGTHOF(prefLangsMM5
), locsToUseMMptBR
, UPRV_LENGTHOF(locsToUseMMptBR
) },
7467 { "MM65", appleLocsMM6
, UPRV_LENGTHOF(appleLocsMM6
), prefLangsMM5
, UPRV_LENGTHOF(prefLangsMM5
), locsToUseMMptBR
, UPRV_LENGTHOF(locsToUseMMptBR
) },
7468 { "MM16", appleLocsMM1
, UPRV_LENGTHOF(appleLocsMM1
), prefLangsMM6
, UPRV_LENGTHOF(prefLangsMM6
), locsToUseMMptPT
, UPRV_LENGTHOF(locsToUseMMptPT
) },
7469 { "MM26", appleLocsMM2
, UPRV_LENGTHOF(appleLocsMM2
), prefLangsMM6
, UPRV_LENGTHOF(prefLangsMM6
), locsToUseMMptBR
, UPRV_LENGTHOF(locsToUseMMptBR
) },
7470 { "MM36", appleLocsMM3
, UPRV_LENGTHOF(appleLocsMM3
), prefLangsMM6
, UPRV_LENGTHOF(prefLangsMM6
), locsToUseMMptBR
, UPRV_LENGTHOF(locsToUseMMptBR
) },
7471 { "MM46", appleLocsMM4
, UPRV_LENGTHOF(appleLocsMM4
), prefLangsMM6
, UPRV_LENGTHOF(prefLangsMM6
), locsToUseMMptPT
, UPRV_LENGTHOF(locsToUseMMptPT
) },
7472 { "MM56", appleLocsMM5
, UPRV_LENGTHOF(appleLocsMM5
), prefLangsMM6
, UPRV_LENGTHOF(prefLangsMM6
), locsToUseMMptBR
, UPRV_LENGTHOF(locsToUseMMptBR
) },
7473 { "MM66", appleLocsMM6
, UPRV_LENGTHOF(appleLocsMM6
), prefLangsMM6
, UPRV_LENGTHOF(prefLangsMM6
), locsToUseMMptBR
, UPRV_LENGTHOF(locsToUseMMptBR
) },
7474 { "MN1", appleLocsMN
, UPRV_LENGTHOF(appleLocsMN
), prefLangsMN1
, UPRV_LENGTHOF(prefLangsMN1
), locsToUseMN_U
, UPRV_LENGTHOF(locsToUseMN_U
) },
7475 { "MN2", appleLocsMN
, UPRV_LENGTHOF(appleLocsMN
), prefLangsMN2
, UPRV_LENGTHOF(prefLangsMN2
), locsToUseMN_U
, UPRV_LENGTHOF(locsToUseMN_U
) },
7476 { "MN3", appleLocsMN
, UPRV_LENGTHOF(appleLocsMN
), prefLangsMN3
, UPRV_LENGTHOF(prefLangsMN3
), locsToUseMN_U
, UPRV_LENGTHOF(locsToUseMN_U
) },
7477 { "MN4", appleLocsMN
, UPRV_LENGTHOF(appleLocsMN
), prefLangsMN4
, UPRV_LENGTHOF(prefLangsMN4
), locsToUseMN_U
, UPRV_LENGTHOF(locsToUseMN_U
) },
7478 { "MO", appleLocsMO
, UPRV_LENGTHOF(appleLocsMO
), prefLangsMO1
, UPRV_LENGTHOF(prefLangsMO1
), locsToUseMO1
, UPRV_LENGTHOF(locsToUseMO1
) },
7480 { NULL
, NULL
, 0, NULL
, 0, NULL
, 0 }
7486 enum { kMaxLocalizationsToUse
= 8, kPrintArrayBufSize
= 128 };
7488 // array, array of pointers to strings to print
7489 // count, count of array elements, may be -1 if array is terminated by a NULL entry
7490 // buf, buffer into which to put concatenated strings
7491 // bufSize, length of buf
7492 static void printStringArray(const char **array
, int32_t count
, char *buf
, int32_t bufSize
) {
7493 char * bufPtr
= buf
;
7494 const char * curEntry
;
7495 int32_t idx
, countMax
= bufSize
/16;
7496 if (count
< 0 || count
> countMax
) {
7499 for (idx
= 0; idx
< count
&& (curEntry
= *array
++) != NULL
; idx
++) {
7500 int32_t len
= sprintf(bufPtr
, "%s\"%.12s\"", (idx
> 0)? ", ": "", curEntry
);
7506 *bufPtr
= 0; /* ensure termination */
7509 static UBool
equalStringArrays(const char **array1
, int32_t count1
, const char **array2
, int32_t count2
) {
7510 const char ** array1Ptr
= array1
;
7511 const char ** array2Ptr
= array2
;
7515 while (*array1Ptr
++ != NULL
) {
7521 while (*array2Ptr
++ != NULL
) {
7525 if (count1
!= count2
) {
7528 for (idx
= 0; idx
< count1
; idx
++) {
7529 if (uprv_strcmp(array1
[idx
], array2
[idx
]) != 0) {
7536 static void TestAppleLocalizationsToUse() {
7537 const AppleLocToUseTestSet
* testSetPtr
;
7538 const MultiPrefTest
* multiSetPtr
;
7539 const char * locsToUse
[kMaxLocalizationsToUse
];
7540 int32_t numLocsToUse
;
7542 char printExpected
[kPrintArrayBufSize
];
7543 char printActual
[kPrintArrayBufSize
];
7545 for (testSetPtr
= altuTestSets
; testSetPtr
->locAndCountEntriesPtr
!= NULL
; testSetPtr
++) {
7546 int32_t iLocSet
, iLang
;
7548 for (iLocSet
= 0; iLocSet
< kNumLocSets
; iLocSet
++) {
7549 for (iLang
= 0; iLang
< testSetPtr
->appleLangAndLocCount
; iLang
++) {
7550 const char * language
= testSetPtr
->appleLangAndLocPtr
[iLang
].language
;
7551 const char ** expLocsForSet
= testSetPtr
->appleLangAndLocPtr
[iLang
].expLocsForSets
[iLocSet
];
7552 status
= U_ZERO_ERROR
;
7554 numLocsToUse
= ualoc_localizationsToUse(&language
, 1,
7555 testSetPtr
->locAndCountEntriesPtr
[iLocSet
].locs
, testSetPtr
->locAndCountEntriesPtr
[iLocSet
].locCount
,
7556 locsToUse
, kMaxLocalizationsToUse
, &status
);
7557 if (U_FAILURE(status
)) {
7558 log_err("FAIL: ualoc_localizationsToUse testSet %d, locSet %d, lang %s, status %s\n",
7559 testSetPtr
-altuTestSets
, iLocSet
+1, language
, u_errorName(status
));
7560 } else if (numLocsToUse
== 0 && expLocsForSet
!= NULL
) {
7561 printStringArray(expLocsForSet
, -1, printExpected
, kPrintArrayBufSize
);
7562 log_err("FAIL: ualoc_localizationsToUse testSet %d, locSet %d, lang %s, expect {%s}, get no results\n",
7563 testSetPtr
-altuTestSets
, iLocSet
+1, language
, printExpected
);
7564 } else if (numLocsToUse
> 0 && expLocsForSet
== NULL
) {
7565 printStringArray(locsToUse
, numLocsToUse
, printActual
, kPrintArrayBufSize
);
7566 log_err("FAIL: ualoc_localizationsToUse testSet %d, locSet %d, lang %s, expect no results, get {%s}\n",
7567 testSetPtr
-altuTestSets
, iLocSet
+1, language
, printActual
);
7568 } else if (numLocsToUse
> 0 && !equalStringArrays(expLocsForSet
, -1, locsToUse
, numLocsToUse
)) {
7569 printStringArray(expLocsForSet
, -1, printExpected
, kPrintArrayBufSize
);
7570 printStringArray(locsToUse
, numLocsToUse
, printActual
, kPrintArrayBufSize
);
7571 log_err("FAIL: ualoc_localizationsToUse testSet %d, locSet %d, lang %s:\n expect {%s}\n get {%s}\n",
7572 testSetPtr
-altuTestSets
, iLocSet
+1, language
, printExpected
, printActual
);
7578 for (multiSetPtr
= multiTestSets
; multiSetPtr
->name
!= NULL
; multiSetPtr
++) {
7579 status
= U_ZERO_ERROR
;
7580 numLocsToUse
= ualoc_localizationsToUse(multiSetPtr
->prefLangs
, multiSetPtr
->prefLangsCount
, multiSetPtr
->availLocs
, multiSetPtr
->availLocsCount
, locsToUse
, kMaxLocalizationsToUse
, &status
);
7581 if (U_FAILURE(status
)) {
7582 log_err("FAIL: ualoc_localizationsToUse appleLocs%s, langs prefLangs%s, status %s\n", multiSetPtr
->name
, multiSetPtr
->name
, u_errorName(status
));
7583 } else if (!equalStringArrays(multiSetPtr
->locsToUse
, multiSetPtr
->locsToUseCount
, locsToUse
, numLocsToUse
)) {
7584 printStringArray(multiSetPtr
->locsToUse
, multiSetPtr
->locsToUseCount
, printExpected
, kPrintArrayBufSize
);
7585 printStringArray(locsToUse
, numLocsToUse
, printActual
, kPrintArrayBufSize
);
7586 log_err("FAIL: ualoc_localizationsToUse appleLocs%s, langs prefLangs%s:\n expect {%s}\n get {%s}\n",
7587 multiSetPtr
->name
, multiSetPtr
->name
, printExpected
, printActual
);