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