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