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"
3509 const char* const basic_minimize_data
[][2] = {
3514 "en_Latn_US_POSIX_1901",
3517 "EN_Latn_US_POSIX_1901",
3520 "en_Zzzz_US_POSIX_1901",
3523 "de_Latn_DE_POSIX_1901",
3529 "en_Latn_US@calendar=gregorian",
3530 "en@calendar=gregorian"
3534 const char* const full_data
[][3] = {
3538 /* "REMOVE-LIKELY" */
5021 "zh_Hani_CN", /* changed due to cldrbug 6204, may be an error */
5022 "zh_Hani", /* changed due to cldrbug 6204, may be an error */
5608 "de@collation=phonebook",
5609 "de_Latn_DE@collation=phonebook",
5610 "de@collation=phonebook"
5614 typedef struct errorDataTag
{
5616 const char* expected
;
5621 const errorData maximizeErrors
[] = {
5625 U_ILLEGAL_ARGUMENT_ERROR
,
5629 "en_THUJIOGIURJHGJFURYHFJGURYYYHHGJURHG",
5631 U_ILLEGAL_ARGUMENT_ERROR
,
5635 "en_THUJIOGIURJHGJFURYHFJGURYYYHHGJURHG",
5637 U_ILLEGAL_ARGUMENT_ERROR
,
5641 "en_Latn_US_POSIX@currency=EURO",
5642 "en_Latn_US_POSIX@currency=EURO",
5643 U_BUFFER_OVERFLOW_ERROR
,
5647 "en_Latn_US_POSIX@currency=EURO",
5648 "en_Latn_US_POSIX@currency=EURO",
5649 U_STRING_NOT_TERMINATED_WARNING
,
5654 const errorData minimizeErrors
[] = {
5658 U_ILLEGAL_ARGUMENT_ERROR
,
5662 "en_THUJIOGIURJHGJFURYHFJGURYYYHHGJURHG",
5664 U_ILLEGAL_ARGUMENT_ERROR
,
5668 "en_Latn_US_POSIX@currency=EURO",
5669 "en__POSIX@currency=EURO",
5670 U_BUFFER_OVERFLOW_ERROR
,
5674 "en_Latn_US_POSIX@currency=EURO",
5675 "en__POSIX@currency=EURO",
5676 U_STRING_NOT_TERMINATED_WARNING
,
5681 static int32_t getExpectedReturnValue(const errorData
* data
)
5683 if (data
->uerror
== U_BUFFER_OVERFLOW_ERROR
||
5684 data
->uerror
== U_STRING_NOT_TERMINATED_WARNING
)
5686 return strlen(data
->expected
);
5694 static int32_t getBufferSize(const errorData
* data
, int32_t actualSize
)
5696 if (data
->expected
== NULL
)
5700 else if (data
->bufferSize
< 0)
5702 return strlen(data
->expected
) + 1;
5706 return data
->bufferSize
;
5710 static void TestLikelySubtags()
5712 char buffer
[ULOC_FULLNAME_CAPACITY
+ ULOC_KEYWORD_AND_VALUES_CAPACITY
+ 1];
5715 for (; i
< UPRV_LENGTHOF(basic_maximize_data
); ++i
)
5717 UErrorCode status
= U_ZERO_ERROR
;
5718 const char* const minimal
= basic_maximize_data
[i
][0];
5719 const char* const maximal
= basic_maximize_data
[i
][1];
5721 /* const int32_t length = */
5722 uloc_addLikelySubtags(
5727 if (U_FAILURE(status
)) {
5728 log_err_status(status
, " unexpected failure of uloc_addLikelySubtags(), minimal \"%s\" status %s\n", minimal
, u_errorName(status
));
5729 status
= U_ZERO_ERROR
;
5731 else if (uprv_strlen(maximal
) == 0) {
5732 if (uprv_stricmp(minimal
, buffer
) != 0) {
5733 log_err(" unexpected maximal value \"%s\" in uloc_addLikelySubtags(), minimal \"%s\" = \"%s\"\n", maximal
, minimal
, buffer
);
5736 else if (uprv_stricmp(maximal
, buffer
) != 0) {
5737 log_err(" maximal doesn't match expected %s in uloc_addLikelySubtags(), minimal \"%s\" = %s\n", maximal
, minimal
, buffer
);
5741 for (i
= 0; i
< UPRV_LENGTHOF(basic_minimize_data
); ++i
) {
5743 UErrorCode status
= U_ZERO_ERROR
;
5744 const char* const maximal
= basic_minimize_data
[i
][0];
5745 const char* const minimal
= basic_minimize_data
[i
][1];
5747 /* const int32_t length = */
5748 uloc_minimizeSubtags(
5754 if (U_FAILURE(status
)) {
5755 log_err_status(status
, " unexpected failure of uloc_MinimizeSubtags(), maximal \"%s\" status %s\n", maximal
, u_errorName(status
));
5756 status
= U_ZERO_ERROR
;
5758 else if (uprv_strlen(minimal
) == 0) {
5759 if (uprv_stricmp(maximal
, buffer
) != 0) {
5760 log_err(" unexpected minimal value \"%s\" in uloc_minimizeSubtags(), maximal \"%s\" = \"%s\"\n", minimal
, maximal
, buffer
);
5763 else if (uprv_stricmp(minimal
, buffer
) != 0) {
5764 log_err(" minimal doesn't match expected %s in uloc_MinimizeSubtags(), maximal \"%s\" = %s\n", minimal
, maximal
, buffer
);
5768 for (i
= 0; i
< UPRV_LENGTHOF(full_data
); ++i
) {
5770 UErrorCode status
= U_ZERO_ERROR
;
5771 const char* const minimal
= full_data
[i
][0];
5772 const char* const maximal
= full_data
[i
][1];
5774 /* const int32_t length = */
5775 uloc_addLikelySubtags(
5780 if (U_FAILURE(status
)) {
5781 log_err_status(status
, " unexpected failure of uloc_addLikelySubtags(), minimal \"%s\" status \"%s\"\n", minimal
, u_errorName(status
));
5782 status
= U_ZERO_ERROR
;
5784 else if (uprv_strlen(maximal
) == 0) {
5785 if (uprv_stricmp(minimal
, buffer
) != 0) {
5786 log_err(" unexpected maximal value \"%s\" in uloc_addLikelySubtags(), minimal \"%s\" = \"%s\"\n", maximal
, minimal
, buffer
);
5789 else if (uprv_stricmp(maximal
, buffer
) != 0) {
5790 log_err(" maximal doesn't match expected \"%s\" in uloc_addLikelySubtags(), minimal \"%s\" = \"%s\"\n", maximal
, minimal
, buffer
);
5794 for (i
= 0; i
< UPRV_LENGTHOF(full_data
); ++i
) {
5796 UErrorCode status
= U_ZERO_ERROR
;
5797 const char* const maximal
= full_data
[i
][1];
5798 const char* const minimal
= full_data
[i
][2];
5800 if (strlen(maximal
) > 0) {
5802 /* const int32_t length = */
5803 uloc_minimizeSubtags(
5809 if (U_FAILURE(status
)) {
5810 log_err_status(status
, " unexpected failure of uloc_minimizeSubtags(), maximal \"%s\" status %s\n", maximal
, u_errorName(status
));
5811 status
= U_ZERO_ERROR
;
5813 else if (uprv_strlen(minimal
) == 0) {
5814 if (uprv_stricmp(maximal
, buffer
) != 0) {
5815 log_err(" unexpected minimal value \"%s\" in uloc_minimizeSubtags(), maximal \"%s\" = \"%s\"\n", minimal
, maximal
, buffer
);
5818 else if (uprv_stricmp(minimal
, buffer
) != 0) {
5819 log_err(" minimal doesn't match expected %s in uloc_MinimizeSubtags(), maximal \"%s\" = %s\n", minimal
, maximal
, buffer
);
5824 for (i
= 0; i
< UPRV_LENGTHOF(maximizeErrors
); ++i
) {
5826 UErrorCode status
= U_ZERO_ERROR
;
5827 const char* const minimal
= maximizeErrors
[i
].tag
;
5828 const char* const maximal
= maximizeErrors
[i
].expected
;
5829 const UErrorCode expectedStatus
= maximizeErrors
[i
].uerror
;
5830 const int32_t expectedLength
= getExpectedReturnValue(&maximizeErrors
[i
]);
5831 const int32_t bufferSize
= getBufferSize(&maximizeErrors
[i
], sizeof(buffer
));
5833 const int32_t length
=
5834 uloc_addLikelySubtags(
5840 if (status
== U_ZERO_ERROR
) {
5841 log_err(" unexpected U_ZERO_ERROR for uloc_addLikelySubtags(), minimal \"%s\" expected status %s\n", minimal
, u_errorName(expectedStatus
));
5842 status
= U_ZERO_ERROR
;
5844 else if (status
!= expectedStatus
) {
5845 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
));
5847 else if (length
!= expectedLength
) {
5848 log_err(" unexpected length for uloc_addLikelySubtags(), minimal \"%s\" expected length %d, but got %d\n", minimal
, expectedLength
, length
);
5850 else if (status
== U_BUFFER_OVERFLOW_ERROR
|| status
== U_STRING_NOT_TERMINATED_WARNING
) {
5851 if (uprv_strnicmp(maximal
, buffer
, bufferSize
) != 0) {
5852 log_err(" maximal doesn't match expected %s in uloc_addLikelySubtags(), minimal \"%s\" = %*s\n",
5853 maximal
, minimal
, (int)sizeof(buffer
), buffer
);
5858 for (i
= 0; i
< UPRV_LENGTHOF(minimizeErrors
); ++i
) {
5860 UErrorCode status
= U_ZERO_ERROR
;
5861 const char* const maximal
= minimizeErrors
[i
].tag
;
5862 const char* const minimal
= minimizeErrors
[i
].expected
;
5863 const UErrorCode expectedStatus
= minimizeErrors
[i
].uerror
;
5864 const int32_t expectedLength
= getExpectedReturnValue(&minimizeErrors
[i
]);
5865 const int32_t bufferSize
= getBufferSize(&minimizeErrors
[i
], sizeof(buffer
));
5867 const int32_t length
=
5868 uloc_minimizeSubtags(
5874 if (status
== U_ZERO_ERROR
) {
5875 log_err(" unexpected U_ZERO_ERROR for uloc_minimizeSubtags(), maximal \"%s\" expected status %s\n", maximal
, u_errorName(expectedStatus
));
5876 status
= U_ZERO_ERROR
;
5878 else if (status
!= expectedStatus
) {
5879 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
));
5881 else if (length
!= expectedLength
) {
5882 log_err(" unexpected length for uloc_minimizeSubtags(), maximal \"%s\" expected length %d, but got %d\n", maximal
, expectedLength
, length
);
5884 else if (status
== U_BUFFER_OVERFLOW_ERROR
|| status
== U_STRING_NOT_TERMINATED_WARNING
) {
5885 if (uprv_strnicmp(minimal
, buffer
, bufferSize
) != 0) {
5886 log_err(" minimal doesn't match expected \"%s\" in uloc_minimizeSubtags(), minimal \"%s\" = \"%*s\"\n",
5887 minimal
, maximal
, (int)sizeof(buffer
), buffer
);
5893 const char* const locale_to_langtag
[][3] = {
5896 {"en_US", "en-US", "en-US"},
5897 {"iw_IL", "he-IL", "he-IL"},
5898 {"sr_Latn_SR", "sr-Latn-SR", "sr-Latn-SR"},
5899 {"en__POSIX", "en-u-va-posix", "en-u-va-posix"},
5900 {"en_POSIX", "en-u-va-posix", "en-u-va-posix"},
5901 {"en_US_POSIX_VAR", "en-US-posix-x-lvariant-var", NULL
}, /* variant POSIX_VAR is processed as regular variant */
5902 {"en_US_VAR_POSIX", "en-US-x-lvariant-var-posix", NULL
}, /* variant VAR_POSIX is processed as regular variant */
5903 {"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 */
5904 {"en_US_POSIX@ca=japanese", "en-US-u-ca-japanese-va-posix", "en-US-u-ca-japanese-va-posix"},
5905 {"und_555", "und-555", "und-555"},
5906 {"123", "und", NULL
},
5907 {"%$#&", "und", NULL
},
5908 {"_Latn", "und-Latn", "und-Latn"},
5909 {"_DE", "und-DE", "und-DE"},
5910 {"und_FR", "und-FR", "und-FR"},
5911 {"th_TH_TH", "th-TH-x-lvariant-th", NULL
},
5912 {"bogus", "bogus", "bogus"},
5913 {"foooobarrr", "und", NULL
},
5914 {"az_AZ_CYRL", "az-Cyrl-AZ", "az-Cyrl-AZ"},
5915 {"aa_BB_CYRL", "aa-BB-x-lvariant-cyrl", NULL
},
5916 {"en_US_1234", "en-US-1234", "en-US-1234"},
5917 {"en_US_VARIANTA_VARIANTB", "en-US-varianta-variantb", "en-US-varianta-variantb"},
5918 {"ja__9876_5432", "ja-9876-5432", "ja-9876-5432"},
5919 {"zh_Hant__VAR", "zh-Hant-x-lvariant-var", NULL
},
5920 {"es__BADVARIANT_GOODVAR", "es-goodvar", NULL
},
5921 {"en@calendar=gregorian", "en-u-ca-gregory", "en-u-ca-gregory"},
5922 {"de@collation=phonebook;calendar=gregorian", "de-u-ca-gregory-co-phonebk", "de-u-ca-gregory-co-phonebk"},
5923 {"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"},
5924 {"en@timezone=America/New_York;calendar=japanese", "en-u-ca-japanese-tz-usnyc", "en-u-ca-japanese-tz-usnyc"},
5925 {"en@timezone=US/Eastern", "en-u-tz-usnyc", "en-u-tz-usnyc"},
5926 {"en@x=x-y-z;a=a-b-c", "en-x-x-y-z", NULL
},
5927 {"it@collation=badcollationtype;colStrength=identical;cu=usd-eur", "it-u-cu-usd-eur-ks-identic", NULL
},
5928 {"en_US_POSIX", "en-US-u-va-posix", "en-US-u-va-posix"},
5929 {"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"},
5930 {"@x=elmer", "x-elmer", "x-elmer"},
5931 {"en@x=elmer", "en-x-elmer", "en-x-elmer"},
5932 {"@x=elmer;a=exta", "und-a-exta-x-elmer", "und-a-exta-x-elmer"},
5933 {"en_US@attribute=attr1-attr2;calendar=gregorian", "en-US-u-attr1-attr2-ca-gregory", "en-US-u-attr1-attr2-ca-gregory"},
5935 {"en@a=bar;attribute=baz", "en-a-bar-u-baz", "en-a-bar-u-baz"},
5936 {"en@a=bar;attribute=baz;x=u-foo", "en-a-bar-u-baz-x-u-foo", "en-a-bar-u-baz-x-u-foo"},
5937 {"en@attribute=baz", "en-u-baz", "en-u-baz"},
5938 {"en@attribute=baz;calendar=islamic-civil", "en-u-baz-ca-islamic-civil", "en-u-baz-ca-islamic-civil"},
5939 {"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"},
5940 {"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"},
5944 static void TestToLanguageTag(void) {
5950 const char *expected
;
5952 for (i
= 0; locale_to_langtag
[i
][0] != NULL
; i
++) {
5953 inloc
= locale_to_langtag
[i
][0];
5955 /* testing non-strict mode */
5956 status
= U_ZERO_ERROR
;
5958 expected
= locale_to_langtag
[i
][1];
5960 len
= uloc_toLanguageTag(inloc
, langtag
, sizeof(langtag
), FALSE
, &status
);
5961 (void)len
; /* Suppress set but not used warning. */
5962 if (U_FAILURE(status
)) {
5963 if (expected
!= NULL
) {
5964 log_err("Error returned by uloc_toLanguageTag for locale id [%s] - error: %s\n",
5965 inloc
, u_errorName(status
));
5968 if (expected
== NULL
) {
5969 log_err("Error should be returned by uloc_toLanguageTag for locale id [%s], but [%s] is returned without errors\n",
5971 } else if (uprv_strcmp(langtag
, expected
) != 0) {
5972 log_data_err("uloc_toLanguageTag returned language tag [%s] for input locale [%s] - expected: [%s]. Are you missing data?\n",
5973 langtag
, inloc
, expected
);
5977 /* testing strict mode */
5978 status
= U_ZERO_ERROR
;
5980 expected
= locale_to_langtag
[i
][2];
5982 len
= uloc_toLanguageTag(inloc
, langtag
, sizeof(langtag
), TRUE
, &status
);
5983 if (U_FAILURE(status
)) {
5984 if (expected
!= NULL
) {
5985 log_data_err("Error returned by uloc_toLanguageTag {strict} for locale id [%s] - error: %s Are you missing data?\n",
5986 inloc
, u_errorName(status
));
5989 if (expected
== NULL
) {
5990 log_err("Error should be returned by uloc_toLanguageTag {strict} for locale id [%s], but [%s] is returned without errors\n",
5992 } else if (uprv_strcmp(langtag
, expected
) != 0) {
5993 log_err("uloc_toLanguageTag {strict} returned language tag [%s] for input locale [%s] - expected: [%s]\n",
5994 langtag
, inloc
, expected
);
6000 #define FULL_LENGTH -1
6001 static const struct {
6005 } langtag_to_locale
[] = {
6006 {"en", "en", FULL_LENGTH
},
6007 {"en-us", "en_US", FULL_LENGTH
},
6008 {"und-US", "_US", FULL_LENGTH
},
6009 {"und-latn", "_Latn", FULL_LENGTH
},
6010 {"en-US-posix", "en_US_POSIX", FULL_LENGTH
},
6011 {"de-de_euro", "de", 2},
6012 {"kok-IN", "kok_IN", FULL_LENGTH
},
6015 {"en-latn-x", "en_Latn", 7},
6016 {"art-lojban", "jbo", FULL_LENGTH
},
6017 {"zh-hakka", "hak", FULL_LENGTH
},
6018 {"zh-cmn-CH", "cmn_CH", FULL_LENGTH
},
6019 {"xxx-yy", "xxx_YY", FULL_LENGTH
},
6020 {"fr-234", "fr_234", FULL_LENGTH
},
6021 {"i-default", "en@x=i-default", FULL_LENGTH
},
6023 {"ja-jp-jp", "ja_JP", 5},
6024 {"bogus", "bogus", FULL_LENGTH
},
6025 {"boguslang", "", 0},
6026 {"EN-lATN-us", "en_Latn_US", FULL_LENGTH
},
6027 {"und-variant-1234", "__VARIANT_1234", FULL_LENGTH
},
6028 {"und-varzero-var1-vartwo", "__VARZERO", 11},
6029 {"en-u-ca-gregory", "en@calendar=gregorian", FULL_LENGTH
},
6030 {"en-U-cu-USD", "en@currency=usd", FULL_LENGTH
},
6031 {"en-US-u-va-posix", "en_US_POSIX", FULL_LENGTH
},
6032 {"en-us-u-ca-gregory-va-posix", "en_US_POSIX@calendar=gregorian", FULL_LENGTH
},
6033 {"en-us-posix-u-va-posix", "en_US_POSIX@va=posix", FULL_LENGTH
},
6034 {"en-us-u-va-posix2", "en_US@va=posix2", FULL_LENGTH
},
6035 {"en-us-vari1-u-va-posix", "en_US_VARI1@va=posix", FULL_LENGTH
},
6036 {"ar-x-1-2-3", "ar@x=1-2-3", FULL_LENGTH
},
6037 {"fr-u-nu-latn-cu-eur", "fr@currency=eur;numbers=latn", FULL_LENGTH
},
6038 {"de-k-kext-u-co-phonebk-nu-latn", "de@collation=phonebook;k=kext;numbers=latn", FULL_LENGTH
},
6039 {"ja-u-cu-jpy-ca-jp", "ja@calendar=yes;currency=jpy;jp=yes", FULL_LENGTH
},
6040 {"en-us-u-tz-usnyc", "en_US@timezone=America/New_York", FULL_LENGTH
},
6041 {"und-a-abc-def", "und@a=abc-def", FULL_LENGTH
},
6042 {"zh-u-ca-chinese-x-u-ca-chinese", "zh@calendar=chinese;x=u-ca-chinese", FULL_LENGTH
},
6043 {"x-elmer", "@x=elmer", FULL_LENGTH
},
6044 {"en-US-u-attr1-attr2-ca-gregory", "en_US@attribute=attr1-attr2;calendar=gregorian", FULL_LENGTH
},
6045 {"sr-u-kn", "sr@colnumeric=yes", FULL_LENGTH
},
6046 {"de-u-kn-co-phonebk", "de@collation=phonebook;colnumeric=yes", FULL_LENGTH
},
6047 {"en-u-attr2-attr1-kn-kb", "en@attribute=attr1-attr2;colbackwards=yes;colnumeric=yes", FULL_LENGTH
},
6048 {"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
},
6049 {"de-u-xc-xphonebk-co-phonebk-ca-buddhist-mo-very-lo-extensi-xd-that-de-should-vc-probably-xz-killthebuffer",
6050 "de@calendar=buddhist;collation=phonebook;de=should;lo=extensi;mo=very;vc=probably;xc=xphonebk;xd=that;xz=yes", 91},
6052 {"en-a-bar-u-baz", "en@a=bar;attribute=baz", FULL_LENGTH
},
6053 {"en-a-bar-u-baz-x-u-foo", "en@a=bar;attribute=baz;x=u-foo", FULL_LENGTH
},
6054 {"en-u-baz", "en@attribute=baz", FULL_LENGTH
},
6055 {"en-u-baz-ca-islamic-civil", "en@attribute=baz;calendar=islamic-civil", FULL_LENGTH
},
6056 {"en-a-bar-u-ca-islamic-civil-x-u-foo", "en@a=bar;calendar=islamic-civil;x=u-foo", FULL_LENGTH
},
6057 {"en-a-bar-u-baz-ca-islamic-civil-x-u-foo", "en@a=bar;attribute=baz;calendar=islamic-civil;x=u-foo", FULL_LENGTH
},
6061 static void TestForLanguageTag(void) {
6066 int32_t expParsedLen
;
6068 for (i
= 0; langtag_to_locale
[i
].bcpID
!= NULL
; i
++) {
6069 status
= U_ZERO_ERROR
;
6071 expParsedLen
= langtag_to_locale
[i
].len
;
6072 if (expParsedLen
== FULL_LENGTH
) {
6073 expParsedLen
= uprv_strlen(langtag_to_locale
[i
].bcpID
);
6075 uloc_forLanguageTag(langtag_to_locale
[i
].bcpID
, locale
, sizeof(locale
), &parsedLen
, &status
);
6076 if (U_FAILURE(status
)) {
6077 log_err_status(status
, "Error returned by uloc_forLanguageTag for language tag [%s] - error: %s\n",
6078 langtag_to_locale
[i
].bcpID
, u_errorName(status
));
6080 if (uprv_strcmp(langtag_to_locale
[i
].locID
, locale
) != 0) {
6081 log_data_err("uloc_forLanguageTag returned locale [%s] for input language tag [%s] - expected: [%s]\n",
6082 locale
, langtag_to_locale
[i
].bcpID
, langtag_to_locale
[i
].locID
);
6084 if (parsedLen
!= expParsedLen
) {
6085 log_err("uloc_forLanguageTag parsed length of %d for input language tag [%s] - expected parsed length: %d\n",
6086 parsedLen
, langtag_to_locale
[i
].bcpID
, expParsedLen
);
6092 static void TestToUnicodeLocaleKey(void)
6094 /* $IN specifies the result should be the input pointer itself */
6095 static const char* DATA
[][2] = {
6097 {"CALEndar", "ca"}, /* difference casing */
6098 {"ca", "ca"}, /* bcp key itself */
6099 {"kv", "kv"}, /* no difference between legacy and bcp */
6100 {"foo", NULL
}, /* unknown, bcp ill-formed */
6101 {"ZZ", "$IN"}, /* unknown, bcp well-formed - */
6106 for (i
= 0; DATA
[i
][0] != NULL
; i
++) {
6107 const char* keyword
= DATA
[i
][0];
6108 const char* expected
= DATA
[i
][1];
6109 const char* bcpKey
= NULL
;
6111 bcpKey
= uloc_toUnicodeLocaleKey(keyword
);
6112 if (expected
== NULL
) {
6113 if (bcpKey
!= NULL
) {
6114 log_err("toUnicodeLocaleKey: keyword=%s => %s, expected=NULL\n", keyword
, bcpKey
);
6116 } else if (bcpKey
== NULL
) {
6117 log_data_err("toUnicodeLocaleKey: keyword=%s => NULL, expected=%s\n", keyword
, expected
);
6118 } else if (uprv_strcmp(expected
, "$IN") == 0) {
6119 if (bcpKey
!= keyword
) {
6120 log_err("toUnicodeLocaleKey: keyword=%s => %s, expected=%s(input pointer)\n", keyword
, bcpKey
, keyword
);
6122 } else if (uprv_strcmp(bcpKey
, expected
) != 0) {
6123 log_err("toUnicodeLocaleKey: keyword=%s => %s, expected=%s\n", keyword
, bcpKey
, expected
);
6128 static void TestToLegacyKey(void)
6130 /* $IN specifies the result should be the input pointer itself */
6131 static const char* DATA
[][2] = {
6132 {"kb", "colbackwards"},
6133 {"kB", "colbackwards"}, /* different casing */
6134 {"Collation", "collation"}, /* keyword itself with different casing */
6135 {"kv", "kv"}, /* no difference between legacy and bcp */
6136 {"foo", "$IN"}, /* unknown, bcp ill-formed */
6137 {"ZZ", "$IN"}, /* unknown, bcp well-formed */
6138 {"e=mc2", NULL
}, /* unknown, bcp/legacy ill-formed */
6143 for (i
= 0; DATA
[i
][0] != NULL
; i
++) {
6144 const char* keyword
= DATA
[i
][0];
6145 const char* expected
= DATA
[i
][1];
6146 const char* legacyKey
= NULL
;
6148 legacyKey
= uloc_toLegacyKey(keyword
);
6149 if (expected
== NULL
) {
6150 if (legacyKey
!= NULL
) {
6151 log_err("toLegacyKey: keyword=%s => %s, expected=NULL\n", keyword
, legacyKey
);
6153 } else if (legacyKey
== NULL
) {
6154 log_err("toLegacyKey: keyword=%s => NULL, expected=%s\n", keyword
, expected
);
6155 } else if (uprv_strcmp(expected
, "$IN") == 0) {
6156 if (legacyKey
!= keyword
) {
6157 log_err("toLegacyKey: keyword=%s => %s, expected=%s(input pointer)\n", keyword
, legacyKey
, keyword
);
6159 } else if (uprv_strcmp(legacyKey
, expected
) != 0) {
6160 log_data_err("toUnicodeLocaleKey: keyword=%s, %s, expected=%s\n", keyword
, legacyKey
, expected
);
6165 static void TestToUnicodeLocaleType(void)
6167 /* $IN specifies the result should be the input pointer itself */
6168 static const char* DATA
[][3] = {
6169 {"tz", "Asia/Kolkata", "inccu"},
6170 {"calendar", "gregorian", "gregory"},
6171 {"ca", "gregorian", "gregory"},
6172 {"ca", "Gregorian", "gregory"},
6173 {"ca", "buddhist", "buddhist"},
6174 {"Calendar", "Japanese", "japanese"},
6175 {"calendar", "Islamic-Civil", "islamic-civil"},
6176 {"calendar", "islamicc", "islamic-civil"}, /* bcp type alias */
6177 {"colalternate", "NON-IGNORABLE", "noignore"},
6178 {"colcaselevel", "yes", "true"},
6179 {"rg", "GBzzzz", "$IN"},
6180 {"tz", "america/new_york", "usnyc"},
6181 {"tz", "Asia/Kolkata", "inccu"},
6182 {"timezone", "navajo", "usden"},
6183 {"ca", "aaaa", "$IN"}, /* unknown type, well-formed type */
6184 {"ca", "gregory-japanese-islamic", "$IN"}, /* unknown type, well-formed type */
6185 {"zz", "gregorian", NULL
}, /* unknown key, ill-formed type */
6186 {"co", "foo-", NULL
}, /* unknown type, ill-formed type */
6187 {"variableTop", "00A0", "$IN"}, /* valid codepoints type */
6188 {"variableTop", "wxyz", "$IN"}, /* invalid codepoints type - return as is for now */
6189 {"kr", "space-punct", "space-punct"}, /* valid reordercode type */
6190 {"kr", "digit-spacepunct", NULL
}, /* invalid (bcp ill-formed) reordercode type */
6195 for (i
= 0; DATA
[i
][0] != NULL
; i
++) {
6196 const char* keyword
= DATA
[i
][0];
6197 const char* value
= DATA
[i
][1];
6198 const char* expected
= DATA
[i
][2];
6199 const char* bcpType
= NULL
;
6201 bcpType
= uloc_toUnicodeLocaleType(keyword
, value
);
6202 if (expected
== NULL
) {
6203 if (bcpType
!= NULL
) {
6204 log_err("toUnicodeLocaleType: keyword=%s, value=%s => %s, expected=NULL\n", keyword
, value
, bcpType
);
6206 } else if (bcpType
== NULL
) {
6207 log_data_err("toUnicodeLocaleType: keyword=%s, value=%s => NULL, expected=%s\n", keyword
, value
, expected
);
6208 } else if (uprv_strcmp(expected
, "$IN") == 0) {
6209 if (bcpType
!= value
) {
6210 log_err("toUnicodeLocaleType: keyword=%s, value=%s => %s, expected=%s(input pointer)\n", keyword
, value
, bcpType
, value
);
6212 } else if (uprv_strcmp(bcpType
, expected
) != 0) {
6213 log_data_err("toUnicodeLocaleType: keyword=%s, value=%s => %s, expected=%s\n", keyword
, value
, bcpType
, expected
);
6218 static void TestToLegacyType(void)
6220 /* $IN specifies the result should be the input pointer itself */
6221 static const char* DATA
[][3] = {
6222 {"calendar", "gregory", "gregorian"},
6223 {"ca", "gregory", "gregorian"},
6224 {"ca", "Gregory", "gregorian"},
6225 {"ca", "buddhist", "buddhist"},
6226 {"Calendar", "Japanese", "japanese"},
6227 {"calendar", "Islamic-Civil", "islamic-civil"},
6228 {"calendar", "islamicc", "islamic-civil"}, /* bcp type alias */
6229 {"colalternate", "noignore", "non-ignorable"},
6230 {"colcaselevel", "true", "yes"},
6231 {"rg", "gbzzzz", "gbzzzz"},
6232 {"tz", "usnyc", "America/New_York"},
6233 {"tz", "inccu", "Asia/Calcutta"},
6234 {"timezone", "usden", "America/Denver"},
6235 {"timezone", "usnavajo", "America/Denver"}, /* bcp type alias */
6236 {"colstrength", "quarternary", "quaternary"}, /* type alias */
6237 {"ca", "aaaa", "$IN"}, /* unknown type */
6238 {"calendar", "gregory-japanese-islamic", "$IN"}, /* unknown type, well-formed type */
6239 {"zz", "gregorian", "$IN"}, /* unknown key, bcp ill-formed type */
6240 {"ca", "gregorian-calendar", "$IN"}, /* known key, bcp ill-formed type */
6241 {"co", "e=mc2", NULL
}, /* known key, ill-formed bcp/legacy type */
6242 {"variableTop", "00A0", "$IN"}, /* valid codepoints type */
6243 {"variableTop", "wxyz", "$IN"}, /* invalid codepoints type - return as is for now */
6244 {"kr", "space-punct", "space-punct"}, /* valid reordercode type */
6245 {"kr", "digit-spacepunct", "digit-spacepunct"}, /* invalid reordercode type, but ok for legacy syntax */
6250 for (i
= 0; DATA
[i
][0] != NULL
; i
++) {
6251 const char* keyword
= DATA
[i
][0];
6252 const char* value
= DATA
[i
][1];
6253 const char* expected
= DATA
[i
][2];
6254 const char* legacyType
= NULL
;
6256 legacyType
= uloc_toLegacyType(keyword
, value
);
6257 if (expected
== NULL
) {
6258 if (legacyType
!= NULL
) {
6259 log_err("toLegacyType: keyword=%s, value=%s => %s, expected=NULL\n", keyword
, value
, legacyType
);
6261 } else if (legacyType
== NULL
) {
6262 log_err("toLegacyType: keyword=%s, value=%s => NULL, expected=%s\n", keyword
, value
, expected
);
6263 } else if (uprv_strcmp(expected
, "$IN") == 0) {
6264 if (legacyType
!= value
) {
6265 log_err("toLegacyType: keyword=%s, value=%s => %s, expected=%s(input pointer)\n", keyword
, value
, legacyType
, value
);
6267 } else if (uprv_strcmp(legacyType
, expected
) != 0) {
6268 log_data_err("toLegacyType: keyword=%s, value=%s => %s, expected=%s\n", keyword
, value
, legacyType
, expected
);
6270 log_verbose("toLegacyType: keyword=%s, value=%s => %s\n", keyword
, value
, legacyType
);
6277 static void test_unicode_define(const char *namech
, char ch
, const char *nameu
, UChar uch
)
6281 log_verbose("Testing whether %s[\\x%02x,'%c'] == %s[U+%04X]\n", namech
, ch
,(int)ch
, nameu
, (int) uch
);
6282 u_charsToUChars(&ch
, asUch
, 1);
6283 if(asUch
[0] != uch
) {
6284 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
);
6286 log_verbose(" .. OK, == U+%04X\n", (int)asUch
[0]);
6290 #define TEST_UNICODE_DEFINE(x,y) test_unicode_define(#x, (char)(x), #y, (UChar)(y))
6292 static void TestUnicodeDefines(void) {
6293 TEST_UNICODE_DEFINE(ULOC_KEYWORD_SEPARATOR
, ULOC_KEYWORD_SEPARATOR_UNICODE
);
6294 TEST_UNICODE_DEFINE(ULOC_KEYWORD_ASSIGN
, ULOC_KEYWORD_ASSIGN_UNICODE
);
6295 TEST_UNICODE_DEFINE(ULOC_KEYWORD_ITEM_SEPARATOR
, ULOC_KEYWORD_ITEM_SEPARATOR_UNICODE
);
6298 static void TestIsRightToLeft() {
6299 // API test only. More test cases in intltest/LocaleTest.
6300 if(uloc_isRightToLeft("root") || !uloc_isRightToLeft("EN-HEBR")) {
6301 log_err("uloc_isRightToLeft() failed");
6306 const char * badLocaleID
;
6307 const char * displayLocale
;
6308 const char * expectedName
;
6309 UErrorCode expectedStatus
;
6312 static const BadLocaleItem badLocaleItems
[] = {
6313 { "-9223372036854775808", "en", "9223372036854775808", U_USING_DEFAULT_WARNING
},
6314 /* add more in the future */
6315 { NULL
, NULL
, NULL
, U_ZERO_ERROR
} /* terminator */
6318 enum { kUBufDispNameMax
= 128, kBBufDispNameMax
= 256 };
6320 static void TestBadLocaleIDs() {
6321 const BadLocaleItem
* itemPtr
;
6322 for (itemPtr
= badLocaleItems
; itemPtr
->badLocaleID
!= NULL
; itemPtr
++) {
6323 UChar ubufExpect
[kUBufDispNameMax
], ubufGet
[kUBufDispNameMax
];
6324 UErrorCode status
= U_ZERO_ERROR
;
6325 int32_t ulenExpect
= u_unescape(itemPtr
->expectedName
, ubufExpect
, kUBufDispNameMax
);
6326 int32_t ulenGet
= uloc_getDisplayName(itemPtr
->badLocaleID
, itemPtr
->displayLocale
, ubufGet
, kUBufDispNameMax
, &status
);
6327 if (status
!= itemPtr
->expectedStatus
||
6328 (U_SUCCESS(status
) && (ulenGet
!= ulenExpect
|| u_strncmp(ubufGet
, ubufExpect
, ulenExpect
) != 0))) {
6329 char bbufExpect
[kBBufDispNameMax
], bbufGet
[kBBufDispNameMax
];
6330 u_austrncpy(bbufExpect
, ubufExpect
, ulenExpect
);
6331 u_austrncpy(bbufGet
, ubufGet
, ulenGet
);
6332 log_err("FAIL: For localeID %s, displayLocale %s, calling uloc_getDisplayName:\n"
6333 " expected status %-26s, name (len %2d): %s\n"
6334 " got status %-26s, name (len %2d): %s\n",
6335 itemPtr
->badLocaleID
, itemPtr
->displayLocale
,
6336 u_errorName(itemPtr
->expectedStatus
), ulenExpect
, bbufExpect
,
6337 u_errorName(status
), ulenGet
, bbufGet
);
6342 typedef enum UldnNameType
{
6350 const char * localeToName
; // NULL to terminate a list of these
6351 UldnNameType nameType
;
6352 const char * expectResult
;
6356 const char * displayLocale
;
6357 const UDisplayContext
* displayOptions
; // set of 3 UDisplayContext items
6358 const UldnItem
* testItems
;
6362 static const UDisplayContext optStdMidLong
[3] = {UDISPCTX_STANDARD_NAMES
, UDISPCTX_CAPITALIZATION_FOR_MIDDLE_OF_SENTENCE
, UDISPCTX_LENGTH_FULL
};
6363 static const UDisplayContext optStdMidShrt
[3] = {UDISPCTX_STANDARD_NAMES
, UDISPCTX_CAPITALIZATION_FOR_MIDDLE_OF_SENTENCE
, UDISPCTX_LENGTH_SHORT
};
6364 static const UDisplayContext optDiaMidLong
[3] = {UDISPCTX_DIALECT_NAMES
, UDISPCTX_CAPITALIZATION_FOR_MIDDLE_OF_SENTENCE
, UDISPCTX_LENGTH_FULL
};
6365 static const UDisplayContext optDiaMidShrt
[3] = {UDISPCTX_DIALECT_NAMES
, UDISPCTX_CAPITALIZATION_FOR_MIDDLE_OF_SENTENCE
, UDISPCTX_LENGTH_SHORT
};
6367 static const UDisplayContext optStdBegLong
[3] = {UDISPCTX_STANDARD_NAMES
, UDISPCTX_CAPITALIZATION_FOR_BEGINNING_OF_SENTENCE
, UDISPCTX_LENGTH_FULL
};
6368 static const UDisplayContext optStdBegShrt
[3] = {UDISPCTX_STANDARD_NAMES
, UDISPCTX_CAPITALIZATION_FOR_BEGINNING_OF_SENTENCE
, UDISPCTX_LENGTH_SHORT
};
6369 static const UDisplayContext optDiaBegLong
[3] = {UDISPCTX_DIALECT_NAMES
, UDISPCTX_CAPITALIZATION_FOR_BEGINNING_OF_SENTENCE
, UDISPCTX_LENGTH_FULL
};
6370 static const UDisplayContext optDiaBegShrt
[3] = {UDISPCTX_DIALECT_NAMES
, UDISPCTX_CAPITALIZATION_FOR_BEGINNING_OF_SENTENCE
, UDISPCTX_LENGTH_SHORT
};
6372 static const UDisplayContext optStdLstLong
[3] = {UDISPCTX_STANDARD_NAMES
, UDISPCTX_CAPITALIZATION_FOR_UI_LIST_OR_MENU
, UDISPCTX_LENGTH_FULL
};
6373 static const UDisplayContext optStdLstShrt
[3] = {UDISPCTX_STANDARD_NAMES
, UDISPCTX_CAPITALIZATION_FOR_UI_LIST_OR_MENU
, UDISPCTX_LENGTH_SHORT
};
6374 static const UDisplayContext optDiaLstLong
[3] = {UDISPCTX_DIALECT_NAMES
, UDISPCTX_CAPITALIZATION_FOR_UI_LIST_OR_MENU
, UDISPCTX_LENGTH_FULL
};
6375 static const UDisplayContext optDiaLstShrt
[3] = {UDISPCTX_DIALECT_NAMES
, UDISPCTX_CAPITALIZATION_FOR_UI_LIST_OR_MENU
, UDISPCTX_LENGTH_SHORT
};
6377 static const UldnItem en_StdMidLong
[] = {
6378 { "en_US", TEST_ULDN_LOCALE
, "English (US)" },
6379 { "en_US_POSIX", TEST_ULDN_LOCALE
, "English (US, Computer)" },
6380 { "en_US@calendar=chinese", TEST_ULDN_LOCALE
, "English (US, Chinese Calendar)" },
6381 { "en_CA", TEST_ULDN_LOCALE
, "English (Canada)" },
6382 { "pt", TEST_ULDN_LOCALE
, "Portuguese" },
6383 { "pt_BR", TEST_ULDN_LOCALE
, "Portuguese (Brazil)" },
6384 { "pt_PT", TEST_ULDN_LOCALE
, "Portuguese (Portugal)" },
6385 { "zh_Hans", TEST_ULDN_LOCALE
, "Chinese (Simplified)" },
6386 { "zh_Hant_HK", TEST_ULDN_LOCALE
, "Chinese (Traditional, Hong Kong)" },
6387 { "zh_HK", TEST_ULDN_LOCALE
, "Chinese (Hong Kong)" },
6388 { "Latn", TEST_ULDN_SCRIPT
, "Latin" },
6389 { "Hans", TEST_ULDN_SCRIPT
, "Simplified Han" },
6390 { "Hant", TEST_ULDN_SCRIPT
, "Traditional Han" },
6391 { "US", TEST_ULDN_REGION
, "United States" },
6392 { "CA", TEST_ULDN_REGION
, "Canada" },
6393 { "GB", TEST_ULDN_REGION
, "United Kingdom" },
6394 { "HK", TEST_ULDN_REGION
, "Hong Kong (China)" },
6397 static const UldnItem en_StdMidShrt
[] = {
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, Calendar: chinese)" },
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
, "US" },
6412 { "CA", TEST_ULDN_REGION
, "Canada" },
6413 { "GB", TEST_ULDN_REGION
, "UK" },
6414 { "HK", TEST_ULDN_REGION
, "Hong Kong" },
6417 static const UldnItem en_DiaMidLong
[] = {
6418 { "en_US", TEST_ULDN_LOCALE
, "American English" },
6419 { "en_US_POSIX", TEST_ULDN_LOCALE
, "American English (Computer)" },
6420 { "en_US@calendar=chinese", TEST_ULDN_LOCALE
, "American English (Chinese Calendar)" },
6421 { "en_CA", TEST_ULDN_LOCALE
, "Canadian English" },
6422 { "pt", TEST_ULDN_LOCALE
, "Portuguese" },
6423 { "pt_BR", TEST_ULDN_LOCALE
, "Brazilian Portuguese" },
6424 { "pt_PT", TEST_ULDN_LOCALE
, "European Portuguese" },
6425 { "zh_Hans", TEST_ULDN_LOCALE
, "Simplified Chinese" },
6426 { "zh_Hant_HK", TEST_ULDN_LOCALE
, "Traditional Chinese (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
, "United States" },
6432 { "CA", TEST_ULDN_REGION
, "Canada" },
6433 { "GB", TEST_ULDN_REGION
, "United Kingdom" },
6434 { "HK", TEST_ULDN_REGION
, "Hong Kong (China)" },
6437 static const UldnItem en_DiaMidShrt
[] = {
6438 { "en_US", TEST_ULDN_LOCALE
, "US English" },
6439 { "en_US_POSIX", TEST_ULDN_LOCALE
, "US English (Computer)" },
6440 { "en_US@calendar=chinese", TEST_ULDN_LOCALE
, "US English (Calendar: chinese)" },
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
, "US" },
6452 { "CA", TEST_ULDN_REGION
, "Canada" },
6453 { "GB", TEST_ULDN_REGION
, "UK" },
6454 { "HK", TEST_ULDN_REGION
, "Hong Kong" },
6457 static const UldnItem fr_StdMidLong
[] = {
6458 { "en_US", TEST_ULDN_LOCALE
, "anglais (\\u00C9.-U.)" },
6459 { "US", TEST_ULDN_REGION
, "\\u00C9tats-Unis" },
6460 { "HK", TEST_ULDN_REGION
, "Hong Kong (Chine)" },
6463 static const UldnItem fr_StdMidShrt
[] = {
6464 { "en_US", TEST_ULDN_LOCALE
, "anglais (\\u00C9.-U.)" },
6465 { "US", TEST_ULDN_REGION
, "\\u00C9.-U." },
6466 { "HK", TEST_ULDN_REGION
, "Hong Kong" },
6469 static const UldnItem fr_StdBegLong
[] = {
6470 { "en_US", TEST_ULDN_LOCALE
, "Anglais (\\u00C9.-U.)" },
6473 static const UldnItem fr_StdLstLong
[] = {
6474 { "en_US", TEST_ULDN_LOCALE
, "Anglais (\\u00C9.-U.)" },
6475 { "PS", TEST_ULDN_REGION
, "Territoires palestiniens" },
6478 static const UldnItem fr_DiaMidLong
[] = {
6479 { "en_US", TEST_ULDN_LOCALE
, "anglais am\\u00E9ricain" },
6482 static const UldnItem ca_StdLstLong
[] = {
6483 { "PS", TEST_ULDN_REGION
, "Territoris palestins" },
6486 static const UldnLocAndOpts uldnLocAndOpts
[] = {
6487 { "en", optStdMidLong
, en_StdMidLong
, UPRV_LENGTHOF(en_StdMidLong
) },
6488 { "en", optStdMidShrt
, en_StdMidShrt
, UPRV_LENGTHOF(en_StdMidShrt
) },
6489 { "en", optDiaMidLong
, en_DiaMidLong
, UPRV_LENGTHOF(en_DiaMidLong
) },
6490 { "en", optDiaMidShrt
, en_DiaMidShrt
, UPRV_LENGTHOF(en_DiaMidShrt
) },
6491 { "fr", optStdMidLong
, fr_StdMidLong
, UPRV_LENGTHOF(fr_StdMidLong
) },
6492 { "fr", optStdMidShrt
, fr_StdMidShrt
, UPRV_LENGTHOF(fr_StdMidShrt
) },
6493 { "fr", optStdBegLong
, fr_StdBegLong
, UPRV_LENGTHOF(fr_StdBegLong
) },
6494 { "fr", optStdLstLong
, fr_StdLstLong
, UPRV_LENGTHOF(fr_StdLstLong
) },
6495 { "fr_CA", optStdLstLong
, fr_StdLstLong
, UPRV_LENGTHOF(fr_StdLstLong
) },
6496 { "fr", optDiaMidLong
, fr_DiaMidLong
, UPRV_LENGTHOF(fr_DiaMidLong
) },
6497 { "ca", optStdLstLong
, ca_StdLstLong
, UPRV_LENGTHOF(ca_StdLstLong
) },
6498 { NULL
, NULL
, NULL
, 0 }
6501 enum { kUNameBuf
= 128, kBNameBuf
= 256 };
6503 static void TestUldnNameVariants() {
6504 const UldnLocAndOpts
* uloPtr
;
6505 for (uloPtr
= uldnLocAndOpts
; uloPtr
->displayLocale
!= NULL
; uloPtr
++) {
6506 UErrorCode status
= U_ZERO_ERROR
;
6507 ULocaleDisplayNames
* uldn
= uldn_openForContext(uloPtr
->displayLocale
, (UDisplayContext
*)uloPtr
->displayOptions
, 3, &status
);
6508 if (U_FAILURE(status
)) {
6509 log_data_err("uldn_openForContext fails, displayLocale %s, contexts %03X %03X %03X: %s - Are you missing data?\n",
6510 uloPtr
->displayLocale
, uloPtr
->displayOptions
[0], uloPtr
->displayOptions
[1], uloPtr
->displayOptions
[2],
6511 u_errorName(status
) );
6514 const UldnItem
* itemPtr
= uloPtr
->testItems
;
6515 int32_t itemCount
= uloPtr
->countItems
;
6516 for (; itemCount
-- > 0; itemPtr
++) {
6517 UChar uget
[kUNameBuf
], uexp
[kUNameBuf
];
6518 int32_t ulenget
, ulenexp
;
6519 const char* typeString
;
6521 status
= U_ZERO_ERROR
;
6522 switch (itemPtr
->nameType
) {
6523 case TEST_ULDN_LOCALE
:
6524 ulenget
= uldn_localeDisplayName(uldn
, itemPtr
->localeToName
, uget
, kUNameBuf
, &status
);
6525 typeString
= "locale";
6527 case TEST_ULDN_LANGUAGE
:
6528 ulenget
= uldn_languageDisplayName(uldn
, itemPtr
->localeToName
, uget
, kUNameBuf
, &status
);
6529 typeString
= "language";
6531 case TEST_ULDN_SCRIPT
:
6532 ulenget
= uldn_scriptDisplayName(uldn
, itemPtr
->localeToName
, uget
, kUNameBuf
, &status
);
6533 typeString
= "script";
6535 case TEST_ULDN_REGION
:
6536 ulenget
= uldn_regionDisplayName(uldn
, itemPtr
->localeToName
, uget
, kUNameBuf
, &status
);
6537 typeString
= "region";
6542 if (U_FAILURE(status
)) {
6543 log_data_err("uldn_%sDisplayName fails, displayLocale %s, contexts %03X %03X %03X, localeToName %s: %s\n",
6544 typeString
, uloPtr
->displayLocale
, uloPtr
->displayOptions
[0], uloPtr
->displayOptions
[1], uloPtr
->displayOptions
[2],
6545 itemPtr
->localeToName
, u_errorName(status
) );
6548 ulenexp
= u_unescape(itemPtr
->expectResult
, uexp
, kUNameBuf
);
6549 if (ulenget
!= ulenexp
|| u_strncmp(uget
, uexp
, ulenexp
) != 0) {
6550 char bexp
[kBNameBuf
], bget
[kBNameBuf
];
6551 u_strToUTF8(bexp
, kBNameBuf
, NULL
, uexp
, ulenexp
, &status
);
6552 u_strToUTF8(bget
, kBNameBuf
, NULL
, uget
, ulenget
, &status
);
6553 log_data_err("uldn_%sDisplayName fails, displayLocale %s, contexts %03X %03X %03X, localeToName %s:\n expect %2d: %s\n get %2d: %s\n",
6554 typeString
, uloPtr
->displayLocale
, uloPtr
->displayOptions
[0], uloPtr
->displayOptions
[1], uloPtr
->displayOptions
[2],
6555 itemPtr
->localeToName
, ulenexp
, bexp
, ulenget
, bget
);
6563 /* Apple-specific, test for Apple-specific function ualoc_getAppleParent */
6564 static const char* localesAndAppleParent
[] = {
6631 "zh_HK", "zh_Hant_HK",
6632 "zh-HK", "zh_Hant_HK",
6634 "zh-Hant-HK", "zh_Hant",
6635 "zh_Hant_HK", "zh_Hant",
6636 "zh-Hant-MO", "zh_Hant_HK",
6637 "zh-Hans-HK", "zh_Hans",
6640 "en-Latn-US", "en_Latn",
6641 "en_US_POSIX", "en_US",
6642 "en_Latn_US_POSIX", "en_Latn_US",
6643 "en-u-ca-hebrew", "root",
6644 "en@calendar=hebrew", "root",
6645 "en_@calendar=hebrew", "root",
6648 "Default@2x", "root",
6650 NULL
/* terminator */
6653 static void TestGetAppleParent() {
6654 const char **localesPtr
= localesAndAppleParent
;
6655 const char * locale
;
6656 while ((locale
= *localesPtr
++) != NULL
) {
6657 const char * expectParent
= *localesPtr
++;
6658 UErrorCode status
= U_ZERO_ERROR
;
6659 char getParent
[ULOC_FULLNAME_CAPACITY
];
6660 int32_t plen
= ualoc_getAppleParent(locale
, getParent
, ULOC_FULLNAME_CAPACITY
, &status
);
6661 if (U_FAILURE(status
)) {
6662 log_err("FAIL: ualoc_getAppleParent input \"%s\", status %s\n", locale
, u_errorName(status
));
6663 } else if (uprv_strcmp(expectParent
, getParent
) != 0) {
6664 log_err("FAIL: ualoc_getAppleParent input \"%s\", expected parent \"%s\", got parent \"%s\"\n", locale
, expectParent
, getParent
);
6669 /* Apple-specific, test for Apple-specific function ualoc_getLanguagesForRegion */
6670 enum { kUALanguageEntryMax
= 10 };
6672 static void TestGetLanguagesForRegion() {
6673 UALanguageEntry entries
[kUALanguageEntryMax
];
6676 const char * region
;
6678 status
= U_ZERO_ERROR
;
6680 entryCount
= ualoc_getLanguagesForRegion(region
, 0.001, entries
, kUALanguageEntryMax
, &status
);
6681 if (U_FAILURE(status
)) {
6682 log_err("FAIL: ualoc_getLanguagesForRegion %s, status %s\n", region
, u_errorName(status
));
6684 // Expect approximately:
6685 // zh_Hans 0.90 UALANGSTATUS_OFFICIAL
6688 // yue 0.043 Yue including Cantonese
6693 // ug_Arab 0.0055 Uighur UALANGSTATUS_REGIONAL_OFFICIAL
6694 // ...at least 4 more with fractions >= 0.001
6695 if (entryCount
< kUALanguageEntryMax
) {
6696 log_err("FAIL: ualoc_getLanguagesForRegion %s, entryCount %d is too small\n", region
, entryCount
);
6698 UALanguageEntry
* entryPtr
= entries
;
6699 if (uprv_strcmp(entryPtr
->languageCode
, "zh_Hans") != 0 || entryPtr
->userFraction
< 0.8 || entryPtr
->userFraction
> 1.0 || entryPtr
->status
!= UALANGSTATUS_OFFICIAL
) {
6700 log_err("FAIL: ualoc_getLanguagesForRegion %s, invalid entries[0] { %s, %.3f, %d }\n", region
, entryPtr
->languageCode
, entryPtr
->userFraction
, (int)entryPtr
->status
);
6702 for (entryPtr
++; entryPtr
< entries
+ kUALanguageEntryMax
&& uprv_strcmp(entryPtr
->languageCode
, "ug_Arab") != 0; entryPtr
++)
6704 if (entryPtr
< entries
+ kUALanguageEntryMax
) {
6705 // we found ug_Arab, make sure it has correct status
6706 if (entryPtr
->status
!= UALANGSTATUS_REGIONAL_OFFICIAL
) {
6707 log_err("FAIL: ualoc_getLanguagesForRegion %s, ug_Arab had incorrect status %d\n", (int)entryPtr
->status
);
6710 // did not find ug_Arab
6711 log_err("FAIL: ualoc_getLanguagesForRegion %s, entries did not include ug_Arab\n", region
);
6716 status
= U_ZERO_ERROR
;
6718 entryCount
= ualoc_getLanguagesForRegion(region
, 0.001, entries
, kUALanguageEntryMax
, &status
);
6719 if (U_FAILURE(status
)) {
6720 log_err("FAIL: ualoc_getLanguagesForRegion %s, status %s\n", region
, u_errorName(status
));
6722 // Expect approximately:
6723 // en 0.85 UALANGSTATUS_OFFICIAL
6724 // fr 0.22 UALANGSTATUS_OFFICIAL
6726 if (entryCount
< 2) {
6727 log_err("FAIL: ualoc_getLanguagesForRegion %s, entryCount %d is too small\n", region
, entryCount
);
6729 if (uprv_strcmp(entries
[0].languageCode
, "en") != 0 || entries
[0].userFraction
< 0.7 || entries
[0].userFraction
> 1.0 || entries
[0].status
!= UALANGSTATUS_OFFICIAL
) {
6730 log_err("FAIL: ualoc_getLanguagesForRegion %s, invalid entries[0] { %s, %.3f, %d }\n", region
, entries
[0].languageCode
, entries
[0].userFraction
, (int)entries
[0].status
);
6732 if (uprv_strcmp(entries
[1].languageCode
, "fr") != 0 || entries
[1].userFraction
< 0.1 || entries
[1].userFraction
> 1.0 || entries
[1].status
!= UALANGSTATUS_OFFICIAL
) {
6733 log_err("FAIL: ualoc_getLanguagesForRegion %s, invalid entries[1] { %s, %.3f, %d }\n", region
, entries
[1].languageCode
, entries
[1].userFraction
, (int)entries
[1].status
);
6738 status
= U_ZERO_ERROR
;
6740 entryCount
= ualoc_getLanguagesForRegion(region
, 0.001, NULL
, 0, &status
);
6741 if (U_FAILURE(status
)) {
6742 log_err("FAIL: ualoc_getLanguagesForRegion %s, status %s\n", region
, u_errorName(status
));
6744 if (entryCount
< 40) {
6745 log_err("FAIL: ualoc_getLanguagesForRegion %s, entryCount %d is too small\n", region
, entryCount
);
6750 /* data for TestAppleLocalizationsToUse */
6753 const char * const *locs
;
6755 } AppleLocsAndCount
;
6757 enum { kNumLocSets
= 6 };
6760 const char * language
;
6761 const char ** expLocsForSets
[kNumLocSets
];
6765 static const char * appleLocs1
[] = {
6799 static const char * appleLocs2
[] = {
6806 "en", "en_AU", "en_GB",
6830 "zh_CN", "zh_HK", "zh_TW",
6833 static const char * appleLocs3
[] = {
6840 "en", "en_AU", "en_CA", "en_GB",
6843 "fr", "fr_CA", "fr_FR",
6855 "pt", "pt_BR", "pt_PT",
6864 "zh_CN", "zh_HK", "zh_MO", "zh_TW",
6867 static const char * appleLocs4
[] = {
6868 "en", "en_AU", "en_CA", "en_GB", "en_IN", "en_US",
6869 "es", "es_419", "es_MX",
6870 "fr", "fr_CA", "fr_CH", "fr_FR",
6871 "nl", "nl_BE", "nl_NL",
6873 "ro", "ro_MD", "ro_RO",
6874 "zh_Hans", "zh_Hant", "zh_Hant_HK",
6877 static const char * appleLocs5
[] = {
6878 "en", "en_001", "en_AU", "en_GB",
6879 "es", "es_ES", "es_MX",
6880 "zh_CN", "zh_Hans", "zh_Hant", "zh_TW",
6890 static const char * appleLocs6
[] = {
6891 "en", "en_001", "en_150", "en_AU", "en_GB",
6892 "es", "es_419", "es_ES", "es_MX",
6893 "zh_CN", "zh_Hans", "zh_Hant", "zh_Hant_HK", "zh_HK", "zh_TW",
6900 static const AppleLocsAndCount locAndCountEntries
[kNumLocSets
] = {
6901 { appleLocs1
, UPRV_LENGTHOF(appleLocs1
) },
6902 { appleLocs2
, UPRV_LENGTHOF(appleLocs2
) },
6903 { appleLocs3
, UPRV_LENGTHOF(appleLocs3
) },
6904 { appleLocs4
, UPRV_LENGTHOF(appleLocs4
) },
6905 { appleLocs5
, UPRV_LENGTHOF(appleLocs5
) },
6906 { appleLocs6
, UPRV_LENGTHOF(appleLocs6
) },
6910 static const char* l1_ar
[] = { "ar", NULL
};
6911 static const char* l1_Ara
[] = { "Arabic", NULL
};
6912 static const char* l1_ca
[] = { "ca", NULL
};
6913 static const char* l1_cs
[] = { "cs", NULL
};
6914 static const char* l1_da
[] = { "da", NULL
};
6915 static const char* l1_Dan
[] = { "Danish", NULL
};
6916 static const char* l1_de
[] = { "de", NULL
};
6917 static const char* l1_Ger
[] = { "German", NULL
};
6918 static const char* l1_el
[] = { "el", NULL
};
6919 static const char* l1_en
[] = { "en", NULL
};
6920 static const char* l1_Eng
[] = { "English", NULL
};
6921 static const char* l2_en_001_
[] = { "en_001", "en", NULL
};
6922 static const char* l2_en_CA_
[] = { "en_CA", "en", NULL
};
6923 static const char* l2_en_GB_
[] = { "en_GB", "en", NULL
};
6924 static const char* l2_en_US_
[] = { "en_US", "en", NULL
};
6925 static const char* l2_en_GB_Eng
[] = { "en_GB", "English", NULL
};
6926 static const char* l3_en_GB001_
[] = { "en_GB", "en_001", "en", NULL
};
6927 static const char* l3_en_AUGB_
[] = { "en_AU", "en_GB", "en", NULL
};
6928 static const char* l3_en_INGB_
[] = { "en_IN", "en_GB", "en", NULL
};
6929 static const char* l4_en_150GB001_
[] = { "en_150", "en_GB", "en_001", "en", NULL
};
6930 static const char* l4_en_AUGB001_
[] = { "en_AU", "en_GB", "en_001", "en", NULL
};
6931 static const char* l1_es
[] = { "es", NULL
};
6932 static const char* l1_Spa
[] = { "Spanish", NULL
};
6933 static const char* l2_es_419_
[] = { "es_419", "es", NULL
};
6934 static const char* l2_es_ES_
[] = { "es_ES", "es", NULL
};
6935 static const char* l2_es_MX_
[] = { "es_MX", "es", NULL
};
6936 static const char* l2_es_MX_Spa
[] = { "es_MX", "Spanish", NULL
};
6937 static const char* l3_es_MX419_
[] = { "es_MX", "es_419", "es", NULL
};
6938 static const char* l1_fi
[] = { "fi", NULL
};
6939 static const char* l1_Fin
[] = { "Finnish", NULL
};
6940 static const char* l1_fil
[] = { "fil", NULL
};
6941 static const char* l1_tl
[] = { "tl", NULL
};
6942 static const char* l1_fr
[] = { "fr", NULL
};
6943 static const char* l1_Fre
[] = { "French", NULL
};
6944 static const char* l2_fr_CA_
[] = { "fr_CA", "fr", NULL
};
6945 static const char* l2_fr_CH_
[] = { "fr_CH", "fr", NULL
};
6946 static const char* l2_fr_FR_
[] = { "fr_FR", "fr", NULL
};
6947 static const char* l1_haw
[] = { "haw", NULL
};
6948 static const char* l1_he
[] = { "he", NULL
};
6949 static const char* l1_hr
[] = { "hr", NULL
};
6950 static const char* l1_hu
[] = { "hu", NULL
};
6951 static const char* l1_id
[] = { "id", NULL
};
6952 static const char* l1_in
[] = { "in", NULL
};
6953 static const char* l1_it
[] = { "it", NULL
};
6954 static const char* l1_Ita
[] = { "Italian", NULL
};
6955 static const char* l1_ja
[] = { "ja", NULL
};
6956 static const char* l1_Japn
[] = { "Japanese", NULL
};
6957 static const char* l1_ko
[] = { "ko", NULL
};
6958 static const char* l1_Kor
[] = { "Korean", NULL
};
6959 static const char* l1_ms
[] = { "ms", NULL
};
6960 static const char* l1_nb
[] = { "nb", NULL
};
6961 static const char* l1_no
[] = { "no", NULL
};
6962 static const char* l1_Nor
[] = { "Norwegian", NULL
};
6963 static const char* l2_no_NO_
[] = { "no_NO", "no", NULL
};
6964 static const char* l1_nl
[] = { "nl", NULL
};
6965 static const char* l1_Dut
[] = { "Dutch", NULL
};
6966 static const char* l2_nl_BE_
[] = { "nl_BE", "nl", NULL
};
6967 static const char* l1_pl
[] = { "pl", NULL
};
6968 static const char* l1_Pol
[] = { "Polish", NULL
};
6969 static const char* l1_pt
[] = { "pt", NULL
};
6970 static const char* l1_pt_PT
[] = { "pt_PT", NULL
};
6971 static const char* l1_Port
[] = { "Portuguese", NULL
};
6972 static const char* l2_pt_BR_
[] = { "pt_BR", "pt", NULL
};
6973 static const char* l2_pt_PT_
[] = { "pt_PT", "pt", NULL
};
6974 static const char* l1_ro
[] = { "ro", NULL
};
6975 static const char* l2_ro_MD_
[] = { "ro_MD", "ro", NULL
};
6976 static const char* l1_mo
[] = { "mo", NULL
};
6977 static const char* l1_ru
[] = { "ru", NULL
};
6978 static const char* l1_Rus
[] = { "Russian", NULL
};
6979 static const char* l1_sk
[] = { "sk", NULL
};
6980 static const char* l1_sr
[] = { "sr", NULL
};
6981 static const char* l1_srLatn
[] = { "sr-Latn", NULL
};
6982 static const char* l1_sv
[] = { "sv", NULL
};
6983 static const char* l1_Swe
[] = { "Swedish", NULL
};
6984 static const char* l1_th
[] = { "th", NULL
};
6985 static const char* l1_Thai
[] = { "Thai", NULL
};
6986 static const char* l1_tlh
[] = { "tlh", NULL
};
6987 static const char* l1_tr
[] = { "tr", NULL
};
6988 static const char* l1_Tur
[] = { "Turkish", NULL
};
6989 static const char* l1_uk
[] = { "uk", NULL
};
6990 static const char* l1_vi
[] = { "vi", NULL
};
6991 static const char* l1_yi
[] = { "yi", NULL
};
6992 static const char* l1_iw
[] = { "iw", NULL
};
6993 static const char* l1_zh_CN
[] = { "zh_CN", NULL
};
6994 static const char* l1_zh_TW
[] = { "zh_TW", NULL
};
6995 static const char* l1_zh_Hans
[] = { "zh_Hans", NULL
};
6996 static const char* l1_zh_Hant
[] = { "zh_Hant", NULL
};
6997 static const char* l1_zhHant
[] = { "zh-Hant", NULL
};
6998 static const char* l2_zh_HKTW
[] = { "zh_HK", "zh_TW", NULL
};
6999 static const char* l2_zh_Hant_HK_
[] = { "zh_Hant_HK", "zh_Hant", NULL
};
7000 static const char* l2_zh_CN_Hans
[] = { "zh_CN", "zh_Hans", NULL
};
7001 static const char* l2_zh_TW_Hant
[] = { "zh_TW", "zh_Hant", NULL
};
7002 static const char* l3_zh_MOHKTW
[] = { "zh_MO", "zh_HK", "zh_TW", NULL
};
7003 static const char* l3_zh_HK_HantHK_Hant
[] = { "zh_HK", "zh_Hant_HK", "zh_Hant", NULL
};
7005 static const LangAndExpLocs appleLangAndLoc
[] = {
7006 // language\ result for appleLocs1 appleLocs2 appleLocs3 appleLocs4 appleLocs5 appleLocs6
7007 { "zh", { l1_zh_CN
, l1_zh_CN
, l1_zh_CN
, l1_zh_Hans
, l1_zh_Hans
, l1_zh_Hans
} },
7008 { "zh-Hans", { l1_zh_CN
, l1_zh_CN
, l1_zh_CN
, l1_zh_Hans
, l1_zh_Hans
, l1_zh_Hans
} },
7009 { "zh-Hant", { l1_zh_TW
, l1_zh_TW
, l1_zh_TW
, l1_zh_Hant
, l1_zh_Hant
, l1_zh_Hant
} },
7010 { "zh-Hans-CN", { l1_zh_CN
, l1_zh_CN
, l1_zh_CN
, l1_zh_Hans
, l2_zh_CN_Hans
, l2_zh_CN_Hans
} },
7011 { "zh-Hans-SG", { l1_zh_CN
, l1_zh_CN
, l1_zh_CN
, l1_zh_Hans
, l1_zh_Hans
, l1_zh_Hans
} },
7012 { "zh-Hant-TW", { l1_zh_TW
, l1_zh_TW
, l1_zh_TW
, l1_zh_Hant
, l2_zh_TW_Hant
, l2_zh_TW_Hant
} },
7013 { "zh-Hant-HK", { l1_zh_TW
, l2_zh_HKTW
, l2_zh_HKTW
, l2_zh_Hant_HK_
, l1_zh_Hant
, l2_zh_Hant_HK_
} },
7014 { "zh-Hant-MO", { l1_zh_TW
, l2_zh_HKTW
, l3_zh_MOHKTW
, l2_zh_Hant_HK_
, l1_zh_Hant
, l2_zh_Hant_HK_
} },
7015 { "zh-Hans-HK", { l1_zh_CN
, l1_zh_CN
, l1_zh_CN
, l1_zh_Hans
, l1_zh_Hans
, l1_zh_Hans
} },
7016 { "zh-CN", { l1_zh_CN
, l1_zh_CN
, l1_zh_CN
, l1_zh_Hans
, l2_zh_CN_Hans
, l2_zh_CN_Hans
} },
7017 { "zh-SG", { l1_zh_CN
, l1_zh_CN
, l1_zh_CN
, l1_zh_Hans
, l1_zh_Hans
, l1_zh_Hans
} },
7018 { "zh-TW", { l1_zh_TW
, l1_zh_TW
, l1_zh_TW
, l1_zh_Hant
, l2_zh_TW_Hant
, l2_zh_TW_Hant
} },
7019 { "zh-HK", { l1_zh_TW
, l2_zh_HKTW
, l2_zh_HKTW
, l2_zh_Hant_HK_
, l1_zh_Hant
, l3_zh_HK_HantHK_Hant
} },
7020 { "zh-MO", { l1_zh_TW
, l2_zh_HKTW
, l3_zh_MOHKTW
, l2_zh_Hant_HK_
, l1_zh_Hant
, l2_zh_Hant_HK_
} },
7021 { "en", { l1_Eng
, l1_en
, l1_en
, l1_en
, l1_en
, l1_en
} },
7022 { "en-US", { l1_Eng
, l1_en
, l1_en
, l2_en_US_
, l1_en
, l1_en
} },
7023 { "en_US", { l1_Eng
, l1_en
, l1_en
, l2_en_US_
, l1_en
, l1_en
} },
7024 { "en-JP", { l1_Eng
, l1_en
, l1_en
, l1_en
, l1_en
, l1_en
} },
7025 { "en-TR", { l1_Eng
, l1_en
, l1_en
, l1_en
, l1_en
, l1_en
} },
7026 { "en-001", { l1_Eng
, l1_en
, l1_en
, l1_en
, l2_en_001_
, l2_en_001_
} },
7027 { "en-CA", { l1_Eng
, l1_en
, l2_en_CA_
, l2_en_CA_
, l2_en_001_
, l2_en_001_
} },
7028 { "en-IL", { l1_Eng
, l1_en
, l1_en
, l1_en
, l2_en_001_
, l2_en_001_
} },
7029 { "en-GB", { l1_Eng
, l2_en_GB_
, l2_en_GB_
, l2_en_GB_
, l3_en_GB001_
, l3_en_GB001_
} },
7030 { "en-IN", { l1_Eng
, l2_en_GB_
, l2_en_GB_
, l3_en_INGB_
, l3_en_GB001_
, l3_en_GB001_
} },
7031 { "en-BD", { l1_Eng
, l2_en_GB_
, l2_en_GB_
, l2_en_GB_
, l3_en_GB001_
, l3_en_GB001_
} },
7032 { "en-GG", { l1_Eng
, l2_en_GB_
, l2_en_GB_
, l2_en_GB_
, l3_en_GB001_
, l3_en_GB001_
} },
7033 { "en-HK", { l1_Eng
, l2_en_GB_
, l2_en_GB_
, l2_en_GB_
, l3_en_GB001_
, l3_en_GB001_
} },
7034 { "en-IE", { l1_Eng
, l2_en_GB_
, l2_en_GB_
, l2_en_GB_
, l3_en_GB001_
, l3_en_GB001_
} },
7035 { "en-JM", { l1_Eng
, l2_en_GB_
, l2_en_GB_
, l2_en_GB_
, l3_en_GB001_
, l3_en_GB001_
} },
7036 { "en-MO", { l1_Eng
, l2_en_GB_
, l2_en_GB_
, l2_en_GB_
, l3_en_GB001_
, l3_en_GB001_
} },
7037 { "en-MT", { l1_Eng
, l2_en_GB_
, l2_en_GB_
, l2_en_GB_
, l3_en_GB001_
, l3_en_GB001_
} },
7038 { "en-PK", { l1_Eng
, l2_en_GB_
, l2_en_GB_
, l2_en_GB_
, l3_en_GB001_
, l3_en_GB001_
} },
7039 { "en-SG", { l1_Eng
, l2_en_GB_
, l2_en_GB_
, l2_en_GB_
, l3_en_GB001_
, l3_en_GB001_
} },
7040 { "en-VG", { l1_Eng
, l2_en_GB_
, l2_en_GB_
, l2_en_GB_
, l3_en_GB001_
, l3_en_GB001_
} },
7041 { "en-ZA", { l1_Eng
, l2_en_GB_
, l2_en_GB_
, l2_en_GB_
, l3_en_GB001_
, l3_en_GB001_
} },
7042 { "en-AU", { l1_Eng
, l3_en_AUGB_
, l3_en_AUGB_
, l3_en_AUGB_
, l4_en_AUGB001_
, l4_en_AUGB001_
} },
7043 { "en-NZ", { l1_Eng
, l3_en_AUGB_
, l3_en_AUGB_
, l3_en_AUGB_
, l4_en_AUGB001_
, l4_en_AUGB001_
} },
7044 { "en-WS", { l1_Eng
, l3_en_AUGB_
, l3_en_AUGB_
, l3_en_AUGB_
, l4_en_AUGB001_
, l4_en_AUGB001_
} },
7045 { "en-150", { l1_Eng
, l2_en_GB_
, l2_en_GB_
, l2_en_GB_
, l3_en_GB001_
, l4_en_150GB001_
} },
7046 { "en-FR", { l1_Eng
, l2_en_GB_
, l2_en_GB_
, l2_en_GB_
, l3_en_GB001_
, l4_en_150GB001_
} },
7047 { "en-BE", { l1_Eng
, l2_en_GB_
, l2_en_GB_
, l2_en_GB_
, l3_en_GB001_
, l4_en_150GB001_
} },
7048 { "en-Latn", { l1_Eng
, l1_en
, l1_en
, l1_en
, l1_en
, l1_en
} },
7049 { "en-Latn-US", { l1_Eng
, l1_en
, l1_en
, l1_en
,/*TODO*/ l1_en
, l1_en
} },
7050 { "en-US-POSIX", { l1_Eng
, l1_en
, l1_en
, l2_en_US_
, l1_en
, l1_en
} },
7051 { "en-Latn-US-POSIX", { l1_Eng
, l1_en
, l1_en
, l1_en
, l1_en
, l1_en
} },
7052 { "en-u-ca-hebrew", { l1_Eng
, l1_en
, l1_en
, l1_en
, l1_en
, l1_en
} },
7053 { "en@calendar=hebrew", { l1_Eng
, l1_en
, l1_en
, l1_en
, l1_en
, l1_en
} },
7054 { "en-", { l1_Eng
, l1_en
, l1_en
, l1_en
, l1_en
, l1_en
} },
7055 { "en_", { l1_Eng
, l1_en
, l1_en
, l1_en
, l1_en
, l1_en
} },
7056 { "es", { l1_Spa
, l1_es
, l1_es
, l1_es
, l1_es
, l1_es
} },
7057 { "es-ES", { l1_Spa
, l1_es
, l1_es
, l1_es
, l2_es_ES_
, l2_es_ES_
} },
7058 { "es-419", { l1_Spa
, l1_es
, l2_es_419_
, l2_es_419_
, l1_es
, l2_es_419_
} },
7059 { "es-MX", { l1_Spa
, l2_es_MX_
, l2_es_419_
, l3_es_MX419_
, l2_es_MX_
, l3_es_MX419_
} },
7060 { "es-AR", { l1_Spa
, l1_es
, l2_es_419_
, l2_es_419_
, l1_es
, l2_es_419_
} },
7061 { "es-BR", { l1_Spa
, l1_es
, l2_es_419_
, l2_es_419_
, l1_es
, l2_es_419_
} },
7062 { "es-BZ", { l1_Spa
, l1_es
, l2_es_419_
, l2_es_419_
, l1_es
, l2_es_419_
} },
7063 { "es-AG", { l1_Spa
, l1_es
, l2_es_419_
, l2_es_419_
, l1_es
, l2_es_419_
} },
7064 { "es-AW", { l1_Spa
, l1_es
, l2_es_419_
, l2_es_419_
, l1_es
, l2_es_419_
} },
7065 { "es-CW", { l1_Spa
, l1_es
, l2_es_419_
, l2_es_419_
, l1_es
, l2_es_419_
} },
7066 { "es-SX", { l1_Spa
, l1_es
, l2_es_419_
, l2_es_419_
, l1_es
, l2_es_419_
} },
7067 { "es-TT", { l1_Spa
, l1_es
, l2_es_419_
, l2_es_419_
, l1_es
, l2_es_419_
} },
7068 { "es-Latn", { l1_Spa
, l1_es
, l1_es
, l1_es
, l1_es
, l1_es
} },
7069 { "es-Latn-MX", { l1_Spa
, l1_es
, l1_es
, l1_es
, l1_es
, l1_es
} },
7070 { "pt", { l1_Port
, l1_pt
, l1_pt
, l1_pt
, NULL
, NULL
} },
7071 { "pt-BR", { l1_Port
, l1_pt
, l2_pt_BR_
, l2_pt_BR_
, NULL
, NULL
} },
7072 { "pt-PT", { l1_Port
, l2_pt_PT_
, l2_pt_PT_
, l1_pt
, NULL
, NULL
} },
7073 { "pt-MO", { l1_Port
, l2_pt_PT_
, l2_pt_PT_
, l1_pt
, NULL
, NULL
} },
7074 { "pt-CH", { l1_Port
, l2_pt_PT_
, l2_pt_PT_
, l1_pt
, NULL
, NULL
} },
7075 { "pt-FR", { l1_Port
, l2_pt_PT_
, l2_pt_PT_
, l1_pt
, NULL
, NULL
} },
7076 { "pt-GQ", { l1_Port
, l2_pt_PT_
, l2_pt_PT_
, l1_pt
, NULL
, NULL
} },
7077 { "pt-LU", { l1_Port
, l2_pt_PT_
, l2_pt_PT_
, l1_pt
, NULL
, NULL
} },
7078 { "fr", { l1_Fre
, l1_fr
, l1_fr
, l1_fr
, NULL
, NULL
} },
7079 { "fr-FR", { l1_Fre
, l1_fr
, l2_fr_FR_
, l2_fr_FR_
, NULL
, NULL
} },
7080 { "fr-CA", { l1_Fre
, l2_fr_CA_
, l2_fr_CA_
, l2_fr_CA_
, NULL
, NULL
} },
7081 { "fr-CH", { l1_Fre
, l1_fr
, l1_fr
, l2_fr_CH_
, NULL
, NULL
} },
7082 { "ar", { l1_Ara
, l1_ar
, l1_ar
, NULL
, NULL
, NULL
} },
7083 { "da", { l1_Dan
, l1_da
, l1_da
, NULL
, NULL
, NULL
} },
7084 { "nl", { l1_Dut
, l1_nl
, l1_nl
, l1_nl
, NULL
, NULL
} },
7085 { "nl-BE", { l1_Dut
, l1_nl
, l1_nl
, l2_nl_BE_
, NULL
, NULL
} },
7086 { "fi", { l1_Fin
, l1_fi
, l1_fi
, NULL
, NULL
, NULL
} },
7087 { "de", { l1_Ger
, l1_de
, l1_de
, NULL
, NULL
, NULL
} },
7088 { "it", { l1_Ita
, l1_it
, l1_it
, NULL
, NULL
, NULL
} },
7089 { "ja", { l1_Japn
, l1_ja
, l1_ja
, NULL
, NULL
, NULL
} },
7090 { "ko", { l1_Kor
, l1_ko
, l1_ko
, NULL
, NULL
, NULL
} },
7091 { "nb", { l1_Nor
, l1_no
, l1_nb
, NULL
, NULL
, NULL
} },
7092 { "no", { l1_Nor
, l1_no
, l1_nb
, NULL
, NULL
, NULL
} },
7093 { "pl", { l1_Pol
, l1_pl
, l1_pl
, NULL
, NULL
, NULL
} },
7094 { "ru", { l1_Rus
, l1_ru
, l1_ru
, NULL
, NULL
, NULL
} },
7095 { "sv", { l1_Swe
, l1_sv
, l1_sv
, NULL
, NULL
, NULL
} },
7096 { "th", { l1_Thai
, l1_th
, l1_th
, NULL
, NULL
, NULL
} },
7097 { "tr", { l1_Tur
, l1_tr
, l1_tr
, NULL
, NULL
, NULL
} },
7098 { "ca", { l1_ca
, l1_ca
, l1_ca
, NULL
, NULL
, NULL
} },
7099 { "cs", { l1_cs
, l1_cs
, l1_cs
, NULL
, NULL
, NULL
} },
7100 { "el", { l1_el
, l1_el
, l1_el
, NULL
, NULL
, NULL
} },
7101 { "he", { l1_he
, l1_he
, l1_he
, NULL
, NULL
, l1_iw
} },
7102 { "iw", { l1_he
, l1_he
, l1_he
, NULL
, NULL
, l1_iw
} },
7103 { "hr", { l1_hr
, l1_hr
, l1_hr
, NULL
, NULL
, NULL
} },
7104 { "hu", { l1_hu
, l1_hu
, l1_hu
, NULL
, NULL
, NULL
} },
7105 { "id", { l1_id
, l1_id
, l1_id
, NULL
, NULL
, l1_in
} },
7106 { "in", { l1_id
, l1_id
, l1_id
, NULL
, NULL
, l1_in
} },
7107 { "ms", { l1_ms
, l1_ms
, l1_ms
, NULL
, NULL
, NULL
} },
7108 { "ro", { l1_ro
, l1_ro
, l1_ro
, l1_ro
, NULL
, l1_mo
} },
7109 { "mo", { l1_ro
, l1_ro
, l1_ro
, l2_ro_MD_
, NULL
, l1_mo
} },
7110 { "sk", { l1_sk
, l1_sk
, l1_sk
, NULL
, NULL
, NULL
} },
7111 { "uk", { l1_uk
, l1_uk
, l1_uk
, NULL
, NULL
, NULL
} },
7112 { "vi", { l1_vi
, l1_vi
, l1_vi
, NULL
, NULL
, NULL
} },
7113 { "yi", { NULL
, NULL
, NULL
, NULL
, l1_yi
, NULL
} },
7114 { "ji", { NULL
, NULL
, NULL
, NULL
, l1_yi
, NULL
} },
7115 { "fil", { NULL
, NULL
, NULL
, NULL
, l1_fil
, l1_tl
} },
7116 { "tl", { NULL
, NULL
, NULL
, NULL
, l1_fil
, l1_tl
} },
7117 { "haw", { NULL
, NULL
, NULL
, NULL
, l1_haw
, NULL
} },
7118 { "sr", { NULL
, NULL
, NULL
, NULL
, l1_sr
, NULL
} },
7119 { "sr-Cyrl", { NULL
, NULL
, NULL
, NULL
, l1_sr
, NULL
} },
7120 { "sr-Latn", { NULL
, NULL
, NULL
, NULL
, l1_srLatn
, NULL
} },
7121 { "tlh", { NULL
, NULL
, NULL
, NULL
, l1_tlh
, NULL
} },
7122 { "Default@2x", { NULL
, NULL
, NULL
, NULL
, NULL
, NULL
} },
7123 { "default", { NULL
, NULL
, NULL
, NULL
, NULL
, NULL
} },
7124 { "root", { NULL
, NULL
, NULL
, NULL
, NULL
, NULL
} },
7125 { "", { NULL
, NULL
, NULL
, NULL
, NULL
, NULL
} },
7126 { "_US", { NULL
, NULL
, NULL
, NULL
, NULL
, NULL
} },
7127 { "-US", { NULL
, NULL
, NULL
, NULL
, NULL
, NULL
} },
7128 { "-u-ca-hebrew", { NULL
, NULL
, NULL
, NULL
, NULL
, NULL
} },
7129 { "-u-ca-hebrew", { NULL
, NULL
, NULL
, NULL
, NULL
, NULL
} },
7130 { "@calendar=hebrew", { NULL
, NULL
, NULL
, NULL
, NULL
, NULL
} },
7132 enum { kNumAppleLangAndLoc
= UPRV_LENGTHOF(appleLangAndLoc
) };
7134 /* tests from <rdar://problem/21518031> */
7136 static const char * appleLocsA1
[] = { "en", "fr", "no", "zh-Hant" };
7137 static const char * appleLocsA2
[] = { "en", "fr", "nb", "zh_TW", "zh_CN", "zh-Hant" };
7138 static const char * appleLocsA3
[] = { "en", "en_IN", "en_GB", "fr", "de", "zh_TW" };
7139 static const char * appleLocsA4
[] = { "Spanish", "es_MX", "English", "en_GB" };
7140 static const char * appleLocsA5
[] = { "en", "fr", "de", "pt", "pt_PT" };
7141 static const char * appleLocsA6
[] = { "en", "no", "no_NO", "pt_PT" };
7143 static const AppleLocsAndCount locAndCountEntriesA
[kNumLocSets
] = {
7144 { appleLocsA1
, UPRV_LENGTHOF(appleLocsA1
) },
7145 { appleLocsA2
, UPRV_LENGTHOF(appleLocsA2
) },
7146 { appleLocsA3
, UPRV_LENGTHOF(appleLocsA3
) },
7147 { appleLocsA4
, UPRV_LENGTHOF(appleLocsA4
) },
7148 { appleLocsA5
, UPRV_LENGTHOF(appleLocsA5
) },
7149 { appleLocsA6
, UPRV_LENGTHOF(appleLocsA6
) },
7152 static const LangAndExpLocs appleLangAndLocA
[] = {
7153 // language\ result for appleLocsA1 appleLocsA2 appleLocsA3 appleLocsA4 appleLocsA5 appleLocsA6
7154 { "zh-Hant", { l1_zhHant
,/*0*/ l1_zhHant
,/*zh_TW*/ l1_zh_TW
, NULL
, NULL
, NULL
} },
7155 { "zh_Hant", { l1_zhHant
, l1_zhHant
,/*zh_TW*/ l1_zh_TW
, NULL
, NULL
, NULL
} },
7156 { "zh_HK", { l1_zhHant
, l1_zhHant
,/*zh_TW*/ l1_zh_TW
, NULL
, NULL
, NULL
} },
7157 { "en_IN", { l1_en
, l1_en
, l3_en_INGB_
, l2_en_GB_Eng
, l1_en
, l1_en
} },
7158 { "es_MX", { NULL
, NULL
, NULL
, l2_es_MX_Spa
, NULL
, NULL
} },
7159 { "pt_PT", { NULL
, NULL
, NULL
, NULL
, l2_pt_PT_
, l1_pt_PT
} },
7160 { "pt", { NULL
, NULL
, NULL
, NULL
, l1_pt
, l1_pt_PT
} },
7161 { "no", { l1_no
, l1_nb
, NULL
, NULL
, NULL
, l1_no
} },
7162 { "no_NO", { l1_no
, l1_nb
, NULL
, NULL
, NULL
, l2_no_NO_
} },
7163 { "nb", { l1_no
, l1_nb
, NULL
, NULL
, NULL
, l1_no
} },
7164 { "nb_NO", { l1_no
, l1_nb
, NULL
, NULL
, NULL
, l2_no_NO_
} },
7166 enum { kNumAppleLangAndLocA
= UPRV_LENGTHOF(appleLangAndLocA
) };
7168 /* tests from log attached to 21682790 */
7170 static const char * appleLocsB1
[] = {
7171 "ar", "Base", "ca", "cs",
7172 "da", "Dutch", "el", "English",
7173 "es_MX", "fi", "French", "German",
7174 "he", "hr", "hu", "id",
7175 "Italian", "Japanese", "ko", "ms",
7176 "no", "pl", "pt", "pt_PT",
7177 "ro", "ru", "sk", "Spanish",
7178 "sv", "th", "tr", "uk",
7179 "vi", "zh_CN", "zh_TW"
7182 static const char * appleLocsB2
[] = {
7184 "da", "Dutch", "el", "English",
7185 "es_MX", "fi", "French", "German",
7186 "he", "hr", "hu", "id",
7187 "Italian", "Japanese", "ko", "ms",
7188 "no", "pl", "pt", "pt_PT",
7189 "ro", "ru", "sk", "Spanish",
7190 "sv", "th", "tr", "uk",
7191 "vi", "zh_CN", "zh_TW"
7194 static const char * appleLocsB3
[] = {
7195 "ar", "ca", "cs", "da",
7196 "de", "el", "en", "es",
7197 "es_MX", "fi", "French", "he",
7198 "hr", "hu", "id", "Italian",
7199 "ja", "ko", "ms", "nl",
7200 "no", "pl", "pt", "pt_PT",
7201 "ro", "ru", "sk", "sv",
7202 "th", "tr", "uk", "vi",
7206 static const char * appleLocsB4
[] = {
7207 "ar", "ca", "cs", "da",
7208 "de", "el", "en", "es",
7209 "es_MX", "fi", "fr", "he",
7210 "hr", "hu", "id", "it",
7211 "ja", "ko", "ms", "nl",
7212 "no", "pl", "pt", "pt_PT",
7213 "ro", "ru", "sk", "sv",
7214 "th", "tr", "uk", "vi",
7218 static const char * appleLocsB5
[] = { "en" };
7220 static const char * appleLocsB6
[] = { "English" };
7222 static const AppleLocsAndCount locAndCountEntriesB
[kNumLocSets
] = {
7223 { appleLocsB1
, UPRV_LENGTHOF(appleLocsB1
) },
7224 { appleLocsB2
, UPRV_LENGTHOF(appleLocsB2
) },
7225 { appleLocsB3
, UPRV_LENGTHOF(appleLocsB3
) },
7226 { appleLocsB4
, UPRV_LENGTHOF(appleLocsB4
) },
7227 { appleLocsB5
, UPRV_LENGTHOF(appleLocsB5
) },
7228 { appleLocsB6
, UPRV_LENGTHOF(appleLocsB6
) },
7231 static const LangAndExpLocs appleLangAndLocB
[] = {
7232 // language\ result for appleLocsB1 appleLocsB2 appleLocsB3 appleLocsB4 appleLocsB5 appleLocsB6
7233 // Prefs 1, logged with sets B1-B3
7234 { "en", { l1_Eng
, l1_Eng
, l1_en
, l1_en
, l1_en
, l1_Eng
} },
7235 { "es", { l1_Spa
, l1_Spa
, l1_es
, l1_es
, NULL
, NULL
} },
7236 // Prefs 2, logged with sets B1-B6
7237 { "English", { l1_Eng
, l1_Eng
, l1_en
, l1_en
, l1_en
, l1_Eng
} },
7238 { "Spanish", { l1_Spa
, l1_Spa
, l1_es
, l1_es
, NULL
, NULL
} },
7240 enum { kNumAppleLangAndLocB
= UPRV_LENGTHOF(appleLangAndLocB
) };
7243 const AppleLocsAndCount
* locAndCountEntriesPtr
;
7244 const LangAndExpLocs
* appleLangAndLocPtr
;
7245 int32_t appleLangAndLocCount
;
7246 } AppleLocToUseTestSet
;
7248 static const AppleLocToUseTestSet altuTestSets
[] = {
7249 { locAndCountEntries
, appleLangAndLoc
, kNumAppleLangAndLoc
},
7250 { locAndCountEntriesA
, appleLangAndLocA
, kNumAppleLangAndLocA
},
7251 { locAndCountEntriesB
, appleLangAndLocB
, kNumAppleLangAndLocB
},
7255 /* tests for multiple prefs sets */
7257 static const char * appleLocsM1
[] = { "en", "en_GB", "pt", "pt_PT", "zh_CN", "zh_Hant" };
7258 static const char * prefLangsM1
[] = { "tlh", "zh_HK", "zh_SG", "zh_Hans", "pt_BR", "pt_PT", "en_IN", "en" };
7259 static const char * locsToUseM1
[] = { "zh_Hant" };
7261 // Tests from first pass at <rdar://problem/22012864>, 2015-11-18
7263 static const char * appleLocsM2
[] = { "fr-FR", "en-US", "en-GB" };
7264 static const char * prefLangsM2
[] = { "fr-CH" };
7265 static const char * locsToUseM2
[] = { "fr-FR" };
7267 static const char * appleLocsM3
[] = { "es-es", "fr-fr" };
7268 static const char * prefLangsM3
[] = { "fr-US", "fr", "en-US" };
7269 static const char * locsToUseM3
[] = { "fr-fr" };
7271 static const char * appleLocsM4
[] = { "es-es", "fr-fr", "fr" };
7272 static const char * prefLangsM4
[] = { "fr-US", "fr", "en-US" };
7273 static const char * locsToUseM4
[] = { "fr" };
7275 // Tests from second pass at <rdar://problem/22012864>, 2015-12-08
7277 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" };
7278 static const char * prefLangsM5
[] = { "fr-US", "en-US" };
7279 static const char * locsToUseM5
[] = { "fr-FR" };
7280 // Per Peter E; expected result changed from "en-US" to "de-CH" per <rdar://problem/26559053>
7281 static const char * appleLocsM6
[] = { "de-CH", "en-US" };
7282 static const char * prefLangsM6
[] = { "de-DE", "en-US" };
7283 static const char * locsToUseM6
[] = { "de-CH" };
7284 // The following is used for M7-MD
7285 static const char * appleLocsMx
[] = { "de-DE", "en-AU", "es-ES", "fr-FR", "hi-IN", "pt-BR", "zh-HK", "zh-TW" };
7287 static const char * prefLangsM7
[] = { "fr-ES", "en-AU" };
7288 static const char * locsToUseM7
[] = { "fr-FR" };
7290 static const char * prefLangsM8
[] = { "de-IT", "en-AU" };
7291 static const char * locsToUseM8
[] = { "de-DE" };
7293 static const char * prefLangsM9
[] = { "hi-US", "en-AU" };
7294 static const char * locsToUseM9
[] = { "hi-IN" };
7296 static const char * prefLangsMA
[] = { "en-IN", "zh-HK" };
7297 static const char * locsToUseMA
[] = { "en-AU" };
7299 static const char * prefLangsMB
[] = { "pt-PT", "en-AU" };
7300 static const char * locsToUseMB
[] = { "en-AU" };
7302 static const char * prefLangsMC
[] = { "pt-PT", "ar" };
7303 static const char * locsToUseMC
[] = { "pt-BR" };
7305 static const char * prefLangsMD
[] = { "zh-CN", "en-AU" };
7306 static const char * locsToUseMD
[] = { "en-AU" };
7308 static const char * appleLocsME
[] = { "de-DE", "en-AU", "es-ES", "fr-FR", "hi-IN", "pt-BR", "zh-CN", "zh-HK" };
7309 static const char * prefLangsME
[] = { "zh-TW", "en-AU" };
7310 static const char * locsToUseME
[] = { "zh-HK" };
7311 // Per Peter E in diagnosis for <rdar://problem/22012864> and <rdar://problem/23815194>
7312 static const char * appleLocsMF
[] = { "en", "en-GB", "fr", "es" };
7313 static const char * prefLangsMF
[] = { "en-IN", "en-GB", "de", "fr" };
7314 static const char * locsToUseMF
[] = { "en-GB", "en" };
7315 // Per Karan M in <rdar://problem/23982460>
7316 static const char * appleLocsMG
[] = { "zh-Hans", "zh-Hant", "zh-HK" };
7317 static const char * prefLangsMG
[] = { "zh-Hans-US", "zh-HK", "en-US" };
7318 static const char * locsToUseMG
[] = { "zh-Hans" };
7319 // Per <rdar://problem/25903891>
7320 static const char * appleLocsMH
[] = { "zh-TW", "zh-CN", "zh-HK" };
7321 static const char * prefLangsMH
[] = { "zh-Hans-HK", "zh-HK", "en" };
7322 static const char * locsToUseMH
[] = { "zh-CN" };
7323 // Per <rdar://problem/26559053>
7324 static const char * appleLocsMI
[] = { "unk", "en-US", "ar-SA" };
7325 static const char * prefLangsMI
[] = { "ar-US" };
7326 static const char * locsToUseMI
[] = { "ar-SA" };
7327 // Per <rdar://problem/30501523> - first for comparison with zh, then real test
7328 static const char * appleLocsMJ
[] = { "zh-CN", "en-US" };
7329 static const char * prefLangsMJ
[] = { "zh", "zh_AC" };
7330 static const char * locsToUseMJ
[] = { "zh-CN" };
7331 static const char * appleLocsMK
[] = { "yue-CN", "en-US" };
7332 static const char * prefLangsMK
[] = { "yue", "yue_AC" };
7333 static const char * locsToUseMK
[] = { "yue-CN" };
7334 // Per <rdar://problem/30433534>
7335 static const char * appleLocsML
[] = { "nl_NL", "es_MX", "fr_FR", "zh_TW", "it_IT", "vi_VN", "fr_CH", "es_CL",
7336 "en_ZA", "ko_KR", "ca_ES", "ro_RO", "en_PH", "en_CA", "en_SG", "en_IN",
7337 "en_NZ", "it_CH", "fr_CA", "da_DK", "de_AT", "pt_BR", "yue_CN", "zh_CN",
7338 "sv_SE", "es_ES", "ar_SA", "hu_HU", "fr_BE", "en_GB", "ja_JP", "zh_HK",
7339 "fi_FI", "tr_TR", "nb_NO", "en_ID", "en_SA", "pl_PL", "ms_MY", "cs_CZ",
7340 "el_GR", "id_ID", "hr_HR", "en_AE", "he_IL", "ru_RU", "wuu_CN", "de_DE",
7341 "de_CH", "en_AU", "nl_BE", "th_TH", "pt_PT", "sk_SK", "en_US", "en_IE",
7342 "es_CO", "uk_UA", "es_US" };
7343 static const char * prefLangsML
[] = { "en-JP" };
7344 static const char * locsToUseML
[] = { "en_US" };
7345 // Per <rdar://problem/32421203>
7346 static const char * appleLocsMM1
[] = { "pt-PT" };
7347 static const char * appleLocsMM2
[] = { "pt-BR" };
7348 static const char * appleLocsMM3
[] = { "pt-PT", "pt-BR" };
7349 static const char * appleLocsMM4
[] = { "en", "pt-PT" };
7350 static const char * appleLocsMM5
[] = { "en", "pt-BR" };
7351 static const char * appleLocsMM6
[] = { "en", "pt-PT", "pt-BR" };
7352 static const char * prefLangsMM1
[] = { "pt-PT" };
7353 static const char * prefLangsMM2
[] = { "pt-BR" };
7354 static const char * prefLangsMM3
[] = { "pt" };
7355 static const char * prefLangsMM4
[] = { "pt-PT", "en" };
7356 static const char * prefLangsMM5
[] = { "pt-BR", "en" };
7357 static const char * prefLangsMM6
[] = { "pt", "en" };
7358 static const char * locsToUseMMptPT
[] = { "pt-PT" };
7359 static const char * locsToUseMMptBR
[] = { "pt-BR" };
7360 static const char * locsToUseMMen
[] = { "en" };
7361 // Per <rdar://problem/32658828>
7362 static const char * appleLocsMN
[] = { "en-US", "en-GB" };
7363 static const char * prefLangsMN1
[] = { "en-KR" };
7364 static const char * prefLangsMN2
[] = { "en-SA" };
7365 static const char * prefLangsMN3
[] = { "en-TW" };
7366 static const char * prefLangsMN4
[] = { "en-JP" };
7367 static const char * locsToUseMN_U
[] = { "en-US" };
7371 const char ** availLocs
;
7372 int32_t availLocsCount
;
7373 const char ** prefLangs
;
7374 int32_t prefLangsCount
;
7375 const char ** locsToUse
;
7376 int32_t locsToUseCount
;
7379 static const MultiPrefTest multiTestSets
[] = {
7380 { "M1", appleLocsM1
, UPRV_LENGTHOF(appleLocsM1
), prefLangsM1
, UPRV_LENGTHOF(prefLangsM1
), locsToUseM1
, UPRV_LENGTHOF(locsToUseM1
) },
7382 { "M2", appleLocsM2
, UPRV_LENGTHOF(appleLocsM2
), prefLangsM2
, UPRV_LENGTHOF(prefLangsM2
), locsToUseM2
, UPRV_LENGTHOF(locsToUseM2
) },
7383 { "M3", appleLocsM3
, UPRV_LENGTHOF(appleLocsM3
), prefLangsM3
, UPRV_LENGTHOF(prefLangsM3
), locsToUseM3
, UPRV_LENGTHOF(locsToUseM3
) },
7384 { "M4", appleLocsM4
, UPRV_LENGTHOF(appleLocsM4
), prefLangsM4
, UPRV_LENGTHOF(prefLangsM4
), locsToUseM4
, UPRV_LENGTHOF(locsToUseM4
) },
7386 { "M5", appleLocsM5
, UPRV_LENGTHOF(appleLocsM5
), prefLangsM5
, UPRV_LENGTHOF(prefLangsM5
), locsToUseM5
, UPRV_LENGTHOF(locsToUseM5
) },
7387 { "M6", appleLocsM6
, UPRV_LENGTHOF(appleLocsM6
), prefLangsM6
, UPRV_LENGTHOF(prefLangsM6
), locsToUseM6
, UPRV_LENGTHOF(locsToUseM6
) },
7388 { "M7", appleLocsMx
, UPRV_LENGTHOF(appleLocsMx
), prefLangsM7
, UPRV_LENGTHOF(prefLangsM7
), locsToUseM7
, UPRV_LENGTHOF(locsToUseM7
) },
7389 { "M8", appleLocsMx
, UPRV_LENGTHOF(appleLocsMx
), prefLangsM8
, UPRV_LENGTHOF(prefLangsM8
), locsToUseM8
, UPRV_LENGTHOF(locsToUseM8
) },
7390 { "M9", appleLocsMx
, UPRV_LENGTHOF(appleLocsMx
), prefLangsM9
, UPRV_LENGTHOF(prefLangsM9
), locsToUseM9
, UPRV_LENGTHOF(locsToUseM9
) },
7391 { "MA", appleLocsMx
, UPRV_LENGTHOF(appleLocsMx
), prefLangsMA
, UPRV_LENGTHOF(prefLangsMA
), locsToUseMA
, UPRV_LENGTHOF(locsToUseMA
) },
7392 { "MB", appleLocsMx
, UPRV_LENGTHOF(appleLocsMx
), prefLangsMB
, UPRV_LENGTHOF(prefLangsMB
), locsToUseMB
, UPRV_LENGTHOF(locsToUseMB
) },
7393 { "MC", appleLocsMx
, UPRV_LENGTHOF(appleLocsMx
), prefLangsMC
, UPRV_LENGTHOF(prefLangsMC
), locsToUseMC
, UPRV_LENGTHOF(locsToUseMC
) },
7394 { "MD", appleLocsMx
, UPRV_LENGTHOF(appleLocsMx
), prefLangsMD
, UPRV_LENGTHOF(prefLangsMD
), locsToUseMD
, UPRV_LENGTHOF(locsToUseMD
) },
7395 { "ME", appleLocsME
, UPRV_LENGTHOF(appleLocsME
), prefLangsME
, UPRV_LENGTHOF(prefLangsME
), locsToUseME
, UPRV_LENGTHOF(locsToUseME
) },
7396 { "MF", appleLocsMF
, UPRV_LENGTHOF(appleLocsMF
), prefLangsMF
, UPRV_LENGTHOF(prefLangsMF
), locsToUseMF
, UPRV_LENGTHOF(locsToUseMF
) },
7397 { "MG", appleLocsMG
, UPRV_LENGTHOF(appleLocsMG
), prefLangsMG
, UPRV_LENGTHOF(prefLangsMG
), locsToUseMG
, UPRV_LENGTHOF(locsToUseMG
) },
7398 { "MH", appleLocsMH
, UPRV_LENGTHOF(appleLocsMH
), prefLangsMH
, UPRV_LENGTHOF(prefLangsMH
), locsToUseMH
, UPRV_LENGTHOF(locsToUseMH
) },
7399 { "MI", appleLocsMI
, UPRV_LENGTHOF(appleLocsMI
), prefLangsMI
, UPRV_LENGTHOF(prefLangsMI
), locsToUseMI
, UPRV_LENGTHOF(locsToUseMI
) },
7400 { "MJ", appleLocsMJ
, UPRV_LENGTHOF(appleLocsMJ
), prefLangsMJ
, UPRV_LENGTHOF(prefLangsMJ
), locsToUseMJ
, UPRV_LENGTHOF(locsToUseMJ
) },
7401 { "MK", appleLocsMK
, UPRV_LENGTHOF(appleLocsMK
), prefLangsMK
, UPRV_LENGTHOF(prefLangsMK
), locsToUseMK
, UPRV_LENGTHOF(locsToUseMK
) },
7402 { "ML", appleLocsML
, UPRV_LENGTHOF(appleLocsML
), prefLangsML
, UPRV_LENGTHOF(prefLangsML
), locsToUseML
, UPRV_LENGTHOF(locsToUseML
) },
7403 { "MM11", appleLocsMM1
, UPRV_LENGTHOF(appleLocsMM1
), prefLangsMM1
, UPRV_LENGTHOF(prefLangsMM1
), locsToUseMMptPT
, UPRV_LENGTHOF(locsToUseMMptPT
) },
7404 { "MM21", appleLocsMM2
, UPRV_LENGTHOF(appleLocsMM2
), prefLangsMM1
, UPRV_LENGTHOF(prefLangsMM1
), locsToUseMMptBR
, UPRV_LENGTHOF(locsToUseMMptBR
) },
7405 { "MM31", appleLocsMM3
, UPRV_LENGTHOF(appleLocsMM3
), prefLangsMM1
, UPRV_LENGTHOF(prefLangsMM1
), locsToUseMMptPT
, UPRV_LENGTHOF(locsToUseMMptPT
) },
7406 { "MM41", appleLocsMM4
, UPRV_LENGTHOF(appleLocsMM4
), prefLangsMM1
, UPRV_LENGTHOF(prefLangsMM1
), locsToUseMMptPT
, UPRV_LENGTHOF(locsToUseMMptPT
) },
7407 { "MM51", appleLocsMM5
, UPRV_LENGTHOF(appleLocsMM5
), prefLangsMM1
, UPRV_LENGTHOF(prefLangsMM1
), locsToUseMMptBR
, UPRV_LENGTHOF(locsToUseMMptBR
) },
7408 { "MM61", appleLocsMM6
, UPRV_LENGTHOF(appleLocsMM6
), prefLangsMM1
, UPRV_LENGTHOF(prefLangsMM1
), locsToUseMMptPT
, UPRV_LENGTHOF(locsToUseMMptPT
) },
7409 { "MM12", appleLocsMM1
, UPRV_LENGTHOF(appleLocsMM1
), prefLangsMM2
, UPRV_LENGTHOF(prefLangsMM2
), locsToUseMMptPT
, UPRV_LENGTHOF(locsToUseMMptPT
) },
7410 { "MM22", appleLocsMM2
, UPRV_LENGTHOF(appleLocsMM2
), prefLangsMM2
, UPRV_LENGTHOF(prefLangsMM2
), locsToUseMMptBR
, UPRV_LENGTHOF(locsToUseMMptBR
) },
7411 { "MM32", appleLocsMM3
, UPRV_LENGTHOF(appleLocsMM3
), prefLangsMM2
, UPRV_LENGTHOF(prefLangsMM2
), locsToUseMMptBR
, UPRV_LENGTHOF(locsToUseMMptBR
) },
7412 { "MM42", appleLocsMM4
, UPRV_LENGTHOF(appleLocsMM4
), prefLangsMM2
, UPRV_LENGTHOF(prefLangsMM2
), locsToUseMMptPT
, UPRV_LENGTHOF(locsToUseMMptPT
) },
7413 { "MM52", appleLocsMM5
, UPRV_LENGTHOF(appleLocsMM5
), prefLangsMM2
, UPRV_LENGTHOF(prefLangsMM2
), locsToUseMMptBR
, UPRV_LENGTHOF(locsToUseMMptBR
) },
7414 { "MM62", appleLocsMM6
, UPRV_LENGTHOF(appleLocsMM6
), prefLangsMM2
, UPRV_LENGTHOF(prefLangsMM2
), locsToUseMMptBR
, UPRV_LENGTHOF(locsToUseMMptBR
) },
7415 { "MM13", appleLocsMM1
, UPRV_LENGTHOF(appleLocsMM1
), prefLangsMM3
, UPRV_LENGTHOF(prefLangsMM3
), locsToUseMMptPT
, UPRV_LENGTHOF(locsToUseMMptPT
) },
7416 { "MM23", appleLocsMM2
, UPRV_LENGTHOF(appleLocsMM2
), prefLangsMM3
, UPRV_LENGTHOF(prefLangsMM3
), locsToUseMMptBR
, UPRV_LENGTHOF(locsToUseMMptBR
) },
7417 { "MM33", appleLocsMM3
, UPRV_LENGTHOF(appleLocsMM3
), prefLangsMM3
, UPRV_LENGTHOF(prefLangsMM3
), locsToUseMMptBR
, UPRV_LENGTHOF(locsToUseMMptBR
) },
7418 { "MM43", appleLocsMM4
, UPRV_LENGTHOF(appleLocsMM4
), prefLangsMM3
, UPRV_LENGTHOF(prefLangsMM3
), locsToUseMMptPT
, UPRV_LENGTHOF(locsToUseMMptPT
) },
7419 { "MM53", appleLocsMM5
, UPRV_LENGTHOF(appleLocsMM5
), prefLangsMM3
, UPRV_LENGTHOF(prefLangsMM3
), locsToUseMMptBR
, UPRV_LENGTHOF(locsToUseMMptBR
) },
7420 { "MM63", appleLocsMM6
, UPRV_LENGTHOF(appleLocsMM6
), prefLangsMM3
, UPRV_LENGTHOF(prefLangsMM3
), locsToUseMMptBR
, UPRV_LENGTHOF(locsToUseMMptBR
) },
7421 { "MM14", appleLocsMM1
, UPRV_LENGTHOF(appleLocsMM1
), prefLangsMM4
, UPRV_LENGTHOF(prefLangsMM4
), locsToUseMMptPT
, UPRV_LENGTHOF(locsToUseMMptPT
) },
7422 { "MM24", appleLocsMM2
, UPRV_LENGTHOF(appleLocsMM2
), prefLangsMM4
, UPRV_LENGTHOF(prefLangsMM4
), locsToUseMMptBR
, UPRV_LENGTHOF(locsToUseMMptBR
) },
7423 { "MM34", appleLocsMM3
, UPRV_LENGTHOF(appleLocsMM3
), prefLangsMM4
, UPRV_LENGTHOF(prefLangsMM4
), locsToUseMMptPT
, UPRV_LENGTHOF(locsToUseMMptPT
) },
7424 { "MM44", appleLocsMM4
, UPRV_LENGTHOF(appleLocsMM4
), prefLangsMM4
, UPRV_LENGTHOF(prefLangsMM4
), locsToUseMMptPT
, UPRV_LENGTHOF(locsToUseMMptPT
) },
7425 { "MM54", appleLocsMM5
, UPRV_LENGTHOF(appleLocsMM5
), prefLangsMM4
, UPRV_LENGTHOF(prefLangsMM4
), locsToUseMMen
, UPRV_LENGTHOF(locsToUseMMen
) }, // want en, see <rdar://problem/22012864>
7426 { "MM64", appleLocsMM6
, UPRV_LENGTHOF(appleLocsMM6
), prefLangsMM4
, UPRV_LENGTHOF(prefLangsMM4
), locsToUseMMptPT
, UPRV_LENGTHOF(locsToUseMMptPT
) },
7427 { "MM15", appleLocsMM1
, UPRV_LENGTHOF(appleLocsMM1
), prefLangsMM5
, UPRV_LENGTHOF(prefLangsMM5
), locsToUseMMptPT
, UPRV_LENGTHOF(locsToUseMMptPT
) },
7428 { "MM25", appleLocsMM2
, UPRV_LENGTHOF(appleLocsMM2
), prefLangsMM5
, UPRV_LENGTHOF(prefLangsMM5
), locsToUseMMptBR
, UPRV_LENGTHOF(locsToUseMMptBR
) },
7429 { "MM35", appleLocsMM3
, UPRV_LENGTHOF(appleLocsMM3
), prefLangsMM5
, UPRV_LENGTHOF(prefLangsMM5
), locsToUseMMptBR
, UPRV_LENGTHOF(locsToUseMMptBR
) },
7430 { "MM45", appleLocsMM4
, UPRV_LENGTHOF(appleLocsMM4
), prefLangsMM5
, UPRV_LENGTHOF(prefLangsMM5
), locsToUseMMptPT
, UPRV_LENGTHOF(locsToUseMMptPT
) },
7431 { "MM55", appleLocsMM5
, UPRV_LENGTHOF(appleLocsMM5
), prefLangsMM5
, UPRV_LENGTHOF(prefLangsMM5
), locsToUseMMptBR
, UPRV_LENGTHOF(locsToUseMMptBR
) },
7432 { "MM65", appleLocsMM6
, UPRV_LENGTHOF(appleLocsMM6
), prefLangsMM5
, UPRV_LENGTHOF(prefLangsMM5
), locsToUseMMptBR
, UPRV_LENGTHOF(locsToUseMMptBR
) },
7433 { "MM16", appleLocsMM1
, UPRV_LENGTHOF(appleLocsMM1
), prefLangsMM6
, UPRV_LENGTHOF(prefLangsMM6
), locsToUseMMptPT
, UPRV_LENGTHOF(locsToUseMMptPT
) },
7434 { "MM26", appleLocsMM2
, UPRV_LENGTHOF(appleLocsMM2
), prefLangsMM6
, UPRV_LENGTHOF(prefLangsMM6
), locsToUseMMptBR
, UPRV_LENGTHOF(locsToUseMMptBR
) },
7435 { "MM36", appleLocsMM3
, UPRV_LENGTHOF(appleLocsMM3
), prefLangsMM6
, UPRV_LENGTHOF(prefLangsMM6
), locsToUseMMptBR
, UPRV_LENGTHOF(locsToUseMMptBR
) },
7436 { "MM46", appleLocsMM4
, UPRV_LENGTHOF(appleLocsMM4
), prefLangsMM6
, UPRV_LENGTHOF(prefLangsMM6
), locsToUseMMptPT
, UPRV_LENGTHOF(locsToUseMMptPT
) },
7437 { "MM56", appleLocsMM5
, UPRV_LENGTHOF(appleLocsMM5
), prefLangsMM6
, UPRV_LENGTHOF(prefLangsMM6
), locsToUseMMptBR
, UPRV_LENGTHOF(locsToUseMMptBR
) },
7438 { "MM66", appleLocsMM6
, UPRV_LENGTHOF(appleLocsMM6
), prefLangsMM6
, UPRV_LENGTHOF(prefLangsMM6
), locsToUseMMptBR
, UPRV_LENGTHOF(locsToUseMMptBR
) },
7439 { "MN1", appleLocsMN
, UPRV_LENGTHOF(appleLocsMN
), prefLangsMN1
, UPRV_LENGTHOF(prefLangsMN1
), locsToUseMN_U
, UPRV_LENGTHOF(locsToUseMN_U
) },
7440 { "MN2", appleLocsMN
, UPRV_LENGTHOF(appleLocsMN
), prefLangsMN2
, UPRV_LENGTHOF(prefLangsMN2
), locsToUseMN_U
, UPRV_LENGTHOF(locsToUseMN_U
) },
7441 { "MN3", appleLocsMN
, UPRV_LENGTHOF(appleLocsMN
), prefLangsMN3
, UPRV_LENGTHOF(prefLangsMN3
), locsToUseMN_U
, UPRV_LENGTHOF(locsToUseMN_U
) },
7442 { "MN4", appleLocsMN
, UPRV_LENGTHOF(appleLocsMN
), prefLangsMN4
, UPRV_LENGTHOF(prefLangsMN4
), locsToUseMN_U
, UPRV_LENGTHOF(locsToUseMN_U
) },
7444 { NULL
, NULL
, 0, NULL
, 0, NULL
, 0 }
7450 enum { kMaxLocalizationsToUse
= 8, kPrintArrayBufSize
= 128 };
7452 // array, array of pointers to strings to print
7453 // count, count of array elements, may be -1 if array is terminated by a NULL entry
7454 // buf, buffer into which to put concatenated strings
7455 // bufSize, length of buf
7456 static void printStringArray(const char **array
, int32_t count
, char *buf
, int32_t bufSize
) {
7457 char * bufPtr
= buf
;
7458 const char * curEntry
;
7459 int32_t idx
, countMax
= bufSize
/16;
7460 if (count
< 0 || count
> countMax
) {
7463 for (idx
= 0; idx
< count
&& (curEntry
= *array
++) != NULL
; idx
++) {
7464 int32_t len
= sprintf(bufPtr
, "%s\"%.12s\"", (idx
> 0)? ", ": "", curEntry
);
7470 *bufPtr
= 0; /* ensure termination */
7473 static UBool
equalStringArrays(const char **array1
, int32_t count1
, const char **array2
, int32_t count2
) {
7474 const char ** array1Ptr
= array1
;
7475 const char ** array2Ptr
= array2
;
7479 while (*array1Ptr
++ != NULL
) {
7485 while (*array2Ptr
++ != NULL
) {
7489 if (count1
!= count2
) {
7492 for (idx
= 0; idx
< count1
; idx
++) {
7493 if (uprv_strcmp(array1
[idx
], array2
[idx
]) != 0) {
7500 static void TestAppleLocalizationsToUse() {
7501 const AppleLocToUseTestSet
* testSetPtr
;
7502 const MultiPrefTest
* multiSetPtr
;
7503 const char * locsToUse
[kMaxLocalizationsToUse
];
7504 int32_t numLocsToUse
;
7506 char printExpected
[kPrintArrayBufSize
];
7507 char printActual
[kPrintArrayBufSize
];
7509 for (testSetPtr
= altuTestSets
; testSetPtr
->locAndCountEntriesPtr
!= NULL
; testSetPtr
++) {
7510 int32_t iLocSet
, iLang
;
7512 for (iLocSet
= 0; iLocSet
< kNumLocSets
; iLocSet
++) {
7513 for (iLang
= 0; iLang
< testSetPtr
->appleLangAndLocCount
; iLang
++) {
7514 const char * language
= testSetPtr
->appleLangAndLocPtr
[iLang
].language
;
7515 const char ** expLocsForSet
= testSetPtr
->appleLangAndLocPtr
[iLang
].expLocsForSets
[iLocSet
];
7516 status
= U_ZERO_ERROR
;
7518 numLocsToUse
= ualoc_localizationsToUse(&language
, 1,
7519 testSetPtr
->locAndCountEntriesPtr
[iLocSet
].locs
, testSetPtr
->locAndCountEntriesPtr
[iLocSet
].locCount
,
7520 locsToUse
, kMaxLocalizationsToUse
, &status
);
7521 if (U_FAILURE(status
)) {
7522 log_err("FAIL: ualoc_localizationsToUse testSet %d, locSet %d, lang %s, status %s\n",
7523 testSetPtr
-altuTestSets
, iLocSet
+1, language
, u_errorName(status
));
7524 } else if (numLocsToUse
== 0 && expLocsForSet
!= NULL
) {
7525 printStringArray(expLocsForSet
, -1, printExpected
, kPrintArrayBufSize
);
7526 log_err("FAIL: ualoc_localizationsToUse testSet %d, locSet %d, lang %s, expect {%s}, get no results\n",
7527 testSetPtr
-altuTestSets
, iLocSet
+1, language
, printExpected
);
7528 } else if (numLocsToUse
> 0 && expLocsForSet
== NULL
) {
7529 printStringArray(locsToUse
, numLocsToUse
, printActual
, kPrintArrayBufSize
);
7530 log_err("FAIL: ualoc_localizationsToUse testSet %d, locSet %d, lang %s, expect no results, get {%s}\n",
7531 testSetPtr
-altuTestSets
, iLocSet
+1, language
, printActual
);
7532 } else if (numLocsToUse
> 0 && !equalStringArrays(expLocsForSet
, -1, locsToUse
, numLocsToUse
)) {
7533 printStringArray(expLocsForSet
, -1, printExpected
, kPrintArrayBufSize
);
7534 printStringArray(locsToUse
, numLocsToUse
, printActual
, kPrintArrayBufSize
);
7535 log_err("FAIL: ualoc_localizationsToUse testSet %d, locSet %d, lang %s:\n expect {%s}\n get {%s}\n",
7536 testSetPtr
-altuTestSets
, iLocSet
+1, language
, printExpected
, printActual
);
7542 for (multiSetPtr
= multiTestSets
; multiSetPtr
->name
!= NULL
; multiSetPtr
++) {
7543 status
= U_ZERO_ERROR
;
7544 numLocsToUse
= ualoc_localizationsToUse(multiSetPtr
->prefLangs
, multiSetPtr
->prefLangsCount
, multiSetPtr
->availLocs
, multiSetPtr
->availLocsCount
, locsToUse
, kMaxLocalizationsToUse
, &status
);
7545 if (U_FAILURE(status
)) {
7546 log_err("FAIL: ualoc_localizationsToUse appleLocs%s, langs prefLangs%s, status %s\n", multiSetPtr
->name
, multiSetPtr
->name
, u_errorName(status
));
7547 } else if (!equalStringArrays(multiSetPtr
->locsToUse
, multiSetPtr
->locsToUseCount
, locsToUse
, numLocsToUse
)) {
7548 printStringArray(multiSetPtr
->locsToUse
, multiSetPtr
->locsToUseCount
, printExpected
, kPrintArrayBufSize
);
7549 printStringArray(locsToUse
, numLocsToUse
, printActual
, kPrintArrayBufSize
);
7550 log_err("FAIL: ualoc_localizationsToUse appleLocs%s, langs prefLangs%s:\n expect {%s}\n get {%s}\n",
7551 multiSetPtr
->name
, multiSetPtr
->name
, printExpected
, printActual
);