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