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