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