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