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