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