1 /********************************************************************
3 * Copyright (c) 1997-2004, International Business Machines Corporation and
4 * others. All Rights Reserved.
5 ********************************************************************/
6 /********************************************************************************
10 * Modification History:
12 * Madhu Katragadda Ported for C API
13 *********************************************************************************
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]))
37 static void TestNullDefault(void);
38 static void TestNonexistentLanguageExemplars(void);
39 void PrintDataTable();
41 /*---------------------------------------------------
43 --------------------------------------------------- */
45 #define LOCALE_INFO_SIZE 28
47 static const char* rawData2
[LOCALE_INFO_SIZE
][LOCALE_SIZE
] = {
49 { "en", "fr", "ca", "el", "no", "zh", "de", "es", "ja" },
51 { "", "", "", "", "", "Hans", "", "", "" },
53 { "US", "FR", "ES", "GR", "NO", "CN", "DE", "", "JP" },
55 { "", "", "", "", "NY", "", "", "", "" },
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" },
61 { "eng", "fra", "cat", "ell", "nor", "zho", "deu", "spa", "jpn" },
63 { "USA", "FRA", "ESP", "GRC", "NOR", "CHN", "DEU", "", "JPN" },
65 { "409", "40c", "403", "408", "814", "804", "407", "a", "411" },
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)" },
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)" },
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)" },
106 /* display language (Greek) */
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"
118 /* display script code (Greek) */
119 { "", "", "", "", "", "Hans", "", "", "" },
120 /* display country (Greek) */
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",
130 "\\u0399\\u03B1\\u03C0\\u03C9\\u03BD\\u03AF\\u03B1"
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) */
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)"
148 static UChar
*** dataTable
=0;
188 #define TESTCASE(name) addTest(root, &name, "tsutil/cloctst/" #name)
190 void addLocaleTest(TestNode
** root
);
192 void addLocaleTest(TestNode
** root
)
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
);
223 /* testing uloc(), uloc_getName(), uloc_getLanguage(), uloc_getVariant(), uloc_getCountry() */
224 static void TestBasicGetters() {
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
]);
235 log_verbose("Testing %s .....\n", testLocale
);
236 cap
=uloc_getLanguage(testLocale
, NULL
, 0, &status
);
237 if(status
==U_BUFFER_OVERFLOW_ERROR
){
239 temp
=(char*)malloc(sizeof(char) * (cap
+1));
240 uloc_getLanguage(testLocale
, temp
, cap
+1, &status
);
242 if(U_FAILURE(status
)){
243 log_err("ERROR: in uloc_getLanguage %s\n", myErrorName(status
));
245 if (0 !=strcmp(temp
,rawData2
[LANG
][i
])) {
246 log_err(" Language code mismatch: %s versus %s\n", temp
, rawData2
[LANG
][i
]);
250 cap
=uloc_getCountry(testLocale
, temp
, cap
, &status
);
251 if(status
==U_BUFFER_OVERFLOW_ERROR
){
253 temp
=(char*)realloc(temp
, sizeof(char) * (cap
+1));
254 uloc_getCountry(testLocale
, temp
, cap
+1, &status
);
256 if(U_FAILURE(status
)){
257 log_err("ERROR: in uloc_getCountry %s\n", myErrorName(status
));
259 if (0 != strcmp(temp
, rawData2
[CTRY
][i
])) {
260 log_err(" Country code mismatch: %s versus %s\n", temp
, rawData2
[CTRY
][i
]);
264 cap
=uloc_getVariant(testLocale
, temp
, cap
, &status
);
265 if(status
==U_BUFFER_OVERFLOW_ERROR
){
267 temp
=(char*)realloc(temp
, sizeof(char) * (cap
+1));
268 uloc_getVariant(testLocale
, temp
, cap
+1, &status
);
270 if(U_FAILURE(status
)){
271 log_err("ERROR: in uloc_getVariant %s\n", myErrorName(status
));
273 if (0 != strcmp(temp
, rawData2
[VAR
][i
])) {
274 log_err("Variant code mismatch: %s versus %s\n", temp
, rawData2
[VAR
][i
]);
277 cap
=uloc_getName(testLocale
, NULL
, 0, &status
);
278 if(status
==U_BUFFER_OVERFLOW_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
);
285 if(U_FAILURE(status
)){
286 log_err("ERROR: in uloc_getName %s\n", myErrorName(status
));
288 if (0 != strcmp(name
, rawData2
[NAME
][i
])){
289 log_err(" Mismatch in getName: %s versus %s\n", name
, rawData2
[NAME
][i
]);
299 static void TestNullDefault() {
300 UErrorCode status
= U_ZERO_ERROR
;
301 char original
[ULOC_FULLNAME_CAPACITY
];
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());
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");
314 /* Test that set & get of default locale work, and that
315 * default locales are cached and reused, and not overwritten.
319 const char *n2_en_US
;
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
);
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
);
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
);
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
);
343 if (n2_en_US
!= n_en_US
) {
344 log_err("Default locale cache failed to reuse en_US locale.\n");
347 if (U_FAILURE(status
)) {
348 log_err("Failure returned from uloc_setDefault - \"%s\"\n", u_errorName(status
));
354 /* Test the i- and x- and @ and . functionality
357 #define PREFIXBUFSIZ 128
359 static void TestPrefixes() {
362 const char *loc
, *expected
;
364 const char *testData
[][7] =
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
},
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 */
390 {NULL
,NULL
,NULL
,NULL
,NULL
,NULL
,NULL
}
393 const char *testTitles
[] = {
394 "uloc_getLanguage()",
400 "uloc_canonicalize()"
403 char buf
[PREFIXBUFSIZ
];
408 for(row
=0;testData
[row
][0] != NULL
;row
++) {
409 loc
= testData
[row
][NAME
];
410 log_verbose("Test #%d: %s\n", row
, loc
);
415 for(n
=0;n
<=(NAME
+2);n
++) {
416 if(n
==NAME
) continue;
418 for(len
=0;len
<PREFIXBUFSIZ
;len
++) {
419 buf
[len
] = '%'; /* Set a tripwire.. */
425 len
= uloc_getLanguage(loc
, buf
, PREFIXBUFSIZ
, &err
);
429 len
= uloc_getScript(loc
, buf
, PREFIXBUFSIZ
, &err
);
433 len
= uloc_getCountry(loc
, buf
, PREFIXBUFSIZ
, &err
);
437 len
= uloc_getVariant(loc
, buf
, PREFIXBUFSIZ
, &err
);
441 len
= uloc_getName(loc
, buf
, PREFIXBUFSIZ
, &err
);
445 len
= uloc_canonicalize(loc
, buf
, PREFIXBUFSIZ
, &err
);
454 log_err("#%d: %s on %s: err %s\n",
455 row
, testTitles
[n
], loc
, u_errorName(err
));
457 log_verbose("#%d: %s on %s: -> [%s] (length %d)\n",
458 row
, testTitles
[n
], loc
, buf
, len
);
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);
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]);
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];
477 if(strcmp(buf
, expected
)) {
478 log_err("#%d: %s on %s: -> [%s] (expected '%s'!)\n",
479 row
, testTitles
[n
], loc
, buf
, expected
);
488 /* testing uloc_getISO3Language(), uloc_getISO3Country(), */
489 static void TestSimpleResourceInfo() {
491 char* testLocale
= 0;
496 testLocale
=(char*)malloc(sizeof(char) * 1);
497 expected
=(UChar
*)malloc(sizeof(UChar
) * 1);
500 log_verbose("Testing getISO3Language and getISO3Country\n");
501 for (i
= 0; i
< LOCALE_SIZE
; i
++) {
503 testLocale
=(char*)realloc(testLocale
, sizeof(char) * (u_strlen(dataTable
[NAME
][i
])+1));
504 u_austrcpy(testLocale
, dataTable
[NAME
][i
]);
506 log_verbose("Testing %s ......\n", testLocale
);
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
]));
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
]));
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
]);
535 * Jitterbug 2439 -- markus 20030425
537 * The lookup of display names must not fall back through the default
538 * locale because that yields useless results.
540 static void TestDisplayNames()
543 UErrorCode errorCode
=U_ZERO_ERROR
;
545 log_verbose("Testing getDisplayName for different locales\n");
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
);
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
));
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
));
573 const char *aLocale
= "es@collation=traditional;calendar=japanese";
574 const char *testL
[] = { "en_US",
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)" };
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
));
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
));
594 log_verbose("pass in uloc_getDisplayName(%s,%s,..) got '%s'\n", aLocale
, testL
[i
], expect
[i
]);
603 /* test for uloc_getAvialable() and uloc_countAvilable()*/
604 static void TestGetAvailableLocales()
610 log_verbose("Testing the no of avialable locales\n");
611 locCount
=uloc_countAvailable();
613 log_data_err("countAvailable() returned an empty list!\n");
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
);
620 log_info("Number of locales returned = %d\n", locCount
);
622 for(i
=0;i
<locCount
;i
++){
623 locList
=uloc_getAvailable(i
);
625 log_verbose(" %s\n", locList
);
629 /* test for u_getDataDirectory, u_setDataDirectory, uloc_getISO3Language */
630 static void TestDataDirectory()
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 */
637 log_verbose("Testing getDataDirectory()\n");
638 temp
= u_getDataDirectory();
639 strcpy(oldDirectory
, temp
);
641 testValue1
=uloc_getISO3Language("en_US");
642 log_verbose("first fetch of language retrieved %s\n", testValue1
);
644 if (0 != strcmp(testValue1
,"eng")){
645 log_err("Initial check of ISO3 language failed: expected \"eng\", got %s \n", testValue1
);
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");
654 log_err("Error in setDataDirectory. Directory not set correctly - came back as [%s], expected [%s]\n", u_getDataDirectory(), path
);
656 testValue2
=uloc_getISO3Language("en_US");
657 log_verbose("second fetch of language retrieved %s \n", testValue2
);
659 u_setDataDirectory(oldDirectory
);
660 testValue3
=uloc_getISO3Language("en_US");
661 log_verbose("third fetch of language retrieved %s \n", testValue3
);
663 if (0 != strcmp(testValue3
,"eng")) {
664 log_err("get/setDataDirectory() failed: expected \"eng\", got \" %s \" \n", testValue3
);
670 /*=========================================================== */
674 static void doTestDisplayNames(const char* displayLocale
, int32_t compareIndex
)
676 UErrorCode status
= U_ZERO_ERROR
;
678 int32_t maxresultsize
;
680 const char *testLocale
;
684 UChar
*testScript
= 0;
690 UChar
* expectedLang
= 0;
691 UChar
* expectedScript
= 0;
692 UChar
* expectedCtry
= 0;
693 UChar
* expectedVar
= 0;
694 UChar
* expectedName
= 0;
698 for(i
=0;i
<LOCALE_SIZE
; ++i
)
700 testLocale
=rawData2
[NAME
][i
];
702 log_verbose("Testing..... %s\n", testLocale
);
705 maxresultsize
=uloc_getDisplayLanguage(testLocale
, displayLocale
, NULL
, maxresultsize
, &status
);
706 if(status
==U_BUFFER_OVERFLOW_ERROR
)
709 testLang
=(UChar
*)malloc(sizeof(UChar
) * (maxresultsize
+1));
710 uloc_getDisplayLanguage(testLocale
, displayLocale
, testLang
, maxresultsize
+ 1, &status
);
716 if(U_FAILURE(status
)){
717 log_err("Error in getDisplayLanguage() %s\n", myErrorName(status
));
721 maxresultsize
=uloc_getDisplayScript(testLocale
, displayLocale
, NULL
, maxresultsize
, &status
);
722 if(status
==U_BUFFER_OVERFLOW_ERROR
)
725 testScript
=(UChar
*)malloc(sizeof(UChar
) * (maxresultsize
+1));
726 uloc_getDisplayScript(testLocale
, displayLocale
, testScript
, maxresultsize
+ 1, &status
);
732 if(U_FAILURE(status
)){
733 log_err("Error in getDisplayScript() %s\n", myErrorName(status
));
737 maxresultsize
=uloc_getDisplayCountry(testLocale
, displayLocale
, NULL
, maxresultsize
, &status
);
738 if(status
==U_BUFFER_OVERFLOW_ERROR
)
741 testCtry
=(UChar
*)malloc(sizeof(UChar
) * (maxresultsize
+1));
742 uloc_getDisplayCountry(testLocale
, displayLocale
, testCtry
, maxresultsize
+ 1, &status
);
748 if(U_FAILURE(status
)){
749 log_err("Error in getDisplayCountry() %s\n", myErrorName(status
));
753 maxresultsize
=uloc_getDisplayVariant(testLocale
, displayLocale
, NULL
, maxresultsize
, &status
);
754 if(status
==U_BUFFER_OVERFLOW_ERROR
)
757 testVar
=(UChar
*)malloc(sizeof(UChar
) * (maxresultsize
+1));
758 uloc_getDisplayVariant(testLocale
, displayLocale
, testVar
, maxresultsize
+ 1, &status
);
764 if(U_FAILURE(status
)){
765 log_err("Error in getDisplayVariant() %s\n", myErrorName(status
));
769 maxresultsize
=uloc_getDisplayName(testLocale
, displayLocale
, NULL
, maxresultsize
, &status
);
770 if(status
==U_BUFFER_OVERFLOW_ERROR
)
773 testName
=(UChar
*)malloc(sizeof(UChar
) * (maxresultsize
+1));
774 uloc_getDisplayName(testLocale
, displayLocale
, testName
, maxresultsize
+ 1, &status
);
780 if(U_FAILURE(status
)){
781 log_err("Error in getDisplayName() %s\n", myErrorName(status
));
784 expectedLang
=dataTable
[compareIndex
][i
];
785 if(u_strlen(expectedLang
)== 0)
786 expectedLang
=dataTable
[DLANG_EN
][i
];
788 expectedScript
=dataTable
[compareIndex
+ 1][i
];
789 if(u_strlen(expectedScript
)== 0)
790 expectedScript
=dataTable
[DSCRIPT_EN
][i
];
792 expectedCtry
=dataTable
[compareIndex
+ 2][i
];
793 if(u_strlen(expectedCtry
)== 0)
794 expectedCtry
=dataTable
[DCTRY_EN
][i
];
796 expectedVar
=dataTable
[compareIndex
+ 3][i
];
797 if(u_strlen(expectedVar
)== 0)
798 expectedVar
=dataTable
[DVAR_EN
][i
];
800 expectedName
=dataTable
[compareIndex
+ 4][i
];
801 if(u_strlen(expectedName
) == 0)
802 expectedName
=dataTable
[DNAME_EN
][i
];
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
);
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
);
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
);
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
);
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
);
824 if(testName
!=&_NUL
) {
827 if(testLang
!=&_NUL
) {
830 if(testScript
!=&_NUL
) {
833 if(testCtry
!=&_NUL
) {
843 /* test for uloc_getISOLanguages, uloc_getISOCountries */
844 static void TestISOFunctions()
846 const char* const* str
=uloc_getISOLanguages();
847 const char* const* str1
=uloc_getISOCountries();
851 UResourceBundle
*res
;
852 UErrorCode status
= U_ZERO_ERROR
;
854 /* test getISOLanguages*/
855 /*str=uloc_getISOLanguages(); */
856 log_verbose("Testing ISO Languages: \n");
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
;
866 for(count
= 0; *(str
+count
) != 0; count
++)
872 /* This code only works on ASCII machines where the keys are stored in ASCII order */
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
);
885 status
= U_ZERO_ERROR
;
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
);
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. */
907 log_err("There is an error in getISOLanguages, got %d, expected %d (as per structLocale)\n", count
, expect
);
910 log_verbose("Testing ISO Countries");
911 for(count
= 0; *(str1
+count
) != 0; count
++)
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
);
922 log_err("There is an error in getISOCountries, got %d, expected %d \n", count
, expect
);
926 static void setUpDataTable()
929 dataTable
= (UChar
***)(calloc(sizeof(UChar
**),LOCALE_INFO_SIZE
));
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
]);
939 static void cleanUpDataTable()
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
]);
955 * @bug 4011756 4011380
957 static void TestISO3Fallback()
959 const char* test
="xx_YY";
963 result
= uloc_getISO3Language(test
);
965 /* Conform to C API usage */
967 if (!result
|| (result
[0] != 0))
968 log_err("getISO3Language() on xx_YY returned %s instead of \"\"");
970 result
= uloc_getISO3Country(test
);
972 if (!result
|| (result
[0] != 0))
973 log_err("getISO3Country() on xx_YY returned %s instead of \"\"");
979 static void TestSimpleDisplayNames()
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.
987 char languageCodes
[] [4] = { "he", "id", "iu", "ug", "yi", "za" };
988 const char* languageNames
[] = { "Hebrew", "Indonesian", "Inuktitut", "Uighur", "Yiddish",
990 UErrorCode status
=U_ZERO_ERROR
;
993 for (i
= 0; i
< 6; i
++) {
995 UChar
*expectedLang
=0;
997 size
=uloc_getDisplayLanguage(languageCodes
[i
], "en_US", NULL
, size
, &status
);
998 if(status
==U_BUFFER_OVERFLOW_ERROR
) {
1000 testLang
=(UChar
*)malloc(sizeof(UChar
) * (size
+ 1));
1001 uloc_getDisplayLanguage(languageCodes
[i
], "en_US", testLang
, size
+ 1, &status
);
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
));
1017 static void TestUninstalledISO3Names()
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",
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" };
1031 for (i
= 0; i
< 8; i
++) {
1032 UErrorCode err
= U_ZERO_ERROR
;
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
));
1039 for (i
= 0; i
< 8; i
++) {
1040 UErrorCode err
= U_ZERO_ERROR
;
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
));
1050 static void TestVariantParsing()
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_";
1061 UChar displayVar
[100];
1062 UChar displayName
[100];
1063 UErrorCode status
=U_ZERO_ERROR
;
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
);
1073 log_err("FAIL: Didn't get U_BUFFER_OVERFLOW_ERROR\n");
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
));
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
);
1087 log_err("FAIL: Didn't get U_BUFFER_OVERFLOW_ERROR\n");
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
));
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
);
1103 log_err("FAIL: Didn't get U_BUFFER_OVERFLOW_ERROR\n");
1105 if(strcmp(austrdup(got
),"FOO")!=0) {
1106 log_err("FAIL: getDisplayVariant() Wanted: foo Got: %s\n", austrdup(got
));
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
);
1117 log_err("FAIL: Didn't get U_BUFFER_OVERFLOW_ERROR\n");
1119 if(strcmp(austrdup(got
),"_FOO")!=0) {
1120 log_err("FAIL: getDisplayVariant() Wanted: _FOO Got: %s\n", austrdup(got
));
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
);
1131 log_err("FAIL: Didn't get U_BUFFER_OVERFLOW_ERROR\n");
1133 if(strcmp(austrdup(got
),"FOO_")!=0) {
1134 log_err("FAIL: getDisplayVariant() Wanted: FOO_ Got: %s\n", austrdup(got
));
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
);
1145 log_err("FAIL: Didn't get U_BUFFER_OVERFLOW_ERROR\n");
1147 if(strcmp(austrdup(got
),"_FOO_")!=0) {
1148 log_err("FAIL: getDisplayVariant() Wanted: _FOO_ Got: %s\n", austrdup(got
));
1154 static void TestObsoleteNames(void)
1157 UErrorCode status
= U_ZERO_ERROR
;
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 { "", "", "", "", "" }
1193 for(i
=0;tests
[i
].locale
[0];i
++)
1197 locale
= tests
[i
].locale
;
1198 log_verbose("** %s:\n", locale
);
1200 status
= U_ZERO_ERROR
;
1201 if(strcmp(tests
[i
].lang3
,uloc_getISO3Language(locale
)))
1203 log_err("FAIL: uloc_getISO3Language(%s)==\t\"%s\",\t expected \"%s\"\n",
1204 locale
, uloc_getISO3Language(locale
), tests
[i
].lang3
);
1208 log_verbose(" uloc_getISO3Language()==\t\"%s\"\n",
1209 uloc_getISO3Language(locale
) );
1212 status
= U_ZERO_ERROR
;
1213 uloc_getLanguage(locale
, buff
, 256, &status
);
1214 if(U_FAILURE(status
))
1216 log_err("FAIL: error getting language from %s\n", locale
);
1220 if(strcmp(buff
,tests
[i
].lang
))
1222 log_err("FAIL: uloc_getLanguage(%s)==\t\"%s\"\t expected \"%s\"\n",
1223 locale
, buff
, tests
[i
].lang
);
1227 log_verbose(" uloc_getLanguage(%s)==\t%s\n", locale
, buff
);
1230 if(strcmp(tests
[i
].lang3
,uloc_getISO3Language(locale
)))
1232 log_err("FAIL: uloc_getISO3Language(%s)==\t\"%s\",\t expected \"%s\"\n",
1233 locale
, uloc_getISO3Language(locale
), tests
[i
].lang3
);
1237 log_verbose(" uloc_getISO3Language()==\t\"%s\"\n",
1238 uloc_getISO3Language(locale
) );
1241 if(strcmp(tests
[i
].ctry3
,uloc_getISO3Country(locale
)))
1243 log_err("FAIL: uloc_getISO3Country(%s)==\t\"%s\",\t expected \"%s\"\n",
1244 locale
, uloc_getISO3Country(locale
), tests
[i
].ctry3
);
1248 log_verbose(" uloc_getISO3Country()==\t\"%s\"\n",
1249 uloc_getISO3Country(locale
) );
1252 status
= U_ZERO_ERROR
;
1253 uloc_getCountry(locale
, buff
, 256, &status
);
1254 if(U_FAILURE(status
))
1256 log_err("FAIL: error getting country from %s\n", locale
);
1260 if(strcmp(buff
,tests
[i
].ctry
))
1262 log_err("FAIL: uloc_getCountry(%s)==\t\"%s\"\t expected \"%s\"\n",
1263 locale
, buff
, tests
[i
].ctry
);
1267 log_verbose(" uloc_getCountry(%s)==\t%s\n", locale
, buff
);
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"));
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"));
1282 i
= uloc_getLanguage("kok",NULL
,0,&icu_err
);
1283 if(U_FAILURE(icu_err
))
1285 log_err("FAIL: Got %s trying to do uloc_getLanguage(kok)\n", u_errorName(icu_err
));
1288 icu_err
= U_ZERO_ERROR
;
1289 uloc_getLanguage("kok",r1_buff
,12,&icu_err
);
1290 if(U_FAILURE(icu_err
))
1292 log_err("FAIL: Got %s trying to do uloc_getLanguage(kok, buff)\n", u_errorName(icu_err
));
1295 r1_addr
= (char *)uloc_getISO3Language("kok");
1297 icu_err
= U_ZERO_ERROR
;
1298 if (strcmp(r1_buff
,"kok") != 0)
1300 log_err("FAIL: uloc_getLanguage(kok)==%s not kok\n",r1_buff
);
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)
1307 printf("uloc_getLanguage error (%s)\n",r1_buff
);
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)
1314 printf("uloc_getLanguage error (%s)\n",r1_buff
);
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)
1324 printf("uloc_getCountry error (%s)\n",r1_buff
);
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)
1333 printf("uloc_getCountry error (%s)\n",r1_buff
);
1341 static void MoreVariants(void)
1344 const char *localeID
;
1345 const char *keyword
;
1346 const char *expectedValue
;
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 ", "", ""}
1354 UErrorCode status
= U_ZERO_ERROR
;
1357 int32_t resultLen
= 0;
1360 for(i
= 0; i
< sizeof(testCases
)/sizeof(testCases
[0]); i
++) {
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
);
1370 static void TestKeywordVariants(void)
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 */
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",
1385 "de_DE@calendar=buddhist;collation=Phonebook;currency=euro",
1386 {"calendar", "collation", "currency"},
1394 "de_DE@currency=EUR",
1395 {"","","","","","",""},
1397 U_INVALID_FORMAT_ERROR
/* must have '=' after '@' */
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 {"","","","","","",""},
1406 U_INVALID_FORMAT_ERROR
1409 UErrorCode status
= U_ZERO_ERROR
;
1411 int32_t i
= 0, j
= 0;
1412 int32_t resultLen
= 0;
1414 UEnumeration
*keywords
;
1415 int32_t keyCount
= 0;
1416 const char *keyword
= NULL
;
1417 int32_t keywordLen
= 0;
1419 for(i
= 0; i
< sizeof(testCases
)/sizeof(testCases
[0]); i
++) {
1420 status
= U_ZERO_ERROR
;
1422 keywords
= uloc_openKeywords(testCases
[i
].localeID
, &status
);
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
));
1429 status
= U_ZERO_ERROR
;
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
);
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
);
1443 uenum_close(keywords
);
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
);
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
);
1459 static void TestKeywordVariantParsing(void)
1462 const char *localeID
;
1463 const char *keyword
;
1464 const char *expectedValue
;
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" },
1472 UErrorCode status
= U_ZERO_ERROR
;
1475 int32_t resultLen
= 0;
1478 for(i
= 0; i
< sizeof(testCases
)/sizeof(testCases
[0]); i
++) {
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
);
1489 const char *l
; /* locale */
1490 const char *k
; /* kw */
1491 const char *v
; /* value */
1492 const char *x
; /* expected */
1493 } kwSetTestCases
[] = {
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" },
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" },
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" },
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" },
1536 { "de@collation=phonebook", "Currency", "CHF", "de@collation=phonebook;currency=CHF" }
1540 static void TestKeywordSet(void)
1543 int32_t resultLen
= 0;
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
);
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
);
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
);
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
));
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
));
1572 log_verbose("pass: #%d: %s + [%s=%s] -> %s\n", i
, kwSetTestCases
[i
].l
, kwSetTestCases
[i
].k
, kwSetTestCases
[i
].v
,buffer
);
1577 static void TestKeywordSetError(void)
1585 /* 0-test whether an error condition modifies the buffer at all */
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
));
1595 /* if(res!=strlen(kwSetTestCases[i].x)) {
1596 log_err("expected result %d got %d\n", strlen(kwSetTestCases[i].x), res);
1599 if(buffer
[blen
]!='%') {
1600 log_err("Buffer byte %d was modified: now %c\n", blen
, buffer
[blen
]);
1603 log_verbose("0-buffer modify OK\n");
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
);
1616 if(res
!=(int32_t)strlen(kwSetTestCases
[i
].x
)) {
1617 log_err("expected result %d got %d\n", strlen(kwSetTestCases
[i
].x
), res
);
1620 if(buffer
[blen
]!='%') {
1621 log_err("Buffer byte %d was modified: now %c\n", blen
, buffer
[blen
]);
1624 log_verbose("1/%d-buffer modify OK\n",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
));
1638 if(buffer
[blen
+1]!='%') {
1639 log_err("Buffer byte %d was modified: now %c\n", blen
+1, buffer
[blen
+1]);
1642 if(res
!=(int32_t)strlen(kwSetTestCases
[i
].x
)) {
1643 log_err("expected result %d got %d\n", strlen(kwSetTestCases
[i
].x
), res
);
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
));
1650 log_verbose("pass: #%d: %s + [%s=%s] -> %s\n", i
, kwSetTestCases
[i
].l
, kwSetTestCases
[i
].k
, kwSetTestCases
[i
].v
,
1653 log_verbose("2/%d-buffer modify OK\n",i
);
1657 static int32_t _canonicalize(int32_t selector
, /* 0==getName, 1==canonicalize */
1658 const char* localeID
,
1660 int32_t resultCapacity
,
1662 /* YOU can change this to use function pointers if you like */
1665 return uloc_getName(localeID
, result
, resultCapacity
, ec
);
1667 return uloc_canonicalize(localeID
, result
, resultCapacity
, ec
);
1673 static void TestCanonicalization(void)
1676 const char *localeID
; /* input */
1677 const char *getNameID
; /* expected getName() result */
1678 const char *canonicalID
; /* expected canonicalize() result */
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 */
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 */
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] */ },
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" }
1759 static const char* label
[] = { "getName", "canonicalize" };
1761 UErrorCode status
= U_ZERO_ERROR
;
1762 int32_t i
, j
, resultLen
= 0, origResultLen
;
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
;
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
));
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
));
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
);
1788 log_verbose("Ok: uloc_%s(%s) => \"%s\"\n",
1789 label
[j
], testCases
[i
].localeID
, buffer
);
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
));
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
);
1803 static void TestDisplayKeywords(void)
1807 static const struct {
1808 const char *localeID
;
1809 const char *displayLocale
;
1810 UChar displayKeyword
[200];
1812 { "ca_ES@currency=ESP", "de_AT",
1813 {0x0057, 0x00e4, 0x0068, 0x0072, 0x0075, 0x006e, 0x0067, 0x0000},
1815 { "ja_JP@calendar=japanese", "de",
1816 { 0x004b, 0x0061, 0x006c, 0x0065, 0x006e, 0x0064, 0x0065, 0x0072, 0x0000}
1818 { "de_DE@collation=traditional", "de_DE",
1819 {0x0053, 0x006f, 0x0072, 0x0074, 0x0069, 0x0065, 0x0072, 0x0075, 0x006e, 0x0067, 0x0000}
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
));
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
));
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
);
1853 log_err("uloc_getDisplayKeyword did not return the expected error. Error: %s\n", u_errorName(status
));
1856 free(displayKeyword
);
1859 uenum_close(keywordEnum
);
1863 static void TestDisplayKeywordValues(void){
1867 const char *localeID
;
1868 const char *displayLocale
;
1869 UChar displayKeywordValue
[500];
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}
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}
1877 { "de_DE@currency=DEM", "it",
1878 {0x004d, 0x0061, 0x0072, 0x0063, 0x006f, 0x0020, 0x0054, 0x0065, 0x0064, 0x0065, 0x0073, 0x0063, 0x006f, 0x0000}
1880 { "el_GR@currency=GRD", "en",
1881 {0x0047, 0x0072, 0x0065, 0x0065, 0x006b, 0x0020, 0x0044, 0x0072, 0x0061, 0x0063, 0x0068, 0x006d, 0x0061, 0x0000}
1883 { "eu_ES@currency=ESP", "it_IT",
1884 {0x0050, 0x0065, 0x0073, 0x0065, 0x0074, 0x0061, 0x0020, 0x0053, 0x0070, 0x0061, 0x0067, 0x006e, 0x006f, 0x006c, 0x0061, 0x0000}
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}
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}
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}
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}
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
));
1913 /* the uenum_next returns NUL terminated string */
1914 keyword
= uenum_next(keywordEnum
, &keywordLen
, &status
);
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
));
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
));
1932 log_err("uloc_getDisplayKeywordValue did not return the expected error. Error: %s\n", u_errorName(status
));
1934 free(displayKeywordValue
);
1936 uenum_close(keywordEnum
);
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},
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},
1953 UEnumeration
* keywordEnum
= uloc_openKeywords(localeID
, &status
);
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
));
1962 /* the uenum_next returns NUL terminated string */
1963 keyword
= uenum_next(keywordEnum
, &keywordLen
, &status
);
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
));
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
);
1981 log_err("uloc_getDisplayKeywordValue did not return the expected error. Error: %s\n", u_errorName(status
));
1983 free(displayKeywordValue
);
1985 uenum_close(keywordEnum
);
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;
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
);
2007 static void TestGetBaseName(void) {
2009 const char *localeID
;
2010 const char *baseName
;
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" }
2017 int32_t i
= 0, baseNameLen
= 0;
2019 UErrorCode status
= U_ZERO_ERROR
;
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
);
2033 /* Jitterbug 4115 */
2034 static void TestDisplayNameWarning(void) {
2037 UErrorCode status
= U_ZERO_ERROR
;
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
));
2048 * Compare the ICU version against the given major/minor version.
2050 static int32_t _cmpversion(const char* version
) {
2051 UVersionInfo x
, icu
;
2052 u_versionFromString(x
, version
);
2054 return memcmp(icu
, x
, U_MAX_VERSION_LENGTH
);
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.
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;
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" */
2076 static void _checklocs(const char* label
,
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
);
2087 log_err("FAIL: %s; req=%s, valid=%s, actual=%s\n",
2088 label
, req
, valid
, actual
);
2092 static void TestGetLocale(void) {
2093 UErrorCode ec
= U_ZERO_ERROR
;
2095 UChar EMPTY
[1] = {0};
2098 #if !UCONFIG_NO_FORMATTING
2101 const char *req
= "en_US_REDWOODSHORES", *valid
, *actual
;
2102 obj
= udat_open(UDAT_DEFAULT
, UDAT_DEFAULT
,
2106 if (U_FAILURE(ec
)) {
2107 log_err("udat_open failed\n");
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");
2116 _checklocs("udat", req
, valid
, actual
);
2122 #if !UCONFIG_NO_FORMATTING
2125 const char *req
= "fr_FR_PROVENCAL", *valid
, *actual
;
2126 obj
= ucal_open(NULL
, 0,
2130 if (U_FAILURE(ec
)) {
2131 log_err("ucal_open failed with error: %s\n", u_errorName(ec
));
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");
2140 _checklocs("ucal", req
, valid
, actual
);
2146 #if !UCONFIG_NO_FORMATTING
2149 const char *req
= "zh_Hant_TW_TAINAN", *valid
, *actual
;
2150 obj
= unum_open(UNUM_DECIMAL
,
2154 if (U_FAILURE(ec
)) {
2155 log_err("unum_open failed\n");
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");
2164 _checklocs("unum", req
, valid
, actual
);
2170 #if !UCONFIG_NO_FORMATTING
2172 UMessageFormat
*obj
;
2173 const char *req
= "ja_JP_TAKAYAMA", *valid
, *actual
;
2175 obj
= umsg_open(EMPTY
, 0,
2178 if (U_FAILURE(ec
)) {
2179 log_err("umsg_open failed\n");
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");
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);
2200 _loccmp(valid
, actual
) >= 0) {
2201 log_verbose("umsg; req=%s, valid=%s, actual=%s\n", req
, valid
, actual
);
2203 log_err("FAIL: umsg; req=%s, valid=%s, actual=%s\n", req
, valid
, actual
);
2210 #if !UCONFIG_NO_BREAK_ITERATION
2212 UBreakIterator
*obj
;
2213 const char *req
= "ar_KW_ABDALI", *valid
, *actual
;
2214 obj
= ubrk_open(UBRK_WORD
,
2219 if (U_FAILURE(ec
)) {
2220 log_err("ubrk_open failed\n");
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");
2229 _checklocs("ubrk", req
, valid
, actual
);
2235 #if !UCONFIG_NO_COLLATION
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");
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");
2250 _checklocs("ucol", req
, valid
, actual
);
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",
2267 static void TestAcceptLanguage(void) {
2268 UErrorCode status
= U_ZERO_ERROR
;
2269 UAcceptResult outResult
;
2270 UEnumeration
*available
;
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
},
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, "
2305 for(i
=0;i
<numTests
;i
++) {
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
);
2311 available
= ures_openAvailableLocales(tests
[i
].icuSet
, &status
);
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
);
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
);