1 /********************************************************************
3 * Copyright (c) 1997-2011, International Business Machines Corporation and
4 * others. All Rights Reserved.
5 ********************************************************************/
6 /*****************************************************************************
10 * Modification History:
12 * Madhu Katragadda Ported for C API
13 ******************************************************************************
24 #include "unicode/putil.h"
25 #include "unicode/ubrk.h"
26 #include "unicode/uchar.h"
27 #include "unicode/ucol.h"
28 #include "unicode/udat.h"
29 #include "unicode/uloc.h"
30 #include "unicode/umsg.h"
31 #include "unicode/ures.h"
32 #include "unicode/uset.h"
33 #include "unicode/ustring.h"
34 #include "unicode/utypes.h"
35 #include "unicode/ulocdata.h"
36 #include "unicode/parseerr.h" /* may not be included with some uconfig switches */
38 #define LENGTHOF(array) (int32_t)(sizeof(array)/sizeof((array)[0]))
40 static void TestNullDefault(void);
41 static void TestNonexistentLanguageExemplars(void);
42 static void TestLocDataErrorCodeChaining(void);
43 static void TestLanguageExemplarsFallbacks(void);
45 static void TestUnicodeDefines(void);
47 void PrintDataTable();
49 /*---------------------------------------------------
51 --------------------------------------------------- */
53 #define LOCALE_INFO_SIZE 28
55 static const char* const rawData2
[LOCALE_INFO_SIZE
][LOCALE_SIZE
] = {
57 { "en", "fr", "ca", "el", "no", "zh", "de", "es", "ja" },
59 { "", "", "", "", "", "", "", "", "" },
61 { "US", "FR", "ES", "GR", "NO", "CN", "DE", "", "JP" },
63 { "", "", "", "", "NY", "", "", "", "" },
65 { "en_US", "fr_FR", "ca_ES",
66 "el_GR", "no_NO_NY", "zh_Hans_CN",
67 "de_DE@collation=phonebook", "es@collation=traditional", "ja_JP@calendar=japanese" },
69 { "eng", "fra", "cat", "ell", "nor", "zho", "deu", "spa", "jpn" },
71 { "USA", "FRA", "ESP", "GRC", "NOR", "CHN", "DEU", "", "JPN" },
73 { "409", "40c", "403", "408", "814", "804", "10407", "40a", "411" },
75 /* display language (English) */
76 { "English", "French", "Catalan", "Greek", "Norwegian", "Chinese", "German", "Spanish", "Japanese" },
77 /* display script code (English) */
78 { "", "", "", "", "", "Simplified Han", "", "", "" },
79 /* display country (English) */
80 { "United States", "France", "Spain", "Greece", "Norway", "China", "Germany", "", "Japan" },
81 /* display variant (English) */
82 { "", "", "", "", "NY", "", "", "", "" },
83 /* display name (English) */
84 { "English (United States)", "French (France)", "Catalan (Spain)",
85 "Greek (Greece)", "Norwegian (Norway, NY)", "Chinese (Simplified Han, China)",
86 "German (Germany, Collation=Phonebook Sort Order)", "Spanish (Collation=Traditional Sort Order)", "Japanese (Japan, Calendar=Japanese Calendar)" },
88 /* display language (French) */
89 { "anglais", "fran\\u00E7ais", "catalan", "grec", "norv\\u00E9gien", "chinois", "allemand", "espagnol", "japonais" },
90 /* display script code (French) */
91 { "", "", "", "", "", "id\\u00e9ogrammes han simplifi\\u00e9s", "", "", "" },
92 /* display country (French) */
93 { "\\u00C9tats-Unis", "France", "Espagne", "Gr\\u00E8ce", "Norv\\u00E8ge", "Chine", "Allemagne", "", "Japon" },
94 /* display variant (French) */
95 { "", "", "", "", "NY", "", "", "", "" },
96 /* display name (French) */
97 { "anglais (\\u00C9tats-Unis)", "fran\\u00E7ais (France)", "catalan (Espagne)",
98 "grec (Gr\\u00E8ce)", "norv\\u00E9gien (Norv\\u00E8ge, NY)", "chinois (id\\u00e9ogrammes han simplifi\\u00e9s, Chine)",
99 "allemand (Allemagne, Ordonnancement=Ordre de l\\u2019annuaire)", "espagnol (Ordonnancement=Ordre traditionnel)", "japonais (Japon, Calendrier=Calendrier japonais)" },
101 /* display language (Catalan) */
102 { "angl\\u00E8s", "franc\\u00E8s", "catal\\u00E0", "grec", "noruec", "xin\\u00E8s", "alemany", "espanyol", "japon\\u00E8s" },
103 /* display script code (Catalan) */
104 { "", "", "", "", "", "xin\\u00e8s simplificat", "", "", "" },
105 /* display country (Catalan) */
106 { "Estats Units", "Fran\\u00E7a", "Espanya", "Gr\\u00E8cia", "Noruega", "Xina", "Alemanya", "", "Jap\\u00F3" },
107 /* display variant (Catalan) */
108 { "", "", "", "", "NY", "", "", "", "" },
109 /* display name (Catalan) */
110 { "angl\\u00E8s (Estats Units)", "franc\\u00E8s (Fran\\u00E7a)", "catal\\u00E0 (Espanya)",
111 "grec (Gr\\u00E8cia)", "noruec (Noruega, NY)", "xin\\u00E8s (xin\\u00e8s simplificat, Xina)",
112 "alemany (Alemanya, ordre alfab\\u00e8tic=ordre de la guia telef\\u00F2nica)", "espanyol (ordre alfab\\u00e8tic=ordre tradicional)", "japon\\u00E8s (Jap\\u00F3, calendari=calendari japon\\u00e8s)" },
114 /* display language (Greek) */
116 "\\u0391\\u03b3\\u03b3\\u03bb\\u03b9\\u03ba\\u03ac",
117 "\\u0393\\u03b1\\u03bb\\u03bb\\u03b9\\u03ba\\u03ac",
118 "\\u039a\\u03b1\\u03c4\\u03b1\\u03bb\\u03b1\\u03bd\\u03b9\\u03ba\\u03ac",
119 "\\u0395\\u03bb\\u03bb\\u03b7\\u03bd\\u03b9\\u03ba\\u03ac",
120 "\\u039d\\u03bf\\u03c1\\u03b2\\u03b7\\u03b3\\u03b9\\u03ba\\u03ac",
121 "\\u039A\\u03B9\\u03BD\\u03B5\\u03B6\\u03B9\\u03BA\\u03AC",
122 "\\u0393\\u03B5\\u03C1\\u03BC\\u03B1\\u03BD\\u03B9\\u03BA\\u03AC",
123 "\\u0399\\u03C3\\u03C0\\u03B1\\u03BD\\u03B9\\u03BA\\u03AC",
124 "\\u0399\\u03B1\\u03C0\\u03C9\\u03BD\\u03B9\\u03BA\\u03AC"
126 /* display script code (Greek) */
128 { "", "", "", "", "", "\\u0391\\u03c0\\u03bb\\u03bf\\u03c0\\u03bf\\u03b9\\u03b7\\u03bc\\u03ad\\u03bd\\u03bf \\u039a\\u03b9\\u03bd\\u03b5\\u03b6\\u03b9\\u03ba\\u03cc", "", "", "" },
129 /* display country (Greek) */
131 "\\u0397\\u03BD\\u03C9\\u03BC\\u03AD\\u03BD\\u03B5\\u03C2 \\u03A0\\u03BF\\u03BB\\u03B9\\u03C4\\u03B5\\u03AF\\u03B5\\u03C2 \\u03C4\\u03B7\\u03C2 \\u0391\\u03BC\\u03B5\\u03C1\\u03B9\\u03BA\\u03AE\\u03C2",
132 "\\u0393\\u03b1\\u03bb\\u03bb\\u03af\\u03b1",
133 "\\u0399\\u03c3\\u03c0\\u03b1\\u03bd\\u03af\\u03b1",
134 "\\u0395\\u03bb\\u03bb\\u03ac\\u03b4\\u03b1",
135 "\\u039d\\u03bf\\u03c1\\u03b2\\u03b7\\u03b3\\u03af\\u03b1",
136 "\\u039A\\u03AF\\u03BD\\u03B1",
137 "\\u0393\\u03B5\\u03C1\\u03BC\\u03B1\\u03BD\\u03AF\\u03B1",
139 "\\u0399\\u03B1\\u03C0\\u03C9\\u03BD\\u03AF\\u03B1"
141 /* display variant (Greek) */
142 { "", "", "", "", "NY", "", "", "", "" }, /* TODO: currently there is no translation for NY in Greek fix this test when we have it */
143 /* display name (Greek) */
145 "\\u0391\\u03b3\\u03b3\\u03bb\\u03b9\\u03ba\\u03ac (\\u0397\\u03BD\\u03C9\\u03BC\\u03AD\\u03BD\\u03B5\\u03C2 \\u03A0\\u03BF\\u03BB\\u03B9\\u03C4\\u03B5\\u03AF\\u03B5\\u03C2 \\u03C4\\u03B7\\u03C2 \\u0391\\u03BC\\u03B5\\u03C1\\u03B9\\u03BA\\u03AE\\u03C2)",
146 "\\u0393\\u03b1\\u03bb\\u03bb\\u03b9\\u03ba\\u03ac (\\u0393\\u03b1\\u03bb\\u03bb\\u03af\\u03b1)",
147 "\\u039a\\u03b1\\u03c4\\u03b1\\u03bb\\u03b1\\u03bd\\u03b9\\u03ba\\u03ac (\\u0399\\u03c3\\u03c0\\u03b1\\u03bd\\u03af\\u03b1)",
148 "\\u0395\\u03bb\\u03bb\\u03b7\\u03bd\\u03b9\\u03ba\\u03ac (\\u0395\\u03bb\\u03bb\\u03ac\\u03b4\\u03b1)",
149 "\\u039d\\u03bf\\u03c1\\u03b2\\u03b7\\u03b3\\u03b9\\u03ba\\u03ac (\\u039d\\u03bf\\u03c1\\u03b2\\u03b7\\u03b3\\u03af\\u03b1, NY)",
150 "\\u039A\\u03B9\\u03BD\\u03B5\\u03B6\\u03B9\\u03BA\\u03AC (\\u0391\\u03c0\\u03bb\\u03bf\\u03c0\\u03bf\\u03b9\\u03b7\\u03bc\\u03ad\\u03bd\\u03bf \\u039a\\u03b9\\u03bd\\u03b5\\u03b6\\u03b9\\u03ba\\u03cc, \\u039A\\u03AF\\u03BD\\u03B1)",
151 "\\u0393\\u03B5\\u03C1\\u03BC\\u03B1\\u03BD\\u03B9\\u03BA\\u03AC (\\u0393\\u03B5\\u03C1\\u03BC\\u03B1\\u03BD\\u03AF\\u03B1, \\u03C4\\u03B1\\u03BA\\u03C4\\u03BF\\u03C0\\u03BF\\u03AF\\u03B7\\u03C3\\u03B7=\\u03A3\\u03B5\\u03B9\\u03C1\\u03AC \\u03C4\\u03B1\\u03BE\\u03B9\\u03BD\\u03CC\\u03BC\\u03B7\\u03C3\\u03B7\\u03C2 \\u03C4\\u03B7\\u03BB\\u03B5\\u03C6\\u03C9\\u03BD\\u03B9\\u03BA\\u03BF\\u03CD \\u03BA\\u03B1\\u03C4\\u03B1\\u03BB\\u03CC\\u03B3\\u03BF\\u03C5)",
152 "\\u0399\\u03C3\\u03C0\\u03B1\\u03BD\\u03B9\\u03BA\\u03AC (\\u03C4\\u03B1\\u03BA\\u03C4\\u03BF\\u03C0\\u03BF\\u03AF\\u03B7\\u03C3\\u03B7=\\u03A0\\u03B1\\u03C1\\u03B1\\u03B4\\u03BF\\u03C3\\u03B9\\u03B1\\u03BA\\u03AE \\u03C3\\u03B5\\u03B9\\u03C1\\u03AC \\u03C4\\u03B1\\u03BE\\u03B9\\u03BD\\u03CC\\u03BC\\u03B7\\u03C3\\u03B7\\u03C2)",
153 "\\u0399\\u03B1\\u03C0\\u03C9\\u03BD\\u03B9\\u03BA\\u03AC (\\u0399\\u03B1\\u03C0\\u03C9\\u03BD\\u03AF\\u03B1, \\u03B7\\u03BC\\u03B5\\u03C1\\u03BF\\u03BB\\u03CC\\u03B3\\u03B9\\u03BF=\\u0399\\u03B1\\u03C0\\u03C9\\u03BD\\u03B9\\u03BA\\u03CC \\u03B7\\u03BC\\u03B5\\u03C1\\u03BF\\u03BB\\u03CC\\u03B3\\u03B9\\u03BF)"
157 static UChar
*** dataTable
=0;
197 #define TESTCASE(name) addTest(root, &name, "tsutil/cloctst/" #name)
199 void addLocaleTest(TestNode
** root
);
201 void addLocaleTest(TestNode
** root
)
203 TESTCASE(TestObsoleteNames
); /* srl- move */
204 TESTCASE(TestBasicGetters
);
205 TESTCASE(TestNullDefault
);
206 TESTCASE(TestPrefixes
);
207 TESTCASE(TestSimpleResourceInfo
);
208 TESTCASE(TestDisplayNames
);
209 TESTCASE(TestGetAvailableLocales
);
210 TESTCASE(TestDataDirectory
);
211 #if !UCONFIG_NO_FILE_IO && !UCONFIG_NO_LEGACY_CONVERSION
212 TESTCASE(TestISOFunctions
);
214 TESTCASE(TestISO3Fallback
);
215 TESTCASE(TestUninstalledISO3Names
);
216 TESTCASE(TestSimpleDisplayNames
);
217 TESTCASE(TestVariantParsing
);
218 TESTCASE(TestKeywordVariants
);
219 TESTCASE(TestKeywordVariantParsing
);
220 TESTCASE(TestCanonicalization
);
221 TESTCASE(TestKeywordSet
);
222 TESTCASE(TestKeywordSetError
);
223 TESTCASE(TestDisplayKeywords
);
224 TESTCASE(TestDisplayKeywordValues
);
225 TESTCASE(TestGetBaseName
);
226 #if !UCONFIG_NO_FILE_IO
227 TESTCASE(TestGetLocale
);
229 TESTCASE(TestDisplayNameWarning
);
230 TESTCASE(TestNonexistentLanguageExemplars
);
231 TESTCASE(TestLocDataErrorCodeChaining
);
232 TESTCASE(TestLanguageExemplarsFallbacks
);
233 TESTCASE(TestCalendar
);
234 TESTCASE(TestDateFormat
);
235 TESTCASE(TestCollation
);
236 TESTCASE(TestULocale
);
237 TESTCASE(TestUResourceBundle
);
238 TESTCASE(TestDisplayName
);
239 TESTCASE(TestAcceptLanguage
);
240 TESTCASE(TestGetLocaleForLCID
);
241 TESTCASE(TestOrientation
);
242 TESTCASE(TestLikelySubtags
);
243 TESTCASE(TestToLanguageTag
);
244 TESTCASE(TestForLanguageTag
);
245 TESTCASE(TestTrailingNull
);
246 TESTCASE(TestUnicodeDefines
);
250 /* testing uloc(), uloc_getName(), uloc_getLanguage(), uloc_getVariant(), uloc_getCountry() */
251 static void TestBasicGetters() {
254 UErrorCode status
= U_ZERO_ERROR
;
255 char *testLocale
= 0;
256 char *temp
= 0, *name
= 0;
257 log_verbose("Testing Basic Getters\n");
258 for (i
= 0; i
< LOCALE_SIZE
; i
++) {
259 testLocale
=(char*)malloc(sizeof(char) * (strlen(rawData2
[NAME
][i
])+1));
260 strcpy(testLocale
,rawData2
[NAME
][i
]);
262 log_verbose("Testing %s .....\n", testLocale
);
263 cap
=uloc_getLanguage(testLocale
, NULL
, 0, &status
);
264 if(status
==U_BUFFER_OVERFLOW_ERROR
){
266 temp
=(char*)malloc(sizeof(char) * (cap
+1));
267 uloc_getLanguage(testLocale
, temp
, cap
+1, &status
);
269 if(U_FAILURE(status
)){
270 log_err("ERROR: in uloc_getLanguage %s\n", myErrorName(status
));
272 if (0 !=strcmp(temp
,rawData2
[LANG
][i
])) {
273 log_err(" Language code mismatch: %s versus %s\n", temp
, rawData2
[LANG
][i
]);
277 cap
=uloc_getCountry(testLocale
, temp
, cap
, &status
);
278 if(status
==U_BUFFER_OVERFLOW_ERROR
){
280 temp
=(char*)realloc(temp
, sizeof(char) * (cap
+1));
281 uloc_getCountry(testLocale
, temp
, cap
+1, &status
);
283 if(U_FAILURE(status
)){
284 log_err("ERROR: in uloc_getCountry %s\n", myErrorName(status
));
286 if (0 != strcmp(temp
, rawData2
[CTRY
][i
])) {
287 log_err(" Country code mismatch: %s versus %s\n", temp
, rawData2
[CTRY
][i
]);
291 cap
=uloc_getVariant(testLocale
, temp
, cap
, &status
);
292 if(status
==U_BUFFER_OVERFLOW_ERROR
){
294 temp
=(char*)realloc(temp
, sizeof(char) * (cap
+1));
295 uloc_getVariant(testLocale
, temp
, cap
+1, &status
);
297 if(U_FAILURE(status
)){
298 log_err("ERROR: in uloc_getVariant %s\n", myErrorName(status
));
300 if (0 != strcmp(temp
, rawData2
[VAR
][i
])) {
301 log_err("Variant code mismatch: %s versus %s\n", temp
, rawData2
[VAR
][i
]);
304 cap
=uloc_getName(testLocale
, NULL
, 0, &status
);
305 if(status
==U_BUFFER_OVERFLOW_ERROR
){
307 name
=(char*)malloc(sizeof(char) * (cap
+1));
308 uloc_getName(testLocale
, name
, cap
+1, &status
);
309 } else if(status
==U_ZERO_ERROR
) {
310 log_err("ERROR: in uloc_getName(%s,NULL,0,..), expected U_BUFFER_OVERFLOW_ERROR!\n", testLocale
);
312 if(U_FAILURE(status
)){
313 log_err("ERROR: in uloc_getName %s\n", myErrorName(status
));
315 if (0 != strcmp(name
, rawData2
[NAME
][i
])){
316 log_err(" Mismatch in getName: %s versus %s\n", name
, rawData2
[NAME
][i
]);
326 static void TestNullDefault() {
327 UErrorCode status
= U_ZERO_ERROR
;
328 char original
[ULOC_FULLNAME_CAPACITY
];
330 uprv_strcpy(original
, uloc_getDefault());
331 uloc_setDefault("qq_BLA", &status
);
332 if (uprv_strcmp(uloc_getDefault(), "qq_BLA") != 0) {
333 log_err(" Mismatch in uloc_setDefault: qq_BLA versus %s\n", uloc_getDefault());
335 uloc_setDefault(NULL
, &status
);
336 if (uprv_strcmp(uloc_getDefault(), original
) != 0) {
337 log_err(" uloc_setDefault(NULL, &status) didn't get the default locale back!\n");
341 /* Test that set & get of default locale work, and that
342 * default locales are cached and reused, and not overwritten.
346 const char *n2_en_US
;
348 status
= U_ZERO_ERROR
;
349 uloc_setDefault("en_US", &status
);
350 n_en_US
= uloc_getDefault();
351 if (strcmp(n_en_US
, "en_US") != 0) {
352 log_err("Wrong result from uloc_getDefault(). Expected \"en_US\", got \"%s\"\n", n_en_US
);
355 uloc_setDefault("fr_FR", &status
);
356 n_fr_FR
= uloc_getDefault();
357 if (strcmp(n_en_US
, "en_US") != 0) {
358 log_err("uloc_setDefault altered previously default string."
359 "Expected \"en_US\", got \"%s\"\n", n_en_US
);
361 if (strcmp(n_fr_FR
, "fr_FR") != 0) {
362 log_err("Wrong result from uloc_getDefault(). Expected \"fr_FR\", got %s\n", n_fr_FR
);
365 uloc_setDefault("en_US", &status
);
366 n2_en_US
= uloc_getDefault();
367 if (strcmp(n2_en_US
, "en_US") != 0) {
368 log_err("Wrong result from uloc_getDefault(). Expected \"en_US\", got \"%s\"\n", n_en_US
);
370 if (n2_en_US
!= n_en_US
) {
371 log_err("Default locale cache failed to reuse en_US locale.\n");
374 if (U_FAILURE(status
)) {
375 log_err("Failure returned from uloc_setDefault - \"%s\"\n", u_errorName(status
));
381 /* Test the i- and x- and @ and . functionality
384 #define PREFIXBUFSIZ 128
386 static void TestPrefixes() {
389 const char *loc
, *expected
;
391 static const char * const testData
[][7] =
393 /* NULL canonicalize() column means "expect same as getName()" */
394 {"sv", "", "FI", "AL", "sv-fi-al", "sv_FI_AL", NULL
},
395 {"en", "", "GB", "", "en-gb", "en_GB", NULL
},
396 {"i-hakka", "", "MT", "XEMXIJA", "i-hakka_MT_XEMXIJA", "i-hakka_MT_XEMXIJA", NULL
},
397 {"i-hakka", "", "CN", "", "i-hakka_CN", "i-hakka_CN", NULL
},
398 {"i-hakka", "", "MX", "", "I-hakka_MX", "i-hakka_MX", NULL
},
399 {"x-klingon", "", "US", "SANJOSE", "X-KLINGON_us_SANJOSE", "x-klingon_US_SANJOSE", NULL
},
401 {"zh", "Hans", "", "PINYIN", "zh-Hans-pinyin", "zh_Hans_PINYIN", "zh_Hans@collation=pinyin"},
402 {"hy", "", "", "AREVMDA", "hy_AREVMDA", "hy_AREVMDA", NULL
},
404 {"mr", "", "", "", "mr.utf8", "mr.utf8", "mr"},
405 {"de", "", "TV", "", "de-tv.koi8r", "de_TV.koi8r", "de_TV"},
406 {"x-piglatin", "", "ML", "", "x-piglatin_ML.MBE", "x-piglatin_ML.MBE", "x-piglatin_ML"}, /* Multibyte English */
407 {"i-cherokee", "","US", "", "i-Cherokee_US.utf7", "i-cherokee_US.utf7", "i-cherokee_US"},
408 {"x-filfli", "", "MT", "FILFLA", "x-filfli_MT_FILFLA.gb-18030", "x-filfli_MT_FILFLA.gb-18030", "x-filfli_MT_FILFLA"},
409 {"no", "", "NO", "NY", "no-no-ny.utf32@B", "no_NO_NY.utf32@B", "no_NO_NY_B"},
410 {"no", "", "NO", "", "no-no.utf32@B", "no_NO.utf32@B", "no_NO_B"},
411 {"no", "", "", "NY", "no__ny", "no__NY", NULL
},
412 {"no", "", "", "", "no@ny", "no@ny", "no__NY"},
413 {"el", "Latn", "", "", "el-latn", "el_Latn", NULL
},
414 {"en", "Cyrl", "RU", "", "en-cyrl-ru", "en_Cyrl_RU", NULL
},
415 {"zh", "Hant", "TW", "STROKE", "zh-hant_TW_STROKE", "zh_Hant_TW_STROKE", "zh_Hant_TW@collation=stroke"},
416 {"qq", "Qqqq", "QQ", "QQ", "qq_Qqqq_QQ_QQ", "qq_Qqqq_QQ_QQ", NULL
},
417 {"qq", "Qqqq", "", "QQ", "qq_Qqqq__QQ", "qq_Qqqq__QQ", NULL
},
418 {"12", "3456", "78", "90", "12_3456_78_90", "12_3456_78_90", NULL
}, /* total garbage */
420 {NULL
,NULL
,NULL
,NULL
,NULL
,NULL
,NULL
}
423 static const char * const testTitles
[] = {
424 "uloc_getLanguage()",
430 "uloc_canonicalize()"
433 char buf
[PREFIXBUFSIZ
];
438 for(row
=0;testData
[row
][0] != NULL
;row
++) {
439 loc
= testData
[row
][NAME
];
440 log_verbose("Test #%d: %s\n", row
, loc
);
445 for(n
=0;n
<=(NAME
+2);n
++) {
446 if(n
==NAME
) continue;
448 for(len
=0;len
<PREFIXBUFSIZ
;len
++) {
449 buf
[len
] = '%'; /* Set a tripwire.. */
455 len
= uloc_getLanguage(loc
, buf
, PREFIXBUFSIZ
, &err
);
459 len
= uloc_getScript(loc
, buf
, PREFIXBUFSIZ
, &err
);
463 len
= uloc_getCountry(loc
, buf
, PREFIXBUFSIZ
, &err
);
467 len
= uloc_getVariant(loc
, buf
, PREFIXBUFSIZ
, &err
);
471 len
= uloc_getName(loc
, buf
, PREFIXBUFSIZ
, &err
);
475 len
= uloc_canonicalize(loc
, buf
, PREFIXBUFSIZ
, &err
);
484 log_err("#%d: %s on %s: err %s\n",
485 row
, testTitles
[n
], loc
, u_errorName(err
));
487 log_verbose("#%d: %s on %s: -> [%s] (length %d)\n",
488 row
, testTitles
[n
], loc
, buf
, len
);
490 if(len
!= (int32_t)strlen(buf
)) {
491 log_err("#%d: %s on %s: -> [%s] (length returned %d, actual %d!)\n",
492 row
, testTitles
[n
], loc
, buf
, len
, strlen(buf
)+1);
496 /* see if they smashed something */
497 if(buf
[len
+1] != '%') {
498 log_err("#%d: %s on %s: -> [%s] - wrote [%X] out ofbounds!\n",
499 row
, testTitles
[n
], loc
, buf
, buf
[len
+1]);
502 expected
= testData
[row
][n
];
503 if (expected
== NULL
&& n
== (NAME
+2)) {
504 /* NULL expected canonicalize() means "expect same as getName()" */
505 expected
= testData
[row
][NAME
+1];
507 if(strcmp(buf
, expected
)) {
508 log_err("#%d: %s on %s: -> [%s] (expected '%s'!)\n",
509 row
, testTitles
[n
], loc
, buf
, expected
);
518 /* testing uloc_getISO3Language(), uloc_getISO3Country(), */
519 static void TestSimpleResourceInfo() {
521 char* testLocale
= 0;
526 testLocale
=(char*)malloc(sizeof(char) * 1);
527 expected
=(UChar
*)malloc(sizeof(UChar
) * 1);
530 log_verbose("Testing getISO3Language and getISO3Country\n");
531 for (i
= 0; i
< LOCALE_SIZE
; i
++) {
533 testLocale
=(char*)realloc(testLocale
, sizeof(char) * (u_strlen(dataTable
[NAME
][i
])+1));
534 u_austrcpy(testLocale
, dataTable
[NAME
][i
]);
536 log_verbose("Testing %s ......\n", testLocale
);
538 temp
=uloc_getISO3Language(testLocale
);
539 expected
=(UChar
*)realloc(expected
, sizeof(UChar
) * (strlen(temp
) + 1));
540 u_uastrcpy(expected
,temp
);
541 if (0 != u_strcmp(expected
, dataTable
[LANG3
][i
])) {
542 log_err(" ISO-3 language code mismatch: %s versus %s\n", austrdup(expected
),
543 austrdup(dataTable
[LANG3
][i
]));
546 temp
=uloc_getISO3Country(testLocale
);
547 expected
=(UChar
*)realloc(expected
, sizeof(UChar
) * (strlen(temp
) + 1));
548 u_uastrcpy(expected
,temp
);
549 if (0 != u_strcmp(expected
, dataTable
[CTRY3
][i
])) {
550 log_err(" ISO-3 Country code mismatch: %s versus %s\n", austrdup(expected
),
551 austrdup(dataTable
[CTRY3
][i
]));
553 sprintf(temp2
, "%x", (int)uloc_getLCID(testLocale
));
554 if (strcmp(temp2
, rawData2
[LCID
][i
]) != 0) {
555 log_err("LCID mismatch: %s versus %s\n", temp2
, rawData2
[LCID
][i
]);
565 * Jitterbug 2439 -- markus 20030425
567 * The lookup of display names must not fall back through the default
568 * locale because that yields useless results.
570 static void TestDisplayNames()
573 UErrorCode errorCode
=U_ZERO_ERROR
;
575 log_verbose("Testing getDisplayName for different locales\n");
577 log_verbose(" In locale = en_US...\n");
578 doTestDisplayNames("en_US", DLANG_EN
);
579 log_verbose(" In locale = fr_FR....\n");
580 doTestDisplayNames("fr_FR", DLANG_FR
);
581 log_verbose(" In locale = ca_ES...\n");
582 doTestDisplayNames("ca_ES", DLANG_CA
);
583 log_verbose(" In locale = gr_EL..\n");
584 doTestDisplayNames("el_GR", DLANG_EL
);
586 /* test that the default locale has a display name for its own language */
587 errorCode
=U_ZERO_ERROR
;
588 length
=uloc_getDisplayLanguage(NULL
, NULL
, buffer
, LENGTHOF(buffer
), &errorCode
);
589 if(U_FAILURE(errorCode
) || (length
<=3 && buffer
[0]<=0x7f)) {
590 /* check <=3 to reject getting the language code as a display name */
591 log_data_err("unable to get a display string for the language of the default locale - %s (Are you missing data?)\n", u_errorName(errorCode
));
594 /* test that we get the language code itself for an unknown language, and a default warning */
595 errorCode
=U_ZERO_ERROR
;
596 length
=uloc_getDisplayLanguage("qq", "rr", buffer
, LENGTHOF(buffer
), &errorCode
);
597 if(errorCode
!=U_USING_DEFAULT_WARNING
|| length
!=2 || buffer
[0]!=0x71 || buffer
[1]!=0x71) {
598 log_err("error getting the display string for an unknown language - %s\n", u_errorName(errorCode
));
601 /* test that we get a default warning for a display name where one component is unknown (4255) */
602 errorCode
=U_ZERO_ERROR
;
603 length
=uloc_getDisplayName("qq_US_POSIX", "en_US", buffer
, LENGTHOF(buffer
), &errorCode
);
604 if(errorCode
!=U_USING_DEFAULT_WARNING
) {
605 log_err("error getting the display name for a locale with an unknown language - %s\n", u_errorName(errorCode
));
610 static const char *aLocale
= "es@collation=traditional;calendar=japanese";
611 static const char *testL
[] = { "en_US",
615 static const char *expect
[] = { "Spanish (Calendar=Japanese Calendar, Collation=Traditional Sort Order)", /* note sorted order of keywords */
616 "espagnol (Calendrier=Calendrier japonais, Ordonnancement=Ordre traditionnel)",
617 "espanyol (calendari=calendari japon\\u00e8s, ordre alfab\\u00e8tic=ordre tradicional)",
618 "\\u0399\\u03C3\\u03C0\\u03B1\\u03BD\\u03B9\\u03BA\\u03AC (\\u03B7\\u03BC\\u03B5\\u03C1\\u03BF\\u03BB\\u03CC\\u03B3\\u03B9\\u03BF=\\u0399\\u03B1\\u03C0\\u03C9\\u03BD\\u03B9\\u03BA\\u03CC \\u03B7\\u03BC\\u03B5\\u03C1\\u03BF\\u03BB\\u03CC\\u03B3\\u03B9\\u03BF, \\u03C4\\u03B1\\u03BA\\u03C4\\u03BF\\u03C0\\u03BF\\u03AF\\u03B7\\u03C3\\u03B7=\\u03A0\\u03B1\\u03C1\\u03B1\\u03B4\\u03BF\\u03C3\\u03B9\\u03B1\\u03BA\\u03AE \\u03C3\\u03B5\\u03B9\\u03C1\\u03AC \\u03C4\\u03B1\\u03BE\\u03B9\\u03BD\\u03CC\\u03BC\\u03B7\\u03C3\\u03B7\\u03C2)" };
621 for(i
=0;i
<LENGTHOF(testL
);i
++) {
622 errorCode
= U_ZERO_ERROR
;
623 uloc_getDisplayName(aLocale
, testL
[i
], buffer
, LENGTHOF(buffer
), &errorCode
);
624 if(U_FAILURE(errorCode
)) {
625 log_err("FAIL in uloc_getDisplayName(%s,%s,..) -> %s\n", aLocale
, testL
[i
], u_errorName(errorCode
));
627 expectBuffer
= CharsToUChars(expect
[i
]);
628 if(u_strcmp(buffer
,expectBuffer
)) {
629 log_data_err("FAIL in uloc_getDisplayName(%s,%s,..) expected '%s' got '%s' (Are you missing data?)\n", aLocale
, testL
[i
], expect
[i
], austrdup(buffer
));
631 log_verbose("pass in uloc_getDisplayName(%s,%s,..) got '%s'\n", aLocale
, testL
[i
], expect
[i
]);
640 /* test for uloc_getAvialable() and uloc_countAvilable()*/
641 static void TestGetAvailableLocales()
647 log_verbose("Testing the no of avialable locales\n");
648 locCount
=uloc_countAvailable();
650 log_data_err("countAvailable() returned an empty list!\n");
652 /* use something sensible w/o hardcoding the count */
653 else if(locCount
< 0){
654 log_data_err("countAvailable() returned a wrong value!= %d\n", locCount
);
657 log_info("Number of locales returned = %d\n", locCount
);
659 for(i
=0;i
<locCount
;i
++){
660 locList
=uloc_getAvailable(i
);
662 log_verbose(" %s\n", locList
);
666 /* test for u_getDataDirectory, u_setDataDirectory, uloc_getISO3Language */
667 static void TestDataDirectory()
670 char oldDirectory
[512];
671 const char *temp
,*testValue1
,*testValue2
,*testValue3
;
672 const char path
[40] ="d:\\icu\\source\\test\\intltest" U_FILE_SEP_STRING
; /*give the required path */
674 log_verbose("Testing getDataDirectory()\n");
675 temp
= u_getDataDirectory();
676 strcpy(oldDirectory
, temp
);
678 testValue1
=uloc_getISO3Language("en_US");
679 log_verbose("first fetch of language retrieved %s\n", testValue1
);
681 if (0 != strcmp(testValue1
,"eng")){
682 log_err("Initial check of ISO3 language failed: expected \"eng\", got %s \n", testValue1
);
685 /*defining the path for DataDirectory */
686 log_verbose("Testing setDataDirectory\n");
687 u_setDataDirectory( path
);
688 if(strcmp(path
, u_getDataDirectory())==0)
689 log_verbose("setDataDirectory working fine\n");
691 log_err("Error in setDataDirectory. Directory not set correctly - came back as [%s], expected [%s]\n", u_getDataDirectory(), path
);
693 testValue2
=uloc_getISO3Language("en_US");
694 log_verbose("second fetch of language retrieved %s \n", testValue2
);
696 u_setDataDirectory(oldDirectory
);
697 testValue3
=uloc_getISO3Language("en_US");
698 log_verbose("third fetch of language retrieved %s \n", testValue3
);
700 if (0 != strcmp(testValue3
,"eng")) {
701 log_err("get/setDataDirectory() failed: expected \"eng\", got \" %s \" \n", testValue3
);
707 /*=========================================================== */
711 static void doTestDisplayNames(const char* displayLocale
, int32_t compareIndex
)
713 UErrorCode status
= U_ZERO_ERROR
;
715 int32_t maxresultsize
;
717 const char *testLocale
;
721 UChar
*testScript
= 0;
727 UChar
* expectedLang
= 0;
728 UChar
* expectedScript
= 0;
729 UChar
* expectedCtry
= 0;
730 UChar
* expectedVar
= 0;
731 UChar
* expectedName
= 0;
735 for(i
=0;i
<LOCALE_SIZE
; ++i
)
737 testLocale
=rawData2
[NAME
][i
];
739 log_verbose("Testing..... %s\n", testLocale
);
742 maxresultsize
=uloc_getDisplayLanguage(testLocale
, displayLocale
, NULL
, maxresultsize
, &status
);
743 if(status
==U_BUFFER_OVERFLOW_ERROR
)
746 testLang
=(UChar
*)malloc(sizeof(UChar
) * (maxresultsize
+1));
747 uloc_getDisplayLanguage(testLocale
, displayLocale
, testLang
, maxresultsize
+ 1, &status
);
753 if(U_FAILURE(status
)){
754 log_err("Error in getDisplayLanguage() %s\n", myErrorName(status
));
758 maxresultsize
=uloc_getDisplayScript(testLocale
, displayLocale
, NULL
, maxresultsize
, &status
);
759 if(status
==U_BUFFER_OVERFLOW_ERROR
)
762 testScript
=(UChar
*)malloc(sizeof(UChar
) * (maxresultsize
+1));
763 uloc_getDisplayScript(testLocale
, displayLocale
, testScript
, maxresultsize
+ 1, &status
);
769 if(U_FAILURE(status
)){
770 log_err("Error in getDisplayScript() %s\n", myErrorName(status
));
774 maxresultsize
=uloc_getDisplayCountry(testLocale
, displayLocale
, NULL
, maxresultsize
, &status
);
775 if(status
==U_BUFFER_OVERFLOW_ERROR
)
778 testCtry
=(UChar
*)malloc(sizeof(UChar
) * (maxresultsize
+1));
779 uloc_getDisplayCountry(testLocale
, displayLocale
, testCtry
, maxresultsize
+ 1, &status
);
785 if(U_FAILURE(status
)){
786 log_err("Error in getDisplayCountry() %s\n", myErrorName(status
));
790 maxresultsize
=uloc_getDisplayVariant(testLocale
, displayLocale
, NULL
, maxresultsize
, &status
);
791 if(status
==U_BUFFER_OVERFLOW_ERROR
)
794 testVar
=(UChar
*)malloc(sizeof(UChar
) * (maxresultsize
+1));
795 uloc_getDisplayVariant(testLocale
, displayLocale
, testVar
, maxresultsize
+ 1, &status
);
801 if(U_FAILURE(status
)){
802 log_err("Error in getDisplayVariant() %s\n", myErrorName(status
));
806 maxresultsize
=uloc_getDisplayName(testLocale
, displayLocale
, NULL
, maxresultsize
, &status
);
807 if(status
==U_BUFFER_OVERFLOW_ERROR
)
810 testName
=(UChar
*)malloc(sizeof(UChar
) * (maxresultsize
+1));
811 uloc_getDisplayName(testLocale
, displayLocale
, testName
, maxresultsize
+ 1, &status
);
817 if(U_FAILURE(status
)){
818 log_err("Error in getDisplayName() %s\n", myErrorName(status
));
821 expectedLang
=dataTable
[compareIndex
][i
];
822 if(u_strlen(expectedLang
)== 0)
823 expectedLang
=dataTable
[DLANG_EN
][i
];
825 expectedScript
=dataTable
[compareIndex
+ 1][i
];
826 if(u_strlen(expectedScript
)== 0)
827 expectedScript
=dataTable
[DSCRIPT_EN
][i
];
829 expectedCtry
=dataTable
[compareIndex
+ 2][i
];
830 if(u_strlen(expectedCtry
)== 0)
831 expectedCtry
=dataTable
[DCTRY_EN
][i
];
833 expectedVar
=dataTable
[compareIndex
+ 3][i
];
834 if(u_strlen(expectedVar
)== 0)
835 expectedVar
=dataTable
[DVAR_EN
][i
];
837 expectedName
=dataTable
[compareIndex
+ 4][i
];
838 if(u_strlen(expectedName
) == 0)
839 expectedName
=dataTable
[DNAME_EN
][i
];
841 if (0 !=u_strcmp(testLang
,expectedLang
)) {
842 log_data_err(" Display Language mismatch: got %s expected %s displayLocale=%s (Are you missing data?)\n", austrdup(testLang
), austrdup(expectedLang
), displayLocale
);
845 if (0 != u_strcmp(testScript
,expectedScript
)) {
846 log_data_err(" Display Script mismatch: got %s expected %s displayLocale=%s (Are you missing data?)\n", austrdup(testScript
), austrdup(expectedScript
), displayLocale
);
849 if (0 != u_strcmp(testCtry
,expectedCtry
)) {
850 log_data_err(" Display Country mismatch: got %s expected %s displayLocale=%s (Are you missing data?)\n", austrdup(testCtry
), austrdup(expectedCtry
), displayLocale
);
853 if (0 != u_strcmp(testVar
,expectedVar
)) {
854 log_data_err(" Display Variant mismatch: got %s expected %s displayLocale=%s (Are you missing data?)\n", austrdup(testVar
), austrdup(expectedVar
), displayLocale
);
857 if(0 != u_strcmp(testName
, expectedName
)) {
858 log_data_err(" Display Name mismatch: got %s expected %s displayLocale=%s (Are you missing data?)\n", austrdup(testName
), austrdup(expectedName
), displayLocale
);
861 if(testName
!=&_NUL
) {
864 if(testLang
!=&_NUL
) {
867 if(testScript
!=&_NUL
) {
870 if(testCtry
!=&_NUL
) {
880 /* test for uloc_getISOLanguages, uloc_getISOCountries */
881 static void TestISOFunctions()
883 const char* const* str
=uloc_getISOLanguages();
884 const char* const* str1
=uloc_getISOCountries();
886 const char *key
= NULL
;
887 int32_t count
= 0, skipped
= 0;
889 UResourceBundle
*res
;
890 UResourceBundle
*subRes
;
891 UErrorCode status
= U_ZERO_ERROR
;
893 /* test getISOLanguages*/
894 /*str=uloc_getISOLanguages(); */
895 log_verbose("Testing ISO Languages: \n");
897 /* use structLocale - this data is no longer in root */
898 res
= ures_openDirect(loadTestData(&status
), "structLocale", &status
);
899 subRes
= ures_getByKey(res
, "Languages", NULL
, &status
);
900 if (U_FAILURE(status
)) {
901 log_data_err("There is an error in structLocale's ures_getByKey(\"Languages\"), status=%s\n", u_errorName(status
));
905 expect
= ures_getSize(subRes
);
906 for(count
= 0; *(str
+count
) != 0; count
++)
910 status
= U_ZERO_ERROR
;
913 /* Skip over language tags. This API only returns language codes. */
914 skipped
+= (key
!= NULL
);
915 ures_getNextString(subRes
, NULL
, &key
, &status
);
917 while (key
!= NULL
&& strchr(key
, '_'));
921 /* TODO: Consider removing sh, which is deprecated */
922 if(strcmp(key
,"root") == 0 || strcmp(key
,"Fallback") == 0 || strcmp(key
,"sh") == 0) {
923 ures_getNextString(subRes
, NULL
, &key
, &status
);
926 #if U_CHARSET_FAMILY==U_ASCII_FAMILY
927 /* This code only works on ASCII machines where the keys are stored in ASCII order */
928 if(strcmp(test
,key
)) {
929 /* The first difference usually implies the place where things get out of sync */
930 log_err("FAIL Language diff at offset %d, \"%s\" != \"%s\"\n", count
, test
, key
);
934 if(!strcmp(test
,"in"))
935 log_err("FAIL getISOLanguages() has obsolete language code %s\n", test
);
936 if(!strcmp(test
,"iw"))
937 log_err("FAIL getISOLanguages() has obsolete language code %s\n", test
);
938 if(!strcmp(test
,"ji"))
939 log_err("FAIL getISOLanguages() has obsolete language code %s\n", test
);
940 if(!strcmp(test
,"jw"))
941 log_err("FAIL getISOLanguages() has obsolete language code %s\n", test
);
942 if(!strcmp(test
,"sh"))
943 log_err("FAIL getISOLanguages() has obsolete language code %s\n", test
);
946 expect
-= skipped
; /* Ignore the skipped resources from structLocale */
949 log_err("There is an error in getISOLanguages, got %d, expected %d (as per structLocale)\n", count
, expect
);
952 subRes
= ures_getByKey(res
, "Countries", subRes
, &status
);
953 log_verbose("Testing ISO Countries");
955 expect
= ures_getSize(subRes
) - 1; /* Skip ZZ */
956 for(count
= 0; *(str1
+count
) != 0; count
++)
959 test
= *(str1
+count
);
961 /* Skip over numeric UN tags. This API only returns ISO-3166 codes. */
962 skipped
+= (key
!= NULL
);
963 ures_getNextString(subRes
, NULL
, &key
, &status
);
965 while (key
!= NULL
&& strlen(key
) != 2);
969 /* TODO: Consider removing CS, which is deprecated */
970 while(strcmp(key
,"QO") == 0 || strcmp(key
,"QU") == 0 || strcmp(key
,"CS") == 0) {
971 ures_getNextString(subRes
, NULL
, &key
, &status
);
974 #if U_CHARSET_FAMILY==U_ASCII_FAMILY
975 /* This code only works on ASCII machines where the keys are stored in ASCII order */
976 if(strcmp(test
,key
)) {
977 /* The first difference usually implies the place where things get out of sync */
978 log_err("FAIL Country diff at offset %d, \"%s\" != \"%s\"\n", count
, test
, key
);
981 if(!strcmp(test
,"FX"))
982 log_err("FAIL getISOCountries() has obsolete country code %s\n", test
);
983 if(!strcmp(test
,"YU"))
984 log_err("FAIL getISOCountries() has obsolete country code %s\n", test
);
985 if(!strcmp(test
,"ZR"))
986 log_err("FAIL getISOCountries() has obsolete country code %s\n", test
);
989 ures_getNextString(subRes
, NULL
, &key
, &status
);
990 if (strcmp(key
, "ZZ") != 0) {
991 log_err("ZZ was expected to be the last entry in structLocale, but got %s\n", key
);
993 #if U_CHARSET_FAMILY==U_EBCDIC_FAMILY
994 /* On EBCDIC machines, the numbers are sorted last. Account for those in the skipped value too. */
997 /* Skip over numeric UN tags. uloc_getISOCountries only returns ISO-3166 codes. */
998 skipped
+= (key
!= NULL
);
999 ures_getNextString(subRes
, NULL
, &key
, &status
);
1001 while (U_SUCCESS(status
) && key
!= NULL
&& strlen(key
) != 2);
1003 expect
-= skipped
; /* Ignore the skipped resources from structLocale */
1006 log_err("There is an error in getISOCountries, got %d, expected %d \n", count
, expect
);
1012 static void setUpDataTable()
1015 dataTable
= (UChar
***)(calloc(sizeof(UChar
**),LOCALE_INFO_SIZE
));
1017 for (i
= 0; i
< LOCALE_INFO_SIZE
; i
++) {
1018 dataTable
[i
] = (UChar
**)(calloc(sizeof(UChar
*),LOCALE_SIZE
));
1019 for (j
= 0; j
< LOCALE_SIZE
; j
++){
1020 dataTable
[i
][j
] = CharsToUChars(rawData2
[i
][j
]);
1025 static void cleanUpDataTable()
1028 if(dataTable
!= NULL
) {
1029 for (i
=0; i
<LOCALE_INFO_SIZE
; i
++) {
1030 for(j
= 0; j
< LOCALE_SIZE
; j
++) {
1031 free(dataTable
[i
][j
]);
1041 * @bug 4011756 4011380
1043 static void TestISO3Fallback()
1045 const char* test
="xx_YY";
1047 const char * result
;
1049 result
= uloc_getISO3Language(test
);
1051 /* Conform to C API usage */
1053 if (!result
|| (result
[0] != 0))
1054 log_err("getISO3Language() on xx_YY returned %s instead of \"\"");
1056 result
= uloc_getISO3Country(test
);
1058 if (!result
|| (result
[0] != 0))
1059 log_err("getISO3Country() on xx_YY returned %s instead of \"\"");
1065 static void TestSimpleDisplayNames()
1068 This test is different from TestDisplayNames because TestDisplayNames checks
1069 fallback behavior, combination of language and country names to form locale
1070 names, and other stuff like that. This test just checks specific language
1071 and country codes to make sure we have the correct names for them.
1073 char languageCodes
[] [4] = { "he", "id", "iu", "ug", "yi", "za", "419" };
1074 const char* languageNames
[] = { "Hebrew", "Indonesian", "Inuktitut", "Uighur", "Yiddish",
1076 const char* inLocale
[] = { "en_US", "zh_Hant"};
1077 UErrorCode status
=U_ZERO_ERROR
;
1080 int32_t localeIndex
= 0;
1081 for (i
= 0; i
< 7; i
++) {
1083 UChar
*expectedLang
=0;
1087 localeIndex
= 1; /* Use the second locale for the rest of the test. */
1090 size
=uloc_getDisplayLanguage(languageCodes
[i
], inLocale
[localeIndex
], NULL
, size
, &status
);
1091 if(status
==U_BUFFER_OVERFLOW_ERROR
) {
1092 status
=U_ZERO_ERROR
;
1093 testLang
=(UChar
*)malloc(sizeof(UChar
) * (size
+ 1));
1094 uloc_getDisplayLanguage(languageCodes
[i
], inLocale
[localeIndex
], testLang
, size
+ 1, &status
);
1096 expectedLang
=(UChar
*)malloc(sizeof(UChar
) * (strlen(languageNames
[i
])+1));
1097 u_uastrcpy(expectedLang
, languageNames
[i
]);
1098 if (u_strcmp(testLang
, expectedLang
) != 0)
1099 log_data_err("Got wrong display name for %s : Expected \"%s\", got \"%s\".\n",
1100 languageCodes
[i
], languageNames
[i
], austrdup(testLang
));
1110 static void TestUninstalledISO3Names()
1112 /* This test checks to make sure getISO3Language and getISO3Country work right
1113 even for locales that are not installed. */
1114 static const char iso2Languages
[][4] = { "am", "ba", "fy", "mr", "rn",
1116 static const char iso3Languages
[][5] = { "amh", "bak", "fry", "mar", "run",
1117 "ssw", "twi", "zul" };
1118 static const char iso2Countries
[][6] = { "am_AF", "ba_BW", "fy_KZ", "mr_MO", "rn_MN",
1119 "ss_SB", "tw_TC", "zu_ZW" };
1120 static const char iso3Countries
[][4] = { "AFG", "BWA", "KAZ", "MAC", "MNG",
1121 "SLB", "TCA", "ZWE" };
1124 for (i
= 0; i
< 8; i
++) {
1125 UErrorCode err
= U_ZERO_ERROR
;
1127 test
= uloc_getISO3Language(iso2Languages
[i
]);
1128 if(strcmp(test
, iso3Languages
[i
]) !=0 || U_FAILURE(err
))
1129 log_err("Got wrong ISO3 code for %s : Expected \"%s\", got \"%s\". %s\n",
1130 iso2Languages
[i
], iso3Languages
[i
], test
, myErrorName(err
));
1132 for (i
= 0; i
< 8; i
++) {
1133 UErrorCode err
= U_ZERO_ERROR
;
1135 test
= uloc_getISO3Country(iso2Countries
[i
]);
1136 if(strcmp(test
, iso3Countries
[i
]) !=0 || U_FAILURE(err
))
1137 log_err("Got wrong ISO3 code for %s : Expected \"%s\", got \"%s\". %s\n",
1138 iso2Countries
[i
], iso3Countries
[i
], test
, myErrorName(err
));
1143 static void TestVariantParsing()
1145 static const char* en_US_custom
="en_US_De Anza_Cupertino_California_United States_Earth";
1146 static const char* dispName
="English (United States, DE ANZA_CUPERTINO_CALIFORNIA_UNITED STATES_EARTH)";
1147 static const char* dispVar
="DE ANZA_CUPERTINO_CALIFORNIA_UNITED STATES_EARTH";
1148 static const char* shortVariant
="fr_FR_foo";
1149 static const char* bogusVariant
="fr_FR__foo";
1150 static const char* bogusVariant2
="fr_FR_foo_";
1151 static const char* bogusVariant3
="fr_FR__foo_";
1154 UChar displayVar
[100];
1155 UChar displayName
[100];
1156 UErrorCode status
=U_ZERO_ERROR
;
1159 size
=uloc_getDisplayVariant(en_US_custom
, "en_US", NULL
, size
, &status
);
1160 if(status
==U_BUFFER_OVERFLOW_ERROR
) {
1161 status
=U_ZERO_ERROR
;
1162 got
=(UChar
*)realloc(got
, sizeof(UChar
) * (size
+1));
1163 uloc_getDisplayVariant(en_US_custom
, "en_US", got
, size
+ 1, &status
);
1166 log_err("FAIL: Didn't get U_BUFFER_OVERFLOW_ERROR\n");
1168 u_uastrcpy(displayVar
, dispVar
);
1169 if(u_strcmp(got
,displayVar
)!=0) {
1170 log_err("FAIL: getDisplayVariant() Wanted %s, got %s\n", dispVar
, austrdup(got
));
1173 size
=uloc_getDisplayName(en_US_custom
, "en_US", NULL
, size
, &status
);
1174 if(status
==U_BUFFER_OVERFLOW_ERROR
) {
1175 status
=U_ZERO_ERROR
;
1176 got
=(UChar
*)realloc(got
, sizeof(UChar
) * (size
+1));
1177 uloc_getDisplayName(en_US_custom
, "en_US", got
, size
+ 1, &status
);
1180 log_err("FAIL: Didn't get U_BUFFER_OVERFLOW_ERROR\n");
1182 u_uastrcpy(displayName
, dispName
);
1183 if(u_strcmp(got
,displayName
)!=0) {
1184 if (status
== U_USING_DEFAULT_WARNING
) {
1185 log_data_err("FAIL: getDisplayName() got %s. Perhaps you are missing data?\n", u_errorName(status
));
1187 log_err("FAIL: getDisplayName() Wanted %s, got %s\n", dispName
, austrdup(got
));
1192 status
=U_ZERO_ERROR
;
1193 size
=uloc_getDisplayVariant(shortVariant
, NULL
, NULL
, size
, &status
);
1194 if(status
==U_BUFFER_OVERFLOW_ERROR
) {
1195 status
=U_ZERO_ERROR
;
1196 got
=(UChar
*)realloc(got
, sizeof(UChar
) * (size
+1));
1197 uloc_getDisplayVariant(shortVariant
, NULL
, got
, size
+ 1, &status
);
1200 log_err("FAIL: Didn't get U_BUFFER_OVERFLOW_ERROR\n");
1202 if(strcmp(austrdup(got
),"FOO")!=0) {
1203 log_err("FAIL: getDisplayVariant() Wanted: foo Got: %s\n", austrdup(got
));
1206 status
=U_ZERO_ERROR
;
1207 size
=uloc_getDisplayVariant(bogusVariant
, NULL
, NULL
, size
, &status
);
1208 if(status
==U_BUFFER_OVERFLOW_ERROR
) {
1209 status
=U_ZERO_ERROR
;
1210 got
=(UChar
*)realloc(got
, sizeof(UChar
) * (size
+1));
1211 uloc_getDisplayVariant(bogusVariant
, NULL
, got
, size
+ 1, &status
);
1214 log_err("FAIL: Didn't get U_BUFFER_OVERFLOW_ERROR\n");
1216 if(strcmp(austrdup(got
),"_FOO")!=0) {
1217 log_err("FAIL: getDisplayVariant() Wanted: _FOO Got: %s\n", austrdup(got
));
1220 status
=U_ZERO_ERROR
;
1221 size
=uloc_getDisplayVariant(bogusVariant2
, NULL
, NULL
, size
, &status
);
1222 if(status
==U_BUFFER_OVERFLOW_ERROR
) {
1223 status
=U_ZERO_ERROR
;
1224 got
=(UChar
*)realloc(got
, sizeof(UChar
) * (size
+1));
1225 uloc_getDisplayVariant(bogusVariant2
, NULL
, got
, size
+ 1, &status
);
1228 log_err("FAIL: Didn't get U_BUFFER_OVERFLOW_ERROR\n");
1230 if(strcmp(austrdup(got
),"FOO_")!=0) {
1231 log_err("FAIL: getDisplayVariant() Wanted: FOO_ Got: %s\n", austrdup(got
));
1234 status
=U_ZERO_ERROR
;
1235 size
=uloc_getDisplayVariant(bogusVariant3
, NULL
, NULL
, size
, &status
);
1236 if(status
==U_BUFFER_OVERFLOW_ERROR
) {
1237 status
=U_ZERO_ERROR
;
1238 got
=(UChar
*)realloc(got
, sizeof(UChar
) * (size
+1));
1239 uloc_getDisplayVariant(bogusVariant3
, NULL
, got
, size
+ 1, &status
);
1242 log_err("FAIL: Didn't get U_BUFFER_OVERFLOW_ERROR\n");
1244 if(strcmp(austrdup(got
),"_FOO_")!=0) {
1245 log_err("FAIL: getDisplayVariant() Wanted: _FOO_ Got: %s\n", austrdup(got
));
1251 static void TestObsoleteNames(void)
1254 UErrorCode status
= U_ZERO_ERROR
;
1266 { "eng_USA", "eng", "en", "USA", "US" },
1267 { "kok", "kok", "kok", "", "" },
1268 { "in", "ind", "in", "", "" },
1269 { "id", "ind", "id", "", "" }, /* NO aliasing */
1270 { "sh", "srp", "sh", "", "" },
1271 { "zz_CS", "", "zz", "SCG", "CS" },
1272 { "zz_FX", "", "zz", "FXX", "FX" },
1273 { "zz_RO", "", "zz", "ROU", "RO" },
1274 { "zz_TP", "", "zz", "TMP", "TP" },
1275 { "zz_TL", "", "zz", "TLS", "TL" },
1276 { "zz_ZR", "", "zz", "ZAR", "ZR" },
1277 { "zz_FXX", "", "zz", "FXX", "FX" }, /* no aliasing. Doesn't go to PS(PSE). */
1278 { "zz_ROM", "", "zz", "ROU", "RO" },
1279 { "zz_ROU", "", "zz", "ROU", "RO" },
1280 { "zz_ZAR", "", "zz", "ZAR", "ZR" },
1281 { "zz_TMP", "", "zz", "TMP", "TP" },
1282 { "zz_TLS", "", "zz", "TLS", "TL" },
1283 { "zz_YUG", "", "zz", "YUG", "YU" },
1284 { "mlt_PSE", "mlt", "mt", "PSE", "PS" },
1285 { "iw", "heb", "iw", "", "" },
1286 { "ji", "yid", "ji", "", "" },
1287 { "jw", "jaw", "jw", "", "" },
1288 { "sh", "srp", "sh", "", "" },
1289 { "", "", "", "", "" }
1292 for(i
=0;tests
[i
].locale
[0];i
++)
1296 locale
= tests
[i
].locale
;
1297 log_verbose("** %s:\n", locale
);
1299 status
= U_ZERO_ERROR
;
1300 if(strcmp(tests
[i
].lang3
,uloc_getISO3Language(locale
)))
1302 log_err("FAIL: uloc_getISO3Language(%s)==\t\"%s\",\t expected \"%s\"\n",
1303 locale
, uloc_getISO3Language(locale
), tests
[i
].lang3
);
1307 log_verbose(" uloc_getISO3Language()==\t\"%s\"\n",
1308 uloc_getISO3Language(locale
) );
1311 status
= U_ZERO_ERROR
;
1312 uloc_getLanguage(locale
, buff
, 256, &status
);
1313 if(U_FAILURE(status
))
1315 log_err("FAIL: error getting language from %s\n", locale
);
1319 if(strcmp(buff
,tests
[i
].lang
))
1321 log_err("FAIL: uloc_getLanguage(%s)==\t\"%s\"\t expected \"%s\"\n",
1322 locale
, buff
, tests
[i
].lang
);
1326 log_verbose(" uloc_getLanguage(%s)==\t%s\n", locale
, buff
);
1329 if(strcmp(tests
[i
].lang3
,uloc_getISO3Language(locale
)))
1331 log_err("FAIL: uloc_getISO3Language(%s)==\t\"%s\",\t expected \"%s\"\n",
1332 locale
, uloc_getISO3Language(locale
), tests
[i
].lang3
);
1336 log_verbose(" uloc_getISO3Language()==\t\"%s\"\n",
1337 uloc_getISO3Language(locale
) );
1340 if(strcmp(tests
[i
].ctry3
,uloc_getISO3Country(locale
)))
1342 log_err("FAIL: uloc_getISO3Country(%s)==\t\"%s\",\t expected \"%s\"\n",
1343 locale
, uloc_getISO3Country(locale
), tests
[i
].ctry3
);
1347 log_verbose(" uloc_getISO3Country()==\t\"%s\"\n",
1348 uloc_getISO3Country(locale
) );
1351 status
= U_ZERO_ERROR
;
1352 uloc_getCountry(locale
, buff
, 256, &status
);
1353 if(U_FAILURE(status
))
1355 log_err("FAIL: error getting country from %s\n", locale
);
1359 if(strcmp(buff
,tests
[i
].ctry
))
1361 log_err("FAIL: uloc_getCountry(%s)==\t\"%s\"\t expected \"%s\"\n",
1362 locale
, buff
, tests
[i
].ctry
);
1366 log_verbose(" uloc_getCountry(%s)==\t%s\n", locale
, buff
);
1371 if (uloc_getLCID("iw_IL") != uloc_getLCID("he_IL")) {
1372 log_err("he,iw LCID mismatch: %X versus %X\n", uloc_getLCID("iw_IL"), uloc_getLCID("he_IL"));
1375 if (uloc_getLCID("iw") != uloc_getLCID("he")) {
1376 log_err("he,iw LCID mismatch: %X versus %X\n", uloc_getLCID("iw"), uloc_getLCID("he"));
1381 i
= uloc_getLanguage("kok",NULL
,0,&icu_err
);
1382 if(U_FAILURE(icu_err
))
1384 log_err("FAIL: Got %s trying to do uloc_getLanguage(kok)\n", u_errorName(icu_err
));
1387 icu_err
= U_ZERO_ERROR
;
1388 uloc_getLanguage("kok",r1_buff
,12,&icu_err
);
1389 if(U_FAILURE(icu_err
))
1391 log_err("FAIL: Got %s trying to do uloc_getLanguage(kok, buff)\n", u_errorName(icu_err
));
1394 r1_addr
= (char *)uloc_getISO3Language("kok");
1396 icu_err
= U_ZERO_ERROR
;
1397 if (strcmp(r1_buff
,"kok") != 0)
1399 log_err("FAIL: uloc_getLanguage(kok)==%s not kok\n",r1_buff
);
1402 r1_addr
= (char *)uloc_getISO3Language("in");
1403 i
= uloc_getLanguage(r1_addr
,r1_buff
,12,&icu_err
);
1404 if (strcmp(r1_buff
,"id") != 0)
1406 printf("uloc_getLanguage error (%s)\n",r1_buff
);
1409 r1_addr
= (char *)uloc_getISO3Language("sh");
1410 i
= uloc_getLanguage(r1_addr
,r1_buff
,12,&icu_err
);
1411 if (strcmp(r1_buff
,"sr") != 0)
1413 printf("uloc_getLanguage error (%s)\n",r1_buff
);
1417 r1_addr
= (char *)uloc_getISO3Country("zz_ZR");
1418 strcpy(p1_buff
,"zz_");
1419 strcat(p1_buff
,r1_addr
);
1420 i
= uloc_getCountry(p1_buff
,r1_buff
,12,&icu_err
);
1421 if (strcmp(r1_buff
,"ZR") != 0)
1423 printf("uloc_getCountry error (%s)\n",r1_buff
);
1426 r1_addr
= (char *)uloc_getISO3Country("zz_FX");
1427 strcpy(p1_buff
,"zz_");
1428 strcat(p1_buff
,r1_addr
);
1429 i
= uloc_getCountry(p1_buff
,r1_buff
,12,&icu_err
);
1430 if (strcmp(r1_buff
,"FX") != 0)
1432 printf("uloc_getCountry error (%s)\n",r1_buff
);
1440 static void TestKeywordVariants(void)
1442 static const struct {
1443 const char *localeID
;
1444 const char *expectedLocaleID
;
1445 const char *expectedLocaleIDNoKeywords
;
1446 const char *expectedCanonicalID
;
1447 const char *expectedKeywords
[10];
1448 int32_t numKeywords
;
1449 UErrorCode expectedStatus
; /* from uloc_openKeywords */
1452 "de_DE@ currency = euro; C o ll A t i o n = Phonebook ; C alen dar = buddhist ",
1453 "de_DE@calendar=buddhist;collation=Phonebook;currency=euro",
1455 "de_DE@calendar=buddhist;collation=Phonebook;currency=euro",
1456 {"calendar", "collation", "currency"},
1464 "de_DE@currency=EUR",
1465 {"","","","","","",""},
1467 U_INVALID_FORMAT_ERROR
/* must have '=' after '@' */
1470 "de_DE@euro;collation=phonebook",
1471 "de_DE", /* error result; bad format */
1472 "de_DE", /* error result; bad format */
1473 "de_DE", /* error result; bad format */
1474 {"","","","","","",""},
1476 U_INVALID_FORMAT_ERROR
1479 UErrorCode status
= U_ZERO_ERROR
;
1481 int32_t i
= 0, j
= 0;
1482 int32_t resultLen
= 0;
1484 UEnumeration
*keywords
;
1485 int32_t keyCount
= 0;
1486 const char *keyword
= NULL
;
1487 int32_t keywordLen
= 0;
1489 for(i
= 0; i
< sizeof(testCases
)/sizeof(testCases
[0]); i
++) {
1490 status
= U_ZERO_ERROR
;
1492 keywords
= uloc_openKeywords(testCases
[i
].localeID
, &status
);
1494 if(status
!= testCases
[i
].expectedStatus
) {
1495 log_err("Expected to uloc_openKeywords(\"%s\") => status %s. Got %s instead\n",
1496 testCases
[i
].localeID
,
1497 u_errorName(testCases
[i
].expectedStatus
), u_errorName(status
));
1499 status
= U_ZERO_ERROR
;
1501 if((keyCount
= uenum_count(keywords
, &status
)) != testCases
[i
].numKeywords
) {
1502 log_err("Expected to get %i keywords, got %i\n", testCases
[i
].numKeywords
, keyCount
);
1506 while((keyword
= uenum_next(keywords
, &keywordLen
, &status
))) {
1507 if(strcmp(keyword
, testCases
[i
].expectedKeywords
[j
]) != 0) {
1508 log_err("Expected to get keyword value %s, got %s\n", testCases
[i
].expectedKeywords
[j
], keyword
);
1513 uenum_reset(keywords
, &status
);
1514 while((keyword
= uenum_next(keywords
, &keywordLen
, &status
))) {
1515 if(strcmp(keyword
, testCases
[i
].expectedKeywords
[j
]) != 0) {
1516 log_err("Expected to get keyword value %s, got %s\n", testCases
[i
].expectedKeywords
[j
], keyword
);
1521 uenum_close(keywords
);
1523 resultLen
= uloc_getName(testCases
[i
].localeID
, buffer
, 256, &status
);
1524 if (uprv_strcmp(testCases
[i
].expectedLocaleID
, buffer
) != 0) {
1525 log_err("Expected uloc_getName(\"%s\") => \"%s\"; got \"%s\"\n",
1526 testCases
[i
].localeID
, testCases
[i
].expectedLocaleID
, buffer
);
1528 resultLen
= uloc_canonicalize(testCases
[i
].localeID
, buffer
, 256, &status
);
1529 if (uprv_strcmp(testCases
[i
].expectedCanonicalID
, buffer
) != 0) {
1530 log_err("Expected uloc_canonicalize(\"%s\") => \"%s\"; got \"%s\"\n",
1531 testCases
[i
].localeID
, testCases
[i
].expectedCanonicalID
, buffer
);
1537 static void TestKeywordVariantParsing(void)
1539 static const struct {
1540 const char *localeID
;
1541 const char *keyword
;
1542 const char *expectedValue
;
1544 { "de_DE@ C o ll A t i o n = Phonebook ", "c o ll a t i o n", "Phonebook" },
1545 { "de_DE", "collation", ""},
1546 { "de_DE@collation=PHONEBOOK", "collation", "PHONEBOOK" },
1547 { "de_DE@currency = euro; CoLLaTion = PHONEBOOk", "collatiON", "PHONEBOOk" },
1550 UErrorCode status
= U_ZERO_ERROR
;
1553 int32_t resultLen
= 0;
1556 for(i
= 0; i
< sizeof(testCases
)/sizeof(testCases
[0]); i
++) {
1558 resultLen
= uloc_getKeywordValue(testCases
[i
].localeID
, testCases
[i
].keyword
, buffer
, 256, &status
);
1559 if(uprv_strcmp(testCases
[i
].expectedValue
, buffer
) != 0) {
1560 log_err("Expected to extract \"%s\" from \"%s\" for keyword \"%s\". Got \"%s\" instead\n",
1561 testCases
[i
].expectedValue
, testCases
[i
].localeID
, testCases
[i
].keyword
, buffer
);
1566 static const struct {
1567 const char *l
; /* locale */
1568 const char *k
; /* kw */
1569 const char *v
; /* value */
1570 const char *x
; /* expected */
1571 } kwSetTestCases
[] = {
1573 { "en_US", "calendar", "japanese", "en_US@calendar=japanese" },
1574 { "en_US@", "calendar", "japanese", "en_US@calendar=japanese" },
1575 { "en_US@calendar=islamic", "calendar", "japanese", "en_US@calendar=japanese" },
1576 { "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 */
1577 { "en_US@calendar=gregorian", "calendar", "japanese", "en_US@calendar=japanese" },
1578 { "de", "Currency", "CHF", "de@currency=CHF" },
1579 { "de", "Currency", "CHF", "de@currency=CHF" },
1581 { "en_US@collation=phonebook", "calendar", "japanese", "en_US@calendar=japanese;collation=phonebook" },
1582 { "en_US@calendar=japanese", "collation", "phonebook", "en_US@calendar=japanese;collation=phonebook" },
1583 { "de@collation=phonebook", "Currency", "CHF", "de@collation=phonebook;currency=CHF" },
1584 { "en_US@calendar=gregorian;collation=phonebook", "calendar", "japanese", "en_US@calendar=japanese;collation=phonebook" },
1585 { "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 */
1586 { "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 */
1587 { "en_US@calendar=islamic;collation=phonebook", "calendar", "japanese", "en_US@calendar=japanese;collation=phonebook" },
1588 { "de@collation=phonebook", "Currency", "CHF", "de@collation=phonebook;currency=CHF" },
1591 { "mt@a=0;b=1;c=2;d=3", "c","j", "mt@a=0;b=1;c=j;d=3" },
1592 { "mt@a=0;b=1;c=2;d=3", "x","j", "mt@a=0;b=1;c=2;d=3;x=j" },
1593 { "mt@a=0;b=1;c=2;d=3", "a","f", "mt@a=f;b=1;c=2;d=3" },
1594 { "mt@a=0;aa=1;aaa=3", "a","x", "mt@a=x;aa=1;aaa=3" },
1595 { "mt@a=0;aa=1;aaa=3", "aa","x", "mt@a=0;aa=x;aaa=3" },
1596 { "mt@a=0;aa=1;aaa=3", "aaa","x", "mt@a=0;aa=1;aaa=x" },
1597 { "mt@a=0;aa=1;aaa=3", "a","yy", "mt@a=yy;aa=1;aaa=3" },
1598 { "mt@a=0;aa=1;aaa=3", "aa","yy", "mt@a=0;aa=yy;aaa=3" },
1599 { "mt@a=0;aa=1;aaa=3", "aaa","yy", "mt@a=0;aa=1;aaa=yy" },
1603 /* 1. removal of item at end */
1604 { "de@collation=phonebook;currency=CHF", "currency", "", "de@collation=phonebook" },
1605 { "de@collation=phonebook;currency=CHF", "currency", NULL
, "de@collation=phonebook" },
1606 /* 2. removal of item at beginning */
1607 { "de@collation=phonebook;currency=CHF", "collation", "", "de@currency=CHF" },
1608 { "de@collation=phonebook;currency=CHF", "collation", NULL
, "de@currency=CHF" },
1609 /* 3. removal of an item not there */
1610 { "de@collation=phonebook;currency=CHF", "calendar", NULL
, "de@collation=phonebook;currency=CHF" },
1611 /* 4. removal of only item */
1612 { "de@collation=phonebook", "collation", NULL
, "de" },
1614 { "de@collation=phonebook", "Currency", "CHF", "de@collation=phonebook;currency=CHF" }
1618 static void TestKeywordSet(void)
1621 int32_t resultLen
= 0;
1626 for(i
= 0; i
< sizeof(kwSetTestCases
)/sizeof(kwSetTestCases
[0]); i
++) {
1627 UErrorCode status
= U_ZERO_ERROR
;
1628 memset(buffer
,'%',1023);
1629 strcpy(buffer
, kwSetTestCases
[i
].l
);
1631 uloc_canonicalize(kwSetTestCases
[i
].l
, cbuffer
, 1023, &status
);
1632 if(strcmp(buffer
,cbuffer
)) {
1633 log_verbose("note: [%d] wasn't canonical, should be: '%s' not '%s'. Won't check for canonicity in output.\n", i
, cbuffer
, buffer
);
1635 /* sanity check test case results for canonicity */
1636 uloc_canonicalize(kwSetTestCases
[i
].x
, cbuffer
, 1023, &status
);
1637 if(strcmp(kwSetTestCases
[i
].x
,cbuffer
)) {
1638 log_err("%s:%d: ERROR: kwSetTestCases[%d].x = '%s', should be %s (must be canonical)\n", __FILE__
, __LINE__
, i
, kwSetTestCases
[i
].x
, cbuffer
);
1641 resultLen
= uloc_setKeywordValue(kwSetTestCases
[i
].k
, kwSetTestCases
[i
].v
, buffer
, 1023, &status
);
1642 if(U_FAILURE(status
)) {
1643 log_err("Err on test case %d: got error %s\n", i
, u_errorName(status
));
1646 if(strcmp(buffer
,kwSetTestCases
[i
].x
) || ((int32_t)strlen(buffer
)!=resultLen
)) {
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
, resultLen
, 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
,buffer
);
1655 static void TestKeywordSetError(void)
1663 /* 0-test whether an error condition modifies the buffer at all */
1666 memset(buffer
,'%',1023);
1667 status
= U_ZERO_ERROR
;
1668 res
= uloc_setKeywordValue(kwSetTestCases
[i
].k
, kwSetTestCases
[i
].v
, buffer
, blen
, &status
);
1669 if(status
!= U_ILLEGAL_ARGUMENT_ERROR
) {
1670 log_err("expected illegal err got %s\n", u_errorName(status
));
1673 /* if(res!=strlen(kwSetTestCases[i].x)) {
1674 log_err("expected result %d got %d\n", strlen(kwSetTestCases[i].x), res);
1677 if(buffer
[blen
]!='%') {
1678 log_err("Buffer byte %d was modified: now %c\n", blen
, buffer
[blen
]);
1681 log_verbose("0-buffer modify OK\n");
1684 /* 1- test a short buffer with growing text */
1685 blen
=(int32_t)strlen(kwSetTestCases
[i
].l
)+1;
1686 memset(buffer
,'%',1023);
1687 strcpy(buffer
,kwSetTestCases
[i
].l
);
1688 status
= U_ZERO_ERROR
;
1689 res
= uloc_setKeywordValue(kwSetTestCases
[i
].k
, kwSetTestCases
[i
].v
, buffer
, blen
, &status
);
1690 if(status
!= U_BUFFER_OVERFLOW_ERROR
) {
1691 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
);
1694 if(res
!=(int32_t)strlen(kwSetTestCases
[i
].x
)) {
1695 log_err("expected result %d got %d\n", strlen(kwSetTestCases
[i
].x
), res
);
1698 if(buffer
[blen
]!='%') {
1699 log_err("Buffer byte %d was modified: now %c\n", blen
, buffer
[blen
]);
1702 log_verbose("1/%d-buffer modify OK\n",i
);
1706 /* 2- test a short buffer - text the same size or shrinking */
1707 blen
=(int32_t)strlen(kwSetTestCases
[i
].l
)+1;
1708 memset(buffer
,'%',1023);
1709 strcpy(buffer
,kwSetTestCases
[i
].l
);
1710 status
= U_ZERO_ERROR
;
1711 res
= uloc_setKeywordValue(kwSetTestCases
[i
].k
, kwSetTestCases
[i
].v
, buffer
, blen
, &status
);
1712 if(status
!= U_ZERO_ERROR
) {
1713 log_err("expected zero error got %s\n", u_errorName(status
));
1716 if(buffer
[blen
+1]!='%') {
1717 log_err("Buffer byte %d was modified: now %c\n", blen
+1, buffer
[blen
+1]);
1720 if(res
!=(int32_t)strlen(kwSetTestCases
[i
].x
)) {
1721 log_err("expected result %d got %d\n", strlen(kwSetTestCases
[i
].x
), res
);
1724 if(strcmp(buffer
,kwSetTestCases
[i
].x
) || ((int32_t)strlen(buffer
)!=res
)) {
1725 log_err("FAIL: #%d: %s + [%s=%s] -> %s (%d) expected %s (%d)\n", i
, kwSetTestCases
[i
].l
, kwSetTestCases
[i
].k
,
1726 kwSetTestCases
[i
].v
, buffer
, res
, kwSetTestCases
[i
].x
, strlen(buffer
));
1728 log_verbose("pass: #%d: %s + [%s=%s] -> %s\n", i
, kwSetTestCases
[i
].l
, kwSetTestCases
[i
].k
, kwSetTestCases
[i
].v
,
1731 log_verbose("2/%d-buffer modify OK\n",i
);
1735 static int32_t _canonicalize(int32_t selector
, /* 0==getName, 1==canonicalize */
1736 const char* localeID
,
1738 int32_t resultCapacity
,
1740 /* YOU can change this to use function pointers if you like */
1743 return uloc_getName(localeID
, result
, resultCapacity
, ec
);
1745 return uloc_canonicalize(localeID
, result
, resultCapacity
, ec
);
1751 static void TestCanonicalization(void)
1753 static const struct {
1754 const char *localeID
; /* input */
1755 const char *getNameID
; /* expected getName() result */
1756 const char *canonicalID
; /* expected canonicalize() result */
1758 { "ca_ES_PREEURO-with-extra-stuff-that really doesn't make any sense-unless-you're trying to increase code coverage",
1759 "ca_ES_PREEURO_WITH_EXTRA_STUFF_THAT REALLY DOESN'T MAKE ANY SENSE_UNLESS_YOU'RE TRYING TO INCREASE CODE COVERAGE",
1760 "ca_ES_PREEURO_WITH_EXTRA_STUFF_THAT REALLY DOESN'T MAKE ANY SENSE_UNLESS_YOU'RE TRYING TO INCREASE CODE COVERAGE"},
1761 { "ca_ES_PREEURO", "ca_ES_PREEURO", "ca_ES@currency=ESP" },
1762 { "de_AT_PREEURO", "de_AT_PREEURO", "de_AT@currency=ATS" },
1763 { "de_DE_PREEURO", "de_DE_PREEURO", "de_DE@currency=DEM" },
1764 { "de_LU_PREEURO", "de_LU_PREEURO", "de_LU@currency=LUF" },
1765 { "el_GR_PREEURO", "el_GR_PREEURO", "el_GR@currency=GRD" },
1766 { "en_BE_PREEURO", "en_BE_PREEURO", "en_BE@currency=BEF" },
1767 { "en_IE_PREEURO", "en_IE_PREEURO", "en_IE@currency=IEP" },
1768 { "es_ES_PREEURO", "es_ES_PREEURO", "es_ES@currency=ESP" },
1769 { "eu_ES_PREEURO", "eu_ES_PREEURO", "eu_ES@currency=ESP" },
1770 { "fi_FI_PREEURO", "fi_FI_PREEURO", "fi_FI@currency=FIM" },
1771 { "fr_BE_PREEURO", "fr_BE_PREEURO", "fr_BE@currency=BEF" },
1772 { "fr_FR_PREEURO", "fr_FR_PREEURO", "fr_FR@currency=FRF" },
1773 { "fr_LU_PREEURO", "fr_LU_PREEURO", "fr_LU@currency=LUF" },
1774 { "ga_IE_PREEURO", "ga_IE_PREEURO", "ga_IE@currency=IEP" },
1775 { "gl_ES_PREEURO", "gl_ES_PREEURO", "gl_ES@currency=ESP" },
1776 { "it_IT_PREEURO", "it_IT_PREEURO", "it_IT@currency=ITL" },
1777 { "nl_BE_PREEURO", "nl_BE_PREEURO", "nl_BE@currency=BEF" },
1778 { "nl_NL_PREEURO", "nl_NL_PREEURO", "nl_NL@currency=NLG" },
1779 { "pt_PT_PREEURO", "pt_PT_PREEURO", "pt_PT@currency=PTE" },
1780 { "de__PHONEBOOK", "de__PHONEBOOK", "de@collation=phonebook" },
1781 { "en_GB_EURO", "en_GB_EURO", "en_GB@currency=EUR" },
1782 { "en_GB@EURO", "en_GB@EURO", "en_GB@currency=EUR" }, /* POSIX ID */
1783 { "es__TRADITIONAL", "es__TRADITIONAL", "es@collation=traditional" },
1784 { "hi__DIRECT", "hi__DIRECT", "hi@collation=direct" },
1785 { "ja_JP_TRADITIONAL", "ja_JP_TRADITIONAL", "ja_JP@calendar=japanese" },
1786 { "th_TH_TRADITIONAL", "th_TH_TRADITIONAL", "th_TH@calendar=buddhist" },
1787 { "zh_TW_STROKE", "zh_TW_STROKE", "zh_TW@collation=stroke" },
1788 { "zh__PINYIN", "zh__PINYIN", "zh@collation=pinyin" },
1789 { "zh@collation=pinyin", "zh@collation=pinyin", "zh@collation=pinyin" },
1790 { "zh_CN@collation=pinyin", "zh_CN@collation=pinyin", "zh_CN@collation=pinyin" },
1791 { "zh_CN_STROKE", "zh_CN_STROKE", "zh_CN@collation=stroke" },
1792 { "zh_CN_CA@collation=pinyin", "zh_CN_CA@collation=pinyin", "zh_CN_CA@collation=pinyin" },
1793 { "en_US_POSIX", "en_US_POSIX", "en_US_POSIX" },
1794 { "hy_AM_REVISED", "hy_AM_REVISED", "hy_AM_REVISED" },
1795 { "no_NO_NY", "no_NO_NY", "no_NO_NY" /* not: "nn_NO" [alan ICU3.0] */ },
1796 { "no@ny", "no@ny", "no__NY" /* not: "nn" [alan ICU3.0] */ }, /* POSIX ID */
1797 { "no-no.utf32@B", "no_NO.utf32@B", "no_NO_B" /* not: "nb_NO_B" [alan ICU3.0] */ }, /* POSIX ID */
1798 { "qz-qz@Euro", "qz_QZ@Euro", "qz_QZ@currency=EUR" }, /* qz-qz uses private use iso codes */
1799 { "en-BOONT", "en_BOONT", "en__BOONT" }, /* registered name */
1800 { "de-1901", "de_1901", "de__1901" }, /* registered name */
1801 { "de-1906", "de_1906", "de__1906" }, /* registered name */
1802 { "sr-SP-Cyrl", "sr_SP_CYRL", "sr_Cyrl_RS" }, /* .NET name */
1803 { "sr-SP-Latn", "sr_SP_LATN", "sr_Latn_RS" }, /* .NET name */
1804 { "sr_YU_CYRILLIC", "sr_YU_CYRILLIC", "sr_Cyrl_RS" }, /* Linux name */
1805 { "uz-UZ-Cyrl", "uz_UZ_CYRL", "uz_Cyrl_UZ" }, /* .NET name */
1806 { "uz-UZ-Latn", "uz_UZ_LATN", "uz_Latn_UZ" }, /* .NET name */
1807 { "zh-CHS", "zh_CHS", "zh_Hans" }, /* .NET name */
1808 { "zh-CHT", "zh_CHT", "zh_Hant" }, /* .NET name This may change back to zh_Hant */
1810 /* posix behavior that used to be performed by getName */
1811 { "mr.utf8", "mr.utf8", "mr" },
1812 { "de-tv.koi8r", "de_TV.koi8r", "de_TV" },
1813 { "x-piglatin_ML.MBE", "x-piglatin_ML.MBE", "x-piglatin_ML" },
1814 { "i-cherokee_US.utf7", "i-cherokee_US.utf7", "i-cherokee_US" },
1815 { "x-filfli_MT_FILFLA.gb-18030", "x-filfli_MT_FILFLA.gb-18030", "x-filfli_MT_FILFLA" },
1816 { "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 */
1818 /* fleshing out canonicalization */
1819 /* trim space and sort keywords, ';' is separator so not present at end in canonical form */
1820 { "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" },
1821 /* already-canonical ids are not changed */
1822 { "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" },
1823 /* PRE_EURO and EURO conversions don't affect other keywords */
1824 { "es_ES_PREEURO@CALendar=Japanese", "es_ES_PREEURO@calendar=Japanese", "es_ES@calendar=Japanese;currency=ESP" },
1825 { "es_ES_EURO@SHOUT=zipeedeedoodah", "es_ES_EURO@shout=zipeedeedoodah", "es_ES@currency=EUR;shout=zipeedeedoodah" },
1826 /* currency keyword overrides PRE_EURO and EURO currency */
1827 { "es_ES_PREEURO@currency=EUR", "es_ES_PREEURO@currency=EUR", "es_ES@currency=EUR" },
1828 { "es_ES_EURO@currency=ESP", "es_ES_EURO@currency=ESP", "es_ES@currency=ESP" },
1829 /* norwegian is just too weird, if we handle things in their full generality */
1830 { "no-Hant-GB_NY@currency=$$$", "no_Hant_GB_NY@currency=$$$", "no_Hant_GB_NY@currency=$$$" /* not: "nn_Hant_GB@currency=$$$" [alan ICU3.0] */ },
1832 /* test cases reflecting internal resource bundle usage */
1833 { "root@kw=foo", "root@kw=foo", "root@kw=foo" },
1834 { "@calendar=gregorian", "@calendar=gregorian", "@calendar=gregorian" },
1835 { "ja_JP@calendar=Japanese", "ja_JP@calendar=Japanese", "ja_JP@calendar=Japanese" },
1836 { "ja_JP", "ja_JP", "ja_JP" },
1838 /* test case for "i-default" */
1839 { "i-default", NULL
, NULL
}
1842 static const char* label
[] = { "getName", "canonicalize" };
1844 UErrorCode status
= U_ZERO_ERROR
;
1845 int32_t i
, j
, resultLen
= 0, origResultLen
;
1848 for (i
=0; i
< sizeof(testCases
)/sizeof(testCases
[0]); i
++) {
1849 for (j
=0; j
<2; ++j
) {
1850 const char* expected
= (j
==0) ? testCases
[i
].getNameID
: testCases
[i
].canonicalID
;
1852 status
= U_ZERO_ERROR
;
1854 if (expected
== NULL
) {
1855 expected
= uloc_getDefault();
1858 /* log_verbose("testing %s -> %s\n", testCases[i], testCases[i].canonicalID); */
1859 origResultLen
= _canonicalize(j
, testCases
[i
].localeID
, NULL
, 0, &status
);
1860 if (status
!= U_BUFFER_OVERFLOW_ERROR
) {
1861 log_err("FAIL: uloc_%s(%s) => %s, expected U_BUFFER_OVERFLOW_ERROR\n",
1862 label
[j
], testCases
[i
].localeID
, u_errorName(status
));
1865 status
= U_ZERO_ERROR
;
1866 resultLen
= _canonicalize(j
, testCases
[i
].localeID
, buffer
, sizeof(buffer
), &status
);
1867 if (U_FAILURE(status
)) {
1868 log_err("FAIL: uloc_%s(%s) => %s, expected U_ZERO_ERROR\n",
1869 label
[j
], testCases
[i
].localeID
, u_errorName(status
));
1872 if(uprv_strcmp(expected
, buffer
) != 0) {
1873 log_err("FAIL: uloc_%s(%s) => \"%s\", expected \"%s\"\n",
1874 label
[j
], testCases
[i
].localeID
, buffer
, expected
);
1876 log_verbose("Ok: uloc_%s(%s) => \"%s\"\n",
1877 label
[j
], testCases
[i
].localeID
, buffer
);
1879 if (resultLen
!= (int32_t)strlen(buffer
)) {
1880 log_err("FAIL: uloc_%s(%s) => len %d, expected len %d\n",
1881 label
[j
], testCases
[i
].localeID
, resultLen
, strlen(buffer
));
1883 if (origResultLen
!= resultLen
) {
1884 log_err("FAIL: uloc_%s(%s) => preflight len %d != actual len %d\n",
1885 label
[j
], testCases
[i
].localeID
, origResultLen
, resultLen
);
1891 static void TestDisplayKeywords(void)
1895 static const struct {
1896 const char *localeID
;
1897 const char *displayLocale
;
1898 UChar displayKeyword
[200];
1900 { "ca_ES@currency=ESP", "de_AT",
1901 {0x0057, 0x00e4, 0x0068, 0x0072, 0x0075, 0x006e, 0x0067, 0x0000},
1903 { "ja_JP@calendar=japanese", "de",
1904 { 0x004b, 0x0061, 0x006c, 0x0065, 0x006e, 0x0064, 0x0065, 0x0072, 0x0000}
1906 { "de_DE@collation=traditional", "de_DE",
1907 {0x0053, 0x006f, 0x0072, 0x0074, 0x0069, 0x0065, 0x0072, 0x0075, 0x006e, 0x0067, 0x0000}
1910 for(i
= 0; i
< sizeof(testCases
)/sizeof(testCases
[0]); i
++) {
1911 UErrorCode status
= U_ZERO_ERROR
;
1912 const char* keyword
=NULL
;
1913 int32_t keywordLen
= 0;
1914 int32_t keywordCount
= 0;
1915 UChar
*displayKeyword
=NULL
;
1916 int32_t displayKeywordLen
= 0;
1917 UEnumeration
* keywordEnum
= uloc_openKeywords(testCases
[i
].localeID
, &status
);
1918 for(keywordCount
= uenum_count(keywordEnum
, &status
); keywordCount
> 0 ; keywordCount
--){
1919 if(U_FAILURE(status
)){
1920 log_err("uloc_getKeywords failed for locale id: %s with error : %s \n", testCases
[i
].localeID
, u_errorName(status
));
1923 /* the uenum_next returns NUL terminated string */
1924 keyword
= uenum_next(keywordEnum
, &keywordLen
, &status
);
1925 /* fetch the displayKeyword */
1926 displayKeywordLen
= uloc_getDisplayKeyword(keyword
, testCases
[i
].displayLocale
, displayKeyword
, displayKeywordLen
, &status
);
1927 if(status
==U_BUFFER_OVERFLOW_ERROR
){
1928 status
= U_ZERO_ERROR
;
1929 displayKeywordLen
++; /* for null termination */
1930 displayKeyword
= (UChar
*) malloc(displayKeywordLen
* U_SIZEOF_UCHAR
);
1931 displayKeywordLen
= uloc_getDisplayKeyword(keyword
, testCases
[i
].displayLocale
, displayKeyword
, displayKeywordLen
, &status
);
1932 if(U_FAILURE(status
)){
1933 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
));
1936 if(u_strncmp(displayKeyword
, testCases
[i
].displayKeyword
, displayKeywordLen
)!=0){
1937 if (status
== U_USING_DEFAULT_WARNING
) {
1938 log_data_err("uloc_getDisplayKeyword did not get the expected value for keyword : %s in locale id: %s for display locale: %s . Got error: %s. Perhaps you are missing data?\n", testCases
[i
].localeID
, keyword
, testCases
[i
].displayLocale
, u_errorName(status
));
1940 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
);
1945 log_err("uloc_getDisplayKeyword did not return the expected error. Error: %s\n", u_errorName(status
));
1948 free(displayKeyword
);
1951 uenum_close(keywordEnum
);
1955 static void TestDisplayKeywordValues(void){
1958 static const struct {
1959 const char *localeID
;
1960 const char *displayLocale
;
1961 UChar displayKeywordValue
[500];
1963 { "ca_ES@currency=ESP", "de_AT",
1964 {0x0053, 0x0070, 0x0061, 0x006e, 0x0069, 0x0073, 0x0063, 0x0068, 0x0065, 0x0020, 0x0050, 0x0065, 0x0073, 0x0065, 0x0074, 0x0061, 0x0000}
1966 { "de_AT@currency=ATS", "fr_FR",
1967 {0x0073, 0x0063, 0x0068, 0x0069, 0x006c, 0x006c, 0x0069, 0x006e, 0x0067, 0x0020, 0x0061, 0x0075, 0x0074, 0x0072, 0x0069, 0x0063, 0x0068, 0x0069, 0x0065, 0x006e, 0x0000}
1969 { "de_DE@currency=DEM", "it",
1970 {0x004d, 0x0061, 0x0072, 0x0063, 0x006f, 0x0020, 0x0054, 0x0065, 0x0064, 0x0065, 0x0073, 0x0063, 0x006f, 0x0000}
1972 { "el_GR@currency=GRD", "en",
1973 {0x0047, 0x0072, 0x0065, 0x0065, 0x006b, 0x0020, 0x0044, 0x0072, 0x0061, 0x0063, 0x0068, 0x006d, 0x0061, 0x0000}
1975 { "eu_ES@currency=ESP", "it_IT",
1976 {0x0050, 0x0065, 0x0073, 0x0065, 0x0074, 0x0061, 0x0020, 0x0053, 0x0070, 0x0061, 0x0067, 0x006e, 0x006f, 0x006c, 0x0061, 0x0000}
1978 { "de@collation=phonebook", "es",
1979 {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}
1982 { "de_DE@collation=phonebook", "es",
1983 {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}
1985 { "es_ES@collation=traditional","de",
1986 {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}
1988 { "ja_JP@calendar=japanese", "de",
1989 {0x004a, 0x0061, 0x0070, 0x0061, 0x006e, 0x0069, 0x0073, 0x0063, 0x0068, 0x0065, 0x0072, 0x0020, 0x004b, 0x0061, 0x006c, 0x0065, 0x006e, 0x0064, 0x0065, 0x0072, 0x0000}
1992 for(i
= 0; i
< sizeof(testCases
)/sizeof(testCases
[0]); i
++) {
1993 UErrorCode status
= U_ZERO_ERROR
;
1994 const char* keyword
=NULL
;
1995 int32_t keywordLen
= 0;
1996 int32_t keywordCount
= 0;
1997 UChar
*displayKeywordValue
= NULL
;
1998 int32_t displayKeywordValueLen
= 0;
1999 UEnumeration
* keywordEnum
= uloc_openKeywords(testCases
[i
].localeID
, &status
);
2000 for(keywordCount
= uenum_count(keywordEnum
, &status
); keywordCount
> 0 ; keywordCount
--){
2001 if(U_FAILURE(status
)){
2002 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
));
2005 /* the uenum_next returns NUL terminated string */
2006 keyword
= uenum_next(keywordEnum
, &keywordLen
, &status
);
2008 /* fetch the displayKeywordValue */
2009 displayKeywordValueLen
= uloc_getDisplayKeywordValue(testCases
[i
].localeID
, keyword
, testCases
[i
].displayLocale
, displayKeywordValue
, displayKeywordValueLen
, &status
);
2010 if(status
==U_BUFFER_OVERFLOW_ERROR
){
2011 status
= U_ZERO_ERROR
;
2012 displayKeywordValueLen
++; /* for null termination */
2013 displayKeywordValue
= (UChar
*)malloc(displayKeywordValueLen
* U_SIZEOF_UCHAR
);
2014 displayKeywordValueLen
= uloc_getDisplayKeywordValue(testCases
[i
].localeID
, keyword
, testCases
[i
].displayLocale
, displayKeywordValue
, displayKeywordValueLen
, &status
);
2015 if(U_FAILURE(status
)){
2016 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
));
2019 if(u_strncmp(displayKeywordValue
, testCases
[i
].displayKeywordValue
, displayKeywordValueLen
)!=0){
2020 if (status
== U_USING_DEFAULT_WARNING
) {
2021 log_data_err("uloc_getDisplayKeywordValue did not return the expected value keyword : %s in locale id: %s for display locale: %s with error : %s Perhaps you are missing data\n", testCases
[i
].localeID
, keyword
, testCases
[i
].displayLocale
, u_errorName(status
));
2023 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
));
2028 log_err("uloc_getDisplayKeywordValue did not return the expected error. Error: %s\n", u_errorName(status
));
2030 free(displayKeywordValue
);
2032 uenum_close(keywordEnum
);
2035 /* test a multiple keywords */
2036 UErrorCode status
= U_ZERO_ERROR
;
2037 const char* keyword
=NULL
;
2038 int32_t keywordLen
= 0;
2039 int32_t keywordCount
= 0;
2040 const char* localeID
= "es@collation=phonebook;calendar=buddhist;currency=DEM";
2041 const char* displayLocale
= "de";
2042 static const UChar expected
[][50] = {
2043 {0x0042, 0x0075, 0x0064, 0x0064, 0x0068, 0x0069, 0x0073, 0x0074, 0x0069, 0x0073, 0x0063, 0x0068, 0x0065, 0x0072, 0x0020, 0x004b, 0x0061, 0x006c, 0x0065, 0x006e, 0x0064, 0x0065, 0x0072, 0x0000},
2045 {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},
2046 {0x0044, 0x0065, 0x0075, 0x0074, 0x0073, 0x0063, 0x0068, 0x0065, 0x0020, 0x004d, 0x0061, 0x0072, 0x006b, 0x0000},
2049 UEnumeration
* keywordEnum
= uloc_openKeywords(localeID
, &status
);
2051 for(keywordCount
= 0; keywordCount
< uenum_count(keywordEnum
, &status
) ; keywordCount
++){
2052 UChar
*displayKeywordValue
= NULL
;
2053 int32_t displayKeywordValueLen
= 0;
2054 if(U_FAILURE(status
)){
2055 log_err("uloc_getKeywords failed for locale id: %s in display locale: % with error : %s \n", localeID
, displayLocale
, u_errorName(status
));
2058 /* the uenum_next returns NUL terminated string */
2059 keyword
= uenum_next(keywordEnum
, &keywordLen
, &status
);
2061 /* fetch the displayKeywordValue */
2062 displayKeywordValueLen
= uloc_getDisplayKeywordValue(localeID
, keyword
, displayLocale
, displayKeywordValue
, displayKeywordValueLen
, &status
);
2063 if(status
==U_BUFFER_OVERFLOW_ERROR
){
2064 status
= U_ZERO_ERROR
;
2065 displayKeywordValueLen
++; /* for null termination */
2066 displayKeywordValue
= (UChar
*)malloc(displayKeywordValueLen
* U_SIZEOF_UCHAR
);
2067 displayKeywordValueLen
= uloc_getDisplayKeywordValue(localeID
, keyword
, displayLocale
, displayKeywordValue
, displayKeywordValueLen
, &status
);
2068 if(U_FAILURE(status
)){
2069 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
));
2072 if(u_strncmp(displayKeywordValue
, expected
[keywordCount
], displayKeywordValueLen
)!=0){
2073 if (status
== U_USING_DEFAULT_WARNING
) {
2074 log_data_err("uloc_getDisplayKeywordValue did not return the expected value keyword : %s in locale id: %s for display locale: %s got error: %s. Perhaps you are missing data?\n", localeID
, keyword
, displayLocale
, u_errorName(status
));
2076 log_err("uloc_getDisplayKeywordValue did not return the expected value keyword : %s in locale id: %s for display locale: %s \n", localeID
, keyword
, displayLocale
);
2081 log_err("uloc_getDisplayKeywordValue did not return the expected error. Error: %s\n", u_errorName(status
));
2083 free(displayKeywordValue
);
2085 uenum_close(keywordEnum
);
2089 /* Test non existent keywords */
2090 UErrorCode status
= U_ZERO_ERROR
;
2091 const char* localeID
= "es";
2092 const char* displayLocale
= "de";
2093 UChar
*displayKeywordValue
= NULL
;
2094 int32_t displayKeywordValueLen
= 0;
2096 /* fetch the displayKeywordValue */
2097 displayKeywordValueLen
= uloc_getDisplayKeywordValue(localeID
, "calendar", displayLocale
, displayKeywordValue
, displayKeywordValueLen
, &status
);
2098 if(U_FAILURE(status
)) {
2099 log_err("uloc_getDisplaykeywordValue returned error status %s\n", u_errorName(status
));
2100 } else if(displayKeywordValueLen
!= 0) {
2101 log_err("uloc_getDisplaykeywordValue returned %d should be 0 \n", displayKeywordValueLen
);
2107 static void TestGetBaseName(void) {
2108 static const struct {
2109 const char *localeID
;
2110 const char *baseName
;
2112 { "de_DE@ C o ll A t i o n = Phonebook ", "de_DE" },
2113 { "de@currency = euro; CoLLaTion = PHONEBOOk", "de" },
2114 { "ja@calendar = buddhist", "ja" }
2117 int32_t i
= 0, baseNameLen
= 0;
2119 UErrorCode status
= U_ZERO_ERROR
;
2121 for(i
= 0; i
< sizeof(testCases
)/sizeof(testCases
[0]); i
++) {
2122 baseNameLen
= uloc_getBaseName(testCases
[i
].localeID
, baseName
, 256, &status
);
2123 if(strcmp(testCases
[i
].baseName
, baseName
)) {
2124 log_err("For locale \"%s\" expected baseName \"%s\", but got \"%s\"\n",
2125 testCases
[i
].localeID
, testCases
[i
].baseName
, baseName
);
2131 static void TestTrailingNull(void) {
2132 const char* localeId
= "zh_Hans";
2133 UChar buffer
[128]; /* sufficient for this test */
2135 UErrorCode status
= U_ZERO_ERROR
;
2138 len
= uloc_getDisplayName(localeId
, localeId
, buffer
, 128, &status
);
2140 log_err("buffer too small");
2144 for (i
= 0; i
< len
; ++i
) {
2145 if (buffer
[i
] == 0) {
2146 log_err("name contained null");
2152 /* Jitterbug 4115 */
2153 static void TestDisplayNameWarning(void) {
2156 UErrorCode status
= U_ZERO_ERROR
;
2158 size
= uloc_getDisplayLanguage("qqq", "kl", name
, sizeof(name
)/sizeof(name
[0]), &status
);
2159 if (status
!= U_USING_DEFAULT_WARNING
) {
2160 log_err("For language \"qqq\" in locale \"kl\", expecting U_USING_DEFAULT_WARNING, but got %s\n",
2161 u_errorName(status
));
2167 * Compare two locale IDs. If they are equal, return 0. If `string'
2168 * starts with `prefix' plus an additional element, that is, string ==
2169 * prefix + '_' + x, then return 1. Otherwise return a value < 0.
2171 static UBool
_loccmp(const char* string
, const char* prefix
) {
2172 int32_t slen
= (int32_t)uprv_strlen(string
),
2173 plen
= (int32_t)uprv_strlen(prefix
);
2174 int32_t c
= uprv_strncmp(string
, prefix
, plen
);
2175 /* 'root' is less than everything */
2176 if (uprv_strcmp(prefix
, "root") == 0) {
2177 return (uprv_strcmp(string
, "root") == 0) ? 0 : 1;
2179 if (c
) return -1; /* mismatch */
2180 if (slen
== plen
) return 0;
2181 if (string
[plen
] == '_') return 1;
2182 return -2; /* false match, e.g. "en_USX" cmp "en_US" */
2185 static void _checklocs(const char* label
,
2188 const char* actual
) {
2189 /* We want the valid to be strictly > the bogus requested locale,
2190 and the valid to be >= the actual. */
2191 if (_loccmp(req
, valid
) > 0 &&
2192 _loccmp(valid
, actual
) >= 0) {
2193 log_verbose("%s; req=%s, valid=%s, actual=%s\n",
2194 label
, req
, valid
, actual
);
2196 log_err("FAIL: %s; req=%s, valid=%s, actual=%s\n",
2197 label
, req
, valid
, actual
);
2201 static void TestGetLocale(void) {
2202 UErrorCode ec
= U_ZERO_ERROR
;
2204 UChar EMPTY
[1] = {0};
2207 #if !UCONFIG_NO_FORMATTING
2210 const char *req
= "en_US_REDWOODSHORES", *valid
, *actual
;
2211 obj
= udat_open(UDAT_DEFAULT
, UDAT_DEFAULT
,
2215 if (U_FAILURE(ec
)) {
2216 log_data_err("udat_open failed.Error %s\n", u_errorName(ec
));
2219 valid
= udat_getLocaleByType(obj
, ULOC_VALID_LOCALE
, &ec
);
2220 actual
= udat_getLocaleByType(obj
, ULOC_ACTUAL_LOCALE
, &ec
);
2221 if (U_FAILURE(ec
)) {
2222 log_err("udat_getLocaleByType() failed\n");
2225 _checklocs("udat", req
, valid
, actual
);
2231 #if !UCONFIG_NO_FORMATTING
2234 const char *req
= "fr_FR_PROVENCAL", *valid
, *actual
;
2235 obj
= ucal_open(NULL
, 0,
2239 if (U_FAILURE(ec
)) {
2240 log_err("ucal_open failed with error: %s\n", u_errorName(ec
));
2243 valid
= ucal_getLocaleByType(obj
, ULOC_VALID_LOCALE
, &ec
);
2244 actual
= ucal_getLocaleByType(obj
, ULOC_ACTUAL_LOCALE
, &ec
);
2245 if (U_FAILURE(ec
)) {
2246 log_err("ucal_getLocaleByType() failed\n");
2249 _checklocs("ucal", req
, valid
, actual
);
2255 #if !UCONFIG_NO_FORMATTING
2258 const char *req
= "zh_Hant_TW_TAINAN", *valid
, *actual
;
2259 obj
= unum_open(UNUM_DECIMAL
,
2263 if (U_FAILURE(ec
)) {
2264 log_err("unum_open failed\n");
2267 valid
= unum_getLocaleByType(obj
, ULOC_VALID_LOCALE
, &ec
);
2268 actual
= unum_getLocaleByType(obj
, ULOC_ACTUAL_LOCALE
, &ec
);
2269 if (U_FAILURE(ec
)) {
2270 log_err("unum_getLocaleByType() failed\n");
2273 _checklocs("unum", req
, valid
, actual
);
2280 /* commented out by weiv 01/12/2005. umsg_getLocaleByType is to be removed */
2281 #if !UCONFIG_NO_FORMATTING
2283 UMessageFormat
*obj
;
2284 const char *req
= "ja_JP_TAKAYAMA", *valid
, *actual
;
2286 obj
= umsg_open(EMPTY
, 0,
2289 if (U_FAILURE(ec
)) {
2290 log_err("umsg_open failed\n");
2293 valid
= umsg_getLocaleByType(obj
, ULOC_VALID_LOCALE
, &ec
);
2294 actual
= umsg_getLocaleByType(obj
, ULOC_ACTUAL_LOCALE
, &ec
);
2295 if (U_FAILURE(ec
)) {
2296 log_err("umsg_getLocaleByType() failed\n");
2299 /* We want the valid to be strictly > the bogus requested locale,
2300 and the valid to be >= the actual. */
2301 /* TODO MessageFormat is currently just storing the locale it is given.
2302 As a result, it will return whatever it was given, even if the
2303 locale is invalid. */
2304 test
= (_cmpversion("3.2") <= 0) ?
2305 /* Here is the weakened test for 3.0: */
2306 (_loccmp(req
, valid
) >= 0) :
2307 /* Here is what the test line SHOULD be: */
2308 (_loccmp(req
, valid
) > 0);
2311 _loccmp(valid
, actual
) >= 0) {
2312 log_verbose("umsg; req=%s, valid=%s, actual=%s\n", req
, valid
, actual
);
2314 log_err("FAIL: umsg; req=%s, valid=%s, actual=%s\n", req
, valid
, actual
);
2322 #if !UCONFIG_NO_BREAK_ITERATION
2324 UBreakIterator
*obj
;
2325 const char *req
= "ar_KW_ABDALI", *valid
, *actual
;
2326 obj
= ubrk_open(UBRK_WORD
,
2331 if (U_FAILURE(ec
)) {
2332 log_err("ubrk_open failed. Error: %s \n", u_errorName(ec
));
2335 valid
= ubrk_getLocaleByType(obj
, ULOC_VALID_LOCALE
, &ec
);
2336 actual
= ubrk_getLocaleByType(obj
, ULOC_ACTUAL_LOCALE
, &ec
);
2337 if (U_FAILURE(ec
)) {
2338 log_err("ubrk_getLocaleByType() failed\n");
2341 _checklocs("ubrk", req
, valid
, actual
);
2347 #if !UCONFIG_NO_COLLATION
2350 const char *req
= "es_AR_BUENOSAIRES", *valid
, *actual
;
2351 obj
= ucol_open(req
, &ec
);
2352 if (U_FAILURE(ec
)) {
2353 log_err("ucol_open failed - %s\n", u_errorName(ec
));
2356 valid
= ucol_getLocaleByType(obj
, ULOC_VALID_LOCALE
, &ec
);
2357 actual
= ucol_getLocaleByType(obj
, ULOC_ACTUAL_LOCALE
, &ec
);
2358 if (U_FAILURE(ec
)) {
2359 log_err("ucol_getLocaleByType() failed\n");
2362 _checklocs("ucol", req
, valid
, actual
);
2368 static void TestNonexistentLanguageExemplars(void) {
2369 /* JB 4068 - Nonexistent language */
2370 UErrorCode ec
= U_ZERO_ERROR
;
2371 ULocaleData
*uld
= ulocdata_open("qqq",&ec
);
2372 if (ec
!= U_USING_DEFAULT_WARNING
) {
2373 log_err_status(ec
, "Exemplar set for \"qqq\", expecting U_USING_DEFAULT_WARNING, but got %s\n",
2376 uset_close(ulocdata_getExemplarSet(uld
, NULL
, 0, ULOCDATA_ES_STANDARD
, &ec
));
2377 ulocdata_close(uld
);
2380 static void TestLocDataErrorCodeChaining(void) {
2381 UErrorCode ec
= U_USELESS_COLLATOR_ERROR
;
2382 ulocdata_open(NULL
, &ec
);
2383 ulocdata_getExemplarSet(NULL
, NULL
, 0, ULOCDATA_ES_STANDARD
, &ec
);
2384 ulocdata_getDelimiter(NULL
, ULOCDATA_DELIMITER_COUNT
, NULL
, -1, &ec
);
2385 ulocdata_getMeasurementSystem(NULL
, &ec
);
2386 ulocdata_getPaperSize(NULL
, NULL
, NULL
, &ec
);
2387 if (ec
!= U_USELESS_COLLATOR_ERROR
) {
2388 log_err("ulocdata API changed the error code to %s\n", u_errorName(ec
));
2392 static void TestLanguageExemplarsFallbacks(void) {
2393 /* Test that en_US fallsback, but en doesn't fallback. */
2394 UErrorCode ec
= U_ZERO_ERROR
;
2395 ULocaleData
*uld
= ulocdata_open("en_US",&ec
);
2396 uset_close(ulocdata_getExemplarSet(uld
, NULL
, 0, ULOCDATA_ES_STANDARD
, &ec
));
2397 if (ec
!= U_USING_FALLBACK_WARNING
) {
2398 log_err_status(ec
, "Exemplar set for \"en_US\", expecting U_USING_FALLBACK_WARNING, but got %s\n",
2401 ulocdata_close(uld
);
2403 uld
= ulocdata_open("en",&ec
);
2404 uset_close(ulocdata_getExemplarSet(uld
, NULL
, 0, ULOCDATA_ES_STANDARD
, &ec
));
2405 if (ec
!= U_ZERO_ERROR
) {
2406 log_err_status(ec
, "Exemplar set for \"en\", expecting U_ZERO_ERROR, but got %s\n",
2409 ulocdata_close(uld
);
2412 static const char *acceptResult(UAcceptResult uar
) {
2413 return udbg_enumName(UDBG_UAcceptResult
, uar
);
2416 static void TestAcceptLanguage(void) {
2417 UErrorCode status
= U_ZERO_ERROR
;
2418 UAcceptResult outResult
;
2419 UEnumeration
*available
;
2425 int32_t httpSet
; /**< Which of http[] should be used? */
2426 const char *icuSet
; /**< ? */
2427 const char *expect
; /**< The expected locale result */
2428 UAcceptResult res
; /**< The expected error code */
2430 /*0*/{ 0, NULL
, "mt_MT", ULOC_ACCEPT_VALID
},
2431 /*1*/{ 1, NULL
, "en", ULOC_ACCEPT_VALID
},
2432 /*2*/{ 2, NULL
, "en", ULOC_ACCEPT_FALLBACK
},
2433 /*3*/{ 3, NULL
, "", ULOC_ACCEPT_FAILED
},
2434 /*4*/{ 4, NULL
, "es", ULOC_ACCEPT_VALID
},
2436 /*5*/{ 5, NULL
, "en", ULOC_ACCEPT_VALID
}, /* XF */
2437 /*6*/{ 6, NULL
, "ja", ULOC_ACCEPT_FALLBACK
}, /* XF */
2438 /*7*/{ 7, NULL
, "zh", ULOC_ACCEPT_FALLBACK
}, /* XF */
2440 const int32_t numTests
= sizeof(tests
)/sizeof(tests
[0]);
2441 static const char *http
[] = {
2442 /*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",
2443 /*1*/ "ja;q=0.5, en;q=0.8, tlh",
2444 /*2*/ "en-wf, de-lx;q=0.8",
2445 /*3*/ "mga-ie;q=0.9, tlh",
2446 /*4*/ "xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, "
2447 "xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, "
2448 "xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, "
2449 "xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, "
2450 "xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, "
2451 "xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, "
2452 "xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, xx-yy;q=.1, "
2455 /*5*/ "zh-xx;q=0.9, en;q=0.6",
2457 /*7*/ "zh-xx;q=0.9",
2460 for(i
=0;i
<numTests
;i
++) {
2462 status
=U_ZERO_ERROR
;
2463 log_verbose("test #%d: http[%s], ICU[%s], expect %s, %s\n",
2464 i
, http
[tests
[i
].httpSet
], tests
[i
].icuSet
, tests
[i
].expect
, acceptResult(tests
[i
].res
));
2466 available
= ures_openAvailableLocales(tests
[i
].icuSet
, &status
);
2468 rc
= uloc_acceptLanguageFromHTTP(tmp
, 199, &outResult
, http
[tests
[i
].httpSet
], available
, &status
);
2469 uenum_close(available
);
2470 log_verbose(" got %s, %s [%s]\n", tmp
[0]?tmp
:"(EMPTY)", acceptResult(outResult
), u_errorName(status
));
2471 if(outResult
!= tests
[i
].res
) {
2472 log_err_status(status
, "FAIL: #%d: expected outResult of %s but got %s\n", i
,
2473 acceptResult( tests
[i
].res
),
2474 acceptResult( outResult
));
2475 log_info("test #%d: http[%s], ICU[%s], expect %s, %s\n",
2476 i
, http
[tests
[i
].httpSet
], tests
[i
].icuSet
, tests
[i
].expect
,acceptResult(tests
[i
].res
));
2478 if((outResult
>0)&&uprv_strcmp(tmp
, tests
[i
].expect
)) {
2479 log_err_status(status
, "FAIL: #%d: expected %s but got %s\n", i
, tests
[i
].expect
, tmp
);
2480 log_info("test #%d: http[%s], ICU[%s], expect %s, %s\n",
2481 i
, http
[tests
[i
].httpSet
], tests
[i
].icuSet
, tests
[i
].expect
, acceptResult(tests
[i
].res
));
2486 static const char* LOCALE_ALIAS
[][2] = {
2500 static UBool
isLocaleAvailable(UResourceBundle
* resIndex
, const char* loc
){
2501 UErrorCode status
= U_ZERO_ERROR
;
2503 ures_getStringByKey(resIndex
, loc
,&len
, &status
);
2504 if(U_FAILURE(status
)){
2510 static void TestCalendar() {
2511 #if !UCONFIG_NO_FORMATTING
2513 UErrorCode status
= U_ZERO_ERROR
;
2514 UResourceBundle
*resIndex
= ures_open(NULL
,"res_index", &status
);
2515 if(U_FAILURE(status
)){
2516 log_err_status(status
, "Could not open res_index.res. Exiting. Error: %s\n", u_errorName(status
));
2519 for (i
=0; i
<LENGTHOF(LOCALE_ALIAS
); i
++) {
2520 const char* oldLoc
= LOCALE_ALIAS
[i
][0];
2521 const char* newLoc
= LOCALE_ALIAS
[i
][1];
2522 UCalendar
* c1
= NULL
;
2523 UCalendar
* c2
= NULL
;
2525 /*Test function "getLocale(ULocale.VALID_LOCALE)"*/
2526 const char* l1
= ucal_getLocaleByType(c1
, ULOC_VALID_LOCALE
, &status
);
2527 const char* l2
= ucal_getLocaleByType(c2
, ULOC_VALID_LOCALE
, &status
);
2529 if(!isLocaleAvailable(resIndex
, newLoc
)){
2532 c1
= ucal_open(NULL
, -1, oldLoc
, UCAL_GREGORIAN
, &status
);
2533 c2
= ucal_open(NULL
, -1, newLoc
, UCAL_GREGORIAN
, &status
);
2535 if (strcmp(newLoc
,l1
)!=0 || strcmp(l1
,l2
)!=0 || status
!=U_ZERO_ERROR
) {
2536 log_err("The locales are not equal!.Old: %s, New: %s \n", oldLoc
, newLoc
);
2538 log_verbose("ucal_getLocaleByType old:%s new:%s\n", l1
, l2
);
2542 ures_close(resIndex
);
2546 static void TestDateFormat() {
2547 #if !UCONFIG_NO_FORMATTING
2549 UErrorCode status
= U_ZERO_ERROR
;
2550 UResourceBundle
*resIndex
= ures_open(NULL
,"res_index", &status
);
2551 if(U_FAILURE(status
)){
2552 log_err_status(status
, "Could not open res_index.res. Exiting. Error: %s\n", u_errorName(status
));
2555 for (i
=0; i
<LENGTHOF(LOCALE_ALIAS
); i
++) {
2556 const char* oldLoc
= LOCALE_ALIAS
[i
][0];
2557 const char* newLoc
= LOCALE_ALIAS
[i
][1];
2558 UDateFormat
* df1
= NULL
;
2559 UDateFormat
* df2
= NULL
;
2560 const char* l1
= NULL
;
2561 const char* l2
= NULL
;
2563 if(!isLocaleAvailable(resIndex
, newLoc
)){
2566 df1
= udat_open(UDAT_FULL
, UDAT_FULL
,oldLoc
, NULL
, 0, NULL
, -1, &status
);
2567 df2
= udat_open(UDAT_FULL
, UDAT_FULL
,newLoc
, NULL
, 0, NULL
, -1, &status
);
2568 if(U_FAILURE(status
)){
2569 log_err("Creation of date format failed %s\n", u_errorName(status
));
2572 /*Test function "getLocale"*/
2573 l1
= udat_getLocaleByType(df1
, ULOC_VALID_LOCALE
, &status
);
2574 l2
= udat_getLocaleByType(df2
, ULOC_VALID_LOCALE
, &status
);
2575 if(U_FAILURE(status
)){
2576 log_err("Fetching the locale by type failed. %s\n", u_errorName(status
));
2578 if (strcmp(newLoc
,l1
)!=0 || strcmp(l1
,l2
)!=0) {
2579 log_err("The locales are not equal!.Old: %s, New: %s \n", oldLoc
, newLoc
);
2581 log_verbose("udat_getLocaleByType old:%s new:%s\n", l1
, l2
);
2585 ures_close(resIndex
);
2589 static void TestCollation() {
2590 #if !UCONFIG_NO_COLLATION
2592 UErrorCode status
= U_ZERO_ERROR
;
2593 UResourceBundle
*resIndex
= ures_open(NULL
,"res_index", &status
);
2594 if(U_FAILURE(status
)){
2595 log_err_status(status
, "Could not open res_index.res. Exiting. Error: %s\n", u_errorName(status
));
2598 for (i
=0; i
<LENGTHOF(LOCALE_ALIAS
); i
++) {
2599 const char* oldLoc
= LOCALE_ALIAS
[i
][0];
2600 const char* newLoc
= LOCALE_ALIAS
[i
][1];
2601 UCollator
* c1
= NULL
;
2602 UCollator
* c2
= NULL
;
2603 const char* l1
= NULL
;
2604 const char* l2
= NULL
;
2606 status
= U_ZERO_ERROR
;
2607 if(!isLocaleAvailable(resIndex
, newLoc
)){
2610 if(U_FAILURE(status
)){
2611 log_err("Creation of collators failed %s\n", u_errorName(status
));
2614 c1
= ucol_open(oldLoc
, &status
);
2615 c2
= ucol_open(newLoc
, &status
);
2616 l1
= ucol_getLocaleByType(c1
, ULOC_VALID_LOCALE
, &status
);
2617 l2
= ucol_getLocaleByType(c2
, ULOC_VALID_LOCALE
, &status
);
2618 if(U_FAILURE(status
)){
2619 log_err("Fetching the locale names failed failed %s\n", u_errorName(status
));
2621 if (strcmp(newLoc
,l1
)!=0 || strcmp(l1
,l2
)!=0) {
2622 log_err("The locales are not equal!.Old: %s, New: %s \n", oldLoc
, newLoc
);
2624 log_verbose("ucol_getLocaleByType old:%s new:%s\n", l1
, l2
);
2628 ures_close(resIndex
);
2632 typedef struct OrientationStructTag
{
2633 const char* localeId
;
2634 ULayoutType character
;
2636 } OrientationStruct
;
2638 static const char* ULayoutTypeToString(ULayoutType type
)
2642 case ULOC_LAYOUT_LTR
:
2643 return "ULOC_LAYOUT_LTR";
2645 case ULOC_LAYOUT_RTL
:
2646 return "ULOC_LAYOUT_RTL";
2648 case ULOC_LAYOUT_TTB
:
2649 return "ULOC_LAYOUT_TTB";
2651 case ULOC_LAYOUT_BTT
:
2652 return "ULOC_LAYOUT_BTT";
2654 case ULOC_LAYOUT_UNKNOWN
:
2658 return "Unknown enum value for ULayoutType!";
2661 static void TestOrientation()
2663 static const OrientationStruct toTest
[] = {
2664 { "ar", ULOC_LAYOUT_RTL
, ULOC_LAYOUT_TTB
},
2665 { "aR", ULOC_LAYOUT_RTL
, ULOC_LAYOUT_TTB
},
2666 { "ar_Arab", ULOC_LAYOUT_RTL
, ULOC_LAYOUT_TTB
},
2667 { "fa", ULOC_LAYOUT_RTL
, ULOC_LAYOUT_TTB
},
2668 { "Fa", ULOC_LAYOUT_RTL
, ULOC_LAYOUT_TTB
},
2669 { "he", ULOC_LAYOUT_RTL
, ULOC_LAYOUT_TTB
},
2670 { "ps", ULOC_LAYOUT_RTL
, ULOC_LAYOUT_TTB
},
2671 { "ur", ULOC_LAYOUT_RTL
, ULOC_LAYOUT_TTB
},
2672 { "UR", ULOC_LAYOUT_RTL
, ULOC_LAYOUT_TTB
},
2673 { "en", ULOC_LAYOUT_LTR
, ULOC_LAYOUT_TTB
}
2677 for (; i
< sizeof(toTest
) / sizeof(toTest
[0]); ++i
) {
2678 UErrorCode statusCO
= U_ZERO_ERROR
;
2679 UErrorCode statusLO
= U_ZERO_ERROR
;
2680 const char* const localeId
= toTest
[i
].localeId
;
2681 const ULayoutType co
= uloc_getCharacterOrientation(localeId
, &statusCO
);
2682 const ULayoutType expectedCO
= toTest
[i
].character
;
2683 const ULayoutType lo
= uloc_getLineOrientation(localeId
, &statusLO
);
2684 const ULayoutType expectedLO
= toTest
[i
].line
;
2685 if (U_FAILURE(statusCO
)) {
2686 log_err_status(statusCO
,
2687 " unexpected failure for uloc_getCharacterOrientation(), with localId \"%s\" and status %s\n",
2689 u_errorName(statusCO
));
2691 else if (co
!= expectedCO
) {
2693 " unexpected result for uloc_getCharacterOrientation(), with localeId \"%s\". Expected %s but got result %s\n",
2695 ULayoutTypeToString(expectedCO
),
2696 ULayoutTypeToString(co
));
2698 if (U_FAILURE(statusLO
)) {
2699 log_err_status(statusLO
,
2700 " unexpected failure for uloc_getLineOrientation(), with localId \"%s\" and status %s\n",
2702 u_errorName(statusLO
));
2704 else if (lo
!= expectedLO
) {
2706 " unexpected result for uloc_getLineOrientation(), with localeId \"%s\". Expected %s but got result %s\n",
2708 ULayoutTypeToString(expectedLO
),
2709 ULayoutTypeToString(lo
));
2714 static void TestULocale() {
2716 UErrorCode status
= U_ZERO_ERROR
;
2717 UResourceBundle
*resIndex
= ures_open(NULL
,"res_index", &status
);
2718 if(U_FAILURE(status
)){
2719 log_err_status(status
, "Could not open res_index.res. Exiting. Error: %s\n", u_errorName(status
));
2722 for (i
=0; i
<LENGTHOF(LOCALE_ALIAS
); i
++) {
2723 const char* oldLoc
= LOCALE_ALIAS
[i
][0];
2724 const char* newLoc
= LOCALE_ALIAS
[i
][1];
2725 UChar name1
[256], name2
[256];
2726 char names1
[256], names2
[256];
2727 int32_t capacity
= 256;
2729 status
= U_ZERO_ERROR
;
2730 if(!isLocaleAvailable(resIndex
, newLoc
)){
2733 uloc_getDisplayName(oldLoc
, ULOC_US
, name1
, capacity
, &status
);
2734 if(U_FAILURE(status
)){
2735 log_err("uloc_getDisplayName(%s) failed %s\n", oldLoc
, u_errorName(status
));
2738 uloc_getDisplayName(newLoc
, ULOC_US
, name2
, capacity
, &status
);
2739 if(U_FAILURE(status
)){
2740 log_err("uloc_getDisplayName(%s) failed %s\n", newLoc
, u_errorName(status
));
2743 if (u_strcmp(name1
, name2
)!=0) {
2744 log_err("The locales are not equal!.Old: %s, New: %s \n", oldLoc
, newLoc
);
2746 u_austrcpy(names1
, name1
);
2747 u_austrcpy(names2
, name2
);
2748 log_verbose("uloc_getDisplayName old:%s new:%s\n", names1
, names2
);
2750 ures_close(resIndex
);
2754 static void TestUResourceBundle() {
2758 UResourceBundle
* rb1
= NULL
;
2759 UResourceBundle
* rb2
= NULL
;
2760 UErrorCode status
= U_ZERO_ERROR
;
2762 UResourceBundle
*resIndex
= NULL
;
2763 if(U_FAILURE(status
)){
2764 log_err("Could not open res_index.res. Exiting. Error: %s\n", u_errorName(status
));
2767 resIndex
= ures_open(NULL
,"res_index", &status
);
2768 for (i
=0; i
<LENGTHOF(LOCALE_ALIAS
); i
++) {
2770 const char* oldLoc
= LOCALE_ALIAS
[i
][0];
2771 const char* newLoc
= LOCALE_ALIAS
[i
][1];
2772 if(!isLocaleAvailable(resIndex
, newLoc
)){
2775 rb1
= ures_open(NULL
, oldLoc
, &status
);
2776 if (U_FAILURE(status
)) {
2777 log_err("ures_open(%s) failed %s\n", oldLoc
, u_errorName(status
));
2780 us1
= ures_getLocaleByType(rb1
, ULOC_ACTUAL_LOCALE
, &status
);
2782 status
= U_ZERO_ERROR
;
2783 rb2
= ures_open(NULL
, newLoc
, &status
);
2784 if (U_FAILURE(status
)) {
2785 log_err("ures_open(%s) failed %s\n", oldLoc
, u_errorName(status
));
2787 us2
= ures_getLocaleByType(rb2
, ULOC_ACTUAL_LOCALE
, &status
);
2789 if (strcmp(us1
,newLoc
)!=0 || strcmp(us1
,us2
)!=0 ) {
2790 log_err("The locales are not equal!.Old: %s, New: %s \n", oldLoc
, newLoc
);
2793 log_verbose("ures_getStringByKey old:%s new:%s\n", us1
, us2
);
2799 ures_close(resIndex
);
2802 static void TestDisplayName() {
2804 UChar oldCountry
[256] = {'\0'};
2805 UChar newCountry
[256] = {'\0'};
2806 UChar oldLang
[256] = {'\0'};
2807 UChar newLang
[256] = {'\0'};
2808 char country
[256] ={'\0'};
2809 char language
[256] ={'\0'};
2810 int32_t capacity
= 256;
2813 for (i
=0; i
<LENGTHOF(LOCALE_ALIAS
); i
++) {
2814 const char* oldLoc
= LOCALE_ALIAS
[i
][0];
2815 const char* newLoc
= LOCALE_ALIAS
[i
][1];
2816 UErrorCode status
= U_ZERO_ERROR
;
2817 int32_t available
= uloc_countAvailable();
2819 for(j
=0; j
<available
; j
++){
2821 const char* dispLoc
= uloc_getAvailable(j
);
2822 int32_t oldCountryLen
= uloc_getDisplayCountry(oldLoc
,dispLoc
, oldCountry
, capacity
, &status
);
2823 int32_t newCountryLen
= uloc_getDisplayCountry(newLoc
, dispLoc
, newCountry
, capacity
, &status
);
2824 int32_t oldLangLen
= uloc_getDisplayLanguage(oldLoc
, dispLoc
, oldLang
, capacity
, &status
);
2825 int32_t newLangLen
= uloc_getDisplayLanguage(newLoc
, dispLoc
, newLang
, capacity
, &status
);
2827 int32_t countryLen
= uloc_getCountry(newLoc
, country
, capacity
, &status
);
2828 int32_t langLen
= uloc_getLanguage(newLoc
, language
, capacity
, &status
);
2829 /* there is a display name for the current country ID */
2830 if(countryLen
!= newCountryLen
){
2831 if(u_strncmp(oldCountry
,newCountry
,oldCountryLen
)!=0){
2832 log_err("uloc_getDisplayCountry() failed for %s in display locale %s \n", oldLoc
, dispLoc
);
2835 /* there is a display name for the current lang ID */
2836 if(langLen
!=newLangLen
){
2837 if(u_strncmp(oldLang
,newLang
,oldLangLen
)){
2838 log_err("uloc_getDisplayLanguage() failed for %s in display locale %s \n", oldLoc
, dispLoc
); }
2844 static void TestGetLocaleForLCID() {
2845 int32_t i
, length
, lengthPre
;
2846 const char* testLocale
= 0;
2847 UErrorCode status
= U_ZERO_ERROR
;
2848 char temp2
[40], temp3
[40];
2851 lcid
= uloc_getLCID("en_US");
2852 if (lcid
!= 0x0409) {
2853 log_err(" uloc_getLCID(\"en_US\") = %d, expected 0x0409\n", lcid
);
2856 lengthPre
= uloc_getLocaleForLCID(lcid
, temp2
, 4, &status
);
2857 if (status
!= U_BUFFER_OVERFLOW_ERROR
) {
2858 log_err(" unexpected result from uloc_getLocaleForLCID with small buffer: %s\n", u_errorName(status
));
2861 status
= U_ZERO_ERROR
;
2864 length
= uloc_getLocaleForLCID(lcid
, temp2
, sizeof(temp2
)/sizeof(char), &status
);
2865 if (U_FAILURE(status
)) {
2866 log_err(" unexpected result from uloc_getLocaleForLCID(0x0409): %s\n", u_errorName(status
));
2867 status
= U_ZERO_ERROR
;
2870 if (length
!= lengthPre
) {
2871 log_err(" uloc_getLocaleForLCID(0x0409): returned length %d does not match preflight length %d\n", length
, lengthPre
);
2874 length
= uloc_getLocaleForLCID(0x12345, temp2
, sizeof(temp2
)/sizeof(char), &status
);
2875 if (U_SUCCESS(status
)) {
2876 log_err(" unexpected result from uloc_getLocaleForLCID(0x12345): %s, status %s\n", temp2
, u_errorName(status
));
2878 status
= U_ZERO_ERROR
;
2880 log_verbose("Testing getLocaleForLCID vs. locale data\n");
2881 for (i
= 0; i
< LOCALE_SIZE
; i
++) {
2883 testLocale
=rawData2
[NAME
][i
];
2885 log_verbose("Testing %s ......\n", testLocale
);
2887 sscanf(rawData2
[LCID
][i
], "%x", &lcid
);
2888 length
= uloc_getLocaleForLCID(lcid
, temp2
, sizeof(temp2
)/sizeof(char), &status
);
2889 if (U_FAILURE(status
)) {
2890 log_err(" unexpected failure of uloc_getLocaleForLCID(%#04x), status %s\n", lcid
, u_errorName(status
));
2891 status
= U_ZERO_ERROR
;
2895 if (length
!= uprv_strlen(temp2
)) {
2896 log_err(" returned length %d not correct for uloc_getLocaleForLCID(%#04x), expected %d\n", length
, lcid
, uprv_strlen(temp2
));
2899 /* Compare language, country, script */
2900 length
= uloc_getLanguage(temp2
, temp3
, sizeof(temp3
)/sizeof(char), &status
);
2901 if (U_FAILURE(status
)) {
2902 log_err(" couldn't get language in uloc_getLocaleForLCID(%#04x) = %s, status %s\n", lcid
, temp2
, u_errorName(status
));
2903 status
= U_ZERO_ERROR
;
2905 else if (uprv_strcmp(temp3
, rawData2
[LANG
][i
]) && !(uprv_strcmp(temp3
, "nn") == 0 && uprv_strcmp(rawData2
[VAR
][i
], "NY") == 0)) {
2906 log_err(" language doesn't match expected %s in in uloc_getLocaleForLCID(%#04x) = %s\n", rawData2
[LANG
][i
], lcid
, temp2
);
2909 length
= uloc_getScript(temp2
, temp3
, sizeof(temp3
)/sizeof(char), &status
);
2910 if (U_FAILURE(status
)) {
2911 log_err(" couldn't get script in uloc_getLocaleForLCID(%#04x) = %s, status %s\n", lcid
, temp2
, u_errorName(status
));
2912 status
= U_ZERO_ERROR
;
2914 else if (uprv_strcmp(temp3
, rawData2
[SCRIPT
][i
])) {
2915 log_err(" script doesn't match expected %s in in uloc_getLocaleForLCID(%#04x) = %s\n", rawData2
[SCRIPT
][i
], lcid
, temp2
);
2918 length
= uloc_getCountry(temp2
, temp3
, sizeof(temp3
)/sizeof(char), &status
);
2919 if (U_FAILURE(status
)) {
2920 log_err(" couldn't get country in uloc_getLocaleForLCID(%#04x) = %s, status %s\n", lcid
, temp2
, u_errorName(status
));
2921 status
= U_ZERO_ERROR
;
2923 else if (uprv_strlen(rawData2
[CTRY
][i
]) && uprv_strcmp(temp3
, rawData2
[CTRY
][i
])) {
2924 log_err(" country doesn't match expected %s in in uloc_getLocaleForLCID(%#04x) = %s\n", rawData2
[CTRY
][i
], lcid
, temp2
);
2930 const char* const basic_maximize_data
[][2] = {
2975 "en_Latn_US_POSIX_1901"
2977 "en_Latn__POSIX_1901",
2978 "en_Latn_US_POSIX_1901"
2981 "en_Latn_US_POSIX_1901"
2984 "de_Latn_DE_POSIX_1901"
2989 "th@calendar=buddhist",
2990 "th_Thai_TH@calendar=buddhist"
3020 "de_Latn_DE_U_CO_PHONEBK"
3022 "de_Latn_u_co_phonebk",
3023 "de_Latn_DE_U_CO_PHONEBK"
3025 "de_Latn_DE_u_co_phonebk",
3026 "de_Latn_DE_U_CO_PHONEBK"
3030 const char* const basic_minimize_data
[][2] = {
3035 "en_Latn_US_POSIX_1901",
3038 "EN_Latn_US_POSIX_1901",
3041 "en_Zzzz_US_POSIX_1901",
3044 "de_Latn_DE_POSIX_1901",
3050 "en_Latn_US@calendar=gregorian",
3051 "en@calendar=gregorian"
3055 const char* const full_data
[][3] = {
3059 /* "REMOVE-LIKELY" */
5129 "de@collation=phonebook",
5130 "de_Latn_DE@collation=phonebook",
5131 "de@collation=phonebook"
5135 typedef struct errorDataTag
{
5137 const char* expected
;
5142 const errorData maximizeErrors
[] = {
5146 U_ILLEGAL_ARGUMENT_ERROR
,
5150 "en_THUJIOGIURJHGJFURYHFJGURYYYHHGJURHG",
5152 U_ILLEGAL_ARGUMENT_ERROR
,
5156 "en_THUJIOGIURJHGJFURYHFJGURYYYHHGJURHG",
5158 U_ILLEGAL_ARGUMENT_ERROR
,
5162 "en_Latn_US_POSIX@currency=EURO",
5163 "en_Latn_US_POSIX@currency=EURO",
5164 U_BUFFER_OVERFLOW_ERROR
,
5168 "en_Latn_US_POSIX@currency=EURO",
5169 "en_Latn_US_POSIX@currency=EURO",
5170 U_STRING_NOT_TERMINATED_WARNING
,
5175 const errorData minimizeErrors
[] = {
5179 U_ILLEGAL_ARGUMENT_ERROR
,
5183 "en_THUJIOGIURJHGJFURYHFJGURYYYHHGJURHG",
5185 U_ILLEGAL_ARGUMENT_ERROR
,
5189 "en_Latn_US_POSIX@currency=EURO",
5190 "en__POSIX@currency=EURO",
5191 U_BUFFER_OVERFLOW_ERROR
,
5195 "en_Latn_US_POSIX@currency=EURO",
5196 "en__POSIX@currency=EURO",
5197 U_STRING_NOT_TERMINATED_WARNING
,
5202 static int32_t getExpectedReturnValue(const errorData
* data
)
5204 if (data
->uerror
== U_BUFFER_OVERFLOW_ERROR
||
5205 data
->uerror
== U_STRING_NOT_TERMINATED_WARNING
)
5207 return strlen(data
->expected
);
5215 static int32_t getBufferSize(const errorData
* data
, int32_t actualSize
)
5217 if (data
->expected
== NULL
)
5221 else if (data
->bufferSize
< 0)
5223 return strlen(data
->expected
) + 1;
5227 return data
->bufferSize
;
5231 static void TestLikelySubtags()
5233 char buffer
[ULOC_FULLNAME_CAPACITY
+ ULOC_KEYWORD_AND_VALUES_CAPACITY
+ 1];
5236 for (; i
< sizeof(basic_maximize_data
) / sizeof(basic_maximize_data
[0]); ++i
)
5238 UErrorCode status
= U_ZERO_ERROR
;
5239 const char* const minimal
= basic_maximize_data
[i
][0];
5240 const char* const maximal
= basic_maximize_data
[i
][1];
5242 /* const int32_t length = */
5243 uloc_addLikelySubtags(
5248 if (U_FAILURE(status
)) {
5249 log_err_status(status
, " unexpected failure of uloc_addLikelySubtags(), minimal \"%s\" status %s\n", minimal
, u_errorName(status
));
5250 status
= U_ZERO_ERROR
;
5252 else if (uprv_strlen(maximal
) == 0) {
5253 if (uprv_stricmp(minimal
, buffer
) != 0) {
5254 log_err(" unexpected maximal value \"%s\" in uloc_addLikelySubtags(), minimal \"%s\" = \"%s\"\n", maximal
, minimal
, buffer
);
5257 else if (uprv_stricmp(maximal
, buffer
) != 0) {
5258 log_err(" maximal doesn't match expected %s in uloc_addLikelySubtags(), minimal \"%s\" = %s\n", maximal
, minimal
, buffer
);
5262 for (i
= 0; i
< sizeof(basic_minimize_data
) / sizeof(basic_minimize_data
[0]); ++i
) {
5264 UErrorCode status
= U_ZERO_ERROR
;
5265 const char* const maximal
= basic_minimize_data
[i
][0];
5266 const char* const minimal
= basic_minimize_data
[i
][1];
5268 /* const int32_t length = */
5269 uloc_minimizeSubtags(
5275 if (U_FAILURE(status
)) {
5276 log_err_status(status
, " unexpected failure of uloc_MinimizeSubtags(), maximal \"%s\" status %s\n", maximal
, u_errorName(status
));
5277 status
= U_ZERO_ERROR
;
5279 else if (uprv_strlen(minimal
) == 0) {
5280 if (uprv_stricmp(maximal
, buffer
) != 0) {
5281 log_err(" unexpected minimal value \"%s\" in uloc_minimizeSubtags(), maximal \"%s\" = \"%s\"\n", minimal
, maximal
, buffer
);
5284 else if (uprv_stricmp(minimal
, buffer
) != 0) {
5285 log_err(" minimal doesn't match expected %s in uloc_MinimizeSubtags(), maximal \"%s\" = %s\n", minimal
, maximal
, buffer
);
5289 for (i
= 0; i
< sizeof(full_data
) / sizeof(full_data
[0]); ++i
) {
5291 UErrorCode status
= U_ZERO_ERROR
;
5292 const char* const minimal
= full_data
[i
][0];
5293 const char* const maximal
= full_data
[i
][1];
5295 /* const int32_t length = */
5296 uloc_addLikelySubtags(
5301 if (U_FAILURE(status
)) {
5302 log_err_status(status
, " unexpected failure of uloc_addLikelySubtags(), minimal \"%s\" status \"%s\"\n", minimal
, u_errorName(status
));
5303 status
= U_ZERO_ERROR
;
5305 else if (uprv_strlen(maximal
) == 0) {
5306 if (uprv_stricmp(minimal
, buffer
) != 0) {
5307 log_err(" unexpected maximal value \"%s\" in uloc_addLikelySubtags(), minimal \"%s\" = \"%s\"\n", maximal
, minimal
, buffer
);
5310 else if (uprv_stricmp(maximal
, buffer
) != 0) {
5311 log_err(" maximal doesn't match expected \"%s\" in uloc_addLikelySubtags(), minimal \"%s\" = \"%s\"\n", maximal
, minimal
, buffer
);
5315 for (i
= 0; i
< sizeof(full_data
) / sizeof(full_data
[0]); ++i
) {
5317 UErrorCode status
= U_ZERO_ERROR
;
5318 const char* const maximal
= full_data
[i
][1];
5319 const char* const minimal
= full_data
[i
][2];
5321 if (strlen(maximal
) > 0) {
5323 /* const int32_t length = */
5324 uloc_minimizeSubtags(
5330 if (U_FAILURE(status
)) {
5331 log_err_status(status
, " unexpected failure of uloc_minimizeSubtags(), maximal \"%s\" status %s\n", maximal
, u_errorName(status
));
5332 status
= U_ZERO_ERROR
;
5334 else if (uprv_strlen(minimal
) == 0) {
5335 if (uprv_stricmp(maximal
, buffer
) != 0) {
5336 log_err(" unexpected minimal value \"%s\" in uloc_minimizeSubtags(), maximal \"%s\" = \"%s\"\n", minimal
, maximal
, buffer
);
5339 else if (uprv_stricmp(minimal
, buffer
) != 0) {
5340 log_err(" minimal doesn't match expected %s in uloc_MinimizeSubtags(), maximal \"%s\" = %s\n", minimal
, maximal
, buffer
);
5345 for (i
= 0; i
< sizeof(maximizeErrors
) / sizeof(maximizeErrors
[0]); ++i
) {
5347 UErrorCode status
= U_ZERO_ERROR
;
5348 const char* const minimal
= maximizeErrors
[i
].tag
;
5349 const char* const maximal
= maximizeErrors
[i
].expected
;
5350 const UErrorCode expectedStatus
= maximizeErrors
[i
].uerror
;
5351 const int32_t expectedLength
= getExpectedReturnValue(&maximizeErrors
[i
]);
5352 const int32_t bufferSize
= getBufferSize(&maximizeErrors
[i
], sizeof(buffer
));
5354 const int32_t length
=
5355 uloc_addLikelySubtags(
5361 if (status
== U_ZERO_ERROR
) {
5362 log_err(" unexpected U_ZERO_ERROR for uloc_addLikelySubtags(), minimal \"%s\" expected status %s\n", minimal
, u_errorName(expectedStatus
));
5363 status
= U_ZERO_ERROR
;
5365 else if (status
!= expectedStatus
) {
5366 log_err_status(status
, " unexpected status for uloc_addLikelySubtags(), minimal \"%s\" expected status %s, but got %s\n", minimal
, u_errorName(expectedStatus
), u_errorName(status
));
5368 else if (length
!= expectedLength
) {
5369 log_err(" unexpected length for uloc_addLikelySubtags(), minimal \"%s\" expected length %d, but got %d\n", minimal
, expectedLength
, length
);
5371 else if (status
== U_BUFFER_OVERFLOW_ERROR
|| status
== U_STRING_NOT_TERMINATED_WARNING
) {
5372 if (uprv_strnicmp(maximal
, buffer
, bufferSize
) != 0) {
5373 log_err(" maximal doesn't match expected %s in uloc_addLikelySubtags(), minimal \"%s\" = %*s\n",
5374 maximal
, minimal
, (int)sizeof(buffer
), buffer
);
5379 for (i
= 0; i
< sizeof(minimizeErrors
) / sizeof(minimizeErrors
[0]); ++i
) {
5381 UErrorCode status
= U_ZERO_ERROR
;
5382 const char* const maximal
= minimizeErrors
[i
].tag
;
5383 const char* const minimal
= minimizeErrors
[i
].expected
;
5384 const UErrorCode expectedStatus
= minimizeErrors
[i
].uerror
;
5385 const int32_t expectedLength
= getExpectedReturnValue(&minimizeErrors
[i
]);
5386 const int32_t bufferSize
= getBufferSize(&minimizeErrors
[i
], sizeof(buffer
));
5388 const int32_t length
=
5389 uloc_minimizeSubtags(
5395 if (status
== U_ZERO_ERROR
) {
5396 log_err(" unexpected U_ZERO_ERROR for uloc_minimizeSubtags(), maximal \"%s\" expected status %s\n", maximal
, u_errorName(expectedStatus
));
5397 status
= U_ZERO_ERROR
;
5399 else if (status
!= expectedStatus
) {
5400 log_err_status(status
, " unexpected status for uloc_minimizeSubtags(), maximal \"%s\" expected status %s, but got %s\n", maximal
, u_errorName(expectedStatus
), u_errorName(status
));
5402 else if (length
!= expectedLength
) {
5403 log_err(" unexpected length for uloc_minimizeSubtags(), maximal \"%s\" expected length %d, but got %d\n", maximal
, expectedLength
, length
);
5405 else if (status
== U_BUFFER_OVERFLOW_ERROR
|| status
== U_STRING_NOT_TERMINATED_WARNING
) {
5406 if (uprv_strnicmp(minimal
, buffer
, bufferSize
) != 0) {
5407 log_err(" minimal doesn't match expected \"%s\" in uloc_minimizeSubtags(), minimal \"%s\" = \"%*s\"\n",
5408 minimal
, maximal
, (int)sizeof(buffer
), buffer
);
5414 const char* const locale_to_langtag
[][3] = {
5415 {"@x=elmer", "x-elmer", "x-elmer"},
5418 {"en_US", "en-US", "en-US"},
5419 {"iw_IL", "he-IL", "he-IL"},
5420 {"sr_Latn_SR", "sr-Latn-SR", "sr-Latn-SR"},
5421 {"en__POSIX", "en-u-va-posix", "en-u-va-posix"},
5422 {"en_POSIX", "en-u-va-posix", "en-u-va-posix"},
5423 {"en_US_POSIX@ca=japanese", "en-US-u-ca-japanese-va-posix", "en-US-u-ca-japanese-va-posix"},
5424 {"und_555", "und-555", "und-555"},
5425 {"123", "und", NULL
},
5426 {"%$#&", "und", NULL
},
5427 {"_Latn", "und-Latn", "und-Latn"},
5428 {"_DE", "und-DE", "und-DE"},
5429 {"und_FR", "und-FR", "und-FR"},
5430 {"th_TH_TH", "th-TH", NULL
},
5431 {"bogus", "bogus", "bogus"},
5432 {"foooobarrr", "und", NULL
},
5433 {"az_AZ_CYRL", "az-Cyrl-AZ", "az-Cyrl-AZ"},
5434 {"aa_BB_CYRL", "aa-BB", NULL
},
5435 {"en_US_1234", "en-US-1234", "en-US-1234"},
5436 {"en_US_VARIANTA_VARIANTB", "en-US-varianta-variantb", "en-US-varianta-variantb"},
5437 {"en_US_VARIANTB_VARIANTA", "en-US-varianta-variantb", "en-US-varianta-variantb"},
5438 {"ja__9876_5432", "ja-5432-9876", "ja-5432-9876"},
5439 {"zh_Hant__VAR", "zh-Hant", NULL
},
5440 {"es__BADVARIANT_GOODVAR", "es-goodvar", NULL
},
5441 {"en@calendar=gregorian", "en-u-ca-gregory", "en-u-ca-gregory"},
5442 {"de@collation=phonebook;calendar=gregorian", "de-u-ca-gregory-co-phonebk", "de-u-ca-gregory-co-phonebk"},
5443 {"th@numbers=thai;z=extz;x=priv-use;a=exta", "th-a-exta-u-nu-thai-z-extz-x-priv-use", "th-a-exta-u-nu-thai-z-extz-x-priv-use"},
5444 {"en@timezone=America/New_York;calendar=japanese", "en-u-ca-japanese-tz-usnyc", "en-u-ca-japanese-tz-usnyc"},
5445 {"en@timezone=US/Eastern", "en-u-tz-usnyc", "en-u-tz-usnyc"},
5446 {"en@x=x-y-z;a=a-b-c", "en-x-x-y-z", NULL
},
5447 {"it@collation=badcollationtype;colStrength=identical;cu=usd-eur", "it-u-ks-identic", NULL
},
5448 {"en_US_POSIX", "en-US-u-va-posix", "en-US-u-va-posix"},
5449 {"en_US_POSIX@calendar=japanese;currency=EUR","en-US-u-ca-japanese-cu-EUR-va-posix", "en-US-u-ca-japanese-cu-EUR-va-posix"},
5450 {"@x=elmer", "x-elmer", "x-elmer"},
5451 {"en@x=elmer", "en-x-elmer", "en-x-elmer"},
5452 {"@x=elmer;a=exta", "und-a-exta-x-elmer", "und-a-exta-x-elmer"},
5457 static void TestToLanguageTag(void) {
5463 const char *expected
;
5465 for (i
= 0; locale_to_langtag
[i
][0] != NULL
; i
++) {
5466 inloc
= locale_to_langtag
[i
][0];
5468 /* testing non-strict mode */
5469 status
= U_ZERO_ERROR
;
5471 expected
= locale_to_langtag
[i
][1];
5473 len
= uloc_toLanguageTag(inloc
, langtag
, sizeof(langtag
), FALSE
, &status
);
5474 if (U_FAILURE(status
)) {
5475 if (expected
!= NULL
) {
5476 log_err("Error returned by uloc_toLanguageTag for locale id [%s] - error: %s\n",
5477 inloc
, u_errorName(status
));
5480 if (expected
== NULL
) {
5481 log_err("Error should be returned by uloc_toLanguageTag for locale id [%s], but [%s] is returned without errors\n",
5483 } else if (uprv_strcmp(langtag
, expected
) != 0) {
5484 log_data_err("uloc_toLanguageTag returned language tag [%s] for input locale [%s] - expected: [%s]. Are you missing data?\n",
5485 langtag
, inloc
, expected
);
5489 /* testing strict mode */
5490 status
= U_ZERO_ERROR
;
5492 expected
= locale_to_langtag
[i
][2];
5494 len
= uloc_toLanguageTag(inloc
, langtag
, sizeof(langtag
), TRUE
, &status
);
5495 if (U_FAILURE(status
)) {
5496 if (expected
!= NULL
) {
5497 log_data_err("Error returned by uloc_toLanguageTag {strict} for locale id [%s] - error: %s Are you missing data?\n",
5498 inloc
, u_errorName(status
));
5501 if (expected
== NULL
) {
5502 log_err("Error should be returned by uloc_toLanguageTag {strict} for locale id [%s], but [%s] is returned without errors\n",
5504 } else if (uprv_strcmp(langtag
, expected
) != 0) {
5505 log_err("uloc_toLanguageTag {strict} returned language tag [%s] for input locale [%s] - expected: [%s]\n",
5506 langtag
, inloc
, expected
);
5512 static const struct {
5516 } langtag_to_locale
[] = {
5518 {"en-us", "en_US", 5},
5519 {"und-US", "_US", 6},
5520 {"und-latn", "_Latn", 8},
5521 {"en-US-posix", "en_US_POSIX", 11},
5522 {"de-de_euro", "de", 2},
5523 {"kok-IN", "kok_IN", 6},
5526 {"en-latn-x", "en_Latn", 7},
5527 {"art-lojban", "jbo", 10},
5528 {"zh-hakka", "hak", 8},
5529 {"zh-cmn-CH", "cmn_CH", 9},
5530 {"xxx-yy", "xxx_YY", 6},
5531 {"fr-234", "fr_234", 6},
5532 {"i-default", "", 9},
5534 {"ja-jp-jp", "ja_JP", 5},
5535 {"bogus", "bogus", 5},
5536 {"boguslang", "", 0},
5537 {"EN-lATN-us", "en_Latn_US", 10},
5538 {"und-variant-1234", "__1234_VARIANT", 16},
5539 {"und-varzero-var1-vartwo", "__VARZERO", 11},
5540 {"en-u-ca-gregory", "en@calendar=gregorian", 15},
5541 {"en-U-cu-USD", "en@currency=usd", 11},
5542 {"en-US-u-va-posix", "en_US_POSIX", 16},
5543 {"ar-x-1-2-3", "ar@x=1-2-3", 10},
5544 {"fr-u-nu-latn-cu-eur", "fr@currency=eur;numbers=latn", 19},
5545 {"de-k-kext-u-co-phonebk-nu-latn", "de@collation=phonebook;k=kext;numbers=latn", 30},
5546 {"ja-u-cu-jpy-ca-jp", "ja@currency=jpy", 11},
5547 {"en-us-u-tz-usnyc", "en_US@timezone=America/New_York", 16},
5548 {"und-a-abc-def", "und@a=abc-def", 13},
5549 {"zh-u-ca-chinese-x-u-ca-chinese", "zh@calendar=chinese;x=u-ca-chinese", 30},
5550 {"x-elmer", "@x=elmer", 7},
5554 static void TestForLanguageTag(void) {
5560 for (i
= 0; langtag_to_locale
[i
].bcpID
!= NULL
; i
++) {
5561 status
= U_ZERO_ERROR
;
5563 uloc_forLanguageTag(langtag_to_locale
[i
].bcpID
, locale
, sizeof(locale
), &parsedLen
, &status
);
5564 if (U_FAILURE(status
)) {
5565 log_err_status(status
, "Error returned by uloc_forLanguageTag for language tag [%s] - error: %s\n",
5566 langtag_to_locale
[i
].bcpID
, u_errorName(status
));
5568 if (uprv_strcmp(langtag_to_locale
[i
].locID
, locale
) != 0) {
5569 log_err("uloc_forLanguageTag returned locale [%s] for input language tag [%s] - expected: [%s]\n",
5570 locale
, langtag_to_locale
[i
].bcpID
, langtag_to_locale
[i
].locID
);
5572 if (parsedLen
!= langtag_to_locale
[i
].len
) {
5573 log_err("uloc_forLanguageTag parsed length of %d for input language tag [%s] - expected parsed length: %d\n",
5574 parsedLen
, langtag_to_locale
[i
].bcpID
, langtag_to_locale
[i
].len
);
5580 static void test_unicode_define(const char *namech
, char ch
, const char *nameu
, UChar uch
)
5584 log_verbose("Testing whether %s[\\x%02x,'%c'] == %s[U+%04X]\n", namech
, ch
,(int)ch
, nameu
, (int) uch
);
5585 u_charsToUChars(&ch
, asUch
, 1);
5586 if(asUch
[0] != uch
) {
5587 log_err("FAIL: %s[\\x%02x,'%c'] maps to U+%04X, but %s = U+%04X\n", namech
, ch
, (int)ch
, (int)asUch
[0], nameu
, (int)uch
);
5589 log_verbose(" .. OK, == U+%04X\n", (int)asUch
[0]);
5593 #define TEST_UNICODE_DEFINE(x,y) test_unicode_define(#x, (char)(x), #y, (UChar)(y))
5595 static void TestUnicodeDefines(void) {
5596 TEST_UNICODE_DEFINE(ULOC_KEYWORD_SEPARATOR
, ULOC_KEYWORD_SEPARATOR_UNICODE
);
5597 TEST_UNICODE_DEFINE(ULOC_KEYWORD_ASSIGN
, ULOC_KEYWORD_ASSIGN_UNICODE
);
5598 TEST_UNICODE_DEFINE(ULOC_KEYWORD_ITEM_SEPARATOR
, ULOC_KEYWORD_ITEM_SEPARATOR_UNICODE
);