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