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