]> git.saurik.com Git - apple/icu.git/blame - icuSources/test/cintltst/cloctst.c
ICU-400.39.tar.gz
[apple/icu.git] / icuSources / test / cintltst / cloctst.c
CommitLineData
b75a7d8f
A
1/********************************************************************
2 * COPYRIGHT:
46f4442e 3 * Copyright (c) 1997-2008, International Business Machines Corporation and
b75a7d8f
A
4 * others. All Rights Reserved.
5 ********************************************************************/
46f4442e 6/*****************************************************************************
b75a7d8f
A
7*
8* File CLOCTST.C
9*
10* Modification History:
11* Name Description
12* Madhu Katragadda Ported for C API
46f4442e 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);
46f4442e 41static void TestLocDataErrorCodeChaining(void);
73c04bcf
A
42static void TestLanguageExemplarsFallbacks(void);
43
b75a7d8f
A
44void PrintDataTable();
45
46/*---------------------------------------------------
47 table of valid data
48 --------------------------------------------------- */
374ca955
A
49#define LOCALE_SIZE 9
50#define LOCALE_INFO_SIZE 28
b75a7d8f 51
46f4442e 52static const char* const rawData2[LOCALE_INFO_SIZE][LOCALE_SIZE] = {
b75a7d8f 53 /* language code */
374ca955
A
54 { "en", "fr", "ca", "el", "no", "zh", "de", "es", "ja" },
55 /* script code */
56 { "", "", "", "", "", "Hans", "", "", "" },
b75a7d8f 57 /* country code */
374ca955 58 { "US", "FR", "ES", "GR", "NO", "CN", "DE", "", "JP" },
b75a7d8f 59 /* variant code */
374ca955 60 { "", "", "", "", "NY", "", "", "", "" },
b75a7d8f 61 /* full name */
374ca955
A
62 { "en_US", "fr_FR", "ca_ES",
63 "el_GR", "no_NO_NY", "zh_Hans_CN",
64 "de_DE@collation=phonebook", "es@collation=traditional", "ja_JP@calendar=japanese" },
b75a7d8f 65 /* ISO-3 language */
374ca955 66 { "eng", "fra", "cat", "ell", "nor", "zho", "deu", "spa", "jpn" },
b75a7d8f 67 /* ISO-3 country */
374ca955
A
68 { "USA", "FRA", "ESP", "GRC", "NOR", "CHN", "DEU", "", "JPN" },
69 /* LCID */
73c04bcf 70 { "409", "40c", "403", "408", "814", "804", "10407", "40a", "411" },
b75a7d8f
A
71
72 /* display language (English) */
374ca955
A
73 { "English", "French", "Catalan", "Greek", "Norwegian", "Chinese", "German", "Spanish", "Japanese" },
74 /* display script code (English) */
75 { "", "", "", "", "", "Simplified Han", "", "", "" },
b75a7d8f 76 /* display country (English) */
374ca955 77 { "United States", "France", "Spain", "Greece", "Norway", "China", "Germany", "", "Japan" },
b75a7d8f 78 /* display variant (English) */
374ca955 79 { "", "", "", "", "NY", "", "", "", "" },
b75a7d8f 80 /* display name (English) */
374ca955
A
81 { "English (United States)", "French (France)", "Catalan (Spain)",
82 "Greek (Greece)", "Norwegian (Norway, NY)", "Chinese (Simplified Han, China)",
46f4442e 83 "German (Germany, collation=Phonebook Sort Order)", "Spanish (collation=Traditional Sort Order)", "Japanese (Japan, calendar=Japanese Calendar)" },
b75a7d8f
A
84
85 /* display language (French) */
374ca955
A
86 { "anglais", "fran\\u00E7ais", "catalan", "grec", "norv\\u00E9gien", "chinois", "allemand", "espagnol", "japonais" },
87 /* display script code (French) */
46f4442e 88 { "", "", "", "", "", "id\\u00e9ogrammes han simplifi\\u00e9s", "", "", "" },
b75a7d8f 89 /* display country (French) */
374ca955 90 { "\\u00C9tats-Unis", "France", "Espagne", "Gr\\u00E8ce", "Norv\\u00E8ge", "Chine", "Allemagne", "", "Japon" },
b75a7d8f 91 /* display variant (French) */
374ca955 92 { "", "", "", "", "NY", "", "", "", "" },
b75a7d8f 93 /* display name (French) */
374ca955 94 { "anglais (\\u00C9tats-Unis)", "fran\\u00E7ais (France)", "catalan (Espagne)",
46f4442e 95 "grec (Gr\\u00E8ce)", "norv\\u00E9gien (Norv\\u00E8ge, NY)", "chinois (id\\u00e9ogrammes han simplifi\\u00e9s, Chine)",
374ca955
A
96 "allemand (Allemagne, Ordonnancement=Ordre de l\\u2019annuaire)", "espagnol (Ordonnancement=Ordre traditionnel)", "japonais (Japon, Calendrier=Calendrier japonais)" },
97
98 /* display language (Catalan) */
46f4442e 99 { "angl\\u00E8s", "franc\\u00E8s", "catal\\u00E0", "grec", "noruec", "xin\\u00E8s", "alemany", "espanyol", "japon\\u00E8s" },
374ca955 100 /* display script code (Catalan) */
46f4442e 101 { "", "", "", "", "", "Xin\\u00e8s Simplificat (Han)", "", "", "" },
374ca955
A
102 /* display country (Catalan) */
103 { "Estats Units", "Fran\\u00E7a", "Espanya", "Gr\\u00E8cia", "Noruega", "Xina", "Alemanya", "", "Jap\\u00F3" },
104 /* display variant (Catalan) */
105 { "", "", "", "", "NY", "", "", "", "" },
106 /* display name (Catalan) */
107 { "angl\\u00E8s (Estats Units)", "franc\\u00E8s (Fran\\u00E7a)", "catal\\u00E0 (Espanya)",
46f4442e
A
108 "grec (Gr\\u00E8cia)", "noruec (Noruega, NY)", "xin\\u00E8s (Xin\\u00e8s Simplificat (Han), Xina)",
109 "alemany (Alemanya, ordre alfab\\u00e8tic=phonebook)", "espanyol (ordre alfab\\u00e8tic=traditional)", "japon\\u00E8s (Jap\\u00F3, calendari=calendari japon\\u00e8s)" },
b75a7d8f
A
110
111 /* display language (Greek) */
112 {
113 "\\u0391\\u03b3\\u03b3\\u03bb\\u03b9\\u03ba\\u03ac",
114 "\\u0393\\u03b1\\u03bb\\u03bb\\u03b9\\u03ba\\u03ac",
374ca955
A
115 "\\u039a\\u03b1\\u03c4\\u03b1\\u03bb\\u03b1\\u03bd\\u03b9\\u03ba\\u03ac",
116 "\\u0395\\u03bb\\u03bb\\u03b7\\u03bd\\u03b9\\u03ba\\u03ac",
117 "\\u039d\\u03bf\\u03c1\\u03b2\\u03b7\\u03b3\\u03b9\\u03ba\\u03ac",
118 "\\u039A\\u03B9\\u03BD\\u03B5\\u03B6\\u03B9\\u03BA\\u03AC",
119 "\\u0393\\u03B5\\u03C1\\u03BC\\u03B1\\u03BD\\u03B9\\u03BA\\u03AC",
120 "\\u0399\\u03C3\\u03C0\\u03B1\\u03BD\\u03B9\\u03BA\\u03AC",
121 "\\u0399\\u03B1\\u03C0\\u03C9\\u03BD\\u03B9\\u03BA\\u03AC"
b75a7d8f 122 },
374ca955 123 /* display script code (Greek) */
46f4442e
A
124
125 { "", "", "", "", "", "\\u039a\\u03b9\\u03bd\\u03b5\\u03b6\\u03b9\\u03ba\\u03cc \\u0391\\u03c0\\u03bb\\u03bf\\u03c0\\u03bf\\u03b9\\u03b7\\u03bc\\u03ad\\u03bd\\u03bf", "", "", "" },
b75a7d8f
A
126 /* display country (Greek) */
127 {
374ca955 128 "\\u0397\\u03bd\\u03c9\\u03bc\\u03ad\\u03bd\\u03b5\\u03c2 \\u03a0\\u03bf\\u03bb\\u03b9\\u03c4\\u03b5\\u03af\\u03b5\\u03c2",
b75a7d8f 129 "\\u0393\\u03b1\\u03bb\\u03bb\\u03af\\u03b1",
374ca955 130 "\\u0399\\u03c3\\u03c0\\u03b1\\u03bd\\u03af\\u03b1",
b75a7d8f 131 "\\u0395\\u03bb\\u03bb\\u03ac\\u03b4\\u03b1",
374ca955
A
132 "\\u039d\\u03bf\\u03c1\\u03b2\\u03b7\\u03b3\\u03af\\u03b1",
133 "\\u039A\\u03AF\\u03BD\\u03B1",
134 "\\u0393\\u03B5\\u03C1\\u03BC\\u03B1\\u03BD\\u03AF\\u03B1",
135 "",
136 "\\u0399\\u03B1\\u03C0\\u03C9\\u03BD\\u03AF\\u03B1"
b75a7d8f
A
137 },
138 /* display variant (Greek) */
374ca955 139 { "", "", "", "", "NY", "", "", "", "" }, /* TODO: currently there is no translation for NY in Greek fix this test when we have it */
b75a7d8f
A
140 /* display name (Greek) */
141 {
374ca955 142 "\\u0391\\u03b3\\u03b3\\u03bb\\u03b9\\u03ba\\u03ac (\\u0397\\u03bd\\u03c9\\u03bc\\u03ad\\u03bd\\u03b5\\u03c2 \\u03a0\\u03bf\\u03bb\\u03b9\\u03c4\\u03b5\\u03af\\u03b5\\u03c2)",
b75a7d8f 143 "\\u0393\\u03b1\\u03bb\\u03bb\\u03b9\\u03ba\\u03ac (\\u0393\\u03b1\\u03bb\\u03bb\\u03af\\u03b1)",
374ca955
A
144 "\\u039a\\u03b1\\u03c4\\u03b1\\u03bb\\u03b1\\u03bd\\u03b9\\u03ba\\u03ac (\\u0399\\u03c3\\u03c0\\u03b1\\u03bd\\u03af\\u03b1)",
145 "\\u0395\\u03bb\\u03bb\\u03b7\\u03bd\\u03b9\\u03ba\\u03ac (\\u0395\\u03bb\\u03bb\\u03ac\\u03b4\\u03b1)",
146 "\\u039d\\u03bf\\u03c1\\u03b2\\u03b7\\u03b3\\u03b9\\u03ba\\u03ac (\\u039d\\u03bf\\u03c1\\u03b2\\u03b7\\u03b3\\u03af\\u03b1, NY)",
46f4442e 147 "\\u039A\\u03B9\\u03BD\\u03B5\\u03B6\\u03B9\\u03BA\\u03AC (\\u039a\\u03b9\\u03bd\\u03b5\\u03b6\\u03b9\\u03ba\\u03cc \\u0391\\u03c0\\u03bb\\u03bf\\u03c0\\u03bf\\u03b9\\u03b7\\u03bc\\u03ad\\u03bd\\u03bf, \\u039A\\u03AF\\u03BD\\u03B1)",
374ca955 148 "\\u0393\\u03B5\\u03C1\\u03BC\\u03B1\\u03BD\\u03B9\\u03BA\\u03AC (\\u0393\\u03B5\\u03C1\\u03BC\\u03B1\\u03BD\\u03AF\\u03B1, \\u03A4\\u03B1\\u03BA\\u03C4\\u03BF\\u03C0\\u03BF\\u03AF\\u03B7\\u03C3\\u03B7=\\u03A3\\u03B5\\u03B9\\u03C1\\u03AC \\u03A4\\u03B7\\u03BB\\u03B5\\u03C6\\u03C9\\u03BD\\u03B9\\u03BA\\u03BF\\u03CD \\u039A\\u03B1\\u03C4\\u03B1\\u03BB\\u03CC\\u03B3\\u03BF\\u03C5)",
46f4442e 149 "\\u0399\\u03C3\\u03C0\\u03B1\\u03BD\\u03B9\\u03BA\\u03AC (\\u03A4\\u03B1\\u03BA\\u03C4\\u03BF\\u03C0\\u03BF\\u03AF\\u03B7\\u03C3\\u03B7\\u003D\\u03A0\\u03B1\\u03C1\\u03B1\\u03B4\\u03BF\\u03C3\\u03B9\\u03B1\\u03BA\\u03AE \\u03A3\\u03B5\\u03B9\\u03C1\\u03AC)",
374ca955 150 "\\u0399\\u03B1\\u03C0\\u03C9\\u03BD\\u03B9\\u03BA\\u03AC (\\u0399\\u03B1\\u03C0\\u03C9\\u03BD\\u03AF\\u03B1, \\u0397\\u03BC\\u03B5\\u03C1\\u03BF\\u03BB\\u03CC\\u03B3\\u03B9\\u03BF=\\u0399\\u03B1\\u03C0\\u03C9\\u03BD\\u03B9\\u03BA\\u03CC \\u0397\\u03BC\\u03B5\\u03C1\\u03BF\\u03BB\\u03CC\\u03B3\\u03B9\\u03BF)"
b75a7d8f
A
151 }
152};
153
154static UChar*** dataTable=0;
155enum {
156 ENGLISH = 0,
157 FRENCH = 1,
374ca955 158 CATALAN = 2,
b75a7d8f
A
159 GREEK = 3,
160 NORWEGIAN = 4
161};
162
163enum {
164 LANG = 0,
374ca955
A
165 SCRIPT = 1,
166 CTRY = 2,
167 VAR = 3,
168 NAME = 4,
169 LANG3 = 5,
170 CTRY3 = 6,
171 LCID = 7,
172 DLANG_EN = 8,
173 DSCRIPT_EN = 9,
174 DCTRY_EN = 10,
175 DVAR_EN = 11,
176 DNAME_EN = 12,
177 DLANG_FR = 13,
178 DSCRIPT_FR = 14,
179 DCTRY_FR = 15,
180 DVAR_FR = 16,
181 DNAME_FR = 17,
182 DLANG_CA = 18,
183 DSCRIPT_CA = 19,
184 DCTRY_CA = 20,
185 DVAR_CA = 21,
186 DNAME_CA = 22,
187 DLANG_EL = 23,
188 DSCRIPT_EL = 24,
189 DCTRY_EL = 25,
190 DVAR_EL = 26,
191 DNAME_EL = 27
b75a7d8f
A
192};
193
374ca955
A
194#define TESTCASE(name) addTest(root, &name, "tsutil/cloctst/" #name)
195
b75a7d8f
A
196void addLocaleTest(TestNode** root);
197
198void addLocaleTest(TestNode** root)
199{
374ca955
A
200 TESTCASE(TestObsoleteNames); /* srl- move */
201 TESTCASE(TestBasicGetters);
202 TESTCASE(TestNullDefault);
203 TESTCASE(TestPrefixes);
204 TESTCASE(TestSimpleResourceInfo);
205 TESTCASE(TestDisplayNames);
206 TESTCASE(TestGetAvailableLocales);
207 TESTCASE(TestDataDirectory);
208 TESTCASE(TestISOFunctions);
209 TESTCASE(TestISO3Fallback);
210 TESTCASE(TestUninstalledISO3Names);
211 TESTCASE(TestSimpleDisplayNames);
212 TESTCASE(TestVariantParsing);
374ca955
A
213 TESTCASE(TestKeywordVariants);
214 TESTCASE(TestKeywordVariantParsing);
215 TESTCASE(TestCanonicalization);
216 TESTCASE(TestKeywordSet);
217 TESTCASE(TestKeywordSetError);
218 TESTCASE(TestDisplayKeywords);
219 TESTCASE(TestDisplayKeywordValues);
220 TESTCASE(TestGetBaseName);
221 TESTCASE(TestGetLocale);
222 TESTCASE(TestDisplayNameWarning);
223 TESTCASE(TestNonexistentLanguageExemplars);
46f4442e 224 TESTCASE(TestLocDataErrorCodeChaining);
73c04bcf
A
225 TESTCASE(TestLanguageExemplarsFallbacks);
226 TESTCASE(TestCalendar);
227 TESTCASE(TestDateFormat);
228 TESTCASE(TestCollation);
229 TESTCASE(TestULocale);
230 TESTCASE(TestUResourceBundle);
231 TESTCASE(TestDisplayName);
232 TESTCASE(TestAcceptLanguage);
233 TESTCASE(TestGetLocaleForLCID);
46f4442e
A
234 TESTCASE(TestOrientation);
235 TESTCASE(TestLikelySubtags);
b75a7d8f
A
236}
237
238
239/* testing uloc(), uloc_getName(), uloc_getLanguage(), uloc_getVariant(), uloc_getCountry() */
240static void TestBasicGetters() {
241 int32_t i;
242 int32_t cap;
243 UErrorCode status = U_ZERO_ERROR;
244 char *testLocale = 0;
245 char *temp = 0, *name = 0;
246 log_verbose("Testing Basic Getters\n");
247 for (i = 0; i < LOCALE_SIZE; i++) {
248 testLocale=(char*)malloc(sizeof(char) * (strlen(rawData2[NAME][i])+1));
249 strcpy(testLocale,rawData2[NAME][i]);
250
251 log_verbose("Testing %s .....\n", testLocale);
252 cap=uloc_getLanguage(testLocale, NULL, 0, &status);
253 if(status==U_BUFFER_OVERFLOW_ERROR){
254 status=U_ZERO_ERROR;
255 temp=(char*)malloc(sizeof(char) * (cap+1));
256 uloc_getLanguage(testLocale, temp, cap+1, &status);
257 }
258 if(U_FAILURE(status)){
259 log_err("ERROR: in uloc_getLanguage %s\n", myErrorName(status));
260 }
261 if (0 !=strcmp(temp,rawData2[LANG][i])) {
262 log_err(" Language code mismatch: %s versus %s\n", temp, rawData2[LANG][i]);
263 }
264
265
266 cap=uloc_getCountry(testLocale, temp, cap, &status);
267 if(status==U_BUFFER_OVERFLOW_ERROR){
268 status=U_ZERO_ERROR;
269 temp=(char*)realloc(temp, sizeof(char) * (cap+1));
270 uloc_getCountry(testLocale, temp, cap+1, &status);
271 }
272 if(U_FAILURE(status)){
273 log_err("ERROR: in uloc_getCountry %s\n", myErrorName(status));
274 }
275 if (0 != strcmp(temp, rawData2[CTRY][i])) {
276 log_err(" Country code mismatch: %s versus %s\n", temp, rawData2[CTRY][i]);
277
278 }
279
280 cap=uloc_getVariant(testLocale, temp, cap, &status);
281 if(status==U_BUFFER_OVERFLOW_ERROR){
282 status=U_ZERO_ERROR;
283 temp=(char*)realloc(temp, sizeof(char) * (cap+1));
284 uloc_getVariant(testLocale, temp, cap+1, &status);
285 }
286 if(U_FAILURE(status)){
287 log_err("ERROR: in uloc_getVariant %s\n", myErrorName(status));
288 }
289 if (0 != strcmp(temp, rawData2[VAR][i])) {
290 log_err("Variant code mismatch: %s versus %s\n", temp, rawData2[VAR][i]);
291 }
292
293 cap=uloc_getName(testLocale, NULL, 0, &status);
294 if(status==U_BUFFER_OVERFLOW_ERROR){
295 status=U_ZERO_ERROR;
296 name=(char*)malloc(sizeof(char) * (cap+1));
297 uloc_getName(testLocale, name, cap+1, &status);
298 } else if(status==U_ZERO_ERROR) {
299 log_err("ERROR: in uloc_getName(%s,NULL,0,..), expected U_BUFFER_OVERFLOW_ERROR!\n", testLocale);
300 }
301 if(U_FAILURE(status)){
302 log_err("ERROR: in uloc_getName %s\n", myErrorName(status));
303 }
304 if (0 != strcmp(name, rawData2[NAME][i])){
305 log_err(" Mismatch in getName: %s versus %s\n", name, rawData2[NAME][i]);
306 }
307
b75a7d8f
A
308 free(temp);
309 free(name);
310
311 free(testLocale);
312 }
313}
314
315static void TestNullDefault() {
316 UErrorCode status = U_ZERO_ERROR;
317 char original[ULOC_FULLNAME_CAPACITY];
318
319 uprv_strcpy(original, uloc_getDefault());
320 uloc_setDefault("qq_BLA", &status);
321 if (uprv_strcmp(uloc_getDefault(), "qq_BLA") != 0) {
322 log_err(" Mismatch in uloc_setDefault: qq_BLA versus %s\n", uloc_getDefault());
323 }
324 uloc_setDefault(NULL, &status);
325 if (uprv_strcmp(uloc_getDefault(), original) != 0) {
326 log_err(" uloc_setDefault(NULL, &status) didn't get the default locale back!\n");
327 }
374ca955
A
328
329 {
330 /* Test that set & get of default locale work, and that
331 * default locales are cached and reused, and not overwritten.
332 */
333 const char *n_en_US;
334 const char *n_fr_FR;
335 const char *n2_en_US;
336
337 status = U_ZERO_ERROR;
338 uloc_setDefault("en_US", &status);
339 n_en_US = uloc_getDefault();
340 if (strcmp(n_en_US, "en_US") != 0) {
341 log_err("Wrong result from uloc_getDefault(). Expected \"en_US\", got \"%s\"\n", n_en_US);
342 }
343
344 uloc_setDefault("fr_FR", &status);
345 n_fr_FR = uloc_getDefault();
346 if (strcmp(n_en_US, "en_US") != 0) {
347 log_err("uloc_setDefault altered previously default string."
348 "Expected \"en_US\", got \"%s\"\n", n_en_US);
349 }
350 if (strcmp(n_fr_FR, "fr_FR") != 0) {
351 log_err("Wrong result from uloc_getDefault(). Expected \"fr_FR\", got %s\n", n_fr_FR);
352 }
353
354 uloc_setDefault("en_US", &status);
355 n2_en_US = uloc_getDefault();
356 if (strcmp(n2_en_US, "en_US") != 0) {
357 log_err("Wrong result from uloc_getDefault(). Expected \"en_US\", got \"%s\"\n", n_en_US);
358 }
359 if (n2_en_US != n_en_US) {
360 log_err("Default locale cache failed to reuse en_US locale.\n");
361 }
362
363 if (U_FAILURE(status)) {
364 log_err("Failure returned from uloc_setDefault - \"%s\"\n", u_errorName(status));
365 }
366
367 }
368
b75a7d8f
A
369}
370/* Test the i- and x- and @ and . functionality
371*/
372
373#define PREFIXBUFSIZ 128
374
375static void TestPrefixes() {
374ca955
A
376 int row = 0;
377 int n;
378 const char *loc, *expected;
379
46f4442e 380 static const char * const testData[][7] =
374ca955
A
381 {
382 /* NULL canonicalize() column means "expect same as getName()" */
383 {"sv", "", "FI", "AL", "sv-fi-al", "sv_FI_AL", NULL},
384 {"en", "", "GB", "", "en-gb", "en_GB", NULL},
385 {"i-hakka", "", "MT", "XEMXIJA", "i-hakka_MT_XEMXIJA", "i-hakka_MT_XEMXIJA", NULL},
386 {"i-hakka", "", "CN", "", "i-hakka_CN", "i-hakka_CN", NULL},
387 {"i-hakka", "", "MX", "", "I-hakka_MX", "i-hakka_MX", NULL},
388 {"x-klingon", "", "US", "SANJOSE", "X-KLINGON_us_SANJOSE", "x-klingon_US_SANJOSE", NULL},
389
390 {"mr", "", "", "", "mr.utf8", "mr.utf8", "mr"},
391 {"de", "", "TV", "", "de-tv.koi8r", "de_TV.koi8r", "de_TV"},
392 {"x-piglatin", "", "ML", "", "x-piglatin_ML.MBE", "x-piglatin_ML.MBE", "x-piglatin_ML"}, /* Multibyte English */
393 {"i-cherokee", "","US", "", "i-Cherokee_US.utf7", "i-cherokee_US.utf7", "i-cherokee_US"},
394 {"x-filfli", "", "MT", "FILFLA", "x-filfli_MT_FILFLA.gb-18030", "x-filfli_MT_FILFLA.gb-18030", "x-filfli_MT_FILFLA"},
395 {"no", "", "NO", "NY", "no-no-ny.utf32@B", "no_NO_NY.utf32@B", "no_NO_NY_B"},
396 {"no", "", "NO", "", "no-no.utf32@B", "no_NO.utf32@B", "no_NO_B"},
397 {"no", "", "", "NY", "no__ny", "no__NY", NULL},
398 {"no", "", "", "", "no@ny", "no@ny", "no__NY"},
399 {"el", "Latn", "", "", "el-latn", "el_Latn", NULL},
400 {"en", "Cyrl", "RU", "", "en-cyrl-ru", "en_Cyrl_RU", NULL},
46f4442e 401 {"zh", "Hant", "TW", "STROKE", "zh-hant_TW_STROKE", "zh_Hant_TW_STROKE", "zh_Hant_TW@collation=stroke"},
374ca955
A
402 {"qq", "Qqqq", "QQ", "QQ", "qq_Qqqq_QQ_QQ", "qq_Qqqq_QQ_QQ", NULL},
403 {"qq", "Qqqq", "", "QQ", "qq_Qqqq__QQ", "qq_Qqqq__QQ", NULL},
404 {"12", "3456", "78", "90", "12_3456_78_90", "12_3456_78_90", NULL}, /* total garbage */
405
406 {NULL,NULL,NULL,NULL,NULL,NULL,NULL}
407 };
408
46f4442e 409 static const char * const testTitles[] = {
374ca955
A
410 "uloc_getLanguage()",
411 "uloc_getScript()",
412 "uloc_getCountry()",
413 "uloc_getVariant()",
414 "name",
415 "uloc_getName()",
416 "uloc_canonicalize()"
417 };
418
419 char buf[PREFIXBUFSIZ];
420 int32_t len;
421 UErrorCode err;
422
423
424 for(row=0;testData[row][0] != NULL;row++) {
425 loc = testData[row][NAME];
426 log_verbose("Test #%d: %s\n", row, loc);
427
428 err = U_ZERO_ERROR;
429 len=0;
430 buf[0]=0;
431 for(n=0;n<=(NAME+2);n++) {
432 if(n==NAME) continue;
433
434 for(len=0;len<PREFIXBUFSIZ;len++) {
435 buf[len] = '%'; /* Set a tripwire.. */
436 }
437 len = 0;
438
439 switch(n) {
440 case LANG:
441 len = uloc_getLanguage(loc, buf, PREFIXBUFSIZ, &err);
442 break;
443
444 case SCRIPT:
445 len = uloc_getScript(loc, buf, PREFIXBUFSIZ, &err);
446 break;
447
448 case CTRY:
449 len = uloc_getCountry(loc, buf, PREFIXBUFSIZ, &err);
450 break;
451
452 case VAR:
453 len = uloc_getVariant(loc, buf, PREFIXBUFSIZ, &err);
454 break;
455
456 case NAME+1:
457 len = uloc_getName(loc, buf, PREFIXBUFSIZ, &err);
458 break;
459
460 case NAME+2:
461 len = uloc_canonicalize(loc, buf, PREFIXBUFSIZ, &err);
462 break;
463
464 default:
465 strcpy(buf, "**??");
466 len=4;
467 }
468
469 if(U_FAILURE(err)) {
470 log_err("#%d: %s on %s: err %s\n",
471 row, testTitles[n], loc, u_errorName(err));
472 } else {
473 log_verbose("#%d: %s on %s: -> [%s] (length %d)\n",
474 row, testTitles[n], loc, buf, len);
475
476 if(len != (int32_t)strlen(buf)) {
477 log_err("#%d: %s on %s: -> [%s] (length returned %d, actual %d!)\n",
478 row, testTitles[n], loc, buf, len, strlen(buf)+1);
479
480 }
481
482 /* see if they smashed something */
483 if(buf[len+1] != '%') {
484 log_err("#%d: %s on %s: -> [%s] - wrote [%X] out ofbounds!\n",
485 row, testTitles[n], loc, buf, buf[len+1]);
486 }
487
488 expected = testData[row][n];
489 if (expected == NULL && n == (NAME+2)) {
490 /* NULL expected canonicalize() means "expect same as getName()" */
491 expected = testData[row][NAME+1];
492 }
493 if(strcmp(buf, expected)) {
494 log_err("#%d: %s on %s: -> [%s] (expected '%s'!)\n",
495 row, testTitles[n], loc, buf, expected);
496
497 }
498 }
b75a7d8f 499 }
b75a7d8f 500 }
b75a7d8f
A
501}
502
503
504/* testing uloc_getISO3Language(), uloc_getISO3Country(), */
505static void TestSimpleResourceInfo() {
506 int32_t i;
507 char* testLocale = 0;
508 UChar* expected = 0;
374ca955 509
b75a7d8f
A
510 const char* temp;
511 char temp2[20];
512 testLocale=(char*)malloc(sizeof(char) * 1);
513 expected=(UChar*)malloc(sizeof(UChar) * 1);
374ca955
A
514
515 setUpDataTable();
b75a7d8f
A
516 log_verbose("Testing getISO3Language and getISO3Country\n");
517 for (i = 0; i < LOCALE_SIZE; i++) {
374ca955 518
b75a7d8f
A
519 testLocale=(char*)realloc(testLocale, sizeof(char) * (u_strlen(dataTable[NAME][i])+1));
520 u_austrcpy(testLocale, dataTable[NAME][i]);
374ca955 521
b75a7d8f 522 log_verbose("Testing %s ......\n", testLocale);
374ca955 523
b75a7d8f
A
524 temp=uloc_getISO3Language(testLocale);
525 expected=(UChar*)realloc(expected, sizeof(UChar) * (strlen(temp) + 1));
526 u_uastrcpy(expected,temp);
527 if (0 != u_strcmp(expected, dataTable[LANG3][i])) {
374ca955
A
528 log_err(" ISO-3 language code mismatch: %s versus %s\n", austrdup(expected),
529 austrdup(dataTable[LANG3][i]));
b75a7d8f 530 }
374ca955 531
b75a7d8f
A
532 temp=uloc_getISO3Country(testLocale);
533 expected=(UChar*)realloc(expected, sizeof(UChar) * (strlen(temp) + 1));
534 u_uastrcpy(expected,temp);
535 if (0 != u_strcmp(expected, dataTable[CTRY3][i])) {
536 log_err(" ISO-3 Country code mismatch: %s versus %s\n", austrdup(expected),
374ca955 537 austrdup(dataTable[CTRY3][i]));
b75a7d8f 538 }
374ca955 539 sprintf(temp2, "%x", (int)uloc_getLCID(testLocale));
b75a7d8f
A
540 if (strcmp(temp2, rawData2[LCID][i]) != 0) {
541 log_err("LCID mismatch: %s versus %s\n", temp2 , rawData2[LCID][i]);
542 }
b75a7d8f 543 }
374ca955
A
544
545 free(expected);
546 free(testLocale);
547 cleanUpDataTable();
b75a7d8f
A
548}
549
550/*
551 * Jitterbug 2439 -- markus 20030425
552 *
553 * The lookup of display names must not fall back through the default
554 * locale because that yields useless results.
555 */
556static void TestDisplayNames()
557{
558 UChar buffer[100];
374ca955 559 UErrorCode errorCode=U_ZERO_ERROR;
b75a7d8f 560 int32_t length;
b75a7d8f
A
561 log_verbose("Testing getDisplayName for different locales\n");
562
563 log_verbose(" In locale = en_US...\n");
564 doTestDisplayNames("en_US", DLANG_EN);
565 log_verbose(" In locale = fr_FR....\n");
566 doTestDisplayNames("fr_FR", DLANG_FR);
374ca955
A
567 log_verbose(" In locale = ca_ES...\n");
568 doTestDisplayNames("ca_ES", DLANG_CA);
b75a7d8f
A
569 log_verbose(" In locale = gr_EL..\n");
570 doTestDisplayNames("el_GR", DLANG_EL);
571
572 /* test that the default locale has a display name for its own language */
573 errorCode=U_ZERO_ERROR;
574 length=uloc_getDisplayLanguage(NULL, NULL, buffer, LENGTHOF(buffer), &errorCode);
575 if(U_FAILURE(errorCode) || (length<=3 && buffer[0]<=0x7f)) {
576 /* check <=3 to reject getting the language code as a display name */
577 log_err("unable to get a display string for the language of the default locale - %s\n", u_errorName(errorCode));
578 }
579
580 /* test that we get the language code itself for an unknown language, and a default warning */
581 errorCode=U_ZERO_ERROR;
582 length=uloc_getDisplayLanguage("qq", "rr", buffer, LENGTHOF(buffer), &errorCode);
583 if(errorCode!=U_USING_DEFAULT_WARNING || length!=2 || buffer[0]!=0x71 || buffer[1]!=0x71) {
584 log_err("error getting the display string for an unknown language - %s\n", u_errorName(errorCode));
585 }
73c04bcf
A
586
587 /* test that we get a default warning for a display name where one component is unknown (4255) */
588 errorCode=U_ZERO_ERROR;
589 length=uloc_getDisplayName("qq_US_POSIX", "en_US", buffer, LENGTHOF(buffer), &errorCode);
590 if(errorCode!=U_USING_DEFAULT_WARNING) {
591 log_err("error getting the display name for a locale with an unknown language - %s\n", u_errorName(errorCode));
592 }
374ca955
A
593
594 {
595 int32_t i;
46f4442e
A
596 static const char *aLocale = "es@collation=traditional;calendar=japanese";
597 static const char *testL[] = { "en_US",
374ca955
A
598 "fr_FR",
599 "ca_ES",
600 "el_GR" };
46f4442e 601 static const char *expect[] = { "Spanish (calendar=Japanese Calendar, collation=Traditional Sort Order)", /* note sorted order of keywords */
374ca955 602 "espagnol (Calendrier=Calendrier japonais, Ordonnancement=Ordre traditionnel)",
46f4442e
A
603 "espanyol (calendari=calendari japon\\u00e8s, ordre alfab\\u00e8tic=traditional)",
604 "\\u0399\\u03C3\\u03C0\\u03B1\\u03BD\\u03B9\\u03BA\\u03AC (\\u0397\\u03BC\\u03B5\\u03C1\\u03BF\\u03BB\\u03CC\\u03B3\\u03B9\\u03BF=\\u0399\\u03B1\\u03C0\\u03C9\\u03BD\\u03B9\\u03BA\\u03CC \\u0397\\u03BC\\u03B5\\u03C1\\u03BF\\u03BB\\u03CC\\u03B3\\u03B9\\u03BF, \\u03A4\\u03B1\\u03BA\\u03C4\\u03BF\\u03C0\\u03BF\\u03AF\\u03B7\\u03C3\\u03B7=\\u03A0\\u03B1\\u03C1\\u03B1\\u03B4\\u03BF\\u03C3\\u03B9\\u03B1\\u03BA\\u03AE \\u03A3\\u03B5\\u03B9\\u03C1\\u03AC)" };
374ca955
A
605 UChar *expectBuffer;
606
607 for(i=0;i<LENGTHOF(testL);i++) {
608 errorCode = U_ZERO_ERROR;
609 uloc_getDisplayName(aLocale, testL[i], buffer, LENGTHOF(buffer), &errorCode);
610 if(U_FAILURE(errorCode)) {
611 log_err("FAIL in uloc_getDisplayName(%s,%s,..) -> %s\n", aLocale, testL[i], u_errorName(errorCode));
612 } else {
613 expectBuffer = CharsToUChars(expect[i]);
614 if(u_strcmp(buffer,expectBuffer)) {
615 log_err("FAIL in uloc_getDisplayName(%s,%s,..) expected '%s' got '%s'\n", aLocale, testL[i], expect[i], austrdup(buffer));
616 } else {
617 log_verbose("pass in uloc_getDisplayName(%s,%s,..) got '%s'\n", aLocale, testL[i], expect[i]);
618 }
619 free(expectBuffer);
620 }
621 }
622 }
b75a7d8f
A
623}
624
625
626/* test for uloc_getAvialable() and uloc_countAvilable()*/
627static void TestGetAvailableLocales()
628{
629
630 const char *locList;
631 int32_t locCount,i;
632
633 log_verbose("Testing the no of avialable locales\n");
634 locCount=uloc_countAvailable();
635 if (locCount == 0)
636 log_data_err("countAvailable() returned an empty list!\n");
637
638 /* use something sensible w/o hardcoding the count */
639 else if(locCount < 0){
640 log_data_err("countAvailable() returned a wrong value!= %d\n", locCount);
641 }
642 else{
643 log_info("Number of locales returned = %d\n", locCount);
644 }
645 for(i=0;i<locCount;i++){
646 locList=uloc_getAvailable(i);
647
648 log_verbose(" %s\n", locList);
649 }
650}
651
652/* test for u_getDataDirectory, u_setDataDirectory, uloc_getISO3Language */
653static void TestDataDirectory()
654{
655
656 char oldDirectory[512];
657 const char *temp,*testValue1,*testValue2,*testValue3;
658 const char path[40] ="d:\\icu\\source\\test\\intltest" U_FILE_SEP_STRING; /*give the required path */
659
660 log_verbose("Testing getDataDirectory()\n");
661 temp = u_getDataDirectory();
662 strcpy(oldDirectory, temp);
663
664 testValue1=uloc_getISO3Language("en_US");
665 log_verbose("first fetch of language retrieved %s\n", testValue1);
666
667 if (0 != strcmp(testValue1,"eng")){
668 log_err("Initial check of ISO3 language failed: expected \"eng\", got %s \n", testValue1);
669 }
670
671 /*defining the path for DataDirectory */
672 log_verbose("Testing setDataDirectory\n");
673 u_setDataDirectory( path );
674 if(strcmp(path, u_getDataDirectory())==0)
675 log_verbose("setDataDirectory working fine\n");
676 else
677 log_err("Error in setDataDirectory. Directory not set correctly - came back as [%s], expected [%s]\n", u_getDataDirectory(), path);
678
679 testValue2=uloc_getISO3Language("en_US");
680 log_verbose("second fetch of language retrieved %s \n", testValue2);
681
682 u_setDataDirectory(oldDirectory);
683 testValue3=uloc_getISO3Language("en_US");
684 log_verbose("third fetch of language retrieved %s \n", testValue3);
685
686 if (0 != strcmp(testValue3,"eng")) {
687 log_err("get/setDataDirectory() failed: expected \"eng\", got \" %s \" \n", testValue3);
688 }
689}
690
691
692
693/*=========================================================== */
694
695static UChar _NUL=0;
696
697static void doTestDisplayNames(const char* displayLocale, int32_t compareIndex)
698{
699 UErrorCode status = U_ZERO_ERROR;
700 int32_t i;
701 int32_t maxresultsize;
702
703 const char *testLocale;
704
705
706 UChar *testLang = 0;
374ca955 707 UChar *testScript = 0;
b75a7d8f
A
708 UChar *testCtry = 0;
709 UChar *testVar = 0;
710 UChar *testName = 0;
711
712
713 UChar* expectedLang = 0;
374ca955 714 UChar* expectedScript = 0;
b75a7d8f
A
715 UChar* expectedCtry = 0;
716 UChar* expectedVar = 0;
717 UChar* expectedName = 0;
718
719setUpDataTable();
720
721 for(i=0;i<LOCALE_SIZE; ++i)
722 {
723 testLocale=rawData2[NAME][i];
724
725 log_verbose("Testing..... %s\n", testLocale);
726
727 maxresultsize=0;
728 maxresultsize=uloc_getDisplayLanguage(testLocale, displayLocale, NULL, maxresultsize, &status);
729 if(status==U_BUFFER_OVERFLOW_ERROR)
730 {
731 status=U_ZERO_ERROR;
732 testLang=(UChar*)malloc(sizeof(UChar) * (maxresultsize+1));
733 uloc_getDisplayLanguage(testLocale, displayLocale, testLang, maxresultsize + 1, &status);
734 }
735 else
736 {
737 testLang=&_NUL;
738 }
739 if(U_FAILURE(status)){
740 log_err("Error in getDisplayLanguage() %s\n", myErrorName(status));
741 }
742
374ca955
A
743 maxresultsize=0;
744 maxresultsize=uloc_getDisplayScript(testLocale, displayLocale, NULL, maxresultsize, &status);
745 if(status==U_BUFFER_OVERFLOW_ERROR)
746 {
747 status=U_ZERO_ERROR;
748 testScript=(UChar*)malloc(sizeof(UChar) * (maxresultsize+1));
749 uloc_getDisplayScript(testLocale, displayLocale, testScript, maxresultsize + 1, &status);
750 }
751 else
752 {
753 testScript=&_NUL;
754 }
755 if(U_FAILURE(status)){
756 log_err("Error in getDisplayScript() %s\n", myErrorName(status));
757 }
758
b75a7d8f
A
759 maxresultsize=0;
760 maxresultsize=uloc_getDisplayCountry(testLocale, displayLocale, NULL, maxresultsize, &status);
761 if(status==U_BUFFER_OVERFLOW_ERROR)
762 {
763 status=U_ZERO_ERROR;
764 testCtry=(UChar*)malloc(sizeof(UChar) * (maxresultsize+1));
765 uloc_getDisplayCountry(testLocale, displayLocale, testCtry, maxresultsize + 1, &status);
766 }
767 else
768 {
769 testCtry=&_NUL;
770 }
771 if(U_FAILURE(status)){
772 log_err("Error in getDisplayCountry() %s\n", myErrorName(status));
773 }
774
775 maxresultsize=0;
776 maxresultsize=uloc_getDisplayVariant(testLocale, displayLocale, NULL, maxresultsize, &status);
777 if(status==U_BUFFER_OVERFLOW_ERROR)
778 {
779 status=U_ZERO_ERROR;
780 testVar=(UChar*)malloc(sizeof(UChar) * (maxresultsize+1));
781 uloc_getDisplayVariant(testLocale, displayLocale, testVar, maxresultsize + 1, &status);
782 }
783 else
784 {
785 testVar=&_NUL;
786 }
787 if(U_FAILURE(status)){
788 log_err("Error in getDisplayVariant() %s\n", myErrorName(status));
789 }
790
791 maxresultsize=0;
792 maxresultsize=uloc_getDisplayName(testLocale, displayLocale, NULL, maxresultsize, &status);
793 if(status==U_BUFFER_OVERFLOW_ERROR)
794 {
795 status=U_ZERO_ERROR;
796 testName=(UChar*)malloc(sizeof(UChar) * (maxresultsize+1));
797 uloc_getDisplayName(testLocale, displayLocale, testName, maxresultsize + 1, &status);
798 }
799 else
800 {
801 testName=&_NUL;
802 }
803 if(U_FAILURE(status)){
804 log_err("Error in getDisplayName() %s\n", myErrorName(status));
805 }
806
807 expectedLang=dataTable[compareIndex][i];
808 if(u_strlen(expectedLang)== 0)
809 expectedLang=dataTable[DLANG_EN][i];
810
374ca955
A
811 expectedScript=dataTable[compareIndex + 1][i];
812 if(u_strlen(expectedScript)== 0)
813 expectedScript=dataTable[DSCRIPT_EN][i];
814
815 expectedCtry=dataTable[compareIndex + 2][i];
b75a7d8f
A
816 if(u_strlen(expectedCtry)== 0)
817 expectedCtry=dataTable[DCTRY_EN][i];
818
374ca955
A
819 expectedVar=dataTable[compareIndex + 3][i];
820 if(u_strlen(expectedVar)== 0)
b75a7d8f
A
821 expectedVar=dataTable[DVAR_EN][i];
822
374ca955 823 expectedName=dataTable[compareIndex + 4][i];
b75a7d8f
A
824 if(u_strlen(expectedName) == 0)
825 expectedName=dataTable[DNAME_EN][i];
826
827 if (0 !=u_strcmp(testLang,expectedLang)) {
828 log_data_err(" Display Language mismatch: got %s expected %s displayLocale=%s\n", austrdup(testLang), austrdup(expectedLang), displayLocale);
829 }
830
374ca955
A
831 if (0 != u_strcmp(testScript,expectedScript)) {
832 log_data_err(" Display Script mismatch: got %s expected %s displayLocale=%s\n", austrdup(testScript), austrdup(expectedScript), displayLocale);
833 }
834
b75a7d8f
A
835 if (0 != u_strcmp(testCtry,expectedCtry)) {
836 log_data_err(" Display Country mismatch: got %s expected %s displayLocale=%s\n", austrdup(testCtry), austrdup(expectedCtry), displayLocale);
837 }
838
839 if (0 != u_strcmp(testVar,expectedVar)) {
840 log_data_err(" Display Variant mismatch: got %s expected %s displayLocale=%s\n", austrdup(testVar), austrdup(expectedVar), displayLocale);
841 }
842
843 if(0 != u_strcmp(testName, expectedName)) {
844 log_data_err(" Display Name mismatch: got %s expected %s displayLocale=%s\n", austrdup(testName), austrdup(expectedName), displayLocale);
845 }
846
847 if(testName!=&_NUL) {
848 free(testName);
849 }
850 if(testLang!=&_NUL) {
851 free(testLang);
852 }
374ca955
A
853 if(testScript!=&_NUL) {
854 free(testScript);
855 }
b75a7d8f
A
856 if(testCtry!=&_NUL) {
857 free(testCtry);
858 }
859 if(testVar!=&_NUL) {
860 free(testVar);
861 }
862 }
863cleanUpDataTable();
864}
865
866/* test for uloc_getISOLanguages, uloc_getISOCountries */
867static void TestISOFunctions()
868{
869 const char* const* str=uloc_getISOLanguages();
870 const char* const* str1=uloc_getISOCountries();
871 const char* test;
46f4442e
A
872 const char *key = NULL;
873 int32_t count = 0, skipped = 0;
b75a7d8f 874 int32_t expect;
374ca955 875 UResourceBundle *res;
46f4442e 876 UResourceBundle *subRes;
374ca955 877 UErrorCode status = U_ZERO_ERROR;
b75a7d8f
A
878
879 /* test getISOLanguages*/
880 /*str=uloc_getISOLanguages(); */
881 log_verbose("Testing ISO Languages: \n");
882
374ca955
A
883 /* use structLocale - this data is no longer in root */
884 res = ures_openDirect(loadTestData(&status), "structLocale", &status);
46f4442e 885 subRes = ures_getByKey(res, "Languages", NULL, &status);
374ca955 886 if (U_FAILURE(status)) {
46f4442e
A
887 log_data_err("There is an error in structLocale's ures_getByKey(\"Languages\"), status=%s\n", u_errorName(status));
888 return;
374ca955
A
889 }
890
46f4442e 891 expect = ures_getSize(subRes);
374ca955 892 for(count = 0; *(str+count) != 0; count++)
b75a7d8f 893 {
46f4442e 894 key = NULL;
374ca955 895 test = *(str+count);
46f4442e 896 status = U_ZERO_ERROR;
374ca955 897
46f4442e
A
898 do {
899 /* Skip over language tags. This API only returns language codes. */
900 skipped += (key != NULL);
901 ures_getNextString(subRes, NULL, &key, &status);
902 }
903 while (key != NULL && strchr(key, '_'));
904
905 if(key == NULL)
906 break;
907 /* TODO: Consider removing sh, which is deprecated */
908 if(strcmp(key,"root") == 0 || strcmp(key,"Fallback") == 0 || strcmp(key,"sh") == 0) {
909 ures_getNextString(subRes, NULL, &key, &status);
910 skipped++;
911 }
73c04bcf 912#if U_CHARSET_FAMILY==U_ASCII_FAMILY
46f4442e
A
913 /* This code only works on ASCII machines where the keys are stored in ASCII order */
914 if(strcmp(test,key)) {
915 /* The first difference usually implies the place where things get out of sync */
916 log_err("FAIL Language diff at offset %d, \"%s\" != \"%s\"\n", count, test, key);
b75a7d8f 917 }
374ca955
A
918#endif
919
920 if(!strcmp(test,"in"))
921 log_err("FAIL getISOLanguages() has obsolete language code %s\n", test);
922 if(!strcmp(test,"iw"))
923 log_err("FAIL getISOLanguages() has obsolete language code %s\n", test);
924 if(!strcmp(test,"ji"))
925 log_err("FAIL getISOLanguages() has obsolete language code %s\n", test);
926 if(!strcmp(test,"jw"))
927 log_err("FAIL getISOLanguages() has obsolete language code %s\n", test);
928 if(!strcmp(test,"sh"))
929 log_err("FAIL getISOLanguages() has obsolete language code %s\n", test);
930 }
931
46f4442e 932 expect -= skipped; /* Ignore the skipped resources from structLocale */
b75a7d8f
A
933
934 if(count!=expect) {
374ca955 935 log_err("There is an error in getISOLanguages, got %d, expected %d (as per structLocale)\n", count, expect);
b75a7d8f
A
936 }
937
46f4442e 938 subRes = ures_getByKey(res, "Countries", subRes, &status);
b75a7d8f 939 log_verbose("Testing ISO Countries");
46f4442e
A
940 skipped = 0;
941 expect = ures_getSize(subRes) - 1; /* Skip ZZ */
374ca955 942 for(count = 0; *(str1+count) != 0; count++)
b75a7d8f 943 {
46f4442e 944 key = NULL;
374ca955 945 test = *(str1+count);
46f4442e
A
946 do {
947 /* Skip over numeric UN tags. This API only returns ISO-3166 codes. */
948 skipped += (key != NULL);
949 ures_getNextString(subRes, NULL, &key, &status);
950 }
951 while (key != NULL && strlen(key) != 2);
952
953 if(key == NULL)
954 break;
955 /* TODO: Consider removing CS, which is deprecated */
956 while(strcmp(key,"QO") == 0 || strcmp(key,"QU") == 0 || strcmp(key,"CS") == 0) {
957 ures_getNextString(subRes, NULL, &key, &status);
958 skipped++;
959 }
960#if U_CHARSET_FAMILY==U_ASCII_FAMILY
961 /* This code only works on ASCII machines where the keys are stored in ASCII order */
962 if(strcmp(test,key)) {
963 /* The first difference usually implies the place where things get out of sync */
964 log_err("FAIL Country diff at offset %d, \"%s\" != \"%s\"\n", count, test, key);
965 }
966#endif
374ca955
A
967 if(!strcmp(test,"FX"))
968 log_err("FAIL getISOCountries() has obsolete country code %s\n", test);
46f4442e
A
969 if(!strcmp(test,"YU"))
970 log_err("FAIL getISOCountries() has obsolete country code %s\n", test);
374ca955
A
971 if(!strcmp(test,"ZR"))
972 log_err("FAIL getISOCountries() has obsolete country code %s\n", test);
b75a7d8f 973 }
46f4442e
A
974
975 ures_getNextString(subRes, NULL, &key, &status);
976 if (strcmp(key, "ZZ") != 0) {
977 log_err("ZZ was expected to be the last entry in structLocale, but got %s\n", key);
978 }
979#if U_CHARSET_FAMILY==U_EBCDIC_FAMILY
980 /* On EBCDIC machines, the numbers are sorted last. Account for those in the skipped value too. */
981 key = NULL;
982 do {
983 /* Skip over numeric UN tags. uloc_getISOCountries only returns ISO-3166 codes. */
984 skipped += (key != NULL);
985 ures_getNextString(subRes, NULL, &key, &status);
986 }
987 while (U_SUCCESS(status) && key != NULL && strlen(key) != 2);
988#endif
989 expect -= skipped; /* Ignore the skipped resources from structLocale */
b75a7d8f
A
990 if(count!=expect)
991 {
992 log_err("There is an error in getISOCountries, got %d, expected %d \n", count, expect);
993 }
46f4442e
A
994 ures_close(subRes);
995 ures_close(res);
b75a7d8f
A
996}
997
998static void setUpDataTable()
999{
1000 int32_t i,j;
1001 dataTable = (UChar***)(calloc(sizeof(UChar**),LOCALE_INFO_SIZE));
1002
374ca955 1003 for (i = 0; i < LOCALE_INFO_SIZE; i++) {
b75a7d8f 1004 dataTable[i] = (UChar**)(calloc(sizeof(UChar*),LOCALE_SIZE));
374ca955 1005 for (j = 0; j < LOCALE_SIZE; j++){
b75a7d8f
A
1006 dataTable[i][j] = CharsToUChars(rawData2[i][j]);
1007 }
1008 }
1009}
1010
1011static void cleanUpDataTable()
1012{
1013 int32_t i,j;
1014 if(dataTable != NULL) {
1015 for (i=0; i<LOCALE_INFO_SIZE; i++) {
1016 for(j = 0; j < LOCALE_SIZE; j++) {
1017 free(dataTable[i][j]);
1018 }
1019 free(dataTable[i]);
1020 }
1021 free(dataTable);
1022 }
1023 dataTable = NULL;
1024}
1025
1026/**
1027 * @bug 4011756 4011380
1028 */
1029static void TestISO3Fallback()
1030{
1031 const char* test="xx_YY";
1032
1033 const char * result;
1034
1035 result = uloc_getISO3Language(test);
1036
1037 /* Conform to C API usage */
1038
1039 if (!result || (result[0] != 0))
1040 log_err("getISO3Language() on xx_YY returned %s instead of \"\"");
1041
1042 result = uloc_getISO3Country(test);
1043
1044 if (!result || (result[0] != 0))
1045 log_err("getISO3Country() on xx_YY returned %s instead of \"\"");
1046}
1047
1048/**
1049 * @bug 4118587
1050 */
1051static void TestSimpleDisplayNames()
1052{
1053 /*
1054 This test is different from TestDisplayNames because TestDisplayNames checks
1055 fallback behavior, combination of language and country names to form locale
1056 names, and other stuff like that. This test just checks specific language
1057 and country codes to make sure we have the correct names for them.
1058 */
46f4442e 1059 char languageCodes[] [4] = { "he", "id", "iu", "ug", "yi", "za", "419" };
374ca955 1060 const char* languageNames [] = { "Hebrew", "Indonesian", "Inuktitut", "Uighur", "Yiddish",
46f4442e
A
1061 "Zhuang", "419" };
1062 const char* inLocale [] = { "en_US", "zh_Hant"};
b75a7d8f
A
1063 UErrorCode status=U_ZERO_ERROR;
1064
1065 int32_t i;
46f4442e
A
1066 int32_t localeIndex = 0;
1067 for (i = 0; i < 7; i++) {
b75a7d8f
A
1068 UChar *testLang=0;
1069 UChar *expectedLang=0;
1070 int size=0;
46f4442e
A
1071
1072 if (i == 6) {
1073 localeIndex = 1; /* Use the second locale for the rest of the test. */
1074 }
1075
1076 size=uloc_getDisplayLanguage(languageCodes[i], inLocale[localeIndex], NULL, size, &status);
b75a7d8f
A
1077 if(status==U_BUFFER_OVERFLOW_ERROR) {
1078 status=U_ZERO_ERROR;
1079 testLang=(UChar*)malloc(sizeof(UChar) * (size + 1));
46f4442e 1080 uloc_getDisplayLanguage(languageCodes[i], inLocale[localeIndex], testLang, size + 1, &status);
b75a7d8f
A
1081 }
1082 expectedLang=(UChar*)malloc(sizeof(UChar) * (strlen(languageNames[i])+1));
1083 u_uastrcpy(expectedLang, languageNames[i]);
1084 if (u_strcmp(testLang, expectedLang) != 0)
1085 log_data_err("Got wrong display name for %s : Expected \"%s\", got \"%s\".\n",
1086 languageCodes[i], languageNames[i], austrdup(testLang));
1087 free(testLang);
1088 free(expectedLang);
1089 }
1090
1091}
1092
1093/**
1094 * @bug 4118595
1095 */
1096static void TestUninstalledISO3Names()
1097{
1098 /* This test checks to make sure getISO3Language and getISO3Country work right
1099 even for locales that are not installed. */
46f4442e 1100 static const char iso2Languages [][4] = { "am", "ba", "fy", "mr", "rn",
b75a7d8f 1101 "ss", "tw", "zu" };
46f4442e 1102 static const char iso3Languages [][5] = { "amh", "bak", "fry", "mar", "run",
b75a7d8f 1103 "ssw", "twi", "zul" };
46f4442e 1104 static const char iso2Countries [][6] = { "am_AF", "ba_BW", "fy_KZ", "mr_MO", "rn_MN",
b75a7d8f 1105 "ss_SB", "tw_TC", "zu_ZW" };
46f4442e 1106 static const char iso3Countries [][4] = { "AFG", "BWA", "KAZ", "MAC", "MNG",
b75a7d8f
A
1107 "SLB", "TCA", "ZWE" };
1108 int32_t i;
1109
1110 for (i = 0; i < 8; i++) {
1111 UErrorCode err = U_ZERO_ERROR;
1112 const char *test;
1113 test = uloc_getISO3Language(iso2Languages[i]);
1114 if(strcmp(test, iso3Languages[i]) !=0 || U_FAILURE(err))
1115 log_err("Got wrong ISO3 code for %s : Expected \"%s\", got \"%s\". %s\n",
1116 iso2Languages[i], iso3Languages[i], test, myErrorName(err));
1117 }
1118 for (i = 0; i < 8; i++) {
1119 UErrorCode err = U_ZERO_ERROR;
1120 const char *test;
1121 test = uloc_getISO3Country(iso2Countries[i]);
1122 if(strcmp(test, iso3Countries[i]) !=0 || U_FAILURE(err))
1123 log_err("Got wrong ISO3 code for %s : Expected \"%s\", got \"%s\". %s\n",
1124 iso2Countries[i], iso3Countries[i], test, myErrorName(err));
1125 }
1126}
1127
1128
1129static void TestVariantParsing()
1130{
46f4442e
A
1131 static const char* en_US_custom="en_US_De Anza_Cupertino_California_United States_Earth";
1132 static const char* dispName="English (United States, DE ANZA_CUPERTINO_CALIFORNIA_UNITED STATES_EARTH)";
1133 static const char* dispVar="DE ANZA_CUPERTINO_CALIFORNIA_UNITED STATES_EARTH";
1134 static const char* shortVariant="fr_FR_foo";
1135 static const char* bogusVariant="fr_FR__foo";
1136 static const char* bogusVariant2="fr_FR_foo_";
1137 static const char* bogusVariant3="fr_FR__foo_";
b75a7d8f
A
1138
1139
1140 UChar displayVar[100];
1141 UChar displayName[100];
1142 UErrorCode status=U_ZERO_ERROR;
1143 UChar* got=0;
1144 int32_t size=0;
1145 size=uloc_getDisplayVariant(en_US_custom, "en_US", NULL, size, &status);
1146 if(status==U_BUFFER_OVERFLOW_ERROR) {
1147 status=U_ZERO_ERROR;
1148 got=(UChar*)realloc(got, sizeof(UChar) * (size+1));
1149 uloc_getDisplayVariant(en_US_custom, "en_US", got, size + 1, &status);
1150 }
1151 else {
1152 log_err("FAIL: Didn't get U_BUFFER_OVERFLOW_ERROR\n");
1153 }
1154 u_uastrcpy(displayVar, dispVar);
1155 if(u_strcmp(got,displayVar)!=0) {
1156 log_err("FAIL: getDisplayVariant() Wanted %s, got %s\n", dispVar, austrdup(got));
1157 }
1158 size=0;
1159 size=uloc_getDisplayName(en_US_custom, "en_US", NULL, size, &status);
1160 if(status==U_BUFFER_OVERFLOW_ERROR) {
1161 status=U_ZERO_ERROR;
1162 got=(UChar*)realloc(got, sizeof(UChar) * (size+1));
1163 uloc_getDisplayName(en_US_custom, "en_US", got, size + 1, &status);
1164 }
1165 else {
1166 log_err("FAIL: Didn't get U_BUFFER_OVERFLOW_ERROR\n");
1167 }
1168 u_uastrcpy(displayName, dispName);
1169 if(u_strcmp(got,displayName)!=0) {
1170 log_err("FAIL: getDisplayName() Wanted %s, got %s\n", dispName, austrdup(got));
1171 }
1172
1173 size=0;
1174 status=U_ZERO_ERROR;
1175 size=uloc_getDisplayVariant(shortVariant, NULL, NULL, size, &status);
1176 if(status==U_BUFFER_OVERFLOW_ERROR) {
1177 status=U_ZERO_ERROR;
1178 got=(UChar*)realloc(got, sizeof(UChar) * (size+1));
1179 uloc_getDisplayVariant(shortVariant, NULL, got, size + 1, &status);
1180 }
1181 else {
1182 log_err("FAIL: Didn't get U_BUFFER_OVERFLOW_ERROR\n");
1183 }
1184 if(strcmp(austrdup(got),"FOO")!=0) {
1185 log_err("FAIL: getDisplayVariant() Wanted: foo Got: %s\n", austrdup(got));
1186 }
1187 size=0;
1188 status=U_ZERO_ERROR;
1189 size=uloc_getDisplayVariant(bogusVariant, NULL, NULL, size, &status);
1190 if(status==U_BUFFER_OVERFLOW_ERROR) {
1191 status=U_ZERO_ERROR;
1192 got=(UChar*)realloc(got, sizeof(UChar) * (size+1));
1193 uloc_getDisplayVariant(bogusVariant, NULL, got, size + 1, &status);
1194 }
1195 else {
1196 log_err("FAIL: Didn't get U_BUFFER_OVERFLOW_ERROR\n");
1197 }
1198 if(strcmp(austrdup(got),"_FOO")!=0) {
1199 log_err("FAIL: getDisplayVariant() Wanted: _FOO Got: %s\n", austrdup(got));
1200 }
1201 size=0;
1202 status=U_ZERO_ERROR;
1203 size=uloc_getDisplayVariant(bogusVariant2, NULL, NULL, size, &status);
1204 if(status==U_BUFFER_OVERFLOW_ERROR) {
1205 status=U_ZERO_ERROR;
1206 got=(UChar*)realloc(got, sizeof(UChar) * (size+1));
1207 uloc_getDisplayVariant(bogusVariant2, NULL, got, size + 1, &status);
1208 }
1209 else {
1210 log_err("FAIL: Didn't get U_BUFFER_OVERFLOW_ERROR\n");
1211 }
1212 if(strcmp(austrdup(got),"FOO_")!=0) {
1213 log_err("FAIL: getDisplayVariant() Wanted: FOO_ Got: %s\n", austrdup(got));
1214 }
1215 size=0;
1216 status=U_ZERO_ERROR;
1217 size=uloc_getDisplayVariant(bogusVariant3, NULL, NULL, size, &status);
1218 if(status==U_BUFFER_OVERFLOW_ERROR) {
1219 status=U_ZERO_ERROR;
1220 got=(UChar*)realloc(got, sizeof(UChar) * (size+1));
1221 uloc_getDisplayVariant(bogusVariant3, NULL, got, size + 1, &status);
1222 }
1223 else {
1224 log_err("FAIL: Didn't get U_BUFFER_OVERFLOW_ERROR\n");
1225 }
1226 if(strcmp(austrdup(got),"_FOO_")!=0) {
1227 log_err("FAIL: getDisplayVariant() Wanted: _FOO_ Got: %s\n", austrdup(got));
1228 }
1229 free(got);
1230}
1231
1232
1233static void TestObsoleteNames(void)
1234{
1235 int32_t i;
1236 UErrorCode status = U_ZERO_ERROR;
1237 char buff[256];
1238
46f4442e 1239 static const struct
b75a7d8f
A
1240 {
1241 char locale[9];
46f4442e
A
1242 char lang3[4];
1243 char lang[4];
1244 char ctry3[4];
1245 char ctry[4];
b75a7d8f
A
1246 } tests[] =
1247 {
1248 { "eng_USA", "eng", "en", "USA", "US" },
1249 { "kok", "kok", "kok", "", "" },
1250 { "in", "ind", "in", "", "" },
1251 { "id", "ind", "id", "", "" }, /* NO aliasing */
1252 { "sh", "srp", "sh", "", "" },
46f4442e 1253 { "zz_CS", "", "zz", "SCG", "CS" },
b75a7d8f
A
1254 { "zz_FX", "", "zz", "FXX", "FX" },
1255 { "zz_RO", "", "zz", "ROU", "RO" },
1256 { "zz_TP", "", "zz", "TMP", "TP" },
1257 { "zz_TL", "", "zz", "TLS", "TL" },
1258 { "zz_ZR", "", "zz", "ZAR", "ZR" },
1259 { "zz_FXX", "", "zz", "FXX", "FX" }, /* no aliasing. Doesn't go to PS(PSE). */
1260 { "zz_ROM", "", "zz", "ROU", "RO" },
1261 { "zz_ROU", "", "zz", "ROU", "RO" },
1262 { "zz_ZAR", "", "zz", "ZAR", "ZR" },
1263 { "zz_TMP", "", "zz", "TMP", "TP" },
1264 { "zz_TLS", "", "zz", "TLS", "TL" },
46f4442e 1265 { "zz_YUG", "", "zz", "YUG", "YU" },
b75a7d8f
A
1266 { "mlt_PSE", "mlt", "mt", "PSE", "PS" },
1267 { "iw", "heb", "iw", "", "" },
1268 { "ji", "yid", "ji", "", "" },
1269 { "jw", "jaw", "jw", "", "" },
1270 { "sh", "srp", "sh", "", "" },
1271 { "", "", "", "", "" }
1272 };
1273
1274 for(i=0;tests[i].locale[0];i++)
1275 {
1276 const char *locale;
1277
1278 locale = tests[i].locale;
1279 log_verbose("** %s:\n", locale);
1280
1281 status = U_ZERO_ERROR;
1282 if(strcmp(tests[i].lang3,uloc_getISO3Language(locale)))
1283 {
1284 log_err("FAIL: uloc_getISO3Language(%s)==\t\"%s\",\t expected \"%s\"\n",
1285 locale, uloc_getISO3Language(locale), tests[i].lang3);
1286 }
1287 else
1288 {
1289 log_verbose(" uloc_getISO3Language()==\t\"%s\"\n",
1290 uloc_getISO3Language(locale) );
1291 }
1292
1293 status = U_ZERO_ERROR;
1294 uloc_getLanguage(locale, buff, 256, &status);
1295 if(U_FAILURE(status))
1296 {
1297 log_err("FAIL: error getting language from %s\n", locale);
1298 }
1299 else
1300 {
1301 if(strcmp(buff,tests[i].lang))
1302 {
1303 log_err("FAIL: uloc_getLanguage(%s)==\t\"%s\"\t expected \"%s\"\n",
1304 locale, buff, tests[i].lang);
1305 }
1306 else
1307 {
1308 log_verbose(" uloc_getLanguage(%s)==\t%s\n", locale, buff);
1309 }
1310 }
1311 if(strcmp(tests[i].lang3,uloc_getISO3Language(locale)))
1312 {
1313 log_err("FAIL: uloc_getISO3Language(%s)==\t\"%s\",\t expected \"%s\"\n",
1314 locale, uloc_getISO3Language(locale), tests[i].lang3);
1315 }
1316 else
1317 {
1318 log_verbose(" uloc_getISO3Language()==\t\"%s\"\n",
1319 uloc_getISO3Language(locale) );
1320 }
1321
1322 if(strcmp(tests[i].ctry3,uloc_getISO3Country(locale)))
1323 {
1324 log_err("FAIL: uloc_getISO3Country(%s)==\t\"%s\",\t expected \"%s\"\n",
1325 locale, uloc_getISO3Country(locale), tests[i].ctry3);
1326 }
1327 else
1328 {
1329 log_verbose(" uloc_getISO3Country()==\t\"%s\"\n",
1330 uloc_getISO3Country(locale) );
1331 }
1332
1333 status = U_ZERO_ERROR;
1334 uloc_getCountry(locale, buff, 256, &status);
1335 if(U_FAILURE(status))
1336 {
1337 log_err("FAIL: error getting country from %s\n", locale);
1338 }
1339 else
1340 {
1341 if(strcmp(buff,tests[i].ctry))
1342 {
1343 log_err("FAIL: uloc_getCountry(%s)==\t\"%s\"\t expected \"%s\"\n",
1344 locale, buff, tests[i].ctry);
1345 }
1346 else
1347 {
1348 log_verbose(" uloc_getCountry(%s)==\t%s\n", locale, buff);
1349 }
1350 }
1351 }
1352
374ca955
A
1353 if (uloc_getLCID("iw_IL") != uloc_getLCID("he_IL")) {
1354 log_err("he,iw LCID mismatch: %X versus %X\n", uloc_getLCID("iw_IL"), uloc_getLCID("he_IL"));
1355 }
1356
1357 if (uloc_getLCID("iw") != uloc_getLCID("he")) {
1358 log_err("he,iw LCID mismatch: %X versus %X\n", uloc_getLCID("iw"), uloc_getLCID("he"));
1359 }
1360
b75a7d8f
A
1361#if 0
1362
1363 i = uloc_getLanguage("kok",NULL,0,&icu_err);
1364 if(U_FAILURE(icu_err))
1365 {
1366 log_err("FAIL: Got %s trying to do uloc_getLanguage(kok)\n", u_errorName(icu_err));
1367 }
1368
1369 icu_err = U_ZERO_ERROR;
1370 uloc_getLanguage("kok",r1_buff,12,&icu_err);
1371 if(U_FAILURE(icu_err))
1372 {
1373 log_err("FAIL: Got %s trying to do uloc_getLanguage(kok, buff)\n", u_errorName(icu_err));
1374 }
1375
1376 r1_addr = (char *)uloc_getISO3Language("kok");
1377
1378 icu_err = U_ZERO_ERROR;
1379 if (strcmp(r1_buff,"kok") != 0)
1380 {
1381 log_err("FAIL: uloc_getLanguage(kok)==%s not kok\n",r1_buff);
1382 line--;
1383 }
1384 r1_addr = (char *)uloc_getISO3Language("in");
1385 i = uloc_getLanguage(r1_addr,r1_buff,12,&icu_err);
1386 if (strcmp(r1_buff,"id") != 0)
1387 {
1388 printf("uloc_getLanguage error (%s)\n",r1_buff);
1389 line--;
1390 }
1391 r1_addr = (char *)uloc_getISO3Language("sh");
1392 i = uloc_getLanguage(r1_addr,r1_buff,12,&icu_err);
1393 if (strcmp(r1_buff,"sr") != 0)
1394 {
1395 printf("uloc_getLanguage error (%s)\n",r1_buff);
1396 line--;
1397 }
1398
1399 r1_addr = (char *)uloc_getISO3Country("zz_ZR");
1400 strcpy(p1_buff,"zz_");
1401 strcat(p1_buff,r1_addr);
1402 i = uloc_getCountry(p1_buff,r1_buff,12,&icu_err);
1403 if (strcmp(r1_buff,"ZR") != 0)
1404 {
1405 printf("uloc_getCountry error (%s)\n",r1_buff);
1406 line--;
1407 }
1408 r1_addr = (char *)uloc_getISO3Country("zz_FX");
1409 strcpy(p1_buff,"zz_");
1410 strcat(p1_buff,r1_addr);
1411 i = uloc_getCountry(p1_buff,r1_buff,12,&icu_err);
1412 if (strcmp(r1_buff,"FX") != 0)
1413 {
1414 printf("uloc_getCountry error (%s)\n",r1_buff);
1415 line--;
1416 }
1417
1418#endif
1419
1420}
1421
374ca955
A
1422static void TestKeywordVariants(void)
1423{
46f4442e 1424 static const struct {
374ca955
A
1425 const char *localeID;
1426 const char *expectedLocaleID;
1427 const char *expectedLocaleIDNoKeywords;
1428 const char *expectedCanonicalID;
1429 const char *expectedKeywords[10];
1430 int32_t numKeywords;
1431 UErrorCode expectedStatus; /* from uloc_openKeywords */
1432 } testCases[] = {
1433 {
1434 "de_DE@ currency = euro; C o ll A t i o n = Phonebook ; C alen dar = buddhist ",
1435 "de_DE@calendar=buddhist;collation=Phonebook;currency=euro",
1436 "de_DE",
1437 "de_DE@calendar=buddhist;collation=Phonebook;currency=euro",
1438 {"calendar", "collation", "currency"},
1439 3,
1440 U_ZERO_ERROR
1441 },
1442 {
1443 "de_DE@euro",
1444 "de_DE@euro",
1445 "de_DE",
1446 "de_DE@currency=EUR",
1447 {"","","","","","",""},
1448 0,
1449 U_INVALID_FORMAT_ERROR /* must have '=' after '@' */
1450 },
1451 {
1452 "de_DE@euro;collation=phonebook",
1453 "de_DE", /* error result; bad format */
1454 "de_DE", /* error result; bad format */
1455 "de_DE", /* error result; bad format */
1456 {"","","","","","",""},
1457 0,
1458 U_INVALID_FORMAT_ERROR
1459 }
1460 };
1461 UErrorCode status = U_ZERO_ERROR;
1462
1463 int32_t i = 0, j = 0;
1464 int32_t resultLen = 0;
1465 char buffer[256];
1466 UEnumeration *keywords;
1467 int32_t keyCount = 0;
1468 const char *keyword = NULL;
1469 int32_t keywordLen = 0;
1470
1471 for(i = 0; i < sizeof(testCases)/sizeof(testCases[0]); i++) {
1472 status = U_ZERO_ERROR;
1473 *buffer = 0;
1474 keywords = uloc_openKeywords(testCases[i].localeID, &status);
1475
1476 if(status != testCases[i].expectedStatus) {
1477 log_err("Expected to uloc_openKeywords(\"%s\") => status %s. Got %s instead\n",
1478 testCases[i].localeID,
1479 u_errorName(testCases[i].expectedStatus), u_errorName(status));
1480 }
1481 status = U_ZERO_ERROR;
1482 if(keywords) {
1483 if((keyCount = uenum_count(keywords, &status)) != testCases[i].numKeywords) {
1484 log_err("Expected to get %i keywords, got %i\n", testCases[i].numKeywords, keyCount);
b75a7d8f 1485 }
374ca955
A
1486 if(keyCount) {
1487 j = 0;
1488 while((keyword = uenum_next(keywords, &keywordLen, &status))) {
1489 if(strcmp(keyword, testCases[i].expectedKeywords[j]) != 0) {
1490 log_err("Expected to get keyword value %s, got %s\n", testCases[i].expectedKeywords[j], keyword);
b75a7d8f 1491 }
374ca955 1492 j++;
b75a7d8f 1493 }
73c04bcf
A
1494 j = 0;
1495 uenum_reset(keywords, &status);
1496 while((keyword = uenum_next(keywords, &keywordLen, &status))) {
1497 if(strcmp(keyword, testCases[i].expectedKeywords[j]) != 0) {
1498 log_err("Expected to get keyword value %s, got %s\n", testCases[i].expectedKeywords[j], keyword);
1499 }
1500 j++;
1501 }
b75a7d8f 1502 }
374ca955 1503 uenum_close(keywords);
b75a7d8f 1504 }
374ca955
A
1505 resultLen = uloc_getName(testCases[i].localeID, buffer, 256, &status);
1506 if (uprv_strcmp(testCases[i].expectedLocaleID, buffer) != 0) {
1507 log_err("Expected uloc_getName(\"%s\") => \"%s\"; got \"%s\"\n",
1508 testCases[i].localeID, testCases[i].expectedLocaleID, buffer);
b75a7d8f 1509 }
374ca955
A
1510 resultLen = uloc_canonicalize(testCases[i].localeID, buffer, 256, &status);
1511 if (uprv_strcmp(testCases[i].expectedCanonicalID, buffer) != 0) {
1512 log_err("Expected uloc_canonicalize(\"%s\") => \"%s\"; got \"%s\"\n",
1513 testCases[i].localeID, testCases[i].expectedCanonicalID, buffer);
1514 }
1515 }
1516
1517}
1518
1519static void TestKeywordVariantParsing(void)
1520{
46f4442e 1521 static const struct {
374ca955
A
1522 const char *localeID;
1523 const char *keyword;
1524 const char *expectedValue;
1525 } testCases[] = {
1526 { "de_DE@ C o ll A t i o n = Phonebook ", "c o ll a t i o n", "Phonebook" },
1527 { "de_DE", "collation", ""},
1528 { "de_DE@collation=PHONEBOOK", "collation", "PHONEBOOK" },
1529 { "de_DE@currency = euro; CoLLaTion = PHONEBOOk", "collatiON", "PHONEBOOk" },
1530 };
1531
1532 UErrorCode status = U_ZERO_ERROR;
1533
1534 int32_t i = 0;
1535 int32_t resultLen = 0;
1536 char buffer[256];
1537
1538 for(i = 0; i < sizeof(testCases)/sizeof(testCases[0]); i++) {
1539 *buffer = 0;
1540 resultLen = uloc_getKeywordValue(testCases[i].localeID, testCases[i].keyword, buffer, 256, &status);
1541 if(uprv_strcmp(testCases[i].expectedValue, buffer) != 0) {
1542 log_err("Expected to extract \"%s\" from \"%s\" for keyword \"%s\". Got \"%s\" instead\n",
1543 testCases[i].expectedValue, testCases[i].localeID, testCases[i].keyword, buffer);
b75a7d8f 1544 }
b75a7d8f
A
1545 }
1546}
1547
46f4442e 1548static const struct {
374ca955
A
1549 const char *l; /* locale */
1550 const char *k; /* kw */
1551 const char *v; /* value */
1552 const char *x; /* expected */
1553} kwSetTestCases[] = {
1554#if 1
1555 { "en_US", "calendar", "japanese", "en_US@calendar=japanese" },
1556 { "en_US@", "calendar", "japanese", "en_US@calendar=japanese" },
1557 { "en_US@calendar=islamic", "calendar", "japanese", "en_US@calendar=japanese" },
1558 { "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 */
1559 { "en_US@calendar=gregorian", "calendar", "japanese", "en_US@calendar=japanese" },
1560 { "de", "Currency", "CHF", "de@currency=CHF" },
1561 { "de", "Currency", "CHF", "de@currency=CHF" },
1562
1563 { "en_US@collation=phonebook", "calendar", "japanese", "en_US@calendar=japanese;collation=phonebook" },
1564 { "en_US@calendar=japanese", "collation", "phonebook", "en_US@calendar=japanese;collation=phonebook" },
1565 { "de@collation=phonebook", "Currency", "CHF", "de@collation=phonebook;currency=CHF" },
1566 { "en_US@calendar=gregorian;collation=phonebook", "calendar", "japanese", "en_US@calendar=japanese;collation=phonebook" },
1567 { "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 */
1568 { "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 */
1569 { "en_US@calendar=islamic;collation=phonebook", "calendar", "japanese", "en_US@calendar=japanese;collation=phonebook" },
1570 { "de@collation=phonebook", "Currency", "CHF", "de@collation=phonebook;currency=CHF" },
1571#endif
1572#if 1
1573 { "mt@a=0;b=1;c=2;d=3", "c","j", "mt@a=0;b=1;c=j;d=3" },
1574 { "mt@a=0;b=1;c=2;d=3", "x","j", "mt@a=0;b=1;c=2;d=3;x=j" },
1575 { "mt@a=0;b=1;c=2;d=3", "a","f", "mt@a=f;b=1;c=2;d=3" },
1576 { "mt@a=0;aa=1;aaa=3", "a","x", "mt@a=x;aa=1;aaa=3" },
1577 { "mt@a=0;aa=1;aaa=3", "aa","x", "mt@a=0;aa=x;aaa=3" },
1578 { "mt@a=0;aa=1;aaa=3", "aaa","x", "mt@a=0;aa=1;aaa=x" },
1579 { "mt@a=0;aa=1;aaa=3", "a","yy", "mt@a=yy;aa=1;aaa=3" },
1580 { "mt@a=0;aa=1;aaa=3", "aa","yy", "mt@a=0;aa=yy;aaa=3" },
1581 { "mt@a=0;aa=1;aaa=3", "aaa","yy", "mt@a=0;aa=1;aaa=yy" },
1582#endif
1583#if 1
1584 /* removal tests */
1585 /* 1. removal of item at end */
1586 { "de@collation=phonebook;currency=CHF", "currency", "", "de@collation=phonebook" },
1587 { "de@collation=phonebook;currency=CHF", "currency", NULL, "de@collation=phonebook" },
1588 /* 2. removal of item at beginning */
1589 { "de@collation=phonebook;currency=CHF", "collation", "", "de@currency=CHF" },
1590 { "de@collation=phonebook;currency=CHF", "collation", NULL, "de@currency=CHF" },
1591 /* 3. removal of an item not there */
1592 { "de@collation=phonebook;currency=CHF", "calendar", NULL, "de@collation=phonebook;currency=CHF" },
1593 /* 4. removal of only item */
1594 { "de@collation=phonebook", "collation", NULL, "de" },
1595#endif
1596 { "de@collation=phonebook", "Currency", "CHF", "de@collation=phonebook;currency=CHF" }
1597};
b75a7d8f 1598
b75a7d8f 1599
374ca955 1600static void TestKeywordSet(void)
b75a7d8f 1601{
374ca955
A
1602 int32_t i = 0;
1603 int32_t resultLen = 0;
1604 char buffer[1024];
b75a7d8f 1605
374ca955 1606 char cbuffer[1024];
b75a7d8f 1607
374ca955
A
1608 for(i = 0; i < sizeof(kwSetTestCases)/sizeof(kwSetTestCases[0]); i++) {
1609 UErrorCode status = U_ZERO_ERROR;
1610 memset(buffer,'%',1023);
1611 strcpy(buffer, kwSetTestCases[i].l);
b75a7d8f 1612
374ca955
A
1613 uloc_canonicalize(kwSetTestCases[i].l, cbuffer, 1023, &status);
1614 if(strcmp(buffer,cbuffer)) {
1615 log_verbose("note: [%d] wasn't canonical, should be: '%s' not '%s'. Won't check for canonicity in output.\n", i, cbuffer, buffer);
b75a7d8f 1616 }
374ca955
A
1617 /* sanity check test case results for canonicity */
1618 uloc_canonicalize(kwSetTestCases[i].x, cbuffer, 1023, &status);
1619 if(strcmp(kwSetTestCases[i].x,cbuffer)) {
1620 log_err("%s:%d: ERROR: kwSetTestCases[%d].x = '%s', should be %s (must be canonical)\n", __FILE__, __LINE__, i, kwSetTestCases[i].x, cbuffer);
b75a7d8f 1621 }
b75a7d8f 1622
374ca955
A
1623 resultLen = uloc_setKeywordValue(kwSetTestCases[i].k, kwSetTestCases[i].v, buffer, 1023, &status);
1624 if(U_FAILURE(status)) {
1625 log_err("Err on test case %d: got error %s\n", i, u_errorName(status));
1626 continue;
b75a7d8f 1627 }
374ca955
A
1628 if(strcmp(buffer,kwSetTestCases[i].x) || ((int32_t)strlen(buffer)!=resultLen)) {
1629 log_err("FAIL: #%d: %s + [%s=%s] -> %s (%d) expected %s (%d)\n", i, kwSetTestCases[i].l, kwSetTestCases[i].k,
1630 kwSetTestCases[i].v, buffer, resultLen, kwSetTestCases[i].x, strlen(buffer));
1631 } else {
1632 log_verbose("pass: #%d: %s + [%s=%s] -> %s\n", i, kwSetTestCases[i].l, kwSetTestCases[i].k, kwSetTestCases[i].v,buffer);
b75a7d8f
A
1633 }
1634 }
1635}
1636
374ca955
A
1637static void TestKeywordSetError(void)
1638{
1639 char buffer[1024];
1640 UErrorCode status;
1641 int32_t res;
1642 int32_t i;
1643 int32_t blen;
b75a7d8f 1644
374ca955
A
1645 /* 0-test whether an error condition modifies the buffer at all */
1646 blen=0;
1647 i=0;
1648 memset(buffer,'%',1023);
1649 status = U_ZERO_ERROR;
1650 res = uloc_setKeywordValue(kwSetTestCases[i].k, kwSetTestCases[i].v, buffer, blen, &status);
1651 if(status != U_ILLEGAL_ARGUMENT_ERROR) {
1652 log_err("expected illegal err got %s\n", u_errorName(status));
1653 return;
1654 }
1655 /* if(res!=strlen(kwSetTestCases[i].x)) {
1656 log_err("expected result %d got %d\n", strlen(kwSetTestCases[i].x), res);
1657 return;
1658 } */
1659 if(buffer[blen]!='%') {
1660 log_err("Buffer byte %d was modified: now %c\n", blen, buffer[blen]);
1661 return;
1662 }
1663 log_verbose("0-buffer modify OK\n");
b75a7d8f 1664
374ca955
A
1665 for(i=0;i<=2;i++) {
1666 /* 1- test a short buffer with growing text */
73c04bcf 1667 blen=(int32_t)strlen(kwSetTestCases[i].l)+1;
374ca955
A
1668 memset(buffer,'%',1023);
1669 strcpy(buffer,kwSetTestCases[i].l);
1670 status = U_ZERO_ERROR;
1671 res = uloc_setKeywordValue(kwSetTestCases[i].k, kwSetTestCases[i].v, buffer, blen, &status);
1672 if(status != U_BUFFER_OVERFLOW_ERROR) {
1673 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);
1674 return;
b75a7d8f 1675 }
374ca955
A
1676 if(res!=(int32_t)strlen(kwSetTestCases[i].x)) {
1677 log_err("expected result %d got %d\n", strlen(kwSetTestCases[i].x), res);
1678 return;
b75a7d8f 1679 }
374ca955
A
1680 if(buffer[blen]!='%') {
1681 log_err("Buffer byte %d was modified: now %c\n", blen, buffer[blen]);
1682 return;
b75a7d8f 1683 }
374ca955 1684 log_verbose("1/%d-buffer modify OK\n",i);
b75a7d8f
A
1685 }
1686
374ca955
A
1687 for(i=3;i<=4;i++) {
1688 /* 2- test a short buffer - text the same size or shrinking */
73c04bcf 1689 blen=(int32_t)strlen(kwSetTestCases[i].l)+1;
374ca955
A
1690 memset(buffer,'%',1023);
1691 strcpy(buffer,kwSetTestCases[i].l);
1692 status = U_ZERO_ERROR;
1693 res = uloc_setKeywordValue(kwSetTestCases[i].k, kwSetTestCases[i].v, buffer, blen, &status);
1694 if(status != U_ZERO_ERROR) {
1695 log_err("expected zero error got %s\n", u_errorName(status));
1696 return;
b75a7d8f 1697 }
374ca955
A
1698 if(buffer[blen+1]!='%') {
1699 log_err("Buffer byte %d was modified: now %c\n", blen+1, buffer[blen+1]);
1700 return;
b75a7d8f 1701 }
374ca955
A
1702 if(res!=(int32_t)strlen(kwSetTestCases[i].x)) {
1703 log_err("expected result %d got %d\n", strlen(kwSetTestCases[i].x), res);
1704 return;
b75a7d8f 1705 }
374ca955
A
1706 if(strcmp(buffer,kwSetTestCases[i].x) || ((int32_t)strlen(buffer)!=res)) {
1707 log_err("FAIL: #%d: %s + [%s=%s] -> %s (%d) expected %s (%d)\n", i, kwSetTestCases[i].l, kwSetTestCases[i].k,
1708 kwSetTestCases[i].v, buffer, res, kwSetTestCases[i].x, strlen(buffer));
1709 } else {
1710 log_verbose("pass: #%d: %s + [%s=%s] -> %s\n", i, kwSetTestCases[i].l, kwSetTestCases[i].k, kwSetTestCases[i].v,
1711 buffer);
1712 }
1713 log_verbose("2/%d-buffer modify OK\n",i);
b75a7d8f 1714 }
374ca955 1715}
b75a7d8f 1716
374ca955
A
1717static int32_t _canonicalize(int32_t selector, /* 0==getName, 1==canonicalize */
1718 const char* localeID,
1719 char* result,
1720 int32_t resultCapacity,
1721 UErrorCode* ec) {
1722 /* YOU can change this to use function pointers if you like */
1723 switch (selector) {
1724 case 0:
1725 return uloc_getName(localeID, result, resultCapacity, ec);
1726 case 1:
1727 return uloc_canonicalize(localeID, result, resultCapacity, ec);
1728 default:
1729 return -1;
1730 }
b75a7d8f
A
1731}
1732
374ca955 1733static void TestCanonicalization(void)
b75a7d8f 1734{
46f4442e 1735 static const struct {
374ca955
A
1736 const char *localeID; /* input */
1737 const char *getNameID; /* expected getName() result */
1738 const char *canonicalID; /* expected canonicalize() result */
1739 } testCases[] = {
1740 { "ca_ES_PREEURO-with-extra-stuff-that really doesn't make any sense-unless-you're trying to increase code coverage",
1741 "ca_ES_PREEURO_WITH_EXTRA_STUFF_THAT REALLY DOESN'T MAKE ANY SENSE_UNLESS_YOU'RE TRYING TO INCREASE CODE COVERAGE",
1742 "ca_ES_PREEURO_WITH_EXTRA_STUFF_THAT REALLY DOESN'T MAKE ANY SENSE_UNLESS_YOU'RE TRYING TO INCREASE CODE COVERAGE"},
1743 { "ca_ES_PREEURO", "ca_ES_PREEURO", "ca_ES@currency=ESP" },
1744 { "de_AT_PREEURO", "de_AT_PREEURO", "de_AT@currency=ATS" },
1745 { "de_DE_PREEURO", "de_DE_PREEURO", "de_DE@currency=DEM" },
1746 { "de_LU_PREEURO", "de_LU_PREEURO", "de_LU@currency=LUF" },
1747 { "el_GR_PREEURO", "el_GR_PREEURO", "el_GR@currency=GRD" },
1748 { "en_BE_PREEURO", "en_BE_PREEURO", "en_BE@currency=BEF" },
1749 { "en_IE_PREEURO", "en_IE_PREEURO", "en_IE@currency=IEP" },
1750 { "es_ES_PREEURO", "es_ES_PREEURO", "es_ES@currency=ESP" },
1751 { "eu_ES_PREEURO", "eu_ES_PREEURO", "eu_ES@currency=ESP" },
1752 { "fi_FI_PREEURO", "fi_FI_PREEURO", "fi_FI@currency=FIM" },
1753 { "fr_BE_PREEURO", "fr_BE_PREEURO", "fr_BE@currency=BEF" },
1754 { "fr_FR_PREEURO", "fr_FR_PREEURO", "fr_FR@currency=FRF" },
1755 { "fr_LU_PREEURO", "fr_LU_PREEURO", "fr_LU@currency=LUF" },
1756 { "ga_IE_PREEURO", "ga_IE_PREEURO", "ga_IE@currency=IEP" },
1757 { "gl_ES_PREEURO", "gl_ES_PREEURO", "gl_ES@currency=ESP" },
1758 { "it_IT_PREEURO", "it_IT_PREEURO", "it_IT@currency=ITL" },
1759 { "nl_BE_PREEURO", "nl_BE_PREEURO", "nl_BE@currency=BEF" },
1760 { "nl_NL_PREEURO", "nl_NL_PREEURO", "nl_NL@currency=NLG" },
1761 { "pt_PT_PREEURO", "pt_PT_PREEURO", "pt_PT@currency=PTE" },
1762 { "de__PHONEBOOK", "de__PHONEBOOK", "de@collation=phonebook" },
1763 { "en_GB_EURO", "en_GB_EURO", "en_GB@currency=EUR" },
1764 { "en_GB@EURO", "en_GB@EURO", "en_GB@currency=EUR" }, /* POSIX ID */
1765 { "es__TRADITIONAL", "es__TRADITIONAL", "es@collation=traditional" },
1766 { "hi__DIRECT", "hi__DIRECT", "hi@collation=direct" },
1767 { "ja_JP_TRADITIONAL", "ja_JP_TRADITIONAL", "ja_JP@calendar=japanese" },
1768 { "th_TH_TRADITIONAL", "th_TH_TRADITIONAL", "th_TH@calendar=buddhist" },
46f4442e 1769 { "zh_TW_STROKE", "zh_TW_STROKE", "zh_TW@collation=stroke" },
374ca955
A
1770 { "zh__PINYIN", "zh__PINYIN", "zh@collation=pinyin" },
1771 { "zh@collation=pinyin", "zh@collation=pinyin", "zh@collation=pinyin" },
1772 { "zh_CN@collation=pinyin", "zh_CN@collation=pinyin", "zh_CN@collation=pinyin" },
46f4442e 1773 { "zh_CN_STROKE", "zh_CN_STROKE", "zh_CN@collation=stroke" },
374ca955
A
1774 { "zh_CN_CA@collation=pinyin", "zh_CN_CA@collation=pinyin", "zh_CN_CA@collation=pinyin" },
1775 { "en_US_POSIX", "en_US_POSIX", "en_US_POSIX" },
1776 { "hy_AM_REVISED", "hy_AM_REVISED", "hy_AM_REVISED" },
1777 { "no_NO_NY", "no_NO_NY", "no_NO_NY" /* not: "nn_NO" [alan ICU3.0] */ },
1778 { "no@ny", "no@ny", "no__NY" /* not: "nn" [alan ICU3.0] */ }, /* POSIX ID */
1779 { "no-no.utf32@B", "no_NO.utf32@B", "no_NO_B" /* not: "nb_NO_B" [alan ICU3.0] */ }, /* POSIX ID */
1780 { "qz-qz@Euro", "qz_QZ@Euro", "qz_QZ@currency=EUR" }, /* qz-qz uses private use iso codes */
1781 { "en-BOONT", "en_BOONT", "en__BOONT" }, /* registered name */
1782 { "de-1901", "de_1901", "de__1901" }, /* registered name */
1783 { "de-1906", "de_1906", "de__1906" }, /* registered name */
46f4442e
A
1784 { "sr-SP-Cyrl", "sr_SP_CYRL", "sr_Cyrl_RS" }, /* .NET name */
1785 { "sr-SP-Latn", "sr_SP_LATN", "sr_Latn_RS" }, /* .NET name */
1786 { "sr_YU_CYRILLIC", "sr_YU_CYRILLIC", "sr_Cyrl_RS" }, /* Linux name */
374ca955
A
1787 { "uz-UZ-Cyrl", "uz_UZ_CYRL", "uz_Cyrl_UZ" }, /* .NET name */
1788 { "uz-UZ-Latn", "uz_UZ_LATN", "uz_Latn_UZ" }, /* .NET name */
1789 { "zh-CHS", "zh_CHS", "zh_Hans" }, /* .NET name */
73c04bcf 1790 { "zh-CHT", "zh_CHT", "zh_Hant" }, /* .NET name This may change back to zh_Hant */
374ca955
A
1791
1792 /* posix behavior that used to be performed by getName */
1793 { "mr.utf8", "mr.utf8", "mr" },
1794 { "de-tv.koi8r", "de_TV.koi8r", "de_TV" },
1795 { "x-piglatin_ML.MBE", "x-piglatin_ML.MBE", "x-piglatin_ML" },
1796 { "i-cherokee_US.utf7", "i-cherokee_US.utf7", "i-cherokee_US" },
1797 { "x-filfli_MT_FILFLA.gb-18030", "x-filfli_MT_FILFLA.gb-18030", "x-filfli_MT_FILFLA" },
1798 { "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 */
1799
1800 /* fleshing out canonicalization */
1801 /* trim space and sort keywords, ';' is separator so not present at end in canonical form */
1802 { "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" },
1803 /* already-canonical ids are not changed */
1804 { "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" },
1805 /* PRE_EURO and EURO conversions don't affect other keywords */
1806 { "es_ES_PREEURO@CALendar=Japanese", "es_ES_PREEURO@calendar=Japanese", "es_ES@calendar=Japanese;currency=ESP" },
1807 { "es_ES_EURO@SHOUT=zipeedeedoodah", "es_ES_EURO@shout=zipeedeedoodah", "es_ES@currency=EUR;shout=zipeedeedoodah" },
1808 /* currency keyword overrides PRE_EURO and EURO currency */
1809 { "es_ES_PREEURO@currency=EUR", "es_ES_PREEURO@currency=EUR", "es_ES@currency=EUR" },
1810 { "es_ES_EURO@currency=ESP", "es_ES_EURO@currency=ESP", "es_ES@currency=ESP" },
1811 /* norwegian is just too weird, if we handle things in their full generality */
1812 { "no-Hant-GB_NY@currency=$$$", "no_Hant_GB_NY@currency=$$$", "no_Hant_GB_NY@currency=$$$" /* not: "nn_Hant_GB@currency=$$$" [alan ICU3.0] */ },
1813
1814 /* test cases reflecting internal resource bundle usage */
1815 { "root@kw=foo", "root@kw=foo", "root@kw=foo" },
1816 { "@calendar=gregorian", "@calendar=gregorian", "@calendar=gregorian" },
1817 { "ja_JP@calendar=Japanese", "ja_JP@calendar=Japanese", "ja_JP@calendar=Japanese" },
73c04bcf
A
1818 { "ja_JP", "ja_JP", "ja_JP" },
1819
1820 /* test case for "i-default" */
1821 { "i-default", NULL, NULL }
374ca955
A
1822 };
1823
1824 static const char* label[] = { "getName", "canonicalize" };
1825
1826 UErrorCode status = U_ZERO_ERROR;
1827 int32_t i, j, resultLen = 0, origResultLen;
1828 char buffer[256];
1829
1830 for (i=0; i < sizeof(testCases)/sizeof(testCases[0]); i++) {
1831 for (j=0; j<2; ++j) {
1832 const char* expected = (j==0) ? testCases[i].getNameID : testCases[i].canonicalID;
1833 *buffer = 0;
1834 status = U_ZERO_ERROR;
73c04bcf
A
1835
1836 if (expected == NULL) {
1837 expected = uloc_getDefault();
1838 }
1839
374ca955
A
1840 /* log_verbose("testing %s -> %s\n", testCases[i], testCases[i].canonicalID); */
1841 origResultLen = _canonicalize(j, testCases[i].localeID, NULL, 0, &status);
1842 if (status != U_BUFFER_OVERFLOW_ERROR) {
1843 log_err("FAIL: uloc_%s(%s) => %s, expected U_BUFFER_OVERFLOW_ERROR\n",
1844 label[j], testCases[i].localeID, u_errorName(status));
1845 continue;
1846 }
1847 status = U_ZERO_ERROR;
1848 resultLen = _canonicalize(j, testCases[i].localeID, buffer, sizeof(buffer), &status);
1849 if (U_FAILURE(status)) {
1850 log_err("FAIL: uloc_%s(%s) => %s, expected U_ZERO_ERROR\n",
1851 label[j], testCases[i].localeID, u_errorName(status));
1852 continue;
1853 }
1854 if(uprv_strcmp(expected, buffer) != 0) {
1855 log_err("FAIL: uloc_%s(%s) => \"%s\", expected \"%s\"\n",
1856 label[j], testCases[i].localeID, buffer, expected);
1857 } else {
1858 log_verbose("Ok: uloc_%s(%s) => \"%s\"\n",
1859 label[j], testCases[i].localeID, buffer);
1860 }
1861 if (resultLen != (int32_t)strlen(buffer)) {
1862 log_err("FAIL: uloc_%s(%s) => len %d, expected len %d\n",
1863 label[j], testCases[i].localeID, resultLen, strlen(buffer));
1864 }
1865 if (origResultLen != resultLen) {
1866 log_err("FAIL: uloc_%s(%s) => preflight len %d != actual len %d\n",
1867 label[j], testCases[i].localeID, origResultLen, resultLen);
1868 }
b75a7d8f
A
1869 }
1870 }
1871}
1872
374ca955
A
1873static void TestDisplayKeywords(void)
1874{
1875 int32_t i;
b75a7d8f 1876
374ca955
A
1877 static const struct {
1878 const char *localeID;
1879 const char *displayLocale;
1880 UChar displayKeyword[200];
1881 } testCases[] = {
1882 { "ca_ES@currency=ESP", "de_AT",
1883 {0x0057, 0x00e4, 0x0068, 0x0072, 0x0075, 0x006e, 0x0067, 0x0000},
1884 },
1885 { "ja_JP@calendar=japanese", "de",
1886 { 0x004b, 0x0061, 0x006c, 0x0065, 0x006e, 0x0064, 0x0065, 0x0072, 0x0000}
1887 },
1888 { "de_DE@collation=traditional", "de_DE",
1889 {0x0053, 0x006f, 0x0072, 0x0074, 0x0069, 0x0065, 0x0072, 0x0075, 0x006e, 0x0067, 0x0000}
1890 },
1891 };
1892 for(i = 0; i < sizeof(testCases)/sizeof(testCases[0]); i++) {
1893 UErrorCode status = U_ZERO_ERROR;
1894 const char* keyword =NULL;
1895 int32_t keywordLen = 0;
1896 int32_t keywordCount = 0;
1897 UChar *displayKeyword=NULL;
1898 int32_t displayKeywordLen = 0;
1899 UEnumeration* keywordEnum = uloc_openKeywords(testCases[i].localeID, &status);
1900 for(keywordCount = uenum_count(keywordEnum, &status); keywordCount > 0 ; keywordCount--){
1901 if(U_FAILURE(status)){
1902 log_err("uloc_getKeywords failed for locale id: %s with error : %s \n", testCases[i].localeID, u_errorName(status));
1903 break;
1904 }
1905 /* the uenum_next returns NUL terminated string */
1906 keyword = uenum_next(keywordEnum, &keywordLen, &status);
1907 /* fetch the displayKeyword */
1908 displayKeywordLen = uloc_getDisplayKeyword(keyword, testCases[i].displayLocale, displayKeyword, displayKeywordLen, &status);
1909 if(status==U_BUFFER_OVERFLOW_ERROR){
1910 status = U_ZERO_ERROR;
1911 displayKeywordLen++; /* for null termination */
1912 displayKeyword = (UChar*) malloc(displayKeywordLen * U_SIZEOF_UCHAR);
1913 displayKeywordLen = uloc_getDisplayKeyword(keyword, testCases[i].displayLocale, displayKeyword, displayKeywordLen, &status);
1914 if(U_FAILURE(status)){
1915 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));
1916 break;
1917 }
1918 if(u_strncmp(displayKeyword, testCases[i].displayKeyword, displayKeywordLen)!=0){
1919 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);
1920 break;
1921 }
1922 }else{
1923 log_err("uloc_getDisplayKeyword did not return the expected error. Error: %s\n", u_errorName(status));
1924 }
1925
1926 free(displayKeyword);
1927
1928 }
1929 uenum_close(keywordEnum);
b75a7d8f 1930 }
374ca955 1931}
b75a7d8f 1932
374ca955 1933static void TestDisplayKeywordValues(void){
46f4442e 1934 int32_t i;
374ca955 1935
46f4442e 1936 static const struct {
374ca955
A
1937 const char *localeID;
1938 const char *displayLocale;
1939 UChar displayKeywordValue[500];
1940 } testCases[] = {
1941 { "ca_ES@currency=ESP", "de_AT",
1942 {0x0053, 0x0070, 0x0061, 0x006e, 0x0069, 0x0073, 0x0063, 0x0068, 0x0065, 0x0020, 0x0050, 0x0065, 0x0073, 0x0065, 0x0074, 0x0065, 0x0000}
1943 },
1944 { "de_AT@currency=ATS", "fr_FR",
1945 {0x0073, 0x0063, 0x0068, 0x0069, 0x006c, 0x006c, 0x0069, 0x006e, 0x0067, 0x0020, 0x0061, 0x0075, 0x0074, 0x0072, 0x0069, 0x0063, 0x0068, 0x0069, 0x0065, 0x006e, 0x0000}
1946 },
1947 { "de_DE@currency=DEM", "it",
1948 {0x004d, 0x0061, 0x0072, 0x0063, 0x006f, 0x0020, 0x0054, 0x0065, 0x0064, 0x0065, 0x0073, 0x0063, 0x006f, 0x0000}
1949 },
1950 { "el_GR@currency=GRD", "en",
1951 {0x0047, 0x0072, 0x0065, 0x0065, 0x006b, 0x0020, 0x0044, 0x0072, 0x0061, 0x0063, 0x0068, 0x006d, 0x0061, 0x0000}
1952 },
1953 { "eu_ES@currency=ESP", "it_IT",
1954 {0x0050, 0x0065, 0x0073, 0x0065, 0x0074, 0x0061, 0x0020, 0x0053, 0x0070, 0x0061, 0x0067, 0x006e, 0x006f, 0x006c, 0x0061, 0x0000}
1955 },
1956 { "de@collation=phonebook", "es",
1957 {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}
1958 },
1959
1960 { "de_DE@collation=phonebook", "es",
1961 {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}
1962 },
1963 { "es_ES@collation=traditional","de",
1964 {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}
1965 },
1966 { "ja_JP@calendar=japanese", "de",
1967 {0x004a, 0x0061, 0x0070, 0x0061, 0x006e, 0x0069, 0x0073, 0x0063, 0x0068, 0x0065, 0x0072, 0x0020, 0x004b, 0x0061, 0x006c, 0x0065, 0x006e, 0x0064, 0x0065, 0x0072, 0x0000}
1968 },
1969 };
1970 for(i = 0; i < sizeof(testCases)/sizeof(testCases[0]); i++) {
1971 UErrorCode status = U_ZERO_ERROR;
1972 const char* keyword =NULL;
1973 int32_t keywordLen = 0;
1974 int32_t keywordCount = 0;
1975 UChar *displayKeywordValue = NULL;
1976 int32_t displayKeywordValueLen = 0;
1977 UEnumeration* keywordEnum = uloc_openKeywords(testCases[i].localeID, &status);
1978 for(keywordCount = uenum_count(keywordEnum, &status); keywordCount > 0 ; keywordCount--){
1979 if(U_FAILURE(status)){
1980 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));
1981 break;
1982 }
1983 /* the uenum_next returns NUL terminated string */
1984 keyword = uenum_next(keywordEnum, &keywordLen, &status);
1985
1986 /* fetch the displayKeywordValue */
1987 displayKeywordValueLen = uloc_getDisplayKeywordValue(testCases[i].localeID, keyword, testCases[i].displayLocale, displayKeywordValue, displayKeywordValueLen, &status);
1988 if(status==U_BUFFER_OVERFLOW_ERROR){
1989 status = U_ZERO_ERROR;
1990 displayKeywordValueLen++; /* for null termination */
1991 displayKeywordValue = (UChar*)malloc(displayKeywordValueLen * U_SIZEOF_UCHAR);
1992 displayKeywordValueLen = uloc_getDisplayKeywordValue(testCases[i].localeID, keyword, testCases[i].displayLocale, displayKeywordValue, displayKeywordValueLen, &status);
1993 if(U_FAILURE(status)){
1994 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));
1995 break;
1996 }
1997 if(u_strncmp(displayKeywordValue, testCases[i].displayKeywordValue, displayKeywordValueLen)!=0){
1998 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));
1999 break;
2000 }
2001 }else{
2002 log_err("uloc_getDisplayKeywordValue did not return the expected error. Error: %s\n", u_errorName(status));
2003 }
2004 free(displayKeywordValue);
2005 }
2006 uenum_close(keywordEnum);
2007 }
2008 {
2009 /* test a multiple keywords */
2010 UErrorCode status = U_ZERO_ERROR;
2011 const char* keyword =NULL;
2012 int32_t keywordLen = 0;
2013 int32_t keywordCount = 0;
2014 const char* localeID = "es@collation=phonebook;calendar=buddhist;currency=DEM";
2015 const char* displayLocale = "de";
46f4442e 2016 static const UChar expected[][50] = {
374ca955
A
2017 {0x0042, 0x0075, 0x0064, 0x0064, 0x0068, 0x0069, 0x0073, 0x0074, 0x0069, 0x0073, 0x0063, 0x0068, 0x0065, 0x0072, 0x0020, 0x004b, 0x0061, 0x006c, 0x0065, 0x006e, 0x0064, 0x0065, 0x0072, 0x0000},
2018
2019 {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},
2020 {0x0044, 0x0065, 0x0075, 0x0074, 0x0073, 0x0063, 0x0068, 0x0065, 0x0020, 0x004d, 0x0061, 0x0072, 0x006b, 0x0000},
2021 };
2022
2023 UEnumeration* keywordEnum = uloc_openKeywords(localeID, &status);
2024
2025 for(keywordCount = 0; keywordCount < uenum_count(keywordEnum, &status) ; keywordCount++){
2026 UChar *displayKeywordValue = NULL;
2027 int32_t displayKeywordValueLen = 0;
2028 if(U_FAILURE(status)){
2029 log_err("uloc_getKeywords failed for locale id: %s in display locale: % with error : %s \n", localeID, displayLocale, u_errorName(status));
2030 break;
2031 }
2032 /* the uenum_next returns NUL terminated string */
2033 keyword = uenum_next(keywordEnum, &keywordLen, &status);
2034
2035 /* fetch the displayKeywordValue */
2036 displayKeywordValueLen = uloc_getDisplayKeywordValue(localeID, keyword, displayLocale, displayKeywordValue, displayKeywordValueLen, &status);
2037 if(status==U_BUFFER_OVERFLOW_ERROR){
2038 status = U_ZERO_ERROR;
2039 displayKeywordValueLen++; /* for null termination */
2040 displayKeywordValue = (UChar*)malloc(displayKeywordValueLen * U_SIZEOF_UCHAR);
2041 displayKeywordValueLen = uloc_getDisplayKeywordValue(localeID, keyword, displayLocale, displayKeywordValue, displayKeywordValueLen, &status);
2042 if(U_FAILURE(status)){
2043 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));
2044 break;
2045 }
2046 if(u_strncmp(displayKeywordValue, expected[keywordCount], displayKeywordValueLen)!=0){
2047 log_err("uloc_getDisplayKeywordValue did not return the expected value keyword : %s in locale id: %s for display locale: %s \n", localeID, keyword, displayLocale);
2048 break;
2049 }
2050 }else{
2051 log_err("uloc_getDisplayKeywordValue did not return the expected error. Error: %s\n", u_errorName(status));
2052 }
2053 free(displayKeywordValue);
2054 }
2055 uenum_close(keywordEnum);
2056
2057 }
b75a7d8f 2058 {
374ca955
A
2059 /* Test non existent keywords */
2060 UErrorCode status = U_ZERO_ERROR;
2061 const char* localeID = "es";
2062 const char* displayLocale = "de";
2063 UChar *displayKeywordValue = NULL;
2064 int32_t displayKeywordValueLen = 0;
2065
2066 /* fetch the displayKeywordValue */
2067 displayKeywordValueLen = uloc_getDisplayKeywordValue(localeID, "calendar", displayLocale, displayKeywordValue, displayKeywordValueLen, &status);
2068 if(U_FAILURE(status)) {
2069 log_err("uloc_getDisplaykeywordValue returned error status %s\n", u_errorName(status));
2070 } else if(displayKeywordValueLen != 0) {
2071 log_err("uloc_getDisplaykeywordValue returned %d should be 0 \n", displayKeywordValueLen);
b75a7d8f
A
2072 }
2073 }
374ca955 2074}
b75a7d8f 2075
b75a7d8f 2076
374ca955 2077static void TestGetBaseName(void) {
46f4442e 2078 static const struct {
374ca955
A
2079 const char *localeID;
2080 const char *baseName;
2081 } testCases[] = {
2082 { "de_DE@ C o ll A t i o n = Phonebook ", "de_DE" },
2083 { "de@currency = euro; CoLLaTion = PHONEBOOk", "de" },
2084 { "ja@calendar = buddhist", "ja" }
2085 };
b75a7d8f 2086
374ca955
A
2087 int32_t i = 0, baseNameLen = 0;
2088 char baseName[256];
2089 UErrorCode status = U_ZERO_ERROR;
b75a7d8f 2090
374ca955
A
2091 for(i = 0; i < sizeof(testCases)/sizeof(testCases[0]); i++) {
2092 baseNameLen = uloc_getBaseName(testCases[i].localeID, baseName, 256, &status);
2093 if(strcmp(testCases[i].baseName, baseName)) {
2094 log_err("For locale \"%s\" expected baseName \"%s\", but got \"%s\"\n",
2095 testCases[i].localeID, testCases[i].baseName, baseName);
2096 return;
2097 }
b75a7d8f 2098 }
b75a7d8f 2099
b75a7d8f
A
2100}
2101
b75a7d8f 2102
374ca955
A
2103/* Jitterbug 4115 */
2104static void TestDisplayNameWarning(void) {
2105 UChar name[256];
2106 int32_t size;
2107 UErrorCode status = U_ZERO_ERROR;
2108
2109 size = uloc_getDisplayLanguage("qqq", "kl", name, sizeof(name)/sizeof(name[0]), &status);
2110 if (status != U_USING_DEFAULT_WARNING) {
2111 log_err("For language \"qqq\" in locale \"kl\", expecting U_USING_DEFAULT_WARNING, but got %s\n",
2112 u_errorName(status));
2113 }
2114}
b75a7d8f 2115
b75a7d8f 2116
374ca955
A
2117/**
2118 * Compare two locale IDs. If they are equal, return 0. If `string'
2119 * starts with `prefix' plus an additional element, that is, string ==
2120 * prefix + '_' + x, then return 1. Otherwise return a value < 0.
2121 */
2122static UBool _loccmp(const char* string, const char* prefix) {
73c04bcf
A
2123 int32_t slen = (int32_t)uprv_strlen(string),
2124 plen = (int32_t)uprv_strlen(prefix);
374ca955
A
2125 int32_t c = uprv_strncmp(string, prefix, plen);
2126 /* 'root' is less than everything */
2127 if (uprv_strcmp(prefix, "root") == 0) {
2128 return (uprv_strcmp(string, "root") == 0) ? 0 : 1;
2129 }
2130 if (c) return -1; /* mismatch */
2131 if (slen == plen) return 0;
2132 if (string[plen] == '_') return 1;
2133 return -2; /* false match, e.g. "en_USX" cmp "en_US" */
2134}
b75a7d8f 2135
374ca955
A
2136static void _checklocs(const char* label,
2137 const char* req,
2138 const char* valid,
2139 const char* actual) {
2140 /* We want the valid to be strictly > the bogus requested locale,
2141 and the valid to be >= the actual. */
2142 if (_loccmp(req, valid) > 0 &&
2143 _loccmp(valid, actual) >= 0) {
2144 log_verbose("%s; req=%s, valid=%s, actual=%s\n",
2145 label, req, valid, actual);
2146 } else {
2147 log_err("FAIL: %s; req=%s, valid=%s, actual=%s\n",
2148 label, req, valid, actual);
b75a7d8f
A
2149 }
2150}
2151
374ca955
A
2152static void TestGetLocale(void) {
2153 UErrorCode ec = U_ZERO_ERROR;
2154 UParseError pe;
2155 UChar EMPTY[1] = {0};
b75a7d8f 2156
374ca955
A
2157 /* === udat === */
2158#if !UCONFIG_NO_FORMATTING
2159 {
2160 UDateFormat *obj;
2161 const char *req = "en_US_REDWOODSHORES", *valid, *actual;
2162 obj = udat_open(UDAT_DEFAULT, UDAT_DEFAULT,
2163 req,
2164 NULL, 0,
2165 NULL, 0, &ec);
2166 if (U_FAILURE(ec)) {
73c04bcf 2167 log_err("udat_open failed.Error %s\n", u_errorName(ec));
374ca955
A
2168 return;
2169 }
2170 valid = udat_getLocaleByType(obj, ULOC_VALID_LOCALE, &ec);
2171 actual = udat_getLocaleByType(obj, ULOC_ACTUAL_LOCALE, &ec);
2172 if (U_FAILURE(ec)) {
2173 log_err("udat_getLocaleByType() failed\n");
2174 return;
2175 }
2176 _checklocs("udat", req, valid, actual);
2177 udat_close(obj);
b75a7d8f 2178 }
374ca955 2179#endif
b75a7d8f 2180
374ca955
A
2181 /* === ucal === */
2182#if !UCONFIG_NO_FORMATTING
2183 {
2184 UCalendar *obj;
2185 const char *req = "fr_FR_PROVENCAL", *valid, *actual;
2186 obj = ucal_open(NULL, 0,
2187 req,
2188 UCAL_GREGORIAN,
2189 &ec);
2190 if (U_FAILURE(ec)) {
2191 log_err("ucal_open failed with error: %s\n", u_errorName(ec));
2192 return;
2193 }
2194 valid = ucal_getLocaleByType(obj, ULOC_VALID_LOCALE, &ec);
2195 actual = ucal_getLocaleByType(obj, ULOC_ACTUAL_LOCALE, &ec);
2196 if (U_FAILURE(ec)) {
2197 log_err("ucal_getLocaleByType() failed\n");
2198 return;
2199 }
2200 _checklocs("ucal", req, valid, actual);
2201 ucal_close(obj);
b75a7d8f 2202 }
374ca955 2203#endif
b75a7d8f 2204
374ca955
A
2205 /* === unum === */
2206#if !UCONFIG_NO_FORMATTING
2207 {
2208 UNumberFormat *obj;
2209 const char *req = "zh_Hant_TW_TAINAN", *valid, *actual;
2210 obj = unum_open(UNUM_DECIMAL,
2211 NULL, 0,
2212 req,
2213 &pe, &ec);
2214 if (U_FAILURE(ec)) {
2215 log_err("unum_open failed\n");
2216 return;
2217 }
2218 valid = unum_getLocaleByType(obj, ULOC_VALID_LOCALE, &ec);
2219 actual = unum_getLocaleByType(obj, ULOC_ACTUAL_LOCALE, &ec);
2220 if (U_FAILURE(ec)) {
2221 log_err("unum_getLocaleByType() failed\n");
2222 return;
2223 }
2224 _checklocs("unum", req, valid, actual);
2225 unum_close(obj);
2226 }
2227#endif
b75a7d8f 2228
374ca955 2229 /* === umsg === */
73c04bcf
A
2230#if 0
2231 /* commented out by weiv 01/12/2005. umsg_getLocaleByType is to be removed */
374ca955
A
2232#if !UCONFIG_NO_FORMATTING
2233 {
2234 UMessageFormat *obj;
2235 const char *req = "ja_JP_TAKAYAMA", *valid, *actual;
2236 UBool test;
2237 obj = umsg_open(EMPTY, 0,
2238 req,
2239 &pe, &ec);
2240 if (U_FAILURE(ec)) {
2241 log_err("umsg_open failed\n");
2242 return;
2243 }
2244 valid = umsg_getLocaleByType(obj, ULOC_VALID_LOCALE, &ec);
2245 actual = umsg_getLocaleByType(obj, ULOC_ACTUAL_LOCALE, &ec);
2246 if (U_FAILURE(ec)) {
2247 log_err("umsg_getLocaleByType() failed\n");
2248 return;
2249 }
2250 /* We want the valid to be strictly > the bogus requested locale,
2251 and the valid to be >= the actual. */
2252 /* TODO MessageFormat is currently just storing the locale it is given.
2253 As a result, it will return whatever it was given, even if the
2254 locale is invalid. */
2255 test = (_cmpversion("3.2") <= 0) ?
2256 /* Here is the weakened test for 3.0: */
2257 (_loccmp(req, valid) >= 0) :
2258 /* Here is what the test line SHOULD be: */
2259 (_loccmp(req, valid) > 0);
2260
2261 if (test &&
2262 _loccmp(valid, actual) >= 0) {
2263 log_verbose("umsg; req=%s, valid=%s, actual=%s\n", req, valid, actual);
2264 } else {
2265 log_err("FAIL: umsg; req=%s, valid=%s, actual=%s\n", req, valid, actual);
2266 }
2267 umsg_close(obj);
2268 }
73c04bcf 2269#endif
374ca955 2270#endif
b75a7d8f 2271
374ca955
A
2272 /* === ubrk === */
2273#if !UCONFIG_NO_BREAK_ITERATION
2274 {
2275 UBreakIterator *obj;
2276 const char *req = "ar_KW_ABDALI", *valid, *actual;
2277 obj = ubrk_open(UBRK_WORD,
2278 req,
2279 EMPTY,
2280 0,
2281 &ec);
2282 if (U_FAILURE(ec)) {
73c04bcf 2283 log_err("ubrk_open failed. Error: %s \n", u_errorName(ec));
374ca955
A
2284 return;
2285 }
2286 valid = ubrk_getLocaleByType(obj, ULOC_VALID_LOCALE, &ec);
2287 actual = ubrk_getLocaleByType(obj, ULOC_ACTUAL_LOCALE, &ec);
2288 if (U_FAILURE(ec)) {
2289 log_err("ubrk_getLocaleByType() failed\n");
2290 return;
2291 }
2292 _checklocs("ubrk", req, valid, actual);
2293 ubrk_close(obj);
2294 }
2295#endif
b75a7d8f 2296
374ca955
A
2297 /* === ucol === */
2298#if !UCONFIG_NO_COLLATION
2299 {
2300 UCollator *obj;
2301 const char *req = "es_AR_BUENOSAIRES", *valid, *actual;
2302 obj = ucol_open(req, &ec);
2303 if (U_FAILURE(ec)) {
2304 log_err("ucol_open failed\n");
2305 return;
2306 }
2307 valid = ucol_getLocaleByType(obj, ULOC_VALID_LOCALE, &ec);
2308 actual = ucol_getLocaleByType(obj, ULOC_ACTUAL_LOCALE, &ec);
2309 if (U_FAILURE(ec)) {
2310 log_err("ucol_getLocaleByType() failed\n");
2311 return;
2312 }
2313 _checklocs("ucol", req, valid, actual);
2314 ucol_close(obj);
2315 }
2316#endif
2317}
b75a7d8f 2318
374ca955
A
2319static void TestNonexistentLanguageExemplars(void) {
2320 /* JB 4068 - Nonexistent language */
2321 UErrorCode ec = U_ZERO_ERROR;
73c04bcf 2322 ULocaleData *uld = ulocdata_open("qqq",&ec);
374ca955
A
2323 if (ec != U_USING_DEFAULT_WARNING) {
2324 log_err("Exemplar set for \"qqq\", expecting U_USING_DEFAULT_WARNING, but got %s\n",
2325 u_errorName(ec));
b75a7d8f 2326 }
73c04bcf
A
2327 uset_close(ulocdata_getExemplarSet(uld, NULL, 0, ULOCDATA_ES_STANDARD, &ec));
2328 ulocdata_close(uld);
2329}
2330
46f4442e
A
2331static void TestLocDataErrorCodeChaining(void) {
2332 UErrorCode ec = U_USELESS_COLLATOR_ERROR;
2333 ulocdata_open(NULL, &ec);
2334 ulocdata_getExemplarSet(NULL, NULL, 0, ULOCDATA_ES_STANDARD, &ec);
2335 ulocdata_getDelimiter(NULL, ULOCDATA_DELIMITER_COUNT, NULL, -1, &ec);
2336 ulocdata_getMeasurementSystem(NULL, &ec);
2337 ulocdata_getPaperSize(NULL, NULL, NULL, &ec);
2338 if (ec != U_USELESS_COLLATOR_ERROR) {
2339 log_err("ulocdata API changed the error code to %s\n", u_errorName(ec));
2340 }
2341}
2342
73c04bcf
A
2343static void TestLanguageExemplarsFallbacks(void) {
2344 /* Test that en_US fallsback, but en doesn't fallback. */
2345 UErrorCode ec = U_ZERO_ERROR;
2346 ULocaleData *uld = ulocdata_open("en_US",&ec);
2347 uset_close(ulocdata_getExemplarSet(uld, NULL, 0, ULOCDATA_ES_STANDARD, &ec));
2348 if (ec != U_USING_FALLBACK_WARNING) {
2349 log_err("Exemplar set for \"en_US\", expecting U_USING_FALLBACK_WARNING, but got %s\n",
2350 u_errorName(ec));
2351 }
2352 ulocdata_close(uld);
2353 ec = U_ZERO_ERROR;
2354 uld = ulocdata_open("en",&ec);
2355 uset_close(ulocdata_getExemplarSet(uld, NULL, 0, ULOCDATA_ES_STANDARD, &ec));
2356 if (ec != U_ZERO_ERROR) {
2357 log_err("Exemplar set for \"en\", expecting U_ZERO_ERROR, but got %s\n",
2358 u_errorName(ec));
2359 }
2360 ulocdata_close(uld);
374ca955 2361}
b75a7d8f 2362
374ca955 2363static void TestAcceptLanguage(void) {
46f4442e
A
2364 UErrorCode status = U_ZERO_ERROR;
2365 UAcceptResult outResult;
2366 UEnumeration *available;
2367 char tmp[200];
2368 int i;
2369 int32_t rc = 0;
2370
2371 struct {
2372 int32_t httpSet;
2373 const char *icuSet;
2374 const char *expect;
2375 UAcceptResult res;
2376 } tests[] = {
2377 /*0*/{ 0, NULL, "mt_MT", ULOC_ACCEPT_VALID },
2378 /*1*/{ 1, NULL, "en", ULOC_ACCEPT_VALID },
2379 /*2*/{ 2, NULL, "en", ULOC_ACCEPT_FALLBACK },
2380 /*3*/{ 3, NULL, "", ULOC_ACCEPT_FAILED },
2381 /*4*/{ 4, NULL, "es", ULOC_ACCEPT_VALID },
2382 };
2383 const int32_t numTests = sizeof(tests)/sizeof(tests[0]);
2384 static const char *http[] = {
2385 /*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",
2386 /*1*/ "ja;q=0.5, en;q=0.8, tlh",
2387 /*2*/ "en-wf, de-lx;q=0.8",
2388 /*3*/ "mga-ie;q=0.9, tlh",
2389 /*4*/ "xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, "
2390 "xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, "
2391 "xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, "
2392 "xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, "
2393 "xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, "
2394 "xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, "
2395 "xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, xx-yy;q=.1, "
2396 "es"
2397 };
374ca955 2398
46f4442e
A
2399 for(i=0;i<numTests;i++) {
2400 outResult = -3;
2401 status=U_ZERO_ERROR;
2402 log_verbose("test #%d: http[%s], ICU[%s], expect %s, %d\n",
2403 i, http[tests[i].httpSet], tests[i].icuSet, tests[i].expect, tests[i].res);
2404
2405 available = ures_openAvailableLocales(tests[i].icuSet, &status);
2406 tmp[0]=0;
2407 rc = uloc_acceptLanguageFromHTTP(tmp, 199, &outResult, http[tests[i].httpSet], available, &status);
2408 uenum_close(available);
2409 log_verbose(" got %s, %d [%s]\n", tmp[0]?tmp:"(EMPTY)", outResult, u_errorName(status));
2410 if(outResult != tests[i].res) {
2411 log_err("FAIL: #%d: expected outResult of %d but got %d\n", i, tests[i].res, outResult);
2412 log_info("test #%d: http[%s], ICU[%s], expect %s, %d\n",
2413 i, http[tests[i].httpSet], tests[i].icuSet, tests[i].expect, tests[i].res);
2414 }
2415 if((outResult>0)&&uprv_strcmp(tmp, tests[i].expect)) {
2416 log_err("FAIL: #%d: expected %s but got %s\n", i, tests[i].expect, tmp);
2417 log_info("test #%d: http[%s], ICU[%s], expect %s, %d\n",
2418 i, http[tests[i].httpSet], tests[i].icuSet, tests[i].expect, tests[i].res);
2419 }
374ca955 2420 }
b75a7d8f 2421}
73c04bcf
A
2422
2423static const char* LOCALE_ALIAS[][2] = {
2424 {"in", "id"},
2425 {"in_ID", "id_ID"},
2426 {"iw", "he"},
2427 {"iw_IL", "he_IL"},
2428 {"ji", "yi"},
2429 {"en_BU", "en_MM"},
2430 {"en_DY", "en_BJ"},
2431 {"en_HV", "en_BF"},
2432 {"en_NH", "en_VU"},
2433 {"en_RH", "en_ZW"},
2434 {"en_TP", "en_TL"},
2435 {"en_ZR", "en_CD"}
2436};
2437static UBool isLocaleAvailable(UResourceBundle* resIndex, const char* loc){
2438 UErrorCode status = U_ZERO_ERROR;
2439 int32_t len = 0;
2440 ures_getStringByKey(resIndex, loc,&len, &status);
2441 if(U_FAILURE(status)){
2442 return FALSE;
2443 }
2444 return TRUE;
2445}
2446
2447static void TestCalendar() {
2448#if !UCONFIG_NO_FORMATTING
2449 int i;
2450 UErrorCode status = U_ZERO_ERROR;
2451 UResourceBundle *resIndex = ures_open(NULL,"res_index", &status);
2452 if(U_FAILURE(status)){
2453 log_err("Could not open res_index.res. Exiting. Error: %s\n", u_errorName(status));
2454 return;
2455 }
2456 for (i=0; i<LENGTHOF(LOCALE_ALIAS); i++) {
2457 const char* oldLoc = LOCALE_ALIAS[i][0];
2458 const char* newLoc = LOCALE_ALIAS[i][1];
2459 UCalendar* c1 = NULL;
2460 UCalendar* c2 = NULL;
2461
2462 /*Test function "getLocale(ULocale.VALID_LOCALE)"*/
2463 const char* l1 = ucal_getLocaleByType(c1, ULOC_VALID_LOCALE, &status);
2464 const char* l2 = ucal_getLocaleByType(c2, ULOC_VALID_LOCALE, &status);
2465
2466 if(!isLocaleAvailable(resIndex, newLoc)){
2467 continue;
2468 }
2469 c1 = ucal_open(NULL, -1, oldLoc, UCAL_GREGORIAN, &status);
2470 c2 = ucal_open(NULL, -1, newLoc, UCAL_GREGORIAN, &status);
2471
2472 if (strcmp(newLoc,l1)!=0 || strcmp(l1,l2)!=0 || status!=U_ZERO_ERROR) {
2473 log_err("The locales are not equal!.Old: %s, New: %s \n", oldLoc, newLoc);
2474 }
2475 log_verbose("ucal_getLocaleByType old:%s new:%s\n", l1, l2);
2476 ucal_close(c1);
2477 ucal_close(c2);
2478 }
2479 ures_close(resIndex);
2480#endif
2481}
2482
2483static void TestDateFormat() {
2484#if !UCONFIG_NO_FORMATTING
2485 int i;
2486 UErrorCode status = U_ZERO_ERROR;
2487 UResourceBundle *resIndex = ures_open(NULL,"res_index", &status);
2488 if(U_FAILURE(status)){
2489 log_err("Could not open res_index.res. Exiting. Error: %s\n", u_errorName(status));
2490 return;
2491 }
2492 for (i=0; i<LENGTHOF(LOCALE_ALIAS); i++) {
2493 const char* oldLoc = LOCALE_ALIAS[i][0];
2494 const char* newLoc = LOCALE_ALIAS[i][1];
2495 UDateFormat* df1 = NULL;
2496 UDateFormat* df2 = NULL;
2497 const char* l1 = NULL;
2498 const char* l2 = NULL;
2499
2500 if(!isLocaleAvailable(resIndex, newLoc)){
2501 continue;
2502 }
2503 df1 = udat_open(UDAT_FULL, UDAT_FULL,oldLoc, NULL, 0, NULL, -1, &status);
2504 df2 = udat_open(UDAT_FULL, UDAT_FULL,newLoc, NULL, 0, NULL, -1, &status);
2505 if(U_FAILURE(status)){
2506 log_err("Creation of date format failed %s\n", u_errorName(status));
2507 return;
2508 }
2509 /*Test function "getLocale"*/
2510 l1 = udat_getLocaleByType(df1, ULOC_VALID_LOCALE, &status);
2511 l2 = udat_getLocaleByType(df2, ULOC_VALID_LOCALE, &status);
2512 if(U_FAILURE(status)){
2513 log_err("Fetching the locale by type failed. %s\n", u_errorName(status));
2514 }
2515 if (strcmp(newLoc,l1)!=0 || strcmp(l1,l2)!=0) {
2516 log_err("The locales are not equal!.Old: %s, New: %s \n", oldLoc, newLoc);
2517 }
2518 log_verbose("udat_getLocaleByType old:%s new:%s\n", l1, l2);
2519 udat_close(df1);
2520 udat_close(df2);
2521 }
2522 ures_close(resIndex);
2523#endif
2524}
2525
2526static void TestCollation() {
2527#if !UCONFIG_NO_COLLATION
2528 int i;
2529 UErrorCode status = U_ZERO_ERROR;
2530 UResourceBundle *resIndex = ures_open(NULL,"res_index", &status);
2531 if(U_FAILURE(status)){
2532 log_err("Could not open res_index.res. Exiting. Error: %s\n", u_errorName(status));
2533 return;
2534 }
2535 for (i=0; i<LENGTHOF(LOCALE_ALIAS); i++) {
2536 const char* oldLoc = LOCALE_ALIAS[i][0];
2537 const char* newLoc = LOCALE_ALIAS[i][1];
2538 UCollator* c1 = NULL;
2539 UCollator* c2 = NULL;
2540 const char* l1 = NULL;
2541 const char* l2 = NULL;
2542
2543 status = U_ZERO_ERROR;
2544 if(!isLocaleAvailable(resIndex, newLoc)){
2545 continue;
2546 }
2547 if(U_FAILURE(status)){
2548 log_err("Creation of collators failed %s\n", u_errorName(status));
2549 return;
2550 }
2551 c1 = ucol_open(oldLoc, &status);
2552 c2 = ucol_open(newLoc, &status);
2553 l1 = ucol_getLocaleByType(c1, ULOC_VALID_LOCALE, &status);
2554 l2 = ucol_getLocaleByType(c2, ULOC_VALID_LOCALE, &status);
2555 if(U_FAILURE(status)){
2556 log_err("Fetching the locale names failed failed %s\n", u_errorName(status));
2557 }
2558 if (strcmp(newLoc,l1)!=0 || strcmp(l1,l2)!=0) {
2559 log_err("The locales are not equal!.Old: %s, New: %s \n", oldLoc, newLoc);
2560 }
2561 log_verbose("ucol_getLocaleByType old:%s new:%s\n", l1, l2);
2562 ucol_close(c1);
2563 ucol_close(c2);
2564 }
2565 ures_close(resIndex);
2566#endif
2567}
2568
46f4442e
A
2569typedef struct OrientationStructTag {
2570 const char* localeId;
2571 ULayoutType character;
2572 ULayoutType line;
2573} OrientationStruct;
2574
2575const char* ULayoutTypeToString(ULayoutType type)
2576{
2577 switch(type)
2578 {
2579 case ULOC_LAYOUT_LTR:
2580 return "ULOC_LAYOUT_LTR";
2581 break;
2582 case ULOC_LAYOUT_RTL:
2583 return "ULOC_LAYOUT_RTL";
2584 break;
2585 case ULOC_LAYOUT_TTB:
2586 return "ULOC_LAYOUT_TTB";
2587 break;
2588 case ULOC_LAYOUT_BTT:
2589 return "ULOC_LAYOUT_BTT";
2590 break;
2591 case ULOC_LAYOUT_UNKNOWN:
2592 break;
2593 }
2594
2595 return "Unknown enum value for ULayoutType!";
2596}
2597
2598static void TestOrientation()
2599{
2600 static const OrientationStruct toTest [] = {
2601 { "ar", ULOC_LAYOUT_RTL, ULOC_LAYOUT_TTB },
2602 { "aR", ULOC_LAYOUT_RTL, ULOC_LAYOUT_TTB },
2603 { "ar_Arab", ULOC_LAYOUT_RTL, ULOC_LAYOUT_TTB },
2604 { "fa", ULOC_LAYOUT_RTL, ULOC_LAYOUT_TTB },
2605 { "Fa", ULOC_LAYOUT_RTL, ULOC_LAYOUT_TTB },
2606 { "he", ULOC_LAYOUT_RTL, ULOC_LAYOUT_TTB },
2607 { "ps", ULOC_LAYOUT_RTL, ULOC_LAYOUT_TTB },
2608 { "ur", ULOC_LAYOUT_RTL, ULOC_LAYOUT_TTB },
2609 { "UR", ULOC_LAYOUT_RTL, ULOC_LAYOUT_TTB },
2610 { "en", ULOC_LAYOUT_LTR, ULOC_LAYOUT_TTB }
2611 };
2612
2613 size_t i = 0;
2614 for (; i < sizeof(toTest) / sizeof(toTest[0]); ++i) {
2615 UErrorCode statusCO = U_ZERO_ERROR;
2616 UErrorCode statusLO = U_ZERO_ERROR;
2617 const char* const localeId = toTest[i].localeId;
2618 const ULayoutType co = uloc_getCharacterOrientation(localeId, &statusCO);
2619 const ULayoutType expectedCO = toTest[i].character;
2620 const ULayoutType lo = uloc_getLineOrientation(localeId, &statusLO);
2621 const ULayoutType expectedLO = toTest[i].line;
2622 if (U_FAILURE(statusCO)) {
2623 log_err(
2624 " unexpected failure for uloc_getCharacterOrientation(), with localId \"%s\" and status %s\n",
2625 localeId,
2626 u_errorName(statusCO));
2627 }
2628 else if (co != expectedCO) {
2629 log_err(
2630 " unexpected result for uloc_getCharacterOrientation(), with localeId \"%s\". Expected %s but got result %s\n",
2631 localeId,
2632 ULayoutTypeToString(expectedCO),
2633 ULayoutTypeToString(co));
2634 }
2635 if (U_FAILURE(statusLO)) {
2636 log_err(
2637 " unexpected failure for uloc_getLineOrientation(), with localId \"%s\" and status %s\n",
2638 localeId,
2639 u_errorName(statusLO));
2640 }
2641 else if (lo != expectedLO) {
2642 log_err(
2643 " unexpected result for uloc_getLineOrientation(), with localeId \"%s\". Expected %s but got result %s\n",
2644 localeId,
2645 ULayoutTypeToString(expectedLO),
2646 ULayoutTypeToString(lo));
2647 }
2648 }
2649}
2650
73c04bcf
A
2651static void TestULocale() {
2652 int i;
2653 UErrorCode status = U_ZERO_ERROR;
2654 UResourceBundle *resIndex = ures_open(NULL,"res_index", &status);
2655 if(U_FAILURE(status)){
2656 log_err("Could not open res_index.res. Exiting. Error: %s\n", u_errorName(status));
2657 return;
2658 }
2659 for (i=0; i<LENGTHOF(LOCALE_ALIAS); i++) {
2660 const char* oldLoc = LOCALE_ALIAS[i][0];
2661 const char* newLoc = LOCALE_ALIAS[i][1];
2662 UChar name1[256], name2[256];
2663 char names1[256], names2[256];
2664 int32_t capacity = 256;
2665
2666 status = U_ZERO_ERROR;
2667 if(!isLocaleAvailable(resIndex, newLoc)){
2668 continue;
2669 }
2670 uloc_getDisplayName(oldLoc, ULOC_US, name1, capacity, &status);
2671 if(U_FAILURE(status)){
2672 log_err("uloc_getDisplayName(%s) failed %s\n", oldLoc, u_errorName(status));
2673 }
2674
2675 uloc_getDisplayName(newLoc, ULOC_US, name2, capacity, &status);
2676 if(U_FAILURE(status)){
2677 log_err("uloc_getDisplayName(%s) failed %s\n", newLoc, u_errorName(status));
2678 }
2679
2680 if (u_strcmp(name1, name2)!=0) {
2681 log_err("The locales are not equal!.Old: %s, New: %s \n", oldLoc, newLoc);
2682 }
2683 u_austrcpy(names1, name1);
2684 u_austrcpy(names2, name2);
2685 log_verbose("uloc_getDisplayName old:%s new:%s\n", names1, names2);
2686 }
2687 ures_close(resIndex);
2688
2689}
2690
2691static void TestUResourceBundle() {
2692 const char* us1;
2693 const char* us2;
2694
2695 UResourceBundle* rb1 = NULL;
2696 UResourceBundle* rb2 = NULL;
2697 UErrorCode status = U_ZERO_ERROR;
2698 int i;
2699 UResourceBundle *resIndex = NULL;
2700 if(U_FAILURE(status)){
2701 log_err("Could not open res_index.res. Exiting. Error: %s\n", u_errorName(status));
2702 return;
2703 }
2704 resIndex = ures_open(NULL,"res_index", &status);
2705 for (i=0; i<LENGTHOF(LOCALE_ALIAS); i++) {
2706
2707 const char* oldLoc = LOCALE_ALIAS[i][0];
2708 const char* newLoc = LOCALE_ALIAS[i][1];
2709 if(!isLocaleAvailable(resIndex, newLoc)){
2710 continue;
2711 }
2712 rb1 = ures_open(NULL, oldLoc, &status);
46f4442e 2713 if (U_FAILURE(status)) {
73c04bcf
A
2714 log_err("ures_open(%s) failed %s\n", oldLoc, u_errorName(status));
2715 }
2716
2717 us1 = ures_getLocale(rb1, &status);
2718
2719 status = U_ZERO_ERROR;
2720 rb2 = ures_open(NULL, newLoc, &status);
46f4442e 2721 if (U_FAILURE(status)) {
73c04bcf
A
2722 log_err("ures_open(%s) failed %s\n", oldLoc, u_errorName(status));
2723 }
2724 us2 = ures_getLocale(rb2, &status);
2725
2726 if (strcmp(us1,newLoc)!=0 || strcmp(us1,us2)!=0 ) {
2727 log_err("The locales are not equal!.Old: %s, New: %s \n", oldLoc, newLoc);
2728 }
2729
2730 log_verbose("ures_getStringByKey old:%s new:%s\n", us1, us2);
2731 ures_close(rb1);
2732 rb1 = NULL;
2733 ures_close(rb2);
2734 rb2 = NULL;
2735 }
2736 ures_close(resIndex);
2737}
2738
2739static void TestDisplayName() {
2740
2741 UChar oldCountry[256] = {'\0'};
2742 UChar newCountry[256] = {'\0'};
2743 UChar oldLang[256] = {'\0'};
2744 UChar newLang[256] = {'\0'};
2745 char country[256] ={'\0'};
2746 char language[256] ={'\0'};
2747 int32_t capacity = 256;
2748 int i =0;
2749 int j=0;
2750 for (i=0; i<LENGTHOF(LOCALE_ALIAS); i++) {
2751 const char* oldLoc = LOCALE_ALIAS[i][0];
2752 const char* newLoc = LOCALE_ALIAS[i][1];
2753 UErrorCode status = U_ZERO_ERROR;
2754 int32_t available = uloc_countAvailable();
2755
2756 for(j=0; j<available; j++){
2757
2758 const char* dispLoc = uloc_getAvailable(j);
2759 int32_t oldCountryLen = uloc_getDisplayCountry(oldLoc,dispLoc, oldCountry, capacity, &status);
2760 int32_t newCountryLen = uloc_getDisplayCountry(newLoc, dispLoc, newCountry, capacity, &status);
2761 int32_t oldLangLen = uloc_getDisplayLanguage(oldLoc, dispLoc, oldLang, capacity, &status);
2762 int32_t newLangLen = uloc_getDisplayLanguage(newLoc, dispLoc, newLang, capacity, &status );
2763
2764 int32_t countryLen = uloc_getCountry(newLoc, country, capacity, &status);
2765 int32_t langLen = uloc_getLanguage(newLoc, language, capacity, &status);
2766 /* there is a display name for the current country ID */
2767 if(countryLen != newCountryLen ){
2768 if(u_strncmp(oldCountry,newCountry,oldCountryLen)!=0){
2769 log_err("uloc_getDisplayCountry() failed for %s in display locale %s \n", oldLoc, dispLoc);
2770 }
2771 }
2772 /* there is a display name for the current lang ID */
2773 if(langLen!=newLangLen){
2774 if(u_strncmp(oldLang,newLang,oldLangLen)){
2775 log_err("uloc_getDisplayLanguage() failed for %s in display locale %s \n", oldLoc, dispLoc); }
2776 }
2777 }
2778 }
2779}
2780
2781static void TestGetLocaleForLCID() {
2782 int32_t i, length, lengthPre;
2783 const char* testLocale = 0;
2784 UErrorCode status = U_ZERO_ERROR;
73c04bcf
A
2785 char temp2[40], temp3[40];
2786 uint32_t lcid;
2787
2788 lcid = uloc_getLCID("en_US");
2789 if (lcid != 0x0409) {
2790 log_err(" uloc_getLCID(\"en_US\") = %d, expected 0x0409\n", lcid);
2791 }
2792
2793 lengthPre = uloc_getLocaleForLCID(lcid, temp2, 4, &status);
2794 if (status != U_BUFFER_OVERFLOW_ERROR) {
2795 log_err(" unexpected result from uloc_getLocaleForLCID with small buffer: %s\n", u_errorName(status));
2796 }
2797 else {
2798 status = U_ZERO_ERROR;
2799 }
2800
2801 length = uloc_getLocaleForLCID(lcid, temp2, sizeof(temp2)/sizeof(char), &status);
2802 if (U_FAILURE(status)) {
2803 log_err(" unexpected result from uloc_getLocaleForLCID(0x0409): %s\n", u_errorName(status));
2804 status = U_ZERO_ERROR;
2805 }
2806
2807 if (length != lengthPre) {
2808 log_err(" uloc_getLocaleForLCID(0x0409): returned length %d does not match preflight length %d\n", length, lengthPre);
2809 }
2810
2811 length = uloc_getLocaleForLCID(0x12345, temp2, sizeof(temp2)/sizeof(char), &status);
2812 if (U_SUCCESS(status)) {
2813 log_err(" unexpected result from uloc_getLocaleForLCID(0x12345): %s, status %s\n", temp2, u_errorName(status));
2814 }
2815 status = U_ZERO_ERROR;
2816
2817 log_verbose("Testing getLocaleForLCID vs. locale data\n");
2818 for (i = 0; i < LOCALE_SIZE; i++) {
2819
2820 testLocale=rawData2[NAME][i];
2821
2822 log_verbose("Testing %s ......\n", testLocale);
2823
2824 sscanf(rawData2[LCID][i], "%x", &lcid);
2825 length = uloc_getLocaleForLCID(lcid, temp2, sizeof(temp2)/sizeof(char), &status);
2826 if (U_FAILURE(status)) {
2827 log_err(" unexpected failure of uloc_getLocaleForLCID(%#04x), status %s\n", lcid, u_errorName(status));
2828 status = U_ZERO_ERROR;
2829 continue;
2830 }
2831
2832 if (length != uprv_strlen(temp2)) {
2833 log_err(" returned length %d not correct for uloc_getLocaleForLCID(%#04x), expected %d\n", length, lcid, uprv_strlen(temp2));
2834 }
2835
2836 /* Compare language, country, script */
2837 length = uloc_getLanguage(temp2, temp3, sizeof(temp3)/sizeof(char), &status);
2838 if (U_FAILURE(status)) {
2839 log_err(" couldn't get language in uloc_getLocaleForLCID(%#04x) = %s, status %s\n", lcid, temp2, u_errorName(status));
2840 status = U_ZERO_ERROR;
2841 }
2842 else if (uprv_strcmp(temp3, rawData2[LANG][i]) && !(uprv_strcmp(temp3, "nn") == 0 && uprv_strcmp(rawData2[VAR][i], "NY") == 0)) {
2843 log_err(" language doesn't match expected %s in in uloc_getLocaleForLCID(%#04x) = %s\n", rawData2[LANG][i], lcid, temp2);
2844 }
2845
2846 length = uloc_getScript(temp2, temp3, sizeof(temp3)/sizeof(char), &status);
2847 if (U_FAILURE(status)) {
2848 log_err(" couldn't get script in uloc_getLocaleForLCID(%#04x) = %s, status %s\n", lcid, temp2, u_errorName(status));
2849 status = U_ZERO_ERROR;
2850 }
2851 else if (uprv_strcmp(temp3, rawData2[SCRIPT][i])) {
2852 log_err(" script doesn't match expected %s in in uloc_getLocaleForLCID(%#04x) = %s\n", rawData2[SCRIPT][i], lcid, temp2);
2853 }
2854
2855 length = uloc_getCountry(temp2, temp3, sizeof(temp3)/sizeof(char), &status);
2856 if (U_FAILURE(status)) {
2857 log_err(" couldn't get country in uloc_getLocaleForLCID(%#04x) = %s, status %s\n", lcid, temp2, u_errorName(status));
2858 status = U_ZERO_ERROR;
2859 }
2860 else if (uprv_strlen(rawData2[CTRY][i]) && uprv_strcmp(temp3, rawData2[CTRY][i])) {
2861 log_err(" country doesn't match expected %s in in uloc_getLocaleForLCID(%#04x) = %s\n", rawData2[CTRY][i], lcid, temp2);
2862 }
2863 }
2864
2865}
2866
46f4442e
A
2867const char* const basic_maximize_data[][2] = {
2868 {
2869 "zu_Zzzz_Zz",
2870 "zu_Latn_ZA",
2871 }, {
2872 "ZU_Zz",
2873 "zu_Latn_ZA"
2874 }, {
2875 "zu_LATN",
2876 "zu_Latn_ZA"
2877 }, {
2878 "en_Zz",
2879 "en_Latn_US"
2880 }, {
2881 "en_us",
2882 "en_Latn_US"
2883 }, {
2884 "en_Kore",
2885 "en_Kore_US"
2886 }, {
2887 "en_Kore_Zz",
2888 "en_Kore_US"
2889 }, {
2890 "en_Kore_ZA",
2891 "en_Kore_ZA"
2892 }, {
2893 "en_Kore_ZA_POSIX",
2894 "en_Kore_ZA_POSIX"
2895 }, {
2896 "en_Gujr",
2897 "en_Gujr_US"
2898 }, {
2899 "en_ZA",
2900 "en_Latn_ZA"
2901 }, {
2902 "en_Gujr_Zz",
2903 "en_Gujr_US"
2904 }, {
2905 "en_Gujr_ZA",
2906 "en_Gujr_ZA"
2907 }, {
2908 "en_Gujr_ZA_POSIX",
2909 "en_Gujr_ZA_POSIX"
2910 }, {
2911 "en_US_POSIX_1901",
2912 "en_Latn_US_POSIX_1901"
2913 }, {
2914 "en_Latn__POSIX_1901",
2915 "en_Latn_US_POSIX_1901"
2916 }, {
2917 "en__POSIX_1901",
2918 "en_Latn_US_POSIX_1901"
2919 }, {
2920 "de__POSIX_1901",
2921 "de_Latn_DE_POSIX_1901"
2922 }, {
2923 "en_US_BOSTON",
2924 "en_Latn_US_BOSTON"
2925 }, {
2926 "th@calendar=buddhist",
2927 "th_Thai_TH@calendar=buddhist"
2928 }, {
2929 "ar_ZZ",
2930 "ar_Arab_EG"
2931 }, {
2932 "zh",
2933 "zh_Hans_CN"
2934 }, {
2935 "zh_TW",
2936 "zh_Hant_TW"
2937 }, {
2938 "zh_HK",
2939 "zh_Hant_HK"
2940 }, {
2941 "zh_Hant",
2942 "zh_Hant_TW"
2943 }, {
2944 "zh_Zzzz_CN",
2945 "zh_Hans_CN"
2946 }, {
2947 "und_US",
2948 "en_Latn_US"
2949 }, {
2950 "und_HK",
2951 "zh_Hant_HK"
2952 }, {
2953 "zzz",
2954 ""
2955 }
2956};
2957
2958const char* const basic_minimize_data[][2] = {
2959 {
2960 "en_Latn_US",
2961 "en"
2962 }, {
2963 "en_Latn_US_POSIX_1901",
2964 "en__POSIX_1901"
2965 }, {
2966 "EN_Latn_US_POSIX_1901",
2967 "en__POSIX_1901"
2968 }, {
2969 "en_Zzzz_US_POSIX_1901",
2970 "en__POSIX_1901"
2971 }, {
2972 "de_Latn_DE_POSIX_1901",
2973 "de__POSIX_1901"
2974 }, {
2975 "und",
2976 ""
2977 }
2978};
2979
2980const char* const full_data[][3] = {
2981 {
2982 /* "FROM", */
2983 /* "ADD-LIKELY", */
2984 /* "REMOVE-LIKELY" */
2985 /* }, { */
2986 "aa",
2987 "aa_Latn_ET",
2988 "aa"
2989 }, {
2990 "af",
2991 "af_Latn_ZA",
2992 "af"
2993 }, {
2994 "ak",
2995 "ak_Latn_GH",
2996 "ak"
2997 }, {
2998 "am",
2999 "am_Ethi_ET",
3000 "am"
3001 }, {
3002 "ar",
3003 "ar_Arab_EG",
3004 "ar"
3005 }, {
3006 "as",
3007 "as_Beng_IN",
3008 "as"
3009 }, {
3010 "az",
3011 "az_Latn_AZ",
3012 "az"
3013 }, {
3014 "be",
3015 "be_Cyrl_BY",
3016 "be"
3017 }, {
3018 "bg",
3019 "bg_Cyrl_BG",
3020 "bg"
3021 }, {
3022 "bn",
3023 "bn_Beng_BD",
3024 "bn"
3025 }, {
3026 "bo",
3027 "bo_Tibt_CN",
3028 "bo"
3029 }, {
3030 "bs",
3031 "bs_Latn_BA",
3032 "bs"
3033 }, {
3034 "ca",
3035 "ca_Latn_ES",
3036 "ca"
3037 }, {
3038 "ch",
3039 "ch_Latn_GU",
3040 "ch"
3041 }, {
3042 "chk",
3043 "chk_Latn_FM",
3044 "chk"
3045 }, {
3046 "cs",
3047 "cs_Latn_CZ",
3048 "cs"
3049 }, {
3050 "cy",
3051 "cy_Latn_GB",
3052 "cy"
3053 }, {
3054 "da",
3055 "da_Latn_DK",
3056 "da"
3057 }, {
3058 "de",
3059 "de_Latn_DE",
3060 "de"
3061 }, {
3062 "dv",
3063 "dv_Thaa_MV",
3064 "dv"
3065 }, {
3066 "dz",
3067 "dz_Tibt_BT",
3068 "dz"
3069 }, {
3070 "ee",
3071 "ee_Latn_GH",
3072 "ee"
3073 }, {
3074 "el",
3075 "el_Grek_GR",
3076 "el"
3077 }, {
3078 "en",
3079 "en_Latn_US",
3080 "en"
3081 }, {
3082 "es",
3083 "es_Latn_ES",
3084 "es"
3085 }, {
3086 "et",
3087 "et_Latn_EE",
3088 "et"
3089 }, {
3090 "eu",
3091 "eu_Latn_ES",
3092 "eu"
3093 }, {
3094 "fa",
3095 "fa_Arab_IR",
3096 "fa"
3097 }, {
3098 "fi",
3099 "fi_Latn_FI",
3100 "fi"
3101 }, {
3102 "fil",
3103 "fil_Latn_PH",
3104 "fil"
3105 }, {
3106 "fj",
3107 "fj_Latn_FJ",
3108 "fj"
3109 }, {
3110 "fo",
3111 "fo_Latn_FO",
3112 "fo"
3113 }, {
3114 "fr",
3115 "fr_Latn_FR",
3116 "fr"
3117 }, {
3118 "fur",
3119 "fur_Latn_IT",
3120 "fur"
3121 }, {
3122 "ga",
3123 "ga_Latn_IE",
3124 "ga"
3125 }, {
3126 "gaa",
3127 "gaa_Latn_GH",
3128 "gaa"
3129 }, {
3130 "gl",
3131 "gl_Latn_ES",
3132 "gl"
3133 }, {
3134 "gn",
3135 "gn_Latn_PY",
3136 "gn"
3137 }, {
3138 "gu",
3139 "gu_Gujr_IN",
3140 "gu"
3141 }, {
3142 "ha",
3143 "ha_Latn_NG",
3144 "ha"
3145 }, {
3146 "haw",
3147 "haw_Latn_US",
3148 "haw"
3149 }, {
3150 "he",
3151 "he_Hebr_IL",
3152 "he"
3153 }, {
3154 "hi",
3155 "hi_Deva_IN",
3156 "hi"
3157 }, {
3158 "hr",
3159 "hr_Latn_HR",
3160 "hr"
3161 }, {
3162 "ht",
3163 "ht_Latn_HT",
3164 "ht"
3165 }, {
3166 "hu",
3167 "hu_Latn_HU",
3168 "hu"
3169 }, {
3170 "hy",
3171 "hy_Armn_AM",
3172 "hy"
3173 }, {
3174 "id",
3175 "id_Latn_ID",
3176 "id"
3177 }, {
3178 "ig",
3179 "ig_Latn_NG",
3180 "ig"
3181 }, {
3182 "ii",
3183 "ii_Latn_CN",
3184 "ii"
3185 }, {
3186 "is",
3187 "is_Latn_IS",
3188 "is"
3189 }, {
3190 "it",
3191 "it_Latn_IT",
3192 "it"
3193 }, {
3194 "iu",
3195 "iu_Cans_CA",
3196 "iu"
3197 }, {
3198 "ja",
3199 "ja_Jpan_JP",
3200 "ja"
3201 }, {
3202 "ka",
3203 "ka_Geor_GE",
3204 "ka"
3205 }, {
3206 "kaj",
3207 "kaj_Latn_NG",
3208 "kaj"
3209 }, {
3210 "kam",
3211 "kam_Latn_KE",
3212 "kam"
3213 }, {
3214 "kk",
3215 "kk_Cyrl_KZ",
3216 "kk"
3217 }, {
3218 "kl",
3219 "kl_Latn_GL",
3220 "kl"
3221 }, {
3222 "km",
3223 "km_Khmr_KH",
3224 "km"
3225 }, {
3226 "kn",
3227 "kn_Knda_IN",
3228 "kn"
3229 }, {
3230 "ko",
3231 "ko_Kore_KR",
3232 "ko"
3233 }, {
3234 "kok",
3235 "kok_Deva_IN",
3236 "kok"
3237 }, {
3238 "kpe",
3239 "kpe_Latn_LR",
3240 "kpe"
3241 }, {
3242 "ku",
3243 "ku_Arab_IQ",
3244 "ku"
3245 }, {
3246 "ky",
3247 "ky_Cyrl_KG",
3248 "ky"
3249 }, {
3250 "la",
3251 "la_Latn_VA",
3252 "la"
3253 }, {
3254 "ln",
3255 "ln_Latn_CD",
3256 "ln"
3257 }, {
3258 "lo",
3259 "lo_Laoo_LA",
3260 "lo"
3261 }, {
3262 "lt",
3263 "lt_Latn_LT",
3264 "lt"
3265 }, {
3266 "lv",
3267 "lv_Latn_LV",
3268 "lv"
3269 }, {
3270 "mg",
3271 "mg_Latn_MG",
3272 "mg"
3273 }, {
3274 "mh",
3275 "mh_Latn_MH",
3276 "mh"
3277 }, {
3278 "mk",
3279 "mk_Cyrl_MK",
3280 "mk"
3281 }, {
3282 "ml",
3283 "ml_Mlym_IN",
3284 "ml"
3285 }, {
3286 "mn",
3287 "mn_Cyrl_MN",
3288 "mn"
3289 }, {
3290 "mr",
3291 "mr_Deva_IN",
3292 "mr"
3293 }, {
3294 "ms",
3295 "ms_Latn_MY",
3296 "ms"
3297 }, {
3298 "mt",
3299 "mt_Latn_MT",
3300 "mt"
3301 }, {
3302 "my",
3303 "my_Mymr_MM",
3304 "my"
3305 }, {
3306 "na",
3307 "na_Latn_NR",
3308 "na"
3309 }, {
3310 "ne",
3311 "ne_Deva_NP",
3312 "ne"
3313 }, {
3314 "niu",
3315 "niu_Latn_NU",
3316 "niu"
3317 }, {
3318 "nl",
3319 "nl_Latn_NL",
3320 "nl"
3321 }, {
3322 "nn",
3323 "nn_Latn_NO",
3324 "nn"
3325 }, {
3326 "nr",
3327 "nr_Latn_ZA",
3328 "nr"
3329 }, {
3330 "nso",
3331 "nso_Latn_ZA",
3332 "nso"
3333 }, {
3334 "ny",
3335 "ny_Latn_MW",
3336 "ny"
3337 }, {
3338 "om",
3339 "om_Latn_ET",
3340 "om"
3341 }, {
3342 "or",
3343 "or_Orya_IN",
3344 "or"
3345 }, {
3346 "pa",
3347 "pa_Guru_IN",
3348 "pa"
3349 }, {
3350 "pa_Arab",
3351 "pa_Arab_PK",
3352 "pa_PK"
3353 }, {
3354 "pa_PK",
3355 "pa_Arab_PK",
3356 "pa_PK"
3357 }, {
3358 "pap",
3359 "pap_Latn_AN",
3360 "pap"
3361 }, {
3362 "pau",
3363 "pau_Latn_PW",
3364 "pau"
3365 }, {
3366 "pl",
3367 "pl_Latn_PL",
3368 "pl"
3369 }, {
3370 "ps",
3371 "ps_Arab_AF",
3372 "ps"
3373 }, {
3374 "pt",
3375 "pt_Latn_BR",
3376 "pt"
3377 }, {
3378 "rn",
3379 "rn_Latn_BI",
3380 "rn"
3381 }, {
3382 "ro",
3383 "ro_Latn_RO",
3384 "ro"
3385 }, {
3386 "ru",
3387 "ru_Cyrl_RU",
3388 "ru"
3389 }, {
3390 "rw",
3391 "rw_Latn_RW",
3392 "rw"
3393 }, {
3394 "sa",
3395 "sa_Deva_IN",
3396 "sa"
3397 }, {
3398 "se",
3399 "se_Latn_NO",
3400 "se"
3401 }, {
3402 "sg",
3403 "sg_Latn_CF",
3404 "sg"
3405 }, {
3406 "si",
3407 "si_Sinh_LK",
3408 "si"
3409 }, {
3410 "sid",
3411 "sid_Latn_ET",
3412 "sid"
3413 }, {
3414 "sk",
3415 "sk_Latn_SK",
3416 "sk"
3417 }, {
3418 "sl",
3419 "sl_Latn_SI",
3420 "sl"
3421 }, {
3422 "sm",
3423 "sm_Latn_WS",
3424 "sm"
3425 }, {
3426 "so",
3427 "so_Latn_SO",
3428 "so"
3429 }, {
3430 "sq",
3431 "sq_Latn_AL",
3432 "sq"
3433 }, {
3434 "sr",
3435 "sr_Cyrl_RS",
3436 "sr"
3437 }, {
3438 "ss",
3439 "ss_Latn_ZA",
3440 "ss"
3441 }, {
3442 "st",
3443 "st_Latn_ZA",
3444 "st"
3445 }, {
3446 "sv",
3447 "sv_Latn_SE",
3448 "sv"
3449 }, {
3450 "sw",
3451 "sw_Latn_TZ",
3452 "sw"
3453 }, {
3454 "ta",
3455 "ta_Taml_IN",
3456 "ta"
3457 }, {
3458 "te",
3459 "te_Telu_IN",
3460 "te"
3461 }, {
3462 "tet",
3463 "tet_Latn_TL",
3464 "tet"
3465 }, {
3466 "tg",
3467 "tg_Cyrl_TJ",
3468 "tg"
3469 }, {
3470 "th",
3471 "th_Thai_TH",
3472 "th"
3473 }, {
3474 "ti",
3475 "ti_Ethi_ET",
3476 "ti"
3477 }, {
3478 "tig",
3479 "tig_Ethi_ER",
3480 "tig"
3481 }, {
3482 "tk",
3483 "tk_Latn_TM",
3484 "tk"
3485 }, {
3486 "tkl",
3487 "tkl_Latn_TK",
3488 "tkl"
3489 }, {
3490 "tn",
3491 "tn_Latn_ZA",
3492 "tn"
3493 }, {
3494 "to",
3495 "to_Latn_TO",
3496 "to"
3497 }, {
3498 "tpi",
3499 "tpi_Latn_PG",
3500 "tpi"
3501 }, {
3502 "tr",
3503 "tr_Latn_TR",
3504 "tr"
3505 }, {
3506 "ts",
3507 "ts_Latn_ZA",
3508 "ts"
3509 }, {
3510 "tt",
3511 "tt_Cyrl_RU",
3512 "tt"
3513 }, {
3514 "tvl",
3515 "tvl_Latn_TV",
3516 "tvl"
3517 }, {
3518 "ty",
3519 "ty_Latn_PF",
3520 "ty"
3521 }, {
3522 "uk",
3523 "uk_Cyrl_UA",
3524 "uk"
3525 }, {
3526 "und",
3527 "en_Latn_US",
3528 "en"
3529 }, {
3530 "und_AD",
3531 "ca_Latn_AD",
3532 "ca_AD"
3533 }, {
3534 "und_AE",
3535 "ar_Arab_AE",
3536 "ar_AE"
3537 }, {
3538 "und_AF",
3539 "fa_Arab_AF",
3540 "fa_AF"
3541 }, {
3542 "und_AL",
3543 "sq_Latn_AL",
3544 "sq"
3545 }, {
3546 "und_AM",
3547 "hy_Armn_AM",
3548 "hy"
3549 }, {
3550 "und_AN",
3551 "pap_Latn_AN",
3552 "pap"
3553 }, {
3554 "und_AO",
3555 "pt_Latn_AO",
3556 "pt_AO"
3557 }, {
3558 "und_AR",
3559 "es_Latn_AR",
3560 "es_AR"
3561 }, {
3562 "und_AS",
3563 "sm_Latn_AS",
3564 "sm_AS"
3565 }, {
3566 "und_AT",
3567 "de_Latn_AT",
3568 "de_AT"
3569 }, {
3570 "und_AW",
3571 "nl_Latn_AW",
3572 "nl_AW"
3573 }, {
3574 "und_AX",
3575 "sv_Latn_AX",
3576 "sv_AX"
3577 }, {
3578 "und_AZ",
3579 "az_Latn_AZ",
3580 "az"
3581 }, {
3582 "und_Arab",
3583 "ar_Arab_EG",
3584 "ar"
3585 }, {
3586 "und_Arab_IN",
3587 "ur_Arab_IN",
3588 "ur_IN"
3589 }, {
3590 "und_Arab_PK",
3591 "ur_Arab_PK",
3592 "ur"
3593 }, {
3594 "und_Arab_SN",
3595 "ar_Arab_SN",
3596 "ar_SN"
3597 }, {
3598 "und_Armn",
3599 "hy_Armn_AM",
3600 "hy"
3601 }, {
3602 "und_BA",
3603 "bs_Latn_BA",
3604 "bs"
3605 }, {
3606 "und_BD",
3607 "bn_Beng_BD",
3608 "bn"
3609 }, {
3610 "und_BE",
3611 "nl_Latn_BE",
3612 "nl_BE"
3613 }, {
3614 "und_BF",
3615 "fr_Latn_BF",
3616 "fr_BF"
3617 }, {
3618 "und_BG",
3619 "bg_Cyrl_BG",
3620 "bg"
3621 }, {
3622 "und_BH",
3623 "ar_Arab_BH",
3624 "ar_BH"
3625 }, {
3626 "und_BI",
3627 "rn_Latn_BI",
3628 "rn"
3629 }, {
3630 "und_BJ",
3631 "fr_Latn_BJ",
3632 "fr_BJ"
3633 }, {
3634 "und_BN",
3635 "ms_Latn_BN",
3636 "ms_BN"
3637 }, {
3638 "und_BO",
3639 "es_Latn_BO",
3640 "es_BO"
3641 }, {
3642 "und_BR",
3643 "pt_Latn_BR",
3644 "pt"
3645 }, {
3646 "und_BT",
3647 "dz_Tibt_BT",
3648 "dz"
3649 }, {
3650 "und_BY",
3651 "be_Cyrl_BY",
3652 "be"
3653 }, {
3654 "und_Beng",
3655 "bn_Beng_BD",
3656 "bn"
3657 }, {
3658 "und_Beng_IN",
3659 "bn_Beng_IN",
3660 "bn_IN"
3661 }, {
3662 "und_CD",
3663 "fr_Latn_CD",
3664 "fr_CD"
3665 }, {
3666 "und_CF",
3667 "sg_Latn_CF",
3668 "sg"
3669 }, {
3670 "und_CG",
3671 "ln_Latn_CG",
3672 "ln_CG"
3673 }, {
3674 "und_CH",
3675 "de_Latn_CH",
3676 "de_CH"
3677 }, {
3678 "und_CI",
3679 "fr_Latn_CI",
3680 "fr_CI"
3681 }, {
3682 "und_CL",
3683 "es_Latn_CL",
3684 "es_CL"
3685 }, {
3686 "und_CM",
3687 "fr_Latn_CM",
3688 "fr_CM"
3689 }, {
3690 "und_CN",
3691 "zh_Hans_CN",
3692 "zh"
3693 }, {
3694 "und_CO",
3695 "es_Latn_CO",
3696 "es_CO"
3697 }, {
3698 "und_CR",
3699 "es_Latn_CR",
3700 "es_CR"
3701 }, {
3702 "und_CU",
3703 "es_Latn_CU",
3704 "es_CU"
3705 }, {
3706 "und_CV",
3707 "pt_Latn_CV",
3708 "pt_CV"
3709 }, {
3710 "und_CY",
3711 "el_Grek_CY",
3712 "el_CY"
3713 }, {
3714 "und_CZ",
3715 "cs_Latn_CZ",
3716 "cs"
3717 }, {
3718 "und_Cans",
3719 "cwd_Cans_CA",
3720 "cwd"
3721 }, {
3722 "und_Cyrl",
3723 "ru_Cyrl_RU",
3724 "ru"
3725 }, {
3726 "und_Cyrl_KZ",
3727 "ru_Cyrl_KZ",
3728 "ru_KZ"
3729 }, {
3730 "und_DE",
3731 "de_Latn_DE",
3732 "de"
3733 }, {
3734 "und_DJ",
3735 "aa_Latn_DJ",
3736 "aa_DJ"
3737 }, {
3738 "und_DK",
3739 "da_Latn_DK",
3740 "da"
3741 }, {
3742 "und_DO",
3743 "es_Latn_DO",
3744 "es_DO"
3745 }, {
3746 "und_DZ",
3747 "ar_Arab_DZ",
3748 "ar_DZ"
3749 }, {
3750 "und_Deva",
3751 "hi_Deva_IN",
3752 "hi"
3753 }, {
3754 "und_EC",
3755 "es_Latn_EC",
3756 "es_EC"
3757 }, {
3758 "und_EE",
3759 "et_Latn_EE",
3760 "et"
3761 }, {
3762 "und_EG",
3763 "ar_Arab_EG",
3764 "ar"
3765 }, {
3766 "und_EH",
3767 "ar_Arab_EH",
3768 "ar_EH"
3769 }, {
3770 "und_ER",
3771 "ti_Ethi_ER",
3772 "ti_ER"
3773 }, {
3774 "und_ES",
3775 "es_Latn_ES",
3776 "es"
3777 }, {
3778 "und_ET",
3779 "am_Ethi_ET",
3780 "am"
3781 }, {
3782 "und_Ethi",
3783 "am_Ethi_ET",
3784 "am"
3785 }, {
3786 "und_Ethi_ER",
3787 "am_Ethi_ER",
3788 "am_ER"
3789 }, {
3790 "und_FI",
3791 "fi_Latn_FI",
3792 "fi"
3793 }, {
3794 "und_FJ",
3795 "fj_Latn_FJ",
3796 "fj"
3797 }, {
3798 "und_FM",
3799 "chk_Latn_FM",
3800 "chk"
3801 }, {
3802 "und_FO",
3803 "fo_Latn_FO",
3804 "fo"
3805 }, {
3806 "und_FR",
3807 "fr_Latn_FR",
3808 "fr"
3809 }, {
3810 "und_GA",
3811 "fr_Latn_GA",
3812 "fr_GA"
3813 }, {
3814 "und_GE",
3815 "ka_Geor_GE",
3816 "ka"
3817 }, {
3818 "und_GF",
3819 "fr_Latn_GF",
3820 "fr_GF"
3821 }, {
3822 "und_GL",
3823 "kl_Latn_GL",
3824 "kl"
3825 }, {
3826 "und_GN",
3827 "fr_Latn_GN",
3828 "fr_GN"
3829 }, {
3830 "und_GP",
3831 "fr_Latn_GP",
3832 "fr_GP"
3833 }, {
3834 "und_GQ",
3835 "fr_Latn_GQ",
3836 "fr_GQ"
3837 }, {
3838 "und_GR",
3839 "el_Grek_GR",
3840 "el"
3841 }, {
3842 "und_GT",
3843 "es_Latn_GT",
3844 "es_GT"
3845 }, {
3846 "und_GU",
3847 "ch_Latn_GU",
3848 "ch"
3849 }, {
3850 "und_GW",
3851 "pt_Latn_GW",
3852 "pt_GW"
3853 }, {
3854 "und_Geor",
3855 "ka_Geor_GE",
3856 "ka"
3857 }, {
3858 "und_Grek",
3859 "el_Grek_GR",
3860 "el"
3861 }, {
3862 "und_Gujr",
3863 "gu_Gujr_IN",
3864 "gu"
3865 }, {
3866 "und_Guru",
3867 "pa_Guru_IN",
3868 "pa"
3869 }, {
3870 "und_HK",
3871 "zh_Hant_HK",
3872 "zh_HK"
3873 }, {
3874 "und_HN",
3875 "es_Latn_HN",
3876 "es_HN"
3877 }, {
3878 "und_HR",
3879 "hr_Latn_HR",
3880 "hr"
3881 }, {
3882 "und_HT",
3883 "ht_Latn_HT",
3884 "ht"
3885 }, {
3886 "und_HU",
3887 "hu_Latn_HU",
3888 "hu"
3889 }, {
3890 "und_Hani",
3891 "zh_Hans_CN",
3892 "zh"
3893 }, {
3894 "und_Hans",
3895 "zh_Hans_CN",
3896 "zh"
3897 }, {
3898 "und_Hant",
3899 "zh_Hant_TW",
3900 "zh_TW"
3901 }, {
3902 "und_Hebr",
3903 "he_Hebr_IL",
3904 "he"
3905 }, {
3906 "und_IL",
3907 "he_Hebr_IL",
3908 "he"
3909 }, {
3910 "und_IN",
3911 "hi_Deva_IN",
3912 "hi"
3913 }, {
3914 "und_IQ",
3915 "ar_Arab_IQ",
3916 "ar_IQ"
3917 }, {
3918 "und_IR",
3919 "fa_Arab_IR",
3920 "fa"
3921 }, {
3922 "und_IS",
3923 "is_Latn_IS",
3924 "is"
3925 }, {
3926 "und_IT",
3927 "it_Latn_IT",
3928 "it"
3929 }, {
3930 "und_JO",
3931 "ar_Arab_JO",
3932 "ar_JO"
3933 }, {
3934 "und_JP",
3935 "ja_Jpan_JP",
3936 "ja"
3937 }, {
3938 "und_Jpan",
3939 "ja_Jpan_JP",
3940 "ja"
3941 }, {
3942 "und_KG",
3943 "ky_Cyrl_KG",
3944 "ky"
3945 }, {
3946 "und_KH",
3947 "km_Khmr_KH",
3948 "km"
3949 }, {
3950 "und_KM",
3951 "ar_Arab_KM",
3952 "ar_KM"
3953 }, {
3954 "und_KP",
3955 "ko_Kore_KP",
3956 "ko_KP"
3957 }, {
3958 "und_KR",
3959 "ko_Kore_KR",
3960 "ko"
3961 }, {
3962 "und_KW",
3963 "ar_Arab_KW",
3964 "ar_KW"
3965 }, {
3966 "und_KZ",
3967 "ru_Cyrl_KZ",
3968 "ru_KZ"
3969 }, {
3970 "und_Khmr",
3971 "km_Khmr_KH",
3972 "km"
3973 }, {
3974 "und_Knda",
3975 "kn_Knda_IN",
3976 "kn"
3977 }, {
3978 "und_Kore",
3979 "ko_Kore_KR",
3980 "ko"
3981 }, {
3982 "und_LA",
3983 "lo_Laoo_LA",
3984 "lo"
3985 }, {
3986 "und_LB",
3987 "ar_Arab_LB",
3988 "ar_LB"
3989 }, {
3990 "und_LI",
3991 "de_Latn_LI",
3992 "de_LI"
3993 }, {
3994 "und_LK",
3995 "si_Sinh_LK",
3996 "si"
3997 }, {
3998 "und_LS",
3999 "st_Latn_LS",
4000 "st_LS"
4001 }, {
4002 "und_LT",
4003 "lt_Latn_LT",
4004 "lt"
4005 }, {
4006 "und_LU",
4007 "fr_Latn_LU",
4008 "fr_LU"
4009 }, {
4010 "und_LV",
4011 "lv_Latn_LV",
4012 "lv"
4013 }, {
4014 "und_LY",
4015 "ar_Arab_LY",
4016 "ar_LY"
4017 }, {
4018 "und_Laoo",
4019 "lo_Laoo_LA",
4020 "lo"
4021 }, {
4022 "und_Latn_ES",
4023 "es_Latn_ES",
4024 "es"
4025 }, {
4026 "und_Latn_ET",
4027 "om_Latn_ET",
4028 "om"
4029 }, {
4030 "und_Latn_GB",
4031 "en_Latn_GB",
4032 "en_GB"
4033 }, {
4034 "und_Latn_GH",
4035 "ak_Latn_GH",
4036 "ak"
4037 }, {
4038 "und_Latn_ID",
4039 "id_Latn_ID",
4040 "id"
4041 }, {
4042 "und_Latn_IT",
4043 "it_Latn_IT",
4044 "it"
4045 }, {
4046 "und_Latn_NG",
4047 "ha_Latn_NG",
4048 "ha"
4049 }, {
4050 "und_Latn_TR",
4051 "tr_Latn_TR",
4052 "tr"
4053 }, {
4054 "und_Latn_ZA",
4055 "en_Latn_ZA",
4056 "en_ZA"
4057 }, {
4058 "und_MA",
4059 "ar_Arab_MA",
4060 "ar_MA"
4061 }, {
4062 "und_MC",
4063 "fr_Latn_MC",
4064 "fr_MC"
4065 }, {
4066 "und_MD",
4067 "ro_Latn_MD",
4068 "ro_MD"
4069 }, {
4070 "und_ME",
4071 "sr_Cyrl_ME",
4072 "sr_ME"
4073 }, {
4074 "und_MG",
4075 "mg_Latn_MG",
4076 "mg"
4077 }, {
4078 "und_MH",
4079 "mh_Latn_MH",
4080 "mh"
4081 }, {
4082 "und_MK",
4083 "mk_Cyrl_MK",
4084 "mk"
4085 }, {
4086 "und_ML",
4087 "fr_Latn_ML",
4088 "fr_ML"
4089 }, {
4090 "und_MM",
4091 "my_Mymr_MM",
4092 "my"
4093 }, {
4094 "und_MN",
4095 "mn_Cyrl_MN",
4096 "mn"
4097 }, {
4098 "und_MO",
4099 "zh_Hant_MO",
4100 "zh_MO"
4101 }, {
4102 "und_MQ",
4103 "fr_Latn_MQ",
4104 "fr_MQ"
4105 }, {
4106 "und_MR",
4107 "ar_Arab_MR",
4108 "ar_MR"
4109 }, {
4110 "und_MT",
4111 "mt_Latn_MT",
4112 "mt"
4113 }, {
4114 "und_MV",
4115 "dv_Thaa_MV",
4116 "dv"
4117 }, {
4118 "und_MW",
4119 "ny_Latn_MW",
4120 "ny"
4121 }, {
4122 "und_MX",
4123 "es_Latn_MX",
4124 "es_MX"
4125 }, {
4126 "und_MY",
4127 "ms_Latn_MY",
4128 "ms"
4129 }, {
4130 "und_MZ",
4131 "pt_Latn_MZ",
4132 "pt_MZ"
4133 }, {
4134 "und_Mlym",
4135 "ml_Mlym_IN",
4136 "ml"
4137 }, {
4138 "und_Mymr",
4139 "my_Mymr_MM",
4140 "my"
4141 }, {
4142 "und_NC",
4143 "fr_Latn_NC",
4144 "fr_NC"
4145 }, {
4146 "und_NE",
4147 "ha_Latn_NE",
4148 "ha_NE"
4149 }, {
4150 "und_NG",
4151 "ha_Latn_NG",
4152 "ha"
4153 }, {
4154 "und_NI",
4155 "es_Latn_NI",
4156 "es_NI"
4157 }, {
4158 "und_NL",
4159 "nl_Latn_NL",
4160 "nl"
4161 }, {
4162 "und_NO",
4163 "nb_Latn_NO",
4164 "nb"
4165 }, {
4166 "und_NP",
4167 "ne_Deva_NP",
4168 "ne"
4169 }, {
4170 "und_NR",
4171 "na_Latn_NR",
4172 "na"
4173 }, {
4174 "und_NU",
4175 "niu_Latn_NU",
4176 "niu"
4177 }, {
4178 "und_OM",
4179 "ar_Arab_OM",
4180 "ar_OM"
4181 }, {
4182 "und_Orya",
4183 "or_Orya_IN",
4184 "or"
4185 }, {
4186 "und_PA",
4187 "es_Latn_PA",
4188 "es_PA"
4189 }, {
4190 "und_PE",
4191 "es_Latn_PE",
4192 "es_PE"
4193 }, {
4194 "und_PF",
4195 "ty_Latn_PF",
4196 "ty"
4197 }, {
4198 "und_PG",
4199 "tpi_Latn_PG",
4200 "tpi"
4201 }, {
4202 "und_PH",
4203 "fil_Latn_PH",
4204 "fil"
4205 }, {
4206 "und_PL",
4207 "pl_Latn_PL",
4208 "pl"
4209 }, {
4210 "und_PM",
4211 "fr_Latn_PM",
4212 "fr_PM"
4213 }, {
4214 "und_PR",
4215 "es_Latn_PR",
4216 "es_PR"
4217 }, {
4218 "und_PS",
4219 "ar_Arab_PS",
4220 "ar_PS"
4221 }, {
4222 "und_PT",
4223 "pt_Latn_PT",
4224 "pt_PT"
4225 }, {
4226 "und_PW",
4227 "pau_Latn_PW",
4228 "pau"
4229 }, {
4230 "und_PY",
4231 "gn_Latn_PY",
4232 "gn"
4233 }, {
4234 "und_QA",
4235 "ar_Arab_QA",
4236 "ar_QA"
4237 }, {
4238 "und_RE",
4239 "fr_Latn_RE",
4240 "fr_RE"
4241 }, {
4242 "und_RO",
4243 "ro_Latn_RO",
4244 "ro"
4245 }, {
4246 "und_RS",
4247 "sr_Cyrl_RS",
4248 "sr"
4249 }, {
4250 "und_RU",
4251 "ru_Cyrl_RU",
4252 "ru"
4253 }, {
4254 "und_RW",
4255 "rw_Latn_RW",
4256 "rw"
4257 }, {
4258 "und_SA",
4259 "ar_Arab_SA",
4260 "ar_SA"
4261 }, {
4262 "und_SD",
4263 "ar_Arab_SD",
4264 "ar_SD"
4265 }, {
4266 "und_SE",
4267 "sv_Latn_SE",
4268 "sv"
4269 }, {
4270 "und_SG",
4271 "en_Latn_SG",
4272 "en_SG"
4273 }, {
4274 "und_SI",
4275 "sl_Latn_SI",
4276 "sl"
4277 }, {
4278 "und_SJ",
4279 "nb_Latn_SJ",
4280 "nb_SJ"
4281 }, {
4282 "und_SK",
4283 "sk_Latn_SK",
4284 "sk"
4285 }, {
4286 "und_SM",
4287 "it_Latn_SM",
4288 "it_SM"
4289 }, {
4290 "und_SN",
4291 "fr_Latn_SN",
4292 "fr_SN"
4293 }, {
4294 "und_SO",
4295 "so_Latn_SO",
4296 "so"
4297 }, {
4298 "und_SR",
4299 "nl_Latn_SR",
4300 "nl_SR"
4301 }, {
4302 "und_ST",
4303 "pt_Latn_ST",
4304 "pt_ST"
4305 }, {
4306 "und_SV",
4307 "es_Latn_SV",
4308 "es_SV"
4309 }, {
4310 "und_SY",
4311 "ar_Arab_SY",
4312 "ar_SY"
4313 }, {
4314 "und_Sinh",
4315 "si_Sinh_LK",
4316 "si"
4317 }, {
4318 "und_TD",
4319 "ar_Arab_TD",
4320 "ar_TD"
4321 }, {
4322 "und_TG",
4323 "ee_Latn_TG",
4324 "ee_TG"
4325 }, {
4326 "und_TH",
4327 "th_Thai_TH",
4328 "th"
4329 }, {
4330 "und_TJ",
4331 "tg_Cyrl_TJ",
4332 "tg"
4333 }, {
4334 "und_TK",
4335 "tkl_Latn_TK",
4336 "tkl"
4337 }, {
4338 "und_TL",
4339 "tet_Latn_TL",
4340 "tet"
4341 }, {
4342 "und_TM",
4343 "tk_Latn_TM",
4344 "tk"
4345 }, {
4346 "und_TN",
4347 "ar_Arab_TN",
4348 "ar_TN"
4349 }, {
4350 "und_TO",
4351 "to_Latn_TO",
4352 "to"
4353 }, {
4354 "und_TR",
4355 "tr_Latn_TR",
4356 "tr"
4357 }, {
4358 "und_TV",
4359 "tvl_Latn_TV",
4360 "tvl"
4361 }, {
4362 "und_TW",
4363 "zh_Hant_TW",
4364 "zh_TW"
4365 }, {
4366 "und_Taml",
4367 "ta_Taml_IN",
4368 "ta"
4369 }, {
4370 "und_Telu",
4371 "te_Telu_IN",
4372 "te"
4373 }, {
4374 "und_Thaa",
4375 "dv_Thaa_MV",
4376 "dv"
4377 }, {
4378 "und_Thai",
4379 "th_Thai_TH",
4380 "th"
4381 }, {
4382 "und_Tibt",
4383 "bo_Tibt_CN",
4384 "bo"
4385 }, {
4386 "und_UA",
4387 "uk_Cyrl_UA",
4388 "uk"
4389 }, {
4390 "und_UY",
4391 "es_Latn_UY",
4392 "es_UY"
4393 }, {
4394 "und_UZ",
4395 "uz_Cyrl_UZ",
4396 "uz"
4397 }, {
4398 "und_VA",
4399 "la_Latn_VA",
4400 "la"
4401 }, {
4402 "und_VE",
4403 "es_Latn_VE",
4404 "es_VE"
4405 }, {
4406 "und_VN",
4407 "vi_Latn_VN",
4408 "vi"
4409 }, {
4410 "und_VU",
4411 "fr_Latn_VU",
4412 "fr_VU"
4413 }, {
4414 "und_WF",
4415 "fr_Latn_WF",
4416 "fr_WF"
4417 }, {
4418 "und_WS",
4419 "sm_Latn_WS",
4420 "sm"
4421 }, {
4422 "und_YE",
4423 "ar_Arab_YE",
4424 "ar_YE"
4425 }, {
4426 "und_YT",
4427 "fr_Latn_YT",
4428 "fr_YT"
4429 }, {
4430 "und_Yiii",
4431 "en_Yiii_US",
4432 "en_Yiii"
4433 }, {
4434 "ur",
4435 "ur_Arab_PK",
4436 "ur"
4437 }, {
4438 "uz",
4439 "uz_Cyrl_UZ",
4440 "uz"
4441 }, {
4442 "uz_AF",
4443 "uz_Arab_AF",
4444 "uz_AF"
4445 }, {
4446 "uz_Arab",
4447 "uz_Arab_AF",
4448 "uz_AF"
4449 }, {
4450 "ve",
4451 "ve_Latn_ZA",
4452 "ve"
4453 }, {
4454 "vi",
4455 "vi_Latn_VN",
4456 "vi"
4457 }, {
4458 "wal",
4459 "wal_Ethi_ET",
4460 "wal"
4461 }, {
4462 "wo",
4463 "wo_Latn_SN",
4464 "wo"
4465 }, {
4466 "xh",
4467 "xh_Latn_ZA",
4468 "xh"
4469 }, {
4470 "yo",
4471 "yo_Latn_NG",
4472 "yo"
4473 }, {
4474 "zh",
4475 "zh_Hans_CN",
4476 "zh"
4477 }, {
4478 "zh_HK",
4479 "zh_Hant_HK",
4480 "zh_HK"
4481 }, {
4482 "zh_Hani",
4483 "zh_Hans_CN",
4484 "zh"
4485 }, {
4486 "zh_Hant",
4487 "zh_Hant_TW",
4488 "zh_TW"
4489 }, {
4490 "zh_MO",
4491 "zh_Hant_MO",
4492 "zh_MO"
4493 }, {
4494 "zh_TW",
4495 "zh_Hant_TW",
4496 "zh_TW"
4497 }, {
4498 "zu",
4499 "zu_Latn_ZA",
4500 "zu"
4501 }, {
4502 "und",
4503 "en_Latn_US",
4504 "en"
4505 }, {
4506 "und_ZZ",
4507 "en_Latn_US",
4508 "en"
4509 }, {
4510 "und_CN",
4511 "zh_Hans_CN",
4512 "zh"
4513 }, {
4514 "und_TW",
4515 "zh_Hant_TW",
4516 "zh_TW"
4517 }, {
4518 "und_HK",
4519 "zh_Hant_HK",
4520 "zh_HK"
4521 }, {
4522 "und_AQ",
4523 "en_Latn_AQ",
4524 "en_AQ"
4525 }, {
4526 "und_Zzzz",
4527 "en_Latn_US",
4528 "en"
4529 }, {
4530 "und_Zzzz_ZZ",
4531 "en_Latn_US",
4532 "en"
4533 }, {
4534 "und_Zzzz_CN",
4535 "zh_Hans_CN",
4536 "zh"
4537 }, {
4538 "und_Zzzz_TW",
4539 "zh_Hant_TW",
4540 "zh_TW"
4541 }, {
4542 "und_Zzzz_HK",
4543 "zh_Hant_HK",
4544 "zh_HK"
4545 }, {
4546 "und_Zzzz_AQ",
4547 "en_Latn_AQ",
4548 "en_AQ"
4549 }, {
4550 "und_Latn",
4551 "en_Latn_US",
4552 "en"
4553 }, {
4554 "und_Latn_ZZ",
4555 "en_Latn_US",
4556 "en"
4557 }, {
4558 "und_Latn_CN",
4559 "ii_Latn_CN",
4560 "ii"
4561 }, {
4562 "und_Latn_TW",
4563 "zh_Latn_TW",
4564 "zh_Latn_TW"
4565 }, {
4566 "und_Latn_HK",
4567 "zh_Latn_HK",
4568 "zh_Latn_HK"
4569 }, {
4570 "und_Latn_AQ",
4571 "en_Latn_AQ",
4572 "en_AQ"
4573 }, {
4574 "und_Hans",
4575 "zh_Hans_CN",
4576 "zh"
4577 }, {
4578 "und_Hans_ZZ",
4579 "zh_Hans_CN",
4580 "zh"
4581 }, {
4582 "und_Hans_CN",
4583 "zh_Hans_CN",
4584 "zh"
4585 }, {
4586 "und_Hans_TW",
4587 "zh_Hans_TW",
4588 "zh_Hans_TW"
4589 }, {
4590 "und_Hans_HK",
4591 "zh_Hans_HK",
4592 "zh_Hans_HK"
4593 }, {
4594 "und_Hans_AQ",
4595 "zh_Hans_AQ",
4596 "zh_AQ"
4597 }, {
4598 "und_Hant",
4599 "zh_Hant_TW",
4600 "zh_TW"
4601 }, {
4602 "und_Hant_ZZ",
4603 "zh_Hant_TW",
4604 "zh_TW"
4605 }, {
4606 "und_Hant_CN",
4607 "zh_Hant_CN",
4608 "zh_Hant_CN"
4609 }, {
4610 "und_Hant_TW",
4611 "zh_Hant_TW",
4612 "zh_TW"
4613 }, {
4614 "und_Hant_HK",
4615 "zh_Hant_HK",
4616 "zh_HK"
4617 }, {
4618 "und_Hant_AQ",
4619 "zh_Hant_AQ",
4620 "zh_Hant_AQ"
4621 }, {
4622 "und_Moon",
4623 "en_Moon_US",
4624 "en_Moon"
4625 }, {
4626 "und_Moon_ZZ",
4627 "en_Moon_US",
4628 "en_Moon"
4629 }, {
4630 "und_Moon_CN",
4631 "zh_Moon_CN",
4632 "zh_Moon"
4633 }, {
4634 "und_Moon_TW",
4635 "zh_Moon_TW",
4636 "zh_Moon_TW"
4637 }, {
4638 "und_Moon_HK",
4639 "zh_Moon_HK",
4640 "zh_Moon_HK"
4641 }, {
4642 "und_Moon_AQ",
4643 "en_Moon_AQ",
4644 "en_Moon_AQ"
4645 }, {
4646 "es",
4647 "es_Latn_ES",
4648 "es"
4649 }, {
4650 "es_ZZ",
4651 "es_Latn_ES",
4652 "es"
4653 }, {
4654 "es_CN",
4655 "es_Latn_CN",
4656 "es_CN"
4657 }, {
4658 "es_TW",
4659 "es_Latn_TW",
4660 "es_TW"
4661 }, {
4662 "es_HK",
4663 "es_Latn_HK",
4664 "es_HK"
4665 }, {
4666 "es_AQ",
4667 "es_Latn_AQ",
4668 "es_AQ"
4669 }, {
4670 "es_Zzzz",
4671 "es_Latn_ES",
4672 "es"
4673 }, {
4674 "es_Zzzz_ZZ",
4675 "es_Latn_ES",
4676 "es"
4677 }, {
4678 "es_Zzzz_CN",
4679 "es_Latn_CN",
4680 "es_CN"
4681 }, {
4682 "es_Zzzz_TW",
4683 "es_Latn_TW",
4684 "es_TW"
4685 }, {
4686 "es_Zzzz_HK",
4687 "es_Latn_HK",
4688 "es_HK"
4689 }, {
4690 "es_Zzzz_AQ",
4691 "es_Latn_AQ",
4692 "es_AQ"
4693 }, {
4694 "es_Latn",
4695 "es_Latn_ES",
4696 "es"
4697 }, {
4698 "es_Latn_ZZ",
4699 "es_Latn_ES",
4700 "es"
4701 }, {
4702 "es_Latn_CN",
4703 "es_Latn_CN",
4704 "es_CN"
4705 }, {
4706 "es_Latn_TW",
4707 "es_Latn_TW",
4708 "es_TW"
4709 }, {
4710 "es_Latn_HK",
4711 "es_Latn_HK",
4712 "es_HK"
4713 }, {
4714 "es_Latn_AQ",
4715 "es_Latn_AQ",
4716 "es_AQ"
4717 }, {
4718 "es_Hans",
4719 "es_Hans_ES",
4720 "es_Hans"
4721 }, {
4722 "es_Hans_ZZ",
4723 "es_Hans_ES",
4724 "es_Hans"
4725 }, {
4726 "es_Hans_CN",
4727 "es_Hans_CN",
4728 "es_Hans_CN"
4729 }, {
4730 "es_Hans_TW",
4731 "es_Hans_TW",
4732 "es_Hans_TW"
4733 }, {
4734 "es_Hans_HK",
4735 "es_Hans_HK",
4736 "es_Hans_HK"
4737 }, {
4738 "es_Hans_AQ",
4739 "es_Hans_AQ",
4740 "es_Hans_AQ"
4741 }, {
4742 "es_Hant",
4743 "es_Hant_ES",
4744 "es_Hant"
4745 }, {
4746 "es_Hant_ZZ",
4747 "es_Hant_ES",
4748 "es_Hant"
4749 }, {
4750 "es_Hant_CN",
4751 "es_Hant_CN",
4752 "es_Hant_CN"
4753 }, {
4754 "es_Hant_TW",
4755 "es_Hant_TW",
4756 "es_Hant_TW"
4757 }, {
4758 "es_Hant_HK",
4759 "es_Hant_HK",
4760 "es_Hant_HK"
4761 }, {
4762 "es_Hant_AQ",
4763 "es_Hant_AQ",
4764 "es_Hant_AQ"
4765 }, {
4766 "es_Moon",
4767 "es_Moon_ES",
4768 "es_Moon"
4769 }, {
4770 "es_Moon_ZZ",
4771 "es_Moon_ES",
4772 "es_Moon"
4773 }, {
4774 "es_Moon_CN",
4775 "es_Moon_CN",
4776 "es_Moon_CN"
4777 }, {
4778 "es_Moon_TW",
4779 "es_Moon_TW",
4780 "es_Moon_TW"
4781 }, {
4782 "es_Moon_HK",
4783 "es_Moon_HK",
4784 "es_Moon_HK"
4785 }, {
4786 "es_Moon_AQ",
4787 "es_Moon_AQ",
4788 "es_Moon_AQ"
4789 }, {
4790 "zh",
4791 "zh_Hans_CN",
4792 "zh"
4793 }, {
4794 "zh_ZZ",
4795 "zh_Hans_CN",
4796 "zh"
4797 }, {
4798 "zh_CN",
4799 "zh_Hans_CN",
4800 "zh"
4801 }, {
4802 "zh_TW",
4803 "zh_Hant_TW",
4804 "zh_TW"
4805 }, {
4806 "zh_HK",
4807 "zh_Hant_HK",
4808 "zh_HK"
4809 }, {
4810 "zh_AQ",
4811 "zh_Hans_AQ",
4812 "zh_AQ"
4813 }, {
4814 "zh_Zzzz",
4815 "zh_Hans_CN",
4816 "zh"
4817 }, {
4818 "zh_Zzzz_ZZ",
4819 "zh_Hans_CN",
4820 "zh"
4821 }, {
4822 "zh_Zzzz_CN",
4823 "zh_Hans_CN",
4824 "zh"
4825 }, {
4826 "zh_Zzzz_TW",
4827 "zh_Hant_TW",
4828 "zh_TW"
4829 }, {
4830 "zh_Zzzz_HK",
4831 "zh_Hant_HK",
4832 "zh_HK"
4833 }, {
4834 "zh_Zzzz_AQ",
4835 "zh_Hans_AQ",
4836 "zh_AQ"
4837 }, {
4838 "zh_Latn",
4839 "zh_Latn_CN",
4840 "zh_Latn"
4841 }, {
4842 "zh_Latn_ZZ",
4843 "zh_Latn_CN",
4844 "zh_Latn"
4845 }, {
4846 "zh_Latn_CN",
4847 "zh_Latn_CN",
4848 "zh_Latn"
4849 }, {
4850 "zh_Latn_TW",
4851 "zh_Latn_TW",
4852 "zh_Latn_TW"
4853 }, {
4854 "zh_Latn_HK",
4855 "zh_Latn_HK",
4856 "zh_Latn_HK"
4857 }, {
4858 "zh_Latn_AQ",
4859 "zh_Latn_AQ",
4860 "zh_Latn_AQ"
4861 }, {
4862 "zh_Hans",
4863 "zh_Hans_CN",
4864 "zh"
4865 }, {
4866 "zh_Hans_ZZ",
4867 "zh_Hans_CN",
4868 "zh"
4869 }, {
4870 "zh_Hans_TW",
4871 "zh_Hans_TW",
4872 "zh_Hans_TW"
4873 }, {
4874 "zh_Hans_HK",
4875 "zh_Hans_HK",
4876 "zh_Hans_HK"
4877 }, {
4878 "zh_Hans_AQ",
4879 "zh_Hans_AQ",
4880 "zh_AQ"
4881 }, {
4882 "zh_Hant",
4883 "zh_Hant_TW",
4884 "zh_TW"
4885 }, {
4886 "zh_Hant_ZZ",
4887 "zh_Hant_TW",
4888 "zh_TW"
4889 }, {
4890 "zh_Hant_CN",
4891 "zh_Hant_CN",
4892 "zh_Hant_CN"
4893 }, {
4894 "zh_Hant_AQ",
4895 "zh_Hant_AQ",
4896 "zh_Hant_AQ"
4897 }, {
4898 "zh_Moon",
4899 "zh_Moon_CN",
4900 "zh_Moon"
4901 }, {
4902 "zh_Moon_ZZ",
4903 "zh_Moon_CN",
4904 "zh_Moon"
4905 }, {
4906 "zh_Moon_CN",
4907 "zh_Moon_CN",
4908 "zh_Moon"
4909 }, {
4910 "zh_Moon_TW",
4911 "zh_Moon_TW",
4912 "zh_Moon_TW"
4913 }, {
4914 "zh_Moon_HK",
4915 "zh_Moon_HK",
4916 "zh_Moon_HK"
4917 }, {
4918 "zh_Moon_AQ",
4919 "zh_Moon_AQ",
4920 "zh_Moon_AQ"
4921 }, {
4922 "art",
4923 "",
4924 ""
4925 }, {
4926 "art_ZZ",
4927 "",
4928 ""
4929 }, {
4930 "art_CN",
4931 "",
4932 ""
4933 }, {
4934 "art_TW",
4935 "",
4936 ""
4937 }, {
4938 "art_HK",
4939 "",
4940 ""
4941 }, {
4942 "art_AQ",
4943 "",
4944 ""
4945 }, {
4946 "art_Zzzz",
4947 "",
4948 ""
4949 }, {
4950 "art_Zzzz_ZZ",
4951 "",
4952 ""
4953 }, {
4954 "art_Zzzz_CN",
4955 "",
4956 ""
4957 }, {
4958 "art_Zzzz_TW",
4959 "",
4960 ""
4961 }, {
4962 "art_Zzzz_HK",
4963 "",
4964 ""
4965 }, {
4966 "art_Zzzz_AQ",
4967 "",
4968 ""
4969 }, {
4970 "art_Latn",
4971 "",
4972 ""
4973 }, {
4974 "art_Latn_ZZ",
4975 "",
4976 ""
4977 }, {
4978 "art_Latn_CN",
4979 "",
4980 ""
4981 }, {
4982 "art_Latn_TW",
4983 "",
4984 ""
4985 }, {
4986 "art_Latn_HK",
4987 "",
4988 ""
4989 }, {
4990 "art_Latn_AQ",
4991 "",
4992 ""
4993 }, {
4994 "art_Hans",
4995 "",
4996 ""
4997 }, {
4998 "art_Hans_ZZ",
4999 "",
5000 ""
5001 }, {
5002 "art_Hans_CN",
5003 "",
5004 ""
5005 }, {
5006 "art_Hans_TW",
5007 "",
5008 ""
5009 }, {
5010 "art_Hans_HK",
5011 "",
5012 ""
5013 }, {
5014 "art_Hans_AQ",
5015 "",
5016 ""
5017 }, {
5018 "art_Hant",
5019 "",
5020 ""
5021 }, {
5022 "art_Hant_ZZ",
5023 "",
5024 ""
5025 }, {
5026 "art_Hant_CN",
5027 "",
5028 ""
5029 }, {
5030 "art_Hant_TW",
5031 "",
5032 ""
5033 }, {
5034 "art_Hant_HK",
5035 "",
5036 ""
5037 }, {
5038 "art_Hant_AQ",
5039 "",
5040 ""
5041 }, {
5042 "art_Moon",
5043 "",
5044 ""
5045 }, {
5046 "art_Moon_ZZ",
5047 "",
5048 ""
5049 }, {
5050 "art_Moon_CN",
5051 "",
5052 ""
5053 }, {
5054 "art_Moon_TW",
5055 "",
5056 ""
5057 }, {
5058 "art_Moon_HK",
5059 "",
5060 ""
5061 }, {
5062 "art_Moon_AQ",
5063 "",
5064 ""
5065 }
5066};
5067
5068typedef struct errorDataTag {
5069 const char* tag;
5070 const char* expected;
5071 UErrorCode uerror;
5072 int32_t bufferSize;
5073} errorData;
5074
5075const errorData maximizeErrors[] = {
5076 {
5077 "enfueiujhytdf",
5078 NULL,
5079 U_ILLEGAL_ARGUMENT_ERROR,
5080 -1
5081 },
5082 {
5083 "en_THUJIOGIURJHGJFURYHFJGURYYYHHGJURHG",
5084 NULL,
5085 U_ILLEGAL_ARGUMENT_ERROR,
5086 -1
5087 },
5088 {
5089 "en_THUJIOGIURJHGJFURYHFJGURYYYHHGJURHG",
5090 NULL,
5091 U_ILLEGAL_ARGUMENT_ERROR,
5092 -1
5093 },
5094 {
5095 "en_Latn_US_POSIX@currency=EURO",
5096 "en_Latn_US_POSIX@currency=EURO",
5097 U_BUFFER_OVERFLOW_ERROR,
5098 29
5099 },
5100 {
5101 "en_Latn_US_POSIX@currency=EURO",
5102 "en_Latn_US_POSIX@currency=EURO",
5103 U_STRING_NOT_TERMINATED_WARNING,
5104 30
5105 }
5106};
5107
5108const errorData minimizeErrors[] = {
5109 {
5110 "enfueiujhytdf",
5111 NULL,
5112 U_ILLEGAL_ARGUMENT_ERROR,
5113 -1
5114 },
5115 {
5116 "en_THUJIOGIURJHGJFURYHFJGURYYYHHGJURHG",
5117 NULL,
5118 U_ILLEGAL_ARGUMENT_ERROR,
5119 -1
5120 },
5121 {
5122 "en_Latn_US_POSIX@currency=EURO",
5123 "en__POSIX@currency=EURO",
5124 U_BUFFER_OVERFLOW_ERROR,
5125 22
5126 },
5127 {
5128 "en_Latn_US_POSIX@currency=EURO",
5129 "en__POSIX@currency=EURO",
5130 U_STRING_NOT_TERMINATED_WARNING,
5131 23
5132 }
5133};
5134
5135static int32_t getExpectedReturnValue(const errorData* data)
5136{
5137 if (data->uerror == U_BUFFER_OVERFLOW_ERROR ||
5138 data->uerror == U_STRING_NOT_TERMINATED_WARNING)
5139 {
5140 return strlen(data->expected);
5141 }
5142 else
5143 {
5144 return -1;
5145 }
5146}
5147
5148static int32_t getBufferSize(const errorData* data, int32_t actualSize)
5149{
5150 if (data->expected == NULL)
5151 {
5152 return actualSize;
5153 }
5154 else if (data->bufferSize < 0)
5155 {
5156 return strlen(data->expected) + 1;
5157 }
5158 else
5159 {
5160 return data->bufferSize;
5161 }
5162}
5163
5164static void TestLikelySubtags()
5165{
5166 char buffer[ULOC_FULLNAME_CAPACITY + ULOC_KEYWORD_AND_VALUES_CAPACITY + 1];
5167 int32_t i = 0;
5168
5169 for (; i < sizeof(basic_maximize_data) / sizeof(basic_maximize_data[0]); ++i)
5170 {
5171 UErrorCode status = U_ZERO_ERROR;
5172 const char* const minimal = basic_maximize_data[i][0];
5173 const char* const maximal = basic_maximize_data[i][1];
5174
5175 const int32_t length =
5176 uloc_addLikelySubtags(
5177 minimal,
5178 buffer,
5179 sizeof(buffer),
5180 &status);
5181 if (U_FAILURE(status)) {
5182 log_err(" unexpected failure of uloc_addLikelySubtags(), minimal \"%s\" status %s\n", minimal, u_errorName(status));
5183 status = U_ZERO_ERROR;
5184 }
5185 else if (uprv_strlen(maximal) == 0) {
5186 if (uprv_stricmp(minimal, buffer) != 0) {
5187 log_err(" unexpected maximal value \"%s\" in uloc_addLikelySubtags(), minimal \"%s\" = \"%s\"\n", maximal, minimal, buffer);
5188 }
5189 }
5190 else if (uprv_stricmp(maximal, buffer) != 0) {
5191 log_err(" maximal doesn't match expected %s in uloc_addLikelySubtags(), minimal \"%s\" = %s\n", maximal, minimal, buffer);
5192 }
5193 }
5194
5195 for (i = 0; i < sizeof(basic_minimize_data) / sizeof(basic_minimize_data[0]); ++i) {
5196
5197 UErrorCode status = U_ZERO_ERROR;
5198 const char* const maximal = basic_minimize_data[i][0];
5199 const char* const minimal = basic_minimize_data[i][1];
5200
5201 const int32_t length =
5202 uloc_minimizeSubtags(
5203 maximal,
5204 buffer,
5205 sizeof(buffer),
5206 &status);
5207
5208 if (U_FAILURE(status)) {
5209 log_err(" unexpected failure of uloc_MinimizeSubtags(), maximal \"%s\" status %s\n", maximal, u_errorName(status));
5210 status = U_ZERO_ERROR;
5211 }
5212 else if (uprv_strlen(minimal) == 0) {
5213 if (uprv_stricmp(maximal, buffer) != 0) {
5214 log_err(" unexpected minimal value \"%s\" in uloc_minimizeSubtags(), maximal \"%s\" = \"%s\"\n", minimal, maximal, buffer);
5215 }
5216 }
5217 else if (uprv_stricmp(minimal, buffer) != 0) {
5218 log_err(" minimal doesn't match expected %s in uloc_MinimizeSubtags(), maximal \"%s\" = %s\n", minimal, maximal, buffer);
5219 }
5220 }
5221
5222 for (i = 0; i < sizeof(full_data) / sizeof(full_data[0]); ++i) {
5223
5224 UErrorCode status = U_ZERO_ERROR;
5225 const char* const minimal = full_data[i][0];
5226 const char* const maximal = full_data[i][1];
5227
5228 const int32_t length =
5229 uloc_addLikelySubtags(
5230 minimal,
5231 buffer,
5232 sizeof(buffer),
5233 &status);
5234 if (U_FAILURE(status)) {
5235 log_err(" unexpected failure of uloc_addLikelySubtags(), minimal \"%s\" status \"%s\"\n", minimal, u_errorName(status));
5236 status = U_ZERO_ERROR;
5237 }
5238 else if (uprv_strlen(maximal) == 0) {
5239 if (uprv_stricmp(minimal, buffer) != 0) {
5240 log_err(" unexpected maximal value \"%s\" in uloc_addLikelySubtags(), minimal \"%s\" = \"%s\"\n", maximal, minimal, buffer);
5241 }
5242 }
5243 else if (uprv_stricmp(maximal, buffer) != 0) {
5244 log_err(" maximal doesn't match expected \"%s\" in uloc_addLikelySubtags(), minimal \"%s\" = \"%s\"\n", maximal, minimal, buffer);
5245 }
5246 }
5247
5248 for (i = 0; i < sizeof(full_data) / sizeof(full_data[0]); ++i) {
5249
5250 UErrorCode status = U_ZERO_ERROR;
5251 const char* const maximal = full_data[i][1];
5252 const char* const minimal = full_data[i][2];
5253
5254 if (strlen(maximal) > 0) {
5255
5256 const int32_t length =
5257 uloc_minimizeSubtags(
5258 maximal,
5259 buffer,
5260 sizeof(buffer),
5261 &status);
5262
5263 if (U_FAILURE(status)) {
5264 log_err(" unexpected failure of uloc_minimizeSubtags(), maximal \"%s\" status %s\n", maximal, u_errorName(status));
5265 status = U_ZERO_ERROR;
5266 }
5267 else if (uprv_strlen(minimal) == 0) {
5268 if (uprv_stricmp(maximal, buffer) != 0) {
5269 log_err(" unexpected minimal value \"%s\" in uloc_minimizeSubtags(), maximal \"%s\" = \"%s\"\n", minimal, maximal, buffer);
5270 }
5271 }
5272 else if (uprv_stricmp(minimal, buffer) != 0) {
5273 log_err(" minimal doesn't match expected %s in uloc_MinimizeSubtags(), maximal \"%s\" = %s\n", minimal, maximal, buffer);
5274 }
5275 }
5276 }
5277
5278 for (i = 0; i < sizeof(maximizeErrors) / sizeof(maximizeErrors[0]); ++i) {
5279
5280 UErrorCode status = U_ZERO_ERROR;
5281 const char* const minimal = maximizeErrors[i].tag;
5282 const char* const maximal = maximizeErrors[i].expected;
5283 const UErrorCode expectedStatus = maximizeErrors[i].uerror;
5284 const int32_t expectedLength = getExpectedReturnValue(&maximizeErrors[i]);
5285 const int32_t bufferSize = getBufferSize(&maximizeErrors[i], sizeof(buffer));
5286
5287 const int32_t length =
5288 uloc_addLikelySubtags(
5289 minimal,
5290 buffer,
5291 bufferSize,
5292 &status);
5293
5294 if (status == U_ZERO_ERROR) {
5295 log_err(" unexpected U_ZERO_ERROR for uloc_addLikelySubtags(), minimal \"%s\" expected status %s\n", minimal, u_errorName(expectedStatus));
5296 status = U_ZERO_ERROR;
5297 }
5298 else if (status != expectedStatus) {
5299 log_err(" unexpected status for uloc_addLikelySubtags(), minimal \"%s\" expected status %s, but got %s\n", minimal, u_errorName(expectedStatus), u_errorName(status));
5300 }
5301 else if (length != expectedLength) {
5302 log_err(" unexpected length for uloc_addLikelySubtags(), minimal \"%s\" expected length %d, but got %d\n", minimal, expectedLength, length);
5303 }
5304 else if (status == U_BUFFER_OVERFLOW_ERROR || status == U_STRING_NOT_TERMINATED_WARNING) {
5305 if (uprv_strnicmp(maximal, buffer, bufferSize) != 0) {
5306 log_err(" maximal doesn't match expected %s in uloc_addLikelySubtags(), minimal \"%s\" = %*s\n",
5307 maximal, minimal, (int)sizeof(buffer), buffer);
5308 }
5309 }
5310 }
5311
5312 for (i = 0; i < sizeof(minimizeErrors) / sizeof(minimizeErrors[0]); ++i) {
5313
5314 UErrorCode status = U_ZERO_ERROR;
5315 const char* const maximal = minimizeErrors[i].tag;
5316 const char* const minimal = minimizeErrors[i].expected;
5317 const UErrorCode expectedStatus = minimizeErrors[i].uerror;
5318 const int32_t expectedLength = getExpectedReturnValue(&minimizeErrors[i]);
5319 const int32_t bufferSize = getBufferSize(&minimizeErrors[i], sizeof(buffer));
5320
5321 const int32_t length =
5322 uloc_minimizeSubtags(
5323 maximal,
5324 buffer,
5325 bufferSize,
5326 &status);
5327
5328 if (status == U_ZERO_ERROR) {
5329 log_err(" unexpected U_ZERO_ERROR for uloc_minimizeSubtags(), maximal \"%s\" expected status %s\n", maximal, u_errorName(expectedStatus));
5330 status = U_ZERO_ERROR;
5331 }
5332 else if (status != expectedStatus) {
5333 log_err(" unexpected status for uloc_minimizeSubtags(), maximal \"%s\" expected status %s, but got %s\n", maximal, u_errorName(expectedStatus), u_errorName(status));
5334 }
5335 else if (length != expectedLength) {
5336 log_err(" unexpected length for uloc_minimizeSubtags(), maximal \"%s\" expected length %d, but got %d\n", maximal, expectedLength, length);
5337 }
5338 else if (status == U_BUFFER_OVERFLOW_ERROR || status == U_STRING_NOT_TERMINATED_WARNING) {
5339 if (uprv_strnicmp(minimal, buffer, bufferSize) != 0) {
5340 log_err(" minimal doesn't match expected \"%s\" in uloc_minimizeSubtags(), minimal \"%s\" = \"%*s\"\n",
5341 minimal, maximal, (int)sizeof(buffer), buffer);
5342 }
5343 }
5344 }
5345}