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