• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /********************************************************************
2  * COPYRIGHT:
3  * Copyright (c) 1997-2007, International Business Machines Corporation and
4  * others. All Rights Reserved.
5  ********************************************************************/
6 /*****************************************************************************
7 *
8 * File CLOCTST.C
9 *
10 * Modification History:
11 *        Name                     Description
12 *     Madhu Katragadda            Ported for C API
13 ******************************************************************************
14 */
15 #include "cloctst.h"
16 #include <stdlib.h>
17 #include <stdio.h>
18 #include <string.h>
19 #include "cintltst.h"
20 #include "cstring.h"
21 #include "uparse.h"
22 #include "uresimp.h"
23 
24 #include "unicode/putil.h"
25 #include "unicode/ubrk.h"
26 #include "unicode/uchar.h"
27 #include "unicode/ucol.h"
28 #include "unicode/udat.h"
29 #include "unicode/uloc.h"
30 #include "unicode/umsg.h"
31 #include "unicode/ures.h"
32 #include "unicode/uset.h"
33 #include "unicode/ustring.h"
34 #include "unicode/utypes.h"
35 #include "unicode/ulocdata.h"
36 #include "unicode/parseerr.h" /* may not be included with some uconfig switches */
37 #define LENGTHOF(array) (int32_t)(sizeof(array)/sizeof((array)[0]))
38 
39 static void TestNullDefault(void);
40 static void TestNonexistentLanguageExemplars(void);
41 static void TestLocDataErrorCodeChaining(void);
42 static void TestLanguageExemplarsFallbacks(void);
43 
44 void PrintDataTable();
45 
46 /*---------------------------------------------------
47   table of valid data
48  --------------------------------------------------- */
49 #define LOCALE_SIZE 9
50 #define LOCALE_INFO_SIZE 28
51 
52 static const char* const rawData2[LOCALE_INFO_SIZE][LOCALE_SIZE] = {
53     /* language code */
54     {   "en",   "fr",   "ca",   "el",   "no",   "zh",   "de",   "es",  "ja"    },
55     /* script code */
56     {   "",     "",     "",     "",     "",     "Hans", "", "", ""  },
57     /* country code */
58     {   "US",   "FR",   "ES",   "GR",   "NO",   "CN", "DE", "", "JP"    },
59     /* variant code */
60     {   "",     "",     "",     "",     "NY",   "", "", "", ""      },
61     /* full name */
62     {   "en_US",    "fr_FR",    "ca_ES",
63         "el_GR",    "no_NO_NY", "zh_Hans_CN",
64         "de_DE@collation=phonebook", "es@collation=traditional",  "ja_JP@calendar=japanese" },
65     /* ISO-3 language */
66     {   "eng",  "fra",  "cat",  "ell",  "nor",  "zho", "deu", "spa", "jpn"   },
67     /* ISO-3 country */
68     {   "USA",  "FRA",  "ESP",  "GRC",  "NOR",  "CHN", "DEU", "", "JPN"   },
69     /* LCID */
70     {   "409", "40c", "403", "408", "814",  "804", "10407", "40a", "411"     },
71 
72     /* display language (English) */
73     {   "English",  "French",   "Catalan", "Greek",    "Norwegian", "Chinese", "German", "Spanish", "Japanese"    },
74     /* display script code (English) */
75     {   "",     "",     "",     "",     "",     "Simplified Han", "", "", ""       },
76     /* display country (English) */
77     {   "United States",    "France",   "Spain",  "Greece",   "Norway", "China", "Germany", "", "Japan"       },
78     /* display variant (English) */
79     {   "",     "",     "",     "",     "NY",  "", "", "", ""       },
80     /* display name (English) */
81     {   "English (United States)", "French (France)", "Catalan (Spain)",
82         "Greek (Greece)", "Norwegian (Norway, NY)", "Chinese (Simplified Han, China)",
83         "German (Germany, collation=Phonebook Sort Order)", "Spanish (collation=Traditional Sort Order)", "Japanese (Japan, calendar=Japanese Calendar)" },
84 
85     /* display language (French) */
86     {   "anglais",  "fran\\u00E7ais",   "catalan", "grec",    "norv\\u00E9gien",    "chinois", "allemand", "espagnol", "japonais"     },
87     /* display script code (French) */
88     {   "",     "",     "",     "",     "",     "id\\u00e9ogrammes han (variante simplifi\\u00e9e)", "", "", ""         },
89     /* display country (French) */
90     {   "\\u00C9tats-Unis",    "France",   "Espagne",  "Gr\\u00E8ce",   "Norv\\u00E8ge",    "Chine", "Allemagne", "", "Japon"       },
91     /* display variant (French) */
92     {   "",     "",     "",     "",     "NY",   "", "", "", ""       },
93     /* display name (French) */
94     {   "anglais (\\u00C9tats-Unis)", "fran\\u00E7ais (France)", "catalan (Espagne)",
95         "grec (Gr\\u00E8ce)", "norv\\u00E9gien (Norv\\u00E8ge, NY)",  "chinois (id\\u00e9ogrammes han (variante simplifi\\u00e9e), Chine)",
96         "allemand (Allemagne, Ordonnancement=Ordre de l\\u2019annuaire)", "espagnol (Ordonnancement=Ordre traditionnel)", "japonais (Japon, Calendrier=Calendrier japonais)" },
97 
98     /* display language (Catalan) */
99     {   "angl\\u00E8s", "franc\\u00E8s", "catal\\u00E0", "grec",  "noruec", "xin\\u00E9s", "alemany", "espanyol", "japon\\u00E8s"    },
100     /* display script code (Catalan) */
101     {   "",     "",     "",     "",     "",     "Hans", "", "", ""         },
102     /* display country (Catalan) */
103     {   "Estats Units", "Fran\\u00E7a", "Espanya",  "Gr\\u00E8cia", "Noruega",  "Xina", "Alemanya", "", "Jap\\u00F3"    },
104     /* display variant (Catalan) */
105     {   "", "", "",                    "", "NY",    "", "", "", ""    },
106     /* display name (Catalan) */
107     {   "angl\\u00E8s (Estats Units)", "franc\\u00E8s (Fran\\u00E7a)", "catal\\u00E0 (Espanya)",
108     "grec (Gr\\u00E8cia)", "noruec (Noruega, NY)", "xin\\u00E9s (Hans, Xina)",
109     "alemany (Alemanya, collation=phonebook)", "espanyol (collation=traditional)", "japon\\u00E8s (Jap\\u00F3, calendar=japanese)" },
110 
111     /* display language (Greek) */
112     {
113         "\\u0391\\u03b3\\u03b3\\u03bb\\u03b9\\u03ba\\u03ac",
114         "\\u0393\\u03b1\\u03bb\\u03bb\\u03b9\\u03ba\\u03ac",
115         "\\u039a\\u03b1\\u03c4\\u03b1\\u03bb\\u03b1\\u03bd\\u03b9\\u03ba\\u03ac",
116         "\\u0395\\u03bb\\u03bb\\u03b7\\u03bd\\u03b9\\u03ba\\u03ac",
117         "\\u039d\\u03bf\\u03c1\\u03b2\\u03b7\\u03b3\\u03b9\\u03ba\\u03ac",
118         "\\u039A\\u03B9\\u03BD\\u03B5\\u03B6\\u03B9\\u03BA\\u03AC",
119         "\\u0393\\u03B5\\u03C1\\u03BC\\u03B1\\u03BD\\u03B9\\u03BA\\u03AC",
120         "\\u0399\\u03C3\\u03C0\\u03B1\\u03BD\\u03B9\\u03BA\\u03AC",
121         "\\u0399\\u03B1\\u03C0\\u03C9\\u03BD\\u03B9\\u03BA\\u03AC"
122     },
123     /* display script code (Greek) */
124 
125     {   "",     "",     "",     "",     "", "\\u039a\\u03b9\\u03bd\\u03b5\\u03b6\\u03b9\\u03ba\\u03cc \\u0391\\u03c0\\u03bb\\u03bf\\u03c0\\u03bf\\u03b9\\u03b7\\u03bc\\u03ad\\u03bd\\u03bf", "", "", "" },
126     /* display country (Greek) */
127     {
128         "\\u0397\\u03bd\\u03c9\\u03bc\\u03ad\\u03bd\\u03b5\\u03c2 \\u03a0\\u03bf\\u03bb\\u03b9\\u03c4\\u03b5\\u03af\\u03b5\\u03c2",
129         "\\u0393\\u03b1\\u03bb\\u03bb\\u03af\\u03b1",
130         "\\u0399\\u03c3\\u03c0\\u03b1\\u03bd\\u03af\\u03b1",
131         "\\u0395\\u03bb\\u03bb\\u03ac\\u03b4\\u03b1",
132         "\\u039d\\u03bf\\u03c1\\u03b2\\u03b7\\u03b3\\u03af\\u03b1",
133         "\\u039A\\u03AF\\u03BD\\u03B1",
134         "\\u0393\\u03B5\\u03C1\\u03BC\\u03B1\\u03BD\\u03AF\\u03B1",
135         "",
136         "\\u0399\\u03B1\\u03C0\\u03C9\\u03BD\\u03AF\\u03B1"
137     },
138     /* display variant (Greek) */
139     {   "", "", "", "", "NY", "", "", "", ""    }, /* TODO: currently there is no translation for NY in Greek fix this test when we have it */
140     /* display name (Greek) */
141     {
142         "\\u0391\\u03b3\\u03b3\\u03bb\\u03b9\\u03ba\\u03ac (\\u0397\\u03bd\\u03c9\\u03bc\\u03ad\\u03bd\\u03b5\\u03c2 \\u03a0\\u03bf\\u03bb\\u03b9\\u03c4\\u03b5\\u03af\\u03b5\\u03c2)",
143         "\\u0393\\u03b1\\u03bb\\u03bb\\u03b9\\u03ba\\u03ac (\\u0393\\u03b1\\u03bb\\u03bb\\u03af\\u03b1)",
144         "\\u039a\\u03b1\\u03c4\\u03b1\\u03bb\\u03b1\\u03bd\\u03b9\\u03ba\\u03ac (\\u0399\\u03c3\\u03c0\\u03b1\\u03bd\\u03af\\u03b1)",
145         "\\u0395\\u03bb\\u03bb\\u03b7\\u03bd\\u03b9\\u03ba\\u03ac (\\u0395\\u03bb\\u03bb\\u03ac\\u03b4\\u03b1)",
146         "\\u039d\\u03bf\\u03c1\\u03b2\\u03b7\\u03b3\\u03b9\\u03ba\\u03ac (\\u039d\\u03bf\\u03c1\\u03b2\\u03b7\\u03b3\\u03af\\u03b1, NY)",
147         "\\u039A\\u03B9\\u03BD\\u03B5\\u03B6\\u03B9\\u03BA\\u03AC (\\u039a\\u03b9\\u03bd\\u03b5\\u03b6\\u03b9\\u03ba\\u03cc \\u0391\\u03c0\\u03bb\\u03bf\\u03c0\\u03bf\\u03b9\\u03b7\\u03bc\\u03ad\\u03bd\\u03bf, \\u039A\\u03AF\\u03BD\\u03B1)",
148         "\\u0393\\u03B5\\u03C1\\u03BC\\u03B1\\u03BD\\u03B9\\u03BA\\u03AC (\\u0393\\u03B5\\u03C1\\u03BC\\u03B1\\u03BD\\u03AF\\u03B1, \\u03A4\\u03B1\\u03BA\\u03C4\\u03BF\\u03C0\\u03BF\\u03AF\\u03B7\\u03C3\\u03B7=\\u03A3\\u03B5\\u03B9\\u03C1\\u03AC \\u03A4\\u03B7\\u03BB\\u03B5\\u03C6\\u03C9\\u03BD\\u03B9\\u03BA\\u03BF\\u03CD \\u039A\\u03B1\\u03C4\\u03B1\\u03BB\\u03CC\\u03B3\\u03BF\\u03C5)",
149         "\\u0399\\u03C3\\u03C0\\u03B1\\u03BD\\u03B9\\u03BA\\u03AC (\\u03A4\\u03B1\\u03BA\\u03C4\\u03BF\\u03C0\\u03BF\\u03AF\\u03B7\\u03C3\\u03B7\\u003D\\u03A0\\u03B1\\u03C1\\u03B1\\u03B4\\u03BF\\u03C3\\u03B9\\u03B1\\u03BA\\u03AE \\u03A3\\u03B5\\u03B9\\u03C1\\u03AC)",
150         "\\u0399\\u03B1\\u03C0\\u03C9\\u03BD\\u03B9\\u03BA\\u03AC (\\u0399\\u03B1\\u03C0\\u03C9\\u03BD\\u03AF\\u03B1, \\u0397\\u03BC\\u03B5\\u03C1\\u03BF\\u03BB\\u03CC\\u03B3\\u03B9\\u03BF=\\u0399\\u03B1\\u03C0\\u03C9\\u03BD\\u03B9\\u03BA\\u03CC \\u0397\\u03BC\\u03B5\\u03C1\\u03BF\\u03BB\\u03CC\\u03B3\\u03B9\\u03BF)"
151     }
152 };
153 
154 static UChar*** dataTable=0;
155 enum {
156     ENGLISH = 0,
157     FRENCH = 1,
158     CATALAN = 2,
159     GREEK = 3,
160     NORWEGIAN = 4
161 };
162 
163 enum {
164     LANG = 0,
165     SCRIPT = 1,
166     CTRY = 2,
167     VAR = 3,
168     NAME = 4,
169     LANG3 = 5,
170     CTRY3 = 6,
171     LCID = 7,
172     DLANG_EN = 8,
173     DSCRIPT_EN = 9,
174     DCTRY_EN = 10,
175     DVAR_EN = 11,
176     DNAME_EN = 12,
177     DLANG_FR = 13,
178     DSCRIPT_FR = 14,
179     DCTRY_FR = 15,
180     DVAR_FR = 16,
181     DNAME_FR = 17,
182     DLANG_CA = 18,
183     DSCRIPT_CA = 19,
184     DCTRY_CA = 20,
185     DVAR_CA = 21,
186     DNAME_CA = 22,
187     DLANG_EL = 23,
188     DSCRIPT_EL = 24,
189     DCTRY_EL = 25,
190     DVAR_EL = 26,
191     DNAME_EL = 27
192 };
193 
194 #define TESTCASE(name) addTest(root, &name, "tsutil/cloctst/" #name)
195 
196 void addLocaleTest(TestNode** root);
197 
addLocaleTest(TestNode ** root)198 void addLocaleTest(TestNode** root)
199 {
200     TESTCASE(TestObsoleteNames); /* srl- move */
201     TESTCASE(TestBasicGetters);
202     TESTCASE(TestNullDefault);
203     TESTCASE(TestPrefixes);
204     TESTCASE(TestSimpleResourceInfo);
205     TESTCASE(TestDisplayNames);
206     TESTCASE(TestGetAvailableLocales);
207     TESTCASE(TestDataDirectory);
208     TESTCASE(TestISOFunctions);
209     TESTCASE(TestISO3Fallback);
210     TESTCASE(TestUninstalledISO3Names);
211     TESTCASE(TestSimpleDisplayNames);
212     TESTCASE(TestVariantParsing);
213     TESTCASE(TestKeywordVariants);
214     TESTCASE(TestKeywordVariantParsing);
215     TESTCASE(TestCanonicalization);
216     TESTCASE(TestKeywordSet);
217     TESTCASE(TestKeywordSetError);
218     TESTCASE(TestDisplayKeywords);
219     TESTCASE(TestDisplayKeywordValues);
220     TESTCASE(TestGetBaseName);
221     TESTCASE(TestGetLocale);
222     TESTCASE(TestDisplayNameWarning);
223     TESTCASE(TestNonexistentLanguageExemplars);
224     TESTCASE(TestLocDataErrorCodeChaining);
225     TESTCASE(TestLanguageExemplarsFallbacks);
226     TESTCASE(TestCalendar);
227     TESTCASE(TestDateFormat);
228     TESTCASE(TestCollation);
229     TESTCASE(TestULocale);
230     TESTCASE(TestUResourceBundle);
231     TESTCASE(TestDisplayName);
232     TESTCASE(TestAcceptLanguage);
233     TESTCASE(TestGetLocaleForLCID);
234 }
235 
236 
237 /* testing uloc(), uloc_getName(), uloc_getLanguage(), uloc_getVariant(), uloc_getCountry() */
TestBasicGetters()238 static void TestBasicGetters() {
239     int32_t i;
240     int32_t cap;
241     UErrorCode status = U_ZERO_ERROR;
242     char *testLocale = 0;
243     char *temp = 0, *name = 0;
244     log_verbose("Testing Basic Getters\n");
245     for (i = 0; i < LOCALE_SIZE; i++) {
246         testLocale=(char*)malloc(sizeof(char) * (strlen(rawData2[NAME][i])+1));
247         strcpy(testLocale,rawData2[NAME][i]);
248 
249         log_verbose("Testing   %s  .....\n", testLocale);
250         cap=uloc_getLanguage(testLocale, NULL, 0, &status);
251         if(status==U_BUFFER_OVERFLOW_ERROR){
252             status=U_ZERO_ERROR;
253             temp=(char*)malloc(sizeof(char) * (cap+1));
254             uloc_getLanguage(testLocale, temp, cap+1, &status);
255         }
256         if(U_FAILURE(status)){
257             log_err("ERROR: in uloc_getLanguage  %s\n", myErrorName(status));
258         }
259         if (0 !=strcmp(temp,rawData2[LANG][i]))    {
260             log_err("  Language code mismatch: %s versus  %s\n", temp, rawData2[LANG][i]);
261         }
262 
263 
264         cap=uloc_getCountry(testLocale, temp, cap, &status);
265         if(status==U_BUFFER_OVERFLOW_ERROR){
266             status=U_ZERO_ERROR;
267             temp=(char*)realloc(temp, sizeof(char) * (cap+1));
268             uloc_getCountry(testLocale, temp, cap+1, &status);
269         }
270         if(U_FAILURE(status)){
271             log_err("ERROR: in uloc_getCountry  %s\n", myErrorName(status));
272         }
273         if (0 != strcmp(temp, rawData2[CTRY][i])) {
274             log_err(" Country code mismatch:  %s  versus   %s\n", temp, rawData2[CTRY][i]);
275 
276           }
277 
278         cap=uloc_getVariant(testLocale, temp, cap, &status);
279         if(status==U_BUFFER_OVERFLOW_ERROR){
280             status=U_ZERO_ERROR;
281             temp=(char*)realloc(temp, sizeof(char) * (cap+1));
282             uloc_getVariant(testLocale, temp, cap+1, &status);
283         }
284         if(U_FAILURE(status)){
285             log_err("ERROR: in uloc_getVariant  %s\n", myErrorName(status));
286         }
287         if (0 != strcmp(temp, rawData2[VAR][i])) {
288             log_err("Variant code mismatch:  %s  versus   %s\n", temp, rawData2[VAR][i]);
289         }
290 
291         cap=uloc_getName(testLocale, NULL, 0, &status);
292         if(status==U_BUFFER_OVERFLOW_ERROR){
293             status=U_ZERO_ERROR;
294             name=(char*)malloc(sizeof(char) * (cap+1));
295             uloc_getName(testLocale, name, cap+1, &status);
296         } else if(status==U_ZERO_ERROR) {
297           log_err("ERROR: in uloc_getName(%s,NULL,0,..), expected U_BUFFER_OVERFLOW_ERROR!\n", testLocale);
298         }
299         if(U_FAILURE(status)){
300             log_err("ERROR: in uloc_getName   %s\n", myErrorName(status));
301         }
302         if (0 != strcmp(name, rawData2[NAME][i])){
303             log_err(" Mismatch in getName:  %s  versus   %s\n", name, rawData2[NAME][i]);
304         }
305 
306         free(temp);
307         free(name);
308 
309         free(testLocale);
310     }
311 }
312 
TestNullDefault()313 static void TestNullDefault() {
314     UErrorCode status = U_ZERO_ERROR;
315     char original[ULOC_FULLNAME_CAPACITY];
316 
317     uprv_strcpy(original, uloc_getDefault());
318     uloc_setDefault("qq_BLA", &status);
319     if (uprv_strcmp(uloc_getDefault(), "qq_BLA") != 0) {
320         log_err(" Mismatch in uloc_setDefault:  qq_BLA  versus   %s\n", uloc_getDefault());
321     }
322     uloc_setDefault(NULL, &status);
323     if (uprv_strcmp(uloc_getDefault(), original) != 0) {
324         log_err(" uloc_setDefault(NULL, &status) didn't get the default locale back!\n");
325     }
326 
327     {
328     /* Test that set & get of default locale work, and that
329      * default locales are cached and reused, and not overwritten.
330      */
331         const char *n_en_US;
332         const char *n_fr_FR;
333         const char *n2_en_US;
334 
335         status = U_ZERO_ERROR;
336         uloc_setDefault("en_US", &status);
337         n_en_US = uloc_getDefault();
338         if (strcmp(n_en_US, "en_US") != 0) {
339             log_err("Wrong result from uloc_getDefault().  Expected \"en_US\", got \"%s\"\n", n_en_US);
340         }
341 
342         uloc_setDefault("fr_FR", &status);
343         n_fr_FR = uloc_getDefault();
344         if (strcmp(n_en_US, "en_US") != 0) {
345             log_err("uloc_setDefault altered previously default string."
346                 "Expected \"en_US\", got \"%s\"\n",  n_en_US);
347         }
348         if (strcmp(n_fr_FR, "fr_FR") != 0) {
349             log_err("Wrong result from uloc_getDefault().  Expected \"fr_FR\", got %s\n",  n_fr_FR);
350         }
351 
352         uloc_setDefault("en_US", &status);
353         n2_en_US = uloc_getDefault();
354         if (strcmp(n2_en_US, "en_US") != 0) {
355             log_err("Wrong result from uloc_getDefault().  Expected \"en_US\", got \"%s\"\n", n_en_US);
356         }
357         if (n2_en_US != n_en_US) {
358             log_err("Default locale cache failed to reuse en_US locale.\n");
359         }
360 
361         if (U_FAILURE(status)) {
362             log_err("Failure returned from uloc_setDefault - \"%s\"\n", u_errorName(status));
363         }
364 
365     }
366 
367 }
368 /* Test the i- and x- and @ and . functionality
369 */
370 
371 #define PREFIXBUFSIZ 128
372 
TestPrefixes()373 static void TestPrefixes() {
374     int row = 0;
375     int n;
376     const char *loc, *expected;
377 
378     static const char * const testData[][7] =
379     {
380         /* NULL canonicalize() column means "expect same as getName()" */
381         {"sv", "", "FI", "AL", "sv-fi-al", "sv_FI_AL", NULL},
382         {"en", "", "GB", "", "en-gb", "en_GB", NULL},
383         {"i-hakka", "", "MT", "XEMXIJA", "i-hakka_MT_XEMXIJA", "i-hakka_MT_XEMXIJA", NULL},
384         {"i-hakka", "", "CN", "", "i-hakka_CN", "i-hakka_CN", NULL},
385         {"i-hakka", "", "MX", "", "I-hakka_MX", "i-hakka_MX", NULL},
386         {"x-klingon", "", "US", "SANJOSE", "X-KLINGON_us_SANJOSE", "x-klingon_US_SANJOSE", NULL},
387 
388         {"mr", "", "", "", "mr.utf8", "mr.utf8", "mr"},
389         {"de", "", "TV", "", "de-tv.koi8r", "de_TV.koi8r", "de_TV"},
390         {"x-piglatin", "", "ML", "", "x-piglatin_ML.MBE", "x-piglatin_ML.MBE", "x-piglatin_ML"},  /* Multibyte English */
391         {"i-cherokee", "","US", "", "i-Cherokee_US.utf7", "i-cherokee_US.utf7", "i-cherokee_US"},
392         {"x-filfli", "", "MT", "FILFLA", "x-filfli_MT_FILFLA.gb-18030", "x-filfli_MT_FILFLA.gb-18030", "x-filfli_MT_FILFLA"},
393         {"no", "", "NO", "NY", "no-no-ny.utf32@B", "no_NO_NY.utf32@B", "no_NO_NY_B"},
394         {"no", "", "NO", "",  "no-no.utf32@B", "no_NO.utf32@B", "no_NO_B"},
395         {"no", "", "",   "NY", "no__ny", "no__NY", NULL},
396         {"no", "", "",   "", "no@ny", "no@ny", "no__NY"},
397         {"el", "Latn", "", "", "el-latn", "el_Latn", NULL},
398         {"en", "Cyrl", "RU", "", "en-cyrl-ru", "en_Cyrl_RU", NULL},
399         {"zh", "Hant", "TW", "STROKE", "zh-hant_TW_STROKE", "zh_Hant_TW_STROKE", NULL},
400         {"qq", "Qqqq", "QQ", "QQ", "qq_Qqqq_QQ_QQ", "qq_Qqqq_QQ_QQ", NULL},
401         {"qq", "Qqqq", "", "QQ", "qq_Qqqq__QQ", "qq_Qqqq__QQ", NULL},
402         {"12", "3456", "78", "90", "12_3456_78_90", "12_3456_78_90", NULL}, /* total garbage */
403 
404         {NULL,NULL,NULL,NULL,NULL,NULL,NULL}
405     };
406 
407     static const char * const testTitles[] = {
408         "uloc_getLanguage()",
409         "uloc_getScript()",
410         "uloc_getCountry()",
411         "uloc_getVariant()",
412         "name",
413         "uloc_getName()",
414         "uloc_canonicalize()"
415     };
416 
417     char buf[PREFIXBUFSIZ];
418     int32_t len;
419     UErrorCode err;
420 
421 
422     for(row=0;testData[row][0] != NULL;row++) {
423         loc = testData[row][NAME];
424         log_verbose("Test #%d: %s\n", row, loc);
425 
426         err = U_ZERO_ERROR;
427         len=0;
428         buf[0]=0;
429         for(n=0;n<=(NAME+2);n++) {
430             if(n==NAME) continue;
431 
432             for(len=0;len<PREFIXBUFSIZ;len++) {
433                 buf[len] = '%'; /* Set a tripwire.. */
434             }
435             len = 0;
436 
437             switch(n) {
438             case LANG:
439                 len = uloc_getLanguage(loc, buf, PREFIXBUFSIZ, &err);
440                 break;
441 
442             case SCRIPT:
443                 len = uloc_getScript(loc, buf, PREFIXBUFSIZ, &err);
444                 break;
445 
446             case CTRY:
447                 len = uloc_getCountry(loc, buf, PREFIXBUFSIZ, &err);
448                 break;
449 
450             case VAR:
451                 len = uloc_getVariant(loc, buf, PREFIXBUFSIZ, &err);
452                 break;
453 
454             case NAME+1:
455                 len = uloc_getName(loc, buf, PREFIXBUFSIZ, &err);
456                 break;
457 
458             case NAME+2:
459                 len = uloc_canonicalize(loc, buf, PREFIXBUFSIZ, &err);
460                 break;
461 
462             default:
463                 strcpy(buf, "**??");
464                 len=4;
465             }
466 
467             if(U_FAILURE(err)) {
468                 log_err("#%d: %s on %s: err %s\n",
469                     row, testTitles[n], loc, u_errorName(err));
470             } else {
471                 log_verbose("#%d: %s on %s: -> [%s] (length %d)\n",
472                     row, testTitles[n], loc, buf, len);
473 
474                 if(len != (int32_t)strlen(buf)) {
475                     log_err("#%d: %s on %s: -> [%s] (length returned %d, actual %d!)\n",
476                         row, testTitles[n], loc, buf, len, strlen(buf)+1);
477 
478                 }
479 
480                 /* see if they smashed something */
481                 if(buf[len+1] != '%') {
482                     log_err("#%d: %s on %s: -> [%s] - wrote [%X] out ofbounds!\n",
483                         row, testTitles[n], loc, buf, buf[len+1]);
484                 }
485 
486                 expected = testData[row][n];
487                 if (expected == NULL && n == (NAME+2)) {
488                     /* NULL expected canonicalize() means "expect same as getName()" */
489                     expected = testData[row][NAME+1];
490                 }
491                 if(strcmp(buf, expected)) {
492                     log_err("#%d: %s on %s: -> [%s] (expected '%s'!)\n",
493                         row, testTitles[n], loc, buf, expected);
494 
495                 }
496             }
497         }
498     }
499 }
500 
501 
502 /* testing uloc_getISO3Language(), uloc_getISO3Country(),  */
TestSimpleResourceInfo()503 static void TestSimpleResourceInfo() {
504     int32_t i;
505     char* testLocale = 0;
506     UChar* expected = 0;
507 
508     const char* temp;
509     char            temp2[20];
510     testLocale=(char*)malloc(sizeof(char) * 1);
511     expected=(UChar*)malloc(sizeof(UChar) * 1);
512 
513     setUpDataTable();
514     log_verbose("Testing getISO3Language and getISO3Country\n");
515     for (i = 0; i < LOCALE_SIZE; i++) {
516 
517         testLocale=(char*)realloc(testLocale, sizeof(char) * (u_strlen(dataTable[NAME][i])+1));
518         u_austrcpy(testLocale, dataTable[NAME][i]);
519 
520         log_verbose("Testing   %s ......\n", testLocale);
521 
522         temp=uloc_getISO3Language(testLocale);
523         expected=(UChar*)realloc(expected, sizeof(UChar) * (strlen(temp) + 1));
524         u_uastrcpy(expected,temp);
525         if (0 != u_strcmp(expected, dataTable[LANG3][i])) {
526             log_err("  ISO-3 language code mismatch:  %s versus  %s\n",  austrdup(expected),
527                 austrdup(dataTable[LANG3][i]));
528         }
529 
530         temp=uloc_getISO3Country(testLocale);
531         expected=(UChar*)realloc(expected, sizeof(UChar) * (strlen(temp) + 1));
532         u_uastrcpy(expected,temp);
533         if (0 != u_strcmp(expected, dataTable[CTRY3][i])) {
534             log_err("  ISO-3 Country code mismatch:  %s versus  %s\n",  austrdup(expected),
535                 austrdup(dataTable[CTRY3][i]));
536         }
537         sprintf(temp2, "%x", (int)uloc_getLCID(testLocale));
538         if (strcmp(temp2, rawData2[LCID][i]) != 0) {
539             log_err("LCID mismatch: %s versus %s\n", temp2 , rawData2[LCID][i]);
540         }
541     }
542 
543     free(expected);
544     free(testLocale);
545     cleanUpDataTable();
546 }
547 
548 /*
549  * Jitterbug 2439 -- markus 20030425
550  *
551  * The lookup of display names must not fall back through the default
552  * locale because that yields useless results.
553  */
TestDisplayNames()554 static void TestDisplayNames()
555 {
556     UChar buffer[100];
557     UErrorCode errorCode=U_ZERO_ERROR;
558     int32_t length;
559     log_verbose("Testing getDisplayName for different locales\n");
560 
561     log_verbose("  In locale = en_US...\n");
562     doTestDisplayNames("en_US", DLANG_EN);
563     log_verbose("  In locale = fr_FR....\n");
564     doTestDisplayNames("fr_FR", DLANG_FR);
565     log_verbose("  In locale = ca_ES...\n");
566     doTestDisplayNames("ca_ES", DLANG_CA);
567     log_verbose("  In locale = gr_EL..\n");
568     doTestDisplayNames("el_GR", DLANG_EL);
569 
570     /* test that the default locale has a display name for its own language */
571     errorCode=U_ZERO_ERROR;
572     length=uloc_getDisplayLanguage(NULL, NULL, buffer, LENGTHOF(buffer), &errorCode);
573     if(U_FAILURE(errorCode) || (length<=3 && buffer[0]<=0x7f)) {
574         /* check <=3 to reject getting the language code as a display name */
575         log_err("unable to get a display string for the language of the default locale - %s\n", u_errorName(errorCode));
576     }
577 
578     /* test that we get the language code itself for an unknown language, and a default warning */
579     errorCode=U_ZERO_ERROR;
580     length=uloc_getDisplayLanguage("qq", "rr", buffer, LENGTHOF(buffer), &errorCode);
581     if(errorCode!=U_USING_DEFAULT_WARNING || length!=2 || buffer[0]!=0x71 || buffer[1]!=0x71) {
582         log_err("error getting the display string for an unknown language - %s\n", u_errorName(errorCode));
583     }
584 
585     /* test that we get a default warning for a display name where one component is unknown (4255) */
586     errorCode=U_ZERO_ERROR;
587     length=uloc_getDisplayName("qq_US_POSIX", "en_US", buffer, LENGTHOF(buffer), &errorCode);
588     if(errorCode!=U_USING_DEFAULT_WARNING) {
589         log_err("error getting the display name for a locale with an unknown language - %s\n", u_errorName(errorCode));
590     }
591 
592     {
593         int32_t i;
594         static const char *aLocale = "es@collation=traditional;calendar=japanese";
595         static const char *testL[] = { "en_US",
596             "fr_FR",
597             "ca_ES",
598             "el_GR" };
599         static const char *expect[] = { "Spanish (calendar=Japanese Calendar, collation=Traditional Sort Order)", /* note sorted order of keywords */
600             "espagnol (Calendrier=Calendrier japonais, Ordonnancement=Ordre traditionnel)",
601             "espanyol (calendar=japanese, collation=traditional)",
602             "\\u0399\\u03C3\\u03C0\\u03B1\\u03BD\\u03B9\\u03BA\\u03AC (\\u0397\\u03BC\\u03B5\\u03C1\\u03BF\\u03BB\\u03CC\\u03B3\\u03B9\\u03BF=\\u0399\\u03B1\\u03C0\\u03C9\\u03BD\\u03B9\\u03BA\\u03CC \\u0397\\u03BC\\u03B5\\u03C1\\u03BF\\u03BB\\u03CC\\u03B3\\u03B9\\u03BF, \\u03A4\\u03B1\\u03BA\\u03C4\\u03BF\\u03C0\\u03BF\\u03AF\\u03B7\\u03C3\\u03B7=\\u03A0\\u03B1\\u03C1\\u03B1\\u03B4\\u03BF\\u03C3\\u03B9\\u03B1\\u03BA\\u03AE \\u03A3\\u03B5\\u03B9\\u03C1\\u03AC)" };
603         UChar *expectBuffer;
604 
605         for(i=0;i<LENGTHOF(testL);i++) {
606             errorCode = U_ZERO_ERROR;
607             uloc_getDisplayName(aLocale, testL[i], buffer, LENGTHOF(buffer), &errorCode);
608             if(U_FAILURE(errorCode)) {
609                 log_err("FAIL in uloc_getDisplayName(%s,%s,..) -> %s\n", aLocale, testL[i], u_errorName(errorCode));
610             } else {
611                 expectBuffer = CharsToUChars(expect[i]);
612                 if(u_strcmp(buffer,expectBuffer)) {
613                     log_err("FAIL in uloc_getDisplayName(%s,%s,..) expected '%s' got '%s'\n", aLocale, testL[i], expect[i], austrdup(buffer));
614                 } else {
615                     log_verbose("pass in uloc_getDisplayName(%s,%s,..) got '%s'\n", aLocale, testL[i], expect[i]);
616                 }
617                 free(expectBuffer);
618             }
619         }
620     }
621 }
622 
623 
624 /* test for uloc_getAvialable()  and uloc_countAvilable()*/
TestGetAvailableLocales()625 static void TestGetAvailableLocales()
626 {
627 
628     const char *locList;
629     int32_t locCount,i;
630 
631     log_verbose("Testing the no of avialable locales\n");
632     locCount=uloc_countAvailable();
633     if (locCount == 0)
634         log_data_err("countAvailable() returned an empty list!\n");
635 
636     /* use something sensible w/o hardcoding the count */
637     else if(locCount < 0){
638         log_data_err("countAvailable() returned a wrong value!= %d\n", locCount);
639     }
640     else{
641         log_info("Number of locales returned = %d\n", locCount);
642     }
643     for(i=0;i<locCount;i++){
644         locList=uloc_getAvailable(i);
645 
646         log_verbose(" %s\n", locList);
647     }
648 }
649 
650 /* test for u_getDataDirectory, u_setDataDirectory, uloc_getISO3Language */
TestDataDirectory()651 static void TestDataDirectory()
652 {
653 
654     char            oldDirectory[512];
655     const char     *temp,*testValue1,*testValue2,*testValue3;
656     const char path[40] ="d:\\icu\\source\\test\\intltest" U_FILE_SEP_STRING; /*give the required path */
657 
658     log_verbose("Testing getDataDirectory()\n");
659     temp = u_getDataDirectory();
660     strcpy(oldDirectory, temp);
661 
662     testValue1=uloc_getISO3Language("en_US");
663     log_verbose("first fetch of language retrieved  %s\n", testValue1);
664 
665     if (0 != strcmp(testValue1,"eng")){
666         log_err("Initial check of ISO3 language failed: expected \"eng\", got  %s \n", testValue1);
667     }
668 
669     /*defining the path for DataDirectory */
670     log_verbose("Testing setDataDirectory\n");
671     u_setDataDirectory( path );
672     if(strcmp(path, u_getDataDirectory())==0)
673         log_verbose("setDataDirectory working fine\n");
674     else
675         log_err("Error in setDataDirectory. Directory not set correctly - came back as [%s], expected [%s]\n", u_getDataDirectory(), path);
676 
677     testValue2=uloc_getISO3Language("en_US");
678     log_verbose("second fetch of language retrieved  %s \n", testValue2);
679 
680     u_setDataDirectory(oldDirectory);
681     testValue3=uloc_getISO3Language("en_US");
682     log_verbose("third fetch of language retrieved  %s \n", testValue3);
683 
684     if (0 != strcmp(testValue3,"eng")) {
685        log_err("get/setDataDirectory() failed: expected \"eng\", got \" %s  \" \n", testValue3);
686     }
687 }
688 
689 
690 
691 /*=========================================================== */
692 
693 static UChar _NUL=0;
694 
doTestDisplayNames(const char * displayLocale,int32_t compareIndex)695 static void doTestDisplayNames(const char* displayLocale, int32_t compareIndex)
696 {
697     UErrorCode status = U_ZERO_ERROR;
698     int32_t i;
699     int32_t maxresultsize;
700 
701     const char *testLocale;
702 
703 
704     UChar  *testLang  = 0;
705     UChar  *testScript  = 0;
706     UChar  *testCtry = 0;
707     UChar  *testVar = 0;
708     UChar  *testName = 0;
709 
710 
711     UChar*  expectedLang = 0;
712     UChar*  expectedScript = 0;
713     UChar*  expectedCtry = 0;
714     UChar*  expectedVar = 0;
715     UChar*  expectedName = 0;
716 
717 setUpDataTable();
718 
719     for(i=0;i<LOCALE_SIZE; ++i)
720     {
721         testLocale=rawData2[NAME][i];
722 
723         log_verbose("Testing.....  %s\n", testLocale);
724 
725         maxresultsize=0;
726         maxresultsize=uloc_getDisplayLanguage(testLocale, displayLocale, NULL, maxresultsize, &status);
727         if(status==U_BUFFER_OVERFLOW_ERROR)
728         {
729             status=U_ZERO_ERROR;
730             testLang=(UChar*)malloc(sizeof(UChar) * (maxresultsize+1));
731             uloc_getDisplayLanguage(testLocale, displayLocale, testLang, maxresultsize + 1, &status);
732         }
733         else
734         {
735             testLang=&_NUL;
736         }
737         if(U_FAILURE(status)){
738             log_err("Error in getDisplayLanguage()  %s\n", myErrorName(status));
739         }
740 
741         maxresultsize=0;
742         maxresultsize=uloc_getDisplayScript(testLocale, displayLocale, NULL, maxresultsize, &status);
743         if(status==U_BUFFER_OVERFLOW_ERROR)
744         {
745             status=U_ZERO_ERROR;
746             testScript=(UChar*)malloc(sizeof(UChar) * (maxresultsize+1));
747             uloc_getDisplayScript(testLocale, displayLocale, testScript, maxresultsize + 1, &status);
748         }
749         else
750         {
751             testScript=&_NUL;
752         }
753         if(U_FAILURE(status)){
754             log_err("Error in getDisplayScript()  %s\n", myErrorName(status));
755         }
756 
757         maxresultsize=0;
758         maxresultsize=uloc_getDisplayCountry(testLocale, displayLocale, NULL, maxresultsize, &status);
759         if(status==U_BUFFER_OVERFLOW_ERROR)
760         {
761             status=U_ZERO_ERROR;
762             testCtry=(UChar*)malloc(sizeof(UChar) * (maxresultsize+1));
763             uloc_getDisplayCountry(testLocale, displayLocale, testCtry, maxresultsize + 1, &status);
764         }
765         else
766         {
767             testCtry=&_NUL;
768         }
769         if(U_FAILURE(status)){
770             log_err("Error in getDisplayCountry()  %s\n", myErrorName(status));
771         }
772 
773         maxresultsize=0;
774         maxresultsize=uloc_getDisplayVariant(testLocale, displayLocale, NULL, maxresultsize, &status);
775         if(status==U_BUFFER_OVERFLOW_ERROR)
776         {
777             status=U_ZERO_ERROR;
778             testVar=(UChar*)malloc(sizeof(UChar) * (maxresultsize+1));
779             uloc_getDisplayVariant(testLocale, displayLocale, testVar, maxresultsize + 1, &status);
780         }
781         else
782         {
783             testVar=&_NUL;
784         }
785         if(U_FAILURE(status)){
786                 log_err("Error in getDisplayVariant()  %s\n", myErrorName(status));
787         }
788 
789         maxresultsize=0;
790         maxresultsize=uloc_getDisplayName(testLocale, displayLocale, NULL, maxresultsize, &status);
791         if(status==U_BUFFER_OVERFLOW_ERROR)
792         {
793             status=U_ZERO_ERROR;
794             testName=(UChar*)malloc(sizeof(UChar) * (maxresultsize+1));
795             uloc_getDisplayName(testLocale, displayLocale, testName, maxresultsize + 1, &status);
796         }
797         else
798         {
799             testName=&_NUL;
800         }
801         if(U_FAILURE(status)){
802             log_err("Error in getDisplayName()  %s\n", myErrorName(status));
803         }
804 
805         expectedLang=dataTable[compareIndex][i];
806         if(u_strlen(expectedLang)== 0)
807             expectedLang=dataTable[DLANG_EN][i];
808 
809         expectedScript=dataTable[compareIndex + 1][i];
810         if(u_strlen(expectedScript)== 0)
811             expectedScript=dataTable[DSCRIPT_EN][i];
812 
813         expectedCtry=dataTable[compareIndex + 2][i];
814         if(u_strlen(expectedCtry)== 0)
815             expectedCtry=dataTable[DCTRY_EN][i];
816 
817         expectedVar=dataTable[compareIndex + 3][i];
818         if(u_strlen(expectedVar)== 0)
819             expectedVar=dataTable[DVAR_EN][i];
820 
821         expectedName=dataTable[compareIndex + 4][i];
822         if(u_strlen(expectedName) == 0)
823             expectedName=dataTable[DNAME_EN][i];
824 
825         if (0 !=u_strcmp(testLang,expectedLang))  {
826             log_data_err(" Display Language mismatch: got %s expected %s displayLocale=%s\n", austrdup(testLang), austrdup(expectedLang), displayLocale);
827         }
828 
829         if (0 != u_strcmp(testScript,expectedScript))   {
830             log_data_err(" Display Script mismatch: got %s expected %s displayLocale=%s\n", austrdup(testScript), austrdup(expectedScript), displayLocale);
831         }
832 
833         if (0 != u_strcmp(testCtry,expectedCtry))   {
834             log_data_err(" Display Country mismatch: got %s expected %s displayLocale=%s\n", austrdup(testCtry), austrdup(expectedCtry), displayLocale);
835         }
836 
837         if (0 != u_strcmp(testVar,expectedVar))    {
838             log_data_err(" Display Variant mismatch: got %s expected %s displayLocale=%s\n", austrdup(testVar), austrdup(expectedVar), displayLocale);
839         }
840 
841         if(0 != u_strcmp(testName, expectedName))    {
842             log_data_err(" Display Name mismatch: got %s expected %s displayLocale=%s\n", austrdup(testName), austrdup(expectedName), displayLocale);
843         }
844 
845         if(testName!=&_NUL) {
846             free(testName);
847         }
848         if(testLang!=&_NUL) {
849             free(testLang);
850         }
851         if(testScript!=&_NUL) {
852             free(testScript);
853         }
854         if(testCtry!=&_NUL) {
855             free(testCtry);
856         }
857         if(testVar!=&_NUL) {
858             free(testVar);
859         }
860     }
861 cleanUpDataTable();
862 }
863 
864 /* test for uloc_getISOLanguages, uloc_getISOCountries */
TestISOFunctions()865 static void TestISOFunctions()
866 {
867     const char* const* str=uloc_getISOLanguages();
868     const char* const* str1=uloc_getISOCountries();
869     const char* test;
870     const char *key = NULL;
871     int32_t count = 0, skipped = 0;
872     int32_t expect;
873     UResourceBundle *res;
874     UResourceBundle *subRes;
875     UErrorCode status = U_ZERO_ERROR;
876 
877     /*  test getISOLanguages*/
878     /*str=uloc_getISOLanguages(); */
879     log_verbose("Testing ISO Languages: \n");
880 
881     /* use structLocale - this data is no longer in root */
882     res = ures_openDirect(loadTestData(&status), "structLocale", &status);
883     subRes = ures_getByKey(res, "Languages", NULL, &status);
884     if (U_FAILURE(status)) {
885         log_err("There is an error in structLocale's ures_getByKey(\"Languages\"), status=%s\n", u_errorName(status));
886         return;
887     }
888 
889     expect = ures_getSize(subRes);
890     for(count = 0; *(str+count) != 0; count++)
891     {
892         key = NULL;
893         test = *(str+count);
894         status = U_ZERO_ERROR;
895 
896         do {
897             /* Skip over language tags. This API only returns language codes. */
898             skipped += (key != NULL);
899             ures_getNextString(subRes, NULL, &key, &status);
900         }
901         while (key != NULL && strchr(key, '_'));
902 
903         if(key == NULL)
904             break;
905         /* TODO: Consider removing sh, which is deprecated */
906         if(strcmp(key,"root") == 0 || strcmp(key,"Fallback") == 0 || strcmp(key,"sh") == 0) {
907             ures_getNextString(subRes, NULL, &key, &status);
908             skipped++;
909         }
910 #if U_CHARSET_FAMILY==U_ASCII_FAMILY
911         /* This code only works on ASCII machines where the keys are stored in ASCII order */
912         if(strcmp(test,key)) {
913             /* The first difference usually implies the place where things get out of sync */
914             log_err("FAIL Language diff at offset %d, \"%s\" != \"%s\"\n", count, test, key);
915         }
916 #endif
917 
918         if(!strcmp(test,"in"))
919             log_err("FAIL getISOLanguages() has obsolete language code %s\n", test);
920         if(!strcmp(test,"iw"))
921             log_err("FAIL getISOLanguages() has obsolete language code %s\n", test);
922         if(!strcmp(test,"ji"))
923             log_err("FAIL getISOLanguages() has obsolete language code %s\n", test);
924         if(!strcmp(test,"jw"))
925             log_err("FAIL getISOLanguages() has obsolete language code %s\n", test);
926         if(!strcmp(test,"sh"))
927             log_err("FAIL getISOLanguages() has obsolete language code %s\n", test);
928     }
929 
930     expect -= skipped; /* Ignore the skipped resources from structLocale */
931 
932     if(count!=expect) {
933         log_err("There is an error in getISOLanguages, got %d, expected %d (as per structLocale)\n", count, expect);
934     }
935 
936     subRes = ures_getByKey(res, "Countries", subRes, &status);
937     log_verbose("Testing ISO Countries");
938     skipped = 0;
939     expect = ures_getSize(subRes) - 1; /* Skip ZZ */
940     for(count = 0; *(str1+count) != 0; count++)
941     {
942         key = NULL;
943         test = *(str1+count);
944         do {
945             /* Skip over numeric UN tags. This API only returns ISO-3166 codes. */
946             skipped += (key != NULL);
947             ures_getNextString(subRes, NULL, &key, &status);
948         }
949         while (key != NULL && strlen(key) != 2);
950 
951         if(key == NULL)
952             break;
953         /* TODO: Consider removing CS, which is deprecated */
954         while(strcmp(key,"QO") == 0 || strcmp(key,"QU") == 0 || strcmp(key,"CS") == 0) {
955             ures_getNextString(subRes, NULL, &key, &status);
956             skipped++;
957         }
958 #if U_CHARSET_FAMILY==U_ASCII_FAMILY
959         /* This code only works on ASCII machines where the keys are stored in ASCII order */
960         if(strcmp(test,key)) {
961             /* The first difference usually implies the place where things get out of sync */
962             log_err("FAIL Country diff at offset %d, \"%s\" != \"%s\"\n", count, test, key);
963         }
964 #endif
965         if(!strcmp(test,"FX"))
966             log_err("FAIL getISOCountries() has obsolete country code %s\n", test);
967         if(!strcmp(test,"YU"))
968             log_err("FAIL getISOCountries() has obsolete country code %s\n", test);
969         if(!strcmp(test,"ZR"))
970             log_err("FAIL getISOCountries() has obsolete country code %s\n", test);
971     }
972 
973     ures_getNextString(subRes, NULL, &key, &status);
974     if (strcmp(key, "ZZ") != 0) {
975         log_err("ZZ was expected to be the last entry in structLocale, but got %s\n", key);
976     }
977 #if U_CHARSET_FAMILY==U_EBCDIC_FAMILY
978     /* On EBCDIC machines, the numbers are sorted last. Account for those in the skipped value too. */
979     key = NULL;
980     do {
981         /* Skip over numeric UN tags. uloc_getISOCountries only returns ISO-3166 codes. */
982         skipped += (key != NULL);
983         ures_getNextString(subRes, NULL, &key, &status);
984     }
985     while (U_SUCCESS(status) && key != NULL && strlen(key) != 2);
986 #endif
987     expect -= skipped; /* Ignore the skipped resources from structLocale */
988     if(count!=expect)
989     {
990         log_err("There is an error in getISOCountries, got %d, expected %d \n", count, expect);
991     }
992     ures_close(subRes);
993     ures_close(res);
994 }
995 
setUpDataTable()996 static void setUpDataTable()
997 {
998     int32_t i,j;
999     dataTable = (UChar***)(calloc(sizeof(UChar**),LOCALE_INFO_SIZE));
1000 
1001     for (i = 0; i < LOCALE_INFO_SIZE; i++) {
1002         dataTable[i] = (UChar**)(calloc(sizeof(UChar*),LOCALE_SIZE));
1003         for (j = 0; j < LOCALE_SIZE; j++){
1004             dataTable[i][j] = CharsToUChars(rawData2[i][j]);
1005         }
1006     }
1007 }
1008 
cleanUpDataTable()1009 static void cleanUpDataTable()
1010 {
1011     int32_t i,j;
1012     if(dataTable != NULL) {
1013         for (i=0; i<LOCALE_INFO_SIZE; i++) {
1014             for(j = 0; j < LOCALE_SIZE; j++) {
1015                 free(dataTable[i][j]);
1016             }
1017             free(dataTable[i]);
1018         }
1019         free(dataTable);
1020     }
1021     dataTable = NULL;
1022 }
1023 
1024 /**
1025  * @bug 4011756 4011380
1026  */
TestISO3Fallback()1027 static void TestISO3Fallback()
1028 {
1029     const char* test="xx_YY";
1030 
1031     const char * result;
1032 
1033     result = uloc_getISO3Language(test);
1034 
1035     /* Conform to C API usage  */
1036 
1037     if (!result || (result[0] != 0))
1038        log_err("getISO3Language() on xx_YY returned %s instead of \"\"");
1039 
1040     result = uloc_getISO3Country(test);
1041 
1042     if (!result || (result[0] != 0))
1043         log_err("getISO3Country() on xx_YY returned %s instead of \"\"");
1044 }
1045 
1046 /**
1047  * @bug 4118587
1048  */
TestSimpleDisplayNames()1049 static void TestSimpleDisplayNames()
1050 {
1051   /*
1052      This test is different from TestDisplayNames because TestDisplayNames checks
1053      fallback behavior, combination of language and country names to form locale
1054      names, and other stuff like that.  This test just checks specific language
1055      and country codes to make sure we have the correct names for them.
1056   */
1057     char languageCodes[] [4] = { "he", "id", "iu", "ug", "yi", "za" };
1058     const char* languageNames [] = { "Hebrew", "Indonesian", "Inuktitut", "Uighur", "Yiddish",
1059                                "Zhuang" };
1060     UErrorCode status=U_ZERO_ERROR;
1061 
1062     int32_t i;
1063     for (i = 0; i < 6; i++) {
1064         UChar *testLang=0;
1065         UChar *expectedLang=0;
1066         int size=0;
1067         size=uloc_getDisplayLanguage(languageCodes[i], "en_US", NULL, size, &status);
1068         if(status==U_BUFFER_OVERFLOW_ERROR) {
1069             status=U_ZERO_ERROR;
1070             testLang=(UChar*)malloc(sizeof(UChar) * (size + 1));
1071             uloc_getDisplayLanguage(languageCodes[i], "en_US", testLang, size + 1, &status);
1072         }
1073         expectedLang=(UChar*)malloc(sizeof(UChar) * (strlen(languageNames[i])+1));
1074         u_uastrcpy(expectedLang, languageNames[i]);
1075         if (u_strcmp(testLang, expectedLang) != 0)
1076             log_data_err("Got wrong display name for %s : Expected \"%s\", got \"%s\".\n",
1077                     languageCodes[i], languageNames[i], austrdup(testLang));
1078         free(testLang);
1079         free(expectedLang);
1080     }
1081 
1082 }
1083 
1084 /**
1085  * @bug 4118595
1086  */
TestUninstalledISO3Names()1087 static void TestUninstalledISO3Names()
1088 {
1089   /* This test checks to make sure getISO3Language and getISO3Country work right
1090      even for locales that are not installed. */
1091     static const char iso2Languages [][4] = {     "am", "ba", "fy", "mr", "rn",
1092                                         "ss", "tw", "zu" };
1093     static const char iso3Languages [][5] = {     "amh", "bak", "fry", "mar", "run",
1094                                         "ssw", "twi", "zul" };
1095     static const char iso2Countries [][6] = {     "am_AF", "ba_BW", "fy_KZ", "mr_MO", "rn_MN",
1096                                         "ss_SB", "tw_TC", "zu_ZW" };
1097     static const char iso3Countries [][4] = {     "AFG", "BWA", "KAZ", "MAC", "MNG",
1098                                         "SLB", "TCA", "ZWE" };
1099     int32_t i;
1100 
1101     for (i = 0; i < 8; i++) {
1102       UErrorCode err = U_ZERO_ERROR;
1103       const char *test;
1104       test = uloc_getISO3Language(iso2Languages[i]);
1105       if(strcmp(test, iso3Languages[i]) !=0 || U_FAILURE(err))
1106          log_err("Got wrong ISO3 code for %s : Expected \"%s\", got \"%s\". %s\n",
1107                      iso2Languages[i], iso3Languages[i], test, myErrorName(err));
1108     }
1109     for (i = 0; i < 8; i++) {
1110       UErrorCode err = U_ZERO_ERROR;
1111       const char *test;
1112       test = uloc_getISO3Country(iso2Countries[i]);
1113       if(strcmp(test, iso3Countries[i]) !=0 || U_FAILURE(err))
1114          log_err("Got wrong ISO3 code for %s : Expected \"%s\", got \"%s\". %s\n",
1115                      iso2Countries[i], iso3Countries[i], test, myErrorName(err));
1116     }
1117 }
1118 
1119 
TestVariantParsing()1120 static void TestVariantParsing()
1121 {
1122     static const char* en_US_custom="en_US_De Anza_Cupertino_California_United States_Earth";
1123     static const char* dispName="English (United States, DE ANZA_CUPERTINO_CALIFORNIA_UNITED STATES_EARTH)";
1124     static const char* dispVar="DE ANZA_CUPERTINO_CALIFORNIA_UNITED STATES_EARTH";
1125     static const char* shortVariant="fr_FR_foo";
1126     static const char* bogusVariant="fr_FR__foo";
1127     static const char* bogusVariant2="fr_FR_foo_";
1128     static const char* bogusVariant3="fr_FR__foo_";
1129 
1130 
1131     UChar displayVar[100];
1132     UChar displayName[100];
1133     UErrorCode status=U_ZERO_ERROR;
1134     UChar* got=0;
1135     int32_t size=0;
1136     size=uloc_getDisplayVariant(en_US_custom, "en_US", NULL, size, &status);
1137     if(status==U_BUFFER_OVERFLOW_ERROR) {
1138         status=U_ZERO_ERROR;
1139         got=(UChar*)realloc(got, sizeof(UChar) * (size+1));
1140         uloc_getDisplayVariant(en_US_custom, "en_US", got, size + 1, &status);
1141     }
1142     else {
1143         log_err("FAIL: Didn't get U_BUFFER_OVERFLOW_ERROR\n");
1144     }
1145     u_uastrcpy(displayVar, dispVar);
1146     if(u_strcmp(got,displayVar)!=0) {
1147         log_err("FAIL: getDisplayVariant() Wanted %s, got %s\n", dispVar, austrdup(got));
1148     }
1149     size=0;
1150     size=uloc_getDisplayName(en_US_custom, "en_US", NULL, size, &status);
1151     if(status==U_BUFFER_OVERFLOW_ERROR) {
1152         status=U_ZERO_ERROR;
1153         got=(UChar*)realloc(got, sizeof(UChar) * (size+1));
1154         uloc_getDisplayName(en_US_custom, "en_US", got, size + 1, &status);
1155     }
1156     else {
1157         log_err("FAIL: Didn't get U_BUFFER_OVERFLOW_ERROR\n");
1158     }
1159     u_uastrcpy(displayName, dispName);
1160     if(u_strcmp(got,displayName)!=0) {
1161         log_err("FAIL: getDisplayName() Wanted %s, got %s\n", dispName, austrdup(got));
1162     }
1163 
1164     size=0;
1165     status=U_ZERO_ERROR;
1166     size=uloc_getDisplayVariant(shortVariant, NULL, NULL, size, &status);
1167     if(status==U_BUFFER_OVERFLOW_ERROR) {
1168         status=U_ZERO_ERROR;
1169         got=(UChar*)realloc(got, sizeof(UChar) * (size+1));
1170         uloc_getDisplayVariant(shortVariant, NULL, got, size + 1, &status);
1171     }
1172     else {
1173         log_err("FAIL: Didn't get U_BUFFER_OVERFLOW_ERROR\n");
1174     }
1175     if(strcmp(austrdup(got),"FOO")!=0) {
1176         log_err("FAIL: getDisplayVariant()  Wanted: foo  Got: %s\n", austrdup(got));
1177     }
1178     size=0;
1179     status=U_ZERO_ERROR;
1180     size=uloc_getDisplayVariant(bogusVariant, NULL, NULL, size, &status);
1181     if(status==U_BUFFER_OVERFLOW_ERROR) {
1182         status=U_ZERO_ERROR;
1183         got=(UChar*)realloc(got, sizeof(UChar) * (size+1));
1184         uloc_getDisplayVariant(bogusVariant, NULL, got, size + 1, &status);
1185     }
1186     else {
1187         log_err("FAIL: Didn't get U_BUFFER_OVERFLOW_ERROR\n");
1188     }
1189     if(strcmp(austrdup(got),"_FOO")!=0) {
1190         log_err("FAIL: getDisplayVariant()  Wanted: _FOO  Got: %s\n", austrdup(got));
1191     }
1192     size=0;
1193     status=U_ZERO_ERROR;
1194     size=uloc_getDisplayVariant(bogusVariant2, NULL, NULL, size, &status);
1195     if(status==U_BUFFER_OVERFLOW_ERROR) {
1196         status=U_ZERO_ERROR;
1197         got=(UChar*)realloc(got, sizeof(UChar) * (size+1));
1198         uloc_getDisplayVariant(bogusVariant2, NULL, got, size + 1, &status);
1199     }
1200     else {
1201         log_err("FAIL: Didn't get U_BUFFER_OVERFLOW_ERROR\n");
1202     }
1203     if(strcmp(austrdup(got),"FOO_")!=0) {
1204         log_err("FAIL: getDisplayVariant()  Wanted: FOO_  Got: %s\n", austrdup(got));
1205     }
1206     size=0;
1207     status=U_ZERO_ERROR;
1208     size=uloc_getDisplayVariant(bogusVariant3, NULL, NULL, size, &status);
1209     if(status==U_BUFFER_OVERFLOW_ERROR) {
1210         status=U_ZERO_ERROR;
1211         got=(UChar*)realloc(got, sizeof(UChar) * (size+1));
1212         uloc_getDisplayVariant(bogusVariant3, NULL, got, size + 1, &status);
1213     }
1214     else {
1215         log_err("FAIL: Didn't get U_BUFFER_OVERFLOW_ERROR\n");
1216     }
1217     if(strcmp(austrdup(got),"_FOO_")!=0) {
1218         log_err("FAIL: getDisplayVariant()  Wanted: _FOO_  Got: %s\n", austrdup(got));
1219     }
1220     free(got);
1221 }
1222 
1223 
TestObsoleteNames(void)1224 static void TestObsoleteNames(void)
1225 {
1226     int32_t i;
1227     UErrorCode status = U_ZERO_ERROR;
1228     char buff[256];
1229 
1230     static const struct
1231     {
1232         char locale[9];
1233         char lang3[4];
1234         char lang[4];
1235         char ctry3[4];
1236         char ctry[4];
1237     } tests[] =
1238     {
1239         { "eng_USA", "eng", "en", "USA", "US" },
1240         { "kok",  "kok", "kok", "", "" },
1241         { "in",  "ind", "in", "", "" },
1242         { "id",  "ind", "id", "", "" }, /* NO aliasing */
1243         { "sh",  "srp", "sh", "", "" },
1244         { "zz_CS",  "", "zz", "SCG", "CS" },
1245         { "zz_FX",  "", "zz", "FXX", "FX" },
1246         { "zz_RO",  "", "zz", "ROU", "RO" },
1247         { "zz_TP",  "", "zz", "TMP", "TP" },
1248         { "zz_TL",  "", "zz", "TLS", "TL" },
1249         { "zz_ZR",  "", "zz", "ZAR", "ZR" },
1250         { "zz_FXX",  "", "zz", "FXX", "FX" }, /* no aliasing. Doesn't go to PS(PSE). */
1251         { "zz_ROM",  "", "zz", "ROU", "RO" },
1252         { "zz_ROU",  "", "zz", "ROU", "RO" },
1253         { "zz_ZAR",  "", "zz", "ZAR", "ZR" },
1254         { "zz_TMP",  "", "zz", "TMP", "TP" },
1255         { "zz_TLS",  "", "zz", "TLS", "TL" },
1256         { "zz_YUG",  "", "zz", "YUG", "YU" },
1257         { "mlt_PSE", "mlt", "mt", "PSE", "PS" },
1258         { "iw", "heb", "iw", "", "" },
1259         { "ji", "yid", "ji", "", "" },
1260         { "jw", "jaw", "jw", "", "" },
1261         { "sh", "srp", "sh", "", "" },
1262         { "", "", "", "", "" }
1263     };
1264 
1265     for(i=0;tests[i].locale[0];i++)
1266     {
1267         const char *locale;
1268 
1269         locale = tests[i].locale;
1270         log_verbose("** %s:\n", locale);
1271 
1272         status = U_ZERO_ERROR;
1273         if(strcmp(tests[i].lang3,uloc_getISO3Language(locale)))
1274         {
1275             log_err("FAIL: uloc_getISO3Language(%s)==\t\"%s\",\t expected \"%s\"\n",
1276                 locale,  uloc_getISO3Language(locale), tests[i].lang3);
1277         }
1278         else
1279         {
1280             log_verbose("   uloc_getISO3Language()==\t\"%s\"\n",
1281                 uloc_getISO3Language(locale) );
1282         }
1283 
1284         status = U_ZERO_ERROR;
1285         uloc_getLanguage(locale, buff, 256, &status);
1286         if(U_FAILURE(status))
1287         {
1288             log_err("FAIL: error getting language from %s\n", locale);
1289         }
1290         else
1291         {
1292             if(strcmp(buff,tests[i].lang))
1293             {
1294                 log_err("FAIL: uloc_getLanguage(%s)==\t\"%s\"\t expected \"%s\"\n",
1295                     locale, buff, tests[i].lang);
1296             }
1297             else
1298             {
1299                 log_verbose("  uloc_getLanguage(%s)==\t%s\n", locale, buff);
1300             }
1301         }
1302         if(strcmp(tests[i].lang3,uloc_getISO3Language(locale)))
1303         {
1304             log_err("FAIL: uloc_getISO3Language(%s)==\t\"%s\",\t expected \"%s\"\n",
1305                 locale,  uloc_getISO3Language(locale), tests[i].lang3);
1306         }
1307         else
1308         {
1309             log_verbose("   uloc_getISO3Language()==\t\"%s\"\n",
1310                 uloc_getISO3Language(locale) );
1311         }
1312 
1313         if(strcmp(tests[i].ctry3,uloc_getISO3Country(locale)))
1314         {
1315             log_err("FAIL: uloc_getISO3Country(%s)==\t\"%s\",\t expected \"%s\"\n",
1316                 locale,  uloc_getISO3Country(locale), tests[i].ctry3);
1317         }
1318         else
1319         {
1320             log_verbose("   uloc_getISO3Country()==\t\"%s\"\n",
1321                 uloc_getISO3Country(locale) );
1322         }
1323 
1324         status = U_ZERO_ERROR;
1325         uloc_getCountry(locale, buff, 256, &status);
1326         if(U_FAILURE(status))
1327         {
1328             log_err("FAIL: error getting country from %s\n", locale);
1329         }
1330         else
1331         {
1332             if(strcmp(buff,tests[i].ctry))
1333             {
1334                 log_err("FAIL: uloc_getCountry(%s)==\t\"%s\"\t expected \"%s\"\n",
1335                     locale, buff, tests[i].ctry);
1336             }
1337             else
1338             {
1339                 log_verbose("  uloc_getCountry(%s)==\t%s\n", locale, buff);
1340             }
1341         }
1342     }
1343 
1344     if (uloc_getLCID("iw_IL") != uloc_getLCID("he_IL")) {
1345         log_err("he,iw LCID mismatch: %X versus %X\n", uloc_getLCID("iw_IL"), uloc_getLCID("he_IL"));
1346     }
1347 
1348     if (uloc_getLCID("iw") != uloc_getLCID("he")) {
1349         log_err("he,iw LCID mismatch: %X versus %X\n", uloc_getLCID("iw"), uloc_getLCID("he"));
1350     }
1351 
1352 #if 0
1353 
1354     i = uloc_getLanguage("kok",NULL,0,&icu_err);
1355     if(U_FAILURE(icu_err))
1356     {
1357         log_err("FAIL: Got %s trying to do uloc_getLanguage(kok)\n", u_errorName(icu_err));
1358     }
1359 
1360     icu_err = U_ZERO_ERROR;
1361     uloc_getLanguage("kok",r1_buff,12,&icu_err);
1362     if(U_FAILURE(icu_err))
1363     {
1364         log_err("FAIL: Got %s trying to do uloc_getLanguage(kok, buff)\n", u_errorName(icu_err));
1365     }
1366 
1367     r1_addr = (char *)uloc_getISO3Language("kok");
1368 
1369     icu_err = U_ZERO_ERROR;
1370     if (strcmp(r1_buff,"kok") != 0)
1371     {
1372         log_err("FAIL: uloc_getLanguage(kok)==%s not kok\n",r1_buff);
1373         line--;
1374     }
1375     r1_addr = (char *)uloc_getISO3Language("in");
1376     i = uloc_getLanguage(r1_addr,r1_buff,12,&icu_err);
1377     if (strcmp(r1_buff,"id") != 0)
1378     {
1379         printf("uloc_getLanguage error (%s)\n",r1_buff);
1380         line--;
1381     }
1382     r1_addr = (char *)uloc_getISO3Language("sh");
1383     i = uloc_getLanguage(r1_addr,r1_buff,12,&icu_err);
1384     if (strcmp(r1_buff,"sr") != 0)
1385     {
1386         printf("uloc_getLanguage error (%s)\n",r1_buff);
1387         line--;
1388     }
1389 
1390     r1_addr = (char *)uloc_getISO3Country("zz_ZR");
1391     strcpy(p1_buff,"zz_");
1392     strcat(p1_buff,r1_addr);
1393     i = uloc_getCountry(p1_buff,r1_buff,12,&icu_err);
1394     if (strcmp(r1_buff,"ZR") != 0)
1395     {
1396         printf("uloc_getCountry error (%s)\n",r1_buff);
1397         line--;
1398     }
1399     r1_addr = (char *)uloc_getISO3Country("zz_FX");
1400     strcpy(p1_buff,"zz_");
1401     strcat(p1_buff,r1_addr);
1402     i = uloc_getCountry(p1_buff,r1_buff,12,&icu_err);
1403     if (strcmp(r1_buff,"FX") != 0)
1404     {
1405         printf("uloc_getCountry error (%s)\n",r1_buff);
1406         line--;
1407     }
1408 
1409 #endif
1410 
1411 }
1412 
TestKeywordVariants(void)1413 static void TestKeywordVariants(void)
1414 {
1415     static const struct {
1416         const char *localeID;
1417         const char *expectedLocaleID;
1418         const char *expectedLocaleIDNoKeywords;
1419         const char *expectedCanonicalID;
1420         const char *expectedKeywords[10];
1421         int32_t numKeywords;
1422         UErrorCode expectedStatus; /* from uloc_openKeywords */
1423     } testCases[] = {
1424         {
1425             "de_DE@  currency = euro; C o ll A t i o n   = Phonebook   ; C alen dar = buddhist   ",
1426             "de_DE@calendar=buddhist;collation=Phonebook;currency=euro",
1427             "de_DE",
1428             "de_DE@calendar=buddhist;collation=Phonebook;currency=euro",
1429             {"calendar", "collation", "currency"},
1430             3,
1431             U_ZERO_ERROR
1432         },
1433         {
1434             "de_DE@euro",
1435             "de_DE@euro",
1436             "de_DE",
1437             "de_DE@currency=EUR",
1438             {"","","","","","",""},
1439             0,
1440             U_INVALID_FORMAT_ERROR /* must have '=' after '@' */
1441         },
1442         {
1443             "de_DE@euro;collation=phonebook",
1444             "de_DE", /* error result; bad format */
1445             "de_DE", /* error result; bad format */
1446             "de_DE", /* error result; bad format */
1447             {"","","","","","",""},
1448             0,
1449             U_INVALID_FORMAT_ERROR
1450         }
1451     };
1452     UErrorCode status = U_ZERO_ERROR;
1453 
1454     int32_t i = 0, j = 0;
1455     int32_t resultLen = 0;
1456     char buffer[256];
1457     UEnumeration *keywords;
1458     int32_t keyCount = 0;
1459     const char *keyword = NULL;
1460     int32_t keywordLen = 0;
1461 
1462     for(i = 0; i < sizeof(testCases)/sizeof(testCases[0]); i++) {
1463         status = U_ZERO_ERROR;
1464         *buffer = 0;
1465         keywords = uloc_openKeywords(testCases[i].localeID, &status);
1466 
1467         if(status != testCases[i].expectedStatus) {
1468             log_err("Expected to uloc_openKeywords(\"%s\") => status %s. Got %s instead\n",
1469                     testCases[i].localeID,
1470                     u_errorName(testCases[i].expectedStatus), u_errorName(status));
1471         }
1472         status = U_ZERO_ERROR;
1473         if(keywords) {
1474             if((keyCount = uenum_count(keywords, &status)) != testCases[i].numKeywords) {
1475                 log_err("Expected to get %i keywords, got %i\n", testCases[i].numKeywords, keyCount);
1476             }
1477             if(keyCount) {
1478                 j = 0;
1479                 while((keyword = uenum_next(keywords, &keywordLen, &status))) {
1480                     if(strcmp(keyword, testCases[i].expectedKeywords[j]) != 0) {
1481                         log_err("Expected to get keyword value %s, got %s\n", testCases[i].expectedKeywords[j], keyword);
1482                     }
1483                     j++;
1484                 }
1485                 j = 0;
1486                 uenum_reset(keywords, &status);
1487                 while((keyword = uenum_next(keywords, &keywordLen, &status))) {
1488                     if(strcmp(keyword, testCases[i].expectedKeywords[j]) != 0) {
1489                         log_err("Expected to get keyword value %s, got %s\n", testCases[i].expectedKeywords[j], keyword);
1490                     }
1491                     j++;
1492                 }
1493             }
1494             uenum_close(keywords);
1495         }
1496         resultLen = uloc_getName(testCases[i].localeID, buffer, 256, &status);
1497         if (uprv_strcmp(testCases[i].expectedLocaleID, buffer) != 0) {
1498             log_err("Expected uloc_getName(\"%s\") => \"%s\"; got \"%s\"\n",
1499                     testCases[i].localeID, testCases[i].expectedLocaleID, buffer);
1500         }
1501         resultLen = uloc_canonicalize(testCases[i].localeID, buffer, 256, &status);
1502         if (uprv_strcmp(testCases[i].expectedCanonicalID, buffer) != 0) {
1503             log_err("Expected uloc_canonicalize(\"%s\") => \"%s\"; got \"%s\"\n",
1504                     testCases[i].localeID, testCases[i].expectedCanonicalID, buffer);
1505         }
1506     }
1507 
1508 }
1509 
TestKeywordVariantParsing(void)1510 static void TestKeywordVariantParsing(void)
1511 {
1512     static const struct {
1513         const char *localeID;
1514         const char *keyword;
1515         const char *expectedValue;
1516     } testCases[] = {
1517         { "de_DE@  C o ll A t i o n   = Phonebook   ", "c o ll a t i o n", "Phonebook" },
1518         { "de_DE", "collation", ""},
1519         { "de_DE@collation=PHONEBOOK", "collation", "PHONEBOOK" },
1520         { "de_DE@currency = euro; CoLLaTion   = PHONEBOOk", "collatiON", "PHONEBOOk" },
1521     };
1522 
1523     UErrorCode status = U_ZERO_ERROR;
1524 
1525     int32_t i = 0;
1526     int32_t resultLen = 0;
1527     char buffer[256];
1528 
1529     for(i = 0; i < sizeof(testCases)/sizeof(testCases[0]); i++) {
1530         *buffer = 0;
1531         resultLen = uloc_getKeywordValue(testCases[i].localeID, testCases[i].keyword, buffer, 256, &status);
1532         if(uprv_strcmp(testCases[i].expectedValue, buffer) != 0) {
1533             log_err("Expected to extract \"%s\" from \"%s\" for keyword \"%s\". Got \"%s\" instead\n",
1534                 testCases[i].expectedValue, testCases[i].localeID, testCases[i].keyword, buffer);
1535         }
1536     }
1537 }
1538 
1539 static const struct {
1540   const char *l; /* locale */
1541   const char *k; /* kw */
1542   const char *v; /* value */
1543   const char *x; /* expected */
1544 } kwSetTestCases[] = {
1545 #if 1
1546   { "en_US", "calendar", "japanese", "en_US@calendar=japanese" },
1547   { "en_US@", "calendar", "japanese", "en_US@calendar=japanese" },
1548   { "en_US@calendar=islamic", "calendar", "japanese", "en_US@calendar=japanese" },
1549   { "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 */
1550   { "en_US@calendar=gregorian", "calendar", "japanese", "en_US@calendar=japanese" },
1551   { "de", "Currency", "CHF", "de@currency=CHF" },
1552   { "de", "Currency", "CHF", "de@currency=CHF" },
1553 
1554   { "en_US@collation=phonebook", "calendar", "japanese", "en_US@calendar=japanese;collation=phonebook" },
1555   { "en_US@calendar=japanese", "collation", "phonebook", "en_US@calendar=japanese;collation=phonebook" },
1556   { "de@collation=phonebook", "Currency", "CHF", "de@collation=phonebook;currency=CHF" },
1557   { "en_US@calendar=gregorian;collation=phonebook", "calendar", "japanese", "en_US@calendar=japanese;collation=phonebook" },
1558   { "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 */
1559   { "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 */
1560   { "en_US@calendar=islamic;collation=phonebook", "calendar", "japanese", "en_US@calendar=japanese;collation=phonebook" },
1561   { "de@collation=phonebook", "Currency", "CHF", "de@collation=phonebook;currency=CHF" },
1562 #endif
1563 #if 1
1564   { "mt@a=0;b=1;c=2;d=3", "c","j", "mt@a=0;b=1;c=j;d=3" },
1565   { "mt@a=0;b=1;c=2;d=3", "x","j", "mt@a=0;b=1;c=2;d=3;x=j" },
1566   { "mt@a=0;b=1;c=2;d=3", "a","f", "mt@a=f;b=1;c=2;d=3" },
1567   { "mt@a=0;aa=1;aaa=3", "a","x", "mt@a=x;aa=1;aaa=3" },
1568   { "mt@a=0;aa=1;aaa=3", "aa","x", "mt@a=0;aa=x;aaa=3" },
1569   { "mt@a=0;aa=1;aaa=3", "aaa","x", "mt@a=0;aa=1;aaa=x" },
1570   { "mt@a=0;aa=1;aaa=3", "a","yy", "mt@a=yy;aa=1;aaa=3" },
1571   { "mt@a=0;aa=1;aaa=3", "aa","yy", "mt@a=0;aa=yy;aaa=3" },
1572   { "mt@a=0;aa=1;aaa=3", "aaa","yy", "mt@a=0;aa=1;aaa=yy" },
1573 #endif
1574 #if 1
1575   /* removal tests */
1576   /* 1. removal of item at end */
1577   { "de@collation=phonebook;currency=CHF", "currency",   "", "de@collation=phonebook" },
1578   { "de@collation=phonebook;currency=CHF", "currency", NULL, "de@collation=phonebook" },
1579   /* 2. removal of item at beginning */
1580   { "de@collation=phonebook;currency=CHF", "collation", "", "de@currency=CHF" },
1581   { "de@collation=phonebook;currency=CHF", "collation", NULL, "de@currency=CHF" },
1582   /* 3. removal of an item not there */
1583   { "de@collation=phonebook;currency=CHF", "calendar", NULL, "de@collation=phonebook;currency=CHF" },
1584   /* 4. removal of only item */
1585   { "de@collation=phonebook", "collation", NULL, "de" },
1586 #endif
1587   { "de@collation=phonebook", "Currency", "CHF", "de@collation=phonebook;currency=CHF" }
1588 };
1589 
1590 
TestKeywordSet(void)1591 static void TestKeywordSet(void)
1592 {
1593     int32_t i = 0;
1594     int32_t resultLen = 0;
1595     char buffer[1024];
1596 
1597     char cbuffer[1024];
1598 
1599     for(i = 0; i < sizeof(kwSetTestCases)/sizeof(kwSetTestCases[0]); i++) {
1600         UErrorCode status = U_ZERO_ERROR;
1601         memset(buffer,'%',1023);
1602         strcpy(buffer, kwSetTestCases[i].l);
1603 
1604         uloc_canonicalize(kwSetTestCases[i].l, cbuffer, 1023, &status);
1605         if(strcmp(buffer,cbuffer)) {
1606           log_verbose("note: [%d] wasn't canonical, should be: '%s' not '%s'. Won't check for canonicity in output.\n", i, cbuffer, buffer);
1607         }
1608           /* sanity check test case results for canonicity */
1609         uloc_canonicalize(kwSetTestCases[i].x, cbuffer, 1023, &status);
1610         if(strcmp(kwSetTestCases[i].x,cbuffer)) {
1611           log_err("%s:%d: ERROR: kwSetTestCases[%d].x = '%s', should be %s (must be canonical)\n", __FILE__, __LINE__, i, kwSetTestCases[i].x, cbuffer);
1612         }
1613 
1614         resultLen = uloc_setKeywordValue(kwSetTestCases[i].k, kwSetTestCases[i].v, buffer, 1023, &status);
1615         if(U_FAILURE(status)) {
1616           log_err("Err on test case %d: got error %s\n", i, u_errorName(status));
1617           continue;
1618         }
1619         if(strcmp(buffer,kwSetTestCases[i].x) || ((int32_t)strlen(buffer)!=resultLen)) {
1620           log_err("FAIL: #%d: %s + [%s=%s] -> %s (%d) expected %s (%d)\n", i, kwSetTestCases[i].l, kwSetTestCases[i].k,
1621                   kwSetTestCases[i].v, buffer, resultLen, kwSetTestCases[i].x, strlen(buffer));
1622         } else {
1623           log_verbose("pass: #%d: %s + [%s=%s] -> %s\n", i, kwSetTestCases[i].l, kwSetTestCases[i].k, kwSetTestCases[i].v,buffer);
1624         }
1625     }
1626 }
1627 
TestKeywordSetError(void)1628 static void TestKeywordSetError(void)
1629 {
1630     char buffer[1024];
1631     UErrorCode status;
1632     int32_t res;
1633     int32_t i;
1634     int32_t blen;
1635 
1636     /* 0-test whether an error condition modifies the buffer at all */
1637     blen=0;
1638     i=0;
1639     memset(buffer,'%',1023);
1640     status = U_ZERO_ERROR;
1641     res = uloc_setKeywordValue(kwSetTestCases[i].k, kwSetTestCases[i].v, buffer, blen, &status);
1642     if(status != U_ILLEGAL_ARGUMENT_ERROR) {
1643         log_err("expected illegal err got %s\n", u_errorName(status));
1644         return;
1645     }
1646     /*  if(res!=strlen(kwSetTestCases[i].x)) {
1647     log_err("expected result %d got %d\n", strlen(kwSetTestCases[i].x), res);
1648     return;
1649     } */
1650     if(buffer[blen]!='%') {
1651         log_err("Buffer byte %d was modified: now %c\n", blen, buffer[blen]);
1652         return;
1653     }
1654     log_verbose("0-buffer modify OK\n");
1655 
1656     for(i=0;i<=2;i++) {
1657         /* 1- test a short buffer with growing text */
1658         blen=(int32_t)strlen(kwSetTestCases[i].l)+1;
1659         memset(buffer,'%',1023);
1660         strcpy(buffer,kwSetTestCases[i].l);
1661         status = U_ZERO_ERROR;
1662         res = uloc_setKeywordValue(kwSetTestCases[i].k, kwSetTestCases[i].v, buffer, blen, &status);
1663         if(status != U_BUFFER_OVERFLOW_ERROR) {
1664             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);
1665             return;
1666         }
1667         if(res!=(int32_t)strlen(kwSetTestCases[i].x)) {
1668             log_err("expected result %d got %d\n", strlen(kwSetTestCases[i].x), res);
1669             return;
1670         }
1671         if(buffer[blen]!='%') {
1672             log_err("Buffer byte %d was modified: now %c\n", blen, buffer[blen]);
1673             return;
1674         }
1675         log_verbose("1/%d-buffer modify OK\n",i);
1676     }
1677 
1678     for(i=3;i<=4;i++) {
1679         /* 2- test a short buffer - text the same size or shrinking   */
1680         blen=(int32_t)strlen(kwSetTestCases[i].l)+1;
1681         memset(buffer,'%',1023);
1682         strcpy(buffer,kwSetTestCases[i].l);
1683         status = U_ZERO_ERROR;
1684         res = uloc_setKeywordValue(kwSetTestCases[i].k, kwSetTestCases[i].v, buffer, blen, &status);
1685         if(status != U_ZERO_ERROR) {
1686             log_err("expected zero error got %s\n", u_errorName(status));
1687             return;
1688         }
1689         if(buffer[blen+1]!='%') {
1690             log_err("Buffer byte %d was modified: now %c\n", blen+1, buffer[blen+1]);
1691             return;
1692         }
1693         if(res!=(int32_t)strlen(kwSetTestCases[i].x)) {
1694             log_err("expected result %d got %d\n", strlen(kwSetTestCases[i].x), res);
1695             return;
1696         }
1697         if(strcmp(buffer,kwSetTestCases[i].x) || ((int32_t)strlen(buffer)!=res)) {
1698             log_err("FAIL: #%d: %s + [%s=%s] -> %s (%d) expected %s (%d)\n", i, kwSetTestCases[i].l, kwSetTestCases[i].k,
1699                 kwSetTestCases[i].v, buffer, res, kwSetTestCases[i].x, strlen(buffer));
1700         } else {
1701             log_verbose("pass: #%d: %s + [%s=%s] -> %s\n", i, kwSetTestCases[i].l, kwSetTestCases[i].k, kwSetTestCases[i].v,
1702                 buffer);
1703         }
1704         log_verbose("2/%d-buffer modify OK\n",i);
1705     }
1706 }
1707 
_canonicalize(int32_t selector,const char * localeID,char * result,int32_t resultCapacity,UErrorCode * ec)1708 static int32_t _canonicalize(int32_t selector, /* 0==getName, 1==canonicalize */
1709                              const char* localeID,
1710                              char* result,
1711                              int32_t resultCapacity,
1712                              UErrorCode* ec) {
1713     /* YOU can change this to use function pointers if you like */
1714     switch (selector) {
1715     case 0:
1716         return uloc_getName(localeID, result, resultCapacity, ec);
1717     case 1:
1718         return uloc_canonicalize(localeID, result, resultCapacity, ec);
1719     default:
1720         return -1;
1721     }
1722 }
1723 
TestCanonicalization(void)1724 static void TestCanonicalization(void)
1725 {
1726     static const struct {
1727         const char *localeID;    /* input */
1728         const char *getNameID;   /* expected getName() result */
1729         const char *canonicalID; /* expected canonicalize() result */
1730     } testCases[] = {
1731         { "ca_ES_PREEURO-with-extra-stuff-that really doesn't make any sense-unless-you're trying to increase code coverage",
1732           "ca_ES_PREEURO_WITH_EXTRA_STUFF_THAT REALLY DOESN'T MAKE ANY SENSE_UNLESS_YOU'RE TRYING TO INCREASE CODE COVERAGE",
1733           "ca_ES_PREEURO_WITH_EXTRA_STUFF_THAT REALLY DOESN'T MAKE ANY SENSE_UNLESS_YOU'RE TRYING TO INCREASE CODE COVERAGE"},
1734         { "ca_ES_PREEURO", "ca_ES_PREEURO", "ca_ES@currency=ESP" },
1735         { "de_AT_PREEURO", "de_AT_PREEURO", "de_AT@currency=ATS" },
1736         { "de_DE_PREEURO", "de_DE_PREEURO", "de_DE@currency=DEM" },
1737         { "de_LU_PREEURO", "de_LU_PREEURO", "de_LU@currency=LUF" },
1738         { "el_GR_PREEURO", "el_GR_PREEURO", "el_GR@currency=GRD" },
1739         { "en_BE_PREEURO", "en_BE_PREEURO", "en_BE@currency=BEF" },
1740         { "en_IE_PREEURO", "en_IE_PREEURO", "en_IE@currency=IEP" },
1741         { "es_ES_PREEURO", "es_ES_PREEURO", "es_ES@currency=ESP" },
1742         { "eu_ES_PREEURO", "eu_ES_PREEURO", "eu_ES@currency=ESP" },
1743         { "fi_FI_PREEURO", "fi_FI_PREEURO", "fi_FI@currency=FIM" },
1744         { "fr_BE_PREEURO", "fr_BE_PREEURO", "fr_BE@currency=BEF" },
1745         { "fr_FR_PREEURO", "fr_FR_PREEURO", "fr_FR@currency=FRF" },
1746         { "fr_LU_PREEURO", "fr_LU_PREEURO", "fr_LU@currency=LUF" },
1747         { "ga_IE_PREEURO", "ga_IE_PREEURO", "ga_IE@currency=IEP" },
1748         { "gl_ES_PREEURO", "gl_ES_PREEURO", "gl_ES@currency=ESP" },
1749         { "it_IT_PREEURO", "it_IT_PREEURO", "it_IT@currency=ITL" },
1750         { "nl_BE_PREEURO", "nl_BE_PREEURO", "nl_BE@currency=BEF" },
1751         { "nl_NL_PREEURO", "nl_NL_PREEURO", "nl_NL@currency=NLG" },
1752         { "pt_PT_PREEURO", "pt_PT_PREEURO", "pt_PT@currency=PTE" },
1753         { "de__PHONEBOOK", "de__PHONEBOOK", "de@collation=phonebook" },
1754         { "en_GB_EURO", "en_GB_EURO", "en_GB@currency=EUR" },
1755         { "en_GB@EURO", "en_GB@EURO", "en_GB@currency=EUR" }, /* POSIX ID */
1756         { "es__TRADITIONAL", "es__TRADITIONAL", "es@collation=traditional" },
1757         { "hi__DIRECT", "hi__DIRECT", "hi@collation=direct" },
1758         { "ja_JP_TRADITIONAL", "ja_JP_TRADITIONAL", "ja_JP@calendar=japanese" },
1759         { "th_TH_TRADITIONAL", "th_TH_TRADITIONAL", "th_TH@calendar=buddhist" },
1760         { "zh_TW_STROKE", "zh_TW_STROKE", "zh_Hant_TW@collation=stroke" },
1761         { "zh__PINYIN", "zh__PINYIN", "zh@collation=pinyin" },
1762         { "zh@collation=pinyin", "zh@collation=pinyin", "zh@collation=pinyin" },
1763         { "zh_CN@collation=pinyin", "zh_CN@collation=pinyin", "zh_CN@collation=pinyin" },
1764         { "zh_CN_CA@collation=pinyin", "zh_CN_CA@collation=pinyin", "zh_CN_CA@collation=pinyin" },
1765         { "en_US_POSIX", "en_US_POSIX", "en_US_POSIX" },
1766         { "hy_AM_REVISED", "hy_AM_REVISED", "hy_AM_REVISED" },
1767         { "no_NO_NY", "no_NO_NY", "no_NO_NY" /* not: "nn_NO" [alan ICU3.0] */ },
1768         { "no@ny", "no@ny", "no__NY" /* not: "nn" [alan ICU3.0] */ }, /* POSIX ID */
1769         { "no-no.utf32@B", "no_NO.utf32@B", "no_NO_B" /* not: "nb_NO_B" [alan ICU3.0] */ }, /* POSIX ID */
1770         { "qz-qz@Euro", "qz_QZ@Euro", "qz_QZ@currency=EUR" }, /* qz-qz uses private use iso codes */
1771         { "en-BOONT", "en_BOONT", "en__BOONT" }, /* registered name */
1772         { "de-1901", "de_1901", "de__1901" }, /* registered name */
1773         { "de-1906", "de_1906", "de__1906" }, /* registered name */
1774         { "sr-SP-Cyrl", "sr_SP_CYRL", "sr_Cyrl_CS" }, /* .NET name */
1775         { "sr-SP-Latn", "sr_SP_LATN", "sr_Latn_CS" }, /* .NET name */
1776         { "sr_YU_CYRILLIC", "sr_YU_CYRILLIC", "sr_Cyrl_CS" }, /* Linux name */
1777         { "uz-UZ-Cyrl", "uz_UZ_CYRL", "uz_Cyrl_UZ" }, /* .NET name */
1778         { "uz-UZ-Latn", "uz_UZ_LATN", "uz_Latn_UZ" }, /* .NET name */
1779         { "zh-CHS", "zh_CHS", "zh_Hans" }, /* .NET name */
1780         { "zh-CHT", "zh_CHT", "zh_Hant" }, /* .NET name This may change back to zh_Hant */
1781 
1782         /* posix behavior that used to be performed by getName */
1783         { "mr.utf8", "mr.utf8", "mr" },
1784         { "de-tv.koi8r", "de_TV.koi8r", "de_TV" },
1785         { "x-piglatin_ML.MBE", "x-piglatin_ML.MBE", "x-piglatin_ML" },
1786         { "i-cherokee_US.utf7", "i-cherokee_US.utf7", "i-cherokee_US" },
1787         { "x-filfli_MT_FILFLA.gb-18030", "x-filfli_MT_FILFLA.gb-18030", "x-filfli_MT_FILFLA" },
1788         { "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 */
1789 
1790         /* fleshing out canonicalization */
1791         /* trim space and sort keywords, ';' is separator so not present at end in canonical form */
1792         { "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" },
1793         /* already-canonical ids are not changed */
1794         { "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" },
1795         /* PRE_EURO and EURO conversions don't affect other keywords */
1796         { "es_ES_PREEURO@CALendar=Japanese", "es_ES_PREEURO@calendar=Japanese", "es_ES@calendar=Japanese;currency=ESP" },
1797         { "es_ES_EURO@SHOUT=zipeedeedoodah", "es_ES_EURO@shout=zipeedeedoodah", "es_ES@currency=EUR;shout=zipeedeedoodah" },
1798         /* currency keyword overrides PRE_EURO and EURO currency */
1799         { "es_ES_PREEURO@currency=EUR", "es_ES_PREEURO@currency=EUR", "es_ES@currency=EUR" },
1800         { "es_ES_EURO@currency=ESP", "es_ES_EURO@currency=ESP", "es_ES@currency=ESP" },
1801         /* norwegian is just too weird, if we handle things in their full generality */
1802         { "no-Hant-GB_NY@currency=$$$", "no_Hant_GB_NY@currency=$$$", "no_Hant_GB_NY@currency=$$$" /* not: "nn_Hant_GB@currency=$$$" [alan ICU3.0] */ },
1803 
1804         /* test cases reflecting internal resource bundle usage */
1805         { "root@kw=foo", "root@kw=foo", "root@kw=foo" },
1806         { "@calendar=gregorian", "@calendar=gregorian", "@calendar=gregorian" },
1807         { "ja_JP@calendar=Japanese", "ja_JP@calendar=Japanese", "ja_JP@calendar=Japanese" },
1808         { "ja_JP", "ja_JP", "ja_JP" },
1809 
1810         /* test case for "i-default" */
1811         { "i-default", NULL, NULL }
1812     };
1813 
1814     static const char* label[] = { "getName", "canonicalize" };
1815 
1816     UErrorCode status = U_ZERO_ERROR;
1817     int32_t i, j, resultLen = 0, origResultLen;
1818     char buffer[256];
1819 
1820     for (i=0; i < sizeof(testCases)/sizeof(testCases[0]); i++) {
1821         for (j=0; j<2; ++j) {
1822             const char* expected = (j==0) ? testCases[i].getNameID : testCases[i].canonicalID;
1823             *buffer = 0;
1824             status = U_ZERO_ERROR;
1825 
1826             if (expected == NULL) {
1827                 expected = uloc_getDefault();
1828             }
1829 
1830             /* log_verbose("testing %s -> %s\n", testCases[i], testCases[i].canonicalID); */
1831             origResultLen = _canonicalize(j, testCases[i].localeID, NULL, 0, &status);
1832             if (status != U_BUFFER_OVERFLOW_ERROR) {
1833                 log_err("FAIL: uloc_%s(%s) => %s, expected U_BUFFER_OVERFLOW_ERROR\n",
1834                         label[j], testCases[i].localeID, u_errorName(status));
1835                 continue;
1836             }
1837             status = U_ZERO_ERROR;
1838             resultLen = _canonicalize(j, testCases[i].localeID, buffer, sizeof(buffer), &status);
1839             if (U_FAILURE(status)) {
1840                 log_err("FAIL: uloc_%s(%s) => %s, expected U_ZERO_ERROR\n",
1841                         label[j], testCases[i].localeID, u_errorName(status));
1842                 continue;
1843             }
1844             if(uprv_strcmp(expected, buffer) != 0) {
1845                 log_err("FAIL: uloc_%s(%s) => \"%s\", expected \"%s\"\n",
1846                         label[j], testCases[i].localeID, buffer, expected);
1847             } else {
1848                 log_verbose("Ok: uloc_%s(%s) => \"%s\"\n",
1849                             label[j], testCases[i].localeID, buffer);
1850             }
1851             if (resultLen != (int32_t)strlen(buffer)) {
1852                 log_err("FAIL: uloc_%s(%s) => len %d, expected len %d\n",
1853                         label[j], testCases[i].localeID, resultLen, strlen(buffer));
1854             }
1855             if (origResultLen != resultLen) {
1856                 log_err("FAIL: uloc_%s(%s) => preflight len %d != actual len %d\n",
1857                         label[j], testCases[i].localeID, origResultLen, resultLen);
1858             }
1859         }
1860     }
1861 }
1862 
TestDisplayKeywords(void)1863 static void TestDisplayKeywords(void)
1864 {
1865     int32_t i;
1866 
1867     static const struct {
1868         const char *localeID;
1869         const char *displayLocale;
1870         UChar displayKeyword[200];
1871     } testCases[] = {
1872         {   "ca_ES@currency=ESP",         "de_AT",
1873             {0x0057, 0x00e4, 0x0068, 0x0072, 0x0075, 0x006e, 0x0067, 0x0000},
1874         },
1875         {   "ja_JP@calendar=japanese",         "de",
1876             { 0x004b, 0x0061, 0x006c, 0x0065, 0x006e, 0x0064, 0x0065, 0x0072, 0x0000}
1877         },
1878         {   "de_DE@collation=traditional",       "de_DE",
1879             {0x0053, 0x006f, 0x0072, 0x0074, 0x0069, 0x0065, 0x0072, 0x0075, 0x006e, 0x0067, 0x0000}
1880         },
1881     };
1882     for(i = 0; i < sizeof(testCases)/sizeof(testCases[0]); i++) {
1883         UErrorCode status = U_ZERO_ERROR;
1884         const char* keyword =NULL;
1885         int32_t keywordLen = 0;
1886         int32_t keywordCount = 0;
1887         UChar *displayKeyword=NULL;
1888         int32_t displayKeywordLen = 0;
1889         UEnumeration* keywordEnum = uloc_openKeywords(testCases[i].localeID, &status);
1890         for(keywordCount = uenum_count(keywordEnum, &status); keywordCount > 0 ; keywordCount--){
1891               if(U_FAILURE(status)){
1892                   log_err("uloc_getKeywords failed for locale id: %s with error : %s \n", testCases[i].localeID, u_errorName(status));
1893                   break;
1894               }
1895               /* the uenum_next returns NUL terminated string */
1896               keyword = uenum_next(keywordEnum, &keywordLen, &status);
1897               /* fetch the displayKeyword */
1898               displayKeywordLen = uloc_getDisplayKeyword(keyword, testCases[i].displayLocale, displayKeyword, displayKeywordLen, &status);
1899               if(status==U_BUFFER_OVERFLOW_ERROR){
1900                   status = U_ZERO_ERROR;
1901                   displayKeywordLen++; /* for null termination */
1902                   displayKeyword = (UChar*) malloc(displayKeywordLen * U_SIZEOF_UCHAR);
1903                   displayKeywordLen = uloc_getDisplayKeyword(keyword, testCases[i].displayLocale, displayKeyword, displayKeywordLen, &status);
1904                   if(U_FAILURE(status)){
1905                       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));
1906                       break;
1907                   }
1908                   if(u_strncmp(displayKeyword, testCases[i].displayKeyword, displayKeywordLen)!=0){
1909                       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);
1910                       break;
1911                   }
1912               }else{
1913                   log_err("uloc_getDisplayKeyword did not return the expected error. Error: %s\n", u_errorName(status));
1914               }
1915 
1916               free(displayKeyword);
1917 
1918         }
1919         uenum_close(keywordEnum);
1920     }
1921 }
1922 
TestDisplayKeywordValues(void)1923 static void TestDisplayKeywordValues(void){
1924     int32_t i;
1925 
1926     static const struct {
1927         const char *localeID;
1928         const char *displayLocale;
1929         UChar displayKeywordValue[500];
1930     } testCases[] = {
1931         {   "ca_ES@currency=ESP",         "de_AT",
1932             {0x0053, 0x0070, 0x0061, 0x006e, 0x0069, 0x0073, 0x0063, 0x0068, 0x0065, 0x0020, 0x0050, 0x0065, 0x0073, 0x0065, 0x0074, 0x0065, 0x0000}
1933         },
1934         {   "de_AT@currency=ATS",         "fr_FR",
1935             {0x0073, 0x0063, 0x0068, 0x0069, 0x006c, 0x006c, 0x0069, 0x006e, 0x0067, 0x0020, 0x0061, 0x0075, 0x0074, 0x0072, 0x0069, 0x0063, 0x0068, 0x0069, 0x0065, 0x006e, 0x0000}
1936         },
1937         { "de_DE@currency=DEM",         "it",
1938             {0x004d, 0x0061, 0x0072, 0x0063, 0x006f, 0x0020, 0x0054, 0x0065, 0x0064, 0x0065, 0x0073, 0x0063, 0x006f, 0x0000}
1939         },
1940         {   "el_GR@currency=GRD",         "en",
1941             {0x0047, 0x0072, 0x0065, 0x0065, 0x006b, 0x0020, 0x0044, 0x0072, 0x0061, 0x0063, 0x0068, 0x006d, 0x0061, 0x0000}
1942         },
1943         {   "eu_ES@currency=ESP",         "it_IT",
1944             {0x0050, 0x0065, 0x0073, 0x0065, 0x0074, 0x0061, 0x0020, 0x0053, 0x0070, 0x0061, 0x0067, 0x006e, 0x006f, 0x006c, 0x0061, 0x0000}
1945         },
1946         {   "de@collation=phonebook",     "es",
1947             {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}
1948         },
1949 
1950         { "de_DE@collation=phonebook",  "es",
1951           {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}
1952         },
1953         { "es_ES@collation=traditional","de",
1954           {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}
1955         },
1956         { "ja_JP@calendar=japanese",    "de",
1957            {0x004a, 0x0061, 0x0070, 0x0061, 0x006e, 0x0069, 0x0073, 0x0063, 0x0068, 0x0065, 0x0072, 0x0020, 0x004b, 0x0061, 0x006c, 0x0065, 0x006e, 0x0064, 0x0065, 0x0072, 0x0000}
1958         },
1959     };
1960     for(i = 0; i < sizeof(testCases)/sizeof(testCases[0]); i++) {
1961         UErrorCode status = U_ZERO_ERROR;
1962         const char* keyword =NULL;
1963         int32_t keywordLen = 0;
1964         int32_t keywordCount = 0;
1965         UChar *displayKeywordValue = NULL;
1966         int32_t displayKeywordValueLen = 0;
1967         UEnumeration* keywordEnum = uloc_openKeywords(testCases[i].localeID, &status);
1968         for(keywordCount = uenum_count(keywordEnum, &status); keywordCount > 0 ; keywordCount--){
1969               if(U_FAILURE(status)){
1970                   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));
1971                   break;
1972               }
1973               /* the uenum_next returns NUL terminated string */
1974               keyword = uenum_next(keywordEnum, &keywordLen, &status);
1975 
1976               /* fetch the displayKeywordValue */
1977               displayKeywordValueLen = uloc_getDisplayKeywordValue(testCases[i].localeID, keyword, testCases[i].displayLocale, displayKeywordValue, displayKeywordValueLen, &status);
1978               if(status==U_BUFFER_OVERFLOW_ERROR){
1979                   status = U_ZERO_ERROR;
1980                   displayKeywordValueLen++; /* for null termination */
1981                   displayKeywordValue = (UChar*)malloc(displayKeywordValueLen * U_SIZEOF_UCHAR);
1982                   displayKeywordValueLen = uloc_getDisplayKeywordValue(testCases[i].localeID, keyword, testCases[i].displayLocale, displayKeywordValue, displayKeywordValueLen, &status);
1983                   if(U_FAILURE(status)){
1984                       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));
1985                       break;
1986                   }
1987                   if(u_strncmp(displayKeywordValue, testCases[i].displayKeywordValue, displayKeywordValueLen)!=0){
1988                       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));
1989                       break;
1990                   }
1991               }else{
1992                   log_err("uloc_getDisplayKeywordValue did not return the expected error. Error: %s\n", u_errorName(status));
1993               }
1994               free(displayKeywordValue);
1995         }
1996         uenum_close(keywordEnum);
1997     }
1998     {
1999         /* test a multiple keywords */
2000         UErrorCode status = U_ZERO_ERROR;
2001         const char* keyword =NULL;
2002         int32_t keywordLen = 0;
2003         int32_t keywordCount = 0;
2004         const char* localeID = "es@collation=phonebook;calendar=buddhist;currency=DEM";
2005         const char* displayLocale = "de";
2006         static const UChar expected[][50] = {
2007             {0x0042, 0x0075, 0x0064, 0x0064, 0x0068, 0x0069, 0x0073, 0x0074, 0x0069, 0x0073, 0x0063, 0x0068, 0x0065, 0x0072, 0x0020, 0x004b, 0x0061, 0x006c, 0x0065, 0x006e, 0x0064, 0x0065, 0x0072, 0x0000},
2008 
2009             {0x0054, 0x0065, 0x006c, 0x0065, 0x0066, 0x006f, 0x006e, 0x0062, 0x0075, 0x0063, 0x0068, 0x002d, 0x0053, 0x006f, 0x0072, 0x0074, 0x0069, 0x0065, 0x0072, 0x0072, 0x0065, 0x0067, 0x0065, 0x006c, 0x006e, 0x0000},
2010             {0x0044, 0x0065, 0x0075, 0x0074, 0x0073, 0x0063, 0x0068, 0x0065, 0x0020, 0x004d, 0x0061, 0x0072, 0x006b, 0x0000},
2011         };
2012 
2013         UEnumeration* keywordEnum = uloc_openKeywords(localeID, &status);
2014 
2015         for(keywordCount = 0; keywordCount < uenum_count(keywordEnum, &status) ; keywordCount++){
2016               UChar *displayKeywordValue = NULL;
2017               int32_t displayKeywordValueLen = 0;
2018               if(U_FAILURE(status)){
2019                   log_err("uloc_getKeywords failed for locale id: %s in display locale: % with error : %s \n", localeID, displayLocale, u_errorName(status));
2020                   break;
2021               }
2022               /* the uenum_next returns NUL terminated string */
2023               keyword = uenum_next(keywordEnum, &keywordLen, &status);
2024 
2025               /* fetch the displayKeywordValue */
2026               displayKeywordValueLen = uloc_getDisplayKeywordValue(localeID, keyword, displayLocale, displayKeywordValue, displayKeywordValueLen, &status);
2027               if(status==U_BUFFER_OVERFLOW_ERROR){
2028                   status = U_ZERO_ERROR;
2029                   displayKeywordValueLen++; /* for null termination */
2030                   displayKeywordValue = (UChar*)malloc(displayKeywordValueLen * U_SIZEOF_UCHAR);
2031                   displayKeywordValueLen = uloc_getDisplayKeywordValue(localeID, keyword, displayLocale, displayKeywordValue, displayKeywordValueLen, &status);
2032                   if(U_FAILURE(status)){
2033                       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));
2034                       break;
2035                   }
2036                   if(u_strncmp(displayKeywordValue, expected[keywordCount], displayKeywordValueLen)!=0){
2037                       log_err("uloc_getDisplayKeywordValue did not return the expected value keyword : %s in locale id: %s for display locale: %s \n", localeID, keyword, displayLocale);
2038                       break;
2039                   }
2040               }else{
2041                   log_err("uloc_getDisplayKeywordValue did not return the expected error. Error: %s\n", u_errorName(status));
2042               }
2043               free(displayKeywordValue);
2044         }
2045         uenum_close(keywordEnum);
2046 
2047     }
2048     {
2049         /* Test non existent keywords */
2050         UErrorCode status = U_ZERO_ERROR;
2051         const char* localeID = "es";
2052         const char* displayLocale = "de";
2053         UChar *displayKeywordValue = NULL;
2054         int32_t displayKeywordValueLen = 0;
2055 
2056         /* fetch the displayKeywordValue */
2057         displayKeywordValueLen = uloc_getDisplayKeywordValue(localeID, "calendar", displayLocale, displayKeywordValue, displayKeywordValueLen, &status);
2058         if(U_FAILURE(status)) {
2059           log_err("uloc_getDisplaykeywordValue returned error status %s\n", u_errorName(status));
2060         } else if(displayKeywordValueLen != 0) {
2061           log_err("uloc_getDisplaykeywordValue returned %d should be 0 \n", displayKeywordValueLen);
2062         }
2063     }
2064 }
2065 
2066 
TestGetBaseName(void)2067 static void TestGetBaseName(void) {
2068     static const struct {
2069         const char *localeID;
2070         const char *baseName;
2071     } testCases[] = {
2072         { "de_DE@  C o ll A t i o n   = Phonebook   ", "de_DE" },
2073         { "de@currency = euro; CoLLaTion   = PHONEBOOk", "de" },
2074         { "ja@calendar = buddhist", "ja" }
2075     };
2076 
2077     int32_t i = 0, baseNameLen = 0;
2078     char baseName[256];
2079     UErrorCode status = U_ZERO_ERROR;
2080 
2081     for(i = 0; i < sizeof(testCases)/sizeof(testCases[0]); i++) {
2082         baseNameLen = uloc_getBaseName(testCases[i].localeID, baseName, 256, &status);
2083         if(strcmp(testCases[i].baseName, baseName)) {
2084             log_err("For locale \"%s\" expected baseName \"%s\", but got \"%s\"\n",
2085                 testCases[i].localeID, testCases[i].baseName, baseName);
2086             return;
2087         }
2088     }
2089 
2090 }
2091 
2092 
2093 /* Jitterbug 4115 */
TestDisplayNameWarning(void)2094 static void TestDisplayNameWarning(void) {
2095     UChar name[256];
2096     int32_t size;
2097     UErrorCode status = U_ZERO_ERROR;
2098 
2099     size = uloc_getDisplayLanguage("qqq", "kl", name, sizeof(name)/sizeof(name[0]), &status);
2100     if (status != U_USING_DEFAULT_WARNING) {
2101         log_err("For language \"qqq\" in locale \"kl\", expecting U_USING_DEFAULT_WARNING, but got %s\n",
2102             u_errorName(status));
2103     }
2104 }
2105 
2106 
2107 /**
2108  * Compare two locale IDs.  If they are equal, return 0.  If `string'
2109  * starts with `prefix' plus an additional element, that is, string ==
2110  * prefix + '_' + x, then return 1.  Otherwise return a value < 0.
2111  */
_loccmp(const char * string,const char * prefix)2112 static UBool _loccmp(const char* string, const char* prefix) {
2113     int32_t slen = (int32_t)uprv_strlen(string),
2114             plen = (int32_t)uprv_strlen(prefix);
2115     int32_t c = uprv_strncmp(string, prefix, plen);
2116     /* 'root' is less than everything */
2117     if (uprv_strcmp(prefix, "root") == 0) {
2118         return (uprv_strcmp(string, "root") == 0) ? 0 : 1;
2119     }
2120     if (c) return -1; /* mismatch */
2121     if (slen == plen) return 0;
2122     if (string[plen] == '_') return 1;
2123     return -2; /* false match, e.g. "en_USX" cmp "en_US" */
2124 }
2125 
_checklocs(const char * label,const char * req,const char * valid,const char * actual)2126 static void _checklocs(const char* label,
2127                        const char* req,
2128                        const char* valid,
2129                        const char* actual) {
2130     /* We want the valid to be strictly > the bogus requested locale,
2131        and the valid to be >= the actual. */
2132     if (_loccmp(req, valid) > 0 &&
2133         _loccmp(valid, actual) >= 0) {
2134         log_verbose("%s; req=%s, valid=%s, actual=%s\n",
2135                     label, req, valid, actual);
2136     } else {
2137         log_err("FAIL: %s; req=%s, valid=%s, actual=%s\n",
2138                 label, req, valid, actual);
2139     }
2140 }
2141 
TestGetLocale(void)2142 static void TestGetLocale(void) {
2143     UErrorCode ec = U_ZERO_ERROR;
2144     UParseError pe;
2145     UChar EMPTY[1] = {0};
2146 
2147     /* === udat === */
2148 #if !UCONFIG_NO_FORMATTING
2149     {
2150         UDateFormat *obj;
2151         const char *req = "en_US_REDWOODSHORES", *valid, *actual;
2152         obj = udat_open(UDAT_DEFAULT, UDAT_DEFAULT,
2153                         req,
2154                         NULL, 0,
2155                         NULL, 0, &ec);
2156         if (U_FAILURE(ec)) {
2157             log_err("udat_open failed.Error %s\n", u_errorName(ec));
2158             return;
2159         }
2160         valid = udat_getLocaleByType(obj, ULOC_VALID_LOCALE, &ec);
2161         actual = udat_getLocaleByType(obj, ULOC_ACTUAL_LOCALE, &ec);
2162         if (U_FAILURE(ec)) {
2163             log_err("udat_getLocaleByType() failed\n");
2164             return;
2165         }
2166         _checklocs("udat", req, valid, actual);
2167         udat_close(obj);
2168     }
2169 #endif
2170 
2171     /* === ucal === */
2172 #if !UCONFIG_NO_FORMATTING
2173     {
2174         UCalendar *obj;
2175         const char *req = "fr_FR_PROVENCAL", *valid, *actual;
2176         obj = ucal_open(NULL, 0,
2177                         req,
2178                         UCAL_GREGORIAN,
2179                         &ec);
2180         if (U_FAILURE(ec)) {
2181             log_err("ucal_open failed with error: %s\n", u_errorName(ec));
2182             return;
2183         }
2184         valid = ucal_getLocaleByType(obj, ULOC_VALID_LOCALE, &ec);
2185         actual = ucal_getLocaleByType(obj, ULOC_ACTUAL_LOCALE, &ec);
2186         if (U_FAILURE(ec)) {
2187             log_err("ucal_getLocaleByType() failed\n");
2188             return;
2189         }
2190         _checklocs("ucal", req, valid, actual);
2191         ucal_close(obj);
2192     }
2193 #endif
2194 
2195     /* === unum === */
2196 #if !UCONFIG_NO_FORMATTING
2197     {
2198         UNumberFormat *obj;
2199         const char *req = "zh_Hant_TW_TAINAN", *valid, *actual;
2200         obj = unum_open(UNUM_DECIMAL,
2201                         NULL, 0,
2202                         req,
2203                         &pe, &ec);
2204         if (U_FAILURE(ec)) {
2205             log_err("unum_open failed\n");
2206             return;
2207         }
2208         valid = unum_getLocaleByType(obj, ULOC_VALID_LOCALE, &ec);
2209         actual = unum_getLocaleByType(obj, ULOC_ACTUAL_LOCALE, &ec);
2210         if (U_FAILURE(ec)) {
2211             log_err("unum_getLocaleByType() failed\n");
2212             return;
2213         }
2214         _checklocs("unum", req, valid, actual);
2215         unum_close(obj);
2216     }
2217 #endif
2218 
2219     /* === umsg === */
2220 #if 0
2221     /* commented out by weiv 01/12/2005. umsg_getLocaleByType is to be removed */
2222 #if !UCONFIG_NO_FORMATTING
2223     {
2224         UMessageFormat *obj;
2225         const char *req = "ja_JP_TAKAYAMA", *valid, *actual;
2226         UBool test;
2227         obj = umsg_open(EMPTY, 0,
2228                         req,
2229                         &pe, &ec);
2230         if (U_FAILURE(ec)) {
2231             log_err("umsg_open failed\n");
2232             return;
2233         }
2234         valid = umsg_getLocaleByType(obj, ULOC_VALID_LOCALE, &ec);
2235         actual = umsg_getLocaleByType(obj, ULOC_ACTUAL_LOCALE, &ec);
2236         if (U_FAILURE(ec)) {
2237             log_err("umsg_getLocaleByType() failed\n");
2238             return;
2239         }
2240         /* We want the valid to be strictly > the bogus requested locale,
2241            and the valid to be >= the actual. */
2242         /* TODO MessageFormat is currently just storing the locale it is given.
2243            As a result, it will return whatever it was given, even if the
2244            locale is invalid. */
2245         test = (_cmpversion("3.2") <= 0) ?
2246             /* Here is the weakened test for 3.0: */
2247             (_loccmp(req, valid) >= 0) :
2248             /* Here is what the test line SHOULD be: */
2249             (_loccmp(req, valid) > 0);
2250 
2251         if (test &&
2252             _loccmp(valid, actual) >= 0) {
2253             log_verbose("umsg; req=%s, valid=%s, actual=%s\n", req, valid, actual);
2254         } else {
2255             log_err("FAIL: umsg; req=%s, valid=%s, actual=%s\n", req, valid, actual);
2256         }
2257         umsg_close(obj);
2258     }
2259 #endif
2260 #endif
2261 
2262     /* === ubrk === */
2263 #if !UCONFIG_NO_BREAK_ITERATION
2264     {
2265         UBreakIterator *obj;
2266         const char *req = "ar_KW_ABDALI", *valid, *actual;
2267         obj = ubrk_open(UBRK_WORD,
2268                         req,
2269                         EMPTY,
2270                         0,
2271                         &ec);
2272         if (U_FAILURE(ec)) {
2273             log_err("ubrk_open failed. Error: %s \n", u_errorName(ec));
2274             return;
2275         }
2276         valid = ubrk_getLocaleByType(obj, ULOC_VALID_LOCALE, &ec);
2277         actual = ubrk_getLocaleByType(obj, ULOC_ACTUAL_LOCALE, &ec);
2278         if (U_FAILURE(ec)) {
2279             log_err("ubrk_getLocaleByType() failed\n");
2280             return;
2281         }
2282         _checklocs("ubrk", req, valid, actual);
2283         ubrk_close(obj);
2284     }
2285 #endif
2286 
2287     /* === ucol === */
2288 #if !UCONFIG_NO_COLLATION
2289     {
2290         UCollator *obj;
2291         const char *req = "es_AR_BUENOSAIRES", *valid, *actual;
2292         obj = ucol_open(req, &ec);
2293         if (U_FAILURE(ec)) {
2294             log_err("ucol_open failed\n");
2295             return;
2296         }
2297         valid = ucol_getLocaleByType(obj, ULOC_VALID_LOCALE, &ec);
2298         actual = ucol_getLocaleByType(obj, ULOC_ACTUAL_LOCALE, &ec);
2299         if (U_FAILURE(ec)) {
2300             log_err("ucol_getLocaleByType() failed\n");
2301             return;
2302         }
2303         _checklocs("ucol", req, valid, actual);
2304         ucol_close(obj);
2305     }
2306 #endif
2307 }
2308 
TestNonexistentLanguageExemplars(void)2309 static void TestNonexistentLanguageExemplars(void) {
2310     /* JB 4068 - Nonexistent language */
2311     UErrorCode ec = U_ZERO_ERROR;
2312     ULocaleData *uld = ulocdata_open("qqq",&ec);
2313     if (ec != U_USING_DEFAULT_WARNING) {
2314         log_err("Exemplar set for \"qqq\", expecting U_USING_DEFAULT_WARNING, but got %s\n",
2315             u_errorName(ec));
2316     }
2317     uset_close(ulocdata_getExemplarSet(uld, NULL, 0, ULOCDATA_ES_STANDARD, &ec));
2318     ulocdata_close(uld);
2319 }
2320 
TestLocDataErrorCodeChaining(void)2321 static void TestLocDataErrorCodeChaining(void) {
2322     UErrorCode ec = U_USELESS_COLLATOR_ERROR;
2323     ulocdata_open(NULL, &ec);
2324     ulocdata_getExemplarSet(NULL, NULL, 0, ULOCDATA_ES_STANDARD, &ec);
2325     ulocdata_getDelimiter(NULL, ULOCDATA_DELIMITER_COUNT, NULL, -1, &ec);
2326     ulocdata_getMeasurementSystem(NULL, &ec);
2327     ulocdata_getPaperSize(NULL, NULL, NULL, &ec);
2328     if (ec != U_USELESS_COLLATOR_ERROR) {
2329         log_err("ulocdata API changed the error code to %s\n", u_errorName(ec));
2330     }
2331 }
2332 
TestLanguageExemplarsFallbacks(void)2333 static void TestLanguageExemplarsFallbacks(void) {
2334     /* Test that en_US fallsback, but en doesn't fallback. */
2335     UErrorCode ec = U_ZERO_ERROR;
2336     ULocaleData *uld = ulocdata_open("en_US",&ec);
2337     uset_close(ulocdata_getExemplarSet(uld, NULL, 0, ULOCDATA_ES_STANDARD, &ec));
2338     if (ec != U_USING_FALLBACK_WARNING) {
2339         log_err("Exemplar set for \"en_US\", expecting U_USING_FALLBACK_WARNING, but got %s\n",
2340             u_errorName(ec));
2341     }
2342     ulocdata_close(uld);
2343     ec = U_ZERO_ERROR;
2344     uld = ulocdata_open("en",&ec);
2345     uset_close(ulocdata_getExemplarSet(uld, NULL, 0, ULOCDATA_ES_STANDARD, &ec));
2346     if (ec != U_ZERO_ERROR) {
2347         log_err("Exemplar set for \"en\", expecting U_ZERO_ERROR, but got %s\n",
2348             u_errorName(ec));
2349     }
2350     ulocdata_close(uld);
2351 }
2352 
TestAcceptLanguage(void)2353 static void TestAcceptLanguage(void) {
2354     UErrorCode status = U_ZERO_ERROR;
2355     UAcceptResult outResult;
2356     UEnumeration *available;
2357     char tmp[200];
2358     int i;
2359     int32_t rc = 0;
2360 
2361     struct {
2362         int32_t httpSet;
2363         const char *icuSet;
2364         const char *expect;
2365         UAcceptResult res;
2366     } tests[] = {
2367         /*0*/{ 0, NULL, "mt_MT", ULOC_ACCEPT_VALID },
2368         /*1*/{ 1, NULL, "en", ULOC_ACCEPT_VALID },
2369         /*2*/{ 2, NULL, "en", ULOC_ACCEPT_FALLBACK },
2370         /*3*/{ 3, NULL, "", ULOC_ACCEPT_FAILED },
2371         /*4*/{ 4, NULL, "es", ULOC_ACCEPT_VALID },
2372     };
2373     const int32_t numTests = sizeof(tests)/sizeof(tests[0]);
2374     static const char *http[] = {
2375         /*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",
2376         /*1*/ "ja;q=0.5, en;q=0.8, tlh",
2377         /*2*/ "en-wf, de-lx;q=0.8",
2378         /*3*/ "mga-ie;q=0.9, tlh",
2379         /*4*/ "xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, "
2380               "xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, "
2381               "xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, "
2382               "xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, "
2383               "xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, "
2384               "xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, "
2385               "xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, xx-yy;q=.1, "
2386               "es"
2387     };
2388 
2389     for(i=0;i<numTests;i++) {
2390         outResult = -3;
2391         status=U_ZERO_ERROR;
2392         log_verbose("test #%d: http[%s], ICU[%s], expect %s, %d\n",
2393             i, http[tests[i].httpSet], tests[i].icuSet, tests[i].expect, tests[i].res);
2394 
2395         available = ures_openAvailableLocales(tests[i].icuSet, &status);
2396         tmp[0]=0;
2397         rc = uloc_acceptLanguageFromHTTP(tmp, 199, &outResult, http[tests[i].httpSet], available, &status);
2398         uenum_close(available);
2399         log_verbose(" got %s, %d [%s]\n", tmp[0]?tmp:"(EMPTY)", outResult, u_errorName(status));
2400         if(outResult != tests[i].res) {
2401             log_err("FAIL: #%d: expected outResult of %d but got %d\n", i, tests[i].res, outResult);
2402             log_info("test #%d: http[%s], ICU[%s], expect %s, %d\n",
2403                 i, http[tests[i].httpSet], tests[i].icuSet, tests[i].expect, tests[i].res);
2404         }
2405         if((outResult>0)&&uprv_strcmp(tmp, tests[i].expect)) {
2406             log_err("FAIL: #%d: expected %s but got %s\n", i, tests[i].expect, tmp);
2407             log_info("test #%d: http[%s], ICU[%s], expect %s, %d\n",
2408                 i, http[tests[i].httpSet], tests[i].icuSet, tests[i].expect, tests[i].res);
2409         }
2410     }
2411 }
2412 
2413 static const char* LOCALE_ALIAS[][2] = {
2414     {"in", "id"},
2415     {"in_ID", "id_ID"},
2416     {"iw", "he"},
2417     {"iw_IL", "he_IL"},
2418     {"ji", "yi"},
2419     {"en_BU", "en_MM"},
2420     {"en_DY", "en_BJ"},
2421     {"en_HV", "en_BF"},
2422     {"en_NH", "en_VU"},
2423     {"en_RH", "en_ZW"},
2424     {"en_TP", "en_TL"},
2425     {"en_ZR", "en_CD"}
2426 };
isLocaleAvailable(UResourceBundle * resIndex,const char * loc)2427 static UBool isLocaleAvailable(UResourceBundle* resIndex, const char* loc){
2428     UErrorCode status = U_ZERO_ERROR;
2429     int32_t len = 0;
2430     ures_getStringByKey(resIndex, loc,&len, &status);
2431     if(U_FAILURE(status)){
2432         return FALSE;
2433     }
2434     return TRUE;
2435 }
2436 
TestCalendar()2437 static void TestCalendar() {
2438 #if !UCONFIG_NO_FORMATTING
2439     int i;
2440     UErrorCode status = U_ZERO_ERROR;
2441     UResourceBundle *resIndex = ures_open(NULL,"res_index", &status);
2442     if(U_FAILURE(status)){
2443         log_err("Could not open res_index.res. Exiting. Error: %s\n", u_errorName(status));
2444         return;
2445     }
2446     for (i=0; i<LENGTHOF(LOCALE_ALIAS); i++) {
2447         const char* oldLoc = LOCALE_ALIAS[i][0];
2448         const char* newLoc = LOCALE_ALIAS[i][1];
2449         UCalendar* c1 = NULL;
2450         UCalendar* c2 = NULL;
2451 
2452         /*Test function "getLocale(ULocale.VALID_LOCALE)"*/
2453         const char* l1 = ucal_getLocaleByType(c1, ULOC_VALID_LOCALE, &status);
2454         const char* l2 = ucal_getLocaleByType(c2, ULOC_VALID_LOCALE, &status);
2455 
2456         if(!isLocaleAvailable(resIndex, newLoc)){
2457             continue;
2458         }
2459         c1 = ucal_open(NULL, -1, oldLoc, UCAL_GREGORIAN, &status);
2460         c2 = ucal_open(NULL, -1, newLoc, UCAL_GREGORIAN, &status);
2461 
2462         if (strcmp(newLoc,l1)!=0 || strcmp(l1,l2)!=0 || status!=U_ZERO_ERROR) {
2463             log_err("The locales are not equal!.Old: %s, New: %s \n", oldLoc, newLoc);
2464         }
2465         log_verbose("ucal_getLocaleByType old:%s   new:%s\n", l1, l2);
2466         ucal_close(c1);
2467         ucal_close(c2);
2468     }
2469     ures_close(resIndex);
2470 #endif
2471 }
2472 
TestDateFormat()2473 static void TestDateFormat() {
2474 #if !UCONFIG_NO_FORMATTING
2475     int i;
2476     UErrorCode status = U_ZERO_ERROR;
2477     UResourceBundle *resIndex = ures_open(NULL,"res_index", &status);
2478     if(U_FAILURE(status)){
2479         log_err("Could not open res_index.res. Exiting. Error: %s\n", u_errorName(status));
2480         return;
2481     }
2482     for (i=0; i<LENGTHOF(LOCALE_ALIAS); i++) {
2483         const char* oldLoc = LOCALE_ALIAS[i][0];
2484         const char* newLoc = LOCALE_ALIAS[i][1];
2485         UDateFormat* df1 = NULL;
2486         UDateFormat* df2 = NULL;
2487         const char* l1 = NULL;
2488         const char* l2 = NULL;
2489 
2490         if(!isLocaleAvailable(resIndex, newLoc)){
2491             continue;
2492         }
2493         df1 = udat_open(UDAT_FULL, UDAT_FULL,oldLoc, NULL, 0, NULL, -1, &status);
2494         df2 = udat_open(UDAT_FULL, UDAT_FULL,newLoc, NULL, 0, NULL, -1, &status);
2495         if(U_FAILURE(status)){
2496             log_err("Creation of date format failed  %s\n", u_errorName(status));
2497             return;
2498         }
2499         /*Test function "getLocale"*/
2500         l1 = udat_getLocaleByType(df1, ULOC_VALID_LOCALE, &status);
2501         l2 = udat_getLocaleByType(df2, ULOC_VALID_LOCALE, &status);
2502         if(U_FAILURE(status)){
2503             log_err("Fetching the locale by type failed.  %s\n", u_errorName(status));
2504         }
2505         if (strcmp(newLoc,l1)!=0 || strcmp(l1,l2)!=0) {
2506             log_err("The locales are not equal!.Old: %s, New: %s \n", oldLoc, newLoc);
2507         }
2508         log_verbose("udat_getLocaleByType old:%s   new:%s\n", l1, l2);
2509         udat_close(df1);
2510         udat_close(df2);
2511     }
2512     ures_close(resIndex);
2513 #endif
2514 }
2515 
TestCollation()2516 static void TestCollation() {
2517 #if !UCONFIG_NO_COLLATION
2518     int i;
2519     UErrorCode status = U_ZERO_ERROR;
2520     UResourceBundle *resIndex = ures_open(NULL,"res_index", &status);
2521     if(U_FAILURE(status)){
2522         log_err("Could not open res_index.res. Exiting. Error: %s\n", u_errorName(status));
2523         return;
2524     }
2525     for (i=0; i<LENGTHOF(LOCALE_ALIAS); i++) {
2526         const char* oldLoc = LOCALE_ALIAS[i][0];
2527         const char* newLoc = LOCALE_ALIAS[i][1];
2528         UCollator* c1 = NULL;
2529         UCollator* c2 = NULL;
2530         const char* l1 = NULL;
2531         const char* l2 = NULL;
2532 
2533         status = U_ZERO_ERROR;
2534         if(!isLocaleAvailable(resIndex, newLoc)){
2535             continue;
2536         }
2537         if(U_FAILURE(status)){
2538             log_err("Creation of collators failed  %s\n", u_errorName(status));
2539             return;
2540         }
2541         c1 = ucol_open(oldLoc, &status);
2542         c2 = ucol_open(newLoc, &status);
2543         l1 = ucol_getLocaleByType(c1, ULOC_VALID_LOCALE, &status);
2544         l2 = ucol_getLocaleByType(c2, ULOC_VALID_LOCALE, &status);
2545         if(U_FAILURE(status)){
2546             log_err("Fetching the locale names failed failed  %s\n", u_errorName(status));
2547         }
2548         if (strcmp(newLoc,l1)!=0 || strcmp(l1,l2)!=0) {
2549             log_err("The locales are not equal!.Old: %s, New: %s \n", oldLoc, newLoc);
2550         }
2551         log_verbose("ucol_getLocaleByType old:%s   new:%s\n", l1, l2);
2552         ucol_close(c1);
2553         ucol_close(c2);
2554     }
2555     ures_close(resIndex);
2556 #endif
2557 }
2558 
TestULocale()2559 static void  TestULocale() {
2560     int i;
2561     UErrorCode status = U_ZERO_ERROR;
2562     UResourceBundle *resIndex = ures_open(NULL,"res_index", &status);
2563     if(U_FAILURE(status)){
2564         log_err("Could not open res_index.res. Exiting. Error: %s\n", u_errorName(status));
2565         return;
2566     }
2567     for (i=0; i<LENGTHOF(LOCALE_ALIAS); i++) {
2568         const char* oldLoc = LOCALE_ALIAS[i][0];
2569         const char* newLoc = LOCALE_ALIAS[i][1];
2570         UChar name1[256], name2[256];
2571         char names1[256], names2[256];
2572         int32_t capacity = 256;
2573 
2574         status = U_ZERO_ERROR;
2575         if(!isLocaleAvailable(resIndex, newLoc)){
2576             continue;
2577         }
2578         uloc_getDisplayName(oldLoc, ULOC_US, name1, capacity, &status);
2579         if(U_FAILURE(status)){
2580             log_err("uloc_getDisplayName(%s) failed %s\n", oldLoc, u_errorName(status));
2581         }
2582 
2583         uloc_getDisplayName(newLoc, ULOC_US, name2, capacity, &status);
2584         if(U_FAILURE(status)){
2585             log_err("uloc_getDisplayName(%s) failed %s\n", newLoc, u_errorName(status));
2586         }
2587 
2588         if (u_strcmp(name1, name2)!=0) {
2589             log_err("The locales are not equal!.Old: %s, New: %s \n", oldLoc, newLoc);
2590         }
2591         u_austrcpy(names1, name1);
2592         u_austrcpy(names2, name2);
2593         log_verbose("uloc_getDisplayName old:%s   new:%s\n", names1, names2);
2594     }
2595     ures_close(resIndex);
2596 
2597 }
2598 
TestUResourceBundle()2599 static void TestUResourceBundle() {
2600     const char* us1;
2601     const char* us2;
2602 
2603     UResourceBundle* rb1 = NULL;
2604     UResourceBundle* rb2 = NULL;
2605     UErrorCode status = U_ZERO_ERROR;
2606     int i;
2607     UResourceBundle *resIndex = NULL;
2608     if(U_FAILURE(status)){
2609         log_err("Could not open res_index.res. Exiting. Error: %s\n", u_errorName(status));
2610         return;
2611     }
2612     resIndex = ures_open(NULL,"res_index", &status);
2613     for (i=0; i<LENGTHOF(LOCALE_ALIAS); i++) {
2614 
2615         const char* oldLoc = LOCALE_ALIAS[i][0];
2616         const char* newLoc = LOCALE_ALIAS[i][1];
2617         if(!isLocaleAvailable(resIndex, newLoc)){
2618             continue;
2619         }
2620         rb1 = ures_open(NULL, oldLoc, &status);
2621         if (U_FAILURE(status)) {
2622             log_err("ures_open(%s) failed %s\n", oldLoc, u_errorName(status));
2623         }
2624 
2625         us1 = ures_getLocale(rb1, &status);
2626 
2627         status = U_ZERO_ERROR;
2628         rb2 = ures_open(NULL, newLoc, &status);
2629         if (U_FAILURE(status)) {
2630             log_err("ures_open(%s) failed %s\n", oldLoc, u_errorName(status));
2631         }
2632         us2 = ures_getLocale(rb2, &status);
2633 
2634         if (strcmp(us1,newLoc)!=0 || strcmp(us1,us2)!=0 ) {
2635             log_err("The locales are not equal!.Old: %s, New: %s \n", oldLoc, newLoc);
2636         }
2637 
2638         log_verbose("ures_getStringByKey old:%s   new:%s\n", us1, us2);
2639         ures_close(rb1);
2640         rb1 = NULL;
2641         ures_close(rb2);
2642         rb2 = NULL;
2643     }
2644     ures_close(resIndex);
2645 }
2646 
TestDisplayName()2647 static void TestDisplayName() {
2648 
2649     UChar oldCountry[256] = {'\0'};
2650     UChar newCountry[256] = {'\0'};
2651     UChar oldLang[256] = {'\0'};
2652     UChar newLang[256] = {'\0'};
2653     char country[256] ={'\0'};
2654     char language[256] ={'\0'};
2655     int32_t capacity = 256;
2656     int i =0;
2657     int j=0;
2658     for (i=0; i<LENGTHOF(LOCALE_ALIAS); i++) {
2659         const char* oldLoc = LOCALE_ALIAS[i][0];
2660         const char* newLoc = LOCALE_ALIAS[i][1];
2661         UErrorCode status = U_ZERO_ERROR;
2662         int32_t available = uloc_countAvailable();
2663 
2664         for(j=0; j<available; j++){
2665 
2666             const char* dispLoc = uloc_getAvailable(j);
2667             int32_t oldCountryLen = uloc_getDisplayCountry(oldLoc,dispLoc, oldCountry, capacity, &status);
2668             int32_t newCountryLen = uloc_getDisplayCountry(newLoc, dispLoc, newCountry, capacity, &status);
2669             int32_t oldLangLen = uloc_getDisplayLanguage(oldLoc, dispLoc, oldLang, capacity, &status);
2670             int32_t newLangLen = uloc_getDisplayLanguage(newLoc, dispLoc, newLang, capacity, &status );
2671 
2672             int32_t countryLen = uloc_getCountry(newLoc, country, capacity, &status);
2673             int32_t langLen  = uloc_getLanguage(newLoc, language, capacity, &status);
2674             /* there is a display name for the current country ID */
2675             if(countryLen != newCountryLen ){
2676                 if(u_strncmp(oldCountry,newCountry,oldCountryLen)!=0){
2677                     log_err("uloc_getDisplayCountry() failed for %s in display locale %s \n", oldLoc, dispLoc);
2678                 }
2679             }
2680             /* there is a display name for the current lang ID */
2681             if(langLen!=newLangLen){
2682                 if(u_strncmp(oldLang,newLang,oldLangLen)){
2683                     log_err("uloc_getDisplayLanguage() failed for %s in display locale %s \n", oldLoc, dispLoc);                }
2684             }
2685         }
2686     }
2687 }
2688 
TestGetLocaleForLCID()2689 static void TestGetLocaleForLCID() {
2690     int32_t i, length, lengthPre;
2691     const char* testLocale = 0;
2692     UErrorCode status = U_ZERO_ERROR;
2693     char            temp2[40], temp3[40];
2694     uint32_t lcid;
2695 
2696     lcid = uloc_getLCID("en_US");
2697     if (lcid != 0x0409) {
2698         log_err("  uloc_getLCID(\"en_US\") = %d, expected 0x0409\n", lcid);
2699     }
2700 
2701     lengthPre = uloc_getLocaleForLCID(lcid, temp2, 4, &status);
2702     if (status != U_BUFFER_OVERFLOW_ERROR) {
2703         log_err("  unexpected result from uloc_getLocaleForLCID with small buffer: %s\n", u_errorName(status));
2704     }
2705     else {
2706         status = U_ZERO_ERROR;
2707     }
2708 
2709     length = uloc_getLocaleForLCID(lcid, temp2, sizeof(temp2)/sizeof(char), &status);
2710     if (U_FAILURE(status)) {
2711         log_err("  unexpected result from uloc_getLocaleForLCID(0x0409): %s\n", u_errorName(status));
2712         status = U_ZERO_ERROR;
2713     }
2714 
2715     if (length != lengthPre) {
2716         log_err("  uloc_getLocaleForLCID(0x0409): returned length %d does not match preflight length %d\n", length, lengthPre);
2717     }
2718 
2719     length = uloc_getLocaleForLCID(0x12345, temp2, sizeof(temp2)/sizeof(char), &status);
2720     if (U_SUCCESS(status)) {
2721         log_err("  unexpected result from uloc_getLocaleForLCID(0x12345): %s, status %s\n", temp2, u_errorName(status));
2722     }
2723     status = U_ZERO_ERROR;
2724 
2725     log_verbose("Testing getLocaleForLCID vs. locale data\n");
2726     for (i = 0; i < LOCALE_SIZE; i++) {
2727 
2728         testLocale=rawData2[NAME][i];
2729 
2730         log_verbose("Testing   %s ......\n", testLocale);
2731 
2732         sscanf(rawData2[LCID][i], "%x", &lcid);
2733         length = uloc_getLocaleForLCID(lcid, temp2, sizeof(temp2)/sizeof(char), &status);
2734         if (U_FAILURE(status)) {
2735             log_err("  unexpected failure of uloc_getLocaleForLCID(%#04x), status %s\n", lcid, u_errorName(status));
2736             status = U_ZERO_ERROR;
2737             continue;
2738         }
2739 
2740         if (length != uprv_strlen(temp2)) {
2741             log_err("  returned length %d not correct for uloc_getLocaleForLCID(%#04x), expected %d\n", length, lcid, uprv_strlen(temp2));
2742         }
2743 
2744         /* Compare language, country, script */
2745         length = uloc_getLanguage(temp2, temp3, sizeof(temp3)/sizeof(char), &status);
2746         if (U_FAILURE(status)) {
2747             log_err("  couldn't get language in uloc_getLocaleForLCID(%#04x) = %s, status %s\n", lcid, temp2, u_errorName(status));
2748             status = U_ZERO_ERROR;
2749         }
2750         else if (uprv_strcmp(temp3, rawData2[LANG][i]) && !(uprv_strcmp(temp3, "nn") == 0 && uprv_strcmp(rawData2[VAR][i], "NY") == 0)) {
2751             log_err("  language doesn't match expected %s in in uloc_getLocaleForLCID(%#04x) = %s\n", rawData2[LANG][i], lcid, temp2);
2752         }
2753 
2754         length = uloc_getScript(temp2, temp3, sizeof(temp3)/sizeof(char), &status);
2755         if (U_FAILURE(status)) {
2756             log_err("  couldn't get script in uloc_getLocaleForLCID(%#04x) = %s, status %s\n", lcid, temp2, u_errorName(status));
2757             status = U_ZERO_ERROR;
2758         }
2759         else if (uprv_strcmp(temp3, rawData2[SCRIPT][i])) {
2760             log_err("  script doesn't match expected %s in in uloc_getLocaleForLCID(%#04x) = %s\n", rawData2[SCRIPT][i], lcid, temp2);
2761         }
2762 
2763         length = uloc_getCountry(temp2, temp3, sizeof(temp3)/sizeof(char), &status);
2764         if (U_FAILURE(status)) {
2765             log_err("  couldn't get country in uloc_getLocaleForLCID(%#04x) = %s, status %s\n", lcid, temp2, u_errorName(status));
2766             status = U_ZERO_ERROR;
2767         }
2768         else if (uprv_strlen(rawData2[CTRY][i]) && uprv_strcmp(temp3, rawData2[CTRY][i])) {
2769             log_err("  country doesn't match expected %s in in uloc_getLocaleForLCID(%#04x) = %s\n", rawData2[CTRY][i], lcid, temp2);
2770         }
2771     }
2772 
2773 }
2774 
2775