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