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