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