1 /********************************************************************
3 * Copyright (c) 1997-2013, International Business Machines Corporation and
4 * others. All Rights Reserved.
5 ********************************************************************/
6 /*****************************************************************************
10 * Modification History:
12 * Madhu Katragadda Ported for C API
13 ******************************************************************************
24 #include "unicode/putil.h"
25 #include "unicode/ubrk.h"
26 #include "unicode/uchar.h"
27 #include "unicode/ucol.h"
28 #include "unicode/udat.h"
29 #include "unicode/uloc.h"
30 #include "unicode/umsg.h"
31 #include "unicode/ures.h"
32 #include "unicode/uset.h"
33 #include "unicode/ustring.h"
34 #include "unicode/utypes.h"
35 #include "unicode/ulocdata.h"
36 #include "unicode/parseerr.h" /* may not be included with some uconfig switches */
38 #define LENGTHOF(array) (int32_t)(sizeof(array)/sizeof((array)[0]))
40 static void TestNullDefault(void);
41 static void TestNonexistentLanguageExemplars(void);
42 static void TestLocDataErrorCodeChaining(void);
43 static void TestLanguageExemplarsFallbacks(void);
45 static void TestUnicodeDefines(void);
47 void PrintDataTable();
49 /*---------------------------------------------------
51 --------------------------------------------------- */
53 #define LOCALE_INFO_SIZE 28
55 static const char* const rawData2
[LOCALE_INFO_SIZE
][LOCALE_SIZE
] = {
57 { "en", "fr", "ca", "el", "no", "zh", "de", "es", "ja" },
59 { "", "", "", "", "", "", "", "", "" },
61 { "US", "FR", "ES", "GR", "NO", "CN", "DE", "", "JP" },
63 { "", "", "", "", "NY", "", "", "", "" },
65 { "en_US", "fr_FR", "ca_ES",
66 "el_GR", "no_NO_NY", "zh_Hans_CN",
67 "de_DE@collation=phonebook", "es@collation=traditional", "ja_JP@calendar=japanese" },
69 { "eng", "fra", "cat", "ell", "nor", "zho", "deu", "spa", "jpn" },
71 { "USA", "FRA", "ESP", "GRC", "NOR", "CHN", "DEU", "", "JPN" },
73 { "409", "40c", "403", "408", "814", "804", "10407", "40a", "411" },
75 /* display language (English) */
76 { "English", "French", "Catalan", "Greek", "Norwegian", "Chinese", "German", "Spanish", "Japanese" },
77 /* display script code (English) */
78 { "", "", "", "", "", "Simplified Han", "", "", "" },
79 /* display country (English) */
80 { "United States", "France", "Spain", "Greece", "Norway", "China", "Germany", "", "Japan" },
81 /* display variant (English) */
82 { "", "", "", "", "NY", "", "", "", "" },
83 /* display name (English) */
84 { "English (United States)", "French (France)", "Catalan (Spain)",
85 "Greek (Greece)", "Norwegian (Norway, NY)", "Chinese (Simplified, China)",
86 "German (Germany, Sort Order=Phonebook Sort Order)", "Spanish (Sort Order=Traditional Sort Order)", "Japanese (Japan, Calendar=Japanese Calendar)" },
88 /* display language (French) */
89 { "anglais", "fran\\u00E7ais", "catalan", "grec", "norv\\u00E9gien", "chinois", "allemand", "espagnol", "japonais" },
90 /* display script code (French) */
91 { "", "", "", "", "", "chinois simplifi\\u00e9", "", "", "" },
92 /* display country (French) */
93 { "\\u00C9tats-Unis", "France", "Espagne", "Gr\\u00E8ce", "Norv\\u00E8ge", "Chine", "Allemagne", "", "Japon" },
94 /* display variant (French) */
95 { "", "", "", "", "NY", "", "", "", "" },
96 /* display name (French) */
97 { "anglais (\\u00C9tats-Unis)", "fran\\u00E7ais (France)", "catalan (Espagne)",
98 "grec (Gr\\u00E8ce)", "norv\\u00E9gien (Norv\\u00E8ge, NY)", "chinois (simplifi\\u00e9, Chine)",
99 "allemand (Allemagne, ordonnancement=Ordre de l\\u2019annuaire)", "espagnol (ordonnancement=Ordre traditionnel)", "japonais (Japon, calendrier=Calendrier japonais)" },
101 /* display language (Catalan) */
102 { "angl\\u00E8s", "franc\\u00E8s", "catal\\u00E0", "grec", "noruec", "xin\\u00E8s", "alemany", "espanyol", "japon\\u00E8s" },
103 /* display script code (Catalan) */
104 { "", "", "", "", "", "xin\\u00E8s simplificat", "", "", "" },
105 /* display country (Catalan) */
106 { "Estats Units", "Fran\\u00E7a", "Espanya", "Gr\\u00E8cia", "Noruega", "Xina", "Alemanya", "", "Jap\\u00F3" },
107 /* display variant (Catalan) */
108 { "", "", "", "", "NY", "", "", "", "" },
109 /* display name (Catalan) */
110 { "angl\\u00E8s (Estats Units)", "franc\\u00E8s (Fran\\u00E7a)", "catal\\u00E0 (Espanya)",
111 "grec (Gr\\u00E8cia)", "noruec (Noruega, NY)", "xin\\u00E8s (simplificat, Xina)",
112 "alemany (Alemanya, ordre alfab\\u00e8tic=ordre de la guia telef\\u00F2nica)", "espanyol (ordre alfab\\u00e8tic=ordre tradicional)", "japon\\u00E8s (Jap\\u00F3, calendari=calendari japon\\u00e8s)" },
114 /* display language (Greek) */
116 "\\u0391\\u03b3\\u03b3\\u03bb\\u03b9\\u03ba\\u03ac",
117 "\\u0393\\u03b1\\u03bb\\u03bb\\u03b9\\u03ba\\u03ac",
118 "\\u039a\\u03b1\\u03c4\\u03b1\\u03bb\\u03b1\\u03bd\\u03b9\\u03ba\\u03ac",
119 "\\u0395\\u03bb\\u03bb\\u03b7\\u03bd\\u03b9\\u03ba\\u03ac",
120 "\\u039d\\u03bf\\u03c1\\u03b2\\u03b7\\u03b3\\u03b9\\u03ba\\u03ac",
121 "\\u039A\\u03B9\\u03BD\\u03B5\\u03B6\\u03B9\\u03BA\\u03AC",
122 "\\u0393\\u03B5\\u03C1\\u03BC\\u03B1\\u03BD\\u03B9\\u03BA\\u03AC",
123 "\\u0399\\u03C3\\u03C0\\u03B1\\u03BD\\u03B9\\u03BA\\u03AC",
124 "\\u0399\\u03B1\\u03C0\\u03C9\\u03BD\\u03B9\\u03BA\\u03AC"
126 /* display script code (Greek) */
128 { "", "", "", "", "", "\\u0391\\u03c0\\u03bb\\u03bf\\u03c0\\u03bf\\u03b9\\u03b7\\u03bc\\u03ad\\u03bd\\u03b1 \\u03a7\\u03b1\\u03bd", "", "", "" },
129 /* display country (Greek) */
131 "\\u0397\\u03BD\\u03C9\\u03BC\\u03AD\\u03BD\\u03B5\\u03C2 \\u03A0\\u03BF\\u03BB\\u03B9\\u03C4\\u03B5\\u03AF\\u03B5\\u03C2 \\u03C4\\u03B7\\u03C2 \\u0391\\u03BC\\u03B5\\u03C1\\u03B9\\u03BA\\u03AE\\u03C2",
132 "\\u0393\\u03b1\\u03bb\\u03bb\\u03af\\u03b1",
133 "\\u0399\\u03c3\\u03c0\\u03b1\\u03bd\\u03af\\u03b1",
134 "\\u0395\\u03bb\\u03bb\\u03ac\\u03b4\\u03b1",
135 "\\u039d\\u03bf\\u03c1\\u03b2\\u03b7\\u03b3\\u03af\\u03b1",
136 "\\u039A\\u03AF\\u03BD\\u03B1",
137 "\\u0393\\u03B5\\u03C1\\u03BC\\u03B1\\u03BD\\u03AF\\u03B1",
139 "\\u0399\\u03B1\\u03C0\\u03C9\\u03BD\\u03AF\\u03B1"
141 /* display variant (Greek) */
142 { "", "", "", "", "NY", "", "", "", "" }, /* TODO: currently there is no translation for NY in Greek fix this test when we have it */
143 /* display name (Greek) */
145 "\\u0391\\u03b3\\u03b3\\u03bb\\u03b9\\u03ba\\u03ac (\\u0397\\u03BD\\u03C9\\u03BC\\u03AD\\u03BD\\u03B5\\u03C2 \\u03A0\\u03BF\\u03BB\\u03B9\\u03C4\\u03B5\\u03AF\\u03B5\\u03C2 \\u03C4\\u03B7\\u03C2 \\u0391\\u03BC\\u03B5\\u03C1\\u03B9\\u03BA\\u03AE\\u03C2)",
146 "\\u0393\\u03b1\\u03bb\\u03bb\\u03b9\\u03ba\\u03ac (\\u0393\\u03b1\\u03bb\\u03bb\\u03af\\u03b1)",
147 "\\u039a\\u03b1\\u03c4\\u03b1\\u03bb\\u03b1\\u03bd\\u03b9\\u03ba\\u03ac (\\u0399\\u03c3\\u03c0\\u03b1\\u03bd\\u03af\\u03b1)",
148 "\\u0395\\u03bb\\u03bb\\u03b7\\u03bd\\u03b9\\u03ba\\u03ac (\\u0395\\u03bb\\u03bb\\u03ac\\u03b4\\u03b1)",
149 "\\u039d\\u03bf\\u03c1\\u03b2\\u03b7\\u03b3\\u03b9\\u03ba\\u03ac (\\u039d\\u03bf\\u03c1\\u03b2\\u03b7\\u03b3\\u03af\\u03b1,NY)",
150 "\\u039A\\u03B9\\u03BD\\u03B5\\u03B6\\u03B9\\u03BA\\u03AC (\\u0391\\u03c0\\u03bb\\u03bf\\u03c0\\u03bf\\u03b9\\u03b7\\u03bc\\u03ad\\u03bd\\u03bf \\u039a\\u03b9\\u03bd\\u03b5\\u03b6\\u03b9\\u03ba\\u03cc,\\u039A\\u03AF\\u03BD\\u03B1)",
151 "\\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)",
152 "\\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)",
153 "\\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)"
157 static UChar
*** dataTable
=0;
197 #define TESTCASE(name) addTest(root, &name, "tsutil/cloctst/" #name)
199 void addLocaleTest(TestNode
** root
);
201 void addLocaleTest(TestNode
** root
)
203 TESTCASE(TestObsoleteNames
); /* srl- move */
204 TESTCASE(TestBasicGetters
);
205 TESTCASE(TestNullDefault
);
206 TESTCASE(TestPrefixes
);
207 TESTCASE(TestSimpleResourceInfo
);
208 TESTCASE(TestDisplayNames
);
209 TESTCASE(TestGetAvailableLocales
);
210 TESTCASE(TestDataDirectory
);
211 #if !UCONFIG_NO_FILE_IO && !UCONFIG_NO_LEGACY_CONVERSION
212 TESTCASE(TestISOFunctions
);
214 TESTCASE(TestISO3Fallback
);
215 TESTCASE(TestUninstalledISO3Names
);
216 TESTCASE(TestSimpleDisplayNames
);
217 TESTCASE(TestVariantParsing
);
218 TESTCASE(TestKeywordVariants
);
219 TESTCASE(TestKeywordVariantParsing
);
220 TESTCASE(TestCanonicalization
);
221 TESTCASE(TestKeywordSet
);
222 TESTCASE(TestKeywordSetError
);
223 TESTCASE(TestDisplayKeywords
);
224 TESTCASE(TestDisplayKeywordValues
);
225 TESTCASE(TestGetBaseName
);
226 #if !UCONFIG_NO_FILE_IO
227 TESTCASE(TestGetLocale
);
229 TESTCASE(TestDisplayNameWarning
);
230 TESTCASE(TestNonexistentLanguageExemplars
);
231 TESTCASE(TestLocDataErrorCodeChaining
);
232 TESTCASE(TestLanguageExemplarsFallbacks
);
233 TESTCASE(TestCalendar
);
234 TESTCASE(TestDateFormat
);
235 TESTCASE(TestCollation
);
236 TESTCASE(TestULocale
);
237 TESTCASE(TestUResourceBundle
);
238 TESTCASE(TestDisplayName
);
239 TESTCASE(TestAcceptLanguage
);
240 TESTCASE(TestGetLocaleForLCID
);
241 TESTCASE(TestOrientation
);
242 TESTCASE(TestLikelySubtags
);
243 TESTCASE(TestToLanguageTag
);
244 TESTCASE(TestForLanguageTag
);
245 TESTCASE(TestTrailingNull
);
246 TESTCASE(TestUnicodeDefines
);
247 TESTCASE(TestEnglishExemplarCharacters
);
251 /* testing uloc(), uloc_getName(), uloc_getLanguage(), uloc_getVariant(), uloc_getCountry() */
252 static void TestBasicGetters() {
255 UErrorCode status
= U_ZERO_ERROR
;
256 char *testLocale
= 0;
257 char *temp
= 0, *name
= 0;
258 log_verbose("Testing Basic Getters\n");
259 for (i
= 0; i
< LOCALE_SIZE
; i
++) {
260 testLocale
=(char*)malloc(sizeof(char) * (strlen(rawData2
[NAME
][i
])+1));
261 strcpy(testLocale
,rawData2
[NAME
][i
]);
263 log_verbose("Testing %s .....\n", testLocale
);
264 cap
=uloc_getLanguage(testLocale
, NULL
, 0, &status
);
265 if(status
==U_BUFFER_OVERFLOW_ERROR
){
267 temp
=(char*)malloc(sizeof(char) * (cap
+1));
268 uloc_getLanguage(testLocale
, temp
, cap
+1, &status
);
270 if(U_FAILURE(status
)){
271 log_err("ERROR: in uloc_getLanguage %s\n", myErrorName(status
));
273 if (0 !=strcmp(temp
,rawData2
[LANG
][i
])) {
274 log_err(" Language code mismatch: %s versus %s\n", temp
, rawData2
[LANG
][i
]);
278 cap
=uloc_getCountry(testLocale
, temp
, cap
, &status
);
279 if(status
==U_BUFFER_OVERFLOW_ERROR
){
281 temp
=(char*)realloc(temp
, sizeof(char) * (cap
+1));
282 uloc_getCountry(testLocale
, temp
, cap
+1, &status
);
284 if(U_FAILURE(status
)){
285 log_err("ERROR: in uloc_getCountry %s\n", myErrorName(status
));
287 if (0 != strcmp(temp
, rawData2
[CTRY
][i
])) {
288 log_err(" Country code mismatch: %s versus %s\n", temp
, rawData2
[CTRY
][i
]);
292 cap
=uloc_getVariant(testLocale
, temp
, cap
, &status
);
293 if(status
==U_BUFFER_OVERFLOW_ERROR
){
295 temp
=(char*)realloc(temp
, sizeof(char) * (cap
+1));
296 uloc_getVariant(testLocale
, temp
, cap
+1, &status
);
298 if(U_FAILURE(status
)){
299 log_err("ERROR: in uloc_getVariant %s\n", myErrorName(status
));
301 if (0 != strcmp(temp
, rawData2
[VAR
][i
])) {
302 log_err("Variant code mismatch: %s versus %s\n", temp
, rawData2
[VAR
][i
]);
305 cap
=uloc_getName(testLocale
, NULL
, 0, &status
);
306 if(status
==U_BUFFER_OVERFLOW_ERROR
){
308 name
=(char*)malloc(sizeof(char) * (cap
+1));
309 uloc_getName(testLocale
, name
, cap
+1, &status
);
310 } else if(status
==U_ZERO_ERROR
) {
311 log_err("ERROR: in uloc_getName(%s,NULL,0,..), expected U_BUFFER_OVERFLOW_ERROR!\n", testLocale
);
313 if(U_FAILURE(status
)){
314 log_err("ERROR: in uloc_getName %s\n", myErrorName(status
));
316 if (0 != strcmp(name
, rawData2
[NAME
][i
])){
317 log_err(" Mismatch in getName: %s versus %s\n", name
, rawData2
[NAME
][i
]);
327 static void TestNullDefault() {
328 UErrorCode status
= U_ZERO_ERROR
;
329 char original
[ULOC_FULLNAME_CAPACITY
];
331 uprv_strcpy(original
, uloc_getDefault());
332 uloc_setDefault("qq_BLA", &status
);
333 if (uprv_strcmp(uloc_getDefault(), "qq_BLA") != 0) {
334 log_err(" Mismatch in uloc_setDefault: qq_BLA versus %s\n", uloc_getDefault());
336 uloc_setDefault(NULL
, &status
);
337 if (uprv_strcmp(uloc_getDefault(), original
) != 0) {
338 log_err(" uloc_setDefault(NULL, &status) didn't get the default locale back!\n");
342 /* Test that set & get of default locale work, and that
343 * default locales are cached and reused, and not overwritten.
347 const char *n2_en_US
;
349 status
= U_ZERO_ERROR
;
350 uloc_setDefault("en_US", &status
);
351 n_en_US
= uloc_getDefault();
352 if (strcmp(n_en_US
, "en_US") != 0) {
353 log_err("Wrong result from uloc_getDefault(). Expected \"en_US\", got \"%s\"\n", n_en_US
);
356 uloc_setDefault("fr_FR", &status
);
357 n_fr_FR
= uloc_getDefault();
358 if (strcmp(n_en_US
, "en_US") != 0) {
359 log_err("uloc_setDefault altered previously default string."
360 "Expected \"en_US\", got \"%s\"\n", n_en_US
);
362 if (strcmp(n_fr_FR
, "fr_FR") != 0) {
363 log_err("Wrong result from uloc_getDefault(). Expected \"fr_FR\", got %s\n", n_fr_FR
);
366 uloc_setDefault("en_US", &status
);
367 n2_en_US
= uloc_getDefault();
368 if (strcmp(n2_en_US
, "en_US") != 0) {
369 log_err("Wrong result from uloc_getDefault(). Expected \"en_US\", got \"%s\"\n", n_en_US
);
371 if (n2_en_US
!= n_en_US
) {
372 log_err("Default locale cache failed to reuse en_US locale.\n");
375 if (U_FAILURE(status
)) {
376 log_err("Failure returned from uloc_setDefault - \"%s\"\n", u_errorName(status
));
382 /* Test the i- and x- and @ and . functionality
385 #define PREFIXBUFSIZ 128
387 static void TestPrefixes() {
390 const char *loc
, *expected
;
392 static const char * const testData
[][7] =
394 /* NULL canonicalize() column means "expect same as getName()" */
395 {"sv", "", "FI", "AL", "sv-fi-al", "sv_FI_AL", NULL
},
396 {"en", "", "GB", "", "en-gb", "en_GB", NULL
},
397 {"i-hakka", "", "MT", "XEMXIJA", "i-hakka_MT_XEMXIJA", "i-hakka_MT_XEMXIJA", NULL
},
398 {"i-hakka", "", "CN", "", "i-hakka_CN", "i-hakka_CN", NULL
},
399 {"i-hakka", "", "MX", "", "I-hakka_MX", "i-hakka_MX", NULL
},
400 {"x-klingon", "", "US", "SANJOSE", "X-KLINGON_us_SANJOSE", "x-klingon_US_SANJOSE", NULL
},
402 {"zh", "Hans", "", "PINYIN", "zh-Hans-pinyin", "zh_Hans__PINYIN", "zh_Hans@collation=pinyin"},
403 {"hy", "", "", "AREVMDA", "hy_AREVMDA", "hy__AREVMDA", NULL
},
405 {"de", "", "", "1901", "de-1901", "de__1901", NULL
},
406 {"mr", "", "", "", "mr.utf8", "mr.utf8", "mr"},
407 {"de", "", "TV", "", "de-tv.koi8r", "de_TV.koi8r", "de_TV"},
408 {"x-piglatin", "", "ML", "", "x-piglatin_ML.MBE", "x-piglatin_ML.MBE", "x-piglatin_ML"}, /* Multibyte English */
409 {"i-cherokee", "","US", "", "i-Cherokee_US.utf7", "i-cherokee_US.utf7", "i-cherokee_US"},
410 {"x-filfli", "", "MT", "FILFLA", "x-filfli_MT_FILFLA.gb-18030", "x-filfli_MT_FILFLA.gb-18030", "x-filfli_MT_FILFLA"},
411 {"no", "", "NO", "NY", "no-no-ny.utf32@B", "no_NO_NY.utf32@B", "no_NO_NY_B"},
412 {"no", "", "NO", "", "no-no.utf32@B", "no_NO.utf32@B", "no_NO_B"},
413 {"no", "", "", "NY", "no__ny", "no__NY", NULL
},
414 {"no", "", "", "", "no@ny", "no@ny", "no__NY"},
415 {"el", "Latn", "", "", "el-latn", "el_Latn", NULL
},
416 {"en", "Cyrl", "RU", "", "en-cyrl-ru", "en_Cyrl_RU", NULL
},
417 {"zh", "Hant", "TW", "STROKE", "zh-hant_TW_STROKE", "zh_Hant_TW_STROKE", "zh_Hant_TW@collation=stroke"},
418 {"qq", "Qqqq", "QQ", "QQ", "qq_Qqqq_QQ_QQ", "qq_Qqqq_QQ_QQ", NULL
},
419 {"qq", "Qqqq", "", "QQ", "qq_Qqqq__QQ", "qq_Qqqq__QQ", NULL
},
420 {"ab", "Cdef", "GH", "IJ", "ab_cdef_gh_ij", "ab_Cdef_GH_IJ", NULL
}, /* total garbage */
422 {NULL
,NULL
,NULL
,NULL
,NULL
,NULL
,NULL
}
425 static const char * const testTitles
[] = {
426 "uloc_getLanguage()",
432 "uloc_canonicalize()"
435 char buf
[PREFIXBUFSIZ
];
440 for(row
=0;testData
[row
][0] != NULL
;row
++) {
441 loc
= testData
[row
][NAME
];
442 log_verbose("Test #%d: %s\n", row
, loc
);
447 for(n
=0;n
<=(NAME
+2);n
++) {
448 if(n
==NAME
) continue;
450 for(len
=0;len
<PREFIXBUFSIZ
;len
++) {
451 buf
[len
] = '%'; /* Set a tripwire.. */
457 len
= uloc_getLanguage(loc
, buf
, PREFIXBUFSIZ
, &err
);
461 len
= uloc_getScript(loc
, buf
, PREFIXBUFSIZ
, &err
);
465 len
= uloc_getCountry(loc
, buf
, PREFIXBUFSIZ
, &err
);
469 len
= uloc_getVariant(loc
, buf
, PREFIXBUFSIZ
, &err
);
473 len
= uloc_getName(loc
, buf
, PREFIXBUFSIZ
, &err
);
477 len
= uloc_canonicalize(loc
, buf
, PREFIXBUFSIZ
, &err
);
486 log_err("#%d: %s on %s: err %s\n",
487 row
, testTitles
[n
], loc
, u_errorName(err
));
489 log_verbose("#%d: %s on %s: -> [%s] (length %d)\n",
490 row
, testTitles
[n
], loc
, buf
, len
);
492 if(len
!= (int32_t)strlen(buf
)) {
493 log_err("#%d: %s on %s: -> [%s] (length returned %d, actual %d!)\n",
494 row
, testTitles
[n
], loc
, buf
, len
, strlen(buf
)+1);
498 /* see if they smashed something */
499 if(buf
[len
+1] != '%') {
500 log_err("#%d: %s on %s: -> [%s] - wrote [%X] out ofbounds!\n",
501 row
, testTitles
[n
], loc
, buf
, buf
[len
+1]);
504 expected
= testData
[row
][n
];
505 if (expected
== NULL
&& n
== (NAME
+2)) {
506 /* NULL expected canonicalize() means "expect same as getName()" */
507 expected
= testData
[row
][NAME
+1];
509 if(strcmp(buf
, expected
)) {
510 log_err("#%d: %s on %s: -> [%s] (expected '%s'!)\n",
511 row
, testTitles
[n
], loc
, buf
, expected
);
520 /* testing uloc_getISO3Language(), uloc_getISO3Country(), */
521 static void TestSimpleResourceInfo() {
523 char* testLocale
= 0;
528 testLocale
=(char*)malloc(sizeof(char) * 1);
529 expected
=(UChar
*)malloc(sizeof(UChar
) * 1);
532 log_verbose("Testing getISO3Language and getISO3Country\n");
533 for (i
= 0; i
< LOCALE_SIZE
; i
++) {
535 testLocale
=(char*)realloc(testLocale
, sizeof(char) * (u_strlen(dataTable
[NAME
][i
])+1));
536 u_austrcpy(testLocale
, dataTable
[NAME
][i
]);
538 log_verbose("Testing %s ......\n", testLocale
);
540 temp
=uloc_getISO3Language(testLocale
);
541 expected
=(UChar
*)realloc(expected
, sizeof(UChar
) * (strlen(temp
) + 1));
542 u_uastrcpy(expected
,temp
);
543 if (0 != u_strcmp(expected
, dataTable
[LANG3
][i
])) {
544 log_err(" ISO-3 language code mismatch: %s versus %s\n", austrdup(expected
),
545 austrdup(dataTable
[LANG3
][i
]));
548 temp
=uloc_getISO3Country(testLocale
);
549 expected
=(UChar
*)realloc(expected
, sizeof(UChar
) * (strlen(temp
) + 1));
550 u_uastrcpy(expected
,temp
);
551 if (0 != u_strcmp(expected
, dataTable
[CTRY3
][i
])) {
552 log_err(" ISO-3 Country code mismatch: %s versus %s\n", austrdup(expected
),
553 austrdup(dataTable
[CTRY3
][i
]));
555 sprintf(temp2
, "%x", (int)uloc_getLCID(testLocale
));
556 if (strcmp(temp2
, rawData2
[LCID
][i
]) != 0) {
557 log_err("LCID mismatch: %s versus %s\n", temp2
, rawData2
[LCID
][i
]);
566 /* if len < 0, we convert until we hit UChar 0x0000, which is not output. will add trailing null
567 * if there's room but won't be included in result. result < 0 indicates an error.
568 * Returns the number of chars written (not those that would be written if there's enough room.*/
569 static int32_t UCharsToEscapedAscii(const UChar
* utext
, int32_t len
, char* resultChars
, int32_t buflen
) {
570 static const struct {
583 static const int32_t ESCAPE_MAP_LENGTH
= sizeof(ESCAPE_MAP
)/sizeof(ESCAPE_MAP
[0]);
584 static const char HEX_DIGITS
[] = {
585 '0', '1', '2', '3', '4', '5', '6', '7',
586 '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'
589 int32_t resultLen
= 0;
590 const int32_t limit
= len
<0 ? buflen
: len
; /* buflen is long enough to hit the buffer limit */
591 const int32_t escapeLimit1
= buflen
-2;
592 const int32_t escapeLimit2
= buflen
-6;
595 if(utext
==NULL
|| resultChars
==NULL
|| buflen
<0) {
599 for(i
=0;i
<limit
&& resultLen
<buflen
;++i
) {
605 for(j
=0;j
<ESCAPE_MAP_LENGTH
&& uc
!=ESCAPE_MAP
[j
].sourceVal
;j
++) {
607 if(j
<ESCAPE_MAP_LENGTH
) {
608 if(resultLen
>escapeLimit1
) {
611 resultChars
[resultLen
++]='\\';
612 resultChars
[resultLen
++]=ESCAPE_MAP
[j
].escapedChar
;
616 u_austrncpy(resultChars
+ resultLen
, &uc
, 1);
621 if(resultLen
>escapeLimit2
) {
625 /* have to escape the uchar */
626 resultChars
[resultLen
++]='\\';
627 resultChars
[resultLen
++]='u';
628 resultChars
[resultLen
++]=HEX_DIGITS
[(uc
>>12)&0xff];
629 resultChars
[resultLen
++]=HEX_DIGITS
[(uc
>>8)&0xff];
630 resultChars
[resultLen
++]=HEX_DIGITS
[(uc
>>4)&0xff];
631 resultChars
[resultLen
++]=HEX_DIGITS
[uc
&0xff];
634 if(resultLen
<buflen
) {
635 resultChars
[resultLen
] = 0;
642 * Jitterbug 2439 -- markus 20030425
644 * The lookup of display names must not fall back through the default
645 * locale because that yields useless results.
647 static void TestDisplayNames()
650 UErrorCode errorCode
=U_ZERO_ERROR
;
652 log_verbose("Testing getDisplayName for different locales\n");
654 log_verbose(" In locale = en_US...\n");
655 doTestDisplayNames("en_US", DLANG_EN
);
656 log_verbose(" In locale = fr_FR....\n");
657 doTestDisplayNames("fr_FR", DLANG_FR
);
658 log_verbose(" In locale = ca_ES...\n");
659 doTestDisplayNames("ca_ES", DLANG_CA
);
660 log_verbose(" In locale = gr_EL..\n");
661 doTestDisplayNames("el_GR", DLANG_EL
);
663 /* test that the default locale has a display name for its own language */
664 errorCode
=U_ZERO_ERROR
;
665 length
=uloc_getDisplayLanguage(NULL
, NULL
, buffer
, LENGTHOF(buffer
), &errorCode
);
666 if(U_FAILURE(errorCode
) || (length
<=3 && buffer
[0]<=0x7f)) {
667 /* check <=3 to reject getting the language code as a display name */
668 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
));
671 /* test that we get the language code itself for an unknown language, and a default warning */
672 errorCode
=U_ZERO_ERROR
;
673 length
=uloc_getDisplayLanguage("qq", "rr", buffer
, LENGTHOF(buffer
), &errorCode
);
674 if(errorCode
!=U_USING_DEFAULT_WARNING
|| length
!=2 || buffer
[0]!=0x71 || buffer
[1]!=0x71) {
675 log_err("error getting the display string for an unknown language - %s\n", u_errorName(errorCode
));
678 /* test that we get a default warning for a display name where one component is unknown (4255) */
679 errorCode
=U_ZERO_ERROR
;
680 length
=uloc_getDisplayName("qq_US_POSIX", "en_US", buffer
, LENGTHOF(buffer
), &errorCode
);
681 if(errorCode
!=U_USING_DEFAULT_WARNING
) {
682 log_err("error getting the display name for a locale with an unknown language - %s\n", u_errorName(errorCode
));
687 static const char *aLocale
= "es@collation=traditional;calendar=japanese";
688 static const char *testL
[] = { "en_US",
692 static const char *expect
[] = { "Spanish (Calendar=Japanese Calendar, Sort Order=Traditional Sort Order)", /* note sorted order of keywords */
693 "espagnol (calendrier=Calendrier japonais, ordonnancement=Ordre traditionnel)",
694 "espanyol (calendari=calendari japon\\u00e8s, ordre alfab\\u00e8tic=ordre tradicional)",
695 "\\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)" };
698 for(i
=0;i
<LENGTHOF(testL
);i
++) {
699 errorCode
= U_ZERO_ERROR
;
700 uloc_getDisplayName(aLocale
, testL
[i
], buffer
, LENGTHOF(buffer
), &errorCode
);
701 if(U_FAILURE(errorCode
)) {
702 log_err("FAIL in uloc_getDisplayName(%s,%s,..) -> %s\n", aLocale
, testL
[i
], u_errorName(errorCode
));
704 expectBuffer
= CharsToUChars(expect
[i
]);
705 if(u_strcmp(buffer
,expectBuffer
)) {
706 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
));
708 log_verbose("pass in uloc_getDisplayName(%s,%s,..) got '%s'\n", aLocale
, testL
[i
], expect
[i
]);
715 /* test that we properly preflight and return data when there's a non-default pattern,
719 static const char *locale
="az_Cyrl";
720 static const char *displayLocale
="ja";
721 static const char *expectedChars
=
722 "\\u30a2\\u30bc\\u30eb\\u30d0\\u30a4\\u30b8\\u30e3\\u30f3\\u8a9e"
723 "(\\u30ad\\u30ea\\u30eb\\u6587\\u5b57)";
724 UErrorCode ec
=U_ZERO_ERROR
;
727 int32_t preflightLen
=uloc_getDisplayName(locale
, displayLocale
, NULL
, 0, &ec
);
728 /* inconvenient semantics when preflighting, this condition is expected... */
729 if(ec
==U_BUFFER_OVERFLOW_ERROR
) {
732 len
=uloc_getDisplayName(locale
, displayLocale
, result
, LENGTHOF(result
), &ec
);
734 log_err("uloc_getDisplayName(%s, %s...) returned error: %s",
735 locale
, displayLocale
, u_errorName(ec
));
737 UChar
*expected
=CharsToUChars(expectedChars
);
738 int32_t expectedLen
=u_strlen(expected
);
740 if(len
!=expectedLen
) {
741 log_data_err("uloc_getDisplayName(%s, %s...) returned string of length %d, expected length %d",
742 locale
, displayLocale
, len
, expectedLen
);
743 } else if(preflightLen
!=expectedLen
) {
744 log_err("uloc_getDisplayName(%s, %s...) returned preflight length %d, expected length %d",
745 locale
, displayLocale
, preflightLen
, expectedLen
);
746 } else if(u_strncmp(result
, expected
, len
)) {
747 int32_t cap
=len
*6+1; /* worst case + space for trailing null */
748 char* resultChars
=(char*)malloc(cap
);
749 int32_t resultCharsLen
=UCharsToEscapedAscii(result
, len
, resultChars
, cap
);
750 if(resultCharsLen
<0 || resultCharsLen
<cap
-1) {
751 log_err("uloc_getDisplayName(%s, %s...) mismatch", locale
, displayLocale
);
753 log_err("uloc_getDisplayName(%s, %s...) returned '%s' but expected '%s'",
754 locale
, displayLocale
, resultChars
, expectedChars
);
759 /* test all buffer sizes */
760 for(i
=len
+1;i
>=0;--i
) {
761 len
=uloc_getDisplayName(locale
, displayLocale
, result
, i
, &ec
);
762 if(ec
==U_BUFFER_OVERFLOW_ERROR
) {
766 log_err("using buffer of length %d returned error %s", i
, u_errorName(ec
));
769 if(len
!=expectedLen
) {
770 log_err("with buffer of length %d, expected length %d but got %d", i
, expectedLen
, len
);
773 /* There's no guarantee about what's in the buffer if we've overflowed, in particular,
774 * we don't know that it's been filled, so no point in checking. */
784 /* test for uloc_getAvialable() and uloc_countAvilable()*/
785 static void TestGetAvailableLocales()
791 log_verbose("Testing the no of avialable locales\n");
792 locCount
=uloc_countAvailable();
794 log_data_err("countAvailable() returned an empty list!\n");
796 /* use something sensible w/o hardcoding the count */
797 else if(locCount
< 0){
798 log_data_err("countAvailable() returned a wrong value!= %d\n", locCount
);
801 log_info("Number of locales returned = %d\n", locCount
);
803 for(i
=0;i
<locCount
;i
++){
804 locList
=uloc_getAvailable(i
);
806 log_verbose(" %s\n", locList
);
810 /* test for u_getDataDirectory, u_setDataDirectory, uloc_getISO3Language */
811 static void TestDataDirectory()
814 char oldDirectory
[512];
815 const char *temp
,*testValue1
,*testValue2
,*testValue3
;
816 const char path
[40] ="d:\\icu\\source\\test\\intltest" U_FILE_SEP_STRING
; /*give the required path */
818 log_verbose("Testing getDataDirectory()\n");
819 temp
= u_getDataDirectory();
820 strcpy(oldDirectory
, temp
);
822 testValue1
=uloc_getISO3Language("en_US");
823 log_verbose("first fetch of language retrieved %s\n", testValue1
);
825 if (0 != strcmp(testValue1
,"eng")){
826 log_err("Initial check of ISO3 language failed: expected \"eng\", got %s \n", testValue1
);
829 /*defining the path for DataDirectory */
830 log_verbose("Testing setDataDirectory\n");
831 u_setDataDirectory( path
);
832 if(strcmp(path
, u_getDataDirectory())==0)
833 log_verbose("setDataDirectory working fine\n");
835 log_err("Error in setDataDirectory. Directory not set correctly - came back as [%s], expected [%s]\n", u_getDataDirectory(), path
);
837 testValue2
=uloc_getISO3Language("en_US");
838 log_verbose("second fetch of language retrieved %s \n", testValue2
);
840 u_setDataDirectory(oldDirectory
);
841 testValue3
=uloc_getISO3Language("en_US");
842 log_verbose("third fetch of language retrieved %s \n", testValue3
);
844 if (0 != strcmp(testValue3
,"eng")) {
845 log_err("get/setDataDirectory() failed: expected \"eng\", got \" %s \" \n", testValue3
);
851 /*=========================================================== */
855 static void doTestDisplayNames(const char* displayLocale
, int32_t compareIndex
)
857 UErrorCode status
= U_ZERO_ERROR
;
859 int32_t maxresultsize
;
861 const char *testLocale
;
865 UChar
*testScript
= 0;
871 UChar
* expectedLang
= 0;
872 UChar
* expectedScript
= 0;
873 UChar
* expectedCtry
= 0;
874 UChar
* expectedVar
= 0;
875 UChar
* expectedName
= 0;
879 for(i
=0;i
<LOCALE_SIZE
; ++i
)
881 testLocale
=rawData2
[NAME
][i
];
883 log_verbose("Testing..... %s\n", testLocale
);
886 maxresultsize
=uloc_getDisplayLanguage(testLocale
, displayLocale
, NULL
, maxresultsize
, &status
);
887 if(status
==U_BUFFER_OVERFLOW_ERROR
)
890 testLang
=(UChar
*)malloc(sizeof(UChar
) * (maxresultsize
+1));
891 uloc_getDisplayLanguage(testLocale
, displayLocale
, testLang
, maxresultsize
+ 1, &status
);
897 if(U_FAILURE(status
)){
898 log_err("Error in getDisplayLanguage() %s\n", myErrorName(status
));
902 maxresultsize
=uloc_getDisplayScript(testLocale
, displayLocale
, NULL
, maxresultsize
, &status
);
903 if(status
==U_BUFFER_OVERFLOW_ERROR
)
906 testScript
=(UChar
*)malloc(sizeof(UChar
) * (maxresultsize
+1));
907 uloc_getDisplayScript(testLocale
, displayLocale
, testScript
, maxresultsize
+ 1, &status
);
913 if(U_FAILURE(status
)){
914 log_err("Error in getDisplayScript() %s\n", myErrorName(status
));
918 maxresultsize
=uloc_getDisplayCountry(testLocale
, displayLocale
, NULL
, maxresultsize
, &status
);
919 if(status
==U_BUFFER_OVERFLOW_ERROR
)
922 testCtry
=(UChar
*)malloc(sizeof(UChar
) * (maxresultsize
+1));
923 uloc_getDisplayCountry(testLocale
, displayLocale
, testCtry
, maxresultsize
+ 1, &status
);
929 if(U_FAILURE(status
)){
930 log_err("Error in getDisplayCountry() %s\n", myErrorName(status
));
934 maxresultsize
=uloc_getDisplayVariant(testLocale
, displayLocale
, NULL
, maxresultsize
, &status
);
935 if(status
==U_BUFFER_OVERFLOW_ERROR
)
938 testVar
=(UChar
*)malloc(sizeof(UChar
) * (maxresultsize
+1));
939 uloc_getDisplayVariant(testLocale
, displayLocale
, testVar
, maxresultsize
+ 1, &status
);
945 if(U_FAILURE(status
)){
946 log_err("Error in getDisplayVariant() %s\n", myErrorName(status
));
950 maxresultsize
=uloc_getDisplayName(testLocale
, displayLocale
, NULL
, maxresultsize
, &status
);
951 if(status
==U_BUFFER_OVERFLOW_ERROR
)
954 testName
=(UChar
*)malloc(sizeof(UChar
) * (maxresultsize
+1));
955 uloc_getDisplayName(testLocale
, displayLocale
, testName
, maxresultsize
+ 1, &status
);
961 if(U_FAILURE(status
)){
962 log_err("Error in getDisplayName() %s\n", myErrorName(status
));
965 expectedLang
=dataTable
[compareIndex
][i
];
966 if(u_strlen(expectedLang
)== 0)
967 expectedLang
=dataTable
[DLANG_EN
][i
];
969 expectedScript
=dataTable
[compareIndex
+ 1][i
];
970 if(u_strlen(expectedScript
)== 0)
971 expectedScript
=dataTable
[DSCRIPT_EN
][i
];
973 expectedCtry
=dataTable
[compareIndex
+ 2][i
];
974 if(u_strlen(expectedCtry
)== 0)
975 expectedCtry
=dataTable
[DCTRY_EN
][i
];
977 expectedVar
=dataTable
[compareIndex
+ 3][i
];
978 if(u_strlen(expectedVar
)== 0)
979 expectedVar
=dataTable
[DVAR_EN
][i
];
981 expectedName
=dataTable
[compareIndex
+ 4][i
];
982 if(u_strlen(expectedName
) == 0)
983 expectedName
=dataTable
[DNAME_EN
][i
];
985 if (0 !=u_strcmp(testLang
,expectedLang
)) {
986 log_data_err(" Display Language mismatch: got %s expected %s displayLocale=%s (Are you missing data?)\n", austrdup(testLang
), austrdup(expectedLang
), displayLocale
);
989 if (0 != u_strcmp(testScript
,expectedScript
)) {
990 log_data_err(" Display Script mismatch: got %s expected %s displayLocale=%s (Are you missing data?)\n", austrdup(testScript
), austrdup(expectedScript
), displayLocale
);
993 if (0 != u_strcmp(testCtry
,expectedCtry
)) {
994 log_data_err(" Display Country mismatch: got %s expected %s displayLocale=%s (Are you missing data?)\n", austrdup(testCtry
), austrdup(expectedCtry
), displayLocale
);
997 if (0 != u_strcmp(testVar
,expectedVar
)) {
998 log_data_err(" Display Variant mismatch: got %s expected %s displayLocale=%s (Are you missing data?)\n", austrdup(testVar
), austrdup(expectedVar
), displayLocale
);
1001 if(0 != u_strcmp(testName
, expectedName
)) {
1002 log_data_err(" Display Name mismatch: got %s expected %s displayLocale=%s (Are you missing data?)\n", austrdup(testName
), austrdup(expectedName
), displayLocale
);
1005 if(testName
!=&_NUL
) {
1008 if(testLang
!=&_NUL
) {
1011 if(testScript
!=&_NUL
) {
1014 if(testCtry
!=&_NUL
) {
1017 if(testVar
!=&_NUL
) {
1024 #if !UCONFIG_NO_FILE_IO && !UCONFIG_NO_LEGACY_CONVERSION
1025 /* test for uloc_getISOLanguages, uloc_getISOCountries */
1026 static void TestISOFunctions()
1028 const char* const* str
=uloc_getISOLanguages();
1029 const char* const* str1
=uloc_getISOCountries();
1031 const char *key
= NULL
;
1032 int32_t count
= 0, skipped
= 0;
1034 UResourceBundle
*res
;
1035 UResourceBundle
*subRes
;
1036 UErrorCode status
= U_ZERO_ERROR
;
1038 /* test getISOLanguages*/
1039 /*str=uloc_getISOLanguages(); */
1040 log_verbose("Testing ISO Languages: \n");
1042 /* use structLocale - this data is no longer in root */
1043 res
= ures_openDirect(loadTestData(&status
), "structLocale", &status
);
1044 subRes
= ures_getByKey(res
, "Languages", NULL
, &status
);
1045 if (U_FAILURE(status
)) {
1046 log_data_err("There is an error in structLocale's ures_getByKey(\"Languages\"), status=%s\n", u_errorName(status
));
1050 expect
= ures_getSize(subRes
);
1051 for(count
= 0; *(str
+count
) != 0; count
++)
1054 test
= *(str
+count
);
1055 status
= U_ZERO_ERROR
;
1058 /* Skip over language tags. This API only returns language codes. */
1059 skipped
+= (key
!= NULL
);
1060 ures_getNextString(subRes
, NULL
, &key
, &status
);
1062 while (key
!= NULL
&& strchr(key
, '_'));
1066 /* TODO: Consider removing sh, which is deprecated */
1067 if(strcmp(key
,"root") == 0 || strcmp(key
,"Fallback") == 0 || strcmp(key
,"sh") == 0) {
1068 ures_getNextString(subRes
, NULL
, &key
, &status
);
1071 #if U_CHARSET_FAMILY==U_ASCII_FAMILY
1072 /* This code only works on ASCII machines where the keys are stored in ASCII order */
1073 if(strcmp(test
,key
)) {
1074 /* The first difference usually implies the place where things get out of sync */
1075 log_err("FAIL Language diff at offset %d, \"%s\" != \"%s\"\n", count
, test
, key
);
1079 if(!strcmp(test
,"in"))
1080 log_err("FAIL getISOLanguages() has obsolete language code %s\n", test
);
1081 if(!strcmp(test
,"iw"))
1082 log_err("FAIL getISOLanguages() has obsolete language code %s\n", test
);
1083 if(!strcmp(test
,"ji"))
1084 log_err("FAIL getISOLanguages() has obsolete language code %s\n", test
);
1085 if(!strcmp(test
,"jw"))
1086 log_err("FAIL getISOLanguages() has obsolete language code %s\n", test
);
1087 if(!strcmp(test
,"sh"))
1088 log_err("FAIL getISOLanguages() has obsolete language code %s\n", test
);
1091 expect
-= skipped
; /* Ignore the skipped resources from structLocale */
1094 log_err("There is an error in getISOLanguages, got %d, expected %d (as per structLocale)\n", count
, expect
);
1097 subRes
= ures_getByKey(res
, "Countries", subRes
, &status
);
1098 log_verbose("Testing ISO Countries");
1100 expect
= ures_getSize(subRes
) - 1; /* Skip ZZ */
1101 for(count
= 0; *(str1
+count
) != 0; count
++)
1104 test
= *(str1
+count
);
1106 /* Skip over numeric UN tags. This API only returns ISO-3166 codes. */
1107 skipped
+= (key
!= NULL
);
1108 ures_getNextString(subRes
, NULL
, &key
, &status
);
1110 while (key
!= NULL
&& strlen(key
) != 2);
1114 /* TODO: Consider removing CS, which is deprecated */
1115 while(strcmp(key
,"QO") == 0 || strcmp(key
,"QU") == 0 || strcmp(key
,"CS") == 0) {
1116 ures_getNextString(subRes
, NULL
, &key
, &status
);
1119 #if U_CHARSET_FAMILY==U_ASCII_FAMILY
1120 /* This code only works on ASCII machines where the keys are stored in ASCII order */
1121 if(strcmp(test
,key
)) {
1122 /* The first difference usually implies the place where things get out of sync */
1123 log_err("FAIL Country diff at offset %d, \"%s\" != \"%s\"\n", count
, test
, key
);
1126 if(!strcmp(test
,"FX"))
1127 log_err("FAIL getISOCountries() has obsolete country code %s\n", test
);
1128 if(!strcmp(test
,"YU"))
1129 log_err("FAIL getISOCountries() has obsolete country code %s\n", test
);
1130 if(!strcmp(test
,"ZR"))
1131 log_err("FAIL getISOCountries() has obsolete country code %s\n", test
);
1134 ures_getNextString(subRes
, NULL
, &key
, &status
);
1135 if (strcmp(key
, "ZZ") != 0) {
1136 log_err("ZZ was expected to be the last entry in structLocale, but got %s\n", key
);
1138 #if U_CHARSET_FAMILY==U_EBCDIC_FAMILY
1139 /* On EBCDIC machines, the numbers are sorted last. Account for those in the skipped value too. */
1142 /* Skip over numeric UN tags. uloc_getISOCountries only returns ISO-3166 codes. */
1143 skipped
+= (key
!= NULL
);
1144 ures_getNextString(subRes
, NULL
, &key
, &status
);
1146 while (U_SUCCESS(status
) && key
!= NULL
&& strlen(key
) != 2);
1148 expect
-= skipped
; /* Ignore the skipped resources from structLocale */
1151 log_err("There is an error in getISOCountries, got %d, expected %d \n", count
, expect
);
1158 static void setUpDataTable()
1161 dataTable
= (UChar
***)(calloc(sizeof(UChar
**),LOCALE_INFO_SIZE
));
1163 for (i
= 0; i
< LOCALE_INFO_SIZE
; i
++) {
1164 dataTable
[i
] = (UChar
**)(calloc(sizeof(UChar
*),LOCALE_SIZE
));
1165 for (j
= 0; j
< LOCALE_SIZE
; j
++){
1166 dataTable
[i
][j
] = CharsToUChars(rawData2
[i
][j
]);
1171 static void cleanUpDataTable()
1174 if(dataTable
!= NULL
) {
1175 for (i
=0; i
<LOCALE_INFO_SIZE
; i
++) {
1176 for(j
= 0; j
< LOCALE_SIZE
; j
++) {
1177 free(dataTable
[i
][j
]);
1187 * @bug 4011756 4011380
1189 static void TestISO3Fallback()
1191 const char* test
="xx_YY";
1193 const char * result
;
1195 result
= uloc_getISO3Language(test
);
1197 /* Conform to C API usage */
1199 if (!result
|| (result
[0] != 0))
1200 log_err("getISO3Language() on xx_YY returned %s instead of \"\"");
1202 result
= uloc_getISO3Country(test
);
1204 if (!result
|| (result
[0] != 0))
1205 log_err("getISO3Country() on xx_YY returned %s instead of \"\"");
1211 static void TestSimpleDisplayNames()
1214 This test is different from TestDisplayNames because TestDisplayNames checks
1215 fallback behavior, combination of language and country names to form locale
1216 names, and other stuff like that. This test just checks specific language
1217 and country codes to make sure we have the correct names for them.
1219 char languageCodes
[] [4] = { "he", "id", "iu", "ug", "yi", "za", "419" };
1220 const char* languageNames
[] = { "Hebrew", "Indonesian", "Inuktitut", "Uyghur", "Yiddish",
1222 const char* inLocale
[] = { "en_US", "zh_Hant"};
1223 UErrorCode status
=U_ZERO_ERROR
;
1226 int32_t localeIndex
= 0;
1227 for (i
= 0; i
< 7; i
++) {
1229 UChar
*expectedLang
=0;
1233 localeIndex
= 1; /* Use the second locale for the rest of the test. */
1236 size
=uloc_getDisplayLanguage(languageCodes
[i
], inLocale
[localeIndex
], NULL
, size
, &status
);
1237 if(status
==U_BUFFER_OVERFLOW_ERROR
) {
1238 status
=U_ZERO_ERROR
;
1239 testLang
=(UChar
*)malloc(sizeof(UChar
) * (size
+ 1));
1240 uloc_getDisplayLanguage(languageCodes
[i
], inLocale
[localeIndex
], testLang
, size
+ 1, &status
);
1242 expectedLang
=(UChar
*)malloc(sizeof(UChar
) * (strlen(languageNames
[i
])+1));
1243 u_uastrcpy(expectedLang
, languageNames
[i
]);
1244 if (u_strcmp(testLang
, expectedLang
) != 0)
1245 log_data_err("Got wrong display name for %s : Expected \"%s\", got \"%s\".\n",
1246 languageCodes
[i
], languageNames
[i
], austrdup(testLang
));
1256 static void TestUninstalledISO3Names()
1258 /* This test checks to make sure getISO3Language and getISO3Country work right
1259 even for locales that are not installed. */
1260 static const char iso2Languages
[][4] = { "am", "ba", "fy", "mr", "rn",
1262 static const char iso3Languages
[][5] = { "amh", "bak", "fry", "mar", "run",
1263 "ssw", "twi", "zul" };
1264 static const char iso2Countries
[][6] = { "am_AF", "ba_BW", "fy_KZ", "mr_MO", "rn_MN",
1265 "ss_SB", "tw_TC", "zu_ZW" };
1266 static const char iso3Countries
[][4] = { "AFG", "BWA", "KAZ", "MAC", "MNG",
1267 "SLB", "TCA", "ZWE" };
1270 for (i
= 0; i
< 8; i
++) {
1271 UErrorCode err
= U_ZERO_ERROR
;
1273 test
= uloc_getISO3Language(iso2Languages
[i
]);
1274 if(strcmp(test
, iso3Languages
[i
]) !=0 || U_FAILURE(err
))
1275 log_err("Got wrong ISO3 code for %s : Expected \"%s\", got \"%s\". %s\n",
1276 iso2Languages
[i
], iso3Languages
[i
], test
, myErrorName(err
));
1278 for (i
= 0; i
< 8; i
++) {
1279 UErrorCode err
= U_ZERO_ERROR
;
1281 test
= uloc_getISO3Country(iso2Countries
[i
]);
1282 if(strcmp(test
, iso3Countries
[i
]) !=0 || U_FAILURE(err
))
1283 log_err("Got wrong ISO3 code for %s : Expected \"%s\", got \"%s\". %s\n",
1284 iso2Countries
[i
], iso3Countries
[i
], test
, myErrorName(err
));
1289 static void TestVariantParsing()
1291 static const char* en_US_custom
="en_US_De Anza_Cupertino_California_United States_Earth";
1292 static const char* dispName
="English (United States, DE ANZA_CUPERTINO_CALIFORNIA_UNITED STATES_EARTH)";
1293 static const char* dispVar
="DE ANZA_CUPERTINO_CALIFORNIA_UNITED STATES_EARTH";
1294 static const char* shortVariant
="fr_FR_foo";
1295 static const char* bogusVariant
="fr_FR__foo";
1296 static const char* bogusVariant2
="fr_FR_foo_";
1297 static const char* bogusVariant3
="fr_FR__foo_";
1300 UChar displayVar
[100];
1301 UChar displayName
[100];
1302 UErrorCode status
=U_ZERO_ERROR
;
1305 size
=uloc_getDisplayVariant(en_US_custom
, "en_US", NULL
, size
, &status
);
1306 if(status
==U_BUFFER_OVERFLOW_ERROR
) {
1307 status
=U_ZERO_ERROR
;
1308 got
=(UChar
*)realloc(got
, sizeof(UChar
) * (size
+1));
1309 uloc_getDisplayVariant(en_US_custom
, "en_US", got
, size
+ 1, &status
);
1312 log_err("FAIL: Didn't get U_BUFFER_OVERFLOW_ERROR\n");
1314 u_uastrcpy(displayVar
, dispVar
);
1315 if(u_strcmp(got
,displayVar
)!=0) {
1316 log_err("FAIL: getDisplayVariant() Wanted %s, got %s\n", dispVar
, austrdup(got
));
1319 size
=uloc_getDisplayName(en_US_custom
, "en_US", NULL
, size
, &status
);
1320 if(status
==U_BUFFER_OVERFLOW_ERROR
) {
1321 status
=U_ZERO_ERROR
;
1322 got
=(UChar
*)realloc(got
, sizeof(UChar
) * (size
+1));
1323 uloc_getDisplayName(en_US_custom
, "en_US", got
, size
+ 1, &status
);
1326 log_err("FAIL: Didn't get U_BUFFER_OVERFLOW_ERROR\n");
1328 u_uastrcpy(displayName
, dispName
);
1329 if(u_strcmp(got
,displayName
)!=0) {
1330 if (status
== U_USING_DEFAULT_WARNING
) {
1331 log_data_err("FAIL: getDisplayName() got %s. Perhaps you are missing data?\n", u_errorName(status
));
1333 log_err("FAIL: getDisplayName() Wanted %s, got %s\n", dispName
, austrdup(got
));
1338 status
=U_ZERO_ERROR
;
1339 size
=uloc_getDisplayVariant(shortVariant
, NULL
, NULL
, size
, &status
);
1340 if(status
==U_BUFFER_OVERFLOW_ERROR
) {
1341 status
=U_ZERO_ERROR
;
1342 got
=(UChar
*)realloc(got
, sizeof(UChar
) * (size
+1));
1343 uloc_getDisplayVariant(shortVariant
, NULL
, got
, size
+ 1, &status
);
1346 log_err("FAIL: Didn't get U_BUFFER_OVERFLOW_ERROR\n");
1348 if(strcmp(austrdup(got
),"FOO")!=0) {
1349 log_err("FAIL: getDisplayVariant() Wanted: foo Got: %s\n", austrdup(got
));
1352 status
=U_ZERO_ERROR
;
1353 size
=uloc_getDisplayVariant(bogusVariant
, NULL
, NULL
, size
, &status
);
1354 if(status
==U_BUFFER_OVERFLOW_ERROR
) {
1355 status
=U_ZERO_ERROR
;
1356 got
=(UChar
*)realloc(got
, sizeof(UChar
) * (size
+1));
1357 uloc_getDisplayVariant(bogusVariant
, NULL
, got
, size
+ 1, &status
);
1360 log_err("FAIL: Didn't get U_BUFFER_OVERFLOW_ERROR\n");
1362 if(strcmp(austrdup(got
),"_FOO")!=0) {
1363 log_err("FAIL: getDisplayVariant() Wanted: _FOO Got: %s\n", austrdup(got
));
1366 status
=U_ZERO_ERROR
;
1367 size
=uloc_getDisplayVariant(bogusVariant2
, NULL
, NULL
, size
, &status
);
1368 if(status
==U_BUFFER_OVERFLOW_ERROR
) {
1369 status
=U_ZERO_ERROR
;
1370 got
=(UChar
*)realloc(got
, sizeof(UChar
) * (size
+1));
1371 uloc_getDisplayVariant(bogusVariant2
, NULL
, got
, size
+ 1, &status
);
1374 log_err("FAIL: Didn't get U_BUFFER_OVERFLOW_ERROR\n");
1376 if(strcmp(austrdup(got
),"FOO_")!=0) {
1377 log_err("FAIL: getDisplayVariant() Wanted: FOO_ Got: %s\n", austrdup(got
));
1380 status
=U_ZERO_ERROR
;
1381 size
=uloc_getDisplayVariant(bogusVariant3
, NULL
, NULL
, size
, &status
);
1382 if(status
==U_BUFFER_OVERFLOW_ERROR
) {
1383 status
=U_ZERO_ERROR
;
1384 got
=(UChar
*)realloc(got
, sizeof(UChar
) * (size
+1));
1385 uloc_getDisplayVariant(bogusVariant3
, NULL
, got
, size
+ 1, &status
);
1388 log_err("FAIL: Didn't get U_BUFFER_OVERFLOW_ERROR\n");
1390 if(strcmp(austrdup(got
),"_FOO_")!=0) {
1391 log_err("FAIL: getDisplayVariant() Wanted: _FOO_ Got: %s\n", austrdup(got
));
1397 static void TestObsoleteNames(void)
1400 UErrorCode status
= U_ZERO_ERROR
;
1412 { "eng_USA", "eng", "en", "USA", "US" },
1413 { "kok", "kok", "kok", "", "" },
1414 { "in", "ind", "in", "", "" },
1415 { "id", "ind", "id", "", "" }, /* NO aliasing */
1416 { "sh", "srp", "sh", "", "" },
1417 { "zz_CS", "", "zz", "SCG", "CS" },
1418 { "zz_FX", "", "zz", "FXX", "FX" },
1419 { "zz_RO", "", "zz", "ROU", "RO" },
1420 { "zz_TP", "", "zz", "TMP", "TP" },
1421 { "zz_TL", "", "zz", "TLS", "TL" },
1422 { "zz_ZR", "", "zz", "ZAR", "ZR" },
1423 { "zz_FXX", "", "zz", "FXX", "FX" }, /* no aliasing. Doesn't go to PS(PSE). */
1424 { "zz_ROM", "", "zz", "ROU", "RO" },
1425 { "zz_ROU", "", "zz", "ROU", "RO" },
1426 { "zz_ZAR", "", "zz", "ZAR", "ZR" },
1427 { "zz_TMP", "", "zz", "TMP", "TP" },
1428 { "zz_TLS", "", "zz", "TLS", "TL" },
1429 { "zz_YUG", "", "zz", "YUG", "YU" },
1430 { "mlt_PSE", "mlt", "mt", "PSE", "PS" },
1431 { "iw", "heb", "iw", "", "" },
1432 { "ji", "yid", "ji", "", "" },
1433 { "jw", "jaw", "jw", "", "" },
1434 { "sh", "srp", "sh", "", "" },
1435 { "", "", "", "", "" }
1438 for(i
=0;tests
[i
].locale
[0];i
++)
1442 locale
= tests
[i
].locale
;
1443 log_verbose("** %s:\n", locale
);
1445 status
= U_ZERO_ERROR
;
1446 if(strcmp(tests
[i
].lang3
,uloc_getISO3Language(locale
)))
1448 log_err("FAIL: uloc_getISO3Language(%s)==\t\"%s\",\t expected \"%s\"\n",
1449 locale
, uloc_getISO3Language(locale
), tests
[i
].lang3
);
1453 log_verbose(" uloc_getISO3Language()==\t\"%s\"\n",
1454 uloc_getISO3Language(locale
) );
1457 status
= U_ZERO_ERROR
;
1458 uloc_getLanguage(locale
, buff
, 256, &status
);
1459 if(U_FAILURE(status
))
1461 log_err("FAIL: error getting language from %s\n", locale
);
1465 if(strcmp(buff
,tests
[i
].lang
))
1467 log_err("FAIL: uloc_getLanguage(%s)==\t\"%s\"\t expected \"%s\"\n",
1468 locale
, buff
, tests
[i
].lang
);
1472 log_verbose(" uloc_getLanguage(%s)==\t%s\n", locale
, buff
);
1475 if(strcmp(tests
[i
].lang3
,uloc_getISO3Language(locale
)))
1477 log_err("FAIL: uloc_getISO3Language(%s)==\t\"%s\",\t expected \"%s\"\n",
1478 locale
, uloc_getISO3Language(locale
), tests
[i
].lang3
);
1482 log_verbose(" uloc_getISO3Language()==\t\"%s\"\n",
1483 uloc_getISO3Language(locale
) );
1486 if(strcmp(tests
[i
].ctry3
,uloc_getISO3Country(locale
)))
1488 log_err("FAIL: uloc_getISO3Country(%s)==\t\"%s\",\t expected \"%s\"\n",
1489 locale
, uloc_getISO3Country(locale
), tests
[i
].ctry3
);
1493 log_verbose(" uloc_getISO3Country()==\t\"%s\"\n",
1494 uloc_getISO3Country(locale
) );
1497 status
= U_ZERO_ERROR
;
1498 uloc_getCountry(locale
, buff
, 256, &status
);
1499 if(U_FAILURE(status
))
1501 log_err("FAIL: error getting country from %s\n", locale
);
1505 if(strcmp(buff
,tests
[i
].ctry
))
1507 log_err("FAIL: uloc_getCountry(%s)==\t\"%s\"\t expected \"%s\"\n",
1508 locale
, buff
, tests
[i
].ctry
);
1512 log_verbose(" uloc_getCountry(%s)==\t%s\n", locale
, buff
);
1517 if (uloc_getLCID("iw_IL") != uloc_getLCID("he_IL")) {
1518 log_err("he,iw LCID mismatch: %X versus %X\n", uloc_getLCID("iw_IL"), uloc_getLCID("he_IL"));
1521 if (uloc_getLCID("iw") != uloc_getLCID("he")) {
1522 log_err("he,iw LCID mismatch: %X versus %X\n", uloc_getLCID("iw"), uloc_getLCID("he"));
1527 i
= uloc_getLanguage("kok",NULL
,0,&icu_err
);
1528 if(U_FAILURE(icu_err
))
1530 log_err("FAIL: Got %s trying to do uloc_getLanguage(kok)\n", u_errorName(icu_err
));
1533 icu_err
= U_ZERO_ERROR
;
1534 uloc_getLanguage("kok",r1_buff
,12,&icu_err
);
1535 if(U_FAILURE(icu_err
))
1537 log_err("FAIL: Got %s trying to do uloc_getLanguage(kok, buff)\n", u_errorName(icu_err
));
1540 r1_addr
= (char *)uloc_getISO3Language("kok");
1542 icu_err
= U_ZERO_ERROR
;
1543 if (strcmp(r1_buff
,"kok") != 0)
1545 log_err("FAIL: uloc_getLanguage(kok)==%s not kok\n",r1_buff
);
1548 r1_addr
= (char *)uloc_getISO3Language("in");
1549 i
= uloc_getLanguage(r1_addr
,r1_buff
,12,&icu_err
);
1550 if (strcmp(r1_buff
,"id") != 0)
1552 printf("uloc_getLanguage error (%s)\n",r1_buff
);
1555 r1_addr
= (char *)uloc_getISO3Language("sh");
1556 i
= uloc_getLanguage(r1_addr
,r1_buff
,12,&icu_err
);
1557 if (strcmp(r1_buff
,"sr") != 0)
1559 printf("uloc_getLanguage error (%s)\n",r1_buff
);
1563 r1_addr
= (char *)uloc_getISO3Country("zz_ZR");
1564 strcpy(p1_buff
,"zz_");
1565 strcat(p1_buff
,r1_addr
);
1566 i
= uloc_getCountry(p1_buff
,r1_buff
,12,&icu_err
);
1567 if (strcmp(r1_buff
,"ZR") != 0)
1569 printf("uloc_getCountry error (%s)\n",r1_buff
);
1572 r1_addr
= (char *)uloc_getISO3Country("zz_FX");
1573 strcpy(p1_buff
,"zz_");
1574 strcat(p1_buff
,r1_addr
);
1575 i
= uloc_getCountry(p1_buff
,r1_buff
,12,&icu_err
);
1576 if (strcmp(r1_buff
,"FX") != 0)
1578 printf("uloc_getCountry error (%s)\n",r1_buff
);
1586 static void TestKeywordVariants(void)
1588 static const struct {
1589 const char *localeID
;
1590 const char *expectedLocaleID
;
1591 const char *expectedLocaleIDNoKeywords
;
1592 const char *expectedCanonicalID
;
1593 const char *expectedKeywords
[10];
1594 int32_t numKeywords
;
1595 UErrorCode expectedStatus
; /* from uloc_openKeywords */
1598 "de_DE@ currency = euro; C o ll A t i o n = Phonebook ; C alen dar = buddhist ",
1599 "de_DE@calendar=buddhist;collation=Phonebook;currency=euro",
1601 "de_DE@calendar=buddhist;collation=Phonebook;currency=euro",
1602 {"calendar", "collation", "currency"},
1610 "de_DE@currency=EUR",
1611 {"","","","","","",""},
1613 U_INVALID_FORMAT_ERROR
/* must have '=' after '@' */
1616 "de_DE@euro;collation=phonebook",
1617 "de_DE", /* error result; bad format */
1618 "de_DE", /* error result; bad format */
1619 "de_DE", /* error result; bad format */
1620 {"","","","","","",""},
1622 U_INVALID_FORMAT_ERROR
1625 UErrorCode status
= U_ZERO_ERROR
;
1627 int32_t i
= 0, j
= 0;
1628 int32_t resultLen
= 0;
1630 UEnumeration
*keywords
;
1631 int32_t keyCount
= 0;
1632 const char *keyword
= NULL
;
1633 int32_t keywordLen
= 0;
1635 for(i
= 0; i
< sizeof(testCases
)/sizeof(testCases
[0]); i
++) {
1636 status
= U_ZERO_ERROR
;
1638 keywords
= uloc_openKeywords(testCases
[i
].localeID
, &status
);
1640 if(status
!= testCases
[i
].expectedStatus
) {
1641 log_err("Expected to uloc_openKeywords(\"%s\") => status %s. Got %s instead\n",
1642 testCases
[i
].localeID
,
1643 u_errorName(testCases
[i
].expectedStatus
), u_errorName(status
));
1645 status
= U_ZERO_ERROR
;
1647 if((keyCount
= uenum_count(keywords
, &status
)) != testCases
[i
].numKeywords
) {
1648 log_err("Expected to get %i keywords, got %i\n", testCases
[i
].numKeywords
, keyCount
);
1652 while((keyword
= uenum_next(keywords
, &keywordLen
, &status
))) {
1653 if(strcmp(keyword
, testCases
[i
].expectedKeywords
[j
]) != 0) {
1654 log_err("Expected to get keyword value %s, got %s\n", testCases
[i
].expectedKeywords
[j
], keyword
);
1659 uenum_reset(keywords
, &status
);
1660 while((keyword
= uenum_next(keywords
, &keywordLen
, &status
))) {
1661 if(strcmp(keyword
, testCases
[i
].expectedKeywords
[j
]) != 0) {
1662 log_err("Expected to get keyword value %s, got %s\n", testCases
[i
].expectedKeywords
[j
], keyword
);
1667 uenum_close(keywords
);
1669 resultLen
= uloc_getName(testCases
[i
].localeID
, buffer
, 256, &status
);
1670 if (uprv_strcmp(testCases
[i
].expectedLocaleID
, buffer
) != 0) {
1671 log_err("Expected uloc_getName(\"%s\") => \"%s\"; got \"%s\"\n",
1672 testCases
[i
].localeID
, testCases
[i
].expectedLocaleID
, buffer
);
1674 resultLen
= uloc_canonicalize(testCases
[i
].localeID
, buffer
, 256, &status
);
1675 if (uprv_strcmp(testCases
[i
].expectedCanonicalID
, buffer
) != 0) {
1676 log_err("Expected uloc_canonicalize(\"%s\") => \"%s\"; got \"%s\"\n",
1677 testCases
[i
].localeID
, testCases
[i
].expectedCanonicalID
, buffer
);
1683 static void TestKeywordVariantParsing(void)
1685 static const struct {
1686 const char *localeID
;
1687 const char *keyword
;
1688 const char *expectedValue
;
1690 { "de_DE@ C o ll A t i o n = Phonebook ", "c o ll a t i o n", "Phonebook" },
1691 { "de_DE", "collation", ""},
1692 { "de_DE@collation=PHONEBOOK", "collation", "PHONEBOOK" },
1693 { "de_DE@currency = euro; CoLLaTion = PHONEBOOk", "collatiON", "PHONEBOOk" },
1696 UErrorCode status
= U_ZERO_ERROR
;
1699 int32_t resultLen
= 0;
1702 for(i
= 0; i
< sizeof(testCases
)/sizeof(testCases
[0]); i
++) {
1704 resultLen
= uloc_getKeywordValue(testCases
[i
].localeID
, testCases
[i
].keyword
, buffer
, 256, &status
);
1705 if(uprv_strcmp(testCases
[i
].expectedValue
, buffer
) != 0) {
1706 log_err("Expected to extract \"%s\" from \"%s\" for keyword \"%s\". Got \"%s\" instead\n",
1707 testCases
[i
].expectedValue
, testCases
[i
].localeID
, testCases
[i
].keyword
, buffer
);
1712 static const struct {
1713 const char *l
; /* locale */
1714 const char *k
; /* kw */
1715 const char *v
; /* value */
1716 const char *x
; /* expected */
1717 } kwSetTestCases
[] = {
1719 { "en_US", "calendar", "japanese", "en_US@calendar=japanese" },
1720 { "en_US@", "calendar", "japanese", "en_US@calendar=japanese" },
1721 { "en_US@calendar=islamic", "calendar", "japanese", "en_US@calendar=japanese" },
1722 { "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 */
1723 { "en_US@calendar=gregorian", "calendar", "japanese", "en_US@calendar=japanese" },
1724 { "de", "Currency", "CHF", "de@currency=CHF" },
1725 { "de", "Currency", "CHF", "de@currency=CHF" },
1727 { "en_US@collation=phonebook", "calendar", "japanese", "en_US@calendar=japanese;collation=phonebook" },
1728 { "en_US@calendar=japanese", "collation", "phonebook", "en_US@calendar=japanese;collation=phonebook" },
1729 { "de@collation=phonebook", "Currency", "CHF", "de@collation=phonebook;currency=CHF" },
1730 { "en_US@calendar=gregorian;collation=phonebook", "calendar", "japanese", "en_US@calendar=japanese;collation=phonebook" },
1731 { "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 */
1732 { "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 */
1733 { "en_US@calendar=islamic;collation=phonebook", "calendar", "japanese", "en_US@calendar=japanese;collation=phonebook" },
1734 { "de@collation=phonebook", "Currency", "CHF", "de@collation=phonebook;currency=CHF" },
1737 { "mt@a=0;b=1;c=2;d=3", "c","j", "mt@a=0;b=1;c=j;d=3" },
1738 { "mt@a=0;b=1;c=2;d=3", "x","j", "mt@a=0;b=1;c=2;d=3;x=j" },
1739 { "mt@a=0;b=1;c=2;d=3", "a","f", "mt@a=f;b=1;c=2;d=3" },
1740 { "mt@a=0;aa=1;aaa=3", "a","x", "mt@a=x;aa=1;aaa=3" },
1741 { "mt@a=0;aa=1;aaa=3", "aa","x", "mt@a=0;aa=x;aaa=3" },
1742 { "mt@a=0;aa=1;aaa=3", "aaa","x", "mt@a=0;aa=1;aaa=x" },
1743 { "mt@a=0;aa=1;aaa=3", "a","yy", "mt@a=yy;aa=1;aaa=3" },
1744 { "mt@a=0;aa=1;aaa=3", "aa","yy", "mt@a=0;aa=yy;aaa=3" },
1745 { "mt@a=0;aa=1;aaa=3", "aaa","yy", "mt@a=0;aa=1;aaa=yy" },
1749 /* 1. removal of item at end */
1750 { "de@collation=phonebook;currency=CHF", "currency", "", "de@collation=phonebook" },
1751 { "de@collation=phonebook;currency=CHF", "currency", NULL
, "de@collation=phonebook" },
1752 /* 2. removal of item at beginning */
1753 { "de@collation=phonebook;currency=CHF", "collation", "", "de@currency=CHF" },
1754 { "de@collation=phonebook;currency=CHF", "collation", NULL
, "de@currency=CHF" },
1755 /* 3. removal of an item not there */
1756 { "de@collation=phonebook;currency=CHF", "calendar", NULL
, "de@collation=phonebook;currency=CHF" },
1757 /* 4. removal of only item */
1758 { "de@collation=phonebook", "collation", NULL
, "de" },
1760 { "de@collation=phonebook", "Currency", "CHF", "de@collation=phonebook;currency=CHF" }
1764 static void TestKeywordSet(void)
1767 int32_t resultLen
= 0;
1772 for(i
= 0; i
< sizeof(kwSetTestCases
)/sizeof(kwSetTestCases
[0]); i
++) {
1773 UErrorCode status
= U_ZERO_ERROR
;
1774 memset(buffer
,'%',1023);
1775 strcpy(buffer
, kwSetTestCases
[i
].l
);
1777 uloc_canonicalize(kwSetTestCases
[i
].l
, cbuffer
, 1023, &status
);
1778 if(strcmp(buffer
,cbuffer
)) {
1779 log_verbose("note: [%d] wasn't canonical, should be: '%s' not '%s'. Won't check for canonicity in output.\n", i
, cbuffer
, buffer
);
1781 /* sanity check test case results for canonicity */
1782 uloc_canonicalize(kwSetTestCases
[i
].x
, cbuffer
, 1023, &status
);
1783 if(strcmp(kwSetTestCases
[i
].x
,cbuffer
)) {
1784 log_err("%s:%d: ERROR: kwSetTestCases[%d].x = '%s', should be %s (must be canonical)\n", __FILE__
, __LINE__
, i
, kwSetTestCases
[i
].x
, cbuffer
);
1787 resultLen
= uloc_setKeywordValue(kwSetTestCases
[i
].k
, kwSetTestCases
[i
].v
, buffer
, 1023, &status
);
1788 if(U_FAILURE(status
)) {
1789 log_err("Err on test case %d: got error %s\n", i
, u_errorName(status
));
1792 if(strcmp(buffer
,kwSetTestCases
[i
].x
) || ((int32_t)strlen(buffer
)!=resultLen
)) {
1793 log_err("FAIL: #%d: %s + [%s=%s] -> %s (%d) expected %s (%d)\n", i
, kwSetTestCases
[i
].l
, kwSetTestCases
[i
].k
,
1794 kwSetTestCases
[i
].v
, buffer
, resultLen
, kwSetTestCases
[i
].x
, strlen(buffer
));
1796 log_verbose("pass: #%d: %s + [%s=%s] -> %s\n", i
, kwSetTestCases
[i
].l
, kwSetTestCases
[i
].k
, kwSetTestCases
[i
].v
,buffer
);
1801 static void TestKeywordSetError(void)
1809 /* 0-test whether an error condition modifies the buffer at all */
1812 memset(buffer
,'%',1023);
1813 status
= U_ZERO_ERROR
;
1814 res
= uloc_setKeywordValue(kwSetTestCases
[i
].k
, kwSetTestCases
[i
].v
, buffer
, blen
, &status
);
1815 if(status
!= U_ILLEGAL_ARGUMENT_ERROR
) {
1816 log_err("expected illegal err got %s\n", u_errorName(status
));
1819 /* if(res!=strlen(kwSetTestCases[i].x)) {
1820 log_err("expected result %d got %d\n", strlen(kwSetTestCases[i].x), res);
1823 if(buffer
[blen
]!='%') {
1824 log_err("Buffer byte %d was modified: now %c\n", blen
, buffer
[blen
]);
1827 log_verbose("0-buffer modify OK\n");
1830 /* 1- test a short buffer with growing text */
1831 blen
=(int32_t)strlen(kwSetTestCases
[i
].l
)+1;
1832 memset(buffer
,'%',1023);
1833 strcpy(buffer
,kwSetTestCases
[i
].l
);
1834 status
= U_ZERO_ERROR
;
1835 res
= uloc_setKeywordValue(kwSetTestCases
[i
].k
, kwSetTestCases
[i
].v
, buffer
, blen
, &status
);
1836 if(status
!= U_BUFFER_OVERFLOW_ERROR
) {
1837 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
);
1840 if(res
!=(int32_t)strlen(kwSetTestCases
[i
].x
)) {
1841 log_err("expected result %d got %d\n", strlen(kwSetTestCases
[i
].x
), res
);
1844 if(buffer
[blen
]!='%') {
1845 log_err("Buffer byte %d was modified: now %c\n", blen
, buffer
[blen
]);
1848 log_verbose("1/%d-buffer modify OK\n",i
);
1852 /* 2- test a short buffer - text the same size or shrinking */
1853 blen
=(int32_t)strlen(kwSetTestCases
[i
].l
)+1;
1854 memset(buffer
,'%',1023);
1855 strcpy(buffer
,kwSetTestCases
[i
].l
);
1856 status
= U_ZERO_ERROR
;
1857 res
= uloc_setKeywordValue(kwSetTestCases
[i
].k
, kwSetTestCases
[i
].v
, buffer
, blen
, &status
);
1858 if(status
!= U_ZERO_ERROR
) {
1859 log_err("expected zero error got %s\n", u_errorName(status
));
1862 if(buffer
[blen
+1]!='%') {
1863 log_err("Buffer byte %d was modified: now %c\n", blen
+1, buffer
[blen
+1]);
1866 if(res
!=(int32_t)strlen(kwSetTestCases
[i
].x
)) {
1867 log_err("expected result %d got %d\n", strlen(kwSetTestCases
[i
].x
), res
);
1870 if(strcmp(buffer
,kwSetTestCases
[i
].x
) || ((int32_t)strlen(buffer
)!=res
)) {
1871 log_err("FAIL: #%d: %s + [%s=%s] -> %s (%d) expected %s (%d)\n", i
, kwSetTestCases
[i
].l
, kwSetTestCases
[i
].k
,
1872 kwSetTestCases
[i
].v
, buffer
, res
, kwSetTestCases
[i
].x
, strlen(buffer
));
1874 log_verbose("pass: #%d: %s + [%s=%s] -> %s\n", i
, kwSetTestCases
[i
].l
, kwSetTestCases
[i
].k
, kwSetTestCases
[i
].v
,
1877 log_verbose("2/%d-buffer modify OK\n",i
);
1881 static int32_t _canonicalize(int32_t selector
, /* 0==getName, 1==canonicalize */
1882 const char* localeID
,
1884 int32_t resultCapacity
,
1886 /* YOU can change this to use function pointers if you like */
1889 return uloc_getName(localeID
, result
, resultCapacity
, ec
);
1891 return uloc_canonicalize(localeID
, result
, resultCapacity
, ec
);
1897 static void TestCanonicalization(void)
1899 static const struct {
1900 const char *localeID
; /* input */
1901 const char *getNameID
; /* expected getName() result */
1902 const char *canonicalID
; /* expected canonicalize() result */
1904 { "ca_ES_PREEURO-with-extra-stuff-that really doesn't make any sense-unless-you're trying to increase code coverage",
1905 "ca_ES_PREEURO_WITH_EXTRA_STUFF_THAT REALLY DOESN'T MAKE ANY SENSE_UNLESS_YOU'RE TRYING TO INCREASE CODE COVERAGE",
1906 "ca_ES_PREEURO_WITH_EXTRA_STUFF_THAT REALLY DOESN'T MAKE ANY SENSE_UNLESS_YOU'RE TRYING TO INCREASE CODE COVERAGE"},
1907 { "ca_ES_PREEURO", "ca_ES_PREEURO", "ca_ES@currency=ESP" },
1908 { "de_AT_PREEURO", "de_AT_PREEURO", "de_AT@currency=ATS" },
1909 { "de_DE_PREEURO", "de_DE_PREEURO", "de_DE@currency=DEM" },
1910 { "de_LU_PREEURO", "de_LU_PREEURO", "de_LU@currency=LUF" },
1911 { "el_GR_PREEURO", "el_GR_PREEURO", "el_GR@currency=GRD" },
1912 { "en_BE_PREEURO", "en_BE_PREEURO", "en_BE@currency=BEF" },
1913 { "en_IE_PREEURO", "en_IE_PREEURO", "en_IE@currency=IEP" },
1914 { "es_ES_PREEURO", "es_ES_PREEURO", "es_ES@currency=ESP" },
1915 { "eu_ES_PREEURO", "eu_ES_PREEURO", "eu_ES@currency=ESP" },
1916 { "fi_FI_PREEURO", "fi_FI_PREEURO", "fi_FI@currency=FIM" },
1917 { "fr_BE_PREEURO", "fr_BE_PREEURO", "fr_BE@currency=BEF" },
1918 { "fr_FR_PREEURO", "fr_FR_PREEURO", "fr_FR@currency=FRF" },
1919 { "fr_LU_PREEURO", "fr_LU_PREEURO", "fr_LU@currency=LUF" },
1920 { "ga_IE_PREEURO", "ga_IE_PREEURO", "ga_IE@currency=IEP" },
1921 { "gl_ES_PREEURO", "gl_ES_PREEURO", "gl_ES@currency=ESP" },
1922 { "it_IT_PREEURO", "it_IT_PREEURO", "it_IT@currency=ITL" },
1923 { "nl_BE_PREEURO", "nl_BE_PREEURO", "nl_BE@currency=BEF" },
1924 { "nl_NL_PREEURO", "nl_NL_PREEURO", "nl_NL@currency=NLG" },
1925 { "pt_PT_PREEURO", "pt_PT_PREEURO", "pt_PT@currency=PTE" },
1926 { "de__PHONEBOOK", "de__PHONEBOOK", "de@collation=phonebook" },
1927 { "en_GB_EURO", "en_GB_EURO", "en_GB@currency=EUR" },
1928 { "en_GB@EURO", "en_GB@EURO", "en_GB@currency=EUR" }, /* POSIX ID */
1929 { "es__TRADITIONAL", "es__TRADITIONAL", "es@collation=traditional" },
1930 { "hi__DIRECT", "hi__DIRECT", "hi@collation=direct" },
1931 { "ja_JP_TRADITIONAL", "ja_JP_TRADITIONAL", "ja_JP@calendar=japanese" },
1932 { "th_TH_TRADITIONAL", "th_TH_TRADITIONAL", "th_TH@calendar=buddhist" },
1933 { "zh_TW_STROKE", "zh_TW_STROKE", "zh_TW@collation=stroke" },
1934 { "zh__PINYIN", "zh__PINYIN", "zh@collation=pinyin" },
1935 { "zh@collation=pinyin", "zh@collation=pinyin", "zh@collation=pinyin" },
1936 { "zh_CN@collation=pinyin", "zh_CN@collation=pinyin", "zh_CN@collation=pinyin" },
1937 { "zh_CN_STROKE", "zh_CN_STROKE", "zh_CN@collation=stroke" },
1938 { "zh_CN_CA@collation=pinyin", "zh_CN_CA@collation=pinyin", "zh_CN_CA@collation=pinyin" },
1939 { "en_US_POSIX", "en_US_POSIX", "en_US_POSIX" },
1940 { "hy_AM_REVISED", "hy_AM_REVISED", "hy_AM_REVISED" },
1941 { "no_NO_NY", "no_NO_NY", "no_NO_NY" /* not: "nn_NO" [alan ICU3.0] */ },
1942 { "no@ny", "no@ny", "no__NY" /* not: "nn" [alan ICU3.0] */ }, /* POSIX ID */
1943 { "no-no.utf32@B", "no_NO.utf32@B", "no_NO_B" /* not: "nb_NO_B" [alan ICU3.0] */ }, /* POSIX ID */
1944 { "qz-qz@Euro", "qz_QZ@Euro", "qz_QZ@currency=EUR" }, /* qz-qz uses private use iso codes */
1945 { "en-BOONT", "en__BOONT", "en__BOONT" }, /* registered name */
1946 { "de-1901", "de__1901", "de__1901" }, /* registered name */
1947 { "de-1906", "de__1906", "de__1906" }, /* registered name */
1948 { "sr-SP-Cyrl", "sr_SP_CYRL", "sr_Cyrl_RS" }, /* .NET name */
1949 { "sr-SP-Latn", "sr_SP_LATN", "sr_Latn_RS" }, /* .NET name */
1950 { "sr_YU_CYRILLIC", "sr_YU_CYRILLIC", "sr_Cyrl_RS" }, /* Linux name */
1951 { "uz-UZ-Cyrl", "uz_UZ_CYRL", "uz_Cyrl_UZ" }, /* .NET name */
1952 { "uz-UZ-Latn", "uz_UZ_LATN", "uz_Latn_UZ" }, /* .NET name */
1953 { "zh-CHS", "zh_CHS", "zh_Hans" }, /* .NET name */
1954 { "zh-CHT", "zh_CHT", "zh_Hant" }, /* .NET name This may change back to zh_Hant */
1956 /* posix behavior that used to be performed by getName */
1957 { "mr.utf8", "mr.utf8", "mr" },
1958 { "de-tv.koi8r", "de_TV.koi8r", "de_TV" },
1959 { "x-piglatin_ML.MBE", "x-piglatin_ML.MBE", "x-piglatin_ML" },
1960 { "i-cherokee_US.utf7", "i-cherokee_US.utf7", "i-cherokee_US" },
1961 { "x-filfli_MT_FILFLA.gb-18030", "x-filfli_MT_FILFLA.gb-18030", "x-filfli_MT_FILFLA" },
1962 { "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 */
1964 /* fleshing out canonicalization */
1965 /* trim space and sort keywords, ';' is separator so not present at end in canonical form */
1966 { "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" },
1967 /* already-canonical ids are not changed */
1968 { "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" },
1969 /* PRE_EURO and EURO conversions don't affect other keywords */
1970 { "es_ES_PREEURO@CALendar=Japanese", "es_ES_PREEURO@calendar=Japanese", "es_ES@calendar=Japanese;currency=ESP" },
1971 { "es_ES_EURO@SHOUT=zipeedeedoodah", "es_ES_EURO@shout=zipeedeedoodah", "es_ES@currency=EUR;shout=zipeedeedoodah" },
1972 /* currency keyword overrides PRE_EURO and EURO currency */
1973 { "es_ES_PREEURO@currency=EUR", "es_ES_PREEURO@currency=EUR", "es_ES@currency=EUR" },
1974 { "es_ES_EURO@currency=ESP", "es_ES_EURO@currency=ESP", "es_ES@currency=ESP" },
1975 /* norwegian is just too weird, if we handle things in their full generality */
1976 { "no-Hant-GB_NY@currency=$$$", "no_Hant_GB_NY@currency=$$$", "no_Hant_GB_NY@currency=$$$" /* not: "nn_Hant_GB@currency=$$$" [alan ICU3.0] */ },
1978 /* test cases reflecting internal resource bundle usage */
1979 { "root@kw=foo", "root@kw=foo", "root@kw=foo" },
1980 { "@calendar=gregorian", "@calendar=gregorian", "@calendar=gregorian" },
1981 { "ja_JP@calendar=Japanese", "ja_JP@calendar=Japanese", "ja_JP@calendar=Japanese" },
1982 { "ja_JP", "ja_JP", "ja_JP" },
1984 /* test case for "i-default" */
1985 { "i-default", "en@x=i-default", "en@x=i-default" }
1988 static const char* label
[] = { "getName", "canonicalize" };
1990 UErrorCode status
= U_ZERO_ERROR
;
1991 int32_t i
, j
, resultLen
= 0, origResultLen
;
1994 for (i
=0; i
< sizeof(testCases
)/sizeof(testCases
[0]); i
++) {
1995 for (j
=0; j
<2; ++j
) {
1996 const char* expected
= (j
==0) ? testCases
[i
].getNameID
: testCases
[i
].canonicalID
;
1998 status
= U_ZERO_ERROR
;
2000 if (expected
== NULL
) {
2001 expected
= uloc_getDefault();
2004 /* log_verbose("testing %s -> %s\n", testCases[i], testCases[i].canonicalID); */
2005 origResultLen
= _canonicalize(j
, testCases
[i
].localeID
, NULL
, 0, &status
);
2006 if (status
!= U_BUFFER_OVERFLOW_ERROR
) {
2007 log_err("FAIL: uloc_%s(%s) => %s, expected U_BUFFER_OVERFLOW_ERROR\n",
2008 label
[j
], testCases
[i
].localeID
, u_errorName(status
));
2011 status
= U_ZERO_ERROR
;
2012 resultLen
= _canonicalize(j
, testCases
[i
].localeID
, buffer
, sizeof(buffer
), &status
);
2013 if (U_FAILURE(status
)) {
2014 log_err("FAIL: uloc_%s(%s) => %s, expected U_ZERO_ERROR\n",
2015 label
[j
], testCases
[i
].localeID
, u_errorName(status
));
2018 if(uprv_strcmp(expected
, buffer
) != 0) {
2019 log_err("FAIL: uloc_%s(%s) => \"%s\", expected \"%s\"\n",
2020 label
[j
], testCases
[i
].localeID
, buffer
, expected
);
2022 log_verbose("Ok: uloc_%s(%s) => \"%s\"\n",
2023 label
[j
], testCases
[i
].localeID
, buffer
);
2025 if (resultLen
!= (int32_t)strlen(buffer
)) {
2026 log_err("FAIL: uloc_%s(%s) => len %d, expected len %d\n",
2027 label
[j
], testCases
[i
].localeID
, resultLen
, strlen(buffer
));
2029 if (origResultLen
!= resultLen
) {
2030 log_err("FAIL: uloc_%s(%s) => preflight len %d != actual len %d\n",
2031 label
[j
], testCases
[i
].localeID
, origResultLen
, resultLen
);
2037 static void TestDisplayKeywords(void)
2041 static const struct {
2042 const char *localeID
;
2043 const char *displayLocale
;
2044 UChar displayKeyword
[200];
2046 { "ca_ES@currency=ESP", "de_AT",
2047 {0x0057, 0x00e4, 0x0068, 0x0072, 0x0075, 0x006e, 0x0067, 0x0000},
2049 { "ja_JP@calendar=japanese", "de",
2050 { 0x004b, 0x0061, 0x006c, 0x0065, 0x006e, 0x0064, 0x0065, 0x0072, 0x0000}
2052 { "de_DE@collation=traditional", "de_DE",
2053 {0x0053, 0x006f, 0x0072, 0x0074, 0x0069, 0x0065, 0x0072, 0x0075, 0x006e, 0x0067, 0x0000}
2056 for(i
= 0; i
< sizeof(testCases
)/sizeof(testCases
[0]); i
++) {
2057 UErrorCode status
= U_ZERO_ERROR
;
2058 const char* keyword
=NULL
;
2059 int32_t keywordLen
= 0;
2060 int32_t keywordCount
= 0;
2061 UChar
*displayKeyword
=NULL
;
2062 int32_t displayKeywordLen
= 0;
2063 UEnumeration
* keywordEnum
= uloc_openKeywords(testCases
[i
].localeID
, &status
);
2064 for(keywordCount
= uenum_count(keywordEnum
, &status
); keywordCount
> 0 ; keywordCount
--){
2065 if(U_FAILURE(status
)){
2066 log_err("uloc_getKeywords failed for locale id: %s with error : %s \n", testCases
[i
].localeID
, u_errorName(status
));
2069 /* the uenum_next returns NUL terminated string */
2070 keyword
= uenum_next(keywordEnum
, &keywordLen
, &status
);
2071 /* fetch the displayKeyword */
2072 displayKeywordLen
= uloc_getDisplayKeyword(keyword
, testCases
[i
].displayLocale
, displayKeyword
, displayKeywordLen
, &status
);
2073 if(status
==U_BUFFER_OVERFLOW_ERROR
){
2074 status
= U_ZERO_ERROR
;
2075 displayKeywordLen
++; /* for null termination */
2076 displayKeyword
= (UChar
*) malloc(displayKeywordLen
* U_SIZEOF_UCHAR
);
2077 displayKeywordLen
= uloc_getDisplayKeyword(keyword
, testCases
[i
].displayLocale
, displayKeyword
, displayKeywordLen
, &status
);
2078 if(U_FAILURE(status
)){
2079 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
));
2082 if(u_strncmp(displayKeyword
, testCases
[i
].displayKeyword
, displayKeywordLen
)!=0){
2083 if (status
== U_USING_DEFAULT_WARNING
) {
2084 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
));
2086 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
);
2091 log_err("uloc_getDisplayKeyword did not return the expected error. Error: %s\n", u_errorName(status
));
2094 free(displayKeyword
);
2097 uenum_close(keywordEnum
);
2101 static void TestDisplayKeywordValues(void){
2104 static const struct {
2105 const char *localeID
;
2106 const char *displayLocale
;
2107 UChar displayKeywordValue
[500];
2109 { "ca_ES@currency=ESP", "de_AT",
2110 {0x0053, 0x0070, 0x0061, 0x006e, 0x0069, 0x0073, 0x0063, 0x0068, 0x0065, 0x0020, 0x0050, 0x0065, 0x0073, 0x0065, 0x0074, 0x0061, 0x0000}
2112 { "de_AT@currency=ATS", "fr_FR",
2113 {0x0073, 0x0063, 0x0068, 0x0069, 0x006c, 0x006c, 0x0069, 0x006e, 0x0067, 0x0020, 0x0061, 0x0075, 0x0074, 0x0072, 0x0069, 0x0063, 0x0068, 0x0069, 0x0065, 0x006e, 0x0000}
2115 { "de_DE@currency=DEM", "it",
2116 {0x004d, 0x0061, 0x0072, 0x0063, 0x006f, 0x0020, 0x0054, 0x0065, 0x0064, 0x0065, 0x0073, 0x0063, 0x006f, 0x0000}
2118 { "el_GR@currency=GRD", "en",
2119 {0x0047, 0x0072, 0x0065, 0x0065, 0x006b, 0x0020, 0x0044, 0x0072, 0x0061, 0x0063, 0x0068, 0x006d, 0x0061, 0x0000}
2121 { "eu_ES@currency=ESP", "it_IT",
2122 {0x0050, 0x0065, 0x0073, 0x0065, 0x0074, 0x0061, 0x0020, 0x0053, 0x0070, 0x0061, 0x0067, 0x006e, 0x006f, 0x006c, 0x0061, 0x0000}
2124 { "de@collation=phonebook", "es",
2125 {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}
2128 { "de_DE@collation=phonebook", "es",
2129 {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}
2131 { "es_ES@collation=traditional","de",
2132 {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}
2134 { "ja_JP@calendar=japanese", "de",
2135 {0x004a, 0x0061, 0x0070, 0x0061, 0x006e, 0x0069, 0x0073, 0x0063, 0x0068, 0x0065, 0x0072, 0x0020, 0x004b, 0x0061, 0x006c, 0x0065, 0x006e, 0x0064, 0x0065, 0x0072, 0x0000}
2138 for(i
= 0; i
< sizeof(testCases
)/sizeof(testCases
[0]); i
++) {
2139 UErrorCode status
= U_ZERO_ERROR
;
2140 const char* keyword
=NULL
;
2141 int32_t keywordLen
= 0;
2142 int32_t keywordCount
= 0;
2143 UChar
*displayKeywordValue
= NULL
;
2144 int32_t displayKeywordValueLen
= 0;
2145 UEnumeration
* keywordEnum
= uloc_openKeywords(testCases
[i
].localeID
, &status
);
2146 for(keywordCount
= uenum_count(keywordEnum
, &status
); keywordCount
> 0 ; keywordCount
--){
2147 if(U_FAILURE(status
)){
2148 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
));
2151 /* the uenum_next returns NUL terminated string */
2152 keyword
= uenum_next(keywordEnum
, &keywordLen
, &status
);
2154 /* fetch the displayKeywordValue */
2155 displayKeywordValueLen
= uloc_getDisplayKeywordValue(testCases
[i
].localeID
, keyword
, testCases
[i
].displayLocale
, displayKeywordValue
, displayKeywordValueLen
, &status
);
2156 if(status
==U_BUFFER_OVERFLOW_ERROR
){
2157 status
= U_ZERO_ERROR
;
2158 displayKeywordValueLen
++; /* for null termination */
2159 displayKeywordValue
= (UChar
*)malloc(displayKeywordValueLen
* U_SIZEOF_UCHAR
);
2160 displayKeywordValueLen
= uloc_getDisplayKeywordValue(testCases
[i
].localeID
, keyword
, testCases
[i
].displayLocale
, displayKeywordValue
, displayKeywordValueLen
, &status
);
2161 if(U_FAILURE(status
)){
2162 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
));
2165 if(u_strncmp(displayKeywordValue
, testCases
[i
].displayKeywordValue
, displayKeywordValueLen
)!=0){
2166 if (status
== U_USING_DEFAULT_WARNING
) {
2167 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
));
2169 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
));
2174 log_err("uloc_getDisplayKeywordValue did not return the expected error. Error: %s\n", u_errorName(status
));
2176 free(displayKeywordValue
);
2178 uenum_close(keywordEnum
);
2181 /* test a multiple keywords */
2182 UErrorCode status
= U_ZERO_ERROR
;
2183 const char* keyword
=NULL
;
2184 int32_t keywordLen
= 0;
2185 int32_t keywordCount
= 0;
2186 const char* localeID
= "es@collation=phonebook;calendar=buddhist;currency=DEM";
2187 const char* displayLocale
= "de";
2188 static const UChar expected
[][50] = {
2189 {0x0042, 0x0075, 0x0064, 0x0064, 0x0068, 0x0069, 0x0073, 0x0074, 0x0069, 0x0073, 0x0063, 0x0068, 0x0065, 0x0072, 0x0020, 0x004b, 0x0061, 0x006c, 0x0065, 0x006e, 0x0064, 0x0065, 0x0072, 0x0000},
2191 {0x0054, 0x0065, 0x006c, 0x0065, 0x0066, 0x006f, 0x006e, 0x0062, 0x0075, 0x0063, 0x0068, 0x002d, 0x0053, 0x006f, 0x0072, 0x0074, 0x0069, 0x0065, 0x0072, 0x0075, 0x006e, 0x0067, 0x0000},
2192 {0x0044, 0x0065, 0x0075, 0x0074, 0x0073, 0x0063, 0x0068, 0x0065, 0x0020, 0x004d, 0x0061, 0x0072, 0x006b, 0x0000},
2195 UEnumeration
* keywordEnum
= uloc_openKeywords(localeID
, &status
);
2197 for(keywordCount
= 0; keywordCount
< uenum_count(keywordEnum
, &status
) ; keywordCount
++){
2198 UChar
*displayKeywordValue
= NULL
;
2199 int32_t displayKeywordValueLen
= 0;
2200 if(U_FAILURE(status
)){
2201 log_err("uloc_getKeywords failed for locale id: %s in display locale: % with error : %s \n", localeID
, displayLocale
, u_errorName(status
));
2204 /* the uenum_next returns NUL terminated string */
2205 keyword
= uenum_next(keywordEnum
, &keywordLen
, &status
);
2207 /* fetch the displayKeywordValue */
2208 displayKeywordValueLen
= uloc_getDisplayKeywordValue(localeID
, keyword
, displayLocale
, displayKeywordValue
, displayKeywordValueLen
, &status
);
2209 if(status
==U_BUFFER_OVERFLOW_ERROR
){
2210 status
= U_ZERO_ERROR
;
2211 displayKeywordValueLen
++; /* for null termination */
2212 displayKeywordValue
= (UChar
*)malloc(displayKeywordValueLen
* U_SIZEOF_UCHAR
);
2213 displayKeywordValueLen
= uloc_getDisplayKeywordValue(localeID
, keyword
, displayLocale
, displayKeywordValue
, displayKeywordValueLen
, &status
);
2214 if(U_FAILURE(status
)){
2215 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
));
2218 if(u_strncmp(displayKeywordValue
, expected
[keywordCount
], displayKeywordValueLen
)!=0){
2219 if (status
== U_USING_DEFAULT_WARNING
) {
2220 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
));
2222 log_err("uloc_getDisplayKeywordValue did not return the expected value keyword : %s in locale id: %s for display locale: %s \n", localeID
, keyword
, displayLocale
);
2227 log_err("uloc_getDisplayKeywordValue did not return the expected error. Error: %s\n", u_errorName(status
));
2229 free(displayKeywordValue
);
2231 uenum_close(keywordEnum
);
2235 /* Test non existent keywords */
2236 UErrorCode status
= U_ZERO_ERROR
;
2237 const char* localeID
= "es";
2238 const char* displayLocale
= "de";
2239 UChar
*displayKeywordValue
= NULL
;
2240 int32_t displayKeywordValueLen
= 0;
2242 /* fetch the displayKeywordValue */
2243 displayKeywordValueLen
= uloc_getDisplayKeywordValue(localeID
, "calendar", displayLocale
, displayKeywordValue
, displayKeywordValueLen
, &status
);
2244 if(U_FAILURE(status
)) {
2245 log_err("uloc_getDisplaykeywordValue returned error status %s\n", u_errorName(status
));
2246 } else if(displayKeywordValueLen
!= 0) {
2247 log_err("uloc_getDisplaykeywordValue returned %d should be 0 \n", displayKeywordValueLen
);
2253 static void TestGetBaseName(void) {
2254 static const struct {
2255 const char *localeID
;
2256 const char *baseName
;
2258 { "de_DE@ C o ll A t i o n = Phonebook ", "de_DE" },
2259 { "de@currency = euro; CoLLaTion = PHONEBOOk", "de" },
2260 { "ja@calendar = buddhist", "ja" }
2263 int32_t i
= 0, baseNameLen
= 0;
2265 UErrorCode status
= U_ZERO_ERROR
;
2267 for(i
= 0; i
< sizeof(testCases
)/sizeof(testCases
[0]); i
++) {
2268 baseNameLen
= uloc_getBaseName(testCases
[i
].localeID
, baseName
, 256, &status
);
2269 if(strcmp(testCases
[i
].baseName
, baseName
)) {
2270 log_err("For locale \"%s\" expected baseName \"%s\", but got \"%s\"\n",
2271 testCases
[i
].localeID
, testCases
[i
].baseName
, baseName
);
2277 static void TestTrailingNull(void) {
2278 const char* localeId
= "zh_Hans";
2279 UChar buffer
[128]; /* sufficient for this test */
2281 UErrorCode status
= U_ZERO_ERROR
;
2284 len
= uloc_getDisplayName(localeId
, localeId
, buffer
, 128, &status
);
2286 log_err("buffer too small");
2290 for (i
= 0; i
< len
; ++i
) {
2291 if (buffer
[i
] == 0) {
2292 log_err("name contained null");
2298 /* Jitterbug 4115 */
2299 static void TestDisplayNameWarning(void) {
2302 UErrorCode status
= U_ZERO_ERROR
;
2304 size
= uloc_getDisplayLanguage("qqq", "kl", name
, sizeof(name
)/sizeof(name
[0]), &status
);
2305 if (status
!= U_USING_DEFAULT_WARNING
) {
2306 log_err("For language \"qqq\" in locale \"kl\", expecting U_USING_DEFAULT_WARNING, but got %s\n",
2307 u_errorName(status
));
2313 * Compare two locale IDs. If they are equal, return 0. If `string'
2314 * starts with `prefix' plus an additional element, that is, string ==
2315 * prefix + '_' + x, then return 1. Otherwise return a value < 0.
2317 static UBool
_loccmp(const char* string
, const char* prefix
) {
2318 int32_t slen
= (int32_t)uprv_strlen(string
),
2319 plen
= (int32_t)uprv_strlen(prefix
);
2320 int32_t c
= uprv_strncmp(string
, prefix
, plen
);
2321 /* 'root' is less than everything */
2322 if (uprv_strcmp(prefix
, "root") == 0) {
2323 return (uprv_strcmp(string
, "root") == 0) ? 0 : 1;
2325 if (c
) return -1; /* mismatch */
2326 if (slen
== plen
) return 0;
2327 if (string
[plen
] == '_') return 1;
2328 return -2; /* false match, e.g. "en_USX" cmp "en_US" */
2331 static void _checklocs(const char* label
,
2334 const char* actual
) {
2335 /* We want the valid to be strictly > the bogus requested locale,
2336 and the valid to be >= the actual. */
2337 if (_loccmp(req
, valid
) > 0 &&
2338 _loccmp(valid
, actual
) >= 0) {
2339 log_verbose("%s; req=%s, valid=%s, actual=%s\n",
2340 label
, req
, valid
, actual
);
2342 log_err("FAIL: %s; req=%s, valid=%s, actual=%s\n",
2343 label
, req
, valid
, actual
);
2347 static void TestGetLocale(void) {
2348 UErrorCode ec
= U_ZERO_ERROR
;
2350 UChar EMPTY
[1] = {0};
2353 #if !UCONFIG_NO_FORMATTING
2356 const char *req
= "en_US_REDWOODSHORES", *valid
, *actual
;
2357 obj
= udat_open(UDAT_DEFAULT
, UDAT_DEFAULT
,
2361 if (U_FAILURE(ec
)) {
2362 log_data_err("udat_open failed.Error %s\n", u_errorName(ec
));
2365 valid
= udat_getLocaleByType(obj
, ULOC_VALID_LOCALE
, &ec
);
2366 actual
= udat_getLocaleByType(obj
, ULOC_ACTUAL_LOCALE
, &ec
);
2367 if (U_FAILURE(ec
)) {
2368 log_err("udat_getLocaleByType() failed\n");
2371 _checklocs("udat", req
, valid
, actual
);
2377 #if !UCONFIG_NO_FORMATTING
2380 const char *req
= "fr_FR_PROVENCAL", *valid
, *actual
;
2381 obj
= ucal_open(NULL
, 0,
2385 if (U_FAILURE(ec
)) {
2386 log_err("ucal_open failed with error: %s\n", u_errorName(ec
));
2389 valid
= ucal_getLocaleByType(obj
, ULOC_VALID_LOCALE
, &ec
);
2390 actual
= ucal_getLocaleByType(obj
, ULOC_ACTUAL_LOCALE
, &ec
);
2391 if (U_FAILURE(ec
)) {
2392 log_err("ucal_getLocaleByType() failed\n");
2395 _checklocs("ucal", req
, valid
, actual
);
2401 #if !UCONFIG_NO_FORMATTING
2404 const char *req
= "zh_Hant_TW_TAINAN", *valid
, *actual
;
2405 obj
= unum_open(UNUM_DECIMAL
,
2409 if (U_FAILURE(ec
)) {
2410 log_err("unum_open failed\n");
2413 valid
= unum_getLocaleByType(obj
, ULOC_VALID_LOCALE
, &ec
);
2414 actual
= unum_getLocaleByType(obj
, ULOC_ACTUAL_LOCALE
, &ec
);
2415 if (U_FAILURE(ec
)) {
2416 log_err("unum_getLocaleByType() failed\n");
2419 _checklocs("unum", req
, valid
, actual
);
2426 /* commented out by weiv 01/12/2005. umsg_getLocaleByType is to be removed */
2427 #if !UCONFIG_NO_FORMATTING
2429 UMessageFormat
*obj
;
2430 const char *req
= "ja_JP_TAKAYAMA", *valid
, *actual
;
2432 obj
= umsg_open(EMPTY
, 0,
2435 if (U_FAILURE(ec
)) {
2436 log_err("umsg_open failed\n");
2439 valid
= umsg_getLocaleByType(obj
, ULOC_VALID_LOCALE
, &ec
);
2440 actual
= umsg_getLocaleByType(obj
, ULOC_ACTUAL_LOCALE
, &ec
);
2441 if (U_FAILURE(ec
)) {
2442 log_err("umsg_getLocaleByType() failed\n");
2445 /* We want the valid to be strictly > the bogus requested locale,
2446 and the valid to be >= the actual. */
2447 /* TODO MessageFormat is currently just storing the locale it is given.
2448 As a result, it will return whatever it was given, even if the
2449 locale is invalid. */
2450 test
= (_cmpversion("3.2") <= 0) ?
2451 /* Here is the weakened test for 3.0: */
2452 (_loccmp(req
, valid
) >= 0) :
2453 /* Here is what the test line SHOULD be: */
2454 (_loccmp(req
, valid
) > 0);
2457 _loccmp(valid
, actual
) >= 0) {
2458 log_verbose("umsg; req=%s, valid=%s, actual=%s\n", req
, valid
, actual
);
2460 log_err("FAIL: umsg; req=%s, valid=%s, actual=%s\n", req
, valid
, actual
);
2468 #if !UCONFIG_NO_BREAK_ITERATION
2470 UBreakIterator
*obj
;
2471 const char *req
= "ar_KW_ABDALI", *valid
, *actual
;
2472 obj
= ubrk_open(UBRK_WORD
,
2477 if (U_FAILURE(ec
)) {
2478 log_err("ubrk_open failed. Error: %s \n", u_errorName(ec
));
2481 valid
= ubrk_getLocaleByType(obj
, ULOC_VALID_LOCALE
, &ec
);
2482 actual
= ubrk_getLocaleByType(obj
, ULOC_ACTUAL_LOCALE
, &ec
);
2483 if (U_FAILURE(ec
)) {
2484 log_err("ubrk_getLocaleByType() failed\n");
2487 _checklocs("ubrk", req
, valid
, actual
);
2493 #if !UCONFIG_NO_COLLATION
2496 const char *req
= "es_AR_BUENOSAIRES", *valid
, *actual
;
2497 obj
= ucol_open(req
, &ec
);
2498 if (U_FAILURE(ec
)) {
2499 log_err("ucol_open failed - %s\n", u_errorName(ec
));
2502 valid
= ucol_getLocaleByType(obj
, ULOC_VALID_LOCALE
, &ec
);
2503 actual
= ucol_getLocaleByType(obj
, ULOC_ACTUAL_LOCALE
, &ec
);
2504 if (U_FAILURE(ec
)) {
2505 log_err("ucol_getLocaleByType() failed\n");
2508 _checklocs("ucol", req
, valid
, actual
);
2513 static void TestEnglishExemplarCharacters(void) {
2514 UErrorCode status
= U_ZERO_ERROR
;
2517 UChar testChars
[] = {
2518 0x61, /* standard */
2519 0xE1, /* auxiliary */
2521 0x2D /* punctuation */
2523 ULocaleData
*uld
= ulocdata_open("en", &status
);
2524 if (U_FAILURE(status
)) {
2525 log_data_err("ulocdata_open() failed : %s - (Are you missing data?)\n", u_errorName(status
));
2529 for (i
= 0; i
< ULOCDATA_ES_COUNT
; i
++) {
2530 exSet
= ulocdata_getExemplarSet(uld
, exSet
, 0, (ULocaleDataExemplarSetType
)i
, &status
);
2531 if (U_FAILURE(status
)) {
2532 log_err_status(status
, "ulocdata_getExemplarSet() for type %d failed\n", i
);
2533 status
= U_ZERO_ERROR
;
2536 if (!uset_contains(exSet
, (UChar32
)testChars
[i
])) {
2537 log_err("Character U+%04X is not included in exemplar type %d\n", testChars
[i
], i
);
2542 ulocdata_close(uld
);
2545 static void TestNonexistentLanguageExemplars(void) {
2546 /* JB 4068 - Nonexistent language */
2547 UErrorCode ec
= U_ZERO_ERROR
;
2548 ULocaleData
*uld
= ulocdata_open("qqq",&ec
);
2549 if (ec
!= U_USING_DEFAULT_WARNING
) {
2550 log_err_status(ec
, "Exemplar set for \"qqq\", expecting U_USING_DEFAULT_WARNING, but got %s\n",
2553 uset_close(ulocdata_getExemplarSet(uld
, NULL
, 0, ULOCDATA_ES_STANDARD
, &ec
));
2554 ulocdata_close(uld
);
2557 static void TestLocDataErrorCodeChaining(void) {
2558 UErrorCode ec
= U_USELESS_COLLATOR_ERROR
;
2559 ulocdata_open(NULL
, &ec
);
2560 ulocdata_getExemplarSet(NULL
, NULL
, 0, ULOCDATA_ES_STANDARD
, &ec
);
2561 ulocdata_getDelimiter(NULL
, ULOCDATA_DELIMITER_COUNT
, NULL
, -1, &ec
);
2562 ulocdata_getMeasurementSystem(NULL
, &ec
);
2563 ulocdata_getPaperSize(NULL
, NULL
, NULL
, &ec
);
2564 if (ec
!= U_USELESS_COLLATOR_ERROR
) {
2565 log_err("ulocdata API changed the error code to %s\n", u_errorName(ec
));
2569 static void TestLanguageExemplarsFallbacks(void) {
2570 /* Test that en_US fallsback, but en doesn't fallback. */
2571 UErrorCode ec
= U_ZERO_ERROR
;
2572 ULocaleData
*uld
= ulocdata_open("en_US",&ec
);
2573 uset_close(ulocdata_getExemplarSet(uld
, NULL
, 0, ULOCDATA_ES_STANDARD
, &ec
));
2574 if (ec
!= U_USING_FALLBACK_WARNING
) {
2575 log_err_status(ec
, "Exemplar set for \"en_US\", expecting U_USING_FALLBACK_WARNING, but got %s\n",
2578 ulocdata_close(uld
);
2580 uld
= ulocdata_open("en",&ec
);
2581 uset_close(ulocdata_getExemplarSet(uld
, NULL
, 0, ULOCDATA_ES_STANDARD
, &ec
));
2582 if (ec
!= U_ZERO_ERROR
) {
2583 log_err_status(ec
, "Exemplar set for \"en\", expecting U_ZERO_ERROR, but got %s\n",
2586 ulocdata_close(uld
);
2589 static const char *acceptResult(UAcceptResult uar
) {
2590 return udbg_enumName(UDBG_UAcceptResult
, uar
);
2593 static void TestAcceptLanguage(void) {
2594 UErrorCode status
= U_ZERO_ERROR
;
2595 UAcceptResult outResult
;
2596 UEnumeration
*available
;
2602 int32_t httpSet
; /**< Which of http[] should be used? */
2603 const char *icuSet
; /**< ? */
2604 const char *expect
; /**< The expected locale result */
2605 UAcceptResult res
; /**< The expected error code */
2607 /*0*/{ 0, NULL
, "mt_MT", ULOC_ACCEPT_VALID
},
2608 /*1*/{ 1, NULL
, "en", ULOC_ACCEPT_VALID
},
2609 /*2*/{ 2, NULL
, "en", ULOC_ACCEPT_FALLBACK
},
2610 /*3*/{ 3, NULL
, "", ULOC_ACCEPT_FAILED
},
2611 /*4*/{ 4, NULL
, "es", ULOC_ACCEPT_VALID
},
2613 /*5*/{ 5, NULL
, "en", ULOC_ACCEPT_VALID
}, /* XF */
2614 /*6*/{ 6, NULL
, "ja", ULOC_ACCEPT_FALLBACK
}, /* XF */
2615 /*7*/{ 7, NULL
, "zh", ULOC_ACCEPT_FALLBACK
}, /* XF */
2617 const int32_t numTests
= sizeof(tests
)/sizeof(tests
[0]);
2618 static const char *http
[] = {
2619 /*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",
2620 /*1*/ "ja;q=0.5, en;q=0.8, tlh",
2621 /*2*/ "en-wf, de-lx;q=0.8",
2622 /*3*/ "mga-ie;q=0.9, tlh",
2623 /*4*/ "xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, "
2624 "xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, "
2625 "xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, "
2626 "xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, "
2627 "xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, "
2628 "xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, "
2629 "xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, xx-yy;q=.1, "
2632 /*5*/ "zh-xx;q=0.9, en;q=0.6",
2634 /*7*/ "zh-xx;q=0.9",
2637 for(i
=0;i
<numTests
;i
++) {
2639 status
=U_ZERO_ERROR
;
2640 log_verbose("test #%d: http[%s], ICU[%s], expect %s, %s\n",
2641 i
, http
[tests
[i
].httpSet
], tests
[i
].icuSet
, tests
[i
].expect
, acceptResult(tests
[i
].res
));
2643 available
= ures_openAvailableLocales(tests
[i
].icuSet
, &status
);
2645 rc
= uloc_acceptLanguageFromHTTP(tmp
, 199, &outResult
, http
[tests
[i
].httpSet
], available
, &status
);
2646 uenum_close(available
);
2647 log_verbose(" got %s, %s [%s]\n", tmp
[0]?tmp
:"(EMPTY)", acceptResult(outResult
), u_errorName(status
));
2648 if(outResult
!= tests
[i
].res
) {
2649 log_err_status(status
, "FAIL: #%d: expected outResult of %s but got %s\n", i
,
2650 acceptResult( tests
[i
].res
),
2651 acceptResult( outResult
));
2652 log_info("test #%d: http[%s], ICU[%s], expect %s, %s\n",
2653 i
, http
[tests
[i
].httpSet
], tests
[i
].icuSet
, tests
[i
].expect
,acceptResult(tests
[i
].res
));
2655 if((outResult
>0)&&uprv_strcmp(tmp
, tests
[i
].expect
)) {
2656 log_err_status(status
, "FAIL: #%d: expected %s but got %s\n", i
, tests
[i
].expect
, tmp
);
2657 log_info("test #%d: http[%s], ICU[%s], expect %s, %s\n",
2658 i
, http
[tests
[i
].httpSet
], tests
[i
].icuSet
, tests
[i
].expect
, acceptResult(tests
[i
].res
));
2663 static const char* LOCALE_ALIAS
[][2] = {
2677 static UBool
isLocaleAvailable(UResourceBundle
* resIndex
, const char* loc
){
2678 UErrorCode status
= U_ZERO_ERROR
;
2680 ures_getStringByKey(resIndex
, loc
,&len
, &status
);
2681 if(U_FAILURE(status
)){
2687 static void TestCalendar() {
2688 #if !UCONFIG_NO_FORMATTING
2690 UErrorCode status
= U_ZERO_ERROR
;
2691 UResourceBundle
*resIndex
= ures_open(NULL
,"res_index", &status
);
2692 if(U_FAILURE(status
)){
2693 log_err_status(status
, "Could not open res_index.res. Exiting. Error: %s\n", u_errorName(status
));
2696 for (i
=0; i
<LENGTHOF(LOCALE_ALIAS
); i
++) {
2697 const char* oldLoc
= LOCALE_ALIAS
[i
][0];
2698 const char* newLoc
= LOCALE_ALIAS
[i
][1];
2699 UCalendar
* c1
= NULL
;
2700 UCalendar
* c2
= NULL
;
2702 /*Test function "getLocale(ULocale.VALID_LOCALE)"*/
2703 const char* l1
= ucal_getLocaleByType(c1
, ULOC_VALID_LOCALE
, &status
);
2704 const char* l2
= ucal_getLocaleByType(c2
, ULOC_VALID_LOCALE
, &status
);
2706 if(!isLocaleAvailable(resIndex
, newLoc
)){
2709 c1
= ucal_open(NULL
, -1, oldLoc
, UCAL_GREGORIAN
, &status
);
2710 c2
= ucal_open(NULL
, -1, newLoc
, UCAL_GREGORIAN
, &status
);
2712 if (strcmp(newLoc
,l1
)!=0 || strcmp(l1
,l2
)!=0 || status
!=U_ZERO_ERROR
) {
2713 log_err("The locales are not equal!.Old: %s, New: %s \n", oldLoc
, newLoc
);
2715 log_verbose("ucal_getLocaleByType old:%s new:%s\n", l1
, l2
);
2719 ures_close(resIndex
);
2723 static void TestDateFormat() {
2724 #if !UCONFIG_NO_FORMATTING
2726 UErrorCode status
= U_ZERO_ERROR
;
2727 UResourceBundle
*resIndex
= ures_open(NULL
,"res_index", &status
);
2728 if(U_FAILURE(status
)){
2729 log_err_status(status
, "Could not open res_index.res. Exiting. Error: %s\n", u_errorName(status
));
2732 for (i
=0; i
<LENGTHOF(LOCALE_ALIAS
); i
++) {
2733 const char* oldLoc
= LOCALE_ALIAS
[i
][0];
2734 const char* newLoc
= LOCALE_ALIAS
[i
][1];
2735 UDateFormat
* df1
= NULL
;
2736 UDateFormat
* df2
= NULL
;
2737 const char* l1
= NULL
;
2738 const char* l2
= NULL
;
2740 if(!isLocaleAvailable(resIndex
, newLoc
)){
2743 df1
= udat_open(UDAT_FULL
, UDAT_FULL
,oldLoc
, NULL
, 0, NULL
, -1, &status
);
2744 df2
= udat_open(UDAT_FULL
, UDAT_FULL
,newLoc
, NULL
, 0, NULL
, -1, &status
);
2745 if(U_FAILURE(status
)){
2746 log_err("Creation of date format failed %s\n", u_errorName(status
));
2749 /*Test function "getLocale"*/
2750 l1
= udat_getLocaleByType(df1
, ULOC_VALID_LOCALE
, &status
);
2751 l2
= udat_getLocaleByType(df2
, ULOC_VALID_LOCALE
, &status
);
2752 if(U_FAILURE(status
)){
2753 log_err("Fetching the locale by type failed. %s\n", u_errorName(status
));
2755 if (strcmp(newLoc
,l1
)!=0 || strcmp(l1
,l2
)!=0) {
2756 log_err("The locales are not equal!.Old: %s, New: %s \n", oldLoc
, newLoc
);
2758 log_verbose("udat_getLocaleByType old:%s new:%s\n", l1
, l2
);
2762 ures_close(resIndex
);
2766 static void TestCollation() {
2767 #if !UCONFIG_NO_COLLATION
2769 UErrorCode status
= U_ZERO_ERROR
;
2770 UResourceBundle
*resIndex
= ures_open(NULL
,"res_index", &status
);
2771 if(U_FAILURE(status
)){
2772 log_err_status(status
, "Could not open res_index.res. Exiting. Error: %s\n", u_errorName(status
));
2775 for (i
=0; i
<LENGTHOF(LOCALE_ALIAS
); i
++) {
2776 const char* oldLoc
= LOCALE_ALIAS
[i
][0];
2777 const char* newLoc
= LOCALE_ALIAS
[i
][1];
2778 UCollator
* c1
= NULL
;
2779 UCollator
* c2
= NULL
;
2780 const char* l1
= NULL
;
2781 const char* l2
= NULL
;
2783 status
= U_ZERO_ERROR
;
2784 if(!isLocaleAvailable(resIndex
, newLoc
)){
2787 if(U_FAILURE(status
)){
2788 log_err("Creation of collators failed %s\n", u_errorName(status
));
2791 c1
= ucol_open(oldLoc
, &status
);
2792 c2
= ucol_open(newLoc
, &status
);
2793 l1
= ucol_getLocaleByType(c1
, ULOC_VALID_LOCALE
, &status
);
2794 l2
= ucol_getLocaleByType(c2
, ULOC_VALID_LOCALE
, &status
);
2795 if(U_FAILURE(status
)){
2796 log_err("Fetching the locale names failed failed %s\n", u_errorName(status
));
2798 if (strcmp(newLoc
,l1
)!=0 || strcmp(l1
,l2
)!=0) {
2799 log_err("The locales are not equal!.Old: %s, New: %s \n", oldLoc
, newLoc
);
2801 log_verbose("ucol_getLocaleByType old:%s new:%s\n", l1
, l2
);
2805 ures_close(resIndex
);
2809 typedef struct OrientationStructTag
{
2810 const char* localeId
;
2811 ULayoutType character
;
2813 } OrientationStruct
;
2815 static const char* ULayoutTypeToString(ULayoutType type
)
2819 case ULOC_LAYOUT_LTR
:
2820 return "ULOC_LAYOUT_LTR";
2822 case ULOC_LAYOUT_RTL
:
2823 return "ULOC_LAYOUT_RTL";
2825 case ULOC_LAYOUT_TTB
:
2826 return "ULOC_LAYOUT_TTB";
2828 case ULOC_LAYOUT_BTT
:
2829 return "ULOC_LAYOUT_BTT";
2831 case ULOC_LAYOUT_UNKNOWN
:
2835 return "Unknown enum value for ULayoutType!";
2838 static void TestOrientation()
2840 static const OrientationStruct toTest
[] = {
2841 { "ar", ULOC_LAYOUT_RTL
, ULOC_LAYOUT_TTB
},
2842 { "aR", ULOC_LAYOUT_RTL
, ULOC_LAYOUT_TTB
},
2843 { "ar_Arab", ULOC_LAYOUT_RTL
, ULOC_LAYOUT_TTB
},
2844 { "fa", ULOC_LAYOUT_RTL
, ULOC_LAYOUT_TTB
},
2845 { "Fa", ULOC_LAYOUT_RTL
, ULOC_LAYOUT_TTB
},
2846 { "he", ULOC_LAYOUT_RTL
, ULOC_LAYOUT_TTB
},
2847 { "ps", ULOC_LAYOUT_RTL
, ULOC_LAYOUT_TTB
},
2848 { "ur", ULOC_LAYOUT_RTL
, ULOC_LAYOUT_TTB
},
2849 { "UR", ULOC_LAYOUT_RTL
, ULOC_LAYOUT_TTB
},
2850 { "en", ULOC_LAYOUT_LTR
, ULOC_LAYOUT_TTB
}
2854 for (; i
< sizeof(toTest
) / sizeof(toTest
[0]); ++i
) {
2855 UErrorCode statusCO
= U_ZERO_ERROR
;
2856 UErrorCode statusLO
= U_ZERO_ERROR
;
2857 const char* const localeId
= toTest
[i
].localeId
;
2858 const ULayoutType co
= uloc_getCharacterOrientation(localeId
, &statusCO
);
2859 const ULayoutType expectedCO
= toTest
[i
].character
;
2860 const ULayoutType lo
= uloc_getLineOrientation(localeId
, &statusLO
);
2861 const ULayoutType expectedLO
= toTest
[i
].line
;
2862 if (U_FAILURE(statusCO
)) {
2863 log_err_status(statusCO
,
2864 " unexpected failure for uloc_getCharacterOrientation(), with localId \"%s\" and status %s\n",
2866 u_errorName(statusCO
));
2868 else if (co
!= expectedCO
) {
2870 " unexpected result for uloc_getCharacterOrientation(), with localeId \"%s\". Expected %s but got result %s\n",
2872 ULayoutTypeToString(expectedCO
),
2873 ULayoutTypeToString(co
));
2875 if (U_FAILURE(statusLO
)) {
2876 log_err_status(statusLO
,
2877 " unexpected failure for uloc_getLineOrientation(), with localId \"%s\" and status %s\n",
2879 u_errorName(statusLO
));
2881 else if (lo
!= expectedLO
) {
2883 " unexpected result for uloc_getLineOrientation(), with localeId \"%s\". Expected %s but got result %s\n",
2885 ULayoutTypeToString(expectedLO
),
2886 ULayoutTypeToString(lo
));
2891 static void TestULocale() {
2893 UErrorCode status
= U_ZERO_ERROR
;
2894 UResourceBundle
*resIndex
= ures_open(NULL
,"res_index", &status
);
2895 if(U_FAILURE(status
)){
2896 log_err_status(status
, "Could not open res_index.res. Exiting. Error: %s\n", u_errorName(status
));
2899 for (i
=0; i
<LENGTHOF(LOCALE_ALIAS
); i
++) {
2900 const char* oldLoc
= LOCALE_ALIAS
[i
][0];
2901 const char* newLoc
= LOCALE_ALIAS
[i
][1];
2902 UChar name1
[256], name2
[256];
2903 char names1
[256], names2
[256];
2904 int32_t capacity
= 256;
2906 status
= U_ZERO_ERROR
;
2907 if(!isLocaleAvailable(resIndex
, newLoc
)){
2910 uloc_getDisplayName(oldLoc
, ULOC_US
, name1
, capacity
, &status
);
2911 if(U_FAILURE(status
)){
2912 log_err("uloc_getDisplayName(%s) failed %s\n", oldLoc
, u_errorName(status
));
2915 uloc_getDisplayName(newLoc
, ULOC_US
, name2
, capacity
, &status
);
2916 if(U_FAILURE(status
)){
2917 log_err("uloc_getDisplayName(%s) failed %s\n", newLoc
, u_errorName(status
));
2920 if (u_strcmp(name1
, name2
)!=0) {
2921 log_err("The locales are not equal!.Old: %s, New: %s \n", oldLoc
, newLoc
);
2923 u_austrcpy(names1
, name1
);
2924 u_austrcpy(names2
, name2
);
2925 log_verbose("uloc_getDisplayName old:%s new:%s\n", names1
, names2
);
2927 ures_close(resIndex
);
2931 static void TestUResourceBundle() {
2935 UResourceBundle
* rb1
= NULL
;
2936 UResourceBundle
* rb2
= NULL
;
2937 UErrorCode status
= U_ZERO_ERROR
;
2939 UResourceBundle
*resIndex
= NULL
;
2940 if(U_FAILURE(status
)){
2941 log_err("Could not open res_index.res. Exiting. Error: %s\n", u_errorName(status
));
2944 resIndex
= ures_open(NULL
,"res_index", &status
);
2945 for (i
=0; i
<LENGTHOF(LOCALE_ALIAS
); i
++) {
2947 const char* oldLoc
= LOCALE_ALIAS
[i
][0];
2948 const char* newLoc
= LOCALE_ALIAS
[i
][1];
2949 if(!isLocaleAvailable(resIndex
, newLoc
)){
2952 rb1
= ures_open(NULL
, oldLoc
, &status
);
2953 if (U_FAILURE(status
)) {
2954 log_err("ures_open(%s) failed %s\n", oldLoc
, u_errorName(status
));
2957 us1
= ures_getLocaleByType(rb1
, ULOC_ACTUAL_LOCALE
, &status
);
2959 status
= U_ZERO_ERROR
;
2960 rb2
= ures_open(NULL
, newLoc
, &status
);
2961 if (U_FAILURE(status
)) {
2962 log_err("ures_open(%s) failed %s\n", oldLoc
, u_errorName(status
));
2964 us2
= ures_getLocaleByType(rb2
, ULOC_ACTUAL_LOCALE
, &status
);
2966 if (strcmp(us1
,newLoc
)!=0 || strcmp(us1
,us2
)!=0 ) {
2967 log_err("The locales are not equal!.Old: %s, New: %s \n", oldLoc
, newLoc
);
2970 log_verbose("ures_getStringByKey old:%s new:%s\n", us1
, us2
);
2976 ures_close(resIndex
);
2979 static void TestDisplayName() {
2981 UChar oldCountry
[256] = {'\0'};
2982 UChar newCountry
[256] = {'\0'};
2983 UChar oldLang
[256] = {'\0'};
2984 UChar newLang
[256] = {'\0'};
2985 char country
[256] ={'\0'};
2986 char language
[256] ={'\0'};
2987 int32_t capacity
= 256;
2990 for (i
=0; i
<LENGTHOF(LOCALE_ALIAS
); i
++) {
2991 const char* oldLoc
= LOCALE_ALIAS
[i
][0];
2992 const char* newLoc
= LOCALE_ALIAS
[i
][1];
2993 UErrorCode status
= U_ZERO_ERROR
;
2994 int32_t available
= uloc_countAvailable();
2996 for(j
=0; j
<available
; j
++){
2998 const char* dispLoc
= uloc_getAvailable(j
);
2999 int32_t oldCountryLen
= uloc_getDisplayCountry(oldLoc
,dispLoc
, oldCountry
, capacity
, &status
);
3000 int32_t newCountryLen
= uloc_getDisplayCountry(newLoc
, dispLoc
, newCountry
, capacity
, &status
);
3001 int32_t oldLangLen
= uloc_getDisplayLanguage(oldLoc
, dispLoc
, oldLang
, capacity
, &status
);
3002 int32_t newLangLen
= uloc_getDisplayLanguage(newLoc
, dispLoc
, newLang
, capacity
, &status
);
3004 int32_t countryLen
= uloc_getCountry(newLoc
, country
, capacity
, &status
);
3005 int32_t langLen
= uloc_getLanguage(newLoc
, language
, capacity
, &status
);
3006 /* there is a display name for the current country ID */
3007 if(countryLen
!= newCountryLen
){
3008 if(u_strncmp(oldCountry
,newCountry
,oldCountryLen
)!=0){
3009 log_err("uloc_getDisplayCountry() failed for %s in display locale %s \n", oldLoc
, dispLoc
);
3012 /* there is a display name for the current lang ID */
3013 if(langLen
!=newLangLen
){
3014 if(u_strncmp(oldLang
,newLang
,oldLangLen
)){
3015 log_err("uloc_getDisplayLanguage() failed for %s in display locale %s \n", oldLoc
, dispLoc
); }
3021 static void TestGetLocaleForLCID() {
3022 int32_t i
, length
, lengthPre
;
3023 const char* testLocale
= 0;
3024 UErrorCode status
= U_ZERO_ERROR
;
3025 char temp2
[40], temp3
[40];
3028 lcid
= uloc_getLCID("en_US");
3029 if (lcid
!= 0x0409) {
3030 log_err(" uloc_getLCID(\"en_US\") = %d, expected 0x0409\n", lcid
);
3033 lengthPre
= uloc_getLocaleForLCID(lcid
, temp2
, 4, &status
);
3034 if (status
!= U_BUFFER_OVERFLOW_ERROR
) {
3035 log_err(" unexpected result from uloc_getLocaleForLCID with small buffer: %s\n", u_errorName(status
));
3038 status
= U_ZERO_ERROR
;
3041 length
= uloc_getLocaleForLCID(lcid
, temp2
, sizeof(temp2
)/sizeof(char), &status
);
3042 if (U_FAILURE(status
)) {
3043 log_err(" unexpected result from uloc_getLocaleForLCID(0x0409): %s\n", u_errorName(status
));
3044 status
= U_ZERO_ERROR
;
3047 if (length
!= lengthPre
) {
3048 log_err(" uloc_getLocaleForLCID(0x0409): returned length %d does not match preflight length %d\n", length
, lengthPre
);
3051 length
= uloc_getLocaleForLCID(0x12345, temp2
, sizeof(temp2
)/sizeof(char), &status
);
3052 if (U_SUCCESS(status
)) {
3053 log_err(" unexpected result from uloc_getLocaleForLCID(0x12345): %s, status %s\n", temp2
, u_errorName(status
));
3055 status
= U_ZERO_ERROR
;
3057 log_verbose("Testing getLocaleForLCID vs. locale data\n");
3058 for (i
= 0; i
< LOCALE_SIZE
; i
++) {
3060 testLocale
=rawData2
[NAME
][i
];
3062 log_verbose("Testing %s ......\n", testLocale
);
3064 sscanf(rawData2
[LCID
][i
], "%x", &lcid
);
3065 length
= uloc_getLocaleForLCID(lcid
, temp2
, sizeof(temp2
)/sizeof(char), &status
);
3066 if (U_FAILURE(status
)) {
3067 log_err(" unexpected failure of uloc_getLocaleForLCID(%#04x), status %s\n", lcid
, u_errorName(status
));
3068 status
= U_ZERO_ERROR
;
3072 if (length
!= uprv_strlen(temp2
)) {
3073 log_err(" returned length %d not correct for uloc_getLocaleForLCID(%#04x), expected %d\n", length
, lcid
, uprv_strlen(temp2
));
3076 /* Compare language, country, script */
3077 length
= uloc_getLanguage(temp2
, temp3
, sizeof(temp3
)/sizeof(char), &status
);
3078 if (U_FAILURE(status
)) {
3079 log_err(" couldn't get language in uloc_getLocaleForLCID(%#04x) = %s, status %s\n", lcid
, temp2
, u_errorName(status
));
3080 status
= U_ZERO_ERROR
;
3082 else if (uprv_strcmp(temp3
, rawData2
[LANG
][i
]) && !(uprv_strcmp(temp3
, "nn") == 0 && uprv_strcmp(rawData2
[VAR
][i
], "NY") == 0)) {
3083 log_err(" language doesn't match expected %s in in uloc_getLocaleForLCID(%#04x) = %s\n", rawData2
[LANG
][i
], lcid
, temp2
);
3086 length
= uloc_getScript(temp2
, temp3
, sizeof(temp3
)/sizeof(char), &status
);
3087 if (U_FAILURE(status
)) {
3088 log_err(" couldn't get script in uloc_getLocaleForLCID(%#04x) = %s, status %s\n", lcid
, temp2
, u_errorName(status
));
3089 status
= U_ZERO_ERROR
;
3091 else if (uprv_strcmp(temp3
, rawData2
[SCRIPT
][i
])) {
3092 log_err(" script doesn't match expected %s in in uloc_getLocaleForLCID(%#04x) = %s\n", rawData2
[SCRIPT
][i
], lcid
, temp2
);
3095 length
= uloc_getCountry(temp2
, temp3
, sizeof(temp3
)/sizeof(char), &status
);
3096 if (U_FAILURE(status
)) {
3097 log_err(" couldn't get country in uloc_getLocaleForLCID(%#04x) = %s, status %s\n", lcid
, temp2
, u_errorName(status
));
3098 status
= U_ZERO_ERROR
;
3100 else if (uprv_strlen(rawData2
[CTRY
][i
]) && uprv_strcmp(temp3
, rawData2
[CTRY
][i
])) {
3101 log_err(" country doesn't match expected %s in in uloc_getLocaleForLCID(%#04x) = %s\n", rawData2
[CTRY
][i
], lcid
, temp2
);
3107 const char* const basic_maximize_data
[][2] = {
3152 "en_Latn_US_POSIX_1901"
3154 "en_Latn__POSIX_1901",
3155 "en_Latn_US_POSIX_1901"
3158 "en_Latn_US_POSIX_1901"
3161 "de_Latn_DE_POSIX_1901"
3166 "th@calendar=buddhist",
3167 "th_Thai_TH@calendar=buddhist"
3197 "de_Latn_DE_U_CO_PHONEBK"
3199 "de_Latn_u_co_phonebk",
3200 "de_Latn_DE_U_CO_PHONEBK"
3202 "de_Latn_DE_u_co_phonebk",
3203 "de_Latn_DE_U_CO_PHONEBK"
3207 const char* const basic_minimize_data
[][2] = {
3212 "en_Latn_US_POSIX_1901",
3215 "EN_Latn_US_POSIX_1901",
3218 "en_Zzzz_US_POSIX_1901",
3221 "de_Latn_DE_POSIX_1901",
3227 "en_Latn_US@calendar=gregorian",
3228 "en@calendar=gregorian"
3232 const char* const full_data
[][3] = {
3236 /* "REMOVE-LIKELY" */
5306 "de@collation=phonebook",
5307 "de_Latn_DE@collation=phonebook",
5308 "de@collation=phonebook"
5312 typedef struct errorDataTag
{
5314 const char* expected
;
5319 const errorData maximizeErrors
[] = {
5323 U_ILLEGAL_ARGUMENT_ERROR
,
5327 "en_THUJIOGIURJHGJFURYHFJGURYYYHHGJURHG",
5329 U_ILLEGAL_ARGUMENT_ERROR
,
5333 "en_THUJIOGIURJHGJFURYHFJGURYYYHHGJURHG",
5335 U_ILLEGAL_ARGUMENT_ERROR
,
5339 "en_Latn_US_POSIX@currency=EURO",
5340 "en_Latn_US_POSIX@currency=EURO",
5341 U_BUFFER_OVERFLOW_ERROR
,
5345 "en_Latn_US_POSIX@currency=EURO",
5346 "en_Latn_US_POSIX@currency=EURO",
5347 U_STRING_NOT_TERMINATED_WARNING
,
5352 const errorData minimizeErrors
[] = {
5356 U_ILLEGAL_ARGUMENT_ERROR
,
5360 "en_THUJIOGIURJHGJFURYHFJGURYYYHHGJURHG",
5362 U_ILLEGAL_ARGUMENT_ERROR
,
5366 "en_Latn_US_POSIX@currency=EURO",
5367 "en__POSIX@currency=EURO",
5368 U_BUFFER_OVERFLOW_ERROR
,
5372 "en_Latn_US_POSIX@currency=EURO",
5373 "en__POSIX@currency=EURO",
5374 U_STRING_NOT_TERMINATED_WARNING
,
5379 static int32_t getExpectedReturnValue(const errorData
* data
)
5381 if (data
->uerror
== U_BUFFER_OVERFLOW_ERROR
||
5382 data
->uerror
== U_STRING_NOT_TERMINATED_WARNING
)
5384 return strlen(data
->expected
);
5392 static int32_t getBufferSize(const errorData
* data
, int32_t actualSize
)
5394 if (data
->expected
== NULL
)
5398 else if (data
->bufferSize
< 0)
5400 return strlen(data
->expected
) + 1;
5404 return data
->bufferSize
;
5408 static void TestLikelySubtags()
5410 char buffer
[ULOC_FULLNAME_CAPACITY
+ ULOC_KEYWORD_AND_VALUES_CAPACITY
+ 1];
5413 for (; i
< sizeof(basic_maximize_data
) / sizeof(basic_maximize_data
[0]); ++i
)
5415 UErrorCode status
= U_ZERO_ERROR
;
5416 const char* const minimal
= basic_maximize_data
[i
][0];
5417 const char* const maximal
= basic_maximize_data
[i
][1];
5419 /* const int32_t length = */
5420 uloc_addLikelySubtags(
5425 if (U_FAILURE(status
)) {
5426 log_err_status(status
, " unexpected failure of uloc_addLikelySubtags(), minimal \"%s\" status %s\n", minimal
, u_errorName(status
));
5427 status
= U_ZERO_ERROR
;
5429 else if (uprv_strlen(maximal
) == 0) {
5430 if (uprv_stricmp(minimal
, buffer
) != 0) {
5431 log_err(" unexpected maximal value \"%s\" in uloc_addLikelySubtags(), minimal \"%s\" = \"%s\"\n", maximal
, minimal
, buffer
);
5434 else if (uprv_stricmp(maximal
, buffer
) != 0) {
5435 log_err(" maximal doesn't match expected %s in uloc_addLikelySubtags(), minimal \"%s\" = %s\n", maximal
, minimal
, buffer
);
5439 for (i
= 0; i
< sizeof(basic_minimize_data
) / sizeof(basic_minimize_data
[0]); ++i
) {
5441 UErrorCode status
= U_ZERO_ERROR
;
5442 const char* const maximal
= basic_minimize_data
[i
][0];
5443 const char* const minimal
= basic_minimize_data
[i
][1];
5445 /* const int32_t length = */
5446 uloc_minimizeSubtags(
5452 if (U_FAILURE(status
)) {
5453 log_err_status(status
, " unexpected failure of uloc_MinimizeSubtags(), maximal \"%s\" status %s\n", maximal
, u_errorName(status
));
5454 status
= U_ZERO_ERROR
;
5456 else if (uprv_strlen(minimal
) == 0) {
5457 if (uprv_stricmp(maximal
, buffer
) != 0) {
5458 log_err(" unexpected minimal value \"%s\" in uloc_minimizeSubtags(), maximal \"%s\" = \"%s\"\n", minimal
, maximal
, buffer
);
5461 else if (uprv_stricmp(minimal
, buffer
) != 0) {
5462 log_err(" minimal doesn't match expected %s in uloc_MinimizeSubtags(), maximal \"%s\" = %s\n", minimal
, maximal
, buffer
);
5466 for (i
= 0; i
< sizeof(full_data
) / sizeof(full_data
[0]); ++i
) {
5468 UErrorCode status
= U_ZERO_ERROR
;
5469 const char* const minimal
= full_data
[i
][0];
5470 const char* const maximal
= full_data
[i
][1];
5472 /* const int32_t length = */
5473 uloc_addLikelySubtags(
5478 if (U_FAILURE(status
)) {
5479 log_err_status(status
, " unexpected failure of uloc_addLikelySubtags(), minimal \"%s\" status \"%s\"\n", minimal
, u_errorName(status
));
5480 status
= U_ZERO_ERROR
;
5482 else if (uprv_strlen(maximal
) == 0) {
5483 if (uprv_stricmp(minimal
, buffer
) != 0) {
5484 log_err(" unexpected maximal value \"%s\" in uloc_addLikelySubtags(), minimal \"%s\" = \"%s\"\n", maximal
, minimal
, buffer
);
5487 else if (uprv_stricmp(maximal
, buffer
) != 0) {
5488 log_err(" maximal doesn't match expected \"%s\" in uloc_addLikelySubtags(), minimal \"%s\" = \"%s\"\n", maximal
, minimal
, buffer
);
5492 for (i
= 0; i
< sizeof(full_data
) / sizeof(full_data
[0]); ++i
) {
5494 UErrorCode status
= U_ZERO_ERROR
;
5495 const char* const maximal
= full_data
[i
][1];
5496 const char* const minimal
= full_data
[i
][2];
5498 if (strlen(maximal
) > 0) {
5500 /* const int32_t length = */
5501 uloc_minimizeSubtags(
5507 if (U_FAILURE(status
)) {
5508 log_err_status(status
, " unexpected failure of uloc_minimizeSubtags(), maximal \"%s\" status %s\n", maximal
, u_errorName(status
));
5509 status
= U_ZERO_ERROR
;
5511 else if (uprv_strlen(minimal
) == 0) {
5512 if (uprv_stricmp(maximal
, buffer
) != 0) {
5513 log_err(" unexpected minimal value \"%s\" in uloc_minimizeSubtags(), maximal \"%s\" = \"%s\"\n", minimal
, maximal
, buffer
);
5516 else if (uprv_stricmp(minimal
, buffer
) != 0) {
5517 log_err(" minimal doesn't match expected %s in uloc_MinimizeSubtags(), maximal \"%s\" = %s\n", minimal
, maximal
, buffer
);
5522 for (i
= 0; i
< sizeof(maximizeErrors
) / sizeof(maximizeErrors
[0]); ++i
) {
5524 UErrorCode status
= U_ZERO_ERROR
;
5525 const char* const minimal
= maximizeErrors
[i
].tag
;
5526 const char* const maximal
= maximizeErrors
[i
].expected
;
5527 const UErrorCode expectedStatus
= maximizeErrors
[i
].uerror
;
5528 const int32_t expectedLength
= getExpectedReturnValue(&maximizeErrors
[i
]);
5529 const int32_t bufferSize
= getBufferSize(&maximizeErrors
[i
], sizeof(buffer
));
5531 const int32_t length
=
5532 uloc_addLikelySubtags(
5538 if (status
== U_ZERO_ERROR
) {
5539 log_err(" unexpected U_ZERO_ERROR for uloc_addLikelySubtags(), minimal \"%s\" expected status %s\n", minimal
, u_errorName(expectedStatus
));
5540 status
= U_ZERO_ERROR
;
5542 else if (status
!= expectedStatus
) {
5543 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
));
5545 else if (length
!= expectedLength
) {
5546 log_err(" unexpected length for uloc_addLikelySubtags(), minimal \"%s\" expected length %d, but got %d\n", minimal
, expectedLength
, length
);
5548 else if (status
== U_BUFFER_OVERFLOW_ERROR
|| status
== U_STRING_NOT_TERMINATED_WARNING
) {
5549 if (uprv_strnicmp(maximal
, buffer
, bufferSize
) != 0) {
5550 log_err(" maximal doesn't match expected %s in uloc_addLikelySubtags(), minimal \"%s\" = %*s\n",
5551 maximal
, minimal
, (int)sizeof(buffer
), buffer
);
5556 for (i
= 0; i
< sizeof(minimizeErrors
) / sizeof(minimizeErrors
[0]); ++i
) {
5558 UErrorCode status
= U_ZERO_ERROR
;
5559 const char* const maximal
= minimizeErrors
[i
].tag
;
5560 const char* const minimal
= minimizeErrors
[i
].expected
;
5561 const UErrorCode expectedStatus
= minimizeErrors
[i
].uerror
;
5562 const int32_t expectedLength
= getExpectedReturnValue(&minimizeErrors
[i
]);
5563 const int32_t bufferSize
= getBufferSize(&minimizeErrors
[i
], sizeof(buffer
));
5565 const int32_t length
=
5566 uloc_minimizeSubtags(
5572 if (status
== U_ZERO_ERROR
) {
5573 log_err(" unexpected U_ZERO_ERROR for uloc_minimizeSubtags(), maximal \"%s\" expected status %s\n", maximal
, u_errorName(expectedStatus
));
5574 status
= U_ZERO_ERROR
;
5576 else if (status
!= expectedStatus
) {
5577 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
));
5579 else if (length
!= expectedLength
) {
5580 log_err(" unexpected length for uloc_minimizeSubtags(), maximal \"%s\" expected length %d, but got %d\n", maximal
, expectedLength
, length
);
5582 else if (status
== U_BUFFER_OVERFLOW_ERROR
|| status
== U_STRING_NOT_TERMINATED_WARNING
) {
5583 if (uprv_strnicmp(minimal
, buffer
, bufferSize
) != 0) {
5584 log_err(" minimal doesn't match expected \"%s\" in uloc_minimizeSubtags(), minimal \"%s\" = \"%*s\"\n",
5585 minimal
, maximal
, (int)sizeof(buffer
), buffer
);
5591 const char* const locale_to_langtag
[][3] = {
5592 {"@x=elmer", "x-elmer", "x-elmer"},
5595 {"en_US", "en-US", "en-US"},
5596 {"iw_IL", "he-IL", "he-IL"},
5597 {"sr_Latn_SR", "sr-Latn-SR", "sr-Latn-SR"},
5598 {"en__POSIX", "en-u-va-posix", "en-u-va-posix"},
5599 {"en_POSIX", "en-u-va-posix", "en-u-va-posix"},
5600 {"en_US_POSIX_VAR", "en-US-posix-x-lvariant-var", NULL
}, /* variant POSIX_VAR is processed as regular variant */
5601 {"en_US_VAR_POSIX", "en-US-x-lvariant-var-posix", NULL
}, /* variant VAR_POSIX is processed as regular variant */
5602 {"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 */
5603 {"en_US_POSIX@ca=japanese", "en-US-u-ca-japanese-va-posix", "en-US-u-ca-japanese-va-posix"},
5604 {"und_555", "und-555", "und-555"},
5605 {"123", "und", NULL
},
5606 {"%$#&", "und", NULL
},
5607 {"_Latn", "und-Latn", "und-Latn"},
5608 {"_DE", "und-DE", "und-DE"},
5609 {"und_FR", "und-FR", "und-FR"},
5610 {"th_TH_TH", "th-TH-x-lvariant-th", NULL
},
5611 {"bogus", "bogus", "bogus"},
5612 {"foooobarrr", "und", NULL
},
5613 {"az_AZ_CYRL", "az-Cyrl-AZ", "az-Cyrl-AZ"},
5614 {"aa_BB_CYRL", "aa-BB-x-lvariant-cyrl", NULL
},
5615 {"en_US_1234", "en-US-1234", "en-US-1234"},
5616 {"en_US_VARIANTA_VARIANTB", "en-US-varianta-variantb", "en-US-varianta-variantb"},
5617 {"ja__9876_5432", "ja-9876-5432", "ja-9876-5432"},
5618 {"zh_Hant__VAR", "zh-Hant-x-lvariant-var", NULL
},
5619 {"es__BADVARIANT_GOODVAR", "es-goodvar", NULL
},
5620 {"en@calendar=gregorian", "en-u-ca-gregory", "en-u-ca-gregory"},
5621 {"de@collation=phonebook;calendar=gregorian", "de-u-ca-gregory-co-phonebk", "de-u-ca-gregory-co-phonebk"},
5622 {"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"},
5623 {"en@timezone=America/New_York;calendar=japanese", "en-u-ca-japanese-tz-usnyc", "en-u-ca-japanese-tz-usnyc"},
5624 {"en@timezone=US/Eastern", "en-u-tz-usnyc", "en-u-tz-usnyc"},
5625 {"en@x=x-y-z;a=a-b-c", "en-x-x-y-z", NULL
},
5626 {"it@collation=badcollationtype;colStrength=identical;cu=usd-eur", "it-u-ks-identic", NULL
},
5627 {"en_US_POSIX", "en-US-u-va-posix", "en-US-u-va-posix"},
5628 {"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"},
5629 {"@x=elmer", "x-elmer", "x-elmer"},
5630 {"en@x=elmer", "en-x-elmer", "en-x-elmer"},
5631 {"@x=elmer;a=exta", "und-a-exta-x-elmer", "und-a-exta-x-elmer"},
5632 {"en_US@attribute=attr1-attr2;calendar=gregorian", "en-US-u-attr1-attr2-ca-gregory", "en-US-u-attr1-attr2-ca-gregory"},
5636 static void TestToLanguageTag(void) {
5642 const char *expected
;
5644 for (i
= 0; locale_to_langtag
[i
][0] != NULL
; i
++) {
5645 inloc
= locale_to_langtag
[i
][0];
5647 /* testing non-strict mode */
5648 status
= U_ZERO_ERROR
;
5650 expected
= locale_to_langtag
[i
][1];
5652 len
= uloc_toLanguageTag(inloc
, langtag
, sizeof(langtag
), FALSE
, &status
);
5653 if (U_FAILURE(status
)) {
5654 if (expected
!= NULL
) {
5655 log_err("Error returned by uloc_toLanguageTag for locale id [%s] - error: %s\n",
5656 inloc
, u_errorName(status
));
5659 if (expected
== NULL
) {
5660 log_err("Error should be returned by uloc_toLanguageTag for locale id [%s], but [%s] is returned without errors\n",
5662 } else if (uprv_strcmp(langtag
, expected
) != 0) {
5663 log_data_err("uloc_toLanguageTag returned language tag [%s] for input locale [%s] - expected: [%s]. Are you missing data?\n",
5664 langtag
, inloc
, expected
);
5668 /* testing strict mode */
5669 status
= U_ZERO_ERROR
;
5671 expected
= locale_to_langtag
[i
][2];
5673 len
= uloc_toLanguageTag(inloc
, langtag
, sizeof(langtag
), TRUE
, &status
);
5674 if (U_FAILURE(status
)) {
5675 if (expected
!= NULL
) {
5676 log_data_err("Error returned by uloc_toLanguageTag {strict} for locale id [%s] - error: %s Are you missing data?\n",
5677 inloc
, u_errorName(status
));
5680 if (expected
== NULL
) {
5681 log_err("Error should be returned by uloc_toLanguageTag {strict} for locale id [%s], but [%s] is returned without errors\n",
5683 } else if (uprv_strcmp(langtag
, expected
) != 0) {
5684 log_err("uloc_toLanguageTag {strict} returned language tag [%s] for input locale [%s] - expected: [%s]\n",
5685 langtag
, inloc
, expected
);
5691 #define FULL_LENGTH -1
5692 static const struct {
5696 } langtag_to_locale
[] = {
5697 {"en", "en", FULL_LENGTH
},
5698 {"en-us", "en_US", FULL_LENGTH
},
5699 {"und-US", "_US", FULL_LENGTH
},
5700 {"und-latn", "_Latn", FULL_LENGTH
},
5701 {"en-US-posix", "en_US_POSIX", FULL_LENGTH
},
5702 {"de-de_euro", "de", 2},
5703 {"kok-IN", "kok_IN", FULL_LENGTH
},
5706 {"en-latn-x", "en_Latn", 7},
5707 {"art-lojban", "jbo", FULL_LENGTH
},
5708 {"zh-hakka", "hak", FULL_LENGTH
},
5709 {"zh-cmn-CH", "cmn_CH", FULL_LENGTH
},
5710 {"xxx-yy", "xxx_YY", FULL_LENGTH
},
5711 {"fr-234", "fr_234", FULL_LENGTH
},
5712 {"i-default", "en@x=i-default", FULL_LENGTH
},
5714 {"ja-jp-jp", "ja_JP", 5},
5715 {"bogus", "bogus", FULL_LENGTH
},
5716 {"boguslang", "", 0},
5717 {"EN-lATN-us", "en_Latn_US", FULL_LENGTH
},
5718 {"und-variant-1234", "__VARIANT_1234", FULL_LENGTH
},
5719 {"und-varzero-var1-vartwo", "__VARZERO", 11},
5720 {"en-u-ca-gregory", "en@calendar=gregorian", FULL_LENGTH
},
5721 {"en-U-cu-USD", "en@currency=usd", FULL_LENGTH
},
5722 {"en-US-u-va-posix", "en_US_POSIX", FULL_LENGTH
},
5723 {"en-us-u-ca-gregory-va-posix", "en_US_POSIX@calendar=gregorian", FULL_LENGTH
},
5724 {"en-us-posix-u-va-posix", "en_US_POSIX@va=posix", FULL_LENGTH
},
5725 {"en-us-u-va-posix2", "en_US@va=posix2", FULL_LENGTH
},
5726 {"en-us-vari1-u-va-posix", "en_US_VARI1@va=posix", FULL_LENGTH
},
5727 {"ar-x-1-2-3", "ar@x=1-2-3", FULL_LENGTH
},
5728 {"fr-u-nu-latn-cu-eur", "fr@currency=eur;numbers=latn", FULL_LENGTH
},
5729 {"de-k-kext-u-co-phonebk-nu-latn", "de@collation=phonebook;k=kext;numbers=latn", FULL_LENGTH
},
5730 {"ja-u-cu-jpy-ca-jp", "ja@calendar=yes;currency=jpy;jp=yes", FULL_LENGTH
},
5731 {"en-us-u-tz-usnyc", "en_US@timezone=America/New_York", FULL_LENGTH
},
5732 {"und-a-abc-def", "und@a=abc-def", FULL_LENGTH
},
5733 {"zh-u-ca-chinese-x-u-ca-chinese", "zh@calendar=chinese;x=u-ca-chinese", FULL_LENGTH
},
5734 {"x-elmer", "@x=elmer", FULL_LENGTH
},
5735 {"en-US-u-attr1-attr2-ca-gregory", "en_US@attribute=attr1-attr2;calendar=gregorian", FULL_LENGTH
},
5736 {"sr-u-kn", "sr@colnumeric=yes", FULL_LENGTH
},
5737 {"de-u-kn-co-phonebk", "de@collation=phonebook;colnumeric=yes", FULL_LENGTH
},
5738 {"en-u-attr2-attr1-kn-kb", "en@attribute=attr1-attr2;colbackwards=yes;colnumeric=yes", FULL_LENGTH
},
5739 {"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
},
5741 {"de-u-xc-xphonebk-co-phonebk-ca-buddhist-mo-very-lo-extensi-xd-that-de-should-vc-probably-xz-killthebuffer",
5742 "de@calendar=buddhist;collation=phonebook;de=should;lo=extensi;mo=very;vc=probably;xc=xphonebk;xd=that;xz=yes", 91},
5746 static void TestForLanguageTag(void) {
5751 int32_t expParsedLen
;
5753 for (i
= 0; langtag_to_locale
[i
].bcpID
!= NULL
; i
++) {
5754 status
= U_ZERO_ERROR
;
5756 expParsedLen
= langtag_to_locale
[i
].len
;
5757 if (expParsedLen
== FULL_LENGTH
) {
5758 expParsedLen
= uprv_strlen(langtag_to_locale
[i
].bcpID
);
5760 uloc_forLanguageTag(langtag_to_locale
[i
].bcpID
, locale
, sizeof(locale
), &parsedLen
, &status
);
5761 if (U_FAILURE(status
)) {
5762 log_err_status(status
, "Error returned by uloc_forLanguageTag for language tag [%s] - error: %s\n",
5763 langtag_to_locale
[i
].bcpID
, u_errorName(status
));
5765 if (uprv_strcmp(langtag_to_locale
[i
].locID
, locale
) != 0) {
5766 log_err("uloc_forLanguageTag returned locale [%s] for input language tag [%s] - expected: [%s]\n",
5767 locale
, langtag_to_locale
[i
].bcpID
, langtag_to_locale
[i
].locID
);
5769 if (parsedLen
!= expParsedLen
) {
5770 log_err("uloc_forLanguageTag parsed length of %d for input language tag [%s] - expected parsed length: %d\n",
5771 parsedLen
, langtag_to_locale
[i
].bcpID
, expParsedLen
);
5777 static void test_unicode_define(const char *namech
, char ch
, const char *nameu
, UChar uch
)
5781 log_verbose("Testing whether %s[\\x%02x,'%c'] == %s[U+%04X]\n", namech
, ch
,(int)ch
, nameu
, (int) uch
);
5782 u_charsToUChars(&ch
, asUch
, 1);
5783 if(asUch
[0] != uch
) {
5784 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
);
5786 log_verbose(" .. OK, == U+%04X\n", (int)asUch
[0]);
5790 #define TEST_UNICODE_DEFINE(x,y) test_unicode_define(#x, (char)(x), #y, (UChar)(y))
5792 static void TestUnicodeDefines(void) {
5793 TEST_UNICODE_DEFINE(ULOC_KEYWORD_SEPARATOR
, ULOC_KEYWORD_SEPARATOR_UNICODE
);
5794 TEST_UNICODE_DEFINE(ULOC_KEYWORD_ASSIGN
, ULOC_KEYWORD_ASSIGN_UNICODE
);
5795 TEST_UNICODE_DEFINE(ULOC_KEYWORD_ITEM_SEPARATOR
, ULOC_KEYWORD_ITEM_SEPARATOR_UNICODE
);