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