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