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