+
+static void TestULocale() {
+ int i;
+ UErrorCode status = U_ZERO_ERROR;
+ UResourceBundle *resIndex = ures_open(NULL,"res_index", &status);
+ if(U_FAILURE(status)){
+ log_err_status(status, "Could not open res_index.res. Exiting. Error: %s\n", u_errorName(status));
+ return;
+ }
+ for (i=0; i<UPRV_LENGTHOF(LOCALE_ALIAS); i++) {
+ const char* oldLoc = LOCALE_ALIAS[i][0];
+ const char* newLoc = LOCALE_ALIAS[i][1];
+ UChar name1[256], name2[256];
+ char names1[256], names2[256];
+ int32_t capacity = 256;
+
+ status = U_ZERO_ERROR;
+ if(!isLocaleAvailable(resIndex, newLoc)){
+ continue;
+ }
+ uloc_getDisplayName(oldLoc, ULOC_US, name1, capacity, &status);
+ if(U_FAILURE(status)){
+ log_err("uloc_getDisplayName(%s) failed %s\n", oldLoc, u_errorName(status));
+ }
+
+ uloc_getDisplayName(newLoc, ULOC_US, name2, capacity, &status);
+ if(U_FAILURE(status)){
+ log_err("uloc_getDisplayName(%s) failed %s\n", newLoc, u_errorName(status));
+ }
+
+ if (u_strcmp(name1, name2)!=0) {
+ log_err("The locales are not equal!.Old: %s, New: %s \n", oldLoc, newLoc);
+ }
+ u_austrcpy(names1, name1);
+ u_austrcpy(names2, name2);
+ log_verbose("uloc_getDisplayName old:%s new:%s\n", names1, names2);
+ }
+ ures_close(resIndex);
+
+}
+
+static void TestUResourceBundle() {
+ const char* us1;
+ const char* us2;
+
+ UResourceBundle* rb1 = NULL;
+ UResourceBundle* rb2 = NULL;
+ UErrorCode status = U_ZERO_ERROR;
+ int i;
+ UResourceBundle *resIndex = NULL;
+ if(U_FAILURE(status)){
+ log_err("Could not open res_index.res. Exiting. Error: %s\n", u_errorName(status));
+ return;
+ }
+ resIndex = ures_open(NULL,"res_index", &status);
+ for (i=0; i<UPRV_LENGTHOF(LOCALE_ALIAS); i++) {
+
+ const char* oldLoc = LOCALE_ALIAS[i][0];
+ const char* newLoc = LOCALE_ALIAS[i][1];
+ if(!isLocaleAvailable(resIndex, newLoc)){
+ continue;
+ }
+ rb1 = ures_open(NULL, oldLoc, &status);
+ if (U_FAILURE(status)) {
+ log_err("ures_open(%s) failed %s\n", oldLoc, u_errorName(status));
+ }
+
+ us1 = ures_getLocaleByType(rb1, ULOC_ACTUAL_LOCALE, &status);
+
+ status = U_ZERO_ERROR;
+ rb2 = ures_open(NULL, newLoc, &status);
+ if (U_FAILURE(status)) {
+ log_err("ures_open(%s) failed %s\n", oldLoc, u_errorName(status));
+ }
+ us2 = ures_getLocaleByType(rb2, ULOC_ACTUAL_LOCALE, &status);
+
+ if (strcmp(us1,newLoc)!=0 || strcmp(us1,us2)!=0 ) {
+ log_err("The locales are not equal!.Old: %s, New: %s \n", oldLoc, newLoc);
+ }
+
+ log_verbose("ures_getStringByKey old:%s new:%s\n", us1, us2);
+ ures_close(rb1);
+ rb1 = NULL;
+ ures_close(rb2);
+ rb2 = NULL;
+ }
+ ures_close(resIndex);
+}
+
+static void TestDisplayName() {
+
+ UChar oldCountry[256] = {'\0'};
+ UChar newCountry[256] = {'\0'};
+ UChar oldLang[256] = {'\0'};
+ UChar newLang[256] = {'\0'};
+ char country[256] ={'\0'};
+ char language[256] ={'\0'};
+ int32_t capacity = 256;
+ int i =0;
+ int j=0;
+ for (i=0; i<UPRV_LENGTHOF(LOCALE_ALIAS); i++) {
+ const char* oldLoc = LOCALE_ALIAS[i][0];
+ const char* newLoc = LOCALE_ALIAS[i][1];
+ UErrorCode status = U_ZERO_ERROR;
+ int32_t available = uloc_countAvailable();
+
+ for(j=0; j<available; j++){
+
+ const char* dispLoc = uloc_getAvailable(j);
+ int32_t oldCountryLen = uloc_getDisplayCountry(oldLoc,dispLoc, oldCountry, capacity, &status);
+ int32_t newCountryLen = uloc_getDisplayCountry(newLoc, dispLoc, newCountry, capacity, &status);
+ int32_t oldLangLen = uloc_getDisplayLanguage(oldLoc, dispLoc, oldLang, capacity, &status);
+ int32_t newLangLen = uloc_getDisplayLanguage(newLoc, dispLoc, newLang, capacity, &status );
+
+ int32_t countryLen = uloc_getCountry(newLoc, country, capacity, &status);
+ int32_t langLen = uloc_getLanguage(newLoc, language, capacity, &status);
+ /* there is a display name for the current country ID */
+ if(countryLen != newCountryLen ){
+ if(u_strncmp(oldCountry,newCountry,oldCountryLen)!=0){
+ log_err("uloc_getDisplayCountry() failed for %s in display locale %s \n", oldLoc, dispLoc);
+ }
+ }
+ /* there is a display name for the current lang ID */
+ if(langLen!=newLangLen){
+ if(u_strncmp(oldLang,newLang,oldLangLen)){
+ log_err("uloc_getDisplayLanguage() failed for %s in display locale %s \n", oldLoc, dispLoc); }
+ }
+ }
+ }
+}
+
+static void TestGetLocaleForLCID() {
+ int32_t i, length, lengthPre;
+ const char* testLocale = 0;
+ UErrorCode status = U_ZERO_ERROR;
+ char temp2[40], temp3[40];
+ uint32_t lcid;
+
+ lcid = uloc_getLCID("en_US");
+ if (lcid != 0x0409) {
+ log_err(" uloc_getLCID(\"en_US\") = %d, expected 0x0409\n", lcid);
+ }
+
+ lengthPre = uloc_getLocaleForLCID(lcid, temp2, 4, &status);
+ if (status != U_BUFFER_OVERFLOW_ERROR) {
+ log_err(" unexpected result from uloc_getLocaleForLCID with small buffer: %s\n", u_errorName(status));
+ }
+ else {
+ status = U_ZERO_ERROR;
+ }
+
+ length = uloc_getLocaleForLCID(lcid, temp2, UPRV_LENGTHOF(temp2), &status);
+ if (U_FAILURE(status)) {
+ log_err(" unexpected result from uloc_getLocaleForLCID(0x0409): %s\n", u_errorName(status));
+ status = U_ZERO_ERROR;
+ }
+
+ if (length != lengthPre) {
+ log_err(" uloc_getLocaleForLCID(0x0409): returned length %d does not match preflight length %d\n", length, lengthPre);
+ }
+
+ length = uloc_getLocaleForLCID(0x12345, temp2, UPRV_LENGTHOF(temp2), &status);
+ if (U_SUCCESS(status)) {
+ log_err(" unexpected result from uloc_getLocaleForLCID(0x12345): %s, status %s\n", temp2, u_errorName(status));
+ }
+ status = U_ZERO_ERROR;
+
+ log_verbose("Testing getLocaleForLCID vs. locale data\n");
+ for (i = 0; i < LOCALE_SIZE; i++) {
+
+ testLocale=rawData2[NAME][i];
+
+ log_verbose("Testing %s ......\n", testLocale);
+
+ sscanf(rawData2[LCID][i], "%x", &lcid);
+ length = uloc_getLocaleForLCID(lcid, temp2, UPRV_LENGTHOF(temp2), &status);
+ if (U_FAILURE(status)) {
+ log_err(" unexpected failure of uloc_getLocaleForLCID(%#04x), status %s\n", lcid, u_errorName(status));
+ status = U_ZERO_ERROR;
+ continue;
+ }
+
+ if (length != uprv_strlen(temp2)) {
+ log_err(" returned length %d not correct for uloc_getLocaleForLCID(%#04x), expected %d\n", length, lcid, uprv_strlen(temp2));
+ }
+
+ /* Compare language, country, script */
+ length = uloc_getLanguage(temp2, temp3, UPRV_LENGTHOF(temp3), &status);
+ if (U_FAILURE(status)) {
+ log_err(" couldn't get language in uloc_getLocaleForLCID(%#04x) = %s, status %s\n", lcid, temp2, u_errorName(status));
+ status = U_ZERO_ERROR;
+ }
+ else if (uprv_strcmp(temp3, rawData2[LANG][i]) && !(uprv_strcmp(temp3, "nn") == 0 && uprv_strcmp(rawData2[VAR][i], "NY") == 0)) {
+ log_err(" language doesn't match expected %s in in uloc_getLocaleForLCID(%#04x) = %s\n", rawData2[LANG][i], lcid, temp2);
+ }
+
+ length = uloc_getScript(temp2, temp3, UPRV_LENGTHOF(temp3), &status);
+ if (U_FAILURE(status)) {
+ log_err(" couldn't get script in uloc_getLocaleForLCID(%#04x) = %s, status %s\n", lcid, temp2, u_errorName(status));
+ status = U_ZERO_ERROR;
+ }
+ else if (uprv_strcmp(temp3, rawData2[SCRIPT][i])) {
+ log_err(" script doesn't match expected %s in in uloc_getLocaleForLCID(%#04x) = %s\n", rawData2[SCRIPT][i], lcid, temp2);
+ }
+
+ length = uloc_getCountry(temp2, temp3, UPRV_LENGTHOF(temp3), &status);
+ if (U_FAILURE(status)) {
+ log_err(" couldn't get country in uloc_getLocaleForLCID(%#04x) = %s, status %s\n", lcid, temp2, u_errorName(status));
+ status = U_ZERO_ERROR;
+ }
+ else if (uprv_strlen(rawData2[CTRY][i]) && uprv_strcmp(temp3, rawData2[CTRY][i])) {
+ log_err(" country doesn't match expected %s in in uloc_getLocaleForLCID(%#04x) = %s\n", rawData2[CTRY][i], lcid, temp2);
+ }
+ }
+
+}
+
+const char* const basic_maximize_data[][2] = {
+ {
+ "zu_Zzzz_Zz",
+ "zu_Latn_ZA",
+ }, {
+ "ZU_Zz",
+ "zu_Latn_ZA"
+ }, {
+ "zu_LATN",
+ "zu_Latn_ZA"
+ }, {
+ "en_Zz",
+ "en_Latn_US"
+ }, {
+ "en_us",
+ "en_Latn_US"
+ }, {
+ "en_Kore",
+ "en_Kore_US"
+ }, {
+ "en_Kore_Zz",
+ "en_Kore_US"
+ }, {
+ "en_Kore_ZA",
+ "en_Kore_ZA"
+ }, {
+ "en_Kore_ZA_POSIX",
+ "en_Kore_ZA_POSIX"
+ }, {
+ "en_Gujr",
+ "en_Gujr_US"
+ }, {
+ "en_ZA",
+ "en_Latn_ZA"
+ }, {
+ "en_Gujr_Zz",
+ "en_Gujr_US"
+ }, {
+ "en_Gujr_ZA",
+ "en_Gujr_ZA"
+ }, {
+ "en_Gujr_ZA_POSIX",
+ "en_Gujr_ZA_POSIX"
+ }, {
+ "en_US_POSIX_1901",
+ "en_Latn_US_POSIX_1901"
+ }, {
+ "en_Latn__POSIX_1901",
+ "en_Latn_US_POSIX_1901"
+ }, {
+ "en__POSIX_1901",
+ "en_Latn_US_POSIX_1901"
+ }, {
+ "de__POSIX_1901",
+ "de_Latn_DE_POSIX_1901"
+ }, {
+ "en_US_BOSTON",
+ "en_Latn_US_BOSTON"
+ }, {
+ "th@calendar=buddhist",
+ "th_Thai_TH@calendar=buddhist"
+ }, {
+ "ar_ZZ",
+ "ar_Arab_EG"
+ }, {
+ "zh",
+ "zh_Hans_CN"
+ }, {
+ "zh_TW",
+ "zh_Hant_TW"
+ }, {
+ "zh_HK",
+ "zh_Hant_HK"
+ }, {
+ "zh_Hant",
+ "zh_Hant_TW"
+ }, {
+ "zh_Zzzz_CN",
+ "zh_Hans_CN"
+ }, {
+ "und_US",
+ "en_Latn_US"
+ }, {
+ "und_HK",
+ "zh_Hant_HK"
+ }, {
+ "zzz",
+ ""
+ }, {
+ "de_u_co_phonebk",
+ "de_Latn_DE_U_CO_PHONEBK"
+ }, {
+ "de_Latn_u_co_phonebk",
+ "de_Latn_DE_U_CO_PHONEBK"
+ }, {
+ "de_Latn_DE_u_co_phonebk",
+ "de_Latn_DE_U_CO_PHONEBK"
+ }, {
+ "_Arab@em=emoji",
+ "ar_Arab_EG@em=emoji"
+ }, {
+ "_Latn@em=emoji",
+ "en_Latn_US@em=emoji"
+ }, {
+ "_Latn_DE@em=emoji",
+ "de_Latn_DE@em=emoji"
+ }, {
+ "_Zzzz_DE@em=emoji",
+ "de_Latn_DE@em=emoji"
+ }, {
+ "_DE@em=emoji",
+ "de_Latn_DE@em=emoji"
+ }
+};
+
+const char* const basic_minimize_data[][2] = {
+ {
+ "en_Latn_US",
+ "en"
+ }, {
+ "en_Latn_US_POSIX_1901",
+ "en__POSIX_1901"
+ }, {
+ "EN_Latn_US_POSIX_1901",
+ "en__POSIX_1901"
+ }, {
+ "en_Zzzz_US_POSIX_1901",
+ "en__POSIX_1901"
+ }, {
+ "de_Latn_DE_POSIX_1901",
+ "de__POSIX_1901"
+ }, {
+ "und",
+ ""
+ }, {
+ "en_Latn_US@calendar=gregorian",
+ "en@calendar=gregorian"
+ }
+};
+
+const char* const full_data[][3] = {
+ {
+ /* "FROM", */
+ /* "ADD-LIKELY", */
+ /* "REMOVE-LIKELY" */
+ /* }, { */
+ "aa",
+ "aa_Latn_ET",
+ "aa"
+ }, {
+ "af",
+ "af_Latn_ZA",
+ "af"
+ }, {
+ "ak",
+ "ak_Latn_GH",
+ "ak"
+ }, {
+ "am",
+ "am_Ethi_ET",
+ "am"
+ }, {
+ "ar",
+ "ar_Arab_EG",
+ "ar"
+ }, {
+ "as",
+ "as_Beng_IN",
+ "as"
+ }, {
+ "az",
+ "az_Latn_AZ",
+ "az"
+ }, {
+ "be",
+ "be_Cyrl_BY",
+ "be"
+ }, {
+ "bg",
+ "bg_Cyrl_BG",
+ "bg"
+ }, {
+ "bn",
+ "bn_Beng_BD",
+ "bn"
+ }, {
+ "bo",
+ "bo_Tibt_CN",
+ "bo"
+ }, {
+ "bs",
+ "bs_Latn_BA",
+ "bs"
+ }, {
+ "ca",
+ "ca_Latn_ES",
+ "ca"
+ }, {
+ "ch",
+ "ch_Latn_GU",
+ "ch"
+ }, {
+ "chk",
+ "chk_Latn_FM",
+ "chk"
+ }, {
+ "cs",
+ "cs_Latn_CZ",
+ "cs"
+ }, {
+ "cy",
+ "cy_Latn_GB",
+ "cy"
+ }, {
+ "da",
+ "da_Latn_DK",
+ "da"
+ }, {
+ "de",
+ "de_Latn_DE",
+ "de"
+ }, {
+ "dv",
+ "dv_Thaa_MV",
+ "dv"
+ }, {
+ "dz",
+ "dz_Tibt_BT",
+ "dz"
+ }, {
+ "ee",
+ "ee_Latn_GH",
+ "ee"
+ }, {
+ "el",
+ "el_Grek_GR",
+ "el"
+ }, {
+ "en",
+ "en_Latn_US",
+ "en"
+ }, {
+ "es",
+ "es_Latn_ES",
+ "es"
+ }, {
+ "et",
+ "et_Latn_EE",
+ "et"
+ }, {
+ "eu",
+ "eu_Latn_ES",
+ "eu"
+ }, {
+ "fa",
+ "fa_Arab_IR",
+ "fa"
+ }, {
+ "fi",
+ "fi_Latn_FI",
+ "fi"
+ }, {
+ "fil",
+ "fil_Latn_PH",
+ "fil"
+ }, {
+ "fo",
+ "fo_Latn_FO",
+ "fo"
+ }, {
+ "fr",
+ "fr_Latn_FR",
+ "fr"
+ }, {
+ "fur",
+ "fur_Latn_IT",
+ "fur"
+ }, {
+ "ga",
+ "ga_Latn_IE",
+ "ga"
+ }, {
+ "gaa",
+ "gaa_Latn_GH",
+ "gaa"
+ }, {
+ "gl",
+ "gl_Latn_ES",
+ "gl"
+ }, {
+ "gn",
+ "gn_Latn_PY",
+ "gn"
+ }, {
+ "gu",
+ "gu_Gujr_IN",
+ "gu"
+ }, {
+ "ha",
+ "ha_Latn_NG",
+ "ha"
+ }, {
+ "haw",
+ "haw_Latn_US",
+ "haw"
+ }, {
+ "he",
+ "he_Hebr_IL",
+ "he"
+ }, {
+ "hi",
+ "hi_Deva_IN",
+ "hi"
+ }, {
+ "hr",
+ "hr_Latn_HR",
+ "hr"
+ }, {
+ "ht",
+ "ht_Latn_HT",
+ "ht"
+ }, {
+ "hu",
+ "hu_Latn_HU",
+ "hu"
+ }, {
+ "hy",
+ "hy_Armn_AM",
+ "hy"
+ }, {
+ "id",
+ "id_Latn_ID",
+ "id"
+ }, {
+ "ig",
+ "ig_Latn_NG",
+ "ig"
+ }, {
+ "ii",
+ "ii_Yiii_CN",
+ "ii"
+ }, {
+ "is",
+ "is_Latn_IS",
+ "is"
+ }, {
+ "it",
+ "it_Latn_IT",
+ "it"
+ }, {
+ "ja",
+ "ja_Jpan_JP",
+ "ja"
+ }, {
+ "ka",
+ "ka_Geor_GE",
+ "ka"
+ }, {
+ "kaj",
+ "kaj_Latn_NG",
+ "kaj"
+ }, {
+ "kam",
+ "kam_Latn_KE",
+ "kam"
+ }, {
+ "kk",
+ "kk_Cyrl_KZ",
+ "kk"
+ }, {
+ "kl",
+ "kl_Latn_GL",
+ "kl"
+ }, {
+ "km",
+ "km_Khmr_KH",
+ "km"
+ }, {
+ "kn",
+ "kn_Knda_IN",
+ "kn"
+ }, {
+ "ko",
+ "ko_Kore_KR",
+ "ko"
+ }, {
+ "kok",
+ "kok_Deva_IN",
+ "kok"
+ }, {
+ "kpe",
+ "kpe_Latn_LR",
+ "kpe"
+ }, {
+ "ku",
+ "ku_Latn_TR",
+ "ku"
+ }, {
+ "ky",
+ "ky_Cyrl_KG",
+ "ky"
+ }, {
+ "la",
+ "la_Latn_VA",
+ "la"
+ }, {
+ "ln",
+ "ln_Latn_CD",
+ "ln"
+ }, {
+ "lo",
+ "lo_Laoo_LA",
+ "lo"
+ }, {
+ "lt",
+ "lt_Latn_LT",
+ "lt"
+ }, {
+ "lv",
+ "lv_Latn_LV",
+ "lv"
+ }, {
+ "mg",
+ "mg_Latn_MG",
+ "mg"
+ }, {
+ "mh",
+ "mh_Latn_MH",
+ "mh"
+ }, {
+ "mk",
+ "mk_Cyrl_MK",
+ "mk"
+ }, {
+ "ml",
+ "ml_Mlym_IN",
+ "ml"
+ }, {
+ "mn",
+ "mn_Cyrl_MN",
+ "mn"
+ }, {
+ "mr",
+ "mr_Deva_IN",
+ "mr"
+ }, {
+ "ms",
+ "ms_Latn_MY",
+ "ms"
+ }, {
+ "mt",
+ "mt_Latn_MT",
+ "mt"
+ }, {
+ "my",
+ "my_Mymr_MM",
+ "my"
+ }, {
+ "na",
+ "na_Latn_NR",
+ "na"
+ }, {
+ "ne",
+ "ne_Deva_NP",
+ "ne"
+ }, {
+ "niu",
+ "niu_Latn_NU",
+ "niu"
+ }, {
+ "nl",
+ "nl_Latn_NL",
+ "nl"
+ }, {
+ "nn",
+ "nn_Latn_NO",
+ "nn"
+ }, {
+ "nr",
+ "nr_Latn_ZA",
+ "nr"
+ }, {
+ "nso",
+ "nso_Latn_ZA",
+ "nso"
+ }, {
+ "ny",
+ "ny_Latn_MW",
+ "ny"
+ }, {
+ "om",
+ "om_Latn_ET",
+ "om"
+ }, {
+ "or",
+ "or_Orya_IN",
+ "or"
+ }, {
+ "pa",
+ "pa_Guru_IN",
+ "pa"
+ }, {
+ "pa_Arab",
+ "pa_Arab_PK",
+ "pa_PK"
+ }, {
+ "pa_PK",
+ "pa_Arab_PK",
+ "pa_PK"
+ }, {
+ "pap",
+ "pap_Latn_AW",
+ "pap"
+ }, {
+ "pau",
+ "pau_Latn_PW",
+ "pau"
+ }, {
+ "pl",
+ "pl_Latn_PL",
+ "pl"
+ }, {
+ "ps",
+ "ps_Arab_AF",
+ "ps"
+ }, {
+ "pt",
+ "pt_Latn_BR",
+ "pt"
+ }, {
+ "rn",
+ "rn_Latn_BI",
+ "rn"
+ }, {
+ "ro",
+ "ro_Latn_RO",
+ "ro"
+ }, {
+ "ru",
+ "ru_Cyrl_RU",
+ "ru"
+ }, {
+ "rw",
+ "rw_Latn_RW",
+ "rw"
+ }, {
+ "sa",
+ "sa_Deva_IN",
+ "sa"
+ }, {
+ "se",
+ "se_Latn_NO",
+ "se"
+ }, {
+ "sg",
+ "sg_Latn_CF",
+ "sg"
+ }, {
+ "si",
+ "si_Sinh_LK",
+ "si"
+ }, {
+ "sid",
+ "sid_Latn_ET",
+ "sid"
+ }, {
+ "sk",
+ "sk_Latn_SK",
+ "sk"
+ }, {
+ "sl",
+ "sl_Latn_SI",
+ "sl"
+ }, {
+ "sm",
+ "sm_Latn_WS",
+ "sm"
+ }, {
+ "so",
+ "so_Latn_SO",
+ "so"
+ }, {
+ "sq",
+ "sq_Latn_AL",
+ "sq"
+ }, {
+ "sr",
+ "sr_Cyrl_RS",
+ "sr"
+ }, {
+ "ss",
+ "ss_Latn_ZA",
+ "ss"
+ }, {
+ "st",
+ "st_Latn_ZA",
+ "st"
+ }, {
+ "sv",
+ "sv_Latn_SE",
+ "sv"
+ }, {
+ "sw",
+ "sw_Latn_TZ",
+ "sw"
+ }, {
+ "ta",
+ "ta_Taml_IN",
+ "ta"
+ }, {
+ "te",
+ "te_Telu_IN",
+ "te"
+ }, {
+ "tet",
+ "tet_Latn_TL",
+ "tet"
+ }, {
+ "tg",
+ "tg_Cyrl_TJ",
+ "tg"
+ }, {
+ "th",
+ "th_Thai_TH",
+ "th"
+ }, {
+ "ti",
+ "ti_Ethi_ET",
+ "ti"
+ }, {
+ "tig",
+ "tig_Ethi_ER",
+ "tig"
+ }, {
+ "tk",
+ "tk_Latn_TM",
+ "tk"
+ }, {
+ "tkl",
+ "tkl_Latn_TK",
+ "tkl"
+ }, {
+ "tn",
+ "tn_Latn_ZA",
+ "tn"
+ }, {
+ "to",
+ "to_Latn_TO",
+ "to"
+ }, {
+ "tpi",
+ "tpi_Latn_PG",
+ "tpi"
+ }, {
+ "tr",
+ "tr_Latn_TR",
+ "tr"
+ }, {
+ "ts",
+ "ts_Latn_ZA",
+ "ts"
+ }, {
+ "tt",
+ "tt_Cyrl_RU",
+ "tt"
+ }, {
+ "tvl",
+ "tvl_Latn_TV",
+ "tvl"
+ }, {
+ "ty",
+ "ty_Latn_PF",
+ "ty"
+ }, {
+ "uk",
+ "uk_Cyrl_UA",
+ "uk"
+ }, {
+ "und",
+ "en_Latn_US",
+ "en"
+ }, {
+ "und_AD",
+ "ca_Latn_AD",
+ "ca_AD"
+ }, {
+ "und_AE",
+ "ar_Arab_AE",
+ "ar_AE"
+ }, {
+ "und_AF",
+ "fa_Arab_AF",
+ "fa_AF"
+ }, {
+ "und_AL",
+ "sq_Latn_AL",
+ "sq"
+ }, {
+ "und_AM",
+ "hy_Armn_AM",
+ "hy"
+ }, {
+ "und_AO",
+ "pt_Latn_AO",
+ "pt_AO"
+ }, {
+ "und_AR",
+ "es_Latn_AR",
+ "es_AR"
+ }, {
+ "und_AS",
+ "sm_Latn_AS",
+ "sm_AS"
+ }, {
+ "und_AT",
+ "de_Latn_AT",
+ "de_AT"
+ }, {
+ "und_AW",
+ "nl_Latn_AW",
+ "nl_AW"
+ }, {
+ "und_AX",
+ "sv_Latn_AX",
+ "sv_AX"
+ }, {
+ "und_AZ",
+ "az_Latn_AZ",
+ "az"
+ }, {
+ "und_Arab",
+ "ar_Arab_EG",
+ "ar"
+ }, {
+ "und_Arab_IN",
+ "ur_Arab_IN",
+ "ur_IN"
+ }, {
+ "und_Arab_PK",
+ "ur_Arab_PK",
+ "ur"
+ }, {
+ "und_Arab_SN",
+ "ar_Arab_SN",
+ "ar_SN"
+ }, {
+ "und_Armn",
+ "hy_Armn_AM",
+ "hy"
+ }, {
+ "und_BA",
+ "bs_Latn_BA",
+ "bs"
+ }, {
+ "und_BD",
+ "bn_Beng_BD",
+ "bn"
+ }, {
+ "und_BE",
+ "nl_Latn_BE",
+ "nl_BE"
+ }, {
+ "und_BF",
+ "fr_Latn_BF",
+ "fr_BF"
+ }, {
+ "und_BG",
+ "bg_Cyrl_BG",
+ "bg"
+ }, {
+ "und_BH",
+ "ar_Arab_BH",
+ "ar_BH"
+ }, {
+ "und_BI",
+ "rn_Latn_BI",
+ "rn"
+ }, {
+ "und_BJ",
+ "fr_Latn_BJ",
+ "fr_BJ"
+ }, {
+ "und_BN",
+ "ms_Latn_BN",
+ "ms_BN"
+ }, {
+ "und_BO",
+ "es_Latn_BO",
+ "es_BO"
+ }, {
+ "und_BR",
+ "pt_Latn_BR",
+ "pt"
+ }, {
+ "und_BT",
+ "dz_Tibt_BT",
+ "dz"
+ }, {
+ "und_BY",
+ "be_Cyrl_BY",
+ "be"
+ }, {
+ "und_Beng",
+ "bn_Beng_BD",
+ "bn"
+ }, {
+ "und_Beng_IN",
+ "bn_Beng_IN",
+ "bn_IN"
+ }, {
+ "und_CD",
+ "sw_Latn_CD",
+ "sw_CD"
+ }, {
+ "und_CF",
+ "fr_Latn_CF",
+ "fr_CF"
+ }, {
+ "und_CG",
+ "fr_Latn_CG",
+ "fr_CG"
+ }, {
+ "und_CH",
+ "de_Latn_CH",
+ "de_CH"
+ }, {
+ "und_CI",
+ "fr_Latn_CI",
+ "fr_CI"
+ }, {
+ "und_CL",
+ "es_Latn_CL",
+ "es_CL"
+ }, {
+ "und_CM",
+ "fr_Latn_CM",
+ "fr_CM"
+ }, {
+ "und_CN",
+ "zh_Hans_CN",
+ "zh"
+ }, {
+ "und_CO",
+ "es_Latn_CO",
+ "es_CO"
+ }, {
+ "und_CR",
+ "es_Latn_CR",
+ "es_CR"
+ }, {
+ "und_CU",
+ "es_Latn_CU",
+ "es_CU"
+ }, {
+ "und_CV",
+ "pt_Latn_CV",
+ "pt_CV"
+ }, {
+ "und_CY",
+ "el_Grek_CY",
+ "el_CY"
+ }, {
+ "und_CZ",
+ "cs_Latn_CZ",
+ "cs"
+ }, {
+ "und_Cher",
+ "chr_Cher_US",
+ "chr"
+ }, {
+ "und_Cyrl",
+ "ru_Cyrl_RU",
+ "ru"
+ }, {
+ "und_Cyrl_KZ",
+ "ru_Cyrl_KZ",
+ "ru_KZ"
+ }, {
+ "und_DE",
+ "de_Latn_DE",
+ "de"
+ }, {
+ "und_DJ",
+ "aa_Latn_DJ",
+ "aa_DJ"
+ }, {
+ "und_DK",
+ "da_Latn_DK",
+ "da"
+ }, {
+ "und_DO",
+ "es_Latn_DO",
+ "es_DO"
+ }, {
+ "und_DZ",
+ "ar_Arab_DZ",
+ "ar_DZ"
+ }, {
+ "und_Deva",
+ "hi_Deva_IN",
+ "hi"
+ }, {
+ "und_EC",
+ "es_Latn_EC",
+ "es_EC"
+ }, {
+ "und_EE",
+ "et_Latn_EE",
+ "et"
+ }, {
+ "und_EG",
+ "ar_Arab_EG",
+ "ar"
+ }, {
+ "und_EH",
+ "ar_Arab_EH",
+ "ar_EH"
+ }, {
+ "und_ER",
+ "ti_Ethi_ER",
+ "ti_ER"
+ }, {
+ "und_ES",
+ "es_Latn_ES",
+ "es"
+ }, {
+ "und_ET",
+ "am_Ethi_ET",
+ "am"
+ }, {
+ "und_Ethi",
+ "am_Ethi_ET",
+ "am"
+ }, {
+ "und_Ethi_ER",
+ "am_Ethi_ER",
+ "am_ER"
+ }, {
+ "und_FI",
+ "fi_Latn_FI",
+ "fi"
+ }, {
+ "und_FM",
+ "en_Latn_FM",
+ "en_FM"
+ }, {
+ "und_FO",
+ "fo_Latn_FO",
+ "fo"
+ }, {
+ "und_FR",
+ "fr_Latn_FR",
+ "fr"
+ }, {
+ "und_GA",
+ "fr_Latn_GA",
+ "fr_GA"
+ }, {
+ "und_GE",
+ "ka_Geor_GE",
+ "ka"
+ }, {
+ "und_GF",
+ "fr_Latn_GF",
+ "fr_GF"
+ }, {
+ "und_GL",
+ "kl_Latn_GL",
+ "kl"
+ }, {
+ "und_GN",
+ "fr_Latn_GN",
+ "fr_GN"
+ }, {
+ "und_GP",
+ "fr_Latn_GP",
+ "fr_GP"
+ }, {
+ "und_GQ",
+ "es_Latn_GQ",
+ "es_GQ"
+ }, {
+ "und_GR",
+ "el_Grek_GR",
+ "el"
+ }, {
+ "und_GT",
+ "es_Latn_GT",
+ "es_GT"
+ }, {
+ "und_GU",
+ "en_Latn_GU",
+ "en_GU"
+ }, {
+ "und_GW",
+ "pt_Latn_GW",
+ "pt_GW"
+ }, {
+ "und_Geor",
+ "ka_Geor_GE",
+ "ka"
+ }, {
+ "und_Grek",
+ "el_Grek_GR",
+ "el"
+ }, {
+ "und_Gujr",
+ "gu_Gujr_IN",
+ "gu"
+ }, {
+ "und_Guru",
+ "pa_Guru_IN",
+ "pa"
+ }, {
+ "und_HK",
+ "zh_Hant_HK",
+ "zh_HK"
+ }, {
+ "und_HN",
+ "es_Latn_HN",
+ "es_HN"
+ }, {
+ "und_HR",
+ "hr_Latn_HR",
+ "hr"
+ }, {
+ "und_HT",
+ "ht_Latn_HT",
+ "ht"
+ }, {
+ "und_HU",
+ "hu_Latn_HU",
+ "hu"
+ }, {
+ "und_Hani",
+ "zh_Hani_CN",
+ "zh_Hani"
+ }, {
+ "und_Hans",
+ "zh_Hans_CN",
+ "zh"
+ }, {
+ "und_Hant",
+ "zh_Hant_TW",
+ "zh_TW"
+ }, {
+ "und_Hebr",
+ "he_Hebr_IL",
+ "he"
+ }, {
+ "und_IL",
+ "he_Hebr_IL",
+ "he"
+ }, {
+ "und_IN",
+ "hi_Deva_IN",
+ "hi"
+ }, {
+ "und_IQ",
+ "ar_Arab_IQ",
+ "ar_IQ"
+ }, {
+ "und_IR",
+ "fa_Arab_IR",
+ "fa"
+ }, {
+ "und_IS",
+ "is_Latn_IS",
+ "is"
+ }, {
+ "und_IT",
+ "it_Latn_IT",
+ "it"
+ }, {
+ "und_JO",
+ "ar_Arab_JO",
+ "ar_JO"
+ }, {
+ "und_JP",
+ "ja_Jpan_JP",
+ "ja"
+ }, {
+ "und_Jpan",
+ "ja_Jpan_JP",
+ "ja"
+ }, {
+ "und_KG",
+ "ky_Cyrl_KG",
+ "ky"
+ }, {
+ "und_KH",
+ "km_Khmr_KH",
+ "km"
+ }, {
+ "und_KM",
+ "ar_Arab_KM",
+ "ar_KM"
+ }, {
+ "und_KP",
+ "ko_Kore_KP",
+ "ko_KP"
+ }, {
+ "und_KR",
+ "ko_Kore_KR",
+ "ko"
+ }, {
+ "und_KW",
+ "ar_Arab_KW",
+ "ar_KW"
+ }, {
+ "und_KZ",
+ "ru_Cyrl_KZ",
+ "ru_KZ"
+ }, {
+ "und_Khmr",
+ "km_Khmr_KH",
+ "km"
+ }, {
+ "und_Knda",
+ "kn_Knda_IN",
+ "kn"
+ }, {
+ "und_Kore",
+ "ko_Kore_KR",
+ "ko"
+ }, {
+ "und_LA",
+ "lo_Laoo_LA",
+ "lo"
+ }, {
+ "und_LB",
+ "ar_Arab_LB",
+ "ar_LB"
+ }, {
+ "und_LI",
+ "de_Latn_LI",
+ "de_LI"
+ }, {
+ "und_LK",
+ "si_Sinh_LK",
+ "si"
+ }, {
+ "und_LS",
+ "st_Latn_LS",
+ "st_LS"
+ }, {
+ "und_LT",
+ "lt_Latn_LT",
+ "lt"
+ }, {
+ "und_LU",
+ "fr_Latn_LU",
+ "fr_LU"
+ }, {
+ "und_LV",
+ "lv_Latn_LV",
+ "lv"
+ }, {
+ "und_LY",
+ "ar_Arab_LY",
+ "ar_LY"
+ }, {
+ "und_Laoo",
+ "lo_Laoo_LA",
+ "lo"
+ }, {
+ "und_Latn_ES",
+ "es_Latn_ES",
+ "es"
+ }, {
+ "und_Latn_ET",
+ "en_Latn_ET",
+ "en_ET"
+ }, {
+ "und_Latn_GB",
+ "en_Latn_GB",
+ "en_GB"
+ }, {
+ "und_Latn_GH",
+ "ak_Latn_GH",
+ "ak"
+ }, {
+ "und_Latn_ID",
+ "id_Latn_ID",
+ "id"
+ }, {
+ "und_Latn_IT",
+ "it_Latn_IT",
+ "it"
+ }, {
+ "und_Latn_NG",
+ "en_Latn_NG",
+ "en_NG"
+ }, {
+ "und_Latn_TR",
+ "tr_Latn_TR",
+ "tr"
+ }, {
+ "und_Latn_ZA",
+ "en_Latn_ZA",
+ "en_ZA"
+ }, {
+ "und_MA",
+ "ar_Arab_MA",
+ "ar_MA"
+ }, {
+ "und_MC",
+ "fr_Latn_MC",
+ "fr_MC"
+ }, {
+ "und_MD",
+ "ro_Latn_MD",
+ "ro_MD"
+ }, {
+ "und_ME",
+ "sr_Latn_ME",
+ "sr_ME"
+ }, {
+ "und_MG",
+ "mg_Latn_MG",
+ "mg"
+ }, {
+ "und_MH",
+ "en_Latn_MH",
+ "en_MH"
+ }, {
+ "und_MK",
+ "mk_Cyrl_MK",
+ "mk"
+ }, {
+ "und_ML",
+ "bm_Latn_ML",
+ "bm"
+ }, {
+ "und_MM",
+ "my_Mymr_MM",
+ "my"
+ }, {
+ "und_MN",
+ "mn_Cyrl_MN",
+ "mn"
+ }, {
+ "und_MO",
+ "zh_Hant_MO",
+ "zh_MO"
+ }, {
+ "und_MQ",
+ "fr_Latn_MQ",
+ "fr_MQ"
+ }, {
+ "und_MR",
+ "ar_Arab_MR",
+ "ar_MR"
+ }, {
+ "und_MT",
+ "mt_Latn_MT",
+ "mt"
+ }, {
+ "und_MV",
+ "dv_Thaa_MV",
+ "dv"
+ }, {
+ "und_MW",
+ "en_Latn_MW",
+ "en_MW"
+ }, {
+ "und_MX",
+ "es_Latn_MX",
+ "es_MX"
+ }, {
+ "und_MY",
+ "ms_Latn_MY",
+ "ms"
+ }, {
+ "und_MZ",
+ "pt_Latn_MZ",
+ "pt_MZ"
+ }, {
+ "und_Mlym",
+ "ml_Mlym_IN",
+ "ml"
+ }, {
+ "und_Mymr",
+ "my_Mymr_MM",
+ "my"
+ }, {
+ "und_NC",
+ "fr_Latn_NC",
+ "fr_NC"
+ }, {
+ "und_NE",
+ "ha_Latn_NE",
+ "ha_NE"
+ }, {
+ "und_NG",
+ "en_Latn_NG",
+ "en_NG"
+ }, {
+ "und_NI",
+ "es_Latn_NI",
+ "es_NI"
+ }, {
+ "und_NL",
+ "nl_Latn_NL",
+ "nl"
+ }, {
+ "und_NO",
+ "nb_Latn_NO",
+ "nb"
+ }, {
+ "und_NP",
+ "ne_Deva_NP",
+ "ne"
+ }, {
+ "und_NR",
+ "en_Latn_NR",
+ "en_NR"
+ }, {
+ "und_NU",
+ "en_Latn_NU",
+ "en_NU"
+ }, {
+ "und_OM",
+ "ar_Arab_OM",
+ "ar_OM"
+ }, {
+ "und_Orya",
+ "or_Orya_IN",
+ "or"
+ }, {
+ "und_PA",
+ "es_Latn_PA",
+ "es_PA"
+ }, {
+ "und_PE",
+ "es_Latn_PE",
+ "es_PE"
+ }, {
+ "und_PF",
+ "fr_Latn_PF",
+ "fr_PF"
+ }, {
+ "und_PG",
+ "tpi_Latn_PG",
+ "tpi"
+ }, {
+ "und_PH",
+ "fil_Latn_PH",
+ "fil"
+ }, {
+ "und_PL",
+ "pl_Latn_PL",
+ "pl"
+ }, {
+ "und_PM",
+ "fr_Latn_PM",
+ "fr_PM"
+ }, {
+ "und_PR",
+ "es_Latn_PR",
+ "es_PR"
+ }, {
+ "und_PS",
+ "ar_Arab_PS",
+ "ar_PS"
+ }, {
+ "und_PT",
+ "pt_Latn_PT",
+ "pt_PT"
+ }, {
+ "und_PW",
+ "pau_Latn_PW",
+ "pau"
+ }, {
+ "und_PY",
+ "gn_Latn_PY",
+ "gn"
+ }, {
+ "und_QA",
+ "ar_Arab_QA",
+ "ar_QA"
+ }, {
+ "und_RE",
+ "fr_Latn_RE",
+ "fr_RE"
+ }, {
+ "und_RO",
+ "ro_Latn_RO",
+ "ro"
+ }, {
+ "und_RS",
+ "sr_Cyrl_RS",
+ "sr"
+ }, {
+ "und_RU",
+ "ru_Cyrl_RU",
+ "ru"
+ }, {
+ "und_RW",
+ "rw_Latn_RW",
+ "rw"
+ }, {
+ "und_SA",
+ "ar_Arab_SA",
+ "ar_SA"
+ }, {
+ "und_SD",
+ "ar_Arab_SD",
+ "ar_SD"
+ }, {
+ "und_SE",
+ "sv_Latn_SE",
+ "sv"
+ }, {
+ "und_SG",
+ "en_Latn_SG",
+ "en_SG"
+ }, {
+ "und_SI",
+ "sl_Latn_SI",
+ "sl"
+ }, {
+ "und_SJ",
+ "nb_Latn_SJ",
+ "nb_SJ"
+ }, {
+ "und_SK",
+ "sk_Latn_SK",
+ "sk"
+ }, {
+ "und_SM",
+ "it_Latn_SM",
+ "it_SM"
+ }, {
+ "und_SN",
+ "fr_Latn_SN",
+ "fr_SN"
+ }, {
+ "und_SO",
+ "so_Latn_SO",
+ "so"
+ }, {
+ "und_SR",
+ "nl_Latn_SR",
+ "nl_SR"
+ }, {
+ "und_ST",
+ "pt_Latn_ST",
+ "pt_ST"
+ }, {
+ "und_SV",
+ "es_Latn_SV",
+ "es_SV"
+ }, {
+ "und_SY",
+ "ar_Arab_SY",
+ "ar_SY"
+ }, {
+ "und_Sinh",
+ "si_Sinh_LK",
+ "si"
+ }, {
+ "und_TD",
+ "fr_Latn_TD",
+ "fr_TD"
+ }, {
+ "und_TG",
+ "fr_Latn_TG",
+ "fr_TG"
+ }, {
+ "und_TH",
+ "th_Thai_TH",
+ "th"
+ }, {
+ "und_TJ",
+ "tg_Cyrl_TJ",
+ "tg"
+ }, {
+ "und_TK",
+ "tkl_Latn_TK",
+ "tkl"
+ }, {
+ "und_TL",
+ "pt_Latn_TL",
+ "pt_TL"
+ }, {
+ "und_TM",
+ "tk_Latn_TM",
+ "tk"
+ }, {
+ "und_TN",
+ "ar_Arab_TN",
+ "ar_TN"
+ }, {
+ "und_TO",
+ "to_Latn_TO",
+ "to"
+ }, {
+ "und_TR",
+ "tr_Latn_TR",
+ "tr"
+ }, {
+ "und_TV",
+ "tvl_Latn_TV",
+ "tvl"
+ }, {
+ "und_TW",
+ "zh_Hant_TW",
+ "zh_TW"
+ }, {
+ "und_Taml",
+ "ta_Taml_IN",
+ "ta"
+ }, {
+ "und_Telu",
+ "te_Telu_IN",
+ "te"
+ }, {
+ "und_Thaa",
+ "dv_Thaa_MV",
+ "dv"
+ }, {
+ "und_Thai",
+ "th_Thai_TH",
+ "th"
+ }, {
+ "und_Tibt",
+ "bo_Tibt_CN",
+ "bo"
+ }, {
+ "und_UA",
+ "uk_Cyrl_UA",
+ "uk"
+ }, {
+ "und_UY",
+ "es_Latn_UY",
+ "es_UY"
+ }, {
+ "und_UZ",
+ "uz_Latn_UZ",
+ "uz"
+ }, {
+ "und_VA",
+ "it_Latn_VA",
+ "it_VA"
+ }, {
+ "und_VE",
+ "es_Latn_VE",
+ "es_VE"
+ }, {
+ "und_VN",
+ "vi_Latn_VN",
+ "vi"
+ }, {
+ "und_VU",
+ "bi_Latn_VU",
+ "bi"
+ }, {
+ "und_WF",
+ "fr_Latn_WF",
+ "fr_WF"
+ }, {
+ "und_WS",
+ "sm_Latn_WS",
+ "sm"
+ }, {
+ "und_YE",
+ "ar_Arab_YE",
+ "ar_YE"
+ }, {
+ "und_YT",
+ "fr_Latn_YT",
+ "fr_YT"
+ }, {
+ "und_Yiii",
+ "ii_Yiii_CN",
+ "ii"
+ }, {
+ "ur",
+ "ur_Arab_PK",
+ "ur"
+ }, {
+ "uz",
+ "uz_Latn_UZ",
+ "uz"
+ }, {
+ "uz_AF",
+ "uz_Arab_AF",
+ "uz_AF"
+ }, {
+ "uz_Arab",
+ "uz_Arab_AF",
+ "uz_AF"
+ }, {
+ "ve",
+ "ve_Latn_ZA",
+ "ve"
+ }, {
+ "vi",
+ "vi_Latn_VN",
+ "vi"
+ }, {
+ "wal",
+ "wal_Ethi_ET",
+ "wal"
+ }, {
+ "wo",
+ "wo_Latn_SN",
+ "wo"
+ }, {
+ "xh",
+ "xh_Latn_ZA",
+ "xh"
+ }, {
+ "yo",
+ "yo_Latn_NG",
+ "yo"
+ }, {
+ "zh",
+ "zh_Hans_CN",
+ "zh"
+ }, {
+ "zh_HK",
+ "zh_Hant_HK",
+ "zh_HK"
+ }, {
+ "zh_Hani",
+ "zh_Hani_CN", /* changed due to cldrbug 6204, may be an error */
+ "zh_Hani", /* changed due to cldrbug 6204, may be an error */
+ }, {
+ "zh_Hant",
+ "zh_Hant_TW",
+ "zh_TW"
+ }, {
+ "zh_MO",
+ "zh_Hant_MO",
+ "zh_MO"
+ }, {
+ "zh_TW",
+ "zh_Hant_TW",
+ "zh_TW"
+ }, {
+ "zu",
+ "zu_Latn_ZA",
+ "zu"
+ }, {
+ "und",
+ "en_Latn_US",
+ "en"
+ }, {
+ "und_ZZ",
+ "en_Latn_US",
+ "en"
+ }, {
+ "und_CN",
+ "zh_Hans_CN",
+ "zh"
+ }, {
+ "und_TW",
+ "zh_Hant_TW",
+ "zh_TW"
+ }, {
+ "und_HK",
+ "zh_Hant_HK",
+ "zh_HK"
+ }, {
+ "und_AQ",
+ "und_Latn_AQ",
+ "und_AQ"
+ }, {
+ "und_Zzzz",
+ "en_Latn_US",
+ "en"
+ }, {
+ "und_Zzzz_ZZ",
+ "en_Latn_US",
+ "en"
+ }, {
+ "und_Zzzz_CN",
+ "zh_Hans_CN",
+ "zh"
+ }, {
+ "und_Zzzz_TW",
+ "zh_Hant_TW",
+ "zh_TW"
+ }, {
+ "und_Zzzz_HK",
+ "zh_Hant_HK",
+ "zh_HK"
+ }, {
+ "und_Zzzz_AQ",
+ "und_Latn_AQ",
+ "und_AQ"
+ }, {
+ "und_Latn",
+ "en_Latn_US",
+ "en"
+ }, {
+ "und_Latn_ZZ",
+ "en_Latn_US",
+ "en"
+ }, {
+ "und_Latn_CN",
+ "za_Latn_CN",
+ "za"
+ }, {
+ "und_Latn_TW",
+ "trv_Latn_TW",
+ "trv"
+ }, {
+ "und_Latn_HK",
+ "zh_Latn_HK",
+ "zh_Latn_HK"
+ }, {
+ "und_Latn_AQ",
+ "und_Latn_AQ",
+ "und_AQ"
+ }, {
+ "und_Hans",
+ "zh_Hans_CN",
+ "zh"
+ }, {
+ "und_Hans_ZZ",
+ "zh_Hans_CN",
+ "zh"
+ }, {
+ "und_Hans_CN",
+ "zh_Hans_CN",
+ "zh"
+ }, {
+ "und_Hans_TW",
+ "zh_Hans_TW",
+ "zh_Hans_TW"
+ }, {
+ "und_Hans_HK",
+ "zh_Hans_HK",
+ "zh_Hans_HK"
+ }, {
+ "und_Hans_AQ",
+ "zh_Hans_AQ",
+ "zh_AQ"
+ }, {
+ "und_Hant",
+ "zh_Hant_TW",
+ "zh_TW"
+ }, {
+ "und_Hant_ZZ",
+ "zh_Hant_TW",
+ "zh_TW"
+ }, {
+ "und_Hant_CN",
+ "zh_Hant_CN",
+ "zh_Hant_CN"
+ }, {
+ "und_Hant_TW",
+ "zh_Hant_TW",
+ "zh_TW"
+ }, {
+ "und_Hant_HK",
+ "zh_Hant_HK",
+ "zh_HK"
+ }, {
+ "und_Hant_AQ",
+ "zh_Hant_AQ",
+ "zh_Hant_AQ"
+ }, {
+ "und_Moon",
+ "en_Moon_US",
+ "en_Moon"
+ }, {
+ "und_Moon_ZZ",
+ "en_Moon_US",
+ "en_Moon"
+ }, {
+ "und_Moon_CN",
+ "zh_Moon_CN",
+ "zh_Moon"
+ }, {
+ "und_Moon_TW",
+ "zh_Moon_TW",
+ "zh_Moon_TW"
+ }, {
+ "und_Moon_HK",
+ "zh_Moon_HK",
+ "zh_Moon_HK"
+ }, {
+ "und_Moon_AQ",
+ "und_Moon_AQ",
+ "und_Moon_AQ"
+ }, {
+ "es",
+ "es_Latn_ES",
+ "es"
+ }, {
+ "es_ZZ",
+ "es_Latn_ES",
+ "es"
+ }, {
+ "es_CN",
+ "es_Latn_CN",
+ "es_CN"
+ }, {
+ "es_TW",
+ "es_Latn_TW",
+ "es_TW"
+ }, {
+ "es_HK",
+ "es_Latn_HK",
+ "es_HK"
+ }, {
+ "es_AQ",
+ "es_Latn_AQ",
+ "es_AQ"
+ }, {
+ "es_Zzzz",
+ "es_Latn_ES",
+ "es"
+ }, {
+ "es_Zzzz_ZZ",
+ "es_Latn_ES",
+ "es"
+ }, {
+ "es_Zzzz_CN",
+ "es_Latn_CN",
+ "es_CN"
+ }, {
+ "es_Zzzz_TW",
+ "es_Latn_TW",
+ "es_TW"
+ }, {
+ "es_Zzzz_HK",
+ "es_Latn_HK",
+ "es_HK"
+ }, {
+ "es_Zzzz_AQ",
+ "es_Latn_AQ",
+ "es_AQ"
+ }, {
+ "es_Latn",
+ "es_Latn_ES",
+ "es"
+ }, {
+ "es_Latn_ZZ",
+ "es_Latn_ES",
+ "es"
+ }, {
+ "es_Latn_CN",
+ "es_Latn_CN",
+ "es_CN"
+ }, {
+ "es_Latn_TW",
+ "es_Latn_TW",
+ "es_TW"
+ }, {
+ "es_Latn_HK",
+ "es_Latn_HK",
+ "es_HK"
+ }, {
+ "es_Latn_AQ",
+ "es_Latn_AQ",
+ "es_AQ"
+ }, {
+ "es_Hans",
+ "es_Hans_ES",
+ "es_Hans"
+ }, {
+ "es_Hans_ZZ",
+ "es_Hans_ES",
+ "es_Hans"
+ }, {
+ "es_Hans_CN",
+ "es_Hans_CN",
+ "es_Hans_CN"
+ }, {
+ "es_Hans_TW",
+ "es_Hans_TW",
+ "es_Hans_TW"
+ }, {
+ "es_Hans_HK",
+ "es_Hans_HK",
+ "es_Hans_HK"
+ }, {
+ "es_Hans_AQ",
+ "es_Hans_AQ",
+ "es_Hans_AQ"
+ }, {
+ "es_Hant",
+ "es_Hant_ES",
+ "es_Hant"
+ }, {
+ "es_Hant_ZZ",
+ "es_Hant_ES",
+ "es_Hant"
+ }, {
+ "es_Hant_CN",
+ "es_Hant_CN",
+ "es_Hant_CN"
+ }, {
+ "es_Hant_TW",
+ "es_Hant_TW",
+ "es_Hant_TW"
+ }, {
+ "es_Hant_HK",
+ "es_Hant_HK",
+ "es_Hant_HK"
+ }, {
+ "es_Hant_AQ",
+ "es_Hant_AQ",
+ "es_Hant_AQ"
+ }, {
+ "es_Moon",
+ "es_Moon_ES",
+ "es_Moon"
+ }, {
+ "es_Moon_ZZ",
+ "es_Moon_ES",
+ "es_Moon"
+ }, {
+ "es_Moon_CN",
+ "es_Moon_CN",
+ "es_Moon_CN"
+ }, {
+ "es_Moon_TW",
+ "es_Moon_TW",
+ "es_Moon_TW"
+ }, {
+ "es_Moon_HK",
+ "es_Moon_HK",
+ "es_Moon_HK"
+ }, {
+ "es_Moon_AQ",
+ "es_Moon_AQ",
+ "es_Moon_AQ"
+ }, {
+ "zh",
+ "zh_Hans_CN",
+ "zh"
+ }, {
+ "zh_ZZ",
+ "zh_Hans_CN",
+ "zh"
+ }, {
+ "zh_CN",
+ "zh_Hans_CN",
+ "zh"
+ }, {
+ "zh_TW",
+ "zh_Hant_TW",
+ "zh_TW"
+ }, {
+ "zh_HK",
+ "zh_Hant_HK",
+ "zh_HK"
+ }, {
+ "zh_AQ",
+ "zh_Hans_AQ",
+ "zh_AQ"
+ }, {
+ "zh_MY",
+ "zh_Hans_MY",
+ "zh_MY"
+ }, {
+ "zh_Zzzz",
+ "zh_Hans_CN",
+ "zh"
+ }, {
+ "zh_Zzzz_ZZ",
+ "zh_Hans_CN",
+ "zh"
+ }, {
+ "zh_Zzzz_CN",
+ "zh_Hans_CN",
+ "zh"
+ }, {
+ "zh_Zzzz_TW",
+ "zh_Hant_TW",
+ "zh_TW"
+ }, {
+ "zh_Zzzz_HK",
+ "zh_Hant_HK",
+ "zh_HK"
+ }, {
+ "zh_Zzzz_AQ",
+ "zh_Hans_AQ",
+ "zh_AQ"
+ }, {
+ "zh_Latn",
+ "zh_Latn_CN",
+ "zh_Latn"
+ }, {
+ "zh_Latn_ZZ",
+ "zh_Latn_CN",
+ "zh_Latn"
+ }, {
+ "zh_Latn_CN",
+ "zh_Latn_CN",
+ "zh_Latn"
+ }, {
+ "zh_Latn_TW",
+ "zh_Latn_TW",
+ "zh_Latn_TW"
+ }, {
+ "zh_Latn_HK",
+ "zh_Latn_HK",
+ "zh_Latn_HK"
+ }, {
+ "zh_Latn_AQ",
+ "zh_Latn_AQ",
+ "zh_Latn_AQ"
+ }, {
+ "zh_Hans",
+ "zh_Hans_CN",
+ "zh"
+ }, {
+ "zh_Hans_ZZ",
+ "zh_Hans_CN",
+ "zh"
+ }, {
+ "zh_Hans_TW",
+ "zh_Hans_TW",
+ "zh_Hans_TW"
+ }, {
+ "zh_Hans_HK",
+ "zh_Hans_HK",
+ "zh_Hans_HK"
+ }, {
+ "zh_Hans_AQ",
+ "zh_Hans_AQ",
+ "zh_AQ"
+ }, {
+ "zh_Hant",
+ "zh_Hant_TW",
+ "zh_TW"
+ }, {
+ "zh_Hant_ZZ",
+ "zh_Hant_TW",
+ "zh_TW"
+ }, {
+ "zh_Hant_CN",
+ "zh_Hant_CN",
+ "zh_Hant_CN"
+ }, {
+ "zh_Hant_AQ",
+ "zh_Hant_AQ",
+ "zh_Hant_AQ"
+ }, {
+ "zh_Moon",
+ "zh_Moon_CN",
+ "zh_Moon"
+ }, {
+ "zh_Moon_ZZ",
+ "zh_Moon_CN",
+ "zh_Moon"
+ }, {
+ "zh_Moon_CN",
+ "zh_Moon_CN",
+ "zh_Moon"
+ }, {
+ "zh_Moon_TW",
+ "zh_Moon_TW",
+ "zh_Moon_TW"
+ }, {
+ "zh_Moon_HK",
+ "zh_Moon_HK",
+ "zh_Moon_HK"
+ }, {
+ "zh_Moon_AQ",
+ "zh_Moon_AQ",
+ "zh_Moon_AQ"
+ }, {
+ "art",
+ "",
+ ""
+ }, {
+ "art_ZZ",
+ "",
+ ""
+ }, {
+ "art_CN",
+ "",
+ ""
+ }, {
+ "art_TW",
+ "",
+ ""
+ }, {
+ "art_HK",
+ "",
+ ""
+ }, {
+ "art_AQ",
+ "",
+ ""
+ }, {
+ "art_Zzzz",
+ "",
+ ""
+ }, {
+ "art_Zzzz_ZZ",
+ "",
+ ""
+ }, {
+ "art_Zzzz_CN",
+ "",
+ ""
+ }, {
+ "art_Zzzz_TW",
+ "",
+ ""
+ }, {
+ "art_Zzzz_HK",
+ "",
+ ""
+ }, {
+ "art_Zzzz_AQ",
+ "",
+ ""
+ }, {
+ "art_Latn",
+ "",
+ ""
+ }, {
+ "art_Latn_ZZ",
+ "",
+ ""
+ }, {
+ "art_Latn_CN",
+ "",
+ ""
+ }, {
+ "art_Latn_TW",
+ "",
+ ""
+ }, {
+ "art_Latn_HK",
+ "",
+ ""
+ }, {
+ "art_Latn_AQ",
+ "",
+ ""
+ }, {
+ "art_Hans",
+ "",
+ ""
+ }, {
+ "art_Hans_ZZ",
+ "",
+ ""
+ }, {
+ "art_Hans_CN",
+ "",
+ ""
+ }, {
+ "art_Hans_TW",
+ "",
+ ""
+ }, {
+ "art_Hans_HK",
+ "",
+ ""
+ }, {
+ "art_Hans_AQ",
+ "",
+ ""
+ }, {
+ "art_Hant",
+ "",
+ ""
+ }, {
+ "art_Hant_ZZ",
+ "",
+ ""
+ }, {
+ "art_Hant_CN",
+ "",
+ ""
+ }, {
+ "art_Hant_TW",
+ "",
+ ""
+ }, {
+ "art_Hant_HK",
+ "",
+ ""
+ }, {
+ "art_Hant_AQ",
+ "",
+ ""
+ }, {
+ "art_Moon",
+ "",
+ ""
+ }, {
+ "art_Moon_ZZ",
+ "",
+ ""
+ }, {
+ "art_Moon_CN",
+ "",
+ ""
+ }, {
+ "art_Moon_TW",
+ "",
+ ""
+ }, {
+ "art_Moon_HK",
+ "",
+ ""
+ }, {
+ "art_Moon_AQ",
+ "",
+ ""
+ }, {
+ "de@collation=phonebook",
+ "de_Latn_DE@collation=phonebook",
+ "de@collation=phonebook"
+ }
+};
+
+typedef struct errorDataTag {
+ const char* tag;
+ const char* expected;
+ UErrorCode uerror;
+ int32_t bufferSize;
+} errorData;
+
+const errorData maximizeErrors[] = {
+ {
+ "enfueiujhytdf",
+ NULL,
+ U_ILLEGAL_ARGUMENT_ERROR,
+ -1
+ },
+ {
+ "en_THUJIOGIURJHGJFURYHFJGURYYYHHGJURHG",
+ NULL,
+ U_ILLEGAL_ARGUMENT_ERROR,
+ -1
+ },
+ {
+ "en_THUJIOGIURJHGJFURYHFJGURYYYHHGJURHG",
+ NULL,
+ U_ILLEGAL_ARGUMENT_ERROR,
+ -1
+ },
+ {
+ "en_Latn_US_POSIX@currency=EURO",
+ "en_Latn_US_POSIX@currency=EURO",
+ U_BUFFER_OVERFLOW_ERROR,
+ 29
+ },
+ {
+ "en_Latn_US_POSIX@currency=EURO",
+ "en_Latn_US_POSIX@currency=EURO",
+ U_STRING_NOT_TERMINATED_WARNING,
+ 30
+ }
+};
+
+const errorData minimizeErrors[] = {
+ {
+ "enfueiujhytdf",
+ NULL,
+ U_ILLEGAL_ARGUMENT_ERROR,
+ -1
+ },
+ {
+ "en_THUJIOGIURJHGJFURYHFJGURYYYHHGJURHG",
+ NULL,
+ U_ILLEGAL_ARGUMENT_ERROR,
+ -1
+ },
+ {
+ "en_Latn_US_POSIX@currency=EURO",
+ "en__POSIX@currency=EURO",
+ U_BUFFER_OVERFLOW_ERROR,
+ 22
+ },
+ {
+ "en_Latn_US_POSIX@currency=EURO",
+ "en__POSIX@currency=EURO",
+ U_STRING_NOT_TERMINATED_WARNING,
+ 23
+ }
+};
+
+static int32_t getExpectedReturnValue(const errorData* data)
+{
+ if (data->uerror == U_BUFFER_OVERFLOW_ERROR ||
+ data->uerror == U_STRING_NOT_TERMINATED_WARNING)
+ {
+ return strlen(data->expected);
+ }
+ else
+ {
+ return -1;
+ }
+}
+
+static int32_t getBufferSize(const errorData* data, int32_t actualSize)
+{
+ if (data->expected == NULL)
+ {
+ return actualSize;
+ }
+ else if (data->bufferSize < 0)
+ {
+ return strlen(data->expected) + 1;
+ }
+ else
+ {
+ return data->bufferSize;
+ }
+}
+
+static void TestLikelySubtags()
+{
+ char buffer[ULOC_FULLNAME_CAPACITY + ULOC_KEYWORD_AND_VALUES_CAPACITY + 1];
+ int32_t i = 0;
+
+ for (; i < UPRV_LENGTHOF(basic_maximize_data); ++i)
+ {
+ UErrorCode status = U_ZERO_ERROR;
+ const char* const minimal = basic_maximize_data[i][0];
+ const char* const maximal = basic_maximize_data[i][1];
+
+ /* const int32_t length = */
+ uloc_addLikelySubtags(
+ minimal,
+ buffer,
+ sizeof(buffer),
+ &status);
+ if (U_FAILURE(status)) {
+ log_err_status(status, " unexpected failure of uloc_addLikelySubtags(), minimal \"%s\" status %s\n", minimal, u_errorName(status));
+ status = U_ZERO_ERROR;
+ }
+ else if (uprv_strlen(maximal) == 0) {
+ if (uprv_stricmp(minimal, buffer) != 0) {
+ log_err(" unexpected maximal value \"%s\" in uloc_addLikelySubtags(), minimal \"%s\" = \"%s\"\n", maximal, minimal, buffer);
+ }
+ }
+ else if (uprv_stricmp(maximal, buffer) != 0) {
+ log_err(" maximal doesn't match expected %s in uloc_addLikelySubtags(), minimal \"%s\" = %s\n", maximal, minimal, buffer);
+ }
+ }
+
+ for (i = 0; i < UPRV_LENGTHOF(basic_minimize_data); ++i) {
+
+ UErrorCode status = U_ZERO_ERROR;
+ const char* const maximal = basic_minimize_data[i][0];
+ const char* const minimal = basic_minimize_data[i][1];
+
+ /* const int32_t length = */
+ uloc_minimizeSubtags(
+ maximal,
+ buffer,
+ sizeof(buffer),
+ &status);
+
+ if (U_FAILURE(status)) {
+ log_err_status(status, " unexpected failure of uloc_MinimizeSubtags(), maximal \"%s\" status %s\n", maximal, u_errorName(status));
+ status = U_ZERO_ERROR;
+ }
+ else if (uprv_strlen(minimal) == 0) {
+ if (uprv_stricmp(maximal, buffer) != 0) {
+ log_err(" unexpected minimal value \"%s\" in uloc_minimizeSubtags(), maximal \"%s\" = \"%s\"\n", minimal, maximal, buffer);
+ }
+ }
+ else if (uprv_stricmp(minimal, buffer) != 0) {
+ log_err(" minimal doesn't match expected %s in uloc_MinimizeSubtags(), maximal \"%s\" = %s\n", minimal, maximal, buffer);
+ }
+ }
+
+ for (i = 0; i < UPRV_LENGTHOF(full_data); ++i) {
+
+ UErrorCode status = U_ZERO_ERROR;
+ const char* const minimal = full_data[i][0];
+ const char* const maximal = full_data[i][1];
+
+ /* const int32_t length = */
+ uloc_addLikelySubtags(
+ minimal,
+ buffer,
+ sizeof(buffer),
+ &status);
+ if (U_FAILURE(status)) {
+ log_err_status(status, " unexpected failure of uloc_addLikelySubtags(), minimal \"%s\" status \"%s\"\n", minimal, u_errorName(status));
+ status = U_ZERO_ERROR;
+ }
+ else if (uprv_strlen(maximal) == 0) {
+ if (uprv_stricmp(minimal, buffer) != 0) {
+ log_err(" unexpected maximal value \"%s\" in uloc_addLikelySubtags(), minimal \"%s\" = \"%s\"\n", maximal, minimal, buffer);
+ }
+ }
+ else if (uprv_stricmp(maximal, buffer) != 0) {
+ log_err(" maximal doesn't match expected \"%s\" in uloc_addLikelySubtags(), minimal \"%s\" = \"%s\"\n", maximal, minimal, buffer);
+ }
+ }
+
+ for (i = 0; i < UPRV_LENGTHOF(full_data); ++i) {
+
+ UErrorCode status = U_ZERO_ERROR;
+ const char* const maximal = full_data[i][1];
+ const char* const minimal = full_data[i][2];
+
+ if (strlen(maximal) > 0) {
+
+ /* const int32_t length = */
+ uloc_minimizeSubtags(
+ maximal,
+ buffer,
+ sizeof(buffer),
+ &status);
+
+ if (U_FAILURE(status)) {
+ log_err_status(status, " unexpected failure of uloc_minimizeSubtags(), maximal \"%s\" status %s\n", maximal, u_errorName(status));
+ status = U_ZERO_ERROR;
+ }
+ else if (uprv_strlen(minimal) == 0) {
+ if (uprv_stricmp(maximal, buffer) != 0) {
+ log_err(" unexpected minimal value \"%s\" in uloc_minimizeSubtags(), maximal \"%s\" = \"%s\"\n", minimal, maximal, buffer);
+ }
+ }
+ else if (uprv_stricmp(minimal, buffer) != 0) {
+ log_err(" minimal doesn't match expected %s in uloc_MinimizeSubtags(), maximal \"%s\" = %s\n", minimal, maximal, buffer);
+ }
+ }
+ }
+
+ for (i = 0; i < UPRV_LENGTHOF(maximizeErrors); ++i) {
+
+ UErrorCode status = U_ZERO_ERROR;
+ const char* const minimal = maximizeErrors[i].tag;
+ const char* const maximal = maximizeErrors[i].expected;
+ const UErrorCode expectedStatus = maximizeErrors[i].uerror;
+ const int32_t expectedLength = getExpectedReturnValue(&maximizeErrors[i]);
+ const int32_t bufferSize = getBufferSize(&maximizeErrors[i], sizeof(buffer));
+
+ const int32_t length =
+ uloc_addLikelySubtags(
+ minimal,
+ buffer,
+ bufferSize,
+ &status);
+
+ if (status == U_ZERO_ERROR) {
+ log_err(" unexpected U_ZERO_ERROR for uloc_addLikelySubtags(), minimal \"%s\" expected status %s\n", minimal, u_errorName(expectedStatus));
+ status = U_ZERO_ERROR;
+ }
+ else if (status != expectedStatus) {
+ 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));
+ }
+ else if (length != expectedLength) {
+ log_err(" unexpected length for uloc_addLikelySubtags(), minimal \"%s\" expected length %d, but got %d\n", minimal, expectedLength, length);
+ }
+ else if (status == U_BUFFER_OVERFLOW_ERROR || status == U_STRING_NOT_TERMINATED_WARNING) {
+ if (uprv_strnicmp(maximal, buffer, bufferSize) != 0) {
+ log_err(" maximal doesn't match expected %s in uloc_addLikelySubtags(), minimal \"%s\" = %*s\n",
+ maximal, minimal, (int)sizeof(buffer), buffer);
+ }
+ }
+ }
+
+ for (i = 0; i < UPRV_LENGTHOF(minimizeErrors); ++i) {
+
+ UErrorCode status = U_ZERO_ERROR;
+ const char* const maximal = minimizeErrors[i].tag;
+ const char* const minimal = minimizeErrors[i].expected;
+ const UErrorCode expectedStatus = minimizeErrors[i].uerror;
+ const int32_t expectedLength = getExpectedReturnValue(&minimizeErrors[i]);
+ const int32_t bufferSize = getBufferSize(&minimizeErrors[i], sizeof(buffer));
+
+ const int32_t length =
+ uloc_minimizeSubtags(
+ maximal,
+ buffer,
+ bufferSize,
+ &status);
+
+ if (status == U_ZERO_ERROR) {
+ log_err(" unexpected U_ZERO_ERROR for uloc_minimizeSubtags(), maximal \"%s\" expected status %s\n", maximal, u_errorName(expectedStatus));
+ status = U_ZERO_ERROR;
+ }
+ else if (status != expectedStatus) {
+ 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));
+ }
+ else if (length != expectedLength) {
+ log_err(" unexpected length for uloc_minimizeSubtags(), maximal \"%s\" expected length %d, but got %d\n", maximal, expectedLength, length);
+ }
+ else if (status == U_BUFFER_OVERFLOW_ERROR || status == U_STRING_NOT_TERMINATED_WARNING) {
+ if (uprv_strnicmp(minimal, buffer, bufferSize) != 0) {
+ log_err(" minimal doesn't match expected \"%s\" in uloc_minimizeSubtags(), minimal \"%s\" = \"%*s\"\n",
+ minimal, maximal, (int)sizeof(buffer), buffer);
+ }
+ }
+ }
+}
+
+const char* const locale_to_langtag[][3] = {
+ {"", "und", "und"},
+ {"en", "en", "en"},
+ {"en_US", "en-US", "en-US"},
+ {"iw_IL", "he-IL", "he-IL"},
+ {"sr_Latn_SR", "sr-Latn-SR", "sr-Latn-SR"},
+ {"en__POSIX", "en-u-va-posix", "en-u-va-posix"},
+ {"en_POSIX", "en-u-va-posix", "en-u-va-posix"},
+ {"en_US_POSIX_VAR", "en-US-posix-x-lvariant-var", NULL}, /* variant POSIX_VAR is processed as regular variant */
+ {"en_US_VAR_POSIX", "en-US-x-lvariant-var-posix", NULL}, /* variant VAR_POSIX is processed as regular variant */
+ {"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 */
+ {"en_US_POSIX@ca=japanese", "en-US-u-ca-japanese-va-posix", "en-US-u-ca-japanese-va-posix"},
+ {"und_555", "und-555", "und-555"},
+ {"123", "und", NULL},
+ {"%$#&", "und", NULL},
+ {"_Latn", "und-Latn", "und-Latn"},
+ {"_DE", "und-DE", "und-DE"},
+ {"und_FR", "und-FR", "und-FR"},
+ {"th_TH_TH", "th-TH-x-lvariant-th", NULL},
+ {"bogus", "bogus", "bogus"},
+ {"foooobarrr", "und", NULL},
+ {"az_AZ_CYRL", "az-Cyrl-AZ", "az-Cyrl-AZ"},
+ {"aa_BB_CYRL", "aa-BB-x-lvariant-cyrl", NULL},
+ {"en_US_1234", "en-US-1234", "en-US-1234"},
+ {"en_US_VARIANTA_VARIANTB", "en-US-varianta-variantb", "en-US-varianta-variantb"},
+ {"ja__9876_5432", "ja-9876-5432", "ja-9876-5432"},
+ {"zh_Hant__VAR", "zh-Hant-x-lvariant-var", NULL},
+ {"es__BADVARIANT_GOODVAR", "es-goodvar", NULL},
+ {"en@calendar=gregorian", "en-u-ca-gregory", "en-u-ca-gregory"},
+ {"de@collation=phonebook;calendar=gregorian", "de-u-ca-gregory-co-phonebk", "de-u-ca-gregory-co-phonebk"},
+ {"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"},
+ {"en@timezone=America/New_York;calendar=japanese", "en-u-ca-japanese-tz-usnyc", "en-u-ca-japanese-tz-usnyc"},
+ {"en@timezone=US/Eastern", "en-u-tz-usnyc", "en-u-tz-usnyc"},
+ {"en@x=x-y-z;a=a-b-c", "en-x-x-y-z", NULL},
+ {"it@collation=badcollationtype;colStrength=identical;cu=usd-eur", "it-u-cu-usd-eur-ks-identic", NULL},
+ {"en_US_POSIX", "en-US-u-va-posix", "en-US-u-va-posix"},
+ {"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"},
+ {"@x=elmer", "x-elmer", "x-elmer"},
+ {"en@x=elmer", "en-x-elmer", "en-x-elmer"},
+ {"@x=elmer;a=exta", "und-a-exta-x-elmer", "und-a-exta-x-elmer"},
+ {"en_US@attribute=attr1-attr2;calendar=gregorian", "en-US-u-attr1-attr2-ca-gregory", "en-US-u-attr1-attr2-ca-gregory"},
+ /* #12671 */
+ {"en@a=bar;attribute=baz", "en-a-bar-u-baz", "en-a-bar-u-baz"},
+ {"en@a=bar;attribute=baz;x=u-foo", "en-a-bar-u-baz-x-u-foo", "en-a-bar-u-baz-x-u-foo"},
+ {"en@attribute=baz", "en-u-baz", "en-u-baz"},
+ {"en@attribute=baz;calendar=islamic-civil", "en-u-baz-ca-islamic-civil", "en-u-baz-ca-islamic-civil"},
+ {"en@a=bar;calendar=islamic-civil;x=u-foo", "en-a-bar-u-ca-islamic-civil-x-u-foo", "en-a-bar-u-ca-islamic-civil-x-u-foo"},
+ {"en@a=bar;attribute=baz;calendar=islamic-civil;x=u-foo", "en-a-bar-u-baz-ca-islamic-civil-x-u-foo", "en-a-bar-u-baz-ca-islamic-civil-x-u-foo"},
+ {NULL, NULL, NULL}
+};
+
+static void TestToLanguageTag(void) {
+ char langtag[256];
+ int32_t i;
+ UErrorCode status;
+ int32_t len;
+ const char *inloc;
+ const char *expected;
+
+ for (i = 0; locale_to_langtag[i][0] != NULL; i++) {
+ inloc = locale_to_langtag[i][0];
+
+ /* testing non-strict mode */
+ status = U_ZERO_ERROR;
+ langtag[0] = 0;
+ expected = locale_to_langtag[i][1];
+
+ len = uloc_toLanguageTag(inloc, langtag, sizeof(langtag), FALSE, &status);
+ (void)len; /* Suppress set but not used warning. */
+ if (U_FAILURE(status)) {
+ if (expected != NULL) {
+ log_err("Error returned by uloc_toLanguageTag for locale id [%s] - error: %s\n",
+ inloc, u_errorName(status));
+ }
+ } else {
+ if (expected == NULL) {
+ log_err("Error should be returned by uloc_toLanguageTag for locale id [%s], but [%s] is returned without errors\n",
+ inloc, langtag);
+ } else if (uprv_strcmp(langtag, expected) != 0) {
+ log_data_err("uloc_toLanguageTag returned language tag [%s] for input locale [%s] - expected: [%s]. Are you missing data?\n",
+ langtag, inloc, expected);
+ }
+ }
+
+ /* testing strict mode */
+ status = U_ZERO_ERROR;
+ langtag[0] = 0;
+ expected = locale_to_langtag[i][2];
+
+ len = uloc_toLanguageTag(inloc, langtag, sizeof(langtag), TRUE, &status);
+ if (U_FAILURE(status)) {
+ if (expected != NULL) {
+ log_data_err("Error returned by uloc_toLanguageTag {strict} for locale id [%s] - error: %s Are you missing data?\n",
+ inloc, u_errorName(status));
+ }
+ } else {
+ if (expected == NULL) {
+ log_err("Error should be returned by uloc_toLanguageTag {strict} for locale id [%s], but [%s] is returned without errors\n",
+ inloc, langtag);
+ } else if (uprv_strcmp(langtag, expected) != 0) {
+ log_err("uloc_toLanguageTag {strict} returned language tag [%s] for input locale [%s] - expected: [%s]\n",
+ langtag, inloc, expected);
+ }
+ }
+ }
+}
+
+#define FULL_LENGTH -1
+static const struct {
+ const char *bcpID;
+ const char *locID;
+ int32_t len;
+} langtag_to_locale[] = {
+ {"en", "en", FULL_LENGTH},
+ {"en-us", "en_US", FULL_LENGTH},
+ {"und-US", "_US", FULL_LENGTH},
+ {"und-latn", "_Latn", FULL_LENGTH},
+ {"en-US-posix", "en_US_POSIX", FULL_LENGTH},
+ {"de-de_euro", "de", 2},
+ {"kok-IN", "kok_IN", FULL_LENGTH},
+ {"123", "", 0},
+ {"en_us", "", 0},
+ {"en-latn-x", "en_Latn", 7},
+ {"art-lojban", "jbo", FULL_LENGTH},
+ {"zh-hakka", "hak", FULL_LENGTH},
+ {"zh-cmn-CH", "cmn_CH", FULL_LENGTH},
+ {"xxx-yy", "xxx_YY", FULL_LENGTH},
+ {"fr-234", "fr_234", FULL_LENGTH},
+ {"i-default", "en@x=i-default", FULL_LENGTH},
+ {"i-test", "", 0},
+ {"ja-jp-jp", "ja_JP", 5},
+ {"bogus", "bogus", FULL_LENGTH},
+ {"boguslang", "", 0},
+ {"EN-lATN-us", "en_Latn_US", FULL_LENGTH},
+ {"und-variant-1234", "__VARIANT_1234", FULL_LENGTH},
+ {"und-varzero-var1-vartwo", "__VARZERO", 11},
+ {"en-u-ca-gregory", "en@calendar=gregorian", FULL_LENGTH},
+ {"en-U-cu-USD", "en@currency=usd", FULL_LENGTH},
+ {"en-US-u-va-posix", "en_US_POSIX", FULL_LENGTH},
+ {"en-us-u-ca-gregory-va-posix", "en_US_POSIX@calendar=gregorian", FULL_LENGTH},
+ {"en-us-posix-u-va-posix", "en_US_POSIX@va=posix", FULL_LENGTH},
+ {"en-us-u-va-posix2", "en_US@va=posix2", FULL_LENGTH},
+ {"en-us-vari1-u-va-posix", "en_US_VARI1@va=posix", FULL_LENGTH},
+ {"ar-x-1-2-3", "ar@x=1-2-3", FULL_LENGTH},
+ {"fr-u-nu-latn-cu-eur", "fr@currency=eur;numbers=latn", FULL_LENGTH},
+ {"de-k-kext-u-co-phonebk-nu-latn", "de@collation=phonebook;k=kext;numbers=latn", FULL_LENGTH},
+ {"ja-u-cu-jpy-ca-jp", "ja@calendar=yes;currency=jpy;jp=yes", FULL_LENGTH},
+ {"en-us-u-tz-usnyc", "en_US@timezone=America/New_York", FULL_LENGTH},
+ {"und-a-abc-def", "und@a=abc-def", FULL_LENGTH},
+ {"zh-u-ca-chinese-x-u-ca-chinese", "zh@calendar=chinese;x=u-ca-chinese", FULL_LENGTH},
+ {"x-elmer", "@x=elmer", FULL_LENGTH},
+ {"en-US-u-attr1-attr2-ca-gregory", "en_US@attribute=attr1-attr2;calendar=gregorian", FULL_LENGTH},
+ {"sr-u-kn", "sr@colnumeric=yes", FULL_LENGTH},
+ {"de-u-kn-co-phonebk", "de@collation=phonebook;colnumeric=yes", FULL_LENGTH},
+ {"en-u-attr2-attr1-kn-kb", "en@attribute=attr1-attr2;colbackwards=yes;colnumeric=yes", FULL_LENGTH},
+ {"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},
+ {"de-u-xc-xphonebk-co-phonebk-ca-buddhist-mo-very-lo-extensi-xd-that-de-should-vc-probably-xz-killthebuffer",
+ "de@calendar=buddhist;collation=phonebook;de=should;lo=extensi;mo=very;vc=probably;xc=xphonebk;xd=that;xz=yes", 91},
+ /* #12761 */
+ {"en-a-bar-u-baz", "en@a=bar;attribute=baz", FULL_LENGTH},
+ {"en-a-bar-u-baz-x-u-foo", "en@a=bar;attribute=baz;x=u-foo", FULL_LENGTH},
+ {"en-u-baz", "en@attribute=baz", FULL_LENGTH},
+ {"en-u-baz-ca-islamic-civil", "en@attribute=baz;calendar=islamic-civil", FULL_LENGTH},
+ {"en-a-bar-u-ca-islamic-civil-x-u-foo", "en@a=bar;calendar=islamic-civil;x=u-foo", FULL_LENGTH},
+ {"en-a-bar-u-baz-ca-islamic-civil-x-u-foo", "en@a=bar;attribute=baz;calendar=islamic-civil;x=u-foo", FULL_LENGTH},
+ {"und-Arab-u-em-emoji", "_Arab@em=emoji", FULL_LENGTH},
+ {"und-Latn-u-em-emoji", "_Latn@em=emoji", FULL_LENGTH},
+ {"und-Latn-DE-u-em-emoji", "_Latn_DE@em=emoji", FULL_LENGTH},
+ {"und-Zzzz-DE-u-em-emoji", "_Zzzz_DE@em=emoji", FULL_LENGTH},
+ {"und-DE-u-em-emoji", "_DE@em=emoji", FULL_LENGTH},
+ {NULL, NULL, 0}
+};
+
+static void TestForLanguageTag(void) {
+ char locale[256];
+ int32_t i;
+ UErrorCode status;
+ int32_t parsedLen;
+ int32_t expParsedLen;
+
+ for (i = 0; langtag_to_locale[i].bcpID != NULL; i++) {
+ status = U_ZERO_ERROR;
+ locale[0] = 0;
+ expParsedLen = langtag_to_locale[i].len;
+ if (expParsedLen == FULL_LENGTH) {
+ expParsedLen = uprv_strlen(langtag_to_locale[i].bcpID);
+ }
+ uloc_forLanguageTag(langtag_to_locale[i].bcpID, locale, sizeof(locale), &parsedLen, &status);
+ if (U_FAILURE(status)) {
+ log_err_status(status, "Error returned by uloc_forLanguageTag for language tag [%s] - error: %s\n",
+ langtag_to_locale[i].bcpID, u_errorName(status));
+ } else {
+ if (uprv_strcmp(langtag_to_locale[i].locID, locale) != 0) {
+ log_data_err("uloc_forLanguageTag returned locale [%s] for input language tag [%s] - expected: [%s]\n",
+ locale, langtag_to_locale[i].bcpID, langtag_to_locale[i].locID);
+ }
+ if (parsedLen != expParsedLen) {
+ log_err("uloc_forLanguageTag parsed length of %d for input language tag [%s] - expected parsed length: %d\n",
+ parsedLen, langtag_to_locale[i].bcpID, expParsedLen);
+ }
+ }
+ }
+}
+
+static void TestToUnicodeLocaleKey(void)
+{
+ /* $IN specifies the result should be the input pointer itself */
+ static const char* DATA[][2] = {
+ {"calendar", "ca"},
+ {"CALEndar", "ca"}, /* difference casing */
+ {"ca", "ca"}, /* bcp key itself */
+ {"kv", "kv"}, /* no difference between legacy and bcp */
+ {"foo", NULL}, /* unknown, bcp ill-formed */
+ {"ZZ", "$IN"}, /* unknown, bcp well-formed - */
+ {NULL, NULL}
+ };
+
+ int32_t i;
+ for (i = 0; DATA[i][0] != NULL; i++) {
+ const char* keyword = DATA[i][0];
+ const char* expected = DATA[i][1];
+ const char* bcpKey = NULL;
+
+ bcpKey = uloc_toUnicodeLocaleKey(keyword);
+ if (expected == NULL) {
+ if (bcpKey != NULL) {
+ log_err("toUnicodeLocaleKey: keyword=%s => %s, expected=NULL\n", keyword, bcpKey);
+ }
+ } else if (bcpKey == NULL) {
+ log_data_err("toUnicodeLocaleKey: keyword=%s => NULL, expected=%s\n", keyword, expected);
+ } else if (uprv_strcmp(expected, "$IN") == 0) {
+ if (bcpKey != keyword) {
+ log_err("toUnicodeLocaleKey: keyword=%s => %s, expected=%s(input pointer)\n", keyword, bcpKey, keyword);
+ }
+ } else if (uprv_strcmp(bcpKey, expected) != 0) {
+ log_err("toUnicodeLocaleKey: keyword=%s => %s, expected=%s\n", keyword, bcpKey, expected);
+ }
+ }
+}
+
+static void TestToLegacyKey(void)
+{
+ /* $IN specifies the result should be the input pointer itself */
+ static const char* DATA[][2] = {
+ {"kb", "colbackwards"},
+ {"kB", "colbackwards"}, /* different casing */
+ {"Collation", "collation"}, /* keyword itself with different casing */
+ {"kv", "kv"}, /* no difference between legacy and bcp */
+ {"foo", "$IN"}, /* unknown, bcp ill-formed */
+ {"ZZ", "$IN"}, /* unknown, bcp well-formed */
+ {"e=mc2", NULL}, /* unknown, bcp/legacy ill-formed */
+ {NULL, NULL}
+ };
+
+ int32_t i;
+ for (i = 0; DATA[i][0] != NULL; i++) {
+ const char* keyword = DATA[i][0];
+ const char* expected = DATA[i][1];
+ const char* legacyKey = NULL;
+
+ legacyKey = uloc_toLegacyKey(keyword);
+ if (expected == NULL) {
+ if (legacyKey != NULL) {
+ log_err("toLegacyKey: keyword=%s => %s, expected=NULL\n", keyword, legacyKey);
+ }
+ } else if (legacyKey == NULL) {
+ log_err("toLegacyKey: keyword=%s => NULL, expected=%s\n", keyword, expected);
+ } else if (uprv_strcmp(expected, "$IN") == 0) {
+ if (legacyKey != keyword) {
+ log_err("toLegacyKey: keyword=%s => %s, expected=%s(input pointer)\n", keyword, legacyKey, keyword);
+ }
+ } else if (uprv_strcmp(legacyKey, expected) != 0) {
+ log_data_err("toUnicodeLocaleKey: keyword=%s, %s, expected=%s\n", keyword, legacyKey, expected);
+ }
+ }
+}
+
+static void TestToUnicodeLocaleType(void)
+{
+ /* $IN specifies the result should be the input pointer itself */
+ static const char* DATA[][3] = {
+ {"tz", "Asia/Kolkata", "inccu"},
+ {"calendar", "gregorian", "gregory"},
+ {"ca", "gregorian", "gregory"},
+ {"ca", "Gregorian", "gregory"},
+ {"ca", "buddhist", "buddhist"},
+ {"Calendar", "Japanese", "japanese"},
+ {"calendar", "Islamic-Civil", "islamic-civil"},
+ {"calendar", "islamicc", "islamic-civil"}, /* bcp type alias */
+ {"colalternate", "NON-IGNORABLE", "noignore"},
+ {"colcaselevel", "yes", "true"},
+ {"rg", "GBzzzz", "$IN"},
+ {"tz", "america/new_york", "usnyc"},
+ {"tz", "Asia/Kolkata", "inccu"},
+ {"timezone", "navajo", "usden"},
+ {"ca", "aaaa", "$IN"}, /* unknown type, well-formed type */
+ {"ca", "gregory-japanese-islamic", "$IN"}, /* unknown type, well-formed type */
+ {"zz", "gregorian", NULL}, /* unknown key, ill-formed type */
+ {"co", "foo-", NULL}, /* unknown type, ill-formed type */
+ {"variableTop", "00A0", "$IN"}, /* valid codepoints type */
+ {"variableTop", "wxyz", "$IN"}, /* invalid codepoints type - return as is for now */
+ {"kr", "space-punct", "space-punct"}, /* valid reordercode type */
+ {"kr", "digit-spacepunct", NULL}, /* invalid (bcp ill-formed) reordercode type */
+ {NULL, NULL, NULL}
+ };
+
+ int32_t i;
+ for (i = 0; DATA[i][0] != NULL; i++) {
+ const char* keyword = DATA[i][0];
+ const char* value = DATA[i][1];
+ const char* expected = DATA[i][2];
+ const char* bcpType = NULL;
+
+ bcpType = uloc_toUnicodeLocaleType(keyword, value);
+ if (expected == NULL) {
+ if (bcpType != NULL) {
+ log_err("toUnicodeLocaleType: keyword=%s, value=%s => %s, expected=NULL\n", keyword, value, bcpType);
+ }
+ } else if (bcpType == NULL) {
+ log_data_err("toUnicodeLocaleType: keyword=%s, value=%s => NULL, expected=%s\n", keyword, value, expected);
+ } else if (uprv_strcmp(expected, "$IN") == 0) {
+ if (bcpType != value) {
+ log_err("toUnicodeLocaleType: keyword=%s, value=%s => %s, expected=%s(input pointer)\n", keyword, value, bcpType, value);
+ }
+ } else if (uprv_strcmp(bcpType, expected) != 0) {
+ log_data_err("toUnicodeLocaleType: keyword=%s, value=%s => %s, expected=%s\n", keyword, value, bcpType, expected);
+ }
+ }
+}
+
+static void TestToLegacyType(void)
+{
+ /* $IN specifies the result should be the input pointer itself */
+ static const char* DATA[][3] = {
+ {"calendar", "gregory", "gregorian"},
+ {"ca", "gregory", "gregorian"},
+ {"ca", "Gregory", "gregorian"},
+ {"ca", "buddhist", "buddhist"},
+ {"Calendar", "Japanese", "japanese"},
+ {"calendar", "Islamic-Civil", "islamic-civil"},
+ {"calendar", "islamicc", "islamic-civil"}, /* bcp type alias */
+ {"colalternate", "noignore", "non-ignorable"},
+ {"colcaselevel", "true", "yes"},
+ {"rg", "gbzzzz", "gbzzzz"},
+ {"tz", "usnyc", "America/New_York"},
+ {"tz", "inccu", "Asia/Calcutta"},
+ {"timezone", "usden", "America/Denver"},
+ {"timezone", "usnavajo", "America/Denver"}, /* bcp type alias */
+ {"colstrength", "quarternary", "quaternary"}, /* type alias */
+ {"ca", "aaaa", "$IN"}, /* unknown type */
+ {"calendar", "gregory-japanese-islamic", "$IN"}, /* unknown type, well-formed type */
+ {"zz", "gregorian", "$IN"}, /* unknown key, bcp ill-formed type */
+ {"ca", "gregorian-calendar", "$IN"}, /* known key, bcp ill-formed type */
+ {"co", "e=mc2", NULL}, /* known key, ill-formed bcp/legacy type */
+ {"variableTop", "00A0", "$IN"}, /* valid codepoints type */
+ {"variableTop", "wxyz", "$IN"}, /* invalid codepoints type - return as is for now */
+ {"kr", "space-punct", "space-punct"}, /* valid reordercode type */
+ {"kr", "digit-spacepunct", "digit-spacepunct"}, /* invalid reordercode type, but ok for legacy syntax */
+ {NULL, NULL, NULL}
+ };
+
+ int32_t i;
+ for (i = 0; DATA[i][0] != NULL; i++) {
+ const char* keyword = DATA[i][0];
+ const char* value = DATA[i][1];
+ const char* expected = DATA[i][2];
+ const char* legacyType = NULL;
+
+ legacyType = uloc_toLegacyType(keyword, value);
+ if (expected == NULL) {
+ if (legacyType != NULL) {
+ log_err("toLegacyType: keyword=%s, value=%s => %s, expected=NULL\n", keyword, value, legacyType);
+ }
+ } else if (legacyType == NULL) {
+ log_err("toLegacyType: keyword=%s, value=%s => NULL, expected=%s\n", keyword, value, expected);
+ } else if (uprv_strcmp(expected, "$IN") == 0) {
+ if (legacyType != value) {
+ log_err("toLegacyType: keyword=%s, value=%s => %s, expected=%s(input pointer)\n", keyword, value, legacyType, value);
+ }
+ } else if (uprv_strcmp(legacyType, expected) != 0) {
+ log_data_err("toLegacyType: keyword=%s, value=%s => %s, expected=%s\n", keyword, value, legacyType, expected);
+ } else {
+ log_verbose("toLegacyType: keyword=%s, value=%s => %s\n", keyword, value, legacyType);
+ }
+ }
+}
+
+
+
+static void test_unicode_define(const char *namech, char ch, const char *nameu, UChar uch)
+{
+ UChar asUch[1];
+ asUch[0]=0;
+ log_verbose("Testing whether %s[\\x%02x,'%c'] == %s[U+%04X]\n", namech, ch,(int)ch, nameu, (int) uch);
+ u_charsToUChars(&ch, asUch, 1);
+ if(asUch[0] != uch) {
+ 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);
+ } else {
+ log_verbose(" .. OK, == U+%04X\n", (int)asUch[0]);
+ }
+}
+
+#define TEST_UNICODE_DEFINE(x,y) test_unicode_define(#x, (char)(x), #y, (UChar)(y))
+
+static void TestUnicodeDefines(void) {
+ TEST_UNICODE_DEFINE(ULOC_KEYWORD_SEPARATOR, ULOC_KEYWORD_SEPARATOR_UNICODE);
+ TEST_UNICODE_DEFINE(ULOC_KEYWORD_ASSIGN, ULOC_KEYWORD_ASSIGN_UNICODE);
+ TEST_UNICODE_DEFINE(ULOC_KEYWORD_ITEM_SEPARATOR, ULOC_KEYWORD_ITEM_SEPARATOR_UNICODE);
+}
+
+static void TestIsRightToLeft() {
+ // API test only. More test cases in intltest/LocaleTest.
+ if(uloc_isRightToLeft("root") || !uloc_isRightToLeft("EN-HEBR")) {
+ log_err("uloc_isRightToLeft() failed");
+ }
+}
+
+typedef struct {
+ const char * badLocaleID;
+ const char * displayLocale;
+ const char * expectedName;
+ UErrorCode expectedStatus;
+} BadLocaleItem;
+
+static const BadLocaleItem badLocaleItems[] = {
+ { "-9223372036854775808", "en", "9223372036854775808", U_USING_DEFAULT_WARNING },
+ /* add more in the future */
+ { NULL, NULL, NULL, U_ZERO_ERROR } /* terminator */
+};
+
+enum { kUBufDispNameMax = 128, kBBufDispNameMax = 256 };
+
+static void TestBadLocaleIDs() {
+ const BadLocaleItem* itemPtr;
+ for (itemPtr = badLocaleItems; itemPtr->badLocaleID != NULL; itemPtr++) {
+ UChar ubufExpect[kUBufDispNameMax], ubufGet[kUBufDispNameMax];
+ UErrorCode status = U_ZERO_ERROR;
+ int32_t ulenExpect = u_unescape(itemPtr->expectedName, ubufExpect, kUBufDispNameMax);
+ int32_t ulenGet = uloc_getDisplayName(itemPtr->badLocaleID, itemPtr->displayLocale, ubufGet, kUBufDispNameMax, &status);
+ if (status != itemPtr->expectedStatus ||
+ (U_SUCCESS(status) && (ulenGet != ulenExpect || u_strncmp(ubufGet, ubufExpect, ulenExpect) != 0))) {
+ char bbufExpect[kBBufDispNameMax], bbufGet[kBBufDispNameMax];
+ u_austrncpy(bbufExpect, ubufExpect, ulenExpect);
+ u_austrncpy(bbufGet, ubufGet, ulenGet);
+ log_err("FAIL: For localeID %s, displayLocale %s, calling uloc_getDisplayName:\n"
+ " expected status %-26s, name (len %2d): %s\n"
+ " got status %-26s, name (len %2d): %s\n",
+ itemPtr->badLocaleID, itemPtr->displayLocale,
+ u_errorName(itemPtr->expectedStatus), ulenExpect, bbufExpect,
+ u_errorName(status), ulenGet, bbufGet );
+ }
+ }
+}
+
+typedef enum UldnNameType {
+ TEST_ULDN_LOCALE,
+ TEST_ULDN_LANGUAGE,
+ TEST_ULDN_SCRIPT,
+ TEST_ULDN_REGION,
+} UldnNameType;
+
+typedef struct {
+ const char * localeToName; // NULL to terminate a list of these
+ UldnNameType nameType;
+ const char * expectResult;
+} UldnItem;
+
+typedef struct {
+ const char * displayLocale;
+ const UDisplayContext * displayOptions; // set of 3 UDisplayContext items
+ const UldnItem * testItems;
+ int32_t countItems;
+} UldnLocAndOpts;
+
+static const UDisplayContext optStdMidLong[3] = {UDISPCTX_STANDARD_NAMES, UDISPCTX_CAPITALIZATION_FOR_MIDDLE_OF_SENTENCE, UDISPCTX_LENGTH_FULL};
+static const UDisplayContext optStdMidShrt[3] = {UDISPCTX_STANDARD_NAMES, UDISPCTX_CAPITALIZATION_FOR_MIDDLE_OF_SENTENCE, UDISPCTX_LENGTH_SHORT};
+static const UDisplayContext optDiaMidLong[3] = {UDISPCTX_DIALECT_NAMES, UDISPCTX_CAPITALIZATION_FOR_MIDDLE_OF_SENTENCE, UDISPCTX_LENGTH_FULL};
+static const UDisplayContext optDiaMidShrt[3] = {UDISPCTX_DIALECT_NAMES, UDISPCTX_CAPITALIZATION_FOR_MIDDLE_OF_SENTENCE, UDISPCTX_LENGTH_SHORT};
+
+static const UDisplayContext optStdBegLong[3] = {UDISPCTX_STANDARD_NAMES, UDISPCTX_CAPITALIZATION_FOR_BEGINNING_OF_SENTENCE, UDISPCTX_LENGTH_FULL};
+static const UDisplayContext optStdBegShrt[3] = {UDISPCTX_STANDARD_NAMES, UDISPCTX_CAPITALIZATION_FOR_BEGINNING_OF_SENTENCE, UDISPCTX_LENGTH_SHORT};
+static const UDisplayContext optDiaBegLong[3] = {UDISPCTX_DIALECT_NAMES, UDISPCTX_CAPITALIZATION_FOR_BEGINNING_OF_SENTENCE, UDISPCTX_LENGTH_FULL};
+static const UDisplayContext optDiaBegShrt[3] = {UDISPCTX_DIALECT_NAMES, UDISPCTX_CAPITALIZATION_FOR_BEGINNING_OF_SENTENCE, UDISPCTX_LENGTH_SHORT};
+
+static const UDisplayContext optStdLstLong[3] = {UDISPCTX_STANDARD_NAMES, UDISPCTX_CAPITALIZATION_FOR_UI_LIST_OR_MENU, UDISPCTX_LENGTH_FULL};
+static const UDisplayContext optStdLstShrt[3] = {UDISPCTX_STANDARD_NAMES, UDISPCTX_CAPITALIZATION_FOR_UI_LIST_OR_MENU, UDISPCTX_LENGTH_SHORT};
+static const UDisplayContext optDiaLstLong[3] = {UDISPCTX_DIALECT_NAMES, UDISPCTX_CAPITALIZATION_FOR_UI_LIST_OR_MENU, UDISPCTX_LENGTH_FULL};
+static const UDisplayContext optDiaLstShrt[3] = {UDISPCTX_DIALECT_NAMES, UDISPCTX_CAPITALIZATION_FOR_UI_LIST_OR_MENU, UDISPCTX_LENGTH_SHORT};
+
+static const UldnItem en_StdMidLong[] = {
+ { "en_US", TEST_ULDN_LOCALE, "English (US)" },
+ { "en_US_POSIX", TEST_ULDN_LOCALE, "English (US, Computer)" },
+ { "en_US@calendar=chinese", TEST_ULDN_LOCALE, "English (US, Chinese Calendar)" },
+ { "en_CA", TEST_ULDN_LOCALE, "English (Canada)" },
+ { "pt", TEST_ULDN_LOCALE, "Portuguese" },
+ { "pt_BR", TEST_ULDN_LOCALE, "Portuguese (Brazil)" },
+ { "pt_PT", TEST_ULDN_LOCALE, "Portuguese (Portugal)" },
+ { "zh_Hans", TEST_ULDN_LOCALE, "Chinese (Simplified)" },
+ { "zh_Hant_HK", TEST_ULDN_LOCALE, "Chinese (Traditional, Hong Kong)" },
+ { "zh_HK", TEST_ULDN_LOCALE, "Chinese (Hong Kong)" },
+ { "Latn", TEST_ULDN_SCRIPT, "Latin" },
+ { "Hans", TEST_ULDN_SCRIPT, "Simplified Han" },
+ { "Hant", TEST_ULDN_SCRIPT, "Traditional Han" },
+ { "US", TEST_ULDN_REGION, "United States" },
+ { "CA", TEST_ULDN_REGION, "Canada" },
+ { "GB", TEST_ULDN_REGION, "United Kingdom" },
+ { "HK", TEST_ULDN_REGION, "Hong Kong (China)" },
+};
+
+static const UldnItem en_StdMidShrt[] = {
+ { "en_US", TEST_ULDN_LOCALE, "English (US)" },
+ { "en_US_POSIX", TEST_ULDN_LOCALE, "English (US, Computer)" },
+ { "en_US@calendar=chinese", TEST_ULDN_LOCALE, "English (US, Calendar: chinese)" },
+ { "en_CA", TEST_ULDN_LOCALE, "English (Canada)" },
+ { "pt", TEST_ULDN_LOCALE, "Portuguese" },
+ { "pt_BR", TEST_ULDN_LOCALE, "Portuguese (Brazil)" },
+ { "pt_PT", TEST_ULDN_LOCALE, "Portuguese (Portugal)" },
+ { "zh_Hans", TEST_ULDN_LOCALE, "Chinese (Simplified)" },
+ { "zh_Hant_HK", TEST_ULDN_LOCALE, "Chinese (Traditional, Hong Kong)" },
+ { "zh_HK", TEST_ULDN_LOCALE, "Chinese (Hong Kong)" },
+ { "Latn", TEST_ULDN_SCRIPT, "Latin" },
+ { "Hans", TEST_ULDN_SCRIPT, "Simplified Han" },
+ { "Hant", TEST_ULDN_SCRIPT, "Traditional Han" },
+ { "US", TEST_ULDN_REGION, "US" },
+ { "CA", TEST_ULDN_REGION, "Canada" },
+ { "GB", TEST_ULDN_REGION, "UK" },
+ { "HK", TEST_ULDN_REGION, "Hong Kong" },
+};
+
+static const UldnItem en_DiaMidLong[] = {
+ { "en_US", TEST_ULDN_LOCALE, "American English" },
+ { "en_US_POSIX", TEST_ULDN_LOCALE, "American English (Computer)" },
+ { "en_US@calendar=chinese", TEST_ULDN_LOCALE, "American English (Chinese Calendar)" },
+ { "en_CA", TEST_ULDN_LOCALE, "Canadian English" },
+ { "pt", TEST_ULDN_LOCALE, "Portuguese" },
+ { "pt_BR", TEST_ULDN_LOCALE, "Brazilian Portuguese" },
+ { "pt_PT", TEST_ULDN_LOCALE, "European Portuguese" },
+ { "zh_Hans", TEST_ULDN_LOCALE, "Simplified Chinese" },
+ { "zh_Hant_HK", TEST_ULDN_LOCALE, "Traditional Chinese (Hong Kong)" },
+ { "zh_HK", TEST_ULDN_LOCALE, "Chinese (Hong Kong)" },
+ { "Latn", TEST_ULDN_SCRIPT, "Latin" },
+ { "Hans", TEST_ULDN_SCRIPT, "Simplified Han" },
+ { "Hant", TEST_ULDN_SCRIPT, "Traditional Han" },
+ { "US", TEST_ULDN_REGION, "United States" },
+ { "CA", TEST_ULDN_REGION, "Canada" },
+ { "GB", TEST_ULDN_REGION, "United Kingdom" },
+ { "HK", TEST_ULDN_REGION, "Hong Kong (China)" },
+};
+
+static const UldnItem en_DiaMidShrt[] = {
+ { "en_US", TEST_ULDN_LOCALE, "US English" },
+ { "en_US_POSIX", TEST_ULDN_LOCALE, "US English (Computer)" },
+ { "en_US@calendar=chinese", TEST_ULDN_LOCALE, "US English (Calendar: chinese)" },
+ { "en_CA", TEST_ULDN_LOCALE, "Canadian English" },
+ { "pt", TEST_ULDN_LOCALE, "Portuguese" },
+ { "pt_BR", TEST_ULDN_LOCALE, "Brazilian Portuguese" },
+ { "pt_PT", TEST_ULDN_LOCALE, "European Portuguese" },
+ { "zh_Hans", TEST_ULDN_LOCALE, "Simplified Chinese" },
+ { "zh_Hant_HK", TEST_ULDN_LOCALE, "Traditional Chinese (Hong Kong)" },
+ { "zh_HK", TEST_ULDN_LOCALE, "Chinese (Hong Kong)" },
+ { "Latn", TEST_ULDN_SCRIPT, "Latin" },
+ { "Hans", TEST_ULDN_SCRIPT, "Simplified Han" },
+ { "Hant", TEST_ULDN_SCRIPT, "Traditional Han" },
+ { "US", TEST_ULDN_REGION, "US" },
+ { "CA", TEST_ULDN_REGION, "Canada" },
+ { "GB", TEST_ULDN_REGION, "UK" },
+ { "HK", TEST_ULDN_REGION, "Hong Kong" },
+};
+
+static const UldnItem fr_StdMidLong[] = {
+ { "en_US", TEST_ULDN_LOCALE, "anglais (\\u00C9.-U.)" },
+ { "US", TEST_ULDN_REGION, "\\u00C9tats-Unis" },
+ { "HK", TEST_ULDN_REGION, "Hong Kong (Chine)" },
+};
+
+static const UldnItem fr_StdMidShrt[] = {
+ { "en_US", TEST_ULDN_LOCALE, "anglais (\\u00C9.-U.)" },
+ { "US", TEST_ULDN_REGION, "\\u00C9.-U." },
+ { "HK", TEST_ULDN_REGION, "Hong Kong" },
+};
+
+static const UldnItem fr_StdBegLong[] = {
+ { "en_US", TEST_ULDN_LOCALE, "Anglais (\\u00C9.-U.)" },
+};
+
+static const UldnItem fr_StdLstLong[] = {
+ { "en_US", TEST_ULDN_LOCALE, "Anglais (\\u00C9.-U.)" },
+ { "PS", TEST_ULDN_REGION, "Territoires palestiniens" },
+};
+
+static const UldnItem fr_DiaMidLong[] = {
+ { "en_US", TEST_ULDN_LOCALE, "anglais am\\u00E9ricain" },
+};
+
+static const UldnItem ca_StdLstLong[] = {
+ { "PS", TEST_ULDN_REGION, "Territoris palestins" },
+};
+
+static const UldnLocAndOpts uldnLocAndOpts[] = {
+ { "en", optStdMidLong, en_StdMidLong, UPRV_LENGTHOF(en_StdMidLong) },
+ { "en", optStdMidShrt, en_StdMidShrt, UPRV_LENGTHOF(en_StdMidShrt) },
+ { "en", optDiaMidLong, en_DiaMidLong, UPRV_LENGTHOF(en_DiaMidLong) },
+ { "en", optDiaMidShrt, en_DiaMidShrt, UPRV_LENGTHOF(en_DiaMidShrt) },
+ { "fr", optStdMidLong, fr_StdMidLong, UPRV_LENGTHOF(fr_StdMidLong) },
+ { "fr", optStdMidShrt, fr_StdMidShrt, UPRV_LENGTHOF(fr_StdMidShrt) },
+ { "fr", optStdBegLong, fr_StdBegLong, UPRV_LENGTHOF(fr_StdBegLong) },
+ { "fr", optStdLstLong, fr_StdLstLong, UPRV_LENGTHOF(fr_StdLstLong) },
+ { "fr_CA", optStdLstLong, fr_StdLstLong, UPRV_LENGTHOF(fr_StdLstLong) },
+ { "fr", optDiaMidLong, fr_DiaMidLong, UPRV_LENGTHOF(fr_DiaMidLong) },
+ { "ca", optStdLstLong, ca_StdLstLong, UPRV_LENGTHOF(ca_StdLstLong) },
+ { NULL, NULL, NULL, 0 }
+};
+
+enum { kUNameBuf = 128, kBNameBuf = 256 };
+
+static void TestUldnNameVariants() {
+ const UldnLocAndOpts * uloPtr;
+ for (uloPtr = uldnLocAndOpts; uloPtr->displayLocale != NULL; uloPtr++) {
+ UErrorCode status = U_ZERO_ERROR;
+ ULocaleDisplayNames * uldn = uldn_openForContext(uloPtr->displayLocale, (UDisplayContext*)uloPtr->displayOptions, 3, &status);
+ if (U_FAILURE(status)) {
+ log_data_err("uldn_openForContext fails, displayLocale %s, contexts %03X %03X %03X: %s - Are you missing data?\n",
+ uloPtr->displayLocale, uloPtr->displayOptions[0], uloPtr->displayOptions[1], uloPtr->displayOptions[2],
+ u_errorName(status) );
+ continue;
+ }
+ const UldnItem * itemPtr = uloPtr->testItems;
+ int32_t itemCount = uloPtr->countItems;
+ for (; itemCount-- > 0; itemPtr++) {
+ UChar uget[kUNameBuf], uexp[kUNameBuf];
+ int32_t ulenget, ulenexp;
+ const char* typeString;
+
+ status = U_ZERO_ERROR;
+ switch (itemPtr->nameType) {
+ case TEST_ULDN_LOCALE:
+ ulenget = uldn_localeDisplayName(uldn, itemPtr->localeToName, uget, kUNameBuf, &status);
+ typeString = "locale";
+ break;
+ case TEST_ULDN_LANGUAGE:
+ ulenget = uldn_languageDisplayName(uldn, itemPtr->localeToName, uget, kUNameBuf, &status);
+ typeString = "language";
+ break;
+ case TEST_ULDN_SCRIPT:
+ ulenget = uldn_scriptDisplayName(uldn, itemPtr->localeToName, uget, kUNameBuf, &status);
+ typeString = "script";
+ break;
+ case TEST_ULDN_REGION:
+ ulenget = uldn_regionDisplayName(uldn, itemPtr->localeToName, uget, kUNameBuf, &status);
+ typeString = "region";
+ break;
+ default:
+ continue;
+ }
+ if (U_FAILURE(status)) {
+ log_data_err("uldn_%sDisplayName fails, displayLocale %s, contexts %03X %03X %03X, localeToName %s: %s\n",
+ typeString, uloPtr->displayLocale, uloPtr->displayOptions[0], uloPtr->displayOptions[1], uloPtr->displayOptions[2],
+ itemPtr->localeToName, u_errorName(status) );
+ continue;
+ }
+ ulenexp = u_unescape(itemPtr->expectResult, uexp, kUNameBuf);
+ if (ulenget != ulenexp || u_strncmp(uget, uexp, ulenexp) != 0) {
+ char bexp[kBNameBuf], bget[kBNameBuf];
+ u_strToUTF8(bexp, kBNameBuf, NULL, uexp, ulenexp, &status);
+ u_strToUTF8(bget, kBNameBuf, NULL, uget, ulenget, &status);
+ log_data_err("uldn_%sDisplayName fails, displayLocale %s, contexts %03X %03X %03X, localeToName %s:\n expect %2d: %s\n get %2d: %s\n",
+ typeString, uloPtr->displayLocale, uloPtr->displayOptions[0], uloPtr->displayOptions[1], uloPtr->displayOptions[2],
+ itemPtr->localeToName, ulenexp, bexp, ulenget, bget );
+ }
+ }
+
+ uldn_close(uldn);
+ }
+}
+
+/* Apple-specific, test for Apple-specific function ualoc_getAppleParent */
+static const char* localesAndAppleParent[] = {
+ "en", "root",
+ "en-US", "en",
+ "en-CA", "en_001",
+ "en-CN", "en",
+ "en-JP", "en",
+ "en-TW", "en",
+ "en-001", "en",
+ "en_001", "en",
+ "en-150", "en_GB",
+ "en-GB", "en_001",
+ "en_GB", "en_001",
+ "en-AU", "en_GB",
+ "en-BE", "en_150",
+ "en-DG", "en_GB",
+ "en-FK", "en_GB",
+ "en-GG", "en_GB",
+ "en-GI", "en_GB",
+ "en-HK", "en_GB",
+ "en-IE", "en_GB",
+ "en-IM", "en_GB",
+ "en-IN", "en_GB",
+ "en-IO", "en_GB",
+ "en-JE", "en_GB",
+ "en-JM", "en_GB",
+ "en-MO", "en_GB",
+ "en-MT", "en_GB",
+ "en-MV", "en_GB",
+ "en-NZ", "en_AU",
+ "en-PK", "en_GB",
+ "en-SG", "en_GB",
+ "en-SH", "en_GB",
+ "en-VG", "en_GB",
+ "es", "root",
+ "es-ES", "es",
+ "es-419", "es",
+ "es_419", "es",
+ "es-MX", "es_419",
+ "es-AR", "es_419",
+ "es-BR", "es_419",
+ "es-BZ", "es_419",
+ "es-AG", "es_419",
+ "es-AW", "es_419",
+ "es-CA", "es_419",
+ "es-CW", "es_419",
+ "es-SX", "es_419",
+ "es-TT", "es_419",
+ "fr", "root",
+ "fr-CA", "fr",
+ "fr-CH", "fr",
+ "haw", "root",
+ "nl", "root",
+ "nl-BE", "nl",
+ "pt", "root",
+ "pt-BR", "pt",
+ "pt-PT", "pt",
+ "pt-MO", "pt_PT",
+ "pt-CH", "pt_PT",
+ "pt-GQ", "pt_PT",
+ "pt-LU", "pt_PT",
+ "sr", "root",
+ "sr-Cyrl", "sr",
+ "sr-Latn", "root",
+ "tlh", "root",
+ "zh_CN", "root",
+ "zh-CN", "root",
+ "zh", "zh_CN",
+ "zh-Hans", "zh",
+ "zh_TW", "root",
+ "zh-TW", "root",
+ "zh-Hant", "zh_TW",
+ "zh_HK", "zh_Hant_HK",
+ "zh-HK", "zh_Hant_HK",
+ "zh_Hant", "zh_TW",
+ "zh-Hant-HK", "zh_Hant",
+ "zh_Hant_HK", "zh_Hant",
+ "zh-Hant-MO", "zh_Hant_HK",
+ "zh-Hans-HK", "zh_Hans",
+ "root", "root",
+ "en-Latn", "en",
+ "en-Latn-US", "en_Latn",
+ "en_US_POSIX", "en_US",
+ "en_Latn_US_POSIX", "en_Latn_US",
+ "en-u-ca-hebrew", "root",
+ "en@calendar=hebrew", "root",
+ "en_@calendar=hebrew", "root",
+ "en-", "root",
+ "en_", "root",
+ "Default@2x", "root",
+ "default", "root",
+ NULL /* terminator */
+};
+
+static void TestGetAppleParent() {
+ const char **localesPtr = localesAndAppleParent;
+ const char * locale;
+ while ((locale = *localesPtr++) != NULL) {
+ const char * expectParent = *localesPtr++;
+ UErrorCode status = U_ZERO_ERROR;
+ char getParent[ULOC_FULLNAME_CAPACITY];
+ int32_t plen = ualoc_getAppleParent(locale, getParent, ULOC_FULLNAME_CAPACITY, &status);
+ if (U_FAILURE(status)) {
+ log_err("FAIL: ualoc_getAppleParent input \"%s\", status %s\n", locale, u_errorName(status));
+ } else if (uprv_strcmp(expectParent, getParent) != 0) {
+ log_err("FAIL: ualoc_getAppleParent input \"%s\", expected parent \"%s\", got parent \"%s\"\n", locale, expectParent, getParent);
+ }
+ }
+}
+
+/* Apple-specific, test for Apple-specific function ualoc_getLanguagesForRegion */
+enum { kUALanguageEntryMax = 10 };
+
+static void TestGetLanguagesForRegion() {
+ UALanguageEntry entries[kUALanguageEntryMax];
+ int32_t entryCount;
+ UErrorCode status;
+ const char * region;
+
+ status = U_ZERO_ERROR;
+ region = "CN";
+ entryCount = ualoc_getLanguagesForRegion(region, 0.001, entries, kUALanguageEntryMax, &status);
+ if (U_FAILURE(status)) {
+ log_err("FAIL: ualoc_getLanguagesForRegion %s, status %s\n", region, u_errorName(status));
+ } else {
+ // Expect approximately:
+ // zh_Hans 0.90 UALANGSTATUS_OFFICIAL
+ // wuu 0.06 Wu
+ // hsn 0.06 Xiang
+ // yue 0.043 Yue including Cantonese
+ // hak 0.023 Hakka
+ // nan 0.019 Minnan
+ // gan 0.017 Gan
+ // ii 0.006 Yi
+ // ug_Arab 0.0055 Uighur UALANGSTATUS_REGIONAL_OFFICIAL
+ // ...at least 4 more with fractions >= 0.001
+ if (entryCount < kUALanguageEntryMax) {
+ log_err("FAIL: ualoc_getLanguagesForRegion %s, entryCount %d is too small\n", region, entryCount);
+ } else {
+ UALanguageEntry* entryPtr = entries;
+ if (uprv_strcmp(entryPtr->languageCode, "zh_Hans") != 0 || entryPtr->userFraction < 0.8 || entryPtr->userFraction > 1.0 || entryPtr->status != UALANGSTATUS_OFFICIAL) {
+ log_err("FAIL: ualoc_getLanguagesForRegion %s, invalid entries[0] { %s, %.3f, %d }\n", region, entryPtr->languageCode, entryPtr->userFraction, (int)entryPtr->status);
+ }
+ for (entryPtr++; entryPtr < entries + kUALanguageEntryMax && uprv_strcmp(entryPtr->languageCode, "ug_Arab") != 0; entryPtr++)
+ ;
+ if (entryPtr < entries + kUALanguageEntryMax) {
+ // we found ug_Arab, make sure it has correct status
+ if (entryPtr->status != UALANGSTATUS_REGIONAL_OFFICIAL) {
+ log_err("FAIL: ualoc_getLanguagesForRegion %s, ug_Arab had incorrect status %d\n", (int)entryPtr->status);
+ }
+ } else {
+ // did not find ug_Arab
+ log_err("FAIL: ualoc_getLanguagesForRegion %s, entries did not include ug_Arab\n", region);
+ }
+ }
+ }
+
+ status = U_ZERO_ERROR;
+ region = "CA";
+ entryCount = ualoc_getLanguagesForRegion(region, 0.001, entries, kUALanguageEntryMax, &status);
+ if (U_FAILURE(status)) {
+ log_err("FAIL: ualoc_getLanguagesForRegion %s, status %s\n", region, u_errorName(status));
+ } else {
+ // Expect approximately:
+ // en 0.85 UALANGSTATUS_OFFICIAL
+ // fr 0.22 UALANGSTATUS_OFFICIAL
+ // ...
+ if (entryCount < 2) {
+ log_err("FAIL: ualoc_getLanguagesForRegion %s, entryCount %d is too small\n", region, entryCount);
+ } else {
+ if (uprv_strcmp(entries[0].languageCode, "en") != 0 || entries[0].userFraction < 0.7 || entries[0].userFraction > 1.0 || entries[0].status != UALANGSTATUS_OFFICIAL) {
+ log_err("FAIL: ualoc_getLanguagesForRegion %s, invalid entries[0] { %s, %.3f, %d }\n", region, entries[0].languageCode, entries[0].userFraction, (int)entries[0].status);
+ }
+ if (uprv_strcmp(entries[1].languageCode, "fr") != 0 || entries[1].userFraction < 0.1 || entries[1].userFraction > 1.0 || entries[1].status != UALANGSTATUS_OFFICIAL) {
+ log_err("FAIL: ualoc_getLanguagesForRegion %s, invalid entries[1] { %s, %.3f, %d }\n", region, entries[1].languageCode, entries[1].userFraction, (int)entries[1].status);
+ }
+ }
+ }
+
+ status = U_ZERO_ERROR;
+ region = "IN";
+ entryCount = ualoc_getLanguagesForRegion(region, 0.001, NULL, 0, &status);
+ if (U_FAILURE(status)) {
+ log_err("FAIL: ualoc_getLanguagesForRegion %s, status %s\n", region, u_errorName(status));
+ } else {
+ if (entryCount < 40) {
+ log_err("FAIL: ualoc_getLanguagesForRegion %s, entryCount %d is too small\n", region, entryCount);
+ }
+ }
+}
+
+/* data for TestAppleLocalizationsToUse */
+
+typedef struct {
+ const char * const *locs;
+ int32_t locCount;
+} AppleLocsAndCount;
+
+enum { kNumLocSets = 6 };
+
+typedef struct {
+ const char * language;
+ const char ** expLocsForSets[kNumLocSets];
+} LangAndExpLocs;
+
+
+static const char * appleLocs1[] = {
+ "Arabic",
+ "Danish",
+ "Dutch",
+ "English",
+ "Finnish",
+ "French",
+ "German",
+ "Italian",
+ "Japanese",
+ "Korean",
+ "Norwegian",
+ "Polish",
+ "Portuguese",
+ "Russian",
+ "Spanish",
+ "Swedish",
+ "Thai",
+ "Turkish",
+ "ca",
+ "cs",
+ "el",
+ "he",
+ "hr",
+ "hu",
+ "id",
+ "ms",
+ "ro",
+ "sk",
+ "uk",
+ "vi",
+ "zh_CN", "zh_TW",
+};
+
+static const char * appleLocs2[] = {
+ "ar",
+ "ca",
+ "cs",
+ "da",
+ "de",
+ "el",
+ "en", "en_AU", "en_GB",
+ "es", "es_MX",
+ "fi",
+ "fr", "fr_CA",
+ "he",
+ "hr",
+ "hu",
+ "id",
+ "it",
+ "ja",
+ "ko",
+ "ms",
+ "nl",
+ "no",
+ "pl",
+ "pt", "pt_PT",
+ "ro",
+ "ru",
+ "sk",
+ "sv",
+ "th",
+ "tr",
+ "uk",
+ "vi",
+ "zh_CN", "zh_HK", "zh_TW",
+};
+
+static const char * appleLocs3[] = {
+ "ar",
+ "ca",
+ "cs",
+ "da",
+ "de",
+ "el",
+ "en", "en_AU", "en_CA", "en_GB",
+ "es", "es_419",
+ "fi",
+ "fr", "fr_CA", "fr_FR",
+ "he",
+ "hr",
+ "hu",
+ "id",
+ "it",
+ "ja",
+ "ko",
+ "ms",
+ "nb",
+ "nl",
+ "pl",
+ "pt", "pt_BR", "pt_PT",
+ "ro",
+ "ru",
+ "sk",
+ "sv",
+ "th",
+ "tr",
+ "uk",
+ "vi",
+ "zh_CN", "zh_HK", "zh_MO", "zh_TW",
+};
+
+static const char * appleLocs4[] = {
+ "en", "en_AU", "en_CA", "en_GB", "en_IN", "en_US",
+ "es", "es_419", "es_MX",
+ "fr", "fr_CA", "fr_CH", "fr_FR",
+ "nl", "nl_BE", "nl_NL",
+ "pt", "pt_BR",
+ "ro", "ro_MD", "ro_RO",
+ "zh_Hans", "zh_Hant", "zh_Hant_HK",
+};
+
+static const char * appleLocs5[] = {
+ "en", "en_001", "en_AU", "en_GB",
+ "es", "es_ES", "es_MX",
+ "zh_CN", "zh_Hans", "zh_Hant", "zh_TW",
+ "yi",
+ "fil",
+ "haw",
+ "tlh",
+ "sr",
+ "sr-Latn",
+};
+
+// list 6
+static const char * appleLocs6[] = {
+ "en", "en_001", "en_150", "en_AU", "en_GB",
+ "es", "es_419", "es_ES", "es_MX",
+ "zh_CN", "zh_Hans", "zh_Hant", "zh_Hant_HK", "zh_HK", "zh_TW",
+ "iw",
+ "in",
+ "mo",
+ "tl",
+};
+
+static const AppleLocsAndCount locAndCountEntries[kNumLocSets] = {
+ { appleLocs1, UPRV_LENGTHOF(appleLocs1) },
+ { appleLocs2, UPRV_LENGTHOF(appleLocs2) },
+ { appleLocs3, UPRV_LENGTHOF(appleLocs3) },
+ { appleLocs4, UPRV_LENGTHOF(appleLocs4) },
+ { appleLocs5, UPRV_LENGTHOF(appleLocs5) },
+ { appleLocs6, UPRV_LENGTHOF(appleLocs6) },
+};
+
+
+static const char* l1_ar[] = { "ar", NULL };
+static const char* l1_Ara[] = { "Arabic", NULL };
+static const char* l1_ca[] = { "ca", NULL };
+static const char* l1_cs[] = { "cs", NULL };
+static const char* l1_da[] = { "da", NULL };
+static const char* l1_Dan[] = { "Danish", NULL };
+static const char* l1_de[] = { "de", NULL };
+static const char* l1_Ger[] = { "German", NULL };
+static const char* l1_el[] = { "el", NULL };
+static const char* l1_en[] = { "en", NULL };
+static const char* l1_Eng[] = { "English", NULL };
+static const char* l2_en_001_[] = { "en_001", "en", NULL };
+static const char* l2_en_CA_[] = { "en_CA", "en", NULL };
+static const char* l2_en_GB_[] = { "en_GB", "en", NULL };
+static const char* l2_en_US_[] = { "en_US", "en", NULL };
+static const char* l2_en_GB_Eng[] = { "en_GB", "English", NULL };
+static const char* l3_en_GB001_[] = { "en_GB", "en_001", "en", NULL };
+static const char* l3_en_AUGB_[] = { "en_AU", "en_GB", "en", NULL };
+static const char* l3_en_INGB_[] = { "en_IN", "en_GB", "en", NULL };
+static const char* l4_en_150GB001_[] = { "en_150", "en_GB", "en_001", "en", NULL };
+static const char* l4_en_AUGB001_[] = { "en_AU", "en_GB", "en_001", "en", NULL };
+static const char* l1_es[] = { "es", NULL };
+static const char* l1_Spa[] = { "Spanish", NULL };
+static const char* l2_es_419_[] = { "es_419", "es", NULL };
+static const char* l2_es_ES_[] = { "es_ES", "es", NULL };
+static const char* l2_es_MX_[] = { "es_MX", "es", NULL };
+static const char* l2_es_MX_Spa[] = { "es_MX", "Spanish", NULL };
+static const char* l3_es_MX419_[] = { "es_MX", "es_419", "es", NULL };
+static const char* l1_fi[] = { "fi", NULL };
+static const char* l1_Fin[] = { "Finnish", NULL };
+static const char* l1_fil[] = { "fil", NULL };
+static const char* l1_tl[] = { "tl", NULL };
+static const char* l1_fr[] = { "fr", NULL };
+static const char* l1_Fre[] = { "French", NULL };
+static const char* l2_fr_CA_[] = { "fr_CA", "fr", NULL };
+static const char* l2_fr_CH_[] = { "fr_CH", "fr", NULL };
+static const char* l2_fr_FR_[] = { "fr_FR", "fr", NULL };
+static const char* l1_haw[] = { "haw", NULL };
+static const char* l1_he[] = { "he", NULL };
+static const char* l1_hr[] = { "hr", NULL };
+static const char* l1_hu[] = { "hu", NULL };
+static const char* l1_id[] = { "id", NULL };
+static const char* l1_in[] = { "in", NULL };
+static const char* l1_it[] = { "it", NULL };
+static const char* l1_Ita[] = { "Italian", NULL };
+static const char* l1_ja[] = { "ja", NULL };
+static const char* l1_Japn[] = { "Japanese", NULL };
+static const char* l1_ko[] = { "ko", NULL };
+static const char* l1_Kor[] = { "Korean", NULL };
+static const char* l1_ms[] = { "ms", NULL };
+static const char* l1_nb[] = { "nb", NULL };
+static const char* l1_no[] = { "no", NULL };
+static const char* l1_Nor[] = { "Norwegian", NULL };
+static const char* l2_no_NO_[] = { "no_NO", "no", NULL };
+static const char* l1_nl[] = { "nl", NULL };
+static const char* l1_Dut[] = { "Dutch", NULL };
+static const char* l2_nl_BE_[] = { "nl_BE", "nl", NULL };
+static const char* l1_pl[] = { "pl", NULL };
+static const char* l1_Pol[] = { "Polish", NULL };
+static const char* l1_pt[] = { "pt", NULL };
+static const char* l1_pt_PT[] = { "pt_PT", NULL };
+static const char* l1_Port[] = { "Portuguese", NULL };
+static const char* l2_pt_BR_[] = { "pt_BR", "pt", NULL };
+static const char* l2_pt_PT_[] = { "pt_PT", "pt", NULL };
+static const char* l1_ro[] = { "ro", NULL };
+static const char* l2_ro_MD_[] = { "ro_MD", "ro", NULL };
+static const char* l1_mo[] = { "mo", NULL };
+static const char* l1_ru[] = { "ru", NULL };
+static const char* l1_Rus[] = { "Russian", NULL };
+static const char* l1_sk[] = { "sk", NULL };
+static const char* l1_sr[] = { "sr", NULL };
+static const char* l1_srLatn[] = { "sr-Latn", NULL };
+static const char* l1_sv[] = { "sv", NULL };
+static const char* l1_Swe[] = { "Swedish", NULL };
+static const char* l1_th[] = { "th", NULL };
+static const char* l1_Thai[] = { "Thai", NULL };
+static const char* l1_tlh[] = { "tlh", NULL };
+static const char* l1_tr[] = { "tr", NULL };
+static const char* l1_Tur[] = { "Turkish", NULL };
+static const char* l1_uk[] = { "uk", NULL };
+static const char* l1_vi[] = { "vi", NULL };
+static const char* l1_yi[] = { "yi", NULL };
+static const char* l1_iw[] = { "iw", NULL };
+static const char* l1_zh_CN[] = { "zh_CN", NULL };
+static const char* l1_zh_TW[] = { "zh_TW", NULL };
+static const char* l1_zh_Hans[] = { "zh_Hans", NULL };
+static const char* l1_zh_Hant[] = { "zh_Hant", NULL };
+static const char* l1_zhHant[] = { "zh-Hant", NULL };
+static const char* l2_zh_HKTW[] = { "zh_HK", "zh_TW", NULL };
+static const char* l2_zh_Hant_HK_[] = { "zh_Hant_HK", "zh_Hant", NULL };
+static const char* l2_zh_CN_Hans[] = { "zh_CN", "zh_Hans", NULL };
+static const char* l2_zh_TW_Hant[] = { "zh_TW", "zh_Hant", NULL };
+static const char* l3_zh_MOHKTW[] = { "zh_MO", "zh_HK", "zh_TW", NULL };
+static const char* l3_zh_HK_HantHK_Hant[] = { "zh_HK", "zh_Hant_HK", "zh_Hant", NULL };
+
+static const LangAndExpLocs appleLangAndLoc[] = {
+// language\ result for appleLocs1 appleLocs2 appleLocs3 appleLocs4 appleLocs5 appleLocs6
+ { "zh", { l1_zh_CN, l1_zh_CN, l1_zh_CN, l1_zh_Hans, l1_zh_Hans, l1_zh_Hans } },
+ { "zh-Hans", { l1_zh_CN, l1_zh_CN, l1_zh_CN, l1_zh_Hans, l1_zh_Hans, l1_zh_Hans } },
+ { "zh-Hant", { l1_zh_TW, l1_zh_TW, l1_zh_TW, l1_zh_Hant, l1_zh_Hant, l1_zh_Hant } },
+ { "zh-Hans-CN", { l1_zh_CN, l1_zh_CN, l1_zh_CN, l1_zh_Hans, l2_zh_CN_Hans, l2_zh_CN_Hans } },
+ { "zh-Hans-SG", { l1_zh_CN, l1_zh_CN, l1_zh_CN, l1_zh_Hans, l1_zh_Hans, l1_zh_Hans } },
+ { "zh-Hant-TW", { l1_zh_TW, l1_zh_TW, l1_zh_TW, l1_zh_Hant, l2_zh_TW_Hant, l2_zh_TW_Hant } },
+ { "zh-Hant-HK", { l1_zh_TW, l2_zh_HKTW, l2_zh_HKTW, l2_zh_Hant_HK_, l1_zh_Hant, l2_zh_Hant_HK_ } },
+ { "zh-Hant-MO", { l1_zh_TW, l2_zh_HKTW, l3_zh_MOHKTW, l2_zh_Hant_HK_, l1_zh_Hant, l2_zh_Hant_HK_ } },
+ { "zh-Hans-HK", { l1_zh_CN, l1_zh_CN, l1_zh_CN, l1_zh_Hans, l1_zh_Hans, l1_zh_Hans } },
+ { "zh-CN", { l1_zh_CN, l1_zh_CN, l1_zh_CN, l1_zh_Hans, l2_zh_CN_Hans, l2_zh_CN_Hans } },
+ { "zh-SG", { l1_zh_CN, l1_zh_CN, l1_zh_CN, l1_zh_Hans, l1_zh_Hans, l1_zh_Hans } },
+ { "zh-TW", { l1_zh_TW, l1_zh_TW, l1_zh_TW, l1_zh_Hant, l2_zh_TW_Hant, l2_zh_TW_Hant } },
+ { "zh-HK", { l1_zh_TW, l2_zh_HKTW, l2_zh_HKTW, l2_zh_Hant_HK_, l1_zh_Hant, l3_zh_HK_HantHK_Hant } },
+ { "zh-MO", { l1_zh_TW, l2_zh_HKTW, l3_zh_MOHKTW, l2_zh_Hant_HK_, l1_zh_Hant, l2_zh_Hant_HK_ } },
+ { "en", { l1_Eng, l1_en, l1_en, l1_en, l1_en, l1_en } },
+ { "en-US", { l1_Eng, l1_en, l1_en, l2_en_US_, l1_en, l1_en } },
+ { "en_US", { l1_Eng, l1_en, l1_en, l2_en_US_, l1_en, l1_en } },
+ { "en-CN", { l1_Eng, l1_en, l1_en, l1_en, l1_en, l1_en } },
+ { "en-JP", { l1_Eng, l1_en, l1_en, l1_en, l1_en, l1_en } },
+ { "en-TW", { l1_Eng, l1_en, l1_en, l1_en, l1_en, l1_en } },
+ { "en-TR", { l1_Eng, l1_en, l1_en, l1_en, l1_en, l1_en } },
+ { "en-001", { l1_Eng, l1_en, l1_en, l1_en, l2_en_001_, l2_en_001_ } },
+ { "en-CA", { l1_Eng, l1_en, l2_en_CA_, l2_en_CA_, l2_en_001_, l2_en_001_ } },
+ { "en-IL", { l1_Eng, l1_en, l1_en, l1_en, l2_en_001_, l2_en_001_ } },
+ { "en-GB", { l1_Eng, l2_en_GB_, l2_en_GB_, l2_en_GB_, l3_en_GB001_, l3_en_GB001_ } },
+ { "en-IN", { l1_Eng, l2_en_GB_, l2_en_GB_, l3_en_INGB_, l3_en_GB001_, l3_en_GB001_ } },
+ { "en-BD", { l1_Eng, l2_en_GB_, l2_en_GB_, l2_en_GB_, l3_en_GB001_, l3_en_GB001_ } },
+ { "en-GG", { l1_Eng, l2_en_GB_, l2_en_GB_, l2_en_GB_, l3_en_GB001_, l3_en_GB001_ } },
+ { "en-HK", { l1_Eng, l2_en_GB_, l2_en_GB_, l2_en_GB_, l3_en_GB001_, l3_en_GB001_ } },
+ { "en-IE", { l1_Eng, l2_en_GB_, l2_en_GB_, l2_en_GB_, l3_en_GB001_, l3_en_GB001_ } },
+ { "en-JM", { l1_Eng, l2_en_GB_, l2_en_GB_, l2_en_GB_, l3_en_GB001_, l3_en_GB001_ } },
+ { "en-MO", { l1_Eng, l2_en_GB_, l2_en_GB_, l2_en_GB_, l3_en_GB001_, l3_en_GB001_ } },
+ { "en-MT", { l1_Eng, l2_en_GB_, l2_en_GB_, l2_en_GB_, l3_en_GB001_, l3_en_GB001_ } },
+ { "en-PK", { l1_Eng, l2_en_GB_, l2_en_GB_, l2_en_GB_, l3_en_GB001_, l3_en_GB001_ } },
+ { "en-SG", { l1_Eng, l2_en_GB_, l2_en_GB_, l2_en_GB_, l3_en_GB001_, l3_en_GB001_ } },
+ { "en-VG", { l1_Eng, l2_en_GB_, l2_en_GB_, l2_en_GB_, l3_en_GB001_, l3_en_GB001_ } },
+ { "en-ZA", { l1_Eng, l2_en_GB_, l2_en_GB_, l2_en_GB_, l3_en_GB001_, l3_en_GB001_ } },
+ { "en-AU", { l1_Eng, l3_en_AUGB_, l3_en_AUGB_, l3_en_AUGB_, l4_en_AUGB001_, l4_en_AUGB001_ } },
+ { "en-NZ", { l1_Eng, l3_en_AUGB_, l3_en_AUGB_, l3_en_AUGB_, l4_en_AUGB001_, l4_en_AUGB001_ } },
+ { "en-WS", { l1_Eng, l3_en_AUGB_, l3_en_AUGB_, l3_en_AUGB_, l4_en_AUGB001_, l4_en_AUGB001_ } },
+ { "en-150", { l1_Eng, l2_en_GB_, l2_en_GB_, l2_en_GB_, l3_en_GB001_, l4_en_150GB001_ } },
+ { "en-FR", { l1_Eng, l2_en_GB_, l2_en_GB_, l2_en_GB_, l3_en_GB001_, l4_en_150GB001_ } },
+ { "en-BE", { l1_Eng, l2_en_GB_, l2_en_GB_, l2_en_GB_, l3_en_GB001_, l4_en_150GB001_ } },
+ { "en-Latn", { l1_Eng, l1_en, l1_en, l1_en, l1_en, l1_en } },
+ { "en-Latn-US", { l1_Eng, l1_en, l1_en, l1_en,/*TODO*/ l1_en, l1_en } },
+ { "en-US-POSIX", { l1_Eng, l1_en, l1_en, l2_en_US_, l1_en, l1_en } },
+ { "en-Latn-US-POSIX", { l1_Eng, l1_en, l1_en, l1_en, l1_en, l1_en } },
+ { "en-u-ca-hebrew", { l1_Eng, l1_en, l1_en, l1_en, l1_en, l1_en } },
+ { "en@calendar=hebrew", { l1_Eng, l1_en, l1_en, l1_en, l1_en, l1_en } },
+ { "en-", { l1_Eng, l1_en, l1_en, l1_en, l1_en, l1_en } },
+ { "en_", { l1_Eng, l1_en, l1_en, l1_en, l1_en, l1_en } },
+ { "es", { l1_Spa, l1_es, l1_es, l1_es, l1_es, l1_es } },
+ { "es-ES", { l1_Spa, l1_es, l1_es, l1_es, l2_es_ES_, l2_es_ES_ } },
+ { "es-419", { l1_Spa, l1_es, l2_es_419_, l2_es_419_, l1_es, l2_es_419_ } },
+ { "es-MX", { l1_Spa, l2_es_MX_, l2_es_419_, l3_es_MX419_, l2_es_MX_, l3_es_MX419_ } },
+ { "es-AR", { l1_Spa, l1_es, l2_es_419_, l2_es_419_, l1_es, l2_es_419_ } },
+ { "es-BR", { l1_Spa, l1_es, l2_es_419_, l2_es_419_, l1_es, l2_es_419_ } },
+ { "es-BZ", { l1_Spa, l1_es, l2_es_419_, l2_es_419_, l1_es, l2_es_419_ } },
+ { "es-AG", { l1_Spa, l1_es, l2_es_419_, l2_es_419_, l1_es, l2_es_419_ } },
+ { "es-AW", { l1_Spa, l1_es, l2_es_419_, l2_es_419_, l1_es, l2_es_419_ } },
+ { "es-CA", { l1_Spa, l1_es, l2_es_419_, l2_es_419_, l1_es, l2_es_419_ } },
+ { "es-CW", { l1_Spa, l1_es, l2_es_419_, l2_es_419_, l1_es, l2_es_419_ } },
+ { "es-SX", { l1_Spa, l1_es, l2_es_419_, l2_es_419_, l1_es, l2_es_419_ } },
+ { "es-TT", { l1_Spa, l1_es, l2_es_419_, l2_es_419_, l1_es, l2_es_419_ } },
+ { "es-Latn", { l1_Spa, l1_es, l1_es, l1_es, l1_es, l1_es } },
+ { "es-Latn-MX", { l1_Spa, l1_es, l1_es, l1_es, l1_es, l1_es } },
+ { "pt", { l1_Port, l1_pt, l1_pt, l1_pt, NULL, NULL } },
+ { "pt-BR", { l1_Port, l1_pt, l2_pt_BR_, l2_pt_BR_, NULL, NULL } },
+ { "pt-PT", { l1_Port, l2_pt_PT_, l2_pt_PT_, l1_pt, NULL, NULL } },
+ { "pt-MO", { l1_Port, l2_pt_PT_, l2_pt_PT_, l1_pt, NULL, NULL } },
+ { "pt-CH", { l1_Port, l2_pt_PT_, l2_pt_PT_, l1_pt, NULL, NULL } },
+ { "pt-FR", { l1_Port, l2_pt_PT_, l2_pt_PT_, l1_pt, NULL, NULL } },
+ { "pt-GQ", { l1_Port, l2_pt_PT_, l2_pt_PT_, l1_pt, NULL, NULL } },
+ { "pt-LU", { l1_Port, l2_pt_PT_, l2_pt_PT_, l1_pt, NULL, NULL } },
+ { "fr", { l1_Fre, l1_fr, l1_fr, l1_fr, NULL, NULL } },
+ { "fr-FR", { l1_Fre, l1_fr, l2_fr_FR_, l2_fr_FR_, NULL, NULL } },
+ { "fr-CA", { l1_Fre, l2_fr_CA_, l2_fr_CA_, l2_fr_CA_, NULL, NULL } },
+ { "fr-CH", { l1_Fre, l1_fr, l1_fr, l2_fr_CH_, NULL, NULL } },
+ { "ar", { l1_Ara, l1_ar, l1_ar, NULL, NULL, NULL } },
+ { "da", { l1_Dan, l1_da, l1_da, NULL, NULL, NULL } },
+ { "nl", { l1_Dut, l1_nl, l1_nl, l1_nl, NULL, NULL } },
+ { "nl-BE", { l1_Dut, l1_nl, l1_nl, l2_nl_BE_, NULL, NULL } },
+ { "fi", { l1_Fin, l1_fi, l1_fi, NULL, NULL, NULL } },
+ { "de", { l1_Ger, l1_de, l1_de, NULL, NULL, NULL } },
+ { "it", { l1_Ita, l1_it, l1_it, NULL, NULL, NULL } },
+ { "ja", { l1_Japn, l1_ja, l1_ja, NULL, NULL, NULL } },
+ { "ko", { l1_Kor, l1_ko, l1_ko, NULL, NULL, NULL } },
+ { "nb", { l1_Nor, l1_no, l1_nb, NULL, NULL, NULL } },
+ { "no", { l1_Nor, l1_no, l1_nb, NULL, NULL, NULL } },
+ { "pl", { l1_Pol, l1_pl, l1_pl, NULL, NULL, NULL } },
+ { "ru", { l1_Rus, l1_ru, l1_ru, NULL, NULL, NULL } },
+ { "sv", { l1_Swe, l1_sv, l1_sv, NULL, NULL, NULL } },
+ { "th", { l1_Thai, l1_th, l1_th, NULL, NULL, NULL } },
+ { "tr", { l1_Tur, l1_tr, l1_tr, NULL, NULL, NULL } },
+ { "ca", { l1_ca, l1_ca, l1_ca, NULL, NULL, NULL } },
+ { "cs", { l1_cs, l1_cs, l1_cs, NULL, NULL, NULL } },
+ { "el", { l1_el, l1_el, l1_el, NULL, NULL, NULL } },
+ { "he", { l1_he, l1_he, l1_he, NULL, NULL, l1_iw } },
+ { "iw", { l1_he, l1_he, l1_he, NULL, NULL, l1_iw } },
+ { "hr", { l1_hr, l1_hr, l1_hr, NULL, NULL, NULL } },
+ { "hu", { l1_hu, l1_hu, l1_hu, NULL, NULL, NULL } },
+ { "id", { l1_id, l1_id, l1_id, NULL, NULL, l1_in } },
+ { "in", { l1_id, l1_id, l1_id, NULL, NULL, l1_in } },
+ { "ms", { l1_ms, l1_ms, l1_ms, NULL, NULL, NULL } },
+ { "ro", { l1_ro, l1_ro, l1_ro, l1_ro, NULL, l1_mo } },
+ { "mo", { l1_ro, l1_ro, l1_ro, l2_ro_MD_, NULL, l1_mo } },
+ { "sk", { l1_sk, l1_sk, l1_sk, NULL, NULL, NULL } },
+ { "uk", { l1_uk, l1_uk, l1_uk, NULL, NULL, NULL } },
+ { "vi", { l1_vi, l1_vi, l1_vi, NULL, NULL, NULL } },
+ { "yi", { NULL, NULL, NULL, NULL, l1_yi, NULL } },
+ { "ji", { NULL, NULL, NULL, NULL, l1_yi, NULL } },
+ { "fil", { NULL, NULL, NULL, NULL, l1_fil, l1_tl } },
+ { "tl", { NULL, NULL, NULL, NULL, l1_fil, l1_tl } },
+ { "haw", { NULL, NULL, NULL, NULL, l1_haw, NULL } },
+ { "sr", { NULL, NULL, NULL, NULL, l1_sr, NULL } },
+ { "sr-Cyrl", { NULL, NULL, NULL, NULL, l1_sr, NULL } },
+ { "sr-Latn", { NULL, NULL, NULL, NULL, l1_srLatn, NULL } },
+ { "tlh", { NULL, NULL, NULL, NULL, l1_tlh, NULL } },
+ { "Default@2x", { NULL, NULL, NULL, NULL, NULL, NULL } },
+ { "default", { NULL, NULL, NULL, NULL, NULL, NULL } },
+ { "root", { NULL, NULL, NULL, NULL, NULL, NULL } },
+ { "", { NULL, NULL, NULL, NULL, NULL, NULL } },
+ { "_US", { NULL, NULL, NULL, NULL, NULL, NULL } },
+ { "-US", { NULL, NULL, NULL, NULL, NULL, NULL } },
+ { "-u-ca-hebrew", { NULL, NULL, NULL, NULL, NULL, NULL } },
+ { "-u-ca-hebrew", { NULL, NULL, NULL, NULL, NULL, NULL } },
+ { "@calendar=hebrew", { NULL, NULL, NULL, NULL, NULL, NULL } },
+};
+enum { kNumAppleLangAndLoc = UPRV_LENGTHOF(appleLangAndLoc) };
+
+/* tests from <rdar://problem/21518031> */
+
+static const char * appleLocsA1[] = { "en", "fr", "no", "zh-Hant" };
+static const char * appleLocsA2[] = { "en", "fr", "nb", "zh_TW", "zh_CN", "zh-Hant" };
+static const char * appleLocsA3[] = { "en", "en_IN", "en_GB", "fr", "de", "zh_TW" };
+static const char * appleLocsA4[] = { "Spanish", "es_MX", "English", "en_GB" };
+static const char * appleLocsA5[] = { "en", "fr", "de", "pt", "pt_PT" };
+static const char * appleLocsA6[] = { "en", "no", "no_NO", "pt_PT" };
+
+static const AppleLocsAndCount locAndCountEntriesA[kNumLocSets] = {
+ { appleLocsA1, UPRV_LENGTHOF(appleLocsA1) },
+ { appleLocsA2, UPRV_LENGTHOF(appleLocsA2) },
+ { appleLocsA3, UPRV_LENGTHOF(appleLocsA3) },
+ { appleLocsA4, UPRV_LENGTHOF(appleLocsA4) },
+ { appleLocsA5, UPRV_LENGTHOF(appleLocsA5) },
+ { appleLocsA6, UPRV_LENGTHOF(appleLocsA6) },
+};
+
+static const LangAndExpLocs appleLangAndLocA[] = {
+// language\ result for appleLocsA1 appleLocsA2 appleLocsA3 appleLocsA4 appleLocsA5 appleLocsA6
+ { "zh-Hant", { l1_zhHant,/*0*/ l1_zhHant,/*zh_TW*/ l1_zh_TW, NULL, NULL, NULL } },
+ { "zh_Hant", { l1_zhHant, l1_zhHant,/*zh_TW*/ l1_zh_TW, NULL, NULL, NULL } },
+ { "zh_HK", { l1_zhHant, l1_zhHant,/*zh_TW*/ l1_zh_TW, NULL, NULL, NULL } },
+ { "en_IN", { l1_en, l1_en, l3_en_INGB_, l2_en_GB_Eng, l1_en, l1_en } },
+ { "es_MX", { NULL, NULL, NULL, l2_es_MX_Spa, NULL, NULL } },
+ { "pt_PT", { NULL, NULL, NULL, NULL, l2_pt_PT_, l1_pt_PT } },
+ { "pt", { NULL, NULL, NULL, NULL, l1_pt, l1_pt_PT } },
+ { "no", { l1_no, l1_nb, NULL, NULL, NULL, l1_no } },
+ { "no_NO", { l1_no, l1_nb, NULL, NULL, NULL, l2_no_NO_ } },
+ { "nb", { l1_no, l1_nb, NULL, NULL, NULL, l1_no } },
+ { "nb_NO", { l1_no, l1_nb, NULL, NULL, NULL, l2_no_NO_ } },
+};
+enum { kNumAppleLangAndLocA = UPRV_LENGTHOF(appleLangAndLocA) };
+
+/* tests from log attached to 21682790 */
+
+static const char * appleLocsB1[] = {
+ "ar", "Base", "ca", "cs",
+ "da", "Dutch", "el", "English",
+ "es_MX", "fi", "French", "German",
+ "he", "hr", "hu", "id",
+ "Italian", "Japanese", "ko", "ms",
+ "no", "pl", "pt", "pt_PT",
+ "ro", "ru", "sk", "Spanish",
+ "sv", "th", "tr", "uk",
+ "vi", "zh_CN", "zh_TW"
+};
+
+static const char * appleLocsB2[] = {
+ "ar", "ca", "cs",
+ "da", "Dutch", "el", "English",
+ "es_MX", "fi", "French", "German",
+ "he", "hr", "hu", "id",
+ "Italian", "Japanese", "ko", "ms",
+ "no", "pl", "pt", "pt_PT",
+ "ro", "ru", "sk", "Spanish",
+ "sv", "th", "tr", "uk",
+ "vi", "zh_CN", "zh_TW"
+};
+
+static const char * appleLocsB3[] = {
+ "ar", "ca", "cs", "da",
+ "de", "el", "en", "es",
+ "es_MX", "fi", "French", "he",
+ "hr", "hu", "id", "Italian",
+ "ja", "ko", "ms", "nl",
+ "no", "pl", "pt", "pt_PT",
+ "ro", "ru", "sk", "sv",
+ "th", "tr", "uk", "vi",
+ "zh_CN", "zh_TW"
+};
+
+static const char * appleLocsB4[] = {
+ "ar", "ca", "cs", "da",
+ "de", "el", "en", "es",
+ "es_MX", "fi", "fr", "he",
+ "hr", "hu", "id", "it",
+ "ja", "ko", "ms", "nl",
+ "no", "pl", "pt", "pt_PT",
+ "ro", "ru", "sk", "sv",
+ "th", "tr", "uk", "vi",
+ "zh_CN", "zh_TW"
+};
+
+static const char * appleLocsB5[] = { "en" };
+
+static const char * appleLocsB6[] = { "English" };
+
+static const AppleLocsAndCount locAndCountEntriesB[kNumLocSets] = {
+ { appleLocsB1, UPRV_LENGTHOF(appleLocsB1) },
+ { appleLocsB2, UPRV_LENGTHOF(appleLocsB2) },
+ { appleLocsB3, UPRV_LENGTHOF(appleLocsB3) },
+ { appleLocsB4, UPRV_LENGTHOF(appleLocsB4) },
+ { appleLocsB5, UPRV_LENGTHOF(appleLocsB5) },
+ { appleLocsB6, UPRV_LENGTHOF(appleLocsB6) },
+};
+
+static const LangAndExpLocs appleLangAndLocB[] = {
+// language\ result for appleLocsB1 appleLocsB2 appleLocsB3 appleLocsB4 appleLocsB5 appleLocsB6
+// Prefs 1, logged with sets B1-B3
+ { "en", { l1_Eng, l1_Eng, l1_en, l1_en, l1_en, l1_Eng } },
+ { "es", { l1_Spa, l1_Spa, l1_es, l1_es, NULL, NULL } },
+// Prefs 2, logged with sets B1-B6
+ { "English", { l1_Eng, l1_Eng, l1_en, l1_en, l1_en, l1_Eng } },
+ { "Spanish", { l1_Spa, l1_Spa, l1_es, l1_es, NULL, NULL } },
+};
+enum { kNumAppleLangAndLocB = UPRV_LENGTHOF(appleLangAndLocB) };
+
+typedef struct {
+ const AppleLocsAndCount * locAndCountEntriesPtr;
+ const LangAndExpLocs * appleLangAndLocPtr;
+ int32_t appleLangAndLocCount;
+} AppleLocToUseTestSet;
+
+static const AppleLocToUseTestSet altuTestSets[] = {
+ { locAndCountEntries, appleLangAndLoc, kNumAppleLangAndLoc },
+ { locAndCountEntriesA, appleLangAndLocA, kNumAppleLangAndLocA },
+ { locAndCountEntriesB, appleLangAndLocB, kNumAppleLangAndLocB },
+ { NULL, NULL, 0 }
+};
+
+/* tests for multiple prefs sets */
+
+static const char * appleLocsM1[] = { "en", "en_GB", "pt", "pt_PT", "zh_CN", "zh_Hant" };
+static const char * prefLangsM1[] = { "tlh", "zh_HK", "zh_SG", "zh_Hans", "pt_BR", "pt_PT", "en_IN", "en" };
+static const char * locsToUseM1[] = { "zh_Hant" };
+
+// Tests from first pass at <rdar://problem/22012864>, 2015-11-18
+
+static const char * appleLocsM2[] = { "fr-FR", "en-US", "en-GB" };
+static const char * prefLangsM2[] = { "fr-CH" };
+static const char * locsToUseM2[] = { "fr-FR" };
+
+static const char * appleLocsM3[] = { "es-es", "fr-fr" };
+static const char * prefLangsM3[] = { "fr-US", "fr", "en-US" };
+static const char * locsToUseM3[] = { "fr-fr" };
+
+static const char * appleLocsM4[] = { "es-es", "fr-fr", "fr" };
+static const char * prefLangsM4[] = { "fr-US", "fr", "en-US" };
+static const char * locsToUseM4[] = { "fr" };
+
+// Tests from second pass at <rdar://problem/22012864>, 2015-12-08
+// Per Karan M
+static const char * appleLocsM5[] = { "en-US", "fr-FR", "de-DE", "es-ES", "es-419", "pt-PT", "pt-BR", "zh-CN", "zh-TW", "zh-HK", "ja-JP", "ko-KR" };
+static const char * prefLangsM5[] = { "fr-US", "en-US" };
+static const char * locsToUseM5[] = { "fr-FR" };
+// Per Peter E; expected result changed from "en-US" to "de-CH" per <rdar://problem/26559053>
+static const char * appleLocsM6[] = { "de-CH", "en-US" };
+static const char * prefLangsM6[] = { "de-DE", "en-US" };
+static const char * locsToUseM6[] = { "de-CH" };
+// The following is used for M7-MD
+static const char * appleLocsMx[] = { "de-DE", "en-AU", "es-ES", "fr-FR", "hi-IN", "pt-BR", "zh-HK", "zh-TW" };
+// Per Karan M
+static const char * prefLangsM7[] = { "fr-ES", "en-AU" };
+static const char * locsToUseM7[] = { "fr-FR" };
+// Per Karan M
+static const char * prefLangsM8[] = { "de-IT", "en-AU" };
+static const char * locsToUseM8[] = { "de-DE" };
+// Per Karan M
+static const char * prefLangsM9[] = { "hi-US", "en-AU" };
+static const char * locsToUseM9[] = { "hi-IN" };
+// Per Karan M
+static const char * prefLangsMA[] = { "en-IN", "zh-HK" };
+static const char * locsToUseMA[] = { "en-AU" };
+// Per Karan M
+static const char * prefLangsMB[] = { "pt-PT", "en-AU" };
+static const char * locsToUseMB[] = { "en-AU" };
+// per Paul B:
+static const char * prefLangsMC[] = { "pt-PT", "ar" };
+static const char * locsToUseMC[] = { "pt-BR" };
+// Per Karan M
+static const char * prefLangsMD[] = { "zh-CN", "en-AU" };
+static const char * locsToUseMD[] = { "en-AU" };
+// Per Karan M
+static const char * appleLocsME[] = { "de-DE", "en-AU", "es-ES", "fr-FR", "hi-IN", "pt-BR", "zh-CN", "zh-HK" };
+static const char * prefLangsME[] = { "zh-TW", "en-AU" };
+static const char * locsToUseME[] = { "zh-HK" };
+// Per Peter E in diagnosis for <rdar://problem/22012864> and <rdar://problem/23815194>
+static const char * appleLocsMF[] = { "en", "en-GB", "fr", "es" };
+static const char * prefLangsMF[] = { "en-IN", "en-GB", "de", "fr" };
+static const char * locsToUseMF[] = { "en-GB", "en" };
+// Per Karan M in <rdar://problem/23982460>
+static const char * appleLocsMG[] = { "zh-Hans", "zh-Hant", "zh-HK" };
+static const char * prefLangsMG[] = { "zh-Hans-US", "zh-HK", "en-US" };
+static const char * locsToUseMG[] = { "zh-Hans" };
+// Per <rdar://problem/25903891>
+static const char * appleLocsMH[] = { "zh-TW", "zh-CN", "zh-HK" };
+static const char * prefLangsMH[] = { "zh-Hans-HK", "zh-HK", "en" };
+static const char * locsToUseMH[] = { "zh-CN" };
+// Per <rdar://problem/26559053>
+static const char * appleLocsMI[] = { "unk", "en-US", "ar-SA" };
+static const char * prefLangsMI[] = { "ar-US" };
+static const char * locsToUseMI[] = { "ar-SA" };
+// Per <rdar://problem/30501523> - first for comparison with zh, then real test
+static const char * appleLocsMJ[] = { "zh-CN", "en-US" };
+static const char * prefLangsMJ[] = { "zh", "zh_AC" };
+static const char * locsToUseMJ[] = { "zh-CN" };
+static const char * appleLocsMK[] = { "yue-CN", "en-US" };
+static const char * prefLangsMK[] = { "yue", "yue_AC" };
+static const char * locsToUseMK[] = { "yue-CN" };
+// Per <rdar://problem/30433534>
+static const char * appleLocsML[] = { "nl_NL", "es_MX", "fr_FR", "zh_TW", "it_IT", "vi_VN", "fr_CH", "es_CL",
+ "en_ZA", "ko_KR", "ca_ES", "ro_RO", "en_PH", "en_CA", "en_SG", "en_IN",
+ "en_NZ", "it_CH", "fr_CA", "da_DK", "de_AT", "pt_BR", "yue_CN", "zh_CN",
+ "sv_SE", "es_ES", "ar_SA", "hu_HU", "fr_BE", "en_GB", "ja_JP", "zh_HK",
+ "fi_FI", "tr_TR", "nb_NO", "en_ID", "en_SA", "pl_PL", "ms_MY", "cs_CZ",
+ "el_GR", "id_ID", "hr_HR", "en_AE", "he_IL", "ru_RU", "wuu_CN", "de_DE",
+ "de_CH", "en_AU", "nl_BE", "th_TH", "pt_PT", "sk_SK", "en_US", "en_IE",
+ "es_CO", "uk_UA", "es_US" };
+static const char * prefLangsML[] = { "en-JP" };
+static const char * locsToUseML[] = { "en_US" };
+// Per <rdar://problem/32421203>
+static const char * appleLocsMM1[] = { "pt-PT" };
+static const char * appleLocsMM2[] = { "pt-BR" };
+static const char * appleLocsMM3[] = { "pt-PT", "pt-BR" };
+static const char * appleLocsMM4[] = { "en", "pt-PT" };
+static const char * appleLocsMM5[] = { "en", "pt-BR" };
+static const char * appleLocsMM6[] = { "en", "pt-PT", "pt-BR" };
+static const char * prefLangsMM1[] = { "pt-PT" };
+static const char * prefLangsMM2[] = { "pt-BR" };
+static const char * prefLangsMM3[] = { "pt" };
+static const char * prefLangsMM4[] = { "pt-PT", "en" };
+static const char * prefLangsMM5[] = { "pt-BR", "en" };
+static const char * prefLangsMM6[] = { "pt", "en" };
+static const char * locsToUseMMptPT[] = { "pt-PT" };
+static const char * locsToUseMMptBR[] = { "pt-BR" };
+static const char * locsToUseMMen[] = { "en" };
+// Per <rdar://problem/32658828>
+static const char * appleLocsMN[] = { "en-US", "en-GB" };
+static const char * prefLangsMN1[] = { "en-KR" };
+static const char * prefLangsMN2[] = { "en-SA" };
+static const char * prefLangsMN3[] = { "en-TW" };
+static const char * prefLangsMN4[] = { "en-JP" };
+static const char * locsToUseMN_U[] = { "en-US" };
+// Per <rdar://problem/36010857>
+static const char * appleLocsMO[] = { "Dutch", "French", "German", "Italian", "Japanese", "Spanish",
+ "ar", "ca", "cs", "da", "el", "en_AU", "en_GB", "en_IN",
+ "es_419", "fi", "fr_CA", "he", "hi", "hr", "hu", "id", "ko",
+ "ms", "no", "pl", "pt", "pt_PT", "ro", "ru", "sk", "sv",
+ "th", "tr", "uk", "vi", "zh_CN", "zh_HK", "zh_TW" };
+static const char * prefLangsMO1[] = { "en-US" };
+static const char * locsToUseMO1[] = { "en_GB" };
+
+typedef struct {
+ const char * name;
+ const char ** availLocs;
+ int32_t availLocsCount;
+ const char ** prefLangs;
+ int32_t prefLangsCount;
+ const char ** locsToUse;
+ int32_t locsToUseCount;
+} MultiPrefTest;
+
+static const MultiPrefTest multiTestSets[] = {
+ { "M1", appleLocsM1, UPRV_LENGTHOF(appleLocsM1), prefLangsM1, UPRV_LENGTHOF(prefLangsM1), locsToUseM1, UPRV_LENGTHOF(locsToUseM1) },
+ //
+ { "M2", appleLocsM2, UPRV_LENGTHOF(appleLocsM2), prefLangsM2, UPRV_LENGTHOF(prefLangsM2), locsToUseM2, UPRV_LENGTHOF(locsToUseM2) },
+ { "M3", appleLocsM3, UPRV_LENGTHOF(appleLocsM3), prefLangsM3, UPRV_LENGTHOF(prefLangsM3), locsToUseM3, UPRV_LENGTHOF(locsToUseM3) },
+ { "M4", appleLocsM4, UPRV_LENGTHOF(appleLocsM4), prefLangsM4, UPRV_LENGTHOF(prefLangsM4), locsToUseM4, UPRV_LENGTHOF(locsToUseM4) },
+ //
+ { "M5", appleLocsM5, UPRV_LENGTHOF(appleLocsM5), prefLangsM5, UPRV_LENGTHOF(prefLangsM5), locsToUseM5, UPRV_LENGTHOF(locsToUseM5) },
+ { "M6", appleLocsM6, UPRV_LENGTHOF(appleLocsM6), prefLangsM6, UPRV_LENGTHOF(prefLangsM6), locsToUseM6, UPRV_LENGTHOF(locsToUseM6) },
+ { "M7", appleLocsMx, UPRV_LENGTHOF(appleLocsMx), prefLangsM7, UPRV_LENGTHOF(prefLangsM7), locsToUseM7, UPRV_LENGTHOF(locsToUseM7) },
+ { "M8", appleLocsMx, UPRV_LENGTHOF(appleLocsMx), prefLangsM8, UPRV_LENGTHOF(prefLangsM8), locsToUseM8, UPRV_LENGTHOF(locsToUseM8) },
+ { "M9", appleLocsMx, UPRV_LENGTHOF(appleLocsMx), prefLangsM9, UPRV_LENGTHOF(prefLangsM9), locsToUseM9, UPRV_LENGTHOF(locsToUseM9) },
+ { "MA", appleLocsMx, UPRV_LENGTHOF(appleLocsMx), prefLangsMA, UPRV_LENGTHOF(prefLangsMA), locsToUseMA, UPRV_LENGTHOF(locsToUseMA) },
+ { "MB", appleLocsMx, UPRV_LENGTHOF(appleLocsMx), prefLangsMB, UPRV_LENGTHOF(prefLangsMB), locsToUseMB, UPRV_LENGTHOF(locsToUseMB) },
+ { "MC", appleLocsMx, UPRV_LENGTHOF(appleLocsMx), prefLangsMC, UPRV_LENGTHOF(prefLangsMC), locsToUseMC, UPRV_LENGTHOF(locsToUseMC) },
+ { "MD", appleLocsMx, UPRV_LENGTHOF(appleLocsMx), prefLangsMD, UPRV_LENGTHOF(prefLangsMD), locsToUseMD, UPRV_LENGTHOF(locsToUseMD) },
+ { "ME", appleLocsME, UPRV_LENGTHOF(appleLocsME), prefLangsME, UPRV_LENGTHOF(prefLangsME), locsToUseME, UPRV_LENGTHOF(locsToUseME) },
+ { "MF", appleLocsMF, UPRV_LENGTHOF(appleLocsMF), prefLangsMF, UPRV_LENGTHOF(prefLangsMF), locsToUseMF, UPRV_LENGTHOF(locsToUseMF) },
+ { "MG", appleLocsMG, UPRV_LENGTHOF(appleLocsMG), prefLangsMG, UPRV_LENGTHOF(prefLangsMG), locsToUseMG, UPRV_LENGTHOF(locsToUseMG) },
+ { "MH", appleLocsMH, UPRV_LENGTHOF(appleLocsMH), prefLangsMH, UPRV_LENGTHOF(prefLangsMH), locsToUseMH, UPRV_LENGTHOF(locsToUseMH) },
+ { "MI", appleLocsMI, UPRV_LENGTHOF(appleLocsMI), prefLangsMI, UPRV_LENGTHOF(prefLangsMI), locsToUseMI, UPRV_LENGTHOF(locsToUseMI) },
+ { "MJ", appleLocsMJ, UPRV_LENGTHOF(appleLocsMJ), prefLangsMJ, UPRV_LENGTHOF(prefLangsMJ), locsToUseMJ, UPRV_LENGTHOF(locsToUseMJ) },
+ { "MK", appleLocsMK, UPRV_LENGTHOF(appleLocsMK), prefLangsMK, UPRV_LENGTHOF(prefLangsMK), locsToUseMK, UPRV_LENGTHOF(locsToUseMK) },
+ { "ML", appleLocsML, UPRV_LENGTHOF(appleLocsML), prefLangsML, UPRV_LENGTHOF(prefLangsML), locsToUseML, UPRV_LENGTHOF(locsToUseML) },
+ { "MM11", appleLocsMM1, UPRV_LENGTHOF(appleLocsMM1), prefLangsMM1, UPRV_LENGTHOF(prefLangsMM1), locsToUseMMptPT, UPRV_LENGTHOF(locsToUseMMptPT) },
+ { "MM21", appleLocsMM2, UPRV_LENGTHOF(appleLocsMM2), prefLangsMM1, UPRV_LENGTHOF(prefLangsMM1), locsToUseMMptBR, UPRV_LENGTHOF(locsToUseMMptBR) },
+ { "MM31", appleLocsMM3, UPRV_LENGTHOF(appleLocsMM3), prefLangsMM1, UPRV_LENGTHOF(prefLangsMM1), locsToUseMMptPT, UPRV_LENGTHOF(locsToUseMMptPT) },
+ { "MM41", appleLocsMM4, UPRV_LENGTHOF(appleLocsMM4), prefLangsMM1, UPRV_LENGTHOF(prefLangsMM1), locsToUseMMptPT, UPRV_LENGTHOF(locsToUseMMptPT) },
+ { "MM51", appleLocsMM5, UPRV_LENGTHOF(appleLocsMM5), prefLangsMM1, UPRV_LENGTHOF(prefLangsMM1), locsToUseMMptBR, UPRV_LENGTHOF(locsToUseMMptBR) },
+ { "MM61", appleLocsMM6, UPRV_LENGTHOF(appleLocsMM6), prefLangsMM1, UPRV_LENGTHOF(prefLangsMM1), locsToUseMMptPT, UPRV_LENGTHOF(locsToUseMMptPT) },
+ { "MM12", appleLocsMM1, UPRV_LENGTHOF(appleLocsMM1), prefLangsMM2, UPRV_LENGTHOF(prefLangsMM2), locsToUseMMptPT, UPRV_LENGTHOF(locsToUseMMptPT) },
+ { "MM22", appleLocsMM2, UPRV_LENGTHOF(appleLocsMM2), prefLangsMM2, UPRV_LENGTHOF(prefLangsMM2), locsToUseMMptBR, UPRV_LENGTHOF(locsToUseMMptBR) },
+ { "MM32", appleLocsMM3, UPRV_LENGTHOF(appleLocsMM3), prefLangsMM2, UPRV_LENGTHOF(prefLangsMM2), locsToUseMMptBR, UPRV_LENGTHOF(locsToUseMMptBR) },
+ { "MM42", appleLocsMM4, UPRV_LENGTHOF(appleLocsMM4), prefLangsMM2, UPRV_LENGTHOF(prefLangsMM2), locsToUseMMptPT, UPRV_LENGTHOF(locsToUseMMptPT) },
+ { "MM52", appleLocsMM5, UPRV_LENGTHOF(appleLocsMM5), prefLangsMM2, UPRV_LENGTHOF(prefLangsMM2), locsToUseMMptBR, UPRV_LENGTHOF(locsToUseMMptBR) },
+ { "MM62", appleLocsMM6, UPRV_LENGTHOF(appleLocsMM6), prefLangsMM2, UPRV_LENGTHOF(prefLangsMM2), locsToUseMMptBR, UPRV_LENGTHOF(locsToUseMMptBR) },
+ { "MM13", appleLocsMM1, UPRV_LENGTHOF(appleLocsMM1), prefLangsMM3, UPRV_LENGTHOF(prefLangsMM3), locsToUseMMptPT, UPRV_LENGTHOF(locsToUseMMptPT) },
+ { "MM23", appleLocsMM2, UPRV_LENGTHOF(appleLocsMM2), prefLangsMM3, UPRV_LENGTHOF(prefLangsMM3), locsToUseMMptBR, UPRV_LENGTHOF(locsToUseMMptBR) },
+ { "MM33", appleLocsMM3, UPRV_LENGTHOF(appleLocsMM3), prefLangsMM3, UPRV_LENGTHOF(prefLangsMM3), locsToUseMMptBR, UPRV_LENGTHOF(locsToUseMMptBR) },
+ { "MM43", appleLocsMM4, UPRV_LENGTHOF(appleLocsMM4), prefLangsMM3, UPRV_LENGTHOF(prefLangsMM3), locsToUseMMptPT, UPRV_LENGTHOF(locsToUseMMptPT) },
+ { "MM53", appleLocsMM5, UPRV_LENGTHOF(appleLocsMM5), prefLangsMM3, UPRV_LENGTHOF(prefLangsMM3), locsToUseMMptBR, UPRV_LENGTHOF(locsToUseMMptBR) },
+ { "MM63", appleLocsMM6, UPRV_LENGTHOF(appleLocsMM6), prefLangsMM3, UPRV_LENGTHOF(prefLangsMM3), locsToUseMMptBR, UPRV_LENGTHOF(locsToUseMMptBR) },
+ { "MM14", appleLocsMM1, UPRV_LENGTHOF(appleLocsMM1), prefLangsMM4, UPRV_LENGTHOF(prefLangsMM4), locsToUseMMptPT, UPRV_LENGTHOF(locsToUseMMptPT) },
+ { "MM24", appleLocsMM2, UPRV_LENGTHOF(appleLocsMM2), prefLangsMM4, UPRV_LENGTHOF(prefLangsMM4), locsToUseMMptBR, UPRV_LENGTHOF(locsToUseMMptBR) },
+ { "MM34", appleLocsMM3, UPRV_LENGTHOF(appleLocsMM3), prefLangsMM4, UPRV_LENGTHOF(prefLangsMM4), locsToUseMMptPT, UPRV_LENGTHOF(locsToUseMMptPT) },
+ { "MM44", appleLocsMM4, UPRV_LENGTHOF(appleLocsMM4), prefLangsMM4, UPRV_LENGTHOF(prefLangsMM4), locsToUseMMptPT, UPRV_LENGTHOF(locsToUseMMptPT) },
+ { "MM54", appleLocsMM5, UPRV_LENGTHOF(appleLocsMM5), prefLangsMM4, UPRV_LENGTHOF(prefLangsMM4), locsToUseMMen, UPRV_LENGTHOF(locsToUseMMen) }, // want en, see <rdar://problem/22012864>
+ { "MM64", appleLocsMM6, UPRV_LENGTHOF(appleLocsMM6), prefLangsMM4, UPRV_LENGTHOF(prefLangsMM4), locsToUseMMptPT, UPRV_LENGTHOF(locsToUseMMptPT) },
+ { "MM15", appleLocsMM1, UPRV_LENGTHOF(appleLocsMM1), prefLangsMM5, UPRV_LENGTHOF(prefLangsMM5), locsToUseMMptPT, UPRV_LENGTHOF(locsToUseMMptPT) },
+ { "MM25", appleLocsMM2, UPRV_LENGTHOF(appleLocsMM2), prefLangsMM5, UPRV_LENGTHOF(prefLangsMM5), locsToUseMMptBR, UPRV_LENGTHOF(locsToUseMMptBR) },
+ { "MM35", appleLocsMM3, UPRV_LENGTHOF(appleLocsMM3), prefLangsMM5, UPRV_LENGTHOF(prefLangsMM5), locsToUseMMptBR, UPRV_LENGTHOF(locsToUseMMptBR) },
+ { "MM45", appleLocsMM4, UPRV_LENGTHOF(appleLocsMM4), prefLangsMM5, UPRV_LENGTHOF(prefLangsMM5), locsToUseMMptPT, UPRV_LENGTHOF(locsToUseMMptPT) },
+ { "MM55", appleLocsMM5, UPRV_LENGTHOF(appleLocsMM5), prefLangsMM5, UPRV_LENGTHOF(prefLangsMM5), locsToUseMMptBR, UPRV_LENGTHOF(locsToUseMMptBR) },
+ { "MM65", appleLocsMM6, UPRV_LENGTHOF(appleLocsMM6), prefLangsMM5, UPRV_LENGTHOF(prefLangsMM5), locsToUseMMptBR, UPRV_LENGTHOF(locsToUseMMptBR) },
+ { "MM16", appleLocsMM1, UPRV_LENGTHOF(appleLocsMM1), prefLangsMM6, UPRV_LENGTHOF(prefLangsMM6), locsToUseMMptPT, UPRV_LENGTHOF(locsToUseMMptPT) },
+ { "MM26", appleLocsMM2, UPRV_LENGTHOF(appleLocsMM2), prefLangsMM6, UPRV_LENGTHOF(prefLangsMM6), locsToUseMMptBR, UPRV_LENGTHOF(locsToUseMMptBR) },
+ { "MM36", appleLocsMM3, UPRV_LENGTHOF(appleLocsMM3), prefLangsMM6, UPRV_LENGTHOF(prefLangsMM6), locsToUseMMptBR, UPRV_LENGTHOF(locsToUseMMptBR) },
+ { "MM46", appleLocsMM4, UPRV_LENGTHOF(appleLocsMM4), prefLangsMM6, UPRV_LENGTHOF(prefLangsMM6), locsToUseMMptPT, UPRV_LENGTHOF(locsToUseMMptPT) },
+ { "MM56", appleLocsMM5, UPRV_LENGTHOF(appleLocsMM5), prefLangsMM6, UPRV_LENGTHOF(prefLangsMM6), locsToUseMMptBR, UPRV_LENGTHOF(locsToUseMMptBR) },
+ { "MM66", appleLocsMM6, UPRV_LENGTHOF(appleLocsMM6), prefLangsMM6, UPRV_LENGTHOF(prefLangsMM6), locsToUseMMptBR, UPRV_LENGTHOF(locsToUseMMptBR) },
+ { "MN1", appleLocsMN, UPRV_LENGTHOF(appleLocsMN), prefLangsMN1, UPRV_LENGTHOF(prefLangsMN1), locsToUseMN_U, UPRV_LENGTHOF(locsToUseMN_U) },
+ { "MN2", appleLocsMN, UPRV_LENGTHOF(appleLocsMN), prefLangsMN2, UPRV_LENGTHOF(prefLangsMN2), locsToUseMN_U, UPRV_LENGTHOF(locsToUseMN_U) },
+ { "MN3", appleLocsMN, UPRV_LENGTHOF(appleLocsMN), prefLangsMN3, UPRV_LENGTHOF(prefLangsMN3), locsToUseMN_U, UPRV_LENGTHOF(locsToUseMN_U) },
+ { "MN4", appleLocsMN, UPRV_LENGTHOF(appleLocsMN), prefLangsMN4, UPRV_LENGTHOF(prefLangsMN4), locsToUseMN_U, UPRV_LENGTHOF(locsToUseMN_U) },
+ { "MO", appleLocsMO, UPRV_LENGTHOF(appleLocsMO), prefLangsMO1, UPRV_LENGTHOF(prefLangsMO1), locsToUseMO1, UPRV_LENGTHOF(locsToUseMO1) },
+
+ { NULL, NULL, 0, NULL, 0, NULL, 0 }
+};
+
+
+/* general enums */
+
+enum { kMaxLocalizationsToUse = 8, kPrintArrayBufSize = 128 };
+
+// array, array of pointers to strings to print
+// count, count of array elements, may be -1 if array is terminated by a NULL entry
+// buf, buffer into which to put concatenated strings
+// bufSize, length of buf
+static void printStringArray(const char **array, int32_t count, char *buf, int32_t bufSize) {
+ char * bufPtr = buf;
+ const char * curEntry;
+ int32_t idx, countMax = bufSize/16;
+ if (count < 0 || count > countMax) {
+ count = countMax;
+ }
+ for (idx = 0; idx < count && (curEntry = *array++) != NULL; idx++) {
+ int32_t len = sprintf(bufPtr, "%s\"%.12s\"", (idx > 0)? ", ": "", curEntry);
+ if (len <= 0) {
+ break;
+ }
+ bufPtr += len;
+ }
+ *bufPtr = 0; /* ensure termination */
+}
+
+static UBool equalStringArrays(const char **array1, int32_t count1, const char **array2, int32_t count2) {
+ const char ** array1Ptr = array1;
+ const char ** array2Ptr = array2;
+ int32_t idx;
+ if (count1 < 0) {
+ count1 = 0;
+ while (*array1Ptr++ != NULL) {
+ count1++;
+ }
+ }
+ if (count2 < 0) {
+ count2 = 0;
+ while (*array2Ptr++ != NULL) {
+ count2++;
+ }
+ }
+ if (count1 != count2) {
+ return FALSE;
+ }
+ for (idx = 0; idx < count1; idx++) {
+ if (uprv_strcmp(array1[idx], array2[idx]) != 0) {
+ return FALSE;
+ }
+ }
+ return TRUE;
+}
+
+static void TestAppleLocalizationsToUse() {
+ const AppleLocToUseTestSet * testSetPtr;
+ const MultiPrefTest * multiSetPtr;
+ const char * locsToUse[kMaxLocalizationsToUse];
+ int32_t numLocsToUse;
+ UErrorCode status;
+ char printExpected[kPrintArrayBufSize];
+ char printActual[kPrintArrayBufSize];
+
+ for (testSetPtr = altuTestSets; testSetPtr->locAndCountEntriesPtr != NULL; testSetPtr++) {
+ int32_t iLocSet, iLang;
+
+ for (iLocSet = 0; iLocSet < kNumLocSets; iLocSet++) {
+ for (iLang = 0; iLang < testSetPtr->appleLangAndLocCount; iLang++) {
+ const char * language = testSetPtr->appleLangAndLocPtr[iLang].language;
+ const char ** expLocsForSet = testSetPtr->appleLangAndLocPtr[iLang].expLocsForSets[iLocSet];
+ status = U_ZERO_ERROR;
+
+ numLocsToUse = ualoc_localizationsToUse(&language, 1,
+ testSetPtr->locAndCountEntriesPtr[iLocSet].locs, testSetPtr->locAndCountEntriesPtr[iLocSet].locCount,
+ locsToUse, kMaxLocalizationsToUse, &status);
+ if (U_FAILURE(status)) {
+ log_err("FAIL: ualoc_localizationsToUse testSet %d, locSet %d, lang %s, status %s\n",
+ testSetPtr-altuTestSets, iLocSet+1, language, u_errorName(status));
+ } else if (numLocsToUse == 0 && expLocsForSet != NULL) {
+ printStringArray(expLocsForSet, -1, printExpected, kPrintArrayBufSize);
+ log_err("FAIL: ualoc_localizationsToUse testSet %d, locSet %d, lang %s, expect {%s}, get no results\n",
+ testSetPtr-altuTestSets, iLocSet+1, language, printExpected);
+ } else if (numLocsToUse > 0 && expLocsForSet == NULL) {
+ printStringArray(locsToUse, numLocsToUse, printActual, kPrintArrayBufSize);
+ log_err("FAIL: ualoc_localizationsToUse testSet %d, locSet %d, lang %s, expect no results, get {%s}\n",
+ testSetPtr-altuTestSets, iLocSet+1, language, printActual);
+ } else if (numLocsToUse > 0 && !equalStringArrays(expLocsForSet, -1, locsToUse, numLocsToUse)) {
+ printStringArray(expLocsForSet, -1, printExpected, kPrintArrayBufSize);
+ printStringArray(locsToUse, numLocsToUse, printActual, kPrintArrayBufSize);
+ log_err("FAIL: ualoc_localizationsToUse testSet %d, locSet %d, lang %s:\n expect {%s}\n get {%s}\n",
+ testSetPtr-altuTestSets, iLocSet+1, language, printExpected, printActual);
+ }
+ }
+ }
+ }
+
+ for (multiSetPtr = multiTestSets; multiSetPtr->name != NULL; multiSetPtr++) {
+ status = U_ZERO_ERROR;
+ numLocsToUse = ualoc_localizationsToUse(multiSetPtr->prefLangs, multiSetPtr->prefLangsCount, multiSetPtr->availLocs, multiSetPtr->availLocsCount, locsToUse, kMaxLocalizationsToUse, &status);
+ if (U_FAILURE(status)) {
+ log_err("FAIL: ualoc_localizationsToUse appleLocs%s, langs prefLangs%s, status %s\n", multiSetPtr->name, multiSetPtr->name, u_errorName(status));
+ } else if (!equalStringArrays(multiSetPtr->locsToUse, multiSetPtr->locsToUseCount, locsToUse, numLocsToUse)) {
+ printStringArray(multiSetPtr->locsToUse, multiSetPtr->locsToUseCount, printExpected, kPrintArrayBufSize);
+ printStringArray(locsToUse, numLocsToUse, printActual, kPrintArrayBufSize);
+ log_err("FAIL: ualoc_localizationsToUse appleLocs%s, langs prefLangs%s:\n expect {%s}\n get {%s}\n",
+ multiSetPtr->name, multiSetPtr->name, printExpected, printActual);
+ }
+ }
+}
+