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