OLD | NEW |
(Empty) | |
| 1 /******************************************************************** |
| 2 * COPYRIGHT: |
| 3 * Copyright (c) 1997-2010, International Business Machines Corporation and |
| 4 * others. All Rights Reserved. |
| 5 ********************************************************************/ |
| 6 |
| 7 #include "cintltst.h" |
| 8 #include "unicode/ures.h" |
| 9 #include "unicode/ucurr.h" |
| 10 #include "unicode/ustring.h" |
| 11 #include "unicode/uset.h" |
| 12 #include "unicode/udat.h" |
| 13 #include "unicode/uscript.h" |
| 14 #include "unicode/ulocdata.h" |
| 15 #include "cstring.h" |
| 16 #include "locmap.h" |
| 17 #include "uresimp.h" |
| 18 |
| 19 /* |
| 20 returns a new UnicodeSet that is a flattened form of the original |
| 21 UnicodeSet. |
| 22 */ |
| 23 static USet* |
| 24 createFlattenSet(USet *origSet, UErrorCode *status) { |
| 25 |
| 26 |
| 27 USet *newSet = NULL; |
| 28 int32_t origItemCount = 0; |
| 29 int32_t idx, graphmeSize; |
| 30 UChar32 start, end; |
| 31 UChar graphme[64]; |
| 32 if (U_FAILURE(*status)) { |
| 33 log_err("createFlattenSet called with %s\n", u_errorName(*status)); |
| 34 return NULL; |
| 35 } |
| 36 newSet = uset_open(1, 0); |
| 37 origItemCount = uset_getItemCount(origSet); |
| 38 for (idx = 0; idx < origItemCount; idx++) { |
| 39 graphmeSize = uset_getItem(origSet, idx, |
| 40 &start, &end, |
| 41 graphme, (int32_t)(sizeof(graphme)/sizeof(graphme[0])), |
| 42 status); |
| 43 if (U_FAILURE(*status)) { |
| 44 log_err("ERROR: uset_getItem returned %s\n", u_errorName(*status)); |
| 45 *status = U_ZERO_ERROR; |
| 46 } |
| 47 if (graphmeSize) { |
| 48 uset_addAllCodePoints(newSet, graphme, graphmeSize); |
| 49 } |
| 50 else { |
| 51 uset_addRange(newSet, start, end); |
| 52 } |
| 53 } |
| 54 return newSet; |
| 55 } |
| 56 static UBool |
| 57 isCurrencyPreEuro(const char* currencyKey){ |
| 58 if( strcmp(currencyKey, "PTE") == 0 || |
| 59 strcmp(currencyKey, "ESP") == 0 || |
| 60 strcmp(currencyKey, "LUF") == 0 || |
| 61 strcmp(currencyKey, "GRD") == 0 || |
| 62 strcmp(currencyKey, "BEF") == 0 || |
| 63 strcmp(currencyKey, "ITL") == 0 || |
| 64 strcmp(currencyKey, "EEK") == 0){ |
| 65 return TRUE; |
| 66 } |
| 67 return FALSE; |
| 68 } |
| 69 static void |
| 70 TestKeyInRootRecursive(UResourceBundle *root, const char *rootName, |
| 71 UResourceBundle *currentBundle, const char *locale) { |
| 72 UErrorCode errorCode = U_ZERO_ERROR; |
| 73 UResourceBundle *subRootBundle = NULL, *subBundle = NULL, *arr = NULL; |
| 74 |
| 75 ures_resetIterator(root); |
| 76 ures_resetIterator(currentBundle); |
| 77 while (ures_hasNext(currentBundle)) { |
| 78 const char *subBundleKey = NULL; |
| 79 const char *currentBundleKey = NULL; |
| 80 |
| 81 errorCode = U_ZERO_ERROR; |
| 82 currentBundleKey = ures_getKey(currentBundle); |
| 83 subBundle = ures_getNextResource(currentBundle, NULL, &errorCode); |
| 84 if (U_FAILURE(errorCode)) { |
| 85 log_err("Can't open a resource for lnocale %s. Error: %s\n", locale,
u_errorName(errorCode)); |
| 86 continue; |
| 87 } |
| 88 subBundleKey = ures_getKey(subBundle); |
| 89 |
| 90 |
| 91 subRootBundle = ures_getByKey(root, subBundleKey, NULL, &errorCode); |
| 92 if (U_FAILURE(errorCode)) { |
| 93 log_err("Can't open a resource with key \"%s\" in \"%s\" from %s for
locale \"%s\"\n", |
| 94 subBundleKey, |
| 95 ures_getKey(currentBundle), |
| 96 rootName, |
| 97 locale); |
| 98 ures_close(subBundle); |
| 99 continue; |
| 100 } |
| 101 if (ures_getType(subRootBundle) != ures_getType(subBundle)) { |
| 102 log_err("key \"%s\" in \"%s\" has a different type from root for loc
ale \"%s\"\n" |
| 103 "\troot=%d, locale=%d\n", |
| 104 subBundleKey, |
| 105 ures_getKey(currentBundle), |
| 106 locale, |
| 107 ures_getType(subRootBundle), |
| 108 ures_getType(subBundle)); |
| 109 ures_close(subBundle); |
| 110 continue; |
| 111 } |
| 112 else if (ures_getType(subBundle) == URES_INT_VECTOR) { |
| 113 int32_t minSize; |
| 114 int32_t subBundleSize; |
| 115 int32_t idx; |
| 116 UBool sameArray = TRUE; |
| 117 const int32_t *subRootBundleArr = ures_getIntVector(subRootBundle, &
minSize, &errorCode); |
| 118 const int32_t *subBundleArr = ures_getIntVector(subBundle, &subBundl
eSize, &errorCode); |
| 119 |
| 120 if (minSize > subBundleSize) { |
| 121 minSize = subBundleSize; |
| 122 log_err("Arrays are different size with key \"%s\" in \"%s\" fro
m root for locale \"%s\"\n", |
| 123 subBundleKey, |
| 124 ures_getKey(currentBundle), |
| 125 locale); |
| 126 } |
| 127 |
| 128 for (idx = 0; idx < minSize && sameArray; idx++) { |
| 129 if (subRootBundleArr[idx] != subBundleArr[idx]) { |
| 130 sameArray = FALSE; |
| 131 } |
| 132 if (strcmp(subBundleKey, "DateTimeElements") == 0 |
| 133 && (subBundleArr[idx] < 1 || 7 < subBundleArr[idx])) |
| 134 { |
| 135 log_err("Value out of range with key \"%s\" at index %d in \
"%s\" for locale \"%s\"\n", |
| 136 subBundleKey, |
| 137 idx, |
| 138 ures_getKey(currentBundle), |
| 139 locale); |
| 140 } |
| 141 } |
| 142 /* Special exception es_US and DateTimeElements */ |
| 143 if (sameArray |
| 144 && !(strcmp(locale, "es_US") == 0 && strcmp(subBundleKey, "DateT
imeElements") == 0)) |
| 145 { |
| 146 log_err("Integer vectors are the same with key \"%s\" in \"%s\"
from root for locale \"%s\"\n", |
| 147 subBundleKey, |
| 148 ures_getKey(currentBundle), |
| 149 locale); |
| 150 } |
| 151 } |
| 152 else if (ures_getType(subBundle) == URES_ARRAY) { |
| 153 UResourceBundle *subSubBundle = ures_getByIndex(subBundle, 0, NULL,
&errorCode); |
| 154 UResourceBundle *subSubRootBundle = ures_getByIndex(subRootBundle, 0
, NULL, &errorCode); |
| 155 |
| 156 if (U_SUCCESS(errorCode) |
| 157 && (ures_getType(subSubBundle) == URES_ARRAY || ures_getType(sub
SubRootBundle) == URES_ARRAY)) |
| 158 { |
| 159 /* Here is one of the recursive parts */ |
| 160 TestKeyInRootRecursive(subRootBundle, rootName, subBundle, local
e); |
| 161 } |
| 162 else { |
| 163 int32_t minSize = ures_getSize(subRootBundle); |
| 164 int32_t idx; |
| 165 UBool sameArray = TRUE; |
| 166 |
| 167 if (minSize > ures_getSize(subBundle)) { |
| 168 minSize = ures_getSize(subBundle); |
| 169 } |
| 170 |
| 171 if ((subBundleKey == NULL |
| 172 || (subBundleKey != NULL && strcmp(subBundleKey, "LocaleScr
ipt") != 0 && !isCurrencyPreEuro(subBundleKey))) |
| 173 && ures_getSize(subRootBundle) != ures_getSize(subBundle)) |
| 174 { |
| 175 log_err("Different size array with key \"%s\" in \"%s\" from
root for locale \"%s\"\n" |
| 176 "\troot array size=%d, locale array size=%d\n", |
| 177 subBundleKey, |
| 178 ures_getKey(currentBundle), |
| 179 locale, |
| 180 ures_getSize(subRootBundle), |
| 181 ures_getSize(subBundle)); |
| 182 } |
| 183 /* |
| 184 if(isCurrencyPreEuro(subBundleKey) && ures_getSize(subBundle)!=3
){ |
| 185 log_err("Different size array with key \"%s\" in \"%s\" for
locale \"%s\" the expected size is 3 got size=%d\n", |
| 186 subBundleKey, |
| 187 ures_getKey(currentBundle), |
| 188 locale, |
| 189 ures_getSize(subBundle)); |
| 190 } |
| 191 */ |
| 192 for (idx = 0; idx < minSize; idx++) { |
| 193 int32_t rootStrLen, localeStrLen; |
| 194 const UChar *rootStr = ures_getStringByIndex(subRootBundle,i
dx,&rootStrLen,&errorCode); |
| 195 const UChar *localeStr = ures_getStringByIndex(subBundle,idx
,&localeStrLen,&errorCode); |
| 196 if (rootStr && localeStr && U_SUCCESS(errorCode)) { |
| 197 if (u_strcmp(rootStr, localeStr) != 0) { |
| 198 sameArray = FALSE; |
| 199 } |
| 200 } |
| 201 else { |
| 202 if ( rootStrLen > 1 && rootStr[0] == 0x41 && rootStr[1]
>= 0x30 && rootStr[1] <= 0x39 ) { |
| 203 /* A2 or A4 in the root string indicates that the res
ource can optionally be an array instead of a */ |
| 204 /* string. Attempt to read it as an array. */ |
| 205 errorCode = U_ZERO_ERROR; |
| 206 arr = ures_getByIndex(subBundle,idx,NULL,&errorCode); |
| 207 if (U_FAILURE(errorCode)) { |
| 208 log_err("Got a NULL string with key \"%s\" in \"%s
\" at index %d for root or locale \"%s\"\n", |
| 209 subBundleKey, |
| 210 ures_getKey(currentBundle), |
| 211 idx, |
| 212 locale); |
| 213 continue; |
| 214 } |
| 215 if (ures_getType(arr) != URES_ARRAY || ures_getSize(ar
r) != (int32_t)rootStr[1] - 0x30) { |
| 216 log_err("Got something other than a string or arra
y of size %d for key \"%s\" in \"%s\" at index %d for root or locale \"%s\"\n", |
| 217 rootStr[1] - 0x30, |
| 218 subBundleKey, |
| 219 ures_getKey(currentBundle), |
| 220 idx, |
| 221 locale); |
| 222 ures_close(arr); |
| 223 continue; |
| 224 } |
| 225 localeStr = ures_getStringByIndex(arr,0,&localeStrLen,
&errorCode); |
| 226 ures_close(arr); |
| 227 if (U_FAILURE(errorCode)) { |
| 228 log_err("Got something other than a string or arra
y for key \"%s\" in \"%s\" at index %d for root or locale \"%s\"\n", |
| 229 subBundleKey, |
| 230 ures_getKey(currentBundle), |
| 231 idx, |
| 232 locale); |
| 233 continue; |
| 234 } |
| 235 } else { |
| 236 log_err("Got a NULL string with key \"%s\" in \"%s\"
at index %d for root or locale \"%s\"\n", |
| 237 subBundleKey, |
| 238 ures_getKey(currentBundle), |
| 239 idx, |
| 240 locale); |
| 241 continue; |
| 242 } |
| 243 } |
| 244 if (localeStr[0] == (UChar)0x20) { |
| 245 log_err("key \"%s\" at index %d in \"%s\" starts with a
space in locale \"%s\"\n", |
| 246 subBundleKey, |
| 247 idx, |
| 248 ures_getKey(currentBundle), |
| 249 locale); |
| 250 } |
| 251 else if ((localeStr[localeStrLen - 1] == (UChar)0x20) && (st
rcmp(subBundleKey,"separator") != 0)) { |
| 252 log_err("key \"%s\" at index %d in \"%s\" ends with a sp
ace in locale \"%s\"\n", |
| 253 subBundleKey, |
| 254 idx, |
| 255 ures_getKey(currentBundle), |
| 256 locale); |
| 257 } |
| 258 else if (subBundleKey != NULL |
| 259 && strcmp(subBundleKey, "DateTimePatterns") == 0) |
| 260 { |
| 261 int32_t quoted = 0; |
| 262 const UChar *localeStrItr = localeStr; |
| 263 while (*localeStrItr) { |
| 264 if (*localeStrItr == (UChar)0x27 /* ' */) { |
| 265 quoted++; |
| 266 } |
| 267 else if ((quoted % 2) == 0) { |
| 268 /* Search for unquoted characters */ |
| 269 if (4 <= idx && idx <= 7 |
| 270 && (*localeStrItr == (UChar)0x6B /* k */ |
| 271 || *localeStrItr == (UChar)0x48 /* H */ |
| 272 || *localeStrItr == (UChar)0x6D /* m */ |
| 273 || *localeStrItr == (UChar)0x73 /* s */ |
| 274 || *localeStrItr == (UChar)0x53 /* S */ |
| 275 || *localeStrItr == (UChar)0x61 /* a */ |
| 276 || *localeStrItr == (UChar)0x68 /* h */ |
| 277 || *localeStrItr == (UChar)0x7A /* z */)) |
| 278 { |
| 279 log_err("key \"%s\" at index %d has time pat
tern chars in date for locale \"%s\"\n", |
| 280 subBundleKey, |
| 281 idx, |
| 282 locale); |
| 283 } |
| 284 else if (0 <= idx && idx <= 3 |
| 285 && (*localeStrItr == (UChar)0x47 /* G */ |
| 286 || *localeStrItr == (UChar)0x79 /* y */ |
| 287 || *localeStrItr == (UChar)0x4D /* M */ |
| 288 || *localeStrItr == (UChar)0x64 /* d */ |
| 289 || *localeStrItr == (UChar)0x45 /* E */ |
| 290 || *localeStrItr == (UChar)0x44 /* D */ |
| 291 || *localeStrItr == (UChar)0x46 /* F */ |
| 292 || *localeStrItr == (UChar)0x77 /* w */ |
| 293 || *localeStrItr == (UChar)0x57 /* W */)) |
| 294 { |
| 295 log_err("key \"%s\" at index %d has date pat
tern chars in time for locale \"%s\"\n", |
| 296 subBundleKey, |
| 297 idx, |
| 298 locale); |
| 299 } |
| 300 } |
| 301 localeStrItr++; |
| 302 } |
| 303 } |
| 304 else if (idx == 4 && subBundleKey != NULL |
| 305 && strcmp(subBundleKey, "NumberElements") == 0 |
| 306 && u_charDigitValue(localeStr[0]) != 0) |
| 307 { |
| 308 log_err("key \"%s\" at index %d has a non-zero based num
ber for locale \"%s\"\n", |
| 309 subBundleKey, |
| 310 idx, |
| 311 locale); |
| 312 } |
| 313 } |
| 314 /* if (sameArray && strcmp(rootName, "root") == 0) { |
| 315 log_err("Arrays are the same with key \"%s\" in \"%s\" from
root for locale \"%s\"\n", |
| 316 subBundleKey, |
| 317 ures_getKey(currentBundle), |
| 318 locale); |
| 319 }*/ |
| 320 } |
| 321 ures_close(subSubBundle); |
| 322 ures_close(subSubRootBundle); |
| 323 } |
| 324 else if (ures_getType(subBundle) == URES_STRING) { |
| 325 int32_t len = 0; |
| 326 const UChar *string = ures_getString(subBundle, &len, &errorCode); |
| 327 if (U_FAILURE(errorCode) || string == NULL) { |
| 328 log_err("Can't open a string with key \"%s\" in \"%s\" for local
e \"%s\"\n", |
| 329 subBundleKey, |
| 330 ures_getKey(currentBundle), |
| 331 locale); |
| 332 } else if (string[0] == (UChar)0x20) { |
| 333 log_err("key \"%s\" in \"%s\" starts with a space in locale \"%s
\"\n", |
| 334 subBundleKey, |
| 335 ures_getKey(currentBundle), |
| 336 locale); |
| 337 /* localeDisplayPattern/separator can end with a space */ |
| 338 } else if (string[len - 1] == (UChar)0x20 && (strcmp(subBundleKey,"s
eparator"))) { |
| 339 log_err("key \"%s\" in \"%s\" ends with a space in locale \"%s\"
\n", |
| 340 subBundleKey, |
| 341 ures_getKey(currentBundle), |
| 342 locale); |
| 343 } else if (strcmp(subBundleKey, "localPatternChars") == 0) { |
| 344 /* Note: We no longer import localPatternChars data starting |
| 345 * ICU 3.8. So it never comes into this else if block. (ticket#
5597) |
| 346 */ |
| 347 |
| 348 /* Check well-formedness of localPatternChars. First, the |
| 349 * length must match the number of fields defined by |
| 350 * DateFormat. Second, each character in the string must |
| 351 * be in the set [A-Za-z]. Finally, each character must be |
| 352 * unique. |
| 353 */ |
| 354 int32_t i,j; |
| 355 #if !UCONFIG_NO_FORMATTING |
| 356 if (len != UDAT_FIELD_COUNT) { |
| 357 log_err("key \"%s\" has the wrong number of characters in lo
cale \"%s\"\n", |
| 358 subBundleKey, |
| 359 locale); |
| 360 } |
| 361 #endif |
| 362 /* Check char validity. */ |
| 363 for (i=0; i<len; ++i) { |
| 364 if (!((string[i] >= 65/*'A'*/ && string[i] <= 90/*'Z'*/) || |
| 365 (string[i] >= 97/*'a'*/ && string[i] <= 122/*'z'*/)))
{ |
| 366 log_err("key \"%s\" has illegal character '%c' in locale
\"%s\"\n", |
| 367 subBundleKey, |
| 368 (char) string[i], |
| 369 locale); |
| 370 } |
| 371 /* Do O(n^2) check for duplicate chars. */ |
| 372 for (j=0; j<i; ++j) { |
| 373 if (string[j] == string[i]) { |
| 374 log_err("key \"%s\" has duplicate character '%c' in
locale \"%s\"\n", |
| 375 subBundleKey, |
| 376 (char) string[i], |
| 377 locale); |
| 378 } |
| 379 } |
| 380 } |
| 381 } |
| 382 /* No fallback was done. Check for duplicate data */ |
| 383 /* The ures_* API does not do fallback of sub-resource bundles, |
| 384 So we can't do this now. */ |
| 385 #if 0 |
| 386 else if (strcmp(locale, "root") != 0 && errorCode == U_ZERO_ERROR) { |
| 387 |
| 388 const UChar *rootString = ures_getString(subRootBundle, &len, &e
rrorCode); |
| 389 if (U_FAILURE(errorCode) || rootString == NULL) { |
| 390 log_err("Can't open a string with key \"%s\" in \"%s\" in ro
ot\n", |
| 391 ures_getKey(subRootBundle), |
| 392 ures_getKey(currentBundle)); |
| 393 continue; |
| 394 } else if (u_strcmp(string, rootString) == 0) { |
| 395 if (strcmp(locale, "de_CH") != 0 && strcmp(subBundleKey, "Co
untries") != 0 && |
| 396 strcmp(subBundleKey, "Version") != 0) { |
| 397 log_err("Found duplicate data with key \"%s\" in \"%s\"
in locale \"%s\"\n", |
| 398 ures_getKey(subRootBundle), |
| 399 ures_getKey(currentBundle), |
| 400 locale); |
| 401 } |
| 402 else { |
| 403 /* Ignore for now. */ |
| 404 /* Can be fixed if fallback through de locale was done.
*/ |
| 405 log_verbose("Skipping key %s in %s\n", subBundleKey, loc
ale); |
| 406 } |
| 407 } |
| 408 } |
| 409 #endif |
| 410 } |
| 411 else if (ures_getType(subBundle) == URES_TABLE) { |
| 412 if (strcmp(subBundleKey, "availableFormats")!=0) { |
| 413 /* Here is one of the recursive parts */ |
| 414 TestKeyInRootRecursive(subRootBundle, rootName, subBundle, local
e); |
| 415 } |
| 416 else { |
| 417 log_verbose("Skipping key %s in %s\n", subBundleKey, locale); |
| 418 } |
| 419 } |
| 420 else if (ures_getType(subBundle) == URES_BINARY || ures_getType(subBundl
e) == URES_INT) { |
| 421 /* Can't do anything to check it */ |
| 422 /* We'll assume it's all correct */ |
| 423 if (strcmp(subBundleKey, "MeasurementSystem") != 0) { |
| 424 log_verbose("Skipping key \"%s\" in \"%s\" for locale \"%s\"\n", |
| 425 subBundleKey, |
| 426 ures_getKey(currentBundle), |
| 427 locale); |
| 428 } |
| 429 /* Testing for MeasurementSystem is done in VerifyTranslation */ |
| 430 } |
| 431 else { |
| 432 log_err("Type %d for key \"%s\" in \"%s\" is unknown for locale \"%s
\"\n", |
| 433 ures_getType(subBundle), |
| 434 subBundleKey, |
| 435 ures_getKey(currentBundle), |
| 436 locale); |
| 437 } |
| 438 ures_close(subRootBundle); |
| 439 ures_close(subBundle); |
| 440 } |
| 441 } |
| 442 |
| 443 |
| 444 static void |
| 445 testLCID(UResourceBundle *currentBundle, |
| 446 const char *localeName) |
| 447 { |
| 448 UErrorCode status = U_ZERO_ERROR; |
| 449 uint32_t expectedLCID; |
| 450 char lcidStringC[64] = {0}; |
| 451 |
| 452 expectedLCID = uloc_getLCID(localeName); |
| 453 if (expectedLCID == 0) { |
| 454 log_verbose("INFO: %-5s does not have any LCID mapping\n", |
| 455 localeName); |
| 456 return; |
| 457 } |
| 458 |
| 459 status = U_ZERO_ERROR; |
| 460 uprv_strcpy(lcidStringC, uprv_convertToPosix(expectedLCID, &status)); |
| 461 if (U_FAILURE(status)) { |
| 462 log_err("ERROR: %.4x does not have a POSIX mapping due to %s\n", |
| 463 expectedLCID, u_errorName(status)); |
| 464 } |
| 465 |
| 466 if(strcmp(localeName, lcidStringC) != 0) { |
| 467 char langName[1024]; |
| 468 char langLCID[1024]; |
| 469 uloc_getLanguage(localeName, langName, sizeof(langName), &status); |
| 470 uloc_getLanguage(lcidStringC, langLCID, sizeof(langLCID), &status); |
| 471 |
| 472 if (strcmp(langName, langLCID) == 0) { |
| 473 log_verbose("WARNING: %-5s resolves to %s (0x%.4x)\n", |
| 474 localeName, lcidStringC, expectedLCID); |
| 475 } |
| 476 else { |
| 477 log_err("ERROR: %-5s has 0x%.4x and the number resolves wrongfully
to %s\n", |
| 478 localeName, expectedLCID, lcidStringC); |
| 479 } |
| 480 } |
| 481 } |
| 482 |
| 483 static void |
| 484 TestLocaleStructure(void) { |
| 485 UResourceBundle *root, *currentLocale; |
| 486 int32_t locCount = uloc_countAvailable(); |
| 487 int32_t locIndex; |
| 488 UErrorCode errorCode = U_ZERO_ERROR; |
| 489 const char *currLoc, *resolvedLoc; |
| 490 |
| 491 /* TODO: Compare against parent's data too. This code can't handle fallbacks
that some tools do already. */ |
| 492 /* char locName[ULOC_FULLNAME_CAPACITY]; |
| 493 char *locNamePtr; |
| 494 |
| 495 for (locIndex = 0; locIndex < locCount; locIndex++) { |
| 496 errorCode=U_ZERO_ERROR; |
| 497 strcpy(locName, uloc_getAvailable(locIndex)); |
| 498 locNamePtr = strrchr(locName, '_'); |
| 499 if (locNamePtr) { |
| 500 *locNamePtr = 0; |
| 501 } |
| 502 else { |
| 503 strcpy(locName, "root"); |
| 504 } |
| 505 |
| 506 root = ures_openDirect(NULL, locName, &errorCode); |
| 507 if(U_FAILURE(errorCode)) { |
| 508 log_err("Can't open %s\n", locName); |
| 509 continue; |
| 510 } |
| 511 */ |
| 512 if (locCount <= 1) { |
| 513 log_data_err("At least root needs to be installed\n"); |
| 514 } |
| 515 |
| 516 root = ures_openDirect(loadTestData(&errorCode), "structLocale", &errorCode)
; |
| 517 if(U_FAILURE(errorCode)) { |
| 518 log_data_err("Can't open structLocale\n"); |
| 519 return; |
| 520 } |
| 521 for (locIndex = 0; locIndex < locCount; locIndex++) { |
| 522 errorCode=U_ZERO_ERROR; |
| 523 currLoc = uloc_getAvailable(locIndex); |
| 524 currentLocale = ures_open(NULL, currLoc, &errorCode); |
| 525 if(errorCode != U_ZERO_ERROR) { |
| 526 if(U_SUCCESS(errorCode)) { |
| 527 /* It's installed, but there is no data. |
| 528 It's installed for the g18n white paper [grhoten] */ |
| 529 log_err("ERROR: Locale %-5s not installed, and it should be, err
%s\n", |
| 530 uloc_getAvailable(locIndex), u_errorName(errorCode)); |
| 531 } else { |
| 532 log_err("%%%%%%% Unexpected error %d in %s %%%%%%%", |
| 533 u_errorName(errorCode), |
| 534 uloc_getAvailable(locIndex)); |
| 535 } |
| 536 ures_close(currentLocale); |
| 537 continue; |
| 538 } |
| 539 ures_getStringByKey(currentLocale, "Version", NULL, &errorCode); |
| 540 if(errorCode != U_ZERO_ERROR) { |
| 541 log_err("No version information is available for locale %s, and it s
hould be!\n", |
| 542 currLoc); |
| 543 } |
| 544 else if (ures_getStringByKey(currentLocale, "Version", NULL, &errorCode)
[0] == (UChar)(0x78)) { |
| 545 log_verbose("WARNING: The locale %s is experimental! It shouldn't be
listed as an installed locale.\n", |
| 546 currLoc); |
| 547 } |
| 548 resolvedLoc = ures_getLocaleByType(currentLocale, ULOC_ACTUAL_LOCALE, &e
rrorCode); |
| 549 if (strcmp(resolvedLoc, currLoc) != 0) { |
| 550 /* All locales have at least a Version resource. |
| 551 If it's absolutely empty, then the previous test will fail too.*/ |
| 552 log_err("Locale resolves to different locale. Is %s an alias of %s?\
n", |
| 553 currLoc, resolvedLoc); |
| 554 } |
| 555 TestKeyInRootRecursive(root, "root", currentLocale, currLoc); |
| 556 |
| 557 testLCID(currentLocale, currLoc); |
| 558 |
| 559 ures_close(currentLocale); |
| 560 } |
| 561 |
| 562 ures_close(root); |
| 563 } |
| 564 |
| 565 static void |
| 566 compareArrays(const char *keyName, |
| 567 UResourceBundle *fromArray, const char *fromLocale, |
| 568 UResourceBundle *toArray, const char *toLocale, |
| 569 int32_t start, int32_t end) |
| 570 { |
| 571 int32_t fromSize = ures_getSize(fromArray); |
| 572 int32_t toSize = ures_getSize(fromArray); |
| 573 int32_t idx; |
| 574 UErrorCode errorCode = U_ZERO_ERROR; |
| 575 |
| 576 if (fromSize > toSize) { |
| 577 fromSize = toSize; |
| 578 log_err("Arrays are different size from \"%s\" to \"%s\"\n", |
| 579 fromLocale, |
| 580 toLocale); |
| 581 } |
| 582 |
| 583 for (idx = start; idx <= end; idx++) { |
| 584 const UChar *fromBundleStr = ures_getStringByIndex(fromArray, idx, NULL,
&errorCode); |
| 585 const UChar *toBundleStr = ures_getStringByIndex(toArray, idx, NULL, &er
rorCode); |
| 586 if (fromBundleStr && toBundleStr && u_strcmp(fromBundleStr, toBundleStr)
!= 0) |
| 587 { |
| 588 log_err("Difference for %s at index %d from %s= \"%s\" to %s= \"%s\"
\n", |
| 589 keyName, |
| 590 idx, |
| 591 fromLocale, |
| 592 austrdup(fromBundleStr), |
| 593 toLocale, |
| 594 austrdup(toBundleStr)); |
| 595 } |
| 596 } |
| 597 } |
| 598 |
| 599 static void |
| 600 compareConsistentCountryInfo(const char *fromLocale, const char *toLocale) { |
| 601 UErrorCode errorCode = U_ZERO_ERROR; |
| 602 UResourceBundle *fromDateTimeElements, *toDateTimeElements, *fromWeekendData
= NULL, *toWeekendData = NULL; |
| 603 UResourceBundle *fromArray, *toArray; |
| 604 UResourceBundle *fromLocaleBund = ures_open(NULL, fromLocale, &errorCode); |
| 605 UResourceBundle *toLocaleBund = ures_open(NULL, toLocale, &errorCode); |
| 606 UResourceBundle *toCalendar, *fromCalendar, *toGregorian, *fromGregorian; |
| 607 |
| 608 if(U_FAILURE(errorCode)) { |
| 609 log_err("Can't open resource bundle %s or %s - %s\n", fromLocale, toLoca
le, u_errorName(errorCode)); |
| 610 return; |
| 611 } |
| 612 fromCalendar = ures_getByKey(fromLocaleBund, "calendar", NULL, &errorCode); |
| 613 fromGregorian = ures_getByKeyWithFallback(fromCalendar, "gregorian", NULL, &
errorCode); |
| 614 fromDateTimeElements = ures_getByKeyWithFallback(fromGregorian, "DateTimeEle
ments", NULL, &errorCode); |
| 615 |
| 616 toCalendar = ures_getByKey(toLocaleBund, "calendar", NULL, &errorCode); |
| 617 toGregorian = ures_getByKeyWithFallback(toCalendar, "gregorian", NULL, &erro
rCode); |
| 618 toDateTimeElements = ures_getByKeyWithFallback(toGregorian, "DateTimeElement
s", NULL, &errorCode); |
| 619 |
| 620 if(U_FAILURE(errorCode)){ |
| 621 log_err("Did not get DateTimeElements from the bundle %s or %s\n", fromL
ocale, toLocale); |
| 622 goto cleanup; |
| 623 } |
| 624 |
| 625 fromWeekendData = ures_getByKeyWithFallback(fromGregorian, "weekend", NULL,
&errorCode); |
| 626 if(U_FAILURE(errorCode)){ |
| 627 log_err("Did not get weekend data from the bundle %s to compare against
%s\n", fromLocale, toLocale); |
| 628 goto cleanup; |
| 629 } |
| 630 toWeekendData = ures_getByKeyWithFallback(toGregorian, "weekend", NULL, &err
orCode); |
| 631 if(U_FAILURE(errorCode)){ |
| 632 log_err("Did not get weekend data from the bundle %s to compare against
%s\n", toLocale, fromLocale); |
| 633 goto cleanup; |
| 634 } |
| 635 |
| 636 if (strcmp(fromLocale, "ar_IN") != 0) |
| 637 { |
| 638 int32_t fromSize; |
| 639 int32_t toSize; |
| 640 int32_t idx; |
| 641 const int32_t *fromBundleArr = ures_getIntVector(fromDateTimeElements, &
fromSize, &errorCode); |
| 642 const int32_t *toBundleArr = ures_getIntVector(toDateTimeElements, &toSi
ze, &errorCode); |
| 643 |
| 644 if (fromSize > toSize) { |
| 645 fromSize = toSize; |
| 646 log_err("Arrays are different size with key \"DateTimeElements\" fro
m \"%s\" to \"%s\"\n", |
| 647 fromLocale, |
| 648 toLocale); |
| 649 } |
| 650 |
| 651 for (idx = 0; idx < fromSize; idx++) { |
| 652 if (fromBundleArr[idx] != toBundleArr[idx]) { |
| 653 log_err("Difference with key \"DateTimeElements\" at index %d fr
om \"%s\" to \"%s\"\n", |
| 654 idx, |
| 655 fromLocale, |
| 656 toLocale); |
| 657 } |
| 658 } |
| 659 } |
| 660 |
| 661 /* test for weekend data */ |
| 662 { |
| 663 int32_t fromSize; |
| 664 int32_t toSize; |
| 665 int32_t idx; |
| 666 const int32_t *fromBundleArr = ures_getIntVector(fromWeekendData, &fromS
ize, &errorCode); |
| 667 const int32_t *toBundleArr = ures_getIntVector(toWeekendData, &toSize, &
errorCode); |
| 668 |
| 669 if (fromSize > toSize) { |
| 670 fromSize = toSize; |
| 671 log_err("Arrays are different size with key \"weekend\" data from \"
%s\" to \"%s\"\n", |
| 672 fromLocale, |
| 673 toLocale); |
| 674 } |
| 675 |
| 676 for (idx = 0; idx < fromSize; idx++) { |
| 677 if (fromBundleArr[idx] != toBundleArr[idx]) { |
| 678 log_err("Difference with key \"weekend\" data at index %d from \
"%s\" to \"%s\"\n", |
| 679 idx, |
| 680 fromLocale, |
| 681 toLocale); |
| 682 } |
| 683 } |
| 684 } |
| 685 |
| 686 fromArray = ures_getByKey(fromLocaleBund, "CurrencyElements", NULL, &errorCo
de); |
| 687 toArray = ures_getByKey(toLocaleBund, "CurrencyElements", NULL, &errorCode); |
| 688 if (strcmp(fromLocale, "en_CA") != 0) |
| 689 { |
| 690 /* The first one is probably localized. */ |
| 691 compareArrays("CurrencyElements", fromArray, fromLocale, toArray, toLoca
le, 1, 2); |
| 692 } |
| 693 ures_close(fromArray); |
| 694 ures_close(toArray); |
| 695 |
| 696 fromArray = ures_getByKey(fromLocaleBund, "NumberPatterns", NULL, &errorCode
); |
| 697 toArray = ures_getByKey(toLocaleBund, "NumberPatterns", NULL, &errorCode); |
| 698 if (strcmp(fromLocale, "en_CA") != 0) |
| 699 { |
| 700 compareArrays("NumberPatterns", fromArray, fromLocale, toArray, toLocale
, 0, 3); |
| 701 } |
| 702 ures_close(fromArray); |
| 703 ures_close(toArray); |
| 704 |
| 705 /* Difficult to test properly */ |
| 706 /* |
| 707 fromArray = ures_getByKey(fromLocaleBund, "DateTimePatterns", NULL, &errorCo
de); |
| 708 toArray = ures_getByKey(toLocaleBund, "DateTimePatterns", NULL, &errorCode); |
| 709 { |
| 710 compareArrays("DateTimePatterns", fromArray, fromLocale, toArray, toLoca
le); |
| 711 } |
| 712 ures_close(fromArray); |
| 713 ures_close(toArray);*/ |
| 714 |
| 715 fromArray = ures_getByKey(fromLocaleBund, "NumberElements", NULL, &errorCode
); |
| 716 toArray = ures_getByKey(toLocaleBund, "NumberElements", NULL, &errorCode); |
| 717 if (strcmp(fromLocale, "en_CA") != 0) |
| 718 { |
| 719 compareArrays("NumberElements", fromArray, fromLocale, toArray, toLocale
, 0, 3); |
| 720 /* Index 4 is a script based 0 */ |
| 721 compareArrays("NumberElements", fromArray, fromLocale, toArray, toLocale
, 5, 10); |
| 722 } |
| 723 ures_close(fromArray); |
| 724 ures_close(toArray); |
| 725 |
| 726 cleanup: |
| 727 ures_close(fromDateTimeElements); |
| 728 ures_close(toDateTimeElements); |
| 729 ures_close(fromWeekendData); |
| 730 ures_close(toWeekendData); |
| 731 |
| 732 ures_close(fromCalendar); |
| 733 ures_close(toCalendar); |
| 734 ures_close(fromGregorian); |
| 735 ures_close(toGregorian); |
| 736 |
| 737 ures_close(fromLocaleBund); |
| 738 ures_close(toLocaleBund); |
| 739 } |
| 740 |
| 741 static void |
| 742 TestConsistentCountryInfo(void) { |
| 743 /* UResourceBundle *fromLocale, *toLocale;*/ |
| 744 int32_t locCount = uloc_countAvailable(); |
| 745 int32_t fromLocIndex, toLocIndex; |
| 746 |
| 747 int32_t fromCountryLen, toCountryLen; |
| 748 char fromCountry[ULOC_FULLNAME_CAPACITY], toCountry[ULOC_FULLNAME_CAPACITY]; |
| 749 |
| 750 int32_t fromVariantLen, toVariantLen; |
| 751 char fromVariant[ULOC_FULLNAME_CAPACITY], toVariant[ULOC_FULLNAME_CAPACITY]; |
| 752 |
| 753 UErrorCode errorCode = U_ZERO_ERROR; |
| 754 |
| 755 for (fromLocIndex = 0; fromLocIndex < locCount; fromLocIndex++) { |
| 756 const char *fromLocale = uloc_getAvailable(fromLocIndex); |
| 757 |
| 758 errorCode=U_ZERO_ERROR; |
| 759 fromCountryLen = uloc_getCountry(fromLocale, fromCountry, ULOC_FULLNAME_
CAPACITY, &errorCode); |
| 760 if (fromCountryLen <= 0) { |
| 761 /* Ignore countryless locales */ |
| 762 continue; |
| 763 } |
| 764 fromVariantLen = uloc_getVariant(fromLocale, fromVariant, ULOC_FULLNAME_
CAPACITY, &errorCode); |
| 765 if (fromVariantLen > 0) { |
| 766 /* Most variants are ignorable like PREEURO, or collation variants.
*/ |
| 767 continue; |
| 768 } |
| 769 /* Start comparing only after the current index. |
| 770 Previous loop should have already compared fromLocIndex. |
| 771 */ |
| 772 for (toLocIndex = fromLocIndex + 1; toLocIndex < locCount; toLocIndex++)
{ |
| 773 const char *toLocale = uloc_getAvailable(toLocIndex); |
| 774 |
| 775 toCountryLen = uloc_getCountry(toLocale, toCountry, ULOC_FULLNAME_CA
PACITY, &errorCode); |
| 776 if(U_FAILURE(errorCode)) { |
| 777 log_err("Unknown failure fromLocale=%s toLocale=%s errorCode=%s\
n", |
| 778 fromLocale, toLocale, u_errorName(errorCode)); |
| 779 continue; |
| 780 } |
| 781 |
| 782 if (toCountryLen <= 0) { |
| 783 /* Ignore countryless locales */ |
| 784 continue; |
| 785 } |
| 786 toVariantLen = uloc_getVariant(toLocale, toVariant, ULOC_FULLNAME_CA
PACITY, &errorCode); |
| 787 if (toVariantLen > 0) { |
| 788 /* Most variants are ignorable like PREEURO, or collation varian
ts. */ |
| 789 /* They're a variant for a reason. */ |
| 790 continue; |
| 791 } |
| 792 if (strcmp(fromCountry, toCountry) == 0) { |
| 793 log_verbose("comparing fromLocale=%s toLocale=%s\n", |
| 794 fromLocale, toLocale); |
| 795 compareConsistentCountryInfo(fromLocale, toLocale); |
| 796 } |
| 797 } |
| 798 } |
| 799 } |
| 800 |
| 801 static int32_t |
| 802 findStringSetMismatch(const char *currLoc, const UChar *string, int32_t langSize
, |
| 803 const UChar *exemplarCharacters, int32_t exemplarLen, |
| 804 UBool ignoreNumbers, UChar* badCharPtr) { |
| 805 UErrorCode errorCode = U_ZERO_ERROR; |
| 806 USet *origSet = uset_openPatternOptions(exemplarCharacters, exemplarLen, USE
T_CASE_INSENSITIVE, &errorCode); |
| 807 USet *exemplarSet = createFlattenSet(origSet, &errorCode); |
| 808 int32_t strIdx; |
| 809 uset_close(origSet); |
| 810 if (U_FAILURE(errorCode)) { |
| 811 log_err("%s: error uset_openPattern returned %s\n", currLoc, u_errorName
(errorCode)); |
| 812 return -1; |
| 813 } |
| 814 |
| 815 for (strIdx = 0; strIdx < langSize; strIdx++) { |
| 816 if (!uset_contains(exemplarSet, string[strIdx]) |
| 817 && string[strIdx] != 0x0020 && string[strIdx] != 0x00A0 && string[st
rIdx] != 0x002e && string[strIdx] != 0x002c && string[strIdx] != 0x002d && strin
g[strIdx] != 0x0027 && string[strIdx] != 0x2019 && string[strIdx] != 0x0f0b |
| 818 && string[strIdx] != 0x200C && string[strIdx] != 0x200D) { |
| 819 if (!ignoreNumbers || (ignoreNumbers && (string[strIdx] < 0x30 || st
ring[strIdx] > 0x39))) { |
| 820 uset_close(exemplarSet); |
| 821 if (badCharPtr) { |
| 822 *badCharPtr = string[strIdx]; |
| 823 } |
| 824 return strIdx; |
| 825 } |
| 826 } |
| 827 } |
| 828 uset_close(exemplarSet); |
| 829 if (badCharPtr) { |
| 830 *badCharPtr = 0; |
| 831 } |
| 832 return -1; |
| 833 } |
| 834 /* include non-invariant chars */ |
| 835 static int32_t |
| 836 myUCharsToChars(const UChar* us, char* cs, int32_t len){ |
| 837 int32_t i=0; |
| 838 for(; i< len; i++){ |
| 839 if(us[i] < 0x7f){ |
| 840 cs[i] = (char)us[i]; |
| 841 }else{ |
| 842 return -1; |
| 843 } |
| 844 } |
| 845 return i; |
| 846 } |
| 847 static void |
| 848 findSetMatch( UScriptCode *scriptCodes, int32_t scriptsLen, |
| 849 USet *exemplarSet, |
| 850 const char *locale){ |
| 851 USet *scripts[10]= {0}; |
| 852 char pattern[256] = { '[', ':', 0x000 }; |
| 853 int32_t patternLen; |
| 854 UChar uPattern[256] = {0}; |
| 855 UErrorCode status = U_ZERO_ERROR; |
| 856 int32_t i; |
| 857 |
| 858 /* create the sets with script codes */ |
| 859 for(i = 0; i<scriptsLen; i++){ |
| 860 strcat(pattern, uscript_getShortName(scriptCodes[i])); |
| 861 strcat(pattern, ":]"); |
| 862 patternLen = (int32_t)strlen(pattern); |
| 863 u_charsToUChars(pattern, uPattern, patternLen); |
| 864 scripts[i] = uset_openPattern(uPattern, patternLen, &status); |
| 865 if(U_FAILURE(status)){ |
| 866 log_err("Could not create set for pattern %s. Error: %s\n", pattern,
u_errorName(status)); |
| 867 return; |
| 868 } |
| 869 pattern[2] = 0; |
| 870 } |
| 871 if (strcmp(locale, "uk") == 0 || strcmp(locale, "uk_UA") == 0) { |
| 872 /* Special addition. Add the modifying apostrophe, which isn't in Cyrill
ic. */ |
| 873 uset_add(scripts[0], 0x2bc); |
| 874 } |
| 875 if(U_SUCCESS(status)){ |
| 876 UBool existsInScript = FALSE; |
| 877 /* iterate over the exemplarSet and ascertain if all |
| 878 * UChars in exemplarSet belong to the scripts returned |
| 879 * by getScript |
| 880 */ |
| 881 int32_t count = uset_getItemCount(exemplarSet); |
| 882 |
| 883 for( i=0; i < count; i++){ |
| 884 UChar32 start = 0; |
| 885 UChar32 end = 0; |
| 886 UChar *str = NULL; |
| 887 int32_t strCapacity = 0; |
| 888 |
| 889 strCapacity = uset_getItem(exemplarSet, i, &start, &end, str, strCap
acity, &status); |
| 890 if(U_SUCCESS(status)){ |
| 891 int32_t j; |
| 892 if(strCapacity == 0){ |
| 893 /* ok the item is a range */ |
| 894 for( j = 0; j < scriptsLen; j++){ |
| 895 if(uset_containsRange(scripts[j], start, end) == TRUE){ |
| 896 existsInScript = TRUE; |
| 897 } |
| 898 } |
| 899 if(existsInScript == FALSE){ |
| 900 for( j = 0; j < scriptsLen; j++){ |
| 901 UChar toPattern[500]={'\0'}; |
| 902 char pat[500]={'\0'}; |
| 903 int32_t len = uset_toPattern(scripts[j], toPattern,
500, TRUE, &status); |
| 904 len = myUCharsToChars(toPattern, pat, len); |
| 905 log_err("uset_indexOf(\\u%04X)=%i uset_indexOf(\\u%0
4X)=%i\n", start, uset_indexOf(scripts[0], start), end, uset_indexOf(scripts[0],
end)); |
| 906 if(len!=-1){ |
| 907 log_err("Pattern: %s\n",pat); |
| 908 } |
| 909 } |
| 910 log_err("ExemplarCharacters and LocaleScript containment
test failed for locale %s. \n", locale); |
| 911 } |
| 912 }else{ |
| 913 strCapacity++; /* increment for NUL termination */ |
| 914 /* allocate the str and call the api again */ |
| 915 str = (UChar*) malloc(U_SIZEOF_UCHAR * strCapacity); |
| 916 strCapacity = uset_getItem(exemplarSet, i, &start, &end, st
r, strCapacity, &status); |
| 917 /* iterate over the scripts and figure out if the string con
tained is actually |
| 918 * in the script set |
| 919 */ |
| 920 for( j = 0; j < scriptsLen; j++){ |
| 921 if(uset_containsString(scripts[j],str, strCapacity) == T
RUE){ |
| 922 existsInScript = TRUE; |
| 923 } |
| 924 } |
| 925 if(existsInScript == FALSE){ |
| 926 log_err("ExemplarCharacters and LocaleScript containment
test failed for locale %s. \n", locale); |
| 927 } |
| 928 } |
| 929 } |
| 930 } |
| 931 |
| 932 } |
| 933 |
| 934 /* close the sets */ |
| 935 for(i = 0; i<scriptsLen; i++){ |
| 936 uset_close(scripts[i]); |
| 937 } |
| 938 } |
| 939 |
| 940 static void VerifyTranslation(void) { |
| 941 static const UVersionInfo icu47 = { 4, 7, 0, 0 }; |
| 942 UResourceBundle *root, *currentLocale; |
| 943 int32_t locCount = uloc_countAvailable(); |
| 944 int32_t locIndex; |
| 945 UErrorCode errorCode = U_ZERO_ERROR; |
| 946 int32_t exemplarLen; |
| 947 const UChar *exemplarCharacters; |
| 948 const char *currLoc; |
| 949 UScriptCode scripts[USCRIPT_CODE_LIMIT]; |
| 950 int32_t numScripts; |
| 951 int32_t idx; |
| 952 int32_t end; |
| 953 UResourceBundle *resArray; |
| 954 |
| 955 if (locCount <= 1) { |
| 956 log_data_err("At least root needs to be installed\n"); |
| 957 } |
| 958 |
| 959 root = ures_openDirect(NULL, "root", &errorCode); |
| 960 if(U_FAILURE(errorCode)) { |
| 961 log_data_err("Can't open root\n"); |
| 962 return; |
| 963 } |
| 964 for (locIndex = 0; locIndex < locCount; locIndex++) { |
| 965 errorCode=U_ZERO_ERROR; |
| 966 currLoc = uloc_getAvailable(locIndex); |
| 967 currentLocale = ures_open(NULL, currLoc, &errorCode); |
| 968 if(errorCode != U_ZERO_ERROR) { |
| 969 if(U_SUCCESS(errorCode)) { |
| 970 /* It's installed, but there is no data. |
| 971 It's installed for the g18n white paper [grhoten] */ |
| 972 log_err("ERROR: Locale %-5s not installed, and it should be!\n", |
| 973 uloc_getAvailable(locIndex)); |
| 974 } else { |
| 975 log_err("%%%%%%% Unexpected error %d in %s %%%%%%%", |
| 976 u_errorName(errorCode), |
| 977 uloc_getAvailable(locIndex)); |
| 978 } |
| 979 ures_close(currentLocale); |
| 980 continue; |
| 981 } |
| 982 exemplarCharacters = ures_getStringByKey(currentLocale, "ExemplarCharact
ers", &exemplarLen, &errorCode); |
| 983 if (U_FAILURE(errorCode)) { |
| 984 log_err("error ures_getStringByKey returned %s\n", u_errorName(error
Code)); |
| 985 } |
| 986 else if (getTestOption(QUICK_OPTION) && exemplarLen > 2048) { |
| 987 log_verbose("skipping test for %s\n", currLoc); |
| 988 } |
| 989 else if (uprv_strncmp(currLoc,"bem",3) == 0) { |
| 990 log_verbose("skipping test for %s, some month and country names know
n to use aux exemplars\n", currLoc); |
| 991 } |
| 992 else { |
| 993 UChar langBuffer[128]; |
| 994 int32_t langSize; |
| 995 int32_t strIdx; |
| 996 UChar badChar; |
| 997 langSize = uloc_getDisplayLanguage(currLoc, currLoc, langBuffer, siz
eof(langBuffer)/sizeof(langBuffer[0]), &errorCode); |
| 998 if (U_FAILURE(errorCode)) { |
| 999 log_err("error uloc_getDisplayLanguage returned %s\n", u_errorNa
me(errorCode)); |
| 1000 } |
| 1001 else { |
| 1002 strIdx = findStringSetMismatch(currLoc, langBuffer, langSize, ex
emplarCharacters, exemplarLen, FALSE, &badChar); |
| 1003 if (strIdx >= 0) { |
| 1004 log_err("getDisplayLanguage(%s) at index %d returned charact
ers not in the exemplar characters: %04X.\n", |
| 1005 currLoc, strIdx, badChar); |
| 1006 } |
| 1007 } |
| 1008 langSize = uloc_getDisplayCountry(currLoc, currLoc, langBuffer, size
of(langBuffer)/sizeof(langBuffer[0]), &errorCode); |
| 1009 if (U_FAILURE(errorCode)) { |
| 1010 log_err("error uloc_getDisplayCountry returned %s\n", u_errorNam
e(errorCode)); |
| 1011 } |
| 1012 else if (uprv_strstr(currLoc, "ti_") != currLoc || isICUVersionAtLea
st(icu47)) { /* TODO: restore DisplayCountry test for ti_* when cldrbug 3058 is
fixed) */ |
| 1013 strIdx = findStringSetMismatch(currLoc, langBuffer, langSize, exem
plarCharacters, exemplarLen, FALSE, &badChar); |
| 1014 if (strIdx >= 0) { |
| 1015 log_err("getDisplayCountry(%s) at index %d returned characte
rs not in the exemplar characters: %04X.\n", |
| 1016 currLoc, strIdx, badChar); |
| 1017 } |
| 1018 } |
| 1019 { |
| 1020 UResourceBundle* cal = ures_getByKey(currentLocale, "calendar",
NULL, &errorCode); |
| 1021 UResourceBundle* greg = ures_getByKeyWithFallback(cal, "gregoria
n", NULL, &errorCode); |
| 1022 UResourceBundle* names = ures_getByKeyWithFallback(greg, "dayNa
mes", NULL, &errorCode); |
| 1023 UResourceBundle* format = ures_getByKeyWithFallback(names, "for
mat", NULL, &errorCode); |
| 1024 resArray = ures_getByKeyWithFallback(format, "wide", NULL, &err
orCode); |
| 1025 |
| 1026 if (U_FAILURE(errorCode)) { |
| 1027 log_err("error ures_getByKey returned %s\n", u_errorName(err
orCode)); |
| 1028 } |
| 1029 if (getTestOption(QUICK_OPTION)) { |
| 1030 end = 1; |
| 1031 } |
| 1032 else { |
| 1033 end = ures_getSize(resArray); |
| 1034 } |
| 1035 |
| 1036 |
| 1037 for (idx = 0; idx < end; idx++) { |
| 1038 const UChar *fromBundleStr = ures_getStringByIndex(resArray,
idx, &langSize, &errorCode); |
| 1039 if (U_FAILURE(errorCode)) { |
| 1040 log_err("error ures_getStringByIndex(%d) returned %s\n",
idx, u_errorName(errorCode)); |
| 1041 continue; |
| 1042 } |
| 1043 strIdx = findStringSetMismatch(currLoc, fromBundleStr, langS
ize, exemplarCharacters, exemplarLen, TRUE, &badChar); |
| 1044 if (strIdx >= 0) { |
| 1045 log_err("getDayNames(%s, %d) at index %d returned charac
ters not in the exemplar characters: %04X.\n", |
| 1046 currLoc, idx, strIdx, badChar); |
| 1047 } |
| 1048 } |
| 1049 ures_close(resArray); |
| 1050 ures_close(format); |
| 1051 ures_close(names); |
| 1052 |
| 1053 names = ures_getByKeyWithFallback(greg, "monthNames", NULL, &err
orCode); |
| 1054 format = ures_getByKeyWithFallback(names,"format", NULL, &errorC
ode); |
| 1055 resArray = ures_getByKeyWithFallback(format, "wide", NULL, &erro
rCode); |
| 1056 if (U_FAILURE(errorCode)) { |
| 1057 log_err("error ures_getByKey returned %s\n", u_errorName(err
orCode)); |
| 1058 } |
| 1059 if (getTestOption(QUICK_OPTION)) { |
| 1060 end = 1; |
| 1061 } |
| 1062 else { |
| 1063 end = ures_getSize(resArray); |
| 1064 } |
| 1065 |
| 1066 for (idx = 0; idx < end; idx++) { |
| 1067 const UChar *fromBundleStr = ures_getStringByIndex(resArray,
idx, &langSize, &errorCode); |
| 1068 if (U_FAILURE(errorCode)) { |
| 1069 log_err("error ures_getStringByIndex(%d) returned %s\n",
idx, u_errorName(errorCode)); |
| 1070 continue; |
| 1071 } |
| 1072 strIdx = findStringSetMismatch(currLoc, fromBundleStr, langS
ize, exemplarCharacters, exemplarLen, TRUE, &badChar); |
| 1073 if (strIdx >= 0) { |
| 1074 log_err("getMonthNames(%s, %d) at index %d returned char
acters not in the exemplar characters: %04X.\n", |
| 1075 currLoc, idx, strIdx, badChar); |
| 1076 } |
| 1077 } |
| 1078 ures_close(resArray); |
| 1079 ures_close(format); |
| 1080 ures_close(names); |
| 1081 ures_close(greg); |
| 1082 ures_close(cal); |
| 1083 } |
| 1084 errorCode = U_ZERO_ERROR; |
| 1085 numScripts = uscript_getCode(currLoc, scripts, sizeof(scripts)/sizeo
f(scripts[0]), &errorCode); |
| 1086 if (numScripts == 0) { |
| 1087 log_err("uscript_getCode(%s) doesn't work.\n", currLoc); |
| 1088 }else if(scripts[0] == USCRIPT_COMMON){ |
| 1089 log_err("uscript_getCode(%s) returned USCRIPT_COMMON.\n", currLo
c); |
| 1090 } |
| 1091 |
| 1092 /* test that the scripts are a superset of exemplar characters. */ |
| 1093 { |
| 1094 ULocaleData *uld = ulocdata_open(currLoc,&errorCode); |
| 1095 USet *exemplarSet = ulocdata_getExemplarSet(uld, NULL, 0, ULOCD
ATA_ES_STANDARD, &errorCode); |
| 1096 /* test if exemplar characters are part of script code */ |
| 1097 findSetMatch(scripts, numScripts, exemplarSet, currLoc); |
| 1098 uset_close(exemplarSet); |
| 1099 ulocdata_close(uld); |
| 1100 } |
| 1101 |
| 1102 /* test that the paperSize API works */ |
| 1103 { |
| 1104 int32_t height=0, width=0; |
| 1105 ulocdata_getPaperSize(currLoc, &height, &width, &errorCode); |
| 1106 if(U_FAILURE(errorCode)){ |
| 1107 log_err("ulocdata_getPaperSize failed for locale %s with erro
r: %s \n", currLoc, u_errorName(errorCode)); |
| 1108 } |
| 1109 if(strstr(currLoc, "_US")!=NULL && height != 279 && width != 216
){ |
| 1110 log_err("ulocdata_getPaperSize did not return expected data f
or locale %s \n", currLoc); |
| 1111 } |
| 1112 } |
| 1113 /* test that the MeasurementSystem works API works */ |
| 1114 { |
| 1115 UMeasurementSystem measurementSystem = ulocdata_getMeasurementSys
tem(currLoc, &errorCode); |
| 1116 if(U_FAILURE(errorCode)){ |
| 1117 log_err("ulocdata_getMeasurementSystem failed for locale %s w
ith error: %s \n", currLoc, u_errorName(errorCode)); |
| 1118 } |
| 1119 if(strstr(currLoc, "_US")!=NULL || strstr(currLoc, "_MM")!=NULL |
| strstr(currLoc, "_LR")!=NULL){ |
| 1120 if(measurementSystem != UMS_US){ |
| 1121 log_err("ulocdata_getMeasurementSystem did not return ex
pected data for locale %s \n", currLoc); |
| 1122 } |
| 1123 }else if(measurementSystem != UMS_SI){ |
| 1124 log_err("ulocdata_getMeasurementSystem did not return expecte
d data for locale %s \n", currLoc); |
| 1125 } |
| 1126 } |
| 1127 } |
| 1128 ures_close(currentLocale); |
| 1129 } |
| 1130 |
| 1131 ures_close(root); |
| 1132 } |
| 1133 |
| 1134 /* adjust this limit as appropriate */ |
| 1135 #define MAX_SCRIPTS_PER_LOCALE 8 |
| 1136 |
| 1137 static void TestExemplarSet(void){ |
| 1138 int32_t i, j, k, m, n; |
| 1139 int32_t equalCount = 0; |
| 1140 UErrorCode ec = U_ZERO_ERROR; |
| 1141 UEnumeration* avail; |
| 1142 USet* exemplarSets[2]; |
| 1143 USet* unassignedSet; |
| 1144 UScriptCode code[MAX_SCRIPTS_PER_LOCALE]; |
| 1145 USet* codeSets[MAX_SCRIPTS_PER_LOCALE]; |
| 1146 int32_t codeLen; |
| 1147 char cbuf[32]; /* 9 should be enough */ |
| 1148 UChar ubuf[64]; /* adjust as needed */ |
| 1149 UBool existsInScript; |
| 1150 int32_t itemCount; |
| 1151 int32_t strLen; |
| 1152 UChar32 start, end; |
| 1153 |
| 1154 unassignedSet = NULL; |
| 1155 exemplarSets[0] = NULL; |
| 1156 exemplarSets[1] = NULL; |
| 1157 for (i=0; i<MAX_SCRIPTS_PER_LOCALE; ++i) { |
| 1158 codeSets[i] = NULL; |
| 1159 } |
| 1160 |
| 1161 avail = ures_openAvailableLocales(NULL, &ec); |
| 1162 if (!assertSuccess("ures_openAvailableLocales", &ec)) goto END; |
| 1163 n = uenum_count(avail, &ec); |
| 1164 if (!assertSuccess("uenum_count", &ec)) goto END; |
| 1165 |
| 1166 u_uastrcpy(ubuf, "[:unassigned:]"); |
| 1167 unassignedSet = uset_openPattern(ubuf, -1, &ec); |
| 1168 if (!assertSuccess("uset_openPattern", &ec)) goto END; |
| 1169 |
| 1170 for(i=0; i<n; i++){ |
| 1171 const char* locale = uenum_next(avail, NULL, &ec); |
| 1172 if (!assertSuccess("uenum_next", &ec)) goto END; |
| 1173 log_verbose("%s\n", locale); |
| 1174 for (k=0; k<2; ++k) { |
| 1175 uint32_t option = (k==0) ? 0 : USET_CASE_INSENSITIVE; |
| 1176 ULocaleData *uld = ulocdata_open(locale,&ec); |
| 1177 USet* exemplarSet = ulocdata_getExemplarSet(uld,NULL, option, ULOCDA
TA_ES_STANDARD, &ec); |
| 1178 uset_close(exemplarSets[k]); |
| 1179 ulocdata_close(uld); |
| 1180 exemplarSets[k] = exemplarSet; |
| 1181 if (!assertSuccess("ulocaledata_getExemplarSet", &ec)) goto END; |
| 1182 |
| 1183 if (uset_containsSome(exemplarSet, unassignedSet)) { |
| 1184 log_err("ExemplarSet contains unassigned characters for locale :
%s\n", locale); |
| 1185 } |
| 1186 codeLen = uscript_getCode(locale, code, 8, &ec); |
| 1187 if (!assertSuccess("uscript_getCode", &ec)) goto END; |
| 1188 |
| 1189 for (j=0; j<MAX_SCRIPTS_PER_LOCALE; ++j) { |
| 1190 uset_close(codeSets[j]); |
| 1191 codeSets[j] = NULL; |
| 1192 } |
| 1193 for (j=0; j<codeLen; ++j) { |
| 1194 uprv_strcpy(cbuf, "[:"); |
| 1195 if(code[j]==-1){ |
| 1196 log_err("USCRIPT_INVALID_CODE returned for locale: %s\n", lo
cale); |
| 1197 continue; |
| 1198 } |
| 1199 uprv_strcat(cbuf, uscript_getShortName(code[j])); |
| 1200 uprv_strcat(cbuf, ":]"); |
| 1201 u_uastrcpy(ubuf, cbuf); |
| 1202 codeSets[j] = uset_openPattern(ubuf, -1, &ec); |
| 1203 } |
| 1204 if (!assertSuccess("uset_openPattern", &ec)) goto END; |
| 1205 |
| 1206 existsInScript = FALSE; |
| 1207 itemCount = uset_getItemCount(exemplarSet); |
| 1208 for (m=0; m<itemCount && !existsInScript; ++m) { |
| 1209 strLen = uset_getItem(exemplarSet, m, &start, &end, ubuf, |
| 1210 sizeof(ubuf)/sizeof(ubuf[0]), &ec); |
| 1211 /* failure here might mean str[] needs to be larger */ |
| 1212 if (!assertSuccess("uset_getItem", &ec)) goto END; |
| 1213 if (strLen == 0) { |
| 1214 for (j=0; j<codeLen; ++j) { |
| 1215 if (codeSets[j]!=NULL && uset_containsRange(codeSets[j],
start, end)) { |
| 1216 existsInScript = TRUE; |
| 1217 break; |
| 1218 } |
| 1219 } |
| 1220 } else { |
| 1221 for (j=0; j<codeLen; ++j) { |
| 1222 if (codeSets[j]!=NULL && uset_containsString(codeSets[j]
, ubuf, strLen)) { |
| 1223 existsInScript = TRUE; |
| 1224 break; |
| 1225 } |
| 1226 } |
| 1227 } |
| 1228 } |
| 1229 |
| 1230 if (existsInScript == FALSE){ |
| 1231 log_err("ExemplarSet containment failed for locale : %s\n", loca
le); |
| 1232 } |
| 1233 } |
| 1234 assertTrue("case-folded is a superset", |
| 1235 uset_containsAll(exemplarSets[1], exemplarSets[0])); |
| 1236 if (uset_equals(exemplarSets[1], exemplarSets[0])) { |
| 1237 ++equalCount; |
| 1238 } |
| 1239 } |
| 1240 /* Note: The case-folded set should sometimes be a strict superset |
| 1241 and sometimes be equal. */ |
| 1242 assertTrue("case-folded is sometimes a strict superset, and sometimes equal"
, |
| 1243 equalCount > 0 && equalCount < n); |
| 1244 |
| 1245 END: |
| 1246 uenum_close(avail); |
| 1247 uset_close(exemplarSets[0]); |
| 1248 uset_close(exemplarSets[1]); |
| 1249 uset_close(unassignedSet); |
| 1250 for (i=0; i<MAX_SCRIPTS_PER_LOCALE; ++i) { |
| 1251 uset_close(codeSets[i]); |
| 1252 } |
| 1253 } |
| 1254 |
| 1255 static void TestLocaleDisplayPattern(void){ |
| 1256 UErrorCode status = U_ZERO_ERROR; |
| 1257 UChar pattern[32] = {0,}; |
| 1258 UChar separator[32] = {0,}; |
| 1259 ULocaleData *uld = ulocdata_open(uloc_getDefault(), &status); |
| 1260 |
| 1261 if(U_FAILURE(status)){ |
| 1262 log_data_err("ulocdata_open error"); |
| 1263 return; |
| 1264 } |
| 1265 ulocdata_getLocaleDisplayPattern(uld, pattern, 32, &status); |
| 1266 if (U_FAILURE(status)){ |
| 1267 log_err("ulocdata_getLocaleDisplayPattern error!"); |
| 1268 } |
| 1269 status = U_ZERO_ERROR; |
| 1270 ulocdata_getLocaleSeparator(uld, separator, 32, &status); |
| 1271 if (U_FAILURE(status)){ |
| 1272 log_err("ulocdata_getLocaleSeparator error!"); |
| 1273 } |
| 1274 ulocdata_close(uld); |
| 1275 } |
| 1276 |
| 1277 static void TestCoverage(void){ |
| 1278 ULocaleDataDelimiterType types[] = { |
| 1279 ULOCDATA_QUOTATION_START, /* Quotation start */ |
| 1280 ULOCDATA_QUOTATION_END, /* Quotation end */ |
| 1281 ULOCDATA_ALT_QUOTATION_START, /* Alternate quotation start */ |
| 1282 ULOCDATA_ALT_QUOTATION_END, /* Alternate quotation end */ |
| 1283 ULOCDATA_DELIMITER_COUNT |
| 1284 }; |
| 1285 int i; |
| 1286 UBool sub; |
| 1287 UErrorCode status = U_ZERO_ERROR; |
| 1288 ULocaleData *uld = ulocdata_open(uloc_getDefault(), &status); |
| 1289 |
| 1290 if(U_FAILURE(status)){ |
| 1291 log_data_err("ulocdata_open error"); |
| 1292 return; |
| 1293 } |
| 1294 |
| 1295 |
| 1296 for(i = 0; i < ULOCDATA_DELIMITER_COUNT; i++){ |
| 1297 UChar result[32] = {0,}; |
| 1298 status = U_ZERO_ERROR; |
| 1299 ulocdata_getDelimiter(uld, types[i], result, 32, &status); |
| 1300 if (U_FAILURE(status)){ |
| 1301 log_err("ulocdata_getgetDelimiter error with type %d", types[i]); |
| 1302 } |
| 1303 } |
| 1304 |
| 1305 sub = ulocdata_getNoSubstitute(uld); |
| 1306 ulocdata_setNoSubstitute(uld,sub); |
| 1307 ulocdata_close(uld); |
| 1308 } |
| 1309 |
| 1310 static void TestCurrencyList(void){ |
| 1311 #if !UCONFIG_NO_FORMATTING |
| 1312 UErrorCode errorCode = U_ZERO_ERROR; |
| 1313 int32_t structLocaleCount, currencyCount; |
| 1314 UEnumeration *en = ucurr_openISOCurrencies(UCURR_ALL, &errorCode); |
| 1315 const char *isoCode, *structISOCode; |
| 1316 UResourceBundle *subBundle; |
| 1317 UResourceBundle *currencies = ures_openDirect(loadTestData(&errorCode), "str
uctLocale", &errorCode); |
| 1318 if(U_FAILURE(errorCode)) { |
| 1319 log_data_err("Can't open structLocale\n"); |
| 1320 return; |
| 1321 } |
| 1322 currencies = ures_getByKey(currencies, "Currencies", currencies, &errorCode)
; |
| 1323 currencyCount = uenum_count(en, &errorCode); |
| 1324 structLocaleCount = ures_getSize(currencies); |
| 1325 if (currencyCount != structLocaleCount) { |
| 1326 log_err("structLocale(%d) and ISO4217(%d) currency list are out of sync.
\n", structLocaleCount, currencyCount); |
| 1327 #if U_CHARSET_FAMILY == U_ASCII_FAMILY |
| 1328 ures_resetIterator(currencies); |
| 1329 while ((isoCode = uenum_next(en, NULL, &errorCode)) != NULL && ures_hasN
ext(currencies)) { |
| 1330 subBundle = ures_getNextResource(currencies, NULL, &errorCode); |
| 1331 structISOCode = ures_getKey(subBundle); |
| 1332 ures_close(subBundle); |
| 1333 if (strcmp(structISOCode, isoCode) != 0) { |
| 1334 log_err("First difference found at structLocale(%s) and ISO4217(
%s).\n", structISOCode, isoCode); |
| 1335 break; |
| 1336 } |
| 1337 } |
| 1338 #endif |
| 1339 } |
| 1340 ures_close(currencies); |
| 1341 uenum_close(en); |
| 1342 #endif |
| 1343 } |
| 1344 |
| 1345 #define TESTCASE(name) addTest(root, &name, "tsutil/cldrtest/" #name) |
| 1346 |
| 1347 void addCLDRTest(TestNode** root); |
| 1348 |
| 1349 void addCLDRTest(TestNode** root) |
| 1350 { |
| 1351 #if !UCONFIG_NO_FILE_IO && !UCONFIG_NO_LEGACY_CONVERSION |
| 1352 TESTCASE(TestLocaleStructure); |
| 1353 TESTCASE(TestCurrencyList); |
| 1354 #endif |
| 1355 TESTCASE(TestConsistentCountryInfo); |
| 1356 TESTCASE(VerifyTranslation); |
| 1357 TESTCASE(TestExemplarSet); |
| 1358 TESTCASE(TestLocaleDisplayPattern); |
| 1359 TESTCASE(TestCoverage); |
| 1360 } |
OLD | NEW |