1 /********************************************************************
2 * COPYRIGHT:
3 * Copyright (c) 1997-2007, International Business Machines Corporation and
4 * others. All Rights Reserved.
5 ********************************************************************/
6 /*****************************************************************************
7 *
8 * File CLOCTST.C
9 *
10 * Modification History:
11 * Name Description
12 * Madhu Katragadda Ported for C API
13 ******************************************************************************
14 */
15 #include "cloctst.h"
16 #include <stdlib.h>
17 #include <stdio.h>
18 #include <string.h>
19 #include "cintltst.h"
20 #include "cstring.h"
21 #include "uparse.h"
22 #include "uresimp.h"
23
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 */
37 #define LENGTHOF(array) (int32_t)(sizeof(array)/sizeof((array)[0]))
38
39 static void TestNullDefault(void);
40 static void TestNonexistentLanguageExemplars(void);
41 static void TestLocDataErrorCodeChaining(void);
42 static void TestLanguageExemplarsFallbacks(void);
43
44 void PrintDataTable();
45
46 /*---------------------------------------------------
47 table of valid data
48 --------------------------------------------------- */
49 #define LOCALE_SIZE 9
50 #define LOCALE_INFO_SIZE 28
51
52 static const char* const rawData2[LOCALE_INFO_SIZE][LOCALE_SIZE] = {
53 /* language code */
54 { "en", "fr", "ca", "el", "no", "zh", "de", "es", "ja" },
55 /* script code */
56 { "", "", "", "", "", "Hans", "", "", "" },
57 /* country code */
58 { "US", "FR", "ES", "GR", "NO", "CN", "DE", "", "JP" },
59 /* variant code */
60 { "", "", "", "", "NY", "", "", "", "" },
61 /* full name */
62 { "en_US", "fr_FR", "ca_ES",
63 "el_GR", "no_NO_NY", "zh_Hans_CN",
64 "de_DE@collation=phonebook", "es@collation=traditional", "ja_JP@calendar=japanese" },
65 /* ISO-3 language */
66 { "eng", "fra", "cat", "ell", "nor", "zho", "deu", "spa", "jpn" },
67 /* ISO-3 country */
68 { "USA", "FRA", "ESP", "GRC", "NOR", "CHN", "DEU", "", "JPN" },
69 /* LCID */
70 { "409", "40c", "403", "408", "814", "804", "10407", "40a", "411" },
71
72 /* display language (English) */
73 { "English", "French", "Catalan", "Greek", "Norwegian", "Chinese", "German", "Spanish", "Japanese" },
74 /* display script code (English) */
75 { "", "", "", "", "", "Simplified Han", "", "", "" },
76 /* display country (English) */
77 { "United States", "France", "Spain", "Greece", "Norway", "China", "Germany", "", "Japan" },
78 /* display variant (English) */
79 { "", "", "", "", "NY", "", "", "", "" },
80 /* display name (English) */
81 { "English (United States)", "French (France)", "Catalan (Spain)",
82 "Greek (Greece)", "Norwegian (Norway, NY)", "Chinese (Simplified Han, China)",
83 "German (Germany, collation=Phonebook Sort Order)", "Spanish (collation=Traditional Sort Order)", "Japanese (Japan, calendar=Japanese Calendar)" },
84
85 /* display language (French) */
86 { "anglais", "fran\\u00E7ais", "catalan", "grec", "norv\\u00E9gien", "chinois", "allemand", "espagnol", "japonais" },
87 /* display script code (French) */
88 { "", "", "", "", "", "id\\u00e9ogrammes han (variante simplifi\\u00e9e)", "", "", "" },
89 /* display country (French) */
90 { "\\u00C9tats-Unis", "France", "Espagne", "Gr\\u00E8ce", "Norv\\u00E8ge", "Chine", "Allemagne", "", "Japon" },
91 /* display variant (French) */
92 { "", "", "", "", "NY", "", "", "", "" },
93 /* display name (French) */
94 { "anglais (\\u00C9tats-Unis)", "fran\\u00E7ais (France)", "catalan (Espagne)",
95 "grec (Gr\\u00E8ce)", "norv\\u00E9gien (Norv\\u00E8ge, NY)", "chinois (id\\u00e9ogrammes han (variante simplifi\\u00e9e), Chine)",
96 "allemand (Allemagne, Ordonnancement=Ordre de l\\u2019annuaire)", "espagnol (Ordonnancement=Ordre traditionnel)", "japonais (Japon, Calendrier=Calendrier japonais)" },
97
98 /* display language (Catalan) */
99 { "angl\\u00E8s", "franc\\u00E8s", "catal\\u00E0", "grec", "noruec", "xin\\u00E9s", "alemany", "espanyol", "japon\\u00E8s" },
100 /* display script code (Catalan) */
101 { "", "", "", "", "", "Hans", "", "", "" },
102 /* display country (Catalan) */
103 { "Estats Units", "Fran\\u00E7a", "Espanya", "Gr\\u00E8cia", "Noruega", "Xina", "Alemanya", "", "Jap\\u00F3" },
104 /* display variant (Catalan) */
105 { "", "", "", "", "NY", "", "", "", "" },
106 /* display name (Catalan) */
107 { "angl\\u00E8s (Estats Units)", "franc\\u00E8s (Fran\\u00E7a)", "catal\\u00E0 (Espanya)",
108 "grec (Gr\\u00E8cia)", "noruec (Noruega, NY)", "xin\\u00E9s (Hans, Xina)",
109 "alemany (Alemanya, collation=phonebook)", "espanyol (collation=traditional)", "japon\\u00E8s (Jap\\u00F3, calendar=japanese)" },
110
111 /* display language (Greek) */
112 {
113 "\\u0391\\u03b3\\u03b3\\u03bb\\u03b9\\u03ba\\u03ac",
114 "\\u0393\\u03b1\\u03bb\\u03bb\\u03b9\\u03ba\\u03ac",
115 "\\u039a\\u03b1\\u03c4\\u03b1\\u03bb\\u03b1\\u03bd\\u03b9\\u03ba\\u03ac",
116 "\\u0395\\u03bb\\u03bb\\u03b7\\u03bd\\u03b9\\u03ba\\u03ac",
117 "\\u039d\\u03bf\\u03c1\\u03b2\\u03b7\\u03b3\\u03b9\\u03ba\\u03ac",
118 "\\u039A\\u03B9\\u03BD\\u03B5\\u03B6\\u03B9\\u03BA\\u03AC",
119 "\\u0393\\u03B5\\u03C1\\u03BC\\u03B1\\u03BD\\u03B9\\u03BA\\u03AC",
120 "\\u0399\\u03C3\\u03C0\\u03B1\\u03BD\\u03B9\\u03BA\\u03AC",
121 "\\u0399\\u03B1\\u03C0\\u03C9\\u03BD\\u03B9\\u03BA\\u03AC"
122 },
123 /* display script code (Greek) */
124
125 { "", "", "", "", "", "\\u039a\\u03b9\\u03bd\\u03b5\\u03b6\\u03b9\\u03ba\\u03cc \\u0391\\u03c0\\u03bb\\u03bf\\u03c0\\u03bf\\u03b9\\u03b7\\u03bc\\u03ad\\u03bd\\u03bf", "", "", "" },
126 /* display country (Greek) */
127 {
128 "\\u0397\\u03bd\\u03c9\\u03bc\\u03ad\\u03bd\\u03b5\\u03c2 \\u03a0\\u03bf\\u03bb\\u03b9\\u03c4\\u03b5\\u03af\\u03b5\\u03c2",
129 "\\u0393\\u03b1\\u03bb\\u03bb\\u03af\\u03b1",
130 "\\u0399\\u03c3\\u03c0\\u03b1\\u03bd\\u03af\\u03b1",
131 "\\u0395\\u03bb\\u03bb\\u03ac\\u03b4\\u03b1",
132 "\\u039d\\u03bf\\u03c1\\u03b2\\u03b7\\u03b3\\u03af\\u03b1",
133 "\\u039A\\u03AF\\u03BD\\u03B1",
134 "\\u0393\\u03B5\\u03C1\\u03BC\\u03B1\\u03BD\\u03AF\\u03B1",
135 "",
136 "\\u0399\\u03B1\\u03C0\\u03C9\\u03BD\\u03AF\\u03B1"
137 },
138 /* display variant (Greek) */
139 { "", "", "", "", "NY", "", "", "", "" }, /* TODO: currently there is no translation for NY in Greek fix this test when we have it */
140 /* display name (Greek) */
141 {
142 "\\u0391\\u03b3\\u03b3\\u03bb\\u03b9\\u03ba\\u03ac (\\u0397\\u03bd\\u03c9\\u03bc\\u03ad\\u03bd\\u03b5\\u03c2 \\u03a0\\u03bf\\u03bb\\u03b9\\u03c4\\u03b5\\u03af\\u03b5\\u03c2)",
143 "\\u0393\\u03b1\\u03bb\\u03bb\\u03b9\\u03ba\\u03ac (\\u0393\\u03b1\\u03bb\\u03bb\\u03af\\u03b1)",
144 "\\u039a\\u03b1\\u03c4\\u03b1\\u03bb\\u03b1\\u03bd\\u03b9\\u03ba\\u03ac (\\u0399\\u03c3\\u03c0\\u03b1\\u03bd\\u03af\\u03b1)",
145 "\\u0395\\u03bb\\u03bb\\u03b7\\u03bd\\u03b9\\u03ba\\u03ac (\\u0395\\u03bb\\u03bb\\u03ac\\u03b4\\u03b1)",
146 "\\u039d\\u03bf\\u03c1\\u03b2\\u03b7\\u03b3\\u03b9\\u03ba\\u03ac (\\u039d\\u03bf\\u03c1\\u03b2\\u03b7\\u03b3\\u03af\\u03b1, NY)",
147 "\\u039A\\u03B9\\u03BD\\u03B5\\u03B6\\u03B9\\u03BA\\u03AC (\\u039a\\u03b9\\u03bd\\u03b5\\u03b6\\u03b9\\u03ba\\u03cc \\u0391\\u03c0\\u03bb\\u03bf\\u03c0\\u03bf\\u03b9\\u03b7\\u03bc\\u03ad\\u03bd\\u03bf, \\u039A\\u03AF\\u03BD\\u03B1)",
148 "\\u0393\\u03B5\\u03C1\\u03BC\\u03B1\\u03BD\\u03B9\\u03BA\\u03AC (\\u0393\\u03B5\\u03C1\\u03BC\\u03B1\\u03BD\\u03AF\\u03B1, \\u03A4\\u03B1\\u03BA\\u03C4\\u03BF\\u03C0\\u03BF\\u03AF\\u03B7\\u03C3\\u03B7=\\u03A3\\u03B5\\u03B9\\u03C1\\u03AC \\u03A4\\u03B7\\u03BB\\u03B5\\u03C6\\u03C9\\u03BD\\u03B9\\u03BA\\u03BF\\u03CD \\u039A\\u03B1\\u03C4\\u03B1\\u03BB\\u03CC\\u03B3\\u03BF\\u03C5)",
149 "\\u0399\\u03C3\\u03C0\\u03B1\\u03BD\\u03B9\\u03BA\\u03AC (\\u03A4\\u03B1\\u03BA\\u03C4\\u03BF\\u03C0\\u03BF\\u03AF\\u03B7\\u03C3\\u03B7\\u003D\\u03A0\\u03B1\\u03C1\\u03B1\\u03B4\\u03BF\\u03C3\\u03B9\\u03B1\\u03BA\\u03AE \\u03A3\\u03B5\\u03B9\\u03C1\\u03AC)",
150 "\\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 \\u0397\\u03BC\\u03B5\\u03C1\\u03BF\\u03BB\\u03CC\\u03B3\\u03B9\\u03BF)"
151 }
152 };
153
154 static UChar*** dataTable=0;
155 enum {
156 ENGLISH = 0,
157 FRENCH = 1,
158 CATALAN = 2,
159 GREEK = 3,
160 NORWEGIAN = 4
161 };
162
163 enum {
164 LANG = 0,
165 SCRIPT = 1,
166 CTRY = 2,
167 VAR = 3,
168 NAME = 4,
169 LANG3 = 5,
170 CTRY3 = 6,
171 LCID = 7,
172 DLANG_EN = 8,
173 DSCRIPT_EN = 9,
174 DCTRY_EN = 10,
175 DVAR_EN = 11,
176 DNAME_EN = 12,
177 DLANG_FR = 13,
178 DSCRIPT_FR = 14,
179 DCTRY_FR = 15,
180 DVAR_FR = 16,
181 DNAME_FR = 17,
182 DLANG_CA = 18,
183 DSCRIPT_CA = 19,
184 DCTRY_CA = 20,
185 DVAR_CA = 21,
186 DNAME_CA = 22,
187 DLANG_EL = 23,
188 DSCRIPT_EL = 24,
189 DCTRY_EL = 25,
190 DVAR_EL = 26,
191 DNAME_EL = 27
192 };
193
194 #define TESTCASE(name) addTest(root, &name, "tsutil/cloctst/" #name)
195
196 void addLocaleTest(TestNode** root);
197
addLocaleTest(TestNode ** root)198 void addLocaleTest(TestNode** root)
199 {
200 TESTCASE(TestObsoleteNames); /* srl- move */
201 TESTCASE(TestBasicGetters);
202 TESTCASE(TestNullDefault);
203 TESTCASE(TestPrefixes);
204 TESTCASE(TestSimpleResourceInfo);
205 TESTCASE(TestDisplayNames);
206 TESTCASE(TestGetAvailableLocales);
207 TESTCASE(TestDataDirectory);
208 TESTCASE(TestISOFunctions);
209 TESTCASE(TestISO3Fallback);
210 TESTCASE(TestUninstalledISO3Names);
211 TESTCASE(TestSimpleDisplayNames);
212 TESTCASE(TestVariantParsing);
213 TESTCASE(TestKeywordVariants);
214 TESTCASE(TestKeywordVariantParsing);
215 TESTCASE(TestCanonicalization);
216 TESTCASE(TestKeywordSet);
217 TESTCASE(TestKeywordSetError);
218 TESTCASE(TestDisplayKeywords);
219 TESTCASE(TestDisplayKeywordValues);
220 TESTCASE(TestGetBaseName);
221 TESTCASE(TestGetLocale);
222 TESTCASE(TestDisplayNameWarning);
223 TESTCASE(TestNonexistentLanguageExemplars);
224 TESTCASE(TestLocDataErrorCodeChaining);
225 TESTCASE(TestLanguageExemplarsFallbacks);
226 TESTCASE(TestCalendar);
227 TESTCASE(TestDateFormat);
228 TESTCASE(TestCollation);
229 TESTCASE(TestULocale);
230 TESTCASE(TestUResourceBundle);
231 TESTCASE(TestDisplayName);
232 TESTCASE(TestAcceptLanguage);
233 TESTCASE(TestGetLocaleForLCID);
234 }
235
236
237 /* testing uloc(), uloc_getName(), uloc_getLanguage(), uloc_getVariant(), uloc_getCountry() */
TestBasicGetters()238 static void TestBasicGetters() {
239 int32_t i;
240 int32_t cap;
241 UErrorCode status = U_ZERO_ERROR;
242 char *testLocale = 0;
243 char *temp = 0, *name = 0;
244 log_verbose("Testing Basic Getters\n");
245 for (i = 0; i < LOCALE_SIZE; i++) {
246 testLocale=(char*)malloc(sizeof(char) * (strlen(rawData2[NAME][i])+1));
247 strcpy(testLocale,rawData2[NAME][i]);
248
249 log_verbose("Testing %s .....\n", testLocale);
250 cap=uloc_getLanguage(testLocale, NULL, 0, &status);
251 if(status==U_BUFFER_OVERFLOW_ERROR){
252 status=U_ZERO_ERROR;
253 temp=(char*)malloc(sizeof(char) * (cap+1));
254 uloc_getLanguage(testLocale, temp, cap+1, &status);
255 }
256 if(U_FAILURE(status)){
257 log_err("ERROR: in uloc_getLanguage %s\n", myErrorName(status));
258 }
259 if (0 !=strcmp(temp,rawData2[LANG][i])) {
260 log_err(" Language code mismatch: %s versus %s\n", temp, rawData2[LANG][i]);
261 }
262
263
264 cap=uloc_getCountry(testLocale, temp, cap, &status);
265 if(status==U_BUFFER_OVERFLOW_ERROR){
266 status=U_ZERO_ERROR;
267 temp=(char*)realloc(temp, sizeof(char) * (cap+1));
268 uloc_getCountry(testLocale, temp, cap+1, &status);
269 }
270 if(U_FAILURE(status)){
271 log_err("ERROR: in uloc_getCountry %s\n", myErrorName(status));
272 }
273 if (0 != strcmp(temp, rawData2[CTRY][i])) {
274 log_err(" Country code mismatch: %s versus %s\n", temp, rawData2[CTRY][i]);
275
276 }
277
278 cap=uloc_getVariant(testLocale, temp, cap, &status);
279 if(status==U_BUFFER_OVERFLOW_ERROR){
280 status=U_ZERO_ERROR;
281 temp=(char*)realloc(temp, sizeof(char) * (cap+1));
282 uloc_getVariant(testLocale, temp, cap+1, &status);
283 }
284 if(U_FAILURE(status)){
285 log_err("ERROR: in uloc_getVariant %s\n", myErrorName(status));
286 }
287 if (0 != strcmp(temp, rawData2[VAR][i])) {
288 log_err("Variant code mismatch: %s versus %s\n", temp, rawData2[VAR][i]);
289 }
290
291 cap=uloc_getName(testLocale, NULL, 0, &status);
292 if(status==U_BUFFER_OVERFLOW_ERROR){
293 status=U_ZERO_ERROR;
294 name=(char*)malloc(sizeof(char) * (cap+1));
295 uloc_getName(testLocale, name, cap+1, &status);
296 } else if(status==U_ZERO_ERROR) {
297 log_err("ERROR: in uloc_getName(%s,NULL,0,..), expected U_BUFFER_OVERFLOW_ERROR!\n", testLocale);
298 }
299 if(U_FAILURE(status)){
300 log_err("ERROR: in uloc_getName %s\n", myErrorName(status));
301 }
302 if (0 != strcmp(name, rawData2[NAME][i])){
303 log_err(" Mismatch in getName: %s versus %s\n", name, rawData2[NAME][i]);
304 }
305
306 free(temp);
307 free(name);
308
309 free(testLocale);
310 }
311 }
312
TestNullDefault()313 static void TestNullDefault() {
314 UErrorCode status = U_ZERO_ERROR;
315 char original[ULOC_FULLNAME_CAPACITY];
316
317 uprv_strcpy(original, uloc_getDefault());
318 uloc_setDefault("qq_BLA", &status);
319 if (uprv_strcmp(uloc_getDefault(), "qq_BLA") != 0) {
320 log_err(" Mismatch in uloc_setDefault: qq_BLA versus %s\n", uloc_getDefault());
321 }
322 uloc_setDefault(NULL, &status);
323 if (uprv_strcmp(uloc_getDefault(), original) != 0) {
324 log_err(" uloc_setDefault(NULL, &status) didn't get the default locale back!\n");
325 }
326
327 {
328 /* Test that set & get of default locale work, and that
329 * default locales are cached and reused, and not overwritten.
330 */
331 const char *n_en_US;
332 const char *n_fr_FR;
333 const char *n2_en_US;
334
335 status = U_ZERO_ERROR;
336 uloc_setDefault("en_US", &status);
337 n_en_US = uloc_getDefault();
338 if (strcmp(n_en_US, "en_US") != 0) {
339 log_err("Wrong result from uloc_getDefault(). Expected \"en_US\", got \"%s\"\n", n_en_US);
340 }
341
342 uloc_setDefault("fr_FR", &status);
343 n_fr_FR = uloc_getDefault();
344 if (strcmp(n_en_US, "en_US") != 0) {
345 log_err("uloc_setDefault altered previously default string."
346 "Expected \"en_US\", got \"%s\"\n", n_en_US);
347 }
348 if (strcmp(n_fr_FR, "fr_FR") != 0) {
349 log_err("Wrong result from uloc_getDefault(). Expected \"fr_FR\", got %s\n", n_fr_FR);
350 }
351
352 uloc_setDefault("en_US", &status);
353 n2_en_US = uloc_getDefault();
354 if (strcmp(n2_en_US, "en_US") != 0) {
355 log_err("Wrong result from uloc_getDefault(). Expected \"en_US\", got \"%s\"\n", n_en_US);
356 }
357 if (n2_en_US != n_en_US) {
358 log_err("Default locale cache failed to reuse en_US locale.\n");
359 }
360
361 if (U_FAILURE(status)) {
362 log_err("Failure returned from uloc_setDefault - \"%s\"\n", u_errorName(status));
363 }
364
365 }
366
367 }
368 /* Test the i- and x- and @ and . functionality
369 */
370
371 #define PREFIXBUFSIZ 128
372
TestPrefixes()373 static void TestPrefixes() {
374 int row = 0;
375 int n;
376 const char *loc, *expected;
377
378 static const char * const testData[][7] =
379 {
380 /* NULL canonicalize() column means "expect same as getName()" */
381 {"sv", "", "FI", "AL", "sv-fi-al", "sv_FI_AL", NULL},
382 {"en", "", "GB", "", "en-gb", "en_GB", NULL},
383 {"i-hakka", "", "MT", "XEMXIJA", "i-hakka_MT_XEMXIJA", "i-hakka_MT_XEMXIJA", NULL},
384 {"i-hakka", "", "CN", "", "i-hakka_CN", "i-hakka_CN", NULL},
385 {"i-hakka", "", "MX", "", "I-hakka_MX", "i-hakka_MX", NULL},
386 {"x-klingon", "", "US", "SANJOSE", "X-KLINGON_us_SANJOSE", "x-klingon_US_SANJOSE", NULL},
387
388 {"mr", "", "", "", "mr.utf8", "mr.utf8", "mr"},
389 {"de", "", "TV", "", "de-tv.koi8r", "de_TV.koi8r", "de_TV"},
390 {"x-piglatin", "", "ML", "", "x-piglatin_ML.MBE", "x-piglatin_ML.MBE", "x-piglatin_ML"}, /* Multibyte English */
391 {"i-cherokee", "","US", "", "i-Cherokee_US.utf7", "i-cherokee_US.utf7", "i-cherokee_US"},
392 {"x-filfli", "", "MT", "FILFLA", "x-filfli_MT_FILFLA.gb-18030", "x-filfli_MT_FILFLA.gb-18030", "x-filfli_MT_FILFLA"},
393 {"no", "", "NO", "NY", "no-no-ny.utf32@B", "no_NO_NY.utf32@B", "no_NO_NY_B"},
394 {"no", "", "NO", "", "no-no.utf32@B", "no_NO.utf32@B", "no_NO_B"},
395 {"no", "", "", "NY", "no__ny", "no__NY", NULL},
396 {"no", "", "", "", "no@ny", "no@ny", "no__NY"},
397 {"el", "Latn", "", "", "el-latn", "el_Latn", NULL},
398 {"en", "Cyrl", "RU", "", "en-cyrl-ru", "en_Cyrl_RU", NULL},
399 {"zh", "Hant", "TW", "STROKE", "zh-hant_TW_STROKE", "zh_Hant_TW_STROKE", NULL},
400 {"qq", "Qqqq", "QQ", "QQ", "qq_Qqqq_QQ_QQ", "qq_Qqqq_QQ_QQ", NULL},
401 {"qq", "Qqqq", "", "QQ", "qq_Qqqq__QQ", "qq_Qqqq__QQ", NULL},
402 {"12", "3456", "78", "90", "12_3456_78_90", "12_3456_78_90", NULL}, /* total garbage */
403
404 {NULL,NULL,NULL,NULL,NULL,NULL,NULL}
405 };
406
407 static const char * const testTitles[] = {
408 "uloc_getLanguage()",
409 "uloc_getScript()",
410 "uloc_getCountry()",
411 "uloc_getVariant()",
412 "name",
413 "uloc_getName()",
414 "uloc_canonicalize()"
415 };
416
417 char buf[PREFIXBUFSIZ];
418 int32_t len;
419 UErrorCode err;
420
421
422 for(row=0;testData[row][0] != NULL;row++) {
423 loc = testData[row][NAME];
424 log_verbose("Test #%d: %s\n", row, loc);
425
426 err = U_ZERO_ERROR;
427 len=0;
428 buf[0]=0;
429 for(n=0;n<=(NAME+2);n++) {
430 if(n==NAME) continue;
431
432 for(len=0;len<PREFIXBUFSIZ;len++) {
433 buf[len] = '%'; /* Set a tripwire.. */
434 }
435 len = 0;
436
437 switch(n) {
438 case LANG:
439 len = uloc_getLanguage(loc, buf, PREFIXBUFSIZ, &err);
440 break;
441
442 case SCRIPT:
443 len = uloc_getScript(loc, buf, PREFIXBUFSIZ, &err);
444 break;
445
446 case CTRY:
447 len = uloc_getCountry(loc, buf, PREFIXBUFSIZ, &err);
448 break;
449
450 case VAR:
451 len = uloc_getVariant(loc, buf, PREFIXBUFSIZ, &err);
452 break;
453
454 case NAME+1:
455 len = uloc_getName(loc, buf, PREFIXBUFSIZ, &err);
456 break;
457
458 case NAME+2:
459 len = uloc_canonicalize(loc, buf, PREFIXBUFSIZ, &err);
460 break;
461
462 default:
463 strcpy(buf, "**??");
464 len=4;
465 }
466
467 if(U_FAILURE(err)) {
468 log_err("#%d: %s on %s: err %s\n",
469 row, testTitles[n], loc, u_errorName(err));
470 } else {
471 log_verbose("#%d: %s on %s: -> [%s] (length %d)\n",
472 row, testTitles[n], loc, buf, len);
473
474 if(len != (int32_t)strlen(buf)) {
475 log_err("#%d: %s on %s: -> [%s] (length returned %d, actual %d!)\n",
476 row, testTitles[n], loc, buf, len, strlen(buf)+1);
477
478 }
479
480 /* see if they smashed something */
481 if(buf[len+1] != '%') {
482 log_err("#%d: %s on %s: -> [%s] - wrote [%X] out ofbounds!\n",
483 row, testTitles[n], loc, buf, buf[len+1]);
484 }
485
486 expected = testData[row][n];
487 if (expected == NULL && n == (NAME+2)) {
488 /* NULL expected canonicalize() means "expect same as getName()" */
489 expected = testData[row][NAME+1];
490 }
491 if(strcmp(buf, expected)) {
492 log_err("#%d: %s on %s: -> [%s] (expected '%s'!)\n",
493 row, testTitles[n], loc, buf, expected);
494
495 }
496 }
497 }
498 }
499 }
500
501
502 /* testing uloc_getISO3Language(), uloc_getISO3Country(), */
TestSimpleResourceInfo()503 static void TestSimpleResourceInfo() {
504 int32_t i;
505 char* testLocale = 0;
506 UChar* expected = 0;
507
508 const char* temp;
509 char temp2[20];
510 testLocale=(char*)malloc(sizeof(char) * 1);
511 expected=(UChar*)malloc(sizeof(UChar) * 1);
512
513 setUpDataTable();
514 log_verbose("Testing getISO3Language and getISO3Country\n");
515 for (i = 0; i < LOCALE_SIZE; i++) {
516
517 testLocale=(char*)realloc(testLocale, sizeof(char) * (u_strlen(dataTable[NAME][i])+1));
518 u_austrcpy(testLocale, dataTable[NAME][i]);
519
520 log_verbose("Testing %s ......\n", testLocale);
521
522 temp=uloc_getISO3Language(testLocale);
523 expected=(UChar*)realloc(expected, sizeof(UChar) * (strlen(temp) + 1));
524 u_uastrcpy(expected,temp);
525 if (0 != u_strcmp(expected, dataTable[LANG3][i])) {
526 log_err(" ISO-3 language code mismatch: %s versus %s\n", austrdup(expected),
527 austrdup(dataTable[LANG3][i]));
528 }
529
530 temp=uloc_getISO3Country(testLocale);
531 expected=(UChar*)realloc(expected, sizeof(UChar) * (strlen(temp) + 1));
532 u_uastrcpy(expected,temp);
533 if (0 != u_strcmp(expected, dataTable[CTRY3][i])) {
534 log_err(" ISO-3 Country code mismatch: %s versus %s\n", austrdup(expected),
535 austrdup(dataTable[CTRY3][i]));
536 }
537 sprintf(temp2, "%x", (int)uloc_getLCID(testLocale));
538 if (strcmp(temp2, rawData2[LCID][i]) != 0) {
539 log_err("LCID mismatch: %s versus %s\n", temp2 , rawData2[LCID][i]);
540 }
541 }
542
543 free(expected);
544 free(testLocale);
545 cleanUpDataTable();
546 }
547
548 /*
549 * Jitterbug 2439 -- markus 20030425
550 *
551 * The lookup of display names must not fall back through the default
552 * locale because that yields useless results.
553 */
TestDisplayNames()554 static void TestDisplayNames()
555 {
556 UChar buffer[100];
557 UErrorCode errorCode=U_ZERO_ERROR;
558 int32_t length;
559 log_verbose("Testing getDisplayName for different locales\n");
560
561 log_verbose(" In locale = en_US...\n");
562 doTestDisplayNames("en_US", DLANG_EN);
563 log_verbose(" In locale = fr_FR....\n");
564 doTestDisplayNames("fr_FR", DLANG_FR);
565 log_verbose(" In locale = ca_ES...\n");
566 doTestDisplayNames("ca_ES", DLANG_CA);
567 log_verbose(" In locale = gr_EL..\n");
568 doTestDisplayNames("el_GR", DLANG_EL);
569
570 /* test that the default locale has a display name for its own language */
571 errorCode=U_ZERO_ERROR;
572 length=uloc_getDisplayLanguage(NULL, NULL, buffer, LENGTHOF(buffer), &errorCode);
573 if(U_FAILURE(errorCode) || (length<=3 && buffer[0]<=0x7f)) {
574 /* check <=3 to reject getting the language code as a display name */
575 log_err("unable to get a display string for the language of the default locale - %s\n", u_errorName(errorCode));
576 }
577
578 /* test that we get the language code itself for an unknown language, and a default warning */
579 errorCode=U_ZERO_ERROR;
580 length=uloc_getDisplayLanguage("qq", "rr", buffer, LENGTHOF(buffer), &errorCode);
581 if(errorCode!=U_USING_DEFAULT_WARNING || length!=2 || buffer[0]!=0x71 || buffer[1]!=0x71) {
582 log_err("error getting the display string for an unknown language - %s\n", u_errorName(errorCode));
583 }
584
585 /* test that we get a default warning for a display name where one component is unknown (4255) */
586 errorCode=U_ZERO_ERROR;
587 length=uloc_getDisplayName("qq_US_POSIX", "en_US", buffer, LENGTHOF(buffer), &errorCode);
588 if(errorCode!=U_USING_DEFAULT_WARNING) {
589 log_err("error getting the display name for a locale with an unknown language - %s\n", u_errorName(errorCode));
590 }
591
592 {
593 int32_t i;
594 static const char *aLocale = "es@collation=traditional;calendar=japanese";
595 static const char *testL[] = { "en_US",
596 "fr_FR",
597 "ca_ES",
598 "el_GR" };
599 static const char *expect[] = { "Spanish (calendar=Japanese Calendar, collation=Traditional Sort Order)", /* note sorted order of keywords */
600 "espagnol (Calendrier=Calendrier japonais, Ordonnancement=Ordre traditionnel)",
601 "espanyol (calendar=japanese, collation=traditional)",
602 "\\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 \\u0397\\u03BC\\u03B5\\u03C1\\u03BF\\u03BB\\u03CC\\u03B3\\u03B9\\u03BF, \\u03A4\\u03B1\\u03BA\\u03C4\\u03BF\\u03C0\\u03BF\\u03AF\\u03B7\\u03C3\\u03B7=\\u03A0\\u03B1\\u03C1\\u03B1\\u03B4\\u03BF\\u03C3\\u03B9\\u03B1\\u03BA\\u03AE \\u03A3\\u03B5\\u03B9\\u03C1\\u03AC)" };
603 UChar *expectBuffer;
604
605 for(i=0;i<LENGTHOF(testL);i++) {
606 errorCode = U_ZERO_ERROR;
607 uloc_getDisplayName(aLocale, testL[i], buffer, LENGTHOF(buffer), &errorCode);
608 if(U_FAILURE(errorCode)) {
609 log_err("FAIL in uloc_getDisplayName(%s,%s,..) -> %s\n", aLocale, testL[i], u_errorName(errorCode));
610 } else {
611 expectBuffer = CharsToUChars(expect[i]);
612 if(u_strcmp(buffer,expectBuffer)) {
613 log_err("FAIL in uloc_getDisplayName(%s,%s,..) expected '%s' got '%s'\n", aLocale, testL[i], expect[i], austrdup(buffer));
614 } else {
615 log_verbose("pass in uloc_getDisplayName(%s,%s,..) got '%s'\n", aLocale, testL[i], expect[i]);
616 }
617 free(expectBuffer);
618 }
619 }
620 }
621 }
622
623
624 /* test for uloc_getAvialable() and uloc_countAvilable()*/
TestGetAvailableLocales()625 static void TestGetAvailableLocales()
626 {
627
628 const char *locList;
629 int32_t locCount,i;
630
631 log_verbose("Testing the no of avialable locales\n");
632 locCount=uloc_countAvailable();
633 if (locCount == 0)
634 log_data_err("countAvailable() returned an empty list!\n");
635
636 /* use something sensible w/o hardcoding the count */
637 else if(locCount < 0){
638 log_data_err("countAvailable() returned a wrong value!= %d\n", locCount);
639 }
640 else{
641 log_info("Number of locales returned = %d\n", locCount);
642 }
643 for(i=0;i<locCount;i++){
644 locList=uloc_getAvailable(i);
645
646 log_verbose(" %s\n", locList);
647 }
648 }
649
650 /* test for u_getDataDirectory, u_setDataDirectory, uloc_getISO3Language */
TestDataDirectory()651 static void TestDataDirectory()
652 {
653
654 char oldDirectory[512];
655 const char *temp,*testValue1,*testValue2,*testValue3;
656 const char path[40] ="d:\\icu\\source\\test\\intltest" U_FILE_SEP_STRING; /*give the required path */
657
658 log_verbose("Testing getDataDirectory()\n");
659 temp = u_getDataDirectory();
660 strcpy(oldDirectory, temp);
661
662 testValue1=uloc_getISO3Language("en_US");
663 log_verbose("first fetch of language retrieved %s\n", testValue1);
664
665 if (0 != strcmp(testValue1,"eng")){
666 log_err("Initial check of ISO3 language failed: expected \"eng\", got %s \n", testValue1);
667 }
668
669 /*defining the path for DataDirectory */
670 log_verbose("Testing setDataDirectory\n");
671 u_setDataDirectory( path );
672 if(strcmp(path, u_getDataDirectory())==0)
673 log_verbose("setDataDirectory working fine\n");
674 else
675 log_err("Error in setDataDirectory. Directory not set correctly - came back as [%s], expected [%s]\n", u_getDataDirectory(), path);
676
677 testValue2=uloc_getISO3Language("en_US");
678 log_verbose("second fetch of language retrieved %s \n", testValue2);
679
680 u_setDataDirectory(oldDirectory);
681 testValue3=uloc_getISO3Language("en_US");
682 log_verbose("third fetch of language retrieved %s \n", testValue3);
683
684 if (0 != strcmp(testValue3,"eng")) {
685 log_err("get/setDataDirectory() failed: expected \"eng\", got \" %s \" \n", testValue3);
686 }
687 }
688
689
690
691 /*=========================================================== */
692
693 static UChar _NUL=0;
694
doTestDisplayNames(const char * displayLocale,int32_t compareIndex)695 static void doTestDisplayNames(const char* displayLocale, int32_t compareIndex)
696 {
697 UErrorCode status = U_ZERO_ERROR;
698 int32_t i;
699 int32_t maxresultsize;
700
701 const char *testLocale;
702
703
704 UChar *testLang = 0;
705 UChar *testScript = 0;
706 UChar *testCtry = 0;
707 UChar *testVar = 0;
708 UChar *testName = 0;
709
710
711 UChar* expectedLang = 0;
712 UChar* expectedScript = 0;
713 UChar* expectedCtry = 0;
714 UChar* expectedVar = 0;
715 UChar* expectedName = 0;
716
717 setUpDataTable();
718
719 for(i=0;i<LOCALE_SIZE; ++i)
720 {
721 testLocale=rawData2[NAME][i];
722
723 log_verbose("Testing..... %s\n", testLocale);
724
725 maxresultsize=0;
726 maxresultsize=uloc_getDisplayLanguage(testLocale, displayLocale, NULL, maxresultsize, &status);
727 if(status==U_BUFFER_OVERFLOW_ERROR)
728 {
729 status=U_ZERO_ERROR;
730 testLang=(UChar*)malloc(sizeof(UChar) * (maxresultsize+1));
731 uloc_getDisplayLanguage(testLocale, displayLocale, testLang, maxresultsize + 1, &status);
732 }
733 else
734 {
735 testLang=&_NUL;
736 }
737 if(U_FAILURE(status)){
738 log_err("Error in getDisplayLanguage() %s\n", myErrorName(status));
739 }
740
741 maxresultsize=0;
742 maxresultsize=uloc_getDisplayScript(testLocale, displayLocale, NULL, maxresultsize, &status);
743 if(status==U_BUFFER_OVERFLOW_ERROR)
744 {
745 status=U_ZERO_ERROR;
746 testScript=(UChar*)malloc(sizeof(UChar) * (maxresultsize+1));
747 uloc_getDisplayScript(testLocale, displayLocale, testScript, maxresultsize + 1, &status);
748 }
749 else
750 {
751 testScript=&_NUL;
752 }
753 if(U_FAILURE(status)){
754 log_err("Error in getDisplayScript() %s\n", myErrorName(status));
755 }
756
757 maxresultsize=0;
758 maxresultsize=uloc_getDisplayCountry(testLocale, displayLocale, NULL, maxresultsize, &status);
759 if(status==U_BUFFER_OVERFLOW_ERROR)
760 {
761 status=U_ZERO_ERROR;
762 testCtry=(UChar*)malloc(sizeof(UChar) * (maxresultsize+1));
763 uloc_getDisplayCountry(testLocale, displayLocale, testCtry, maxresultsize + 1, &status);
764 }
765 else
766 {
767 testCtry=&_NUL;
768 }
769 if(U_FAILURE(status)){
770 log_err("Error in getDisplayCountry() %s\n", myErrorName(status));
771 }
772
773 maxresultsize=0;
774 maxresultsize=uloc_getDisplayVariant(testLocale, displayLocale, NULL, maxresultsize, &status);
775 if(status==U_BUFFER_OVERFLOW_ERROR)
776 {
777 status=U_ZERO_ERROR;
778 testVar=(UChar*)malloc(sizeof(UChar) * (maxresultsize+1));
779 uloc_getDisplayVariant(testLocale, displayLocale, testVar, maxresultsize + 1, &status);
780 }
781 else
782 {
783 testVar=&_NUL;
784 }
785 if(U_FAILURE(status)){
786 log_err("Error in getDisplayVariant() %s\n", myErrorName(status));
787 }
788
789 maxresultsize=0;
790 maxresultsize=uloc_getDisplayName(testLocale, displayLocale, NULL, maxresultsize, &status);
791 if(status==U_BUFFER_OVERFLOW_ERROR)
792 {
793 status=U_ZERO_ERROR;
794 testName=(UChar*)malloc(sizeof(UChar) * (maxresultsize+1));
795 uloc_getDisplayName(testLocale, displayLocale, testName, maxresultsize + 1, &status);
796 }
797 else
798 {
799 testName=&_NUL;
800 }
801 if(U_FAILURE(status)){
802 log_err("Error in getDisplayName() %s\n", myErrorName(status));
803 }
804
805 expectedLang=dataTable[compareIndex][i];
806 if(u_strlen(expectedLang)== 0)
807 expectedLang=dataTable[DLANG_EN][i];
808
809 expectedScript=dataTable[compareIndex + 1][i];
810 if(u_strlen(expectedScript)== 0)
811 expectedScript=dataTable[DSCRIPT_EN][i];
812
813 expectedCtry=dataTable[compareIndex + 2][i];
814 if(u_strlen(expectedCtry)== 0)
815 expectedCtry=dataTable[DCTRY_EN][i];
816
817 expectedVar=dataTable[compareIndex + 3][i];
818 if(u_strlen(expectedVar)== 0)
819 expectedVar=dataTable[DVAR_EN][i];
820
821 expectedName=dataTable[compareIndex + 4][i];
822 if(u_strlen(expectedName) == 0)
823 expectedName=dataTable[DNAME_EN][i];
824
825 if (0 !=u_strcmp(testLang,expectedLang)) {
826 log_data_err(" Display Language mismatch: got %s expected %s displayLocale=%s\n", austrdup(testLang), austrdup(expectedLang), displayLocale);
827 }
828
829 if (0 != u_strcmp(testScript,expectedScript)) {
830 log_data_err(" Display Script mismatch: got %s expected %s displayLocale=%s\n", austrdup(testScript), austrdup(expectedScript), displayLocale);
831 }
832
833 if (0 != u_strcmp(testCtry,expectedCtry)) {
834 log_data_err(" Display Country mismatch: got %s expected %s displayLocale=%s\n", austrdup(testCtry), austrdup(expectedCtry), displayLocale);
835 }
836
837 if (0 != u_strcmp(testVar,expectedVar)) {
838 log_data_err(" Display Variant mismatch: got %s expected %s displayLocale=%s\n", austrdup(testVar), austrdup(expectedVar), displayLocale);
839 }
840
841 if(0 != u_strcmp(testName, expectedName)) {
842 log_data_err(" Display Name mismatch: got %s expected %s displayLocale=%s\n", austrdup(testName), austrdup(expectedName), displayLocale);
843 }
844
845 if(testName!=&_NUL) {
846 free(testName);
847 }
848 if(testLang!=&_NUL) {
849 free(testLang);
850 }
851 if(testScript!=&_NUL) {
852 free(testScript);
853 }
854 if(testCtry!=&_NUL) {
855 free(testCtry);
856 }
857 if(testVar!=&_NUL) {
858 free(testVar);
859 }
860 }
861 cleanUpDataTable();
862 }
863
864 /* test for uloc_getISOLanguages, uloc_getISOCountries */
TestISOFunctions()865 static void TestISOFunctions()
866 {
867 const char* const* str=uloc_getISOLanguages();
868 const char* const* str1=uloc_getISOCountries();
869 const char* test;
870 const char *key = NULL;
871 int32_t count = 0, skipped = 0;
872 int32_t expect;
873 UResourceBundle *res;
874 UResourceBundle *subRes;
875 UErrorCode status = U_ZERO_ERROR;
876
877 /* test getISOLanguages*/
878 /*str=uloc_getISOLanguages(); */
879 log_verbose("Testing ISO Languages: \n");
880
881 /* use structLocale - this data is no longer in root */
882 res = ures_openDirect(loadTestData(&status), "structLocale", &status);
883 subRes = ures_getByKey(res, "Languages", NULL, &status);
884 if (U_FAILURE(status)) {
885 log_err("There is an error in structLocale's ures_getByKey(\"Languages\"), status=%s\n", u_errorName(status));
886 return;
887 }
888
889 expect = ures_getSize(subRes);
890 for(count = 0; *(str+count) != 0; count++)
891 {
892 key = NULL;
893 test = *(str+count);
894 status = U_ZERO_ERROR;
895
896 do {
897 /* Skip over language tags. This API only returns language codes. */
898 skipped += (key != NULL);
899 ures_getNextString(subRes, NULL, &key, &status);
900 }
901 while (key != NULL && strchr(key, '_'));
902
903 if(key == NULL)
904 break;
905 /* TODO: Consider removing sh, which is deprecated */
906 if(strcmp(key,"root") == 0 || strcmp(key,"Fallback") == 0 || strcmp(key,"sh") == 0) {
907 ures_getNextString(subRes, NULL, &key, &status);
908 skipped++;
909 }
910 #if U_CHARSET_FAMILY==U_ASCII_FAMILY
911 /* This code only works on ASCII machines where the keys are stored in ASCII order */
912 if(strcmp(test,key)) {
913 /* The first difference usually implies the place where things get out of sync */
914 log_err("FAIL Language diff at offset %d, \"%s\" != \"%s\"\n", count, test, key);
915 }
916 #endif
917
918 if(!strcmp(test,"in"))
919 log_err("FAIL getISOLanguages() has obsolete language code %s\n", test);
920 if(!strcmp(test,"iw"))
921 log_err("FAIL getISOLanguages() has obsolete language code %s\n", test);
922 if(!strcmp(test,"ji"))
923 log_err("FAIL getISOLanguages() has obsolete language code %s\n", test);
924 if(!strcmp(test,"jw"))
925 log_err("FAIL getISOLanguages() has obsolete language code %s\n", test);
926 if(!strcmp(test,"sh"))
927 log_err("FAIL getISOLanguages() has obsolete language code %s\n", test);
928 }
929
930 expect -= skipped; /* Ignore the skipped resources from structLocale */
931
932 if(count!=expect) {
933 log_err("There is an error in getISOLanguages, got %d, expected %d (as per structLocale)\n", count, expect);
934 }
935
936 subRes = ures_getByKey(res, "Countries", subRes, &status);
937 log_verbose("Testing ISO Countries");
938 skipped = 0;
939 expect = ures_getSize(subRes) - 1; /* Skip ZZ */
940 for(count = 0; *(str1+count) != 0; count++)
941 {
942 key = NULL;
943 test = *(str1+count);
944 do {
945 /* Skip over numeric UN tags. This API only returns ISO-3166 codes. */
946 skipped += (key != NULL);
947 ures_getNextString(subRes, NULL, &key, &status);
948 }
949 while (key != NULL && strlen(key) != 2);
950
951 if(key == NULL)
952 break;
953 /* TODO: Consider removing CS, which is deprecated */
954 while(strcmp(key,"QO") == 0 || strcmp(key,"QU") == 0 || strcmp(key,"CS") == 0) {
955 ures_getNextString(subRes, NULL, &key, &status);
956 skipped++;
957 }
958 #if U_CHARSET_FAMILY==U_ASCII_FAMILY
959 /* This code only works on ASCII machines where the keys are stored in ASCII order */
960 if(strcmp(test,key)) {
961 /* The first difference usually implies the place where things get out of sync */
962 log_err("FAIL Country diff at offset %d, \"%s\" != \"%s\"\n", count, test, key);
963 }
964 #endif
965 if(!strcmp(test,"FX"))
966 log_err("FAIL getISOCountries() has obsolete country code %s\n", test);
967 if(!strcmp(test,"YU"))
968 log_err("FAIL getISOCountries() has obsolete country code %s\n", test);
969 if(!strcmp(test,"ZR"))
970 log_err("FAIL getISOCountries() has obsolete country code %s\n", test);
971 }
972
973 ures_getNextString(subRes, NULL, &key, &status);
974 if (strcmp(key, "ZZ") != 0) {
975 log_err("ZZ was expected to be the last entry in structLocale, but got %s\n", key);
976 }
977 #if U_CHARSET_FAMILY==U_EBCDIC_FAMILY
978 /* On EBCDIC machines, the numbers are sorted last. Account for those in the skipped value too. */
979 key = NULL;
980 do {
981 /* Skip over numeric UN tags. uloc_getISOCountries only returns ISO-3166 codes. */
982 skipped += (key != NULL);
983 ures_getNextString(subRes, NULL, &key, &status);
984 }
985 while (U_SUCCESS(status) && key != NULL && strlen(key) != 2);
986 #endif
987 expect -= skipped; /* Ignore the skipped resources from structLocale */
988 if(count!=expect)
989 {
990 log_err("There is an error in getISOCountries, got %d, expected %d \n", count, expect);
991 }
992 ures_close(subRes);
993 ures_close(res);
994 }
995
setUpDataTable()996 static void setUpDataTable()
997 {
998 int32_t i,j;
999 dataTable = (UChar***)(calloc(sizeof(UChar**),LOCALE_INFO_SIZE));
1000
1001 for (i = 0; i < LOCALE_INFO_SIZE; i++) {
1002 dataTable[i] = (UChar**)(calloc(sizeof(UChar*),LOCALE_SIZE));
1003 for (j = 0; j < LOCALE_SIZE; j++){
1004 dataTable[i][j] = CharsToUChars(rawData2[i][j]);
1005 }
1006 }
1007 }
1008
cleanUpDataTable()1009 static void cleanUpDataTable()
1010 {
1011 int32_t i,j;
1012 if(dataTable != NULL) {
1013 for (i=0; i<LOCALE_INFO_SIZE; i++) {
1014 for(j = 0; j < LOCALE_SIZE; j++) {
1015 free(dataTable[i][j]);
1016 }
1017 free(dataTable[i]);
1018 }
1019 free(dataTable);
1020 }
1021 dataTable = NULL;
1022 }
1023
1024 /**
1025 * @bug 4011756 4011380
1026 */
TestISO3Fallback()1027 static void TestISO3Fallback()
1028 {
1029 const char* test="xx_YY";
1030
1031 const char * result;
1032
1033 result = uloc_getISO3Language(test);
1034
1035 /* Conform to C API usage */
1036
1037 if (!result || (result[0] != 0))
1038 log_err("getISO3Language() on xx_YY returned %s instead of \"\"");
1039
1040 result = uloc_getISO3Country(test);
1041
1042 if (!result || (result[0] != 0))
1043 log_err("getISO3Country() on xx_YY returned %s instead of \"\"");
1044 }
1045
1046 /**
1047 * @bug 4118587
1048 */
TestSimpleDisplayNames()1049 static void TestSimpleDisplayNames()
1050 {
1051 /*
1052 This test is different from TestDisplayNames because TestDisplayNames checks
1053 fallback behavior, combination of language and country names to form locale
1054 names, and other stuff like that. This test just checks specific language
1055 and country codes to make sure we have the correct names for them.
1056 */
1057 char languageCodes[] [4] = { "he", "id", "iu", "ug", "yi", "za" };
1058 const char* languageNames [] = { "Hebrew", "Indonesian", "Inuktitut", "Uighur", "Yiddish",
1059 "Zhuang" };
1060 UErrorCode status=U_ZERO_ERROR;
1061
1062 int32_t i;
1063 for (i = 0; i < 6; i++) {
1064 UChar *testLang=0;
1065 UChar *expectedLang=0;
1066 int size=0;
1067 size=uloc_getDisplayLanguage(languageCodes[i], "en_US", NULL, size, &status);
1068 if(status==U_BUFFER_OVERFLOW_ERROR) {
1069 status=U_ZERO_ERROR;
1070 testLang=(UChar*)malloc(sizeof(UChar) * (size + 1));
1071 uloc_getDisplayLanguage(languageCodes[i], "en_US", testLang, size + 1, &status);
1072 }
1073 expectedLang=(UChar*)malloc(sizeof(UChar) * (strlen(languageNames[i])+1));
1074 u_uastrcpy(expectedLang, languageNames[i]);
1075 if (u_strcmp(testLang, expectedLang) != 0)
1076 log_data_err("Got wrong display name for %s : Expected \"%s\", got \"%s\".\n",
1077 languageCodes[i], languageNames[i], austrdup(testLang));
1078 free(testLang);
1079 free(expectedLang);
1080 }
1081
1082 }
1083
1084 /**
1085 * @bug 4118595
1086 */
TestUninstalledISO3Names()1087 static void TestUninstalledISO3Names()
1088 {
1089 /* This test checks to make sure getISO3Language and getISO3Country work right
1090 even for locales that are not installed. */
1091 static const char iso2Languages [][4] = { "am", "ba", "fy", "mr", "rn",
1092 "ss", "tw", "zu" };
1093 static const char iso3Languages [][5] = { "amh", "bak", "fry", "mar", "run",
1094 "ssw", "twi", "zul" };
1095 static const char iso2Countries [][6] = { "am_AF", "ba_BW", "fy_KZ", "mr_MO", "rn_MN",
1096 "ss_SB", "tw_TC", "zu_ZW" };
1097 static const char iso3Countries [][4] = { "AFG", "BWA", "KAZ", "MAC", "MNG",
1098 "SLB", "TCA", "ZWE" };
1099 int32_t i;
1100
1101 for (i = 0; i < 8; i++) {
1102 UErrorCode err = U_ZERO_ERROR;
1103 const char *test;
1104 test = uloc_getISO3Language(iso2Languages[i]);
1105 if(strcmp(test, iso3Languages[i]) !=0 || U_FAILURE(err))
1106 log_err("Got wrong ISO3 code for %s : Expected \"%s\", got \"%s\". %s\n",
1107 iso2Languages[i], iso3Languages[i], test, myErrorName(err));
1108 }
1109 for (i = 0; i < 8; i++) {
1110 UErrorCode err = U_ZERO_ERROR;
1111 const char *test;
1112 test = uloc_getISO3Country(iso2Countries[i]);
1113 if(strcmp(test, iso3Countries[i]) !=0 || U_FAILURE(err))
1114 log_err("Got wrong ISO3 code for %s : Expected \"%s\", got \"%s\". %s\n",
1115 iso2Countries[i], iso3Countries[i], test, myErrorName(err));
1116 }
1117 }
1118
1119
TestVariantParsing()1120 static void TestVariantParsing()
1121 {
1122 static const char* en_US_custom="en_US_De Anza_Cupertino_California_United States_Earth";
1123 static const char* dispName="English (United States, DE ANZA_CUPERTINO_CALIFORNIA_UNITED STATES_EARTH)";
1124 static const char* dispVar="DE ANZA_CUPERTINO_CALIFORNIA_UNITED STATES_EARTH";
1125 static const char* shortVariant="fr_FR_foo";
1126 static const char* bogusVariant="fr_FR__foo";
1127 static const char* bogusVariant2="fr_FR_foo_";
1128 static const char* bogusVariant3="fr_FR__foo_";
1129
1130
1131 UChar displayVar[100];
1132 UChar displayName[100];
1133 UErrorCode status=U_ZERO_ERROR;
1134 UChar* got=0;
1135 int32_t size=0;
1136 size=uloc_getDisplayVariant(en_US_custom, "en_US", NULL, size, &status);
1137 if(status==U_BUFFER_OVERFLOW_ERROR) {
1138 status=U_ZERO_ERROR;
1139 got=(UChar*)realloc(got, sizeof(UChar) * (size+1));
1140 uloc_getDisplayVariant(en_US_custom, "en_US", got, size + 1, &status);
1141 }
1142 else {
1143 log_err("FAIL: Didn't get U_BUFFER_OVERFLOW_ERROR\n");
1144 }
1145 u_uastrcpy(displayVar, dispVar);
1146 if(u_strcmp(got,displayVar)!=0) {
1147 log_err("FAIL: getDisplayVariant() Wanted %s, got %s\n", dispVar, austrdup(got));
1148 }
1149 size=0;
1150 size=uloc_getDisplayName(en_US_custom, "en_US", NULL, size, &status);
1151 if(status==U_BUFFER_OVERFLOW_ERROR) {
1152 status=U_ZERO_ERROR;
1153 got=(UChar*)realloc(got, sizeof(UChar) * (size+1));
1154 uloc_getDisplayName(en_US_custom, "en_US", got, size + 1, &status);
1155 }
1156 else {
1157 log_err("FAIL: Didn't get U_BUFFER_OVERFLOW_ERROR\n");
1158 }
1159 u_uastrcpy(displayName, dispName);
1160 if(u_strcmp(got,displayName)!=0) {
1161 log_err("FAIL: getDisplayName() Wanted %s, got %s\n", dispName, austrdup(got));
1162 }
1163
1164 size=0;
1165 status=U_ZERO_ERROR;
1166 size=uloc_getDisplayVariant(shortVariant, NULL, NULL, size, &status);
1167 if(status==U_BUFFER_OVERFLOW_ERROR) {
1168 status=U_ZERO_ERROR;
1169 got=(UChar*)realloc(got, sizeof(UChar) * (size+1));
1170 uloc_getDisplayVariant(shortVariant, NULL, got, size + 1, &status);
1171 }
1172 else {
1173 log_err("FAIL: Didn't get U_BUFFER_OVERFLOW_ERROR\n");
1174 }
1175 if(strcmp(austrdup(got),"FOO")!=0) {
1176 log_err("FAIL: getDisplayVariant() Wanted: foo Got: %s\n", austrdup(got));
1177 }
1178 size=0;
1179 status=U_ZERO_ERROR;
1180 size=uloc_getDisplayVariant(bogusVariant, NULL, NULL, size, &status);
1181 if(status==U_BUFFER_OVERFLOW_ERROR) {
1182 status=U_ZERO_ERROR;
1183 got=(UChar*)realloc(got, sizeof(UChar) * (size+1));
1184 uloc_getDisplayVariant(bogusVariant, NULL, got, size + 1, &status);
1185 }
1186 else {
1187 log_err("FAIL: Didn't get U_BUFFER_OVERFLOW_ERROR\n");
1188 }
1189 if(strcmp(austrdup(got),"_FOO")!=0) {
1190 log_err("FAIL: getDisplayVariant() Wanted: _FOO Got: %s\n", austrdup(got));
1191 }
1192 size=0;
1193 status=U_ZERO_ERROR;
1194 size=uloc_getDisplayVariant(bogusVariant2, NULL, NULL, size, &status);
1195 if(status==U_BUFFER_OVERFLOW_ERROR) {
1196 status=U_ZERO_ERROR;
1197 got=(UChar*)realloc(got, sizeof(UChar) * (size+1));
1198 uloc_getDisplayVariant(bogusVariant2, NULL, got, size + 1, &status);
1199 }
1200 else {
1201 log_err("FAIL: Didn't get U_BUFFER_OVERFLOW_ERROR\n");
1202 }
1203 if(strcmp(austrdup(got),"FOO_")!=0) {
1204 log_err("FAIL: getDisplayVariant() Wanted: FOO_ Got: %s\n", austrdup(got));
1205 }
1206 size=0;
1207 status=U_ZERO_ERROR;
1208 size=uloc_getDisplayVariant(bogusVariant3, NULL, NULL, size, &status);
1209 if(status==U_BUFFER_OVERFLOW_ERROR) {
1210 status=U_ZERO_ERROR;
1211 got=(UChar*)realloc(got, sizeof(UChar) * (size+1));
1212 uloc_getDisplayVariant(bogusVariant3, NULL, got, size + 1, &status);
1213 }
1214 else {
1215 log_err("FAIL: Didn't get U_BUFFER_OVERFLOW_ERROR\n");
1216 }
1217 if(strcmp(austrdup(got),"_FOO_")!=0) {
1218 log_err("FAIL: getDisplayVariant() Wanted: _FOO_ Got: %s\n", austrdup(got));
1219 }
1220 free(got);
1221 }
1222
1223
TestObsoleteNames(void)1224 static void TestObsoleteNames(void)
1225 {
1226 int32_t i;
1227 UErrorCode status = U_ZERO_ERROR;
1228 char buff[256];
1229
1230 static const struct
1231 {
1232 char locale[9];
1233 char lang3[4];
1234 char lang[4];
1235 char ctry3[4];
1236 char ctry[4];
1237 } tests[] =
1238 {
1239 { "eng_USA", "eng", "en", "USA", "US" },
1240 { "kok", "kok", "kok", "", "" },
1241 { "in", "ind", "in", "", "" },
1242 { "id", "ind", "id", "", "" }, /* NO aliasing */
1243 { "sh", "srp", "sh", "", "" },
1244 { "zz_CS", "", "zz", "SCG", "CS" },
1245 { "zz_FX", "", "zz", "FXX", "FX" },
1246 { "zz_RO", "", "zz", "ROU", "RO" },
1247 { "zz_TP", "", "zz", "TMP", "TP" },
1248 { "zz_TL", "", "zz", "TLS", "TL" },
1249 { "zz_ZR", "", "zz", "ZAR", "ZR" },
1250 { "zz_FXX", "", "zz", "FXX", "FX" }, /* no aliasing. Doesn't go to PS(PSE). */
1251 { "zz_ROM", "", "zz", "ROU", "RO" },
1252 { "zz_ROU", "", "zz", "ROU", "RO" },
1253 { "zz_ZAR", "", "zz", "ZAR", "ZR" },
1254 { "zz_TMP", "", "zz", "TMP", "TP" },
1255 { "zz_TLS", "", "zz", "TLS", "TL" },
1256 { "zz_YUG", "", "zz", "YUG", "YU" },
1257 { "mlt_PSE", "mlt", "mt", "PSE", "PS" },
1258 { "iw", "heb", "iw", "", "" },
1259 { "ji", "yid", "ji", "", "" },
1260 { "jw", "jaw", "jw", "", "" },
1261 { "sh", "srp", "sh", "", "" },
1262 { "", "", "", "", "" }
1263 };
1264
1265 for(i=0;tests[i].locale[0];i++)
1266 {
1267 const char *locale;
1268
1269 locale = tests[i].locale;
1270 log_verbose("** %s:\n", locale);
1271
1272 status = U_ZERO_ERROR;
1273 if(strcmp(tests[i].lang3,uloc_getISO3Language(locale)))
1274 {
1275 log_err("FAIL: uloc_getISO3Language(%s)==\t\"%s\",\t expected \"%s\"\n",
1276 locale, uloc_getISO3Language(locale), tests[i].lang3);
1277 }
1278 else
1279 {
1280 log_verbose(" uloc_getISO3Language()==\t\"%s\"\n",
1281 uloc_getISO3Language(locale) );
1282 }
1283
1284 status = U_ZERO_ERROR;
1285 uloc_getLanguage(locale, buff, 256, &status);
1286 if(U_FAILURE(status))
1287 {
1288 log_err("FAIL: error getting language from %s\n", locale);
1289 }
1290 else
1291 {
1292 if(strcmp(buff,tests[i].lang))
1293 {
1294 log_err("FAIL: uloc_getLanguage(%s)==\t\"%s\"\t expected \"%s\"\n",
1295 locale, buff, tests[i].lang);
1296 }
1297 else
1298 {
1299 log_verbose(" uloc_getLanguage(%s)==\t%s\n", locale, buff);
1300 }
1301 }
1302 if(strcmp(tests[i].lang3,uloc_getISO3Language(locale)))
1303 {
1304 log_err("FAIL: uloc_getISO3Language(%s)==\t\"%s\",\t expected \"%s\"\n",
1305 locale, uloc_getISO3Language(locale), tests[i].lang3);
1306 }
1307 else
1308 {
1309 log_verbose(" uloc_getISO3Language()==\t\"%s\"\n",
1310 uloc_getISO3Language(locale) );
1311 }
1312
1313 if(strcmp(tests[i].ctry3,uloc_getISO3Country(locale)))
1314 {
1315 log_err("FAIL: uloc_getISO3Country(%s)==\t\"%s\",\t expected \"%s\"\n",
1316 locale, uloc_getISO3Country(locale), tests[i].ctry3);
1317 }
1318 else
1319 {
1320 log_verbose(" uloc_getISO3Country()==\t\"%s\"\n",
1321 uloc_getISO3Country(locale) );
1322 }
1323
1324 status = U_ZERO_ERROR;
1325 uloc_getCountry(locale, buff, 256, &status);
1326 if(U_FAILURE(status))
1327 {
1328 log_err("FAIL: error getting country from %s\n", locale);
1329 }
1330 else
1331 {
1332 if(strcmp(buff,tests[i].ctry))
1333 {
1334 log_err("FAIL: uloc_getCountry(%s)==\t\"%s\"\t expected \"%s\"\n",
1335 locale, buff, tests[i].ctry);
1336 }
1337 else
1338 {
1339 log_verbose(" uloc_getCountry(%s)==\t%s\n", locale, buff);
1340 }
1341 }
1342 }
1343
1344 if (uloc_getLCID("iw_IL") != uloc_getLCID("he_IL")) {
1345 log_err("he,iw LCID mismatch: %X versus %X\n", uloc_getLCID("iw_IL"), uloc_getLCID("he_IL"));
1346 }
1347
1348 if (uloc_getLCID("iw") != uloc_getLCID("he")) {
1349 log_err("he,iw LCID mismatch: %X versus %X\n", uloc_getLCID("iw"), uloc_getLCID("he"));
1350 }
1351
1352 #if 0
1353
1354 i = uloc_getLanguage("kok",NULL,0,&icu_err);
1355 if(U_FAILURE(icu_err))
1356 {
1357 log_err("FAIL: Got %s trying to do uloc_getLanguage(kok)\n", u_errorName(icu_err));
1358 }
1359
1360 icu_err = U_ZERO_ERROR;
1361 uloc_getLanguage("kok",r1_buff,12,&icu_err);
1362 if(U_FAILURE(icu_err))
1363 {
1364 log_err("FAIL: Got %s trying to do uloc_getLanguage(kok, buff)\n", u_errorName(icu_err));
1365 }
1366
1367 r1_addr = (char *)uloc_getISO3Language("kok");
1368
1369 icu_err = U_ZERO_ERROR;
1370 if (strcmp(r1_buff,"kok") != 0)
1371 {
1372 log_err("FAIL: uloc_getLanguage(kok)==%s not kok\n",r1_buff);
1373 line--;
1374 }
1375 r1_addr = (char *)uloc_getISO3Language("in");
1376 i = uloc_getLanguage(r1_addr,r1_buff,12,&icu_err);
1377 if (strcmp(r1_buff,"id") != 0)
1378 {
1379 printf("uloc_getLanguage error (%s)\n",r1_buff);
1380 line--;
1381 }
1382 r1_addr = (char *)uloc_getISO3Language("sh");
1383 i = uloc_getLanguage(r1_addr,r1_buff,12,&icu_err);
1384 if (strcmp(r1_buff,"sr") != 0)
1385 {
1386 printf("uloc_getLanguage error (%s)\n",r1_buff);
1387 line--;
1388 }
1389
1390 r1_addr = (char *)uloc_getISO3Country("zz_ZR");
1391 strcpy(p1_buff,"zz_");
1392 strcat(p1_buff,r1_addr);
1393 i = uloc_getCountry(p1_buff,r1_buff,12,&icu_err);
1394 if (strcmp(r1_buff,"ZR") != 0)
1395 {
1396 printf("uloc_getCountry error (%s)\n",r1_buff);
1397 line--;
1398 }
1399 r1_addr = (char *)uloc_getISO3Country("zz_FX");
1400 strcpy(p1_buff,"zz_");
1401 strcat(p1_buff,r1_addr);
1402 i = uloc_getCountry(p1_buff,r1_buff,12,&icu_err);
1403 if (strcmp(r1_buff,"FX") != 0)
1404 {
1405 printf("uloc_getCountry error (%s)\n",r1_buff);
1406 line--;
1407 }
1408
1409 #endif
1410
1411 }
1412
TestKeywordVariants(void)1413 static void TestKeywordVariants(void)
1414 {
1415 static const struct {
1416 const char *localeID;
1417 const char *expectedLocaleID;
1418 const char *expectedLocaleIDNoKeywords;
1419 const char *expectedCanonicalID;
1420 const char *expectedKeywords[10];
1421 int32_t numKeywords;
1422 UErrorCode expectedStatus; /* from uloc_openKeywords */
1423 } testCases[] = {
1424 {
1425 "de_DE@ currency = euro; C o ll A t i o n = Phonebook ; C alen dar = buddhist ",
1426 "de_DE@calendar=buddhist;collation=Phonebook;currency=euro",
1427 "de_DE",
1428 "de_DE@calendar=buddhist;collation=Phonebook;currency=euro",
1429 {"calendar", "collation", "currency"},
1430 3,
1431 U_ZERO_ERROR
1432 },
1433 {
1434 "de_DE@euro",
1435 "de_DE@euro",
1436 "de_DE",
1437 "de_DE@currency=EUR",
1438 {"","","","","","",""},
1439 0,
1440 U_INVALID_FORMAT_ERROR /* must have '=' after '@' */
1441 },
1442 {
1443 "de_DE@euro;collation=phonebook",
1444 "de_DE", /* error result; bad format */
1445 "de_DE", /* error result; bad format */
1446 "de_DE", /* error result; bad format */
1447 {"","","","","","",""},
1448 0,
1449 U_INVALID_FORMAT_ERROR
1450 }
1451 };
1452 UErrorCode status = U_ZERO_ERROR;
1453
1454 int32_t i = 0, j = 0;
1455 int32_t resultLen = 0;
1456 char buffer[256];
1457 UEnumeration *keywords;
1458 int32_t keyCount = 0;
1459 const char *keyword = NULL;
1460 int32_t keywordLen = 0;
1461
1462 for(i = 0; i < sizeof(testCases)/sizeof(testCases[0]); i++) {
1463 status = U_ZERO_ERROR;
1464 *buffer = 0;
1465 keywords = uloc_openKeywords(testCases[i].localeID, &status);
1466
1467 if(status != testCases[i].expectedStatus) {
1468 log_err("Expected to uloc_openKeywords(\"%s\") => status %s. Got %s instead\n",
1469 testCases[i].localeID,
1470 u_errorName(testCases[i].expectedStatus), u_errorName(status));
1471 }
1472 status = U_ZERO_ERROR;
1473 if(keywords) {
1474 if((keyCount = uenum_count(keywords, &status)) != testCases[i].numKeywords) {
1475 log_err("Expected to get %i keywords, got %i\n", testCases[i].numKeywords, keyCount);
1476 }
1477 if(keyCount) {
1478 j = 0;
1479 while((keyword = uenum_next(keywords, &keywordLen, &status))) {
1480 if(strcmp(keyword, testCases[i].expectedKeywords[j]) != 0) {
1481 log_err("Expected to get keyword value %s, got %s\n", testCases[i].expectedKeywords[j], keyword);
1482 }
1483 j++;
1484 }
1485 j = 0;
1486 uenum_reset(keywords, &status);
1487 while((keyword = uenum_next(keywords, &keywordLen, &status))) {
1488 if(strcmp(keyword, testCases[i].expectedKeywords[j]) != 0) {
1489 log_err("Expected to get keyword value %s, got %s\n", testCases[i].expectedKeywords[j], keyword);
1490 }
1491 j++;
1492 }
1493 }
1494 uenum_close(keywords);
1495 }
1496 resultLen = uloc_getName(testCases[i].localeID, buffer, 256, &status);
1497 if (uprv_strcmp(testCases[i].expectedLocaleID, buffer) != 0) {
1498 log_err("Expected uloc_getName(\"%s\") => \"%s\"; got \"%s\"\n",
1499 testCases[i].localeID, testCases[i].expectedLocaleID, buffer);
1500 }
1501 resultLen = uloc_canonicalize(testCases[i].localeID, buffer, 256, &status);
1502 if (uprv_strcmp(testCases[i].expectedCanonicalID, buffer) != 0) {
1503 log_err("Expected uloc_canonicalize(\"%s\") => \"%s\"; got \"%s\"\n",
1504 testCases[i].localeID, testCases[i].expectedCanonicalID, buffer);
1505 }
1506 }
1507
1508 }
1509
TestKeywordVariantParsing(void)1510 static void TestKeywordVariantParsing(void)
1511 {
1512 static const struct {
1513 const char *localeID;
1514 const char *keyword;
1515 const char *expectedValue;
1516 } testCases[] = {
1517 { "de_DE@ C o ll A t i o n = Phonebook ", "c o ll a t i o n", "Phonebook" },
1518 { "de_DE", "collation", ""},
1519 { "de_DE@collation=PHONEBOOK", "collation", "PHONEBOOK" },
1520 { "de_DE@currency = euro; CoLLaTion = PHONEBOOk", "collatiON", "PHONEBOOk" },
1521 };
1522
1523 UErrorCode status = U_ZERO_ERROR;
1524
1525 int32_t i = 0;
1526 int32_t resultLen = 0;
1527 char buffer[256];
1528
1529 for(i = 0; i < sizeof(testCases)/sizeof(testCases[0]); i++) {
1530 *buffer = 0;
1531 resultLen = uloc_getKeywordValue(testCases[i].localeID, testCases[i].keyword, buffer, 256, &status);
1532 if(uprv_strcmp(testCases[i].expectedValue, buffer) != 0) {
1533 log_err("Expected to extract \"%s\" from \"%s\" for keyword \"%s\". Got \"%s\" instead\n",
1534 testCases[i].expectedValue, testCases[i].localeID, testCases[i].keyword, buffer);
1535 }
1536 }
1537 }
1538
1539 static const struct {
1540 const char *l; /* locale */
1541 const char *k; /* kw */
1542 const char *v; /* value */
1543 const char *x; /* expected */
1544 } kwSetTestCases[] = {
1545 #if 1
1546 { "en_US", "calendar", "japanese", "en_US@calendar=japanese" },
1547 { "en_US@", "calendar", "japanese", "en_US@calendar=japanese" },
1548 { "en_US@calendar=islamic", "calendar", "japanese", "en_US@calendar=japanese" },
1549 { "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 */
1550 { "en_US@calendar=gregorian", "calendar", "japanese", "en_US@calendar=japanese" },
1551 { "de", "Currency", "CHF", "de@currency=CHF" },
1552 { "de", "Currency", "CHF", "de@currency=CHF" },
1553
1554 { "en_US@collation=phonebook", "calendar", "japanese", "en_US@calendar=japanese;collation=phonebook" },
1555 { "en_US@calendar=japanese", "collation", "phonebook", "en_US@calendar=japanese;collation=phonebook" },
1556 { "de@collation=phonebook", "Currency", "CHF", "de@collation=phonebook;currency=CHF" },
1557 { "en_US@calendar=gregorian;collation=phonebook", "calendar", "japanese", "en_US@calendar=japanese;collation=phonebook" },
1558 { "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 */
1559 { "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 */
1560 { "en_US@calendar=islamic;collation=phonebook", "calendar", "japanese", "en_US@calendar=japanese;collation=phonebook" },
1561 { "de@collation=phonebook", "Currency", "CHF", "de@collation=phonebook;currency=CHF" },
1562 #endif
1563 #if 1
1564 { "mt@a=0;b=1;c=2;d=3", "c","j", "mt@a=0;b=1;c=j;d=3" },
1565 { "mt@a=0;b=1;c=2;d=3", "x","j", "mt@a=0;b=1;c=2;d=3;x=j" },
1566 { "mt@a=0;b=1;c=2;d=3", "a","f", "mt@a=f;b=1;c=2;d=3" },
1567 { "mt@a=0;aa=1;aaa=3", "a","x", "mt@a=x;aa=1;aaa=3" },
1568 { "mt@a=0;aa=1;aaa=3", "aa","x", "mt@a=0;aa=x;aaa=3" },
1569 { "mt@a=0;aa=1;aaa=3", "aaa","x", "mt@a=0;aa=1;aaa=x" },
1570 { "mt@a=0;aa=1;aaa=3", "a","yy", "mt@a=yy;aa=1;aaa=3" },
1571 { "mt@a=0;aa=1;aaa=3", "aa","yy", "mt@a=0;aa=yy;aaa=3" },
1572 { "mt@a=0;aa=1;aaa=3", "aaa","yy", "mt@a=0;aa=1;aaa=yy" },
1573 #endif
1574 #if 1
1575 /* removal tests */
1576 /* 1. removal of item at end */
1577 { "de@collation=phonebook;currency=CHF", "currency", "", "de@collation=phonebook" },
1578 { "de@collation=phonebook;currency=CHF", "currency", NULL, "de@collation=phonebook" },
1579 /* 2. removal of item at beginning */
1580 { "de@collation=phonebook;currency=CHF", "collation", "", "de@currency=CHF" },
1581 { "de@collation=phonebook;currency=CHF", "collation", NULL, "de@currency=CHF" },
1582 /* 3. removal of an item not there */
1583 { "de@collation=phonebook;currency=CHF", "calendar", NULL, "de@collation=phonebook;currency=CHF" },
1584 /* 4. removal of only item */
1585 { "de@collation=phonebook", "collation", NULL, "de" },
1586 #endif
1587 { "de@collation=phonebook", "Currency", "CHF", "de@collation=phonebook;currency=CHF" }
1588 };
1589
1590
TestKeywordSet(void)1591 static void TestKeywordSet(void)
1592 {
1593 int32_t i = 0;
1594 int32_t resultLen = 0;
1595 char buffer[1024];
1596
1597 char cbuffer[1024];
1598
1599 for(i = 0; i < sizeof(kwSetTestCases)/sizeof(kwSetTestCases[0]); i++) {
1600 UErrorCode status = U_ZERO_ERROR;
1601 memset(buffer,'%',1023);
1602 strcpy(buffer, kwSetTestCases[i].l);
1603
1604 uloc_canonicalize(kwSetTestCases[i].l, cbuffer, 1023, &status);
1605 if(strcmp(buffer,cbuffer)) {
1606 log_verbose("note: [%d] wasn't canonical, should be: '%s' not '%s'. Won't check for canonicity in output.\n", i, cbuffer, buffer);
1607 }
1608 /* sanity check test case results for canonicity */
1609 uloc_canonicalize(kwSetTestCases[i].x, cbuffer, 1023, &status);
1610 if(strcmp(kwSetTestCases[i].x,cbuffer)) {
1611 log_err("%s:%d: ERROR: kwSetTestCases[%d].x = '%s', should be %s (must be canonical)\n", __FILE__, __LINE__, i, kwSetTestCases[i].x, cbuffer);
1612 }
1613
1614 resultLen = uloc_setKeywordValue(kwSetTestCases[i].k, kwSetTestCases[i].v, buffer, 1023, &status);
1615 if(U_FAILURE(status)) {
1616 log_err("Err on test case %d: got error %s\n", i, u_errorName(status));
1617 continue;
1618 }
1619 if(strcmp(buffer,kwSetTestCases[i].x) || ((int32_t)strlen(buffer)!=resultLen)) {
1620 log_err("FAIL: #%d: %s + [%s=%s] -> %s (%d) expected %s (%d)\n", i, kwSetTestCases[i].l, kwSetTestCases[i].k,
1621 kwSetTestCases[i].v, buffer, resultLen, kwSetTestCases[i].x, strlen(buffer));
1622 } else {
1623 log_verbose("pass: #%d: %s + [%s=%s] -> %s\n", i, kwSetTestCases[i].l, kwSetTestCases[i].k, kwSetTestCases[i].v,buffer);
1624 }
1625 }
1626 }
1627
TestKeywordSetError(void)1628 static void TestKeywordSetError(void)
1629 {
1630 char buffer[1024];
1631 UErrorCode status;
1632 int32_t res;
1633 int32_t i;
1634 int32_t blen;
1635
1636 /* 0-test whether an error condition modifies the buffer at all */
1637 blen=0;
1638 i=0;
1639 memset(buffer,'%',1023);
1640 status = U_ZERO_ERROR;
1641 res = uloc_setKeywordValue(kwSetTestCases[i].k, kwSetTestCases[i].v, buffer, blen, &status);
1642 if(status != U_ILLEGAL_ARGUMENT_ERROR) {
1643 log_err("expected illegal err got %s\n", u_errorName(status));
1644 return;
1645 }
1646 /* if(res!=strlen(kwSetTestCases[i].x)) {
1647 log_err("expected result %d got %d\n", strlen(kwSetTestCases[i].x), res);
1648 return;
1649 } */
1650 if(buffer[blen]!='%') {
1651 log_err("Buffer byte %d was modified: now %c\n", blen, buffer[blen]);
1652 return;
1653 }
1654 log_verbose("0-buffer modify OK\n");
1655
1656 for(i=0;i<=2;i++) {
1657 /* 1- test a short buffer with growing text */
1658 blen=(int32_t)strlen(kwSetTestCases[i].l)+1;
1659 memset(buffer,'%',1023);
1660 strcpy(buffer,kwSetTestCases[i].l);
1661 status = U_ZERO_ERROR;
1662 res = uloc_setKeywordValue(kwSetTestCases[i].k, kwSetTestCases[i].v, buffer, blen, &status);
1663 if(status != U_BUFFER_OVERFLOW_ERROR) {
1664 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);
1665 return;
1666 }
1667 if(res!=(int32_t)strlen(kwSetTestCases[i].x)) {
1668 log_err("expected result %d got %d\n", strlen(kwSetTestCases[i].x), res);
1669 return;
1670 }
1671 if(buffer[blen]!='%') {
1672 log_err("Buffer byte %d was modified: now %c\n", blen, buffer[blen]);
1673 return;
1674 }
1675 log_verbose("1/%d-buffer modify OK\n",i);
1676 }
1677
1678 for(i=3;i<=4;i++) {
1679 /* 2- test a short buffer - text the same size or shrinking */
1680 blen=(int32_t)strlen(kwSetTestCases[i].l)+1;
1681 memset(buffer,'%',1023);
1682 strcpy(buffer,kwSetTestCases[i].l);
1683 status = U_ZERO_ERROR;
1684 res = uloc_setKeywordValue(kwSetTestCases[i].k, kwSetTestCases[i].v, buffer, blen, &status);
1685 if(status != U_ZERO_ERROR) {
1686 log_err("expected zero error got %s\n", u_errorName(status));
1687 return;
1688 }
1689 if(buffer[blen+1]!='%') {
1690 log_err("Buffer byte %d was modified: now %c\n", blen+1, buffer[blen+1]);
1691 return;
1692 }
1693 if(res!=(int32_t)strlen(kwSetTestCases[i].x)) {
1694 log_err("expected result %d got %d\n", strlen(kwSetTestCases[i].x), res);
1695 return;
1696 }
1697 if(strcmp(buffer,kwSetTestCases[i].x) || ((int32_t)strlen(buffer)!=res)) {
1698 log_err("FAIL: #%d: %s + [%s=%s] -> %s (%d) expected %s (%d)\n", i, kwSetTestCases[i].l, kwSetTestCases[i].k,
1699 kwSetTestCases[i].v, buffer, res, kwSetTestCases[i].x, strlen(buffer));
1700 } else {
1701 log_verbose("pass: #%d: %s + [%s=%s] -> %s\n", i, kwSetTestCases[i].l, kwSetTestCases[i].k, kwSetTestCases[i].v,
1702 buffer);
1703 }
1704 log_verbose("2/%d-buffer modify OK\n",i);
1705 }
1706 }
1707
_canonicalize(int32_t selector,const char * localeID,char * result,int32_t resultCapacity,UErrorCode * ec)1708 static int32_t _canonicalize(int32_t selector, /* 0==getName, 1==canonicalize */
1709 const char* localeID,
1710 char* result,
1711 int32_t resultCapacity,
1712 UErrorCode* ec) {
1713 /* YOU can change this to use function pointers if you like */
1714 switch (selector) {
1715 case 0:
1716 return uloc_getName(localeID, result, resultCapacity, ec);
1717 case 1:
1718 return uloc_canonicalize(localeID, result, resultCapacity, ec);
1719 default:
1720 return -1;
1721 }
1722 }
1723
TestCanonicalization(void)1724 static void TestCanonicalization(void)
1725 {
1726 static const struct {
1727 const char *localeID; /* input */
1728 const char *getNameID; /* expected getName() result */
1729 const char *canonicalID; /* expected canonicalize() result */
1730 } testCases[] = {
1731 { "ca_ES_PREEURO-with-extra-stuff-that really doesn't make any sense-unless-you're trying to increase code coverage",
1732 "ca_ES_PREEURO_WITH_EXTRA_STUFF_THAT REALLY DOESN'T MAKE ANY SENSE_UNLESS_YOU'RE TRYING TO INCREASE CODE COVERAGE",
1733 "ca_ES_PREEURO_WITH_EXTRA_STUFF_THAT REALLY DOESN'T MAKE ANY SENSE_UNLESS_YOU'RE TRYING TO INCREASE CODE COVERAGE"},
1734 { "ca_ES_PREEURO", "ca_ES_PREEURO", "ca_ES@currency=ESP" },
1735 { "de_AT_PREEURO", "de_AT_PREEURO", "de_AT@currency=ATS" },
1736 { "de_DE_PREEURO", "de_DE_PREEURO", "de_DE@currency=DEM" },
1737 { "de_LU_PREEURO", "de_LU_PREEURO", "de_LU@currency=LUF" },
1738 { "el_GR_PREEURO", "el_GR_PREEURO", "el_GR@currency=GRD" },
1739 { "en_BE_PREEURO", "en_BE_PREEURO", "en_BE@currency=BEF" },
1740 { "en_IE_PREEURO", "en_IE_PREEURO", "en_IE@currency=IEP" },
1741 { "es_ES_PREEURO", "es_ES_PREEURO", "es_ES@currency=ESP" },
1742 { "eu_ES_PREEURO", "eu_ES_PREEURO", "eu_ES@currency=ESP" },
1743 { "fi_FI_PREEURO", "fi_FI_PREEURO", "fi_FI@currency=FIM" },
1744 { "fr_BE_PREEURO", "fr_BE_PREEURO", "fr_BE@currency=BEF" },
1745 { "fr_FR_PREEURO", "fr_FR_PREEURO", "fr_FR@currency=FRF" },
1746 { "fr_LU_PREEURO", "fr_LU_PREEURO", "fr_LU@currency=LUF" },
1747 { "ga_IE_PREEURO", "ga_IE_PREEURO", "ga_IE@currency=IEP" },
1748 { "gl_ES_PREEURO", "gl_ES_PREEURO", "gl_ES@currency=ESP" },
1749 { "it_IT_PREEURO", "it_IT_PREEURO", "it_IT@currency=ITL" },
1750 { "nl_BE_PREEURO", "nl_BE_PREEURO", "nl_BE@currency=BEF" },
1751 { "nl_NL_PREEURO", "nl_NL_PREEURO", "nl_NL@currency=NLG" },
1752 { "pt_PT_PREEURO", "pt_PT_PREEURO", "pt_PT@currency=PTE" },
1753 { "de__PHONEBOOK", "de__PHONEBOOK", "de@collation=phonebook" },
1754 { "en_GB_EURO", "en_GB_EURO", "en_GB@currency=EUR" },
1755 { "en_GB@EURO", "en_GB@EURO", "en_GB@currency=EUR" }, /* POSIX ID */
1756 { "es__TRADITIONAL", "es__TRADITIONAL", "es@collation=traditional" },
1757 { "hi__DIRECT", "hi__DIRECT", "hi@collation=direct" },
1758 { "ja_JP_TRADITIONAL", "ja_JP_TRADITIONAL", "ja_JP@calendar=japanese" },
1759 { "th_TH_TRADITIONAL", "th_TH_TRADITIONAL", "th_TH@calendar=buddhist" },
1760 { "zh_TW_STROKE", "zh_TW_STROKE", "zh_Hant_TW@collation=stroke" },
1761 { "zh__PINYIN", "zh__PINYIN", "zh@collation=pinyin" },
1762 { "zh@collation=pinyin", "zh@collation=pinyin", "zh@collation=pinyin" },
1763 { "zh_CN@collation=pinyin", "zh_CN@collation=pinyin", "zh_CN@collation=pinyin" },
1764 { "zh_CN_CA@collation=pinyin", "zh_CN_CA@collation=pinyin", "zh_CN_CA@collation=pinyin" },
1765 { "en_US_POSIX", "en_US_POSIX", "en_US_POSIX" },
1766 { "hy_AM_REVISED", "hy_AM_REVISED", "hy_AM_REVISED" },
1767 { "no_NO_NY", "no_NO_NY", "no_NO_NY" /* not: "nn_NO" [alan ICU3.0] */ },
1768 { "no@ny", "no@ny", "no__NY" /* not: "nn" [alan ICU3.0] */ }, /* POSIX ID */
1769 { "no-no.utf32@B", "no_NO.utf32@B", "no_NO_B" /* not: "nb_NO_B" [alan ICU3.0] */ }, /* POSIX ID */
1770 { "qz-qz@Euro", "qz_QZ@Euro", "qz_QZ@currency=EUR" }, /* qz-qz uses private use iso codes */
1771 { "en-BOONT", "en_BOONT", "en__BOONT" }, /* registered name */
1772 { "de-1901", "de_1901", "de__1901" }, /* registered name */
1773 { "de-1906", "de_1906", "de__1906" }, /* registered name */
1774 { "sr-SP-Cyrl", "sr_SP_CYRL", "sr_Cyrl_CS" }, /* .NET name */
1775 { "sr-SP-Latn", "sr_SP_LATN", "sr_Latn_CS" }, /* .NET name */
1776 { "sr_YU_CYRILLIC", "sr_YU_CYRILLIC", "sr_Cyrl_CS" }, /* Linux name */
1777 { "uz-UZ-Cyrl", "uz_UZ_CYRL", "uz_Cyrl_UZ" }, /* .NET name */
1778 { "uz-UZ-Latn", "uz_UZ_LATN", "uz_Latn_UZ" }, /* .NET name */
1779 { "zh-CHS", "zh_CHS", "zh_Hans" }, /* .NET name */
1780 { "zh-CHT", "zh_CHT", "zh_Hant" }, /* .NET name This may change back to zh_Hant */
1781
1782 /* posix behavior that used to be performed by getName */
1783 { "mr.utf8", "mr.utf8", "mr" },
1784 { "de-tv.koi8r", "de_TV.koi8r", "de_TV" },
1785 { "x-piglatin_ML.MBE", "x-piglatin_ML.MBE", "x-piglatin_ML" },
1786 { "i-cherokee_US.utf7", "i-cherokee_US.utf7", "i-cherokee_US" },
1787 { "x-filfli_MT_FILFLA.gb-18030", "x-filfli_MT_FILFLA.gb-18030", "x-filfli_MT_FILFLA" },
1788 { "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 */
1789
1790 /* fleshing out canonicalization */
1791 /* trim space and sort keywords, ';' is separator so not present at end in canonical form */
1792 { "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" },
1793 /* already-canonical ids are not changed */
1794 { "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" },
1795 /* PRE_EURO and EURO conversions don't affect other keywords */
1796 { "es_ES_PREEURO@CALendar=Japanese", "es_ES_PREEURO@calendar=Japanese", "es_ES@calendar=Japanese;currency=ESP" },
1797 { "es_ES_EURO@SHOUT=zipeedeedoodah", "es_ES_EURO@shout=zipeedeedoodah", "es_ES@currency=EUR;shout=zipeedeedoodah" },
1798 /* currency keyword overrides PRE_EURO and EURO currency */
1799 { "es_ES_PREEURO@currency=EUR", "es_ES_PREEURO@currency=EUR", "es_ES@currency=EUR" },
1800 { "es_ES_EURO@currency=ESP", "es_ES_EURO@currency=ESP", "es_ES@currency=ESP" },
1801 /* norwegian is just too weird, if we handle things in their full generality */
1802 { "no-Hant-GB_NY@currency=$$$", "no_Hant_GB_NY@currency=$$$", "no_Hant_GB_NY@currency=$$$" /* not: "nn_Hant_GB@currency=$$$" [alan ICU3.0] */ },
1803
1804 /* test cases reflecting internal resource bundle usage */
1805 { "root@kw=foo", "root@kw=foo", "root@kw=foo" },
1806 { "@calendar=gregorian", "@calendar=gregorian", "@calendar=gregorian" },
1807 { "ja_JP@calendar=Japanese", "ja_JP@calendar=Japanese", "ja_JP@calendar=Japanese" },
1808 { "ja_JP", "ja_JP", "ja_JP" },
1809
1810 /* test case for "i-default" */
1811 { "i-default", NULL, NULL }
1812 };
1813
1814 static const char* label[] = { "getName", "canonicalize" };
1815
1816 UErrorCode status = U_ZERO_ERROR;
1817 int32_t i, j, resultLen = 0, origResultLen;
1818 char buffer[256];
1819
1820 for (i=0; i < sizeof(testCases)/sizeof(testCases[0]); i++) {
1821 for (j=0; j<2; ++j) {
1822 const char* expected = (j==0) ? testCases[i].getNameID : testCases[i].canonicalID;
1823 *buffer = 0;
1824 status = U_ZERO_ERROR;
1825
1826 if (expected == NULL) {
1827 expected = uloc_getDefault();
1828 }
1829
1830 /* log_verbose("testing %s -> %s\n", testCases[i], testCases[i].canonicalID); */
1831 origResultLen = _canonicalize(j, testCases[i].localeID, NULL, 0, &status);
1832 if (status != U_BUFFER_OVERFLOW_ERROR) {
1833 log_err("FAIL: uloc_%s(%s) => %s, expected U_BUFFER_OVERFLOW_ERROR\n",
1834 label[j], testCases[i].localeID, u_errorName(status));
1835 continue;
1836 }
1837 status = U_ZERO_ERROR;
1838 resultLen = _canonicalize(j, testCases[i].localeID, buffer, sizeof(buffer), &status);
1839 if (U_FAILURE(status)) {
1840 log_err("FAIL: uloc_%s(%s) => %s, expected U_ZERO_ERROR\n",
1841 label[j], testCases[i].localeID, u_errorName(status));
1842 continue;
1843 }
1844 if(uprv_strcmp(expected, buffer) != 0) {
1845 log_err("FAIL: uloc_%s(%s) => \"%s\", expected \"%s\"\n",
1846 label[j], testCases[i].localeID, buffer, expected);
1847 } else {
1848 log_verbose("Ok: uloc_%s(%s) => \"%s\"\n",
1849 label[j], testCases[i].localeID, buffer);
1850 }
1851 if (resultLen != (int32_t)strlen(buffer)) {
1852 log_err("FAIL: uloc_%s(%s) => len %d, expected len %d\n",
1853 label[j], testCases[i].localeID, resultLen, strlen(buffer));
1854 }
1855 if (origResultLen != resultLen) {
1856 log_err("FAIL: uloc_%s(%s) => preflight len %d != actual len %d\n",
1857 label[j], testCases[i].localeID, origResultLen, resultLen);
1858 }
1859 }
1860 }
1861 }
1862
TestDisplayKeywords(void)1863 static void TestDisplayKeywords(void)
1864 {
1865 int32_t i;
1866
1867 static const struct {
1868 const char *localeID;
1869 const char *displayLocale;
1870 UChar displayKeyword[200];
1871 } testCases[] = {
1872 { "ca_ES@currency=ESP", "de_AT",
1873 {0x0057, 0x00e4, 0x0068, 0x0072, 0x0075, 0x006e, 0x0067, 0x0000},
1874 },
1875 { "ja_JP@calendar=japanese", "de",
1876 { 0x004b, 0x0061, 0x006c, 0x0065, 0x006e, 0x0064, 0x0065, 0x0072, 0x0000}
1877 },
1878 { "de_DE@collation=traditional", "de_DE",
1879 {0x0053, 0x006f, 0x0072, 0x0074, 0x0069, 0x0065, 0x0072, 0x0075, 0x006e, 0x0067, 0x0000}
1880 },
1881 };
1882 for(i = 0; i < sizeof(testCases)/sizeof(testCases[0]); i++) {
1883 UErrorCode status = U_ZERO_ERROR;
1884 const char* keyword =NULL;
1885 int32_t keywordLen = 0;
1886 int32_t keywordCount = 0;
1887 UChar *displayKeyword=NULL;
1888 int32_t displayKeywordLen = 0;
1889 UEnumeration* keywordEnum = uloc_openKeywords(testCases[i].localeID, &status);
1890 for(keywordCount = uenum_count(keywordEnum, &status); keywordCount > 0 ; keywordCount--){
1891 if(U_FAILURE(status)){
1892 log_err("uloc_getKeywords failed for locale id: %s with error : %s \n", testCases[i].localeID, u_errorName(status));
1893 break;
1894 }
1895 /* the uenum_next returns NUL terminated string */
1896 keyword = uenum_next(keywordEnum, &keywordLen, &status);
1897 /* fetch the displayKeyword */
1898 displayKeywordLen = uloc_getDisplayKeyword(keyword, testCases[i].displayLocale, displayKeyword, displayKeywordLen, &status);
1899 if(status==U_BUFFER_OVERFLOW_ERROR){
1900 status = U_ZERO_ERROR;
1901 displayKeywordLen++; /* for null termination */
1902 displayKeyword = (UChar*) malloc(displayKeywordLen * U_SIZEOF_UCHAR);
1903 displayKeywordLen = uloc_getDisplayKeyword(keyword, testCases[i].displayLocale, displayKeyword, displayKeywordLen, &status);
1904 if(U_FAILURE(status)){
1905 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));
1906 break;
1907 }
1908 if(u_strncmp(displayKeyword, testCases[i].displayKeyword, displayKeywordLen)!=0){
1909 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);
1910 break;
1911 }
1912 }else{
1913 log_err("uloc_getDisplayKeyword did not return the expected error. Error: %s\n", u_errorName(status));
1914 }
1915
1916 free(displayKeyword);
1917
1918 }
1919 uenum_close(keywordEnum);
1920 }
1921 }
1922
TestDisplayKeywordValues(void)1923 static void TestDisplayKeywordValues(void){
1924 int32_t i;
1925
1926 static const struct {
1927 const char *localeID;
1928 const char *displayLocale;
1929 UChar displayKeywordValue[500];
1930 } testCases[] = {
1931 { "ca_ES@currency=ESP", "de_AT",
1932 {0x0053, 0x0070, 0x0061, 0x006e, 0x0069, 0x0073, 0x0063, 0x0068, 0x0065, 0x0020, 0x0050, 0x0065, 0x0073, 0x0065, 0x0074, 0x0065, 0x0000}
1933 },
1934 { "de_AT@currency=ATS", "fr_FR",
1935 {0x0073, 0x0063, 0x0068, 0x0069, 0x006c, 0x006c, 0x0069, 0x006e, 0x0067, 0x0020, 0x0061, 0x0075, 0x0074, 0x0072, 0x0069, 0x0063, 0x0068, 0x0069, 0x0065, 0x006e, 0x0000}
1936 },
1937 { "de_DE@currency=DEM", "it",
1938 {0x004d, 0x0061, 0x0072, 0x0063, 0x006f, 0x0020, 0x0054, 0x0065, 0x0064, 0x0065, 0x0073, 0x0063, 0x006f, 0x0000}
1939 },
1940 { "el_GR@currency=GRD", "en",
1941 {0x0047, 0x0072, 0x0065, 0x0065, 0x006b, 0x0020, 0x0044, 0x0072, 0x0061, 0x0063, 0x0068, 0x006d, 0x0061, 0x0000}
1942 },
1943 { "eu_ES@currency=ESP", "it_IT",
1944 {0x0050, 0x0065, 0x0073, 0x0065, 0x0074, 0x0061, 0x0020, 0x0053, 0x0070, 0x0061, 0x0067, 0x006e, 0x006f, 0x006c, 0x0061, 0x0000}
1945 },
1946 { "de@collation=phonebook", "es",
1947 {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}
1948 },
1949
1950 { "de_DE@collation=phonebook", "es",
1951 {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}
1952 },
1953 { "es_ES@collation=traditional","de",
1954 {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}
1955 },
1956 { "ja_JP@calendar=japanese", "de",
1957 {0x004a, 0x0061, 0x0070, 0x0061, 0x006e, 0x0069, 0x0073, 0x0063, 0x0068, 0x0065, 0x0072, 0x0020, 0x004b, 0x0061, 0x006c, 0x0065, 0x006e, 0x0064, 0x0065, 0x0072, 0x0000}
1958 },
1959 };
1960 for(i = 0; i < sizeof(testCases)/sizeof(testCases[0]); i++) {
1961 UErrorCode status = U_ZERO_ERROR;
1962 const char* keyword =NULL;
1963 int32_t keywordLen = 0;
1964 int32_t keywordCount = 0;
1965 UChar *displayKeywordValue = NULL;
1966 int32_t displayKeywordValueLen = 0;
1967 UEnumeration* keywordEnum = uloc_openKeywords(testCases[i].localeID, &status);
1968 for(keywordCount = uenum_count(keywordEnum, &status); keywordCount > 0 ; keywordCount--){
1969 if(U_FAILURE(status)){
1970 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));
1971 break;
1972 }
1973 /* the uenum_next returns NUL terminated string */
1974 keyword = uenum_next(keywordEnum, &keywordLen, &status);
1975
1976 /* fetch the displayKeywordValue */
1977 displayKeywordValueLen = uloc_getDisplayKeywordValue(testCases[i].localeID, keyword, testCases[i].displayLocale, displayKeywordValue, displayKeywordValueLen, &status);
1978 if(status==U_BUFFER_OVERFLOW_ERROR){
1979 status = U_ZERO_ERROR;
1980 displayKeywordValueLen++; /* for null termination */
1981 displayKeywordValue = (UChar*)malloc(displayKeywordValueLen * U_SIZEOF_UCHAR);
1982 displayKeywordValueLen = uloc_getDisplayKeywordValue(testCases[i].localeID, keyword, testCases[i].displayLocale, displayKeywordValue, displayKeywordValueLen, &status);
1983 if(U_FAILURE(status)){
1984 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));
1985 break;
1986 }
1987 if(u_strncmp(displayKeywordValue, testCases[i].displayKeywordValue, displayKeywordValueLen)!=0){
1988 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));
1989 break;
1990 }
1991 }else{
1992 log_err("uloc_getDisplayKeywordValue did not return the expected error. Error: %s\n", u_errorName(status));
1993 }
1994 free(displayKeywordValue);
1995 }
1996 uenum_close(keywordEnum);
1997 }
1998 {
1999 /* test a multiple keywords */
2000 UErrorCode status = U_ZERO_ERROR;
2001 const char* keyword =NULL;
2002 int32_t keywordLen = 0;
2003 int32_t keywordCount = 0;
2004 const char* localeID = "es@collation=phonebook;calendar=buddhist;currency=DEM";
2005 const char* displayLocale = "de";
2006 static const UChar expected[][50] = {
2007 {0x0042, 0x0075, 0x0064, 0x0064, 0x0068, 0x0069, 0x0073, 0x0074, 0x0069, 0x0073, 0x0063, 0x0068, 0x0065, 0x0072, 0x0020, 0x004b, 0x0061, 0x006c, 0x0065, 0x006e, 0x0064, 0x0065, 0x0072, 0x0000},
2008
2009 {0x0054, 0x0065, 0x006c, 0x0065, 0x0066, 0x006f, 0x006e, 0x0062, 0x0075, 0x0063, 0x0068, 0x002d, 0x0053, 0x006f, 0x0072, 0x0074, 0x0069, 0x0065, 0x0072, 0x0072, 0x0065, 0x0067, 0x0065, 0x006c, 0x006e, 0x0000},
2010 {0x0044, 0x0065, 0x0075, 0x0074, 0x0073, 0x0063, 0x0068, 0x0065, 0x0020, 0x004d, 0x0061, 0x0072, 0x006b, 0x0000},
2011 };
2012
2013 UEnumeration* keywordEnum = uloc_openKeywords(localeID, &status);
2014
2015 for(keywordCount = 0; keywordCount < uenum_count(keywordEnum, &status) ; keywordCount++){
2016 UChar *displayKeywordValue = NULL;
2017 int32_t displayKeywordValueLen = 0;
2018 if(U_FAILURE(status)){
2019 log_err("uloc_getKeywords failed for locale id: %s in display locale: % with error : %s \n", localeID, displayLocale, u_errorName(status));
2020 break;
2021 }
2022 /* the uenum_next returns NUL terminated string */
2023 keyword = uenum_next(keywordEnum, &keywordLen, &status);
2024
2025 /* fetch the displayKeywordValue */
2026 displayKeywordValueLen = uloc_getDisplayKeywordValue(localeID, keyword, displayLocale, displayKeywordValue, displayKeywordValueLen, &status);
2027 if(status==U_BUFFER_OVERFLOW_ERROR){
2028 status = U_ZERO_ERROR;
2029 displayKeywordValueLen++; /* for null termination */
2030 displayKeywordValue = (UChar*)malloc(displayKeywordValueLen * U_SIZEOF_UCHAR);
2031 displayKeywordValueLen = uloc_getDisplayKeywordValue(localeID, keyword, displayLocale, displayKeywordValue, displayKeywordValueLen, &status);
2032 if(U_FAILURE(status)){
2033 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));
2034 break;
2035 }
2036 if(u_strncmp(displayKeywordValue, expected[keywordCount], displayKeywordValueLen)!=0){
2037 log_err("uloc_getDisplayKeywordValue did not return the expected value keyword : %s in locale id: %s for display locale: %s \n", localeID, keyword, displayLocale);
2038 break;
2039 }
2040 }else{
2041 log_err("uloc_getDisplayKeywordValue did not return the expected error. Error: %s\n", u_errorName(status));
2042 }
2043 free(displayKeywordValue);
2044 }
2045 uenum_close(keywordEnum);
2046
2047 }
2048 {
2049 /* Test non existent keywords */
2050 UErrorCode status = U_ZERO_ERROR;
2051 const char* localeID = "es";
2052 const char* displayLocale = "de";
2053 UChar *displayKeywordValue = NULL;
2054 int32_t displayKeywordValueLen = 0;
2055
2056 /* fetch the displayKeywordValue */
2057 displayKeywordValueLen = uloc_getDisplayKeywordValue(localeID, "calendar", displayLocale, displayKeywordValue, displayKeywordValueLen, &status);
2058 if(U_FAILURE(status)) {
2059 log_err("uloc_getDisplaykeywordValue returned error status %s\n", u_errorName(status));
2060 } else if(displayKeywordValueLen != 0) {
2061 log_err("uloc_getDisplaykeywordValue returned %d should be 0 \n", displayKeywordValueLen);
2062 }
2063 }
2064 }
2065
2066
TestGetBaseName(void)2067 static void TestGetBaseName(void) {
2068 static const struct {
2069 const char *localeID;
2070 const char *baseName;
2071 } testCases[] = {
2072 { "de_DE@ C o ll A t i o n = Phonebook ", "de_DE" },
2073 { "de@currency = euro; CoLLaTion = PHONEBOOk", "de" },
2074 { "ja@calendar = buddhist", "ja" }
2075 };
2076
2077 int32_t i = 0, baseNameLen = 0;
2078 char baseName[256];
2079 UErrorCode status = U_ZERO_ERROR;
2080
2081 for(i = 0; i < sizeof(testCases)/sizeof(testCases[0]); i++) {
2082 baseNameLen = uloc_getBaseName(testCases[i].localeID, baseName, 256, &status);
2083 if(strcmp(testCases[i].baseName, baseName)) {
2084 log_err("For locale \"%s\" expected baseName \"%s\", but got \"%s\"\n",
2085 testCases[i].localeID, testCases[i].baseName, baseName);
2086 return;
2087 }
2088 }
2089
2090 }
2091
2092
2093 /* Jitterbug 4115 */
TestDisplayNameWarning(void)2094 static void TestDisplayNameWarning(void) {
2095 UChar name[256];
2096 int32_t size;
2097 UErrorCode status = U_ZERO_ERROR;
2098
2099 size = uloc_getDisplayLanguage("qqq", "kl", name, sizeof(name)/sizeof(name[0]), &status);
2100 if (status != U_USING_DEFAULT_WARNING) {
2101 log_err("For language \"qqq\" in locale \"kl\", expecting U_USING_DEFAULT_WARNING, but got %s\n",
2102 u_errorName(status));
2103 }
2104 }
2105
2106
2107 /**
2108 * Compare two locale IDs. If they are equal, return 0. If `string'
2109 * starts with `prefix' plus an additional element, that is, string ==
2110 * prefix + '_' + x, then return 1. Otherwise return a value < 0.
2111 */
_loccmp(const char * string,const char * prefix)2112 static UBool _loccmp(const char* string, const char* prefix) {
2113 int32_t slen = (int32_t)uprv_strlen(string),
2114 plen = (int32_t)uprv_strlen(prefix);
2115 int32_t c = uprv_strncmp(string, prefix, plen);
2116 /* 'root' is less than everything */
2117 if (uprv_strcmp(prefix, "root") == 0) {
2118 return (uprv_strcmp(string, "root") == 0) ? 0 : 1;
2119 }
2120 if (c) return -1; /* mismatch */
2121 if (slen == plen) return 0;
2122 if (string[plen] == '_') return 1;
2123 return -2; /* false match, e.g. "en_USX" cmp "en_US" */
2124 }
2125
_checklocs(const char * label,const char * req,const char * valid,const char * actual)2126 static void _checklocs(const char* label,
2127 const char* req,
2128 const char* valid,
2129 const char* actual) {
2130 /* We want the valid to be strictly > the bogus requested locale,
2131 and the valid to be >= the actual. */
2132 if (_loccmp(req, valid) > 0 &&
2133 _loccmp(valid, actual) >= 0) {
2134 log_verbose("%s; req=%s, valid=%s, actual=%s\n",
2135 label, req, valid, actual);
2136 } else {
2137 log_err("FAIL: %s; req=%s, valid=%s, actual=%s\n",
2138 label, req, valid, actual);
2139 }
2140 }
2141
TestGetLocale(void)2142 static void TestGetLocale(void) {
2143 UErrorCode ec = U_ZERO_ERROR;
2144 UParseError pe;
2145 UChar EMPTY[1] = {0};
2146
2147 /* === udat === */
2148 #if !UCONFIG_NO_FORMATTING
2149 {
2150 UDateFormat *obj;
2151 const char *req = "en_US_REDWOODSHORES", *valid, *actual;
2152 obj = udat_open(UDAT_DEFAULT, UDAT_DEFAULT,
2153 req,
2154 NULL, 0,
2155 NULL, 0, &ec);
2156 if (U_FAILURE(ec)) {
2157 log_err("udat_open failed.Error %s\n", u_errorName(ec));
2158 return;
2159 }
2160 valid = udat_getLocaleByType(obj, ULOC_VALID_LOCALE, &ec);
2161 actual = udat_getLocaleByType(obj, ULOC_ACTUAL_LOCALE, &ec);
2162 if (U_FAILURE(ec)) {
2163 log_err("udat_getLocaleByType() failed\n");
2164 return;
2165 }
2166 _checklocs("udat", req, valid, actual);
2167 udat_close(obj);
2168 }
2169 #endif
2170
2171 /* === ucal === */
2172 #if !UCONFIG_NO_FORMATTING
2173 {
2174 UCalendar *obj;
2175 const char *req = "fr_FR_PROVENCAL", *valid, *actual;
2176 obj = ucal_open(NULL, 0,
2177 req,
2178 UCAL_GREGORIAN,
2179 &ec);
2180 if (U_FAILURE(ec)) {
2181 log_err("ucal_open failed with error: %s\n", u_errorName(ec));
2182 return;
2183 }
2184 valid = ucal_getLocaleByType(obj, ULOC_VALID_LOCALE, &ec);
2185 actual = ucal_getLocaleByType(obj, ULOC_ACTUAL_LOCALE, &ec);
2186 if (U_FAILURE(ec)) {
2187 log_err("ucal_getLocaleByType() failed\n");
2188 return;
2189 }
2190 _checklocs("ucal", req, valid, actual);
2191 ucal_close(obj);
2192 }
2193 #endif
2194
2195 /* === unum === */
2196 #if !UCONFIG_NO_FORMATTING
2197 {
2198 UNumberFormat *obj;
2199 const char *req = "zh_Hant_TW_TAINAN", *valid, *actual;
2200 obj = unum_open(UNUM_DECIMAL,
2201 NULL, 0,
2202 req,
2203 &pe, &ec);
2204 if (U_FAILURE(ec)) {
2205 log_err("unum_open failed\n");
2206 return;
2207 }
2208 valid = unum_getLocaleByType(obj, ULOC_VALID_LOCALE, &ec);
2209 actual = unum_getLocaleByType(obj, ULOC_ACTUAL_LOCALE, &ec);
2210 if (U_FAILURE(ec)) {
2211 log_err("unum_getLocaleByType() failed\n");
2212 return;
2213 }
2214 _checklocs("unum", req, valid, actual);
2215 unum_close(obj);
2216 }
2217 #endif
2218
2219 /* === umsg === */
2220 #if 0
2221 /* commented out by weiv 01/12/2005. umsg_getLocaleByType is to be removed */
2222 #if !UCONFIG_NO_FORMATTING
2223 {
2224 UMessageFormat *obj;
2225 const char *req = "ja_JP_TAKAYAMA", *valid, *actual;
2226 UBool test;
2227 obj = umsg_open(EMPTY, 0,
2228 req,
2229 &pe, &ec);
2230 if (U_FAILURE(ec)) {
2231 log_err("umsg_open failed\n");
2232 return;
2233 }
2234 valid = umsg_getLocaleByType(obj, ULOC_VALID_LOCALE, &ec);
2235 actual = umsg_getLocaleByType(obj, ULOC_ACTUAL_LOCALE, &ec);
2236 if (U_FAILURE(ec)) {
2237 log_err("umsg_getLocaleByType() failed\n");
2238 return;
2239 }
2240 /* We want the valid to be strictly > the bogus requested locale,
2241 and the valid to be >= the actual. */
2242 /* TODO MessageFormat is currently just storing the locale it is given.
2243 As a result, it will return whatever it was given, even if the
2244 locale is invalid. */
2245 test = (_cmpversion("3.2") <= 0) ?
2246 /* Here is the weakened test for 3.0: */
2247 (_loccmp(req, valid) >= 0) :
2248 /* Here is what the test line SHOULD be: */
2249 (_loccmp(req, valid) > 0);
2250
2251 if (test &&
2252 _loccmp(valid, actual) >= 0) {
2253 log_verbose("umsg; req=%s, valid=%s, actual=%s\n", req, valid, actual);
2254 } else {
2255 log_err("FAIL: umsg; req=%s, valid=%s, actual=%s\n", req, valid, actual);
2256 }
2257 umsg_close(obj);
2258 }
2259 #endif
2260 #endif
2261
2262 /* === ubrk === */
2263 #if !UCONFIG_NO_BREAK_ITERATION
2264 {
2265 UBreakIterator *obj;
2266 const char *req = "ar_KW_ABDALI", *valid, *actual;
2267 obj = ubrk_open(UBRK_WORD,
2268 req,
2269 EMPTY,
2270 0,
2271 &ec);
2272 if (U_FAILURE(ec)) {
2273 log_err("ubrk_open failed. Error: %s \n", u_errorName(ec));
2274 return;
2275 }
2276 valid = ubrk_getLocaleByType(obj, ULOC_VALID_LOCALE, &ec);
2277 actual = ubrk_getLocaleByType(obj, ULOC_ACTUAL_LOCALE, &ec);
2278 if (U_FAILURE(ec)) {
2279 log_err("ubrk_getLocaleByType() failed\n");
2280 return;
2281 }
2282 _checklocs("ubrk", req, valid, actual);
2283 ubrk_close(obj);
2284 }
2285 #endif
2286
2287 /* === ucol === */
2288 #if !UCONFIG_NO_COLLATION
2289 {
2290 UCollator *obj;
2291 const char *req = "es_AR_BUENOSAIRES", *valid, *actual;
2292 obj = ucol_open(req, &ec);
2293 if (U_FAILURE(ec)) {
2294 log_err("ucol_open failed\n");
2295 return;
2296 }
2297 valid = ucol_getLocaleByType(obj, ULOC_VALID_LOCALE, &ec);
2298 actual = ucol_getLocaleByType(obj, ULOC_ACTUAL_LOCALE, &ec);
2299 if (U_FAILURE(ec)) {
2300 log_err("ucol_getLocaleByType() failed\n");
2301 return;
2302 }
2303 _checklocs("ucol", req, valid, actual);
2304 ucol_close(obj);
2305 }
2306 #endif
2307 }
2308
TestNonexistentLanguageExemplars(void)2309 static void TestNonexistentLanguageExemplars(void) {
2310 /* JB 4068 - Nonexistent language */
2311 UErrorCode ec = U_ZERO_ERROR;
2312 ULocaleData *uld = ulocdata_open("qqq",&ec);
2313 if (ec != U_USING_DEFAULT_WARNING) {
2314 log_err("Exemplar set for \"qqq\", expecting U_USING_DEFAULT_WARNING, but got %s\n",
2315 u_errorName(ec));
2316 }
2317 uset_close(ulocdata_getExemplarSet(uld, NULL, 0, ULOCDATA_ES_STANDARD, &ec));
2318 ulocdata_close(uld);
2319 }
2320
TestLocDataErrorCodeChaining(void)2321 static void TestLocDataErrorCodeChaining(void) {
2322 UErrorCode ec = U_USELESS_COLLATOR_ERROR;
2323 ulocdata_open(NULL, &ec);
2324 ulocdata_getExemplarSet(NULL, NULL, 0, ULOCDATA_ES_STANDARD, &ec);
2325 ulocdata_getDelimiter(NULL, ULOCDATA_DELIMITER_COUNT, NULL, -1, &ec);
2326 ulocdata_getMeasurementSystem(NULL, &ec);
2327 ulocdata_getPaperSize(NULL, NULL, NULL, &ec);
2328 if (ec != U_USELESS_COLLATOR_ERROR) {
2329 log_err("ulocdata API changed the error code to %s\n", u_errorName(ec));
2330 }
2331 }
2332
TestLanguageExemplarsFallbacks(void)2333 static void TestLanguageExemplarsFallbacks(void) {
2334 /* Test that en_US fallsback, but en doesn't fallback. */
2335 UErrorCode ec = U_ZERO_ERROR;
2336 ULocaleData *uld = ulocdata_open("en_US",&ec);
2337 uset_close(ulocdata_getExemplarSet(uld, NULL, 0, ULOCDATA_ES_STANDARD, &ec));
2338 if (ec != U_USING_FALLBACK_WARNING) {
2339 log_err("Exemplar set for \"en_US\", expecting U_USING_FALLBACK_WARNING, but got %s\n",
2340 u_errorName(ec));
2341 }
2342 ulocdata_close(uld);
2343 ec = U_ZERO_ERROR;
2344 uld = ulocdata_open("en",&ec);
2345 uset_close(ulocdata_getExemplarSet(uld, NULL, 0, ULOCDATA_ES_STANDARD, &ec));
2346 if (ec != U_ZERO_ERROR) {
2347 log_err("Exemplar set for \"en\", expecting U_ZERO_ERROR, but got %s\n",
2348 u_errorName(ec));
2349 }
2350 ulocdata_close(uld);
2351 }
2352
TestAcceptLanguage(void)2353 static void TestAcceptLanguage(void) {
2354 UErrorCode status = U_ZERO_ERROR;
2355 UAcceptResult outResult;
2356 UEnumeration *available;
2357 char tmp[200];
2358 int i;
2359 int32_t rc = 0;
2360
2361 struct {
2362 int32_t httpSet;
2363 const char *icuSet;
2364 const char *expect;
2365 UAcceptResult res;
2366 } tests[] = {
2367 /*0*/{ 0, NULL, "mt_MT", ULOC_ACCEPT_VALID },
2368 /*1*/{ 1, NULL, "en", ULOC_ACCEPT_VALID },
2369 /*2*/{ 2, NULL, "en", ULOC_ACCEPT_FALLBACK },
2370 /*3*/{ 3, NULL, "", ULOC_ACCEPT_FAILED },
2371 /*4*/{ 4, NULL, "es", ULOC_ACCEPT_VALID },
2372 };
2373 const int32_t numTests = sizeof(tests)/sizeof(tests[0]);
2374 static const char *http[] = {
2375 /*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",
2376 /*1*/ "ja;q=0.5, en;q=0.8, tlh",
2377 /*2*/ "en-wf, de-lx;q=0.8",
2378 /*3*/ "mga-ie;q=0.9, tlh",
2379 /*4*/ "xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, "
2380 "xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, "
2381 "xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, "
2382 "xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, "
2383 "xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, "
2384 "xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, "
2385 "xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, xx-yy;q=.1, "
2386 "es"
2387 };
2388
2389 for(i=0;i<numTests;i++) {
2390 outResult = -3;
2391 status=U_ZERO_ERROR;
2392 log_verbose("test #%d: http[%s], ICU[%s], expect %s, %d\n",
2393 i, http[tests[i].httpSet], tests[i].icuSet, tests[i].expect, tests[i].res);
2394
2395 available = ures_openAvailableLocales(tests[i].icuSet, &status);
2396 tmp[0]=0;
2397 rc = uloc_acceptLanguageFromHTTP(tmp, 199, &outResult, http[tests[i].httpSet], available, &status);
2398 uenum_close(available);
2399 log_verbose(" got %s, %d [%s]\n", tmp[0]?tmp:"(EMPTY)", outResult, u_errorName(status));
2400 if(outResult != tests[i].res) {
2401 log_err("FAIL: #%d: expected outResult of %d but got %d\n", i, tests[i].res, outResult);
2402 log_info("test #%d: http[%s], ICU[%s], expect %s, %d\n",
2403 i, http[tests[i].httpSet], tests[i].icuSet, tests[i].expect, tests[i].res);
2404 }
2405 if((outResult>0)&&uprv_strcmp(tmp, tests[i].expect)) {
2406 log_err("FAIL: #%d: expected %s but got %s\n", i, tests[i].expect, tmp);
2407 log_info("test #%d: http[%s], ICU[%s], expect %s, %d\n",
2408 i, http[tests[i].httpSet], tests[i].icuSet, tests[i].expect, tests[i].res);
2409 }
2410 }
2411 }
2412
2413 static const char* LOCALE_ALIAS[][2] = {
2414 {"in", "id"},
2415 {"in_ID", "id_ID"},
2416 {"iw", "he"},
2417 {"iw_IL", "he_IL"},
2418 {"ji", "yi"},
2419 {"en_BU", "en_MM"},
2420 {"en_DY", "en_BJ"},
2421 {"en_HV", "en_BF"},
2422 {"en_NH", "en_VU"},
2423 {"en_RH", "en_ZW"},
2424 {"en_TP", "en_TL"},
2425 {"en_ZR", "en_CD"}
2426 };
isLocaleAvailable(UResourceBundle * resIndex,const char * loc)2427 static UBool isLocaleAvailable(UResourceBundle* resIndex, const char* loc){
2428 UErrorCode status = U_ZERO_ERROR;
2429 int32_t len = 0;
2430 ures_getStringByKey(resIndex, loc,&len, &status);
2431 if(U_FAILURE(status)){
2432 return FALSE;
2433 }
2434 return TRUE;
2435 }
2436
TestCalendar()2437 static void TestCalendar() {
2438 #if !UCONFIG_NO_FORMATTING
2439 int i;
2440 UErrorCode status = U_ZERO_ERROR;
2441 UResourceBundle *resIndex = ures_open(NULL,"res_index", &status);
2442 if(U_FAILURE(status)){
2443 log_err("Could not open res_index.res. Exiting. Error: %s\n", u_errorName(status));
2444 return;
2445 }
2446 for (i=0; i<LENGTHOF(LOCALE_ALIAS); i++) {
2447 const char* oldLoc = LOCALE_ALIAS[i][0];
2448 const char* newLoc = LOCALE_ALIAS[i][1];
2449 UCalendar* c1 = NULL;
2450 UCalendar* c2 = NULL;
2451
2452 /*Test function "getLocale(ULocale.VALID_LOCALE)"*/
2453 const char* l1 = ucal_getLocaleByType(c1, ULOC_VALID_LOCALE, &status);
2454 const char* l2 = ucal_getLocaleByType(c2, ULOC_VALID_LOCALE, &status);
2455
2456 if(!isLocaleAvailable(resIndex, newLoc)){
2457 continue;
2458 }
2459 c1 = ucal_open(NULL, -1, oldLoc, UCAL_GREGORIAN, &status);
2460 c2 = ucal_open(NULL, -1, newLoc, UCAL_GREGORIAN, &status);
2461
2462 if (strcmp(newLoc,l1)!=0 || strcmp(l1,l2)!=0 || status!=U_ZERO_ERROR) {
2463 log_err("The locales are not equal!.Old: %s, New: %s \n", oldLoc, newLoc);
2464 }
2465 log_verbose("ucal_getLocaleByType old:%s new:%s\n", l1, l2);
2466 ucal_close(c1);
2467 ucal_close(c2);
2468 }
2469 ures_close(resIndex);
2470 #endif
2471 }
2472
TestDateFormat()2473 static void TestDateFormat() {
2474 #if !UCONFIG_NO_FORMATTING
2475 int i;
2476 UErrorCode status = U_ZERO_ERROR;
2477 UResourceBundle *resIndex = ures_open(NULL,"res_index", &status);
2478 if(U_FAILURE(status)){
2479 log_err("Could not open res_index.res. Exiting. Error: %s\n", u_errorName(status));
2480 return;
2481 }
2482 for (i=0; i<LENGTHOF(LOCALE_ALIAS); i++) {
2483 const char* oldLoc = LOCALE_ALIAS[i][0];
2484 const char* newLoc = LOCALE_ALIAS[i][1];
2485 UDateFormat* df1 = NULL;
2486 UDateFormat* df2 = NULL;
2487 const char* l1 = NULL;
2488 const char* l2 = NULL;
2489
2490 if(!isLocaleAvailable(resIndex, newLoc)){
2491 continue;
2492 }
2493 df1 = udat_open(UDAT_FULL, UDAT_FULL,oldLoc, NULL, 0, NULL, -1, &status);
2494 df2 = udat_open(UDAT_FULL, UDAT_FULL,newLoc, NULL, 0, NULL, -1, &status);
2495 if(U_FAILURE(status)){
2496 log_err("Creation of date format failed %s\n", u_errorName(status));
2497 return;
2498 }
2499 /*Test function "getLocale"*/
2500 l1 = udat_getLocaleByType(df1, ULOC_VALID_LOCALE, &status);
2501 l2 = udat_getLocaleByType(df2, ULOC_VALID_LOCALE, &status);
2502 if(U_FAILURE(status)){
2503 log_err("Fetching the locale by type failed. %s\n", u_errorName(status));
2504 }
2505 if (strcmp(newLoc,l1)!=0 || strcmp(l1,l2)!=0) {
2506 log_err("The locales are not equal!.Old: %s, New: %s \n", oldLoc, newLoc);
2507 }
2508 log_verbose("udat_getLocaleByType old:%s new:%s\n", l1, l2);
2509 udat_close(df1);
2510 udat_close(df2);
2511 }
2512 ures_close(resIndex);
2513 #endif
2514 }
2515
TestCollation()2516 static void TestCollation() {
2517 #if !UCONFIG_NO_COLLATION
2518 int i;
2519 UErrorCode status = U_ZERO_ERROR;
2520 UResourceBundle *resIndex = ures_open(NULL,"res_index", &status);
2521 if(U_FAILURE(status)){
2522 log_err("Could not open res_index.res. Exiting. Error: %s\n", u_errorName(status));
2523 return;
2524 }
2525 for (i=0; i<LENGTHOF(LOCALE_ALIAS); i++) {
2526 const char* oldLoc = LOCALE_ALIAS[i][0];
2527 const char* newLoc = LOCALE_ALIAS[i][1];
2528 UCollator* c1 = NULL;
2529 UCollator* c2 = NULL;
2530 const char* l1 = NULL;
2531 const char* l2 = NULL;
2532
2533 status = U_ZERO_ERROR;
2534 if(!isLocaleAvailable(resIndex, newLoc)){
2535 continue;
2536 }
2537 if(U_FAILURE(status)){
2538 log_err("Creation of collators failed %s\n", u_errorName(status));
2539 return;
2540 }
2541 c1 = ucol_open(oldLoc, &status);
2542 c2 = ucol_open(newLoc, &status);
2543 l1 = ucol_getLocaleByType(c1, ULOC_VALID_LOCALE, &status);
2544 l2 = ucol_getLocaleByType(c2, ULOC_VALID_LOCALE, &status);
2545 if(U_FAILURE(status)){
2546 log_err("Fetching the locale names failed failed %s\n", u_errorName(status));
2547 }
2548 if (strcmp(newLoc,l1)!=0 || strcmp(l1,l2)!=0) {
2549 log_err("The locales are not equal!.Old: %s, New: %s \n", oldLoc, newLoc);
2550 }
2551 log_verbose("ucol_getLocaleByType old:%s new:%s\n", l1, l2);
2552 ucol_close(c1);
2553 ucol_close(c2);
2554 }
2555 ures_close(resIndex);
2556 #endif
2557 }
2558
TestULocale()2559 static void TestULocale() {
2560 int i;
2561 UErrorCode status = U_ZERO_ERROR;
2562 UResourceBundle *resIndex = ures_open(NULL,"res_index", &status);
2563 if(U_FAILURE(status)){
2564 log_err("Could not open res_index.res. Exiting. Error: %s\n", u_errorName(status));
2565 return;
2566 }
2567 for (i=0; i<LENGTHOF(LOCALE_ALIAS); i++) {
2568 const char* oldLoc = LOCALE_ALIAS[i][0];
2569 const char* newLoc = LOCALE_ALIAS[i][1];
2570 UChar name1[256], name2[256];
2571 char names1[256], names2[256];
2572 int32_t capacity = 256;
2573
2574 status = U_ZERO_ERROR;
2575 if(!isLocaleAvailable(resIndex, newLoc)){
2576 continue;
2577 }
2578 uloc_getDisplayName(oldLoc, ULOC_US, name1, capacity, &status);
2579 if(U_FAILURE(status)){
2580 log_err("uloc_getDisplayName(%s) failed %s\n", oldLoc, u_errorName(status));
2581 }
2582
2583 uloc_getDisplayName(newLoc, ULOC_US, name2, capacity, &status);
2584 if(U_FAILURE(status)){
2585 log_err("uloc_getDisplayName(%s) failed %s\n", newLoc, u_errorName(status));
2586 }
2587
2588 if (u_strcmp(name1, name2)!=0) {
2589 log_err("The locales are not equal!.Old: %s, New: %s \n", oldLoc, newLoc);
2590 }
2591 u_austrcpy(names1, name1);
2592 u_austrcpy(names2, name2);
2593 log_verbose("uloc_getDisplayName old:%s new:%s\n", names1, names2);
2594 }
2595 ures_close(resIndex);
2596
2597 }
2598
TestUResourceBundle()2599 static void TestUResourceBundle() {
2600 const char* us1;
2601 const char* us2;
2602
2603 UResourceBundle* rb1 = NULL;
2604 UResourceBundle* rb2 = NULL;
2605 UErrorCode status = U_ZERO_ERROR;
2606 int i;
2607 UResourceBundle *resIndex = NULL;
2608 if(U_FAILURE(status)){
2609 log_err("Could not open res_index.res. Exiting. Error: %s\n", u_errorName(status));
2610 return;
2611 }
2612 resIndex = ures_open(NULL,"res_index", &status);
2613 for (i=0; i<LENGTHOF(LOCALE_ALIAS); i++) {
2614
2615 const char* oldLoc = LOCALE_ALIAS[i][0];
2616 const char* newLoc = LOCALE_ALIAS[i][1];
2617 if(!isLocaleAvailable(resIndex, newLoc)){
2618 continue;
2619 }
2620 rb1 = ures_open(NULL, oldLoc, &status);
2621 if (U_FAILURE(status)) {
2622 log_err("ures_open(%s) failed %s\n", oldLoc, u_errorName(status));
2623 }
2624
2625 us1 = ures_getLocale(rb1, &status);
2626
2627 status = U_ZERO_ERROR;
2628 rb2 = ures_open(NULL, newLoc, &status);
2629 if (U_FAILURE(status)) {
2630 log_err("ures_open(%s) failed %s\n", oldLoc, u_errorName(status));
2631 }
2632 us2 = ures_getLocale(rb2, &status);
2633
2634 if (strcmp(us1,newLoc)!=0 || strcmp(us1,us2)!=0 ) {
2635 log_err("The locales are not equal!.Old: %s, New: %s \n", oldLoc, newLoc);
2636 }
2637
2638 log_verbose("ures_getStringByKey old:%s new:%s\n", us1, us2);
2639 ures_close(rb1);
2640 rb1 = NULL;
2641 ures_close(rb2);
2642 rb2 = NULL;
2643 }
2644 ures_close(resIndex);
2645 }
2646
TestDisplayName()2647 static void TestDisplayName() {
2648
2649 UChar oldCountry[256] = {'\0'};
2650 UChar newCountry[256] = {'\0'};
2651 UChar oldLang[256] = {'\0'};
2652 UChar newLang[256] = {'\0'};
2653 char country[256] ={'\0'};
2654 char language[256] ={'\0'};
2655 int32_t capacity = 256;
2656 int i =0;
2657 int j=0;
2658 for (i=0; i<LENGTHOF(LOCALE_ALIAS); i++) {
2659 const char* oldLoc = LOCALE_ALIAS[i][0];
2660 const char* newLoc = LOCALE_ALIAS[i][1];
2661 UErrorCode status = U_ZERO_ERROR;
2662 int32_t available = uloc_countAvailable();
2663
2664 for(j=0; j<available; j++){
2665
2666 const char* dispLoc = uloc_getAvailable(j);
2667 int32_t oldCountryLen = uloc_getDisplayCountry(oldLoc,dispLoc, oldCountry, capacity, &status);
2668 int32_t newCountryLen = uloc_getDisplayCountry(newLoc, dispLoc, newCountry, capacity, &status);
2669 int32_t oldLangLen = uloc_getDisplayLanguage(oldLoc, dispLoc, oldLang, capacity, &status);
2670 int32_t newLangLen = uloc_getDisplayLanguage(newLoc, dispLoc, newLang, capacity, &status );
2671
2672 int32_t countryLen = uloc_getCountry(newLoc, country, capacity, &status);
2673 int32_t langLen = uloc_getLanguage(newLoc, language, capacity, &status);
2674 /* there is a display name for the current country ID */
2675 if(countryLen != newCountryLen ){
2676 if(u_strncmp(oldCountry,newCountry,oldCountryLen)!=0){
2677 log_err("uloc_getDisplayCountry() failed for %s in display locale %s \n", oldLoc, dispLoc);
2678 }
2679 }
2680 /* there is a display name for the current lang ID */
2681 if(langLen!=newLangLen){
2682 if(u_strncmp(oldLang,newLang,oldLangLen)){
2683 log_err("uloc_getDisplayLanguage() failed for %s in display locale %s \n", oldLoc, dispLoc); }
2684 }
2685 }
2686 }
2687 }
2688
TestGetLocaleForLCID()2689 static void TestGetLocaleForLCID() {
2690 int32_t i, length, lengthPre;
2691 const char* testLocale = 0;
2692 UErrorCode status = U_ZERO_ERROR;
2693 char temp2[40], temp3[40];
2694 uint32_t lcid;
2695
2696 lcid = uloc_getLCID("en_US");
2697 if (lcid != 0x0409) {
2698 log_err(" uloc_getLCID(\"en_US\") = %d, expected 0x0409\n", lcid);
2699 }
2700
2701 lengthPre = uloc_getLocaleForLCID(lcid, temp2, 4, &status);
2702 if (status != U_BUFFER_OVERFLOW_ERROR) {
2703 log_err(" unexpected result from uloc_getLocaleForLCID with small buffer: %s\n", u_errorName(status));
2704 }
2705 else {
2706 status = U_ZERO_ERROR;
2707 }
2708
2709 length = uloc_getLocaleForLCID(lcid, temp2, sizeof(temp2)/sizeof(char), &status);
2710 if (U_FAILURE(status)) {
2711 log_err(" unexpected result from uloc_getLocaleForLCID(0x0409): %s\n", u_errorName(status));
2712 status = U_ZERO_ERROR;
2713 }
2714
2715 if (length != lengthPre) {
2716 log_err(" uloc_getLocaleForLCID(0x0409): returned length %d does not match preflight length %d\n", length, lengthPre);
2717 }
2718
2719 length = uloc_getLocaleForLCID(0x12345, temp2, sizeof(temp2)/sizeof(char), &status);
2720 if (U_SUCCESS(status)) {
2721 log_err(" unexpected result from uloc_getLocaleForLCID(0x12345): %s, status %s\n", temp2, u_errorName(status));
2722 }
2723 status = U_ZERO_ERROR;
2724
2725 log_verbose("Testing getLocaleForLCID vs. locale data\n");
2726 for (i = 0; i < LOCALE_SIZE; i++) {
2727
2728 testLocale=rawData2[NAME][i];
2729
2730 log_verbose("Testing %s ......\n", testLocale);
2731
2732 sscanf(rawData2[LCID][i], "%x", &lcid);
2733 length = uloc_getLocaleForLCID(lcid, temp2, sizeof(temp2)/sizeof(char), &status);
2734 if (U_FAILURE(status)) {
2735 log_err(" unexpected failure of uloc_getLocaleForLCID(%#04x), status %s\n", lcid, u_errorName(status));
2736 status = U_ZERO_ERROR;
2737 continue;
2738 }
2739
2740 if (length != uprv_strlen(temp2)) {
2741 log_err(" returned length %d not correct for uloc_getLocaleForLCID(%#04x), expected %d\n", length, lcid, uprv_strlen(temp2));
2742 }
2743
2744 /* Compare language, country, script */
2745 length = uloc_getLanguage(temp2, temp3, sizeof(temp3)/sizeof(char), &status);
2746 if (U_FAILURE(status)) {
2747 log_err(" couldn't get language in uloc_getLocaleForLCID(%#04x) = %s, status %s\n", lcid, temp2, u_errorName(status));
2748 status = U_ZERO_ERROR;
2749 }
2750 else if (uprv_strcmp(temp3, rawData2[LANG][i]) && !(uprv_strcmp(temp3, "nn") == 0 && uprv_strcmp(rawData2[VAR][i], "NY") == 0)) {
2751 log_err(" language doesn't match expected %s in in uloc_getLocaleForLCID(%#04x) = %s\n", rawData2[LANG][i], lcid, temp2);
2752 }
2753
2754 length = uloc_getScript(temp2, temp3, sizeof(temp3)/sizeof(char), &status);
2755 if (U_FAILURE(status)) {
2756 log_err(" couldn't get script in uloc_getLocaleForLCID(%#04x) = %s, status %s\n", lcid, temp2, u_errorName(status));
2757 status = U_ZERO_ERROR;
2758 }
2759 else if (uprv_strcmp(temp3, rawData2[SCRIPT][i])) {
2760 log_err(" script doesn't match expected %s in in uloc_getLocaleForLCID(%#04x) = %s\n", rawData2[SCRIPT][i], lcid, temp2);
2761 }
2762
2763 length = uloc_getCountry(temp2, temp3, sizeof(temp3)/sizeof(char), &status);
2764 if (U_FAILURE(status)) {
2765 log_err(" couldn't get country in uloc_getLocaleForLCID(%#04x) = %s, status %s\n", lcid, temp2, u_errorName(status));
2766 status = U_ZERO_ERROR;
2767 }
2768 else if (uprv_strlen(rawData2[CTRY][i]) && uprv_strcmp(temp3, rawData2[CTRY][i])) {
2769 log_err(" country doesn't match expected %s in in uloc_getLocaleForLCID(%#04x) = %s\n", rawData2[CTRY][i], lcid, temp2);
2770 }
2771 }
2772
2773 }
2774
2775