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