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