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