]>
Commit | Line | Data |
---|---|---|
374ca955 A |
1 | /******************************************************************** |
2 | * COPYRIGHT: | |
57a6839d | 3 | * Copyright (c) 1997-2014, International Business Machines Corporation and |
374ca955 A |
4 | * others. All Rights Reserved. |
5 | ********************************************************************/ | |
6 | ||
7 | #include "cintltst.h" | |
8 | #include "unicode/ures.h" | |
73c04bcf | 9 | #include "unicode/ucurr.h" |
374ca955 A |
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 | ||
73c04bcf A |
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, | |
729e4ab9 | 40 | &start, &end, |
73c04bcf A |
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 | } | |
4388f060 | 54 | uset_closeOver(newSet,USET_CASE_INSENSITIVE); |
73c04bcf A |
55 | return newSet; |
56 | } | |
4388f060 | 57 | |
729e4ab9 | 58 | static UBool |
73c04bcf | 59 | isCurrencyPreEuro(const char* currencyKey){ |
374ca955 A |
60 | if( strcmp(currencyKey, "PTE") == 0 || |
61 | strcmp(currencyKey, "ESP") == 0 || | |
62 | strcmp(currencyKey, "LUF") == 0 || | |
63 | strcmp(currencyKey, "GRD") == 0 || | |
64 | strcmp(currencyKey, "BEF") == 0 || | |
73c04bcf A |
65 | strcmp(currencyKey, "ITL") == 0 || |
66 | strcmp(currencyKey, "EEK") == 0){ | |
374ca955 A |
67 | return TRUE; |
68 | } | |
69 | return FALSE; | |
70 | } | |
51004dcb | 71 | #if !UCONFIG_NO_FILE_IO && !UCONFIG_NO_LEGACY_CONVERSION |
374ca955 A |
72 | static void |
73 | TestKeyInRootRecursive(UResourceBundle *root, const char *rootName, | |
74 | UResourceBundle *currentBundle, const char *locale) { | |
75 | UErrorCode errorCode = U_ZERO_ERROR; | |
729e4ab9 | 76 | UResourceBundle *subRootBundle = NULL, *subBundle = NULL, *arr = NULL; |
374ca955 A |
77 | |
78 | ures_resetIterator(root); | |
79 | ures_resetIterator(currentBundle); | |
80 | while (ures_hasNext(currentBundle)) { | |
81 | const char *subBundleKey = NULL; | |
82 | const char *currentBundleKey = NULL; | |
83 | ||
84 | errorCode = U_ZERO_ERROR; | |
85 | currentBundleKey = ures_getKey(currentBundle); | |
57a6839d | 86 | (void)currentBundleKey; /* Suppress set but not used warning. */ |
374ca955 A |
87 | subBundle = ures_getNextResource(currentBundle, NULL, &errorCode); |
88 | if (U_FAILURE(errorCode)) { | |
729e4ab9 | 89 | log_err("Can't open a resource for lnocale %s. Error: %s\n", locale, u_errorName(errorCode)); |
374ca955 A |
90 | continue; |
91 | } | |
92 | subBundleKey = ures_getKey(subBundle); | |
729e4ab9 | 93 | |
374ca955 A |
94 | |
95 | subRootBundle = ures_getByKey(root, subBundleKey, NULL, &errorCode); | |
96 | if (U_FAILURE(errorCode)) { | |
97 | log_err("Can't open a resource with key \"%s\" in \"%s\" from %s for locale \"%s\"\n", | |
98 | subBundleKey, | |
99 | ures_getKey(currentBundle), | |
100 | rootName, | |
101 | locale); | |
102 | ures_close(subBundle); | |
103 | continue; | |
104 | } | |
105 | if (ures_getType(subRootBundle) != ures_getType(subBundle)) { | |
106 | log_err("key \"%s\" in \"%s\" has a different type from root for locale \"%s\"\n" | |
107 | "\troot=%d, locale=%d\n", | |
108 | subBundleKey, | |
109 | ures_getKey(currentBundle), | |
110 | locale, | |
111 | ures_getType(subRootBundle), | |
112 | ures_getType(subBundle)); | |
46f4442e | 113 | ures_close(subBundle); |
374ca955 A |
114 | continue; |
115 | } | |
116 | else if (ures_getType(subBundle) == URES_INT_VECTOR) { | |
117 | int32_t minSize; | |
118 | int32_t subBundleSize; | |
119 | int32_t idx; | |
120 | UBool sameArray = TRUE; | |
121 | const int32_t *subRootBundleArr = ures_getIntVector(subRootBundle, &minSize, &errorCode); | |
122 | const int32_t *subBundleArr = ures_getIntVector(subBundle, &subBundleSize, &errorCode); | |
123 | ||
124 | if (minSize > subBundleSize) { | |
125 | minSize = subBundleSize; | |
126 | log_err("Arrays are different size with key \"%s\" in \"%s\" from root for locale \"%s\"\n", | |
127 | subBundleKey, | |
128 | ures_getKey(currentBundle), | |
129 | locale); | |
130 | } | |
131 | ||
132 | for (idx = 0; idx < minSize && sameArray; idx++) { | |
133 | if (subRootBundleArr[idx] != subBundleArr[idx]) { | |
134 | sameArray = FALSE; | |
135 | } | |
136 | if (strcmp(subBundleKey, "DateTimeElements") == 0 | |
137 | && (subBundleArr[idx] < 1 || 7 < subBundleArr[idx])) | |
138 | { | |
139 | log_err("Value out of range with key \"%s\" at index %d in \"%s\" for locale \"%s\"\n", | |
140 | subBundleKey, | |
141 | idx, | |
142 | ures_getKey(currentBundle), | |
143 | locale); | |
144 | } | |
145 | } | |
146 | /* Special exception es_US and DateTimeElements */ | |
147 | if (sameArray | |
148 | && !(strcmp(locale, "es_US") == 0 && strcmp(subBundleKey, "DateTimeElements") == 0)) | |
149 | { | |
150 | log_err("Integer vectors are the same with key \"%s\" in \"%s\" from root for locale \"%s\"\n", | |
151 | subBundleKey, | |
152 | ures_getKey(currentBundle), | |
153 | locale); | |
154 | } | |
155 | } | |
156 | else if (ures_getType(subBundle) == URES_ARRAY) { | |
157 | UResourceBundle *subSubBundle = ures_getByIndex(subBundle, 0, NULL, &errorCode); | |
158 | UResourceBundle *subSubRootBundle = ures_getByIndex(subRootBundle, 0, NULL, &errorCode); | |
159 | ||
160 | if (U_SUCCESS(errorCode) | |
161 | && (ures_getType(subSubBundle) == URES_ARRAY || ures_getType(subSubRootBundle) == URES_ARRAY)) | |
162 | { | |
73c04bcf A |
163 | /* Here is one of the recursive parts */ |
164 | TestKeyInRootRecursive(subRootBundle, rootName, subBundle, locale); | |
374ca955 A |
165 | } |
166 | else { | |
167 | int32_t minSize = ures_getSize(subRootBundle); | |
168 | int32_t idx; | |
169 | UBool sameArray = TRUE; | |
170 | ||
171 | if (minSize > ures_getSize(subBundle)) { | |
172 | minSize = ures_getSize(subBundle); | |
173 | } | |
174 | ||
175 | if ((subBundleKey == NULL | |
176 | || (subBundleKey != NULL && strcmp(subBundleKey, "LocaleScript") != 0 && !isCurrencyPreEuro(subBundleKey))) | |
177 | && ures_getSize(subRootBundle) != ures_getSize(subBundle)) | |
178 | { | |
179 | log_err("Different size array with key \"%s\" in \"%s\" from root for locale \"%s\"\n" | |
180 | "\troot array size=%d, locale array size=%d\n", | |
181 | subBundleKey, | |
182 | ures_getKey(currentBundle), | |
183 | locale, | |
184 | ures_getSize(subRootBundle), | |
185 | ures_getSize(subBundle)); | |
186 | } | |
187 | /* | |
188 | if(isCurrencyPreEuro(subBundleKey) && ures_getSize(subBundle)!=3){ | |
189 | log_err("Different size array with key \"%s\" in \"%s\" for locale \"%s\" the expected size is 3 got size=%d\n", | |
190 | subBundleKey, | |
191 | ures_getKey(currentBundle), | |
192 | locale, | |
193 | ures_getSize(subBundle)); | |
194 | } | |
195 | */ | |
196 | for (idx = 0; idx < minSize; idx++) { | |
197 | int32_t rootStrLen, localeStrLen; | |
198 | const UChar *rootStr = ures_getStringByIndex(subRootBundle,idx,&rootStrLen,&errorCode); | |
199 | const UChar *localeStr = ures_getStringByIndex(subBundle,idx,&localeStrLen,&errorCode); | |
200 | if (rootStr && localeStr && U_SUCCESS(errorCode)) { | |
201 | if (u_strcmp(rootStr, localeStr) != 0) { | |
202 | sameArray = FALSE; | |
203 | } | |
204 | } | |
205 | else { | |
729e4ab9 A |
206 | if ( rootStrLen > 1 && rootStr[0] == 0x41 && rootStr[1] >= 0x30 && rootStr[1] <= 0x39 ) { |
207 | /* A2 or A4 in the root string indicates that the resource can optionally be an array instead of a */ | |
208 | /* string. Attempt to read it as an array. */ | |
209 | errorCode = U_ZERO_ERROR; | |
210 | arr = ures_getByIndex(subBundle,idx,NULL,&errorCode); | |
211 | if (U_FAILURE(errorCode)) { | |
212 | log_err("Got a NULL string with key \"%s\" in \"%s\" at index %d for root or locale \"%s\"\n", | |
213 | subBundleKey, | |
214 | ures_getKey(currentBundle), | |
215 | idx, | |
216 | locale); | |
217 | continue; | |
218 | } | |
219 | if (ures_getType(arr) != URES_ARRAY || ures_getSize(arr) != (int32_t)rootStr[1] - 0x30) { | |
220 | log_err("Got something other than a string or array of size %d for key \"%s\" in \"%s\" at index %d for root or locale \"%s\"\n", | |
221 | rootStr[1] - 0x30, | |
222 | subBundleKey, | |
223 | ures_getKey(currentBundle), | |
224 | idx, | |
225 | locale); | |
226 | ures_close(arr); | |
227 | continue; | |
228 | } | |
229 | localeStr = ures_getStringByIndex(arr,0,&localeStrLen,&errorCode); | |
230 | ures_close(arr); | |
231 | if (U_FAILURE(errorCode)) { | |
232 | log_err("Got something other than a string or array for key \"%s\" in \"%s\" at index %d for root or locale \"%s\"\n", | |
233 | subBundleKey, | |
234 | ures_getKey(currentBundle), | |
235 | idx, | |
236 | locale); | |
237 | continue; | |
238 | } | |
239 | } else { | |
240 | log_err("Got a NULL string with key \"%s\" in \"%s\" at index %d for root or locale \"%s\"\n", | |
374ca955 A |
241 | subBundleKey, |
242 | ures_getKey(currentBundle), | |
243 | idx, | |
244 | locale); | |
729e4ab9 A |
245 | continue; |
246 | } | |
374ca955 A |
247 | } |
248 | if (localeStr[0] == (UChar)0x20) { | |
249 | log_err("key \"%s\" at index %d in \"%s\" starts with a space in locale \"%s\"\n", | |
250 | subBundleKey, | |
251 | idx, | |
252 | ures_getKey(currentBundle), | |
253 | locale); | |
254 | } | |
46f4442e | 255 | else if ((localeStr[localeStrLen - 1] == (UChar)0x20) && (strcmp(subBundleKey,"separator") != 0)) { |
374ca955 A |
256 | log_err("key \"%s\" at index %d in \"%s\" ends with a space in locale \"%s\"\n", |
257 | subBundleKey, | |
258 | idx, | |
259 | ures_getKey(currentBundle), | |
260 | locale); | |
261 | } | |
262 | else if (subBundleKey != NULL | |
263 | && strcmp(subBundleKey, "DateTimePatterns") == 0) | |
264 | { | |
265 | int32_t quoted = 0; | |
266 | const UChar *localeStrItr = localeStr; | |
267 | while (*localeStrItr) { | |
268 | if (*localeStrItr == (UChar)0x27 /* ' */) { | |
269 | quoted++; | |
270 | } | |
271 | else if ((quoted % 2) == 0) { | |
272 | /* Search for unquoted characters */ | |
273 | if (4 <= idx && idx <= 7 | |
274 | && (*localeStrItr == (UChar)0x6B /* k */ | |
275 | || *localeStrItr == (UChar)0x48 /* H */ | |
276 | || *localeStrItr == (UChar)0x6D /* m */ | |
277 | || *localeStrItr == (UChar)0x73 /* s */ | |
278 | || *localeStrItr == (UChar)0x53 /* S */ | |
279 | || *localeStrItr == (UChar)0x61 /* a */ | |
280 | || *localeStrItr == (UChar)0x68 /* h */ | |
281 | || *localeStrItr == (UChar)0x7A /* z */)) | |
282 | { | |
283 | log_err("key \"%s\" at index %d has time pattern chars in date for locale \"%s\"\n", | |
284 | subBundleKey, | |
285 | idx, | |
286 | locale); | |
287 | } | |
288 | else if (0 <= idx && idx <= 3 | |
289 | && (*localeStrItr == (UChar)0x47 /* G */ | |
290 | || *localeStrItr == (UChar)0x79 /* y */ | |
291 | || *localeStrItr == (UChar)0x4D /* M */ | |
292 | || *localeStrItr == (UChar)0x64 /* d */ | |
293 | || *localeStrItr == (UChar)0x45 /* E */ | |
294 | || *localeStrItr == (UChar)0x44 /* D */ | |
295 | || *localeStrItr == (UChar)0x46 /* F */ | |
296 | || *localeStrItr == (UChar)0x77 /* w */ | |
297 | || *localeStrItr == (UChar)0x57 /* W */)) | |
298 | { | |
299 | log_err("key \"%s\" at index %d has date pattern chars in time for locale \"%s\"\n", | |
300 | subBundleKey, | |
301 | idx, | |
302 | locale); | |
303 | } | |
304 | } | |
305 | localeStrItr++; | |
306 | } | |
307 | } | |
308 | else if (idx == 4 && subBundleKey != NULL | |
309 | && strcmp(subBundleKey, "NumberElements") == 0 | |
310 | && u_charDigitValue(localeStr[0]) != 0) | |
311 | { | |
312 | log_err("key \"%s\" at index %d has a non-zero based number for locale \"%s\"\n", | |
313 | subBundleKey, | |
314 | idx, | |
315 | locale); | |
316 | } | |
317 | } | |
57a6839d | 318 | (void)sameArray; /* Suppress set but not used warning. */ |
374ca955 A |
319 | /* if (sameArray && strcmp(rootName, "root") == 0) { |
320 | log_err("Arrays are the same with key \"%s\" in \"%s\" from root for locale \"%s\"\n", | |
321 | subBundleKey, | |
322 | ures_getKey(currentBundle), | |
323 | locale); | |
324 | }*/ | |
325 | } | |
326 | ures_close(subSubBundle); | |
327 | ures_close(subSubRootBundle); | |
328 | } | |
329 | else if (ures_getType(subBundle) == URES_STRING) { | |
330 | int32_t len = 0; | |
331 | const UChar *string = ures_getString(subBundle, &len, &errorCode); | |
332 | if (U_FAILURE(errorCode) || string == NULL) { | |
333 | log_err("Can't open a string with key \"%s\" in \"%s\" for locale \"%s\"\n", | |
334 | subBundleKey, | |
335 | ures_getKey(currentBundle), | |
336 | locale); | |
337 | } else if (string[0] == (UChar)0x20) { | |
338 | log_err("key \"%s\" in \"%s\" starts with a space in locale \"%s\"\n", | |
339 | subBundleKey, | |
340 | ures_getKey(currentBundle), | |
341 | locale); | |
46f4442e A |
342 | /* localeDisplayPattern/separator can end with a space */ |
343 | } else if (string[len - 1] == (UChar)0x20 && (strcmp(subBundleKey,"separator"))) { | |
374ca955 A |
344 | log_err("key \"%s\" in \"%s\" ends with a space in locale \"%s\"\n", |
345 | subBundleKey, | |
346 | ures_getKey(currentBundle), | |
347 | locale); | |
46f4442e A |
348 | } else if (strcmp(subBundleKey, "localPatternChars") == 0) { |
349 | /* Note: We no longer import localPatternChars data starting | |
350 | * ICU 3.8. So it never comes into this else if block. (ticket#5597) | |
351 | */ | |
352 | ||
374ca955 A |
353 | /* Check well-formedness of localPatternChars. First, the |
354 | * length must match the number of fields defined by | |
355 | * DateFormat. Second, each character in the string must | |
356 | * be in the set [A-Za-z]. Finally, each character must be | |
357 | * unique. | |
358 | */ | |
359 | int32_t i,j; | |
360 | #if !UCONFIG_NO_FORMATTING | |
361 | if (len != UDAT_FIELD_COUNT) { | |
362 | log_err("key \"%s\" has the wrong number of characters in locale \"%s\"\n", | |
363 | subBundleKey, | |
364 | locale); | |
365 | } | |
366 | #endif | |
367 | /* Check char validity. */ | |
368 | for (i=0; i<len; ++i) { | |
369 | if (!((string[i] >= 65/*'A'*/ && string[i] <= 90/*'Z'*/) || | |
370 | (string[i] >= 97/*'a'*/ && string[i] <= 122/*'z'*/))) { | |
371 | log_err("key \"%s\" has illegal character '%c' in locale \"%s\"\n", | |
372 | subBundleKey, | |
373 | (char) string[i], | |
374 | locale); | |
375 | } | |
376 | /* Do O(n^2) check for duplicate chars. */ | |
377 | for (j=0; j<i; ++j) { | |
378 | if (string[j] == string[i]) { | |
379 | log_err("key \"%s\" has duplicate character '%c' in locale \"%s\"\n", | |
380 | subBundleKey, | |
381 | (char) string[i], | |
382 | locale); | |
383 | } | |
384 | } | |
385 | } | |
386 | } | |
387 | /* No fallback was done. Check for duplicate data */ | |
388 | /* The ures_* API does not do fallback of sub-resource bundles, | |
389 | So we can't do this now. */ | |
390 | #if 0 | |
391 | else if (strcmp(locale, "root") != 0 && errorCode == U_ZERO_ERROR) { | |
392 | ||
393 | const UChar *rootString = ures_getString(subRootBundle, &len, &errorCode); | |
394 | if (U_FAILURE(errorCode) || rootString == NULL) { | |
395 | log_err("Can't open a string with key \"%s\" in \"%s\" in root\n", | |
396 | ures_getKey(subRootBundle), | |
397 | ures_getKey(currentBundle)); | |
398 | continue; | |
399 | } else if (u_strcmp(string, rootString) == 0) { | |
729e4ab9 | 400 | if (strcmp(locale, "de_CH") != 0 && strcmp(subBundleKey, "Countries") != 0 && |
374ca955 A |
401 | strcmp(subBundleKey, "Version") != 0) { |
402 | log_err("Found duplicate data with key \"%s\" in \"%s\" in locale \"%s\"\n", | |
403 | ures_getKey(subRootBundle), | |
404 | ures_getKey(currentBundle), | |
405 | locale); | |
406 | } | |
407 | else { | |
408 | /* Ignore for now. */ | |
409 | /* Can be fixed if fallback through de locale was done. */ | |
410 | log_verbose("Skipping key %s in %s\n", subBundleKey, locale); | |
411 | } | |
412 | } | |
413 | } | |
414 | #endif | |
415 | } | |
416 | else if (ures_getType(subBundle) == URES_TABLE) { | |
73c04bcf A |
417 | if (strcmp(subBundleKey, "availableFormats")!=0) { |
418 | /* Here is one of the recursive parts */ | |
419 | TestKeyInRootRecursive(subRootBundle, rootName, subBundle, locale); | |
420 | } | |
421 | else { | |
422 | log_verbose("Skipping key %s in %s\n", subBundleKey, locale); | |
423 | } | |
374ca955 A |
424 | } |
425 | else if (ures_getType(subBundle) == URES_BINARY || ures_getType(subBundle) == URES_INT) { | |
426 | /* Can't do anything to check it */ | |
427 | /* We'll assume it's all correct */ | |
428 | if (strcmp(subBundleKey, "MeasurementSystem") != 0) { | |
429 | log_verbose("Skipping key \"%s\" in \"%s\" for locale \"%s\"\n", | |
430 | subBundleKey, | |
431 | ures_getKey(currentBundle), | |
432 | locale); | |
433 | } | |
434 | /* Testing for MeasurementSystem is done in VerifyTranslation */ | |
435 | } | |
436 | else { | |
437 | log_err("Type %d for key \"%s\" in \"%s\" is unknown for locale \"%s\"\n", | |
438 | ures_getType(subBundle), | |
439 | subBundleKey, | |
440 | ures_getKey(currentBundle), | |
441 | locale); | |
442 | } | |
443 | ures_close(subRootBundle); | |
444 | ures_close(subBundle); | |
445 | } | |
446 | } | |
51004dcb | 447 | #endif |
374ca955 A |
448 | |
449 | static void | |
450 | testLCID(UResourceBundle *currentBundle, | |
451 | const char *localeName) | |
452 | { | |
453 | UErrorCode status = U_ZERO_ERROR; | |
454 | uint32_t expectedLCID; | |
455 | char lcidStringC[64] = {0}; | |
57a6839d | 456 | int32_t len; |
374ca955 A |
457 | |
458 | expectedLCID = uloc_getLCID(localeName); | |
459 | if (expectedLCID == 0) { | |
460 | log_verbose("INFO: %-5s does not have any LCID mapping\n", | |
461 | localeName); | |
462 | return; | |
463 | } | |
464 | ||
465 | status = U_ZERO_ERROR; | |
57a6839d | 466 | len = uprv_convertToPosix(expectedLCID, lcidStringC, sizeof(lcidStringC)/sizeof(lcidStringC[0]) - 1, &status); |
374ca955 A |
467 | if (U_FAILURE(status)) { |
468 | log_err("ERROR: %.4x does not have a POSIX mapping due to %s\n", | |
469 | expectedLCID, u_errorName(status)); | |
470 | } | |
57a6839d | 471 | lcidStringC[len] = 0; |
374ca955 A |
472 | |
473 | if(strcmp(localeName, lcidStringC) != 0) { | |
474 | char langName[1024]; | |
475 | char langLCID[1024]; | |
476 | uloc_getLanguage(localeName, langName, sizeof(langName), &status); | |
477 | uloc_getLanguage(lcidStringC, langLCID, sizeof(langLCID), &status); | |
478 | ||
479 | if (strcmp(langName, langLCID) == 0) { | |
480 | log_verbose("WARNING: %-5s resolves to %s (0x%.4x)\n", | |
481 | localeName, lcidStringC, expectedLCID); | |
482 | } | |
483 | else { | |
484 | log_err("ERROR: %-5s has 0x%.4x and the number resolves wrongfully to %s\n", | |
485 | localeName, expectedLCID, lcidStringC); | |
486 | } | |
487 | } | |
488 | } | |
489 | ||
51004dcb | 490 | #if !UCONFIG_NO_FILE_IO && !UCONFIG_NO_LEGACY_CONVERSION |
374ca955 A |
491 | static void |
492 | TestLocaleStructure(void) { | |
57a6839d A |
493 | // This test checks the locale structure against a key file located |
494 | // at source/test/testdata/structLocale.txt. When adding new data to | |
b331163b | 495 | // a locale file such as en.txt, the structLocale.txt file must be changed |
57a6839d A |
496 | // too to include the the template of the new data. Otherwise this test |
497 | // will fail! | |
498 | ||
374ca955 A |
499 | UResourceBundle *root, *currentLocale; |
500 | int32_t locCount = uloc_countAvailable(); | |
501 | int32_t locIndex; | |
502 | UErrorCode errorCode = U_ZERO_ERROR; | |
73c04bcf | 503 | const char *currLoc, *resolvedLoc; |
374ca955 A |
504 | |
505 | /* TODO: Compare against parent's data too. This code can't handle fallbacks that some tools do already. */ | |
506 | /* char locName[ULOC_FULLNAME_CAPACITY]; | |
507 | char *locNamePtr; | |
508 | ||
509 | for (locIndex = 0; locIndex < locCount; locIndex++) { | |
510 | errorCode=U_ZERO_ERROR; | |
511 | strcpy(locName, uloc_getAvailable(locIndex)); | |
512 | locNamePtr = strrchr(locName, '_'); | |
513 | if (locNamePtr) { | |
514 | *locNamePtr = 0; | |
515 | } | |
516 | else { | |
517 | strcpy(locName, "root"); | |
518 | } | |
519 | ||
520 | root = ures_openDirect(NULL, locName, &errorCode); | |
521 | if(U_FAILURE(errorCode)) { | |
522 | log_err("Can't open %s\n", locName); | |
523 | continue; | |
524 | } | |
525 | */ | |
526 | if (locCount <= 1) { | |
527 | log_data_err("At least root needs to be installed\n"); | |
528 | } | |
529 | ||
530 | root = ures_openDirect(loadTestData(&errorCode), "structLocale", &errorCode); | |
531 | if(U_FAILURE(errorCode)) { | |
532 | log_data_err("Can't open structLocale\n"); | |
533 | return; | |
534 | } | |
535 | for (locIndex = 0; locIndex < locCount; locIndex++) { | |
536 | errorCode=U_ZERO_ERROR; | |
537 | currLoc = uloc_getAvailable(locIndex); | |
538 | currentLocale = ures_open(NULL, currLoc, &errorCode); | |
539 | if(errorCode != U_ZERO_ERROR) { | |
540 | if(U_SUCCESS(errorCode)) { | |
541 | /* It's installed, but there is no data. | |
542 | It's installed for the g18n white paper [grhoten] */ | |
729e4ab9 A |
543 | log_err("ERROR: Locale %-5s not installed, and it should be, err %s\n", |
544 | uloc_getAvailable(locIndex), u_errorName(errorCode)); | |
374ca955 A |
545 | } else { |
546 | log_err("%%%%%%% Unexpected error %d in %s %%%%%%%", | |
547 | u_errorName(errorCode), | |
548 | uloc_getAvailable(locIndex)); | |
549 | } | |
550 | ures_close(currentLocale); | |
551 | continue; | |
552 | } | |
553 | ures_getStringByKey(currentLocale, "Version", NULL, &errorCode); | |
554 | if(errorCode != U_ZERO_ERROR) { | |
555 | log_err("No version information is available for locale %s, and it should be!\n", | |
556 | currLoc); | |
557 | } | |
558 | else if (ures_getStringByKey(currentLocale, "Version", NULL, &errorCode)[0] == (UChar)(0x78)) { | |
559 | log_verbose("WARNING: The locale %s is experimental! It shouldn't be listed as an installed locale.\n", | |
560 | currLoc); | |
561 | } | |
73c04bcf A |
562 | resolvedLoc = ures_getLocaleByType(currentLocale, ULOC_ACTUAL_LOCALE, &errorCode); |
563 | if (strcmp(resolvedLoc, currLoc) != 0) { | |
564 | /* All locales have at least a Version resource. | |
565 | If it's absolutely empty, then the previous test will fail too.*/ | |
566 | log_err("Locale resolves to different locale. Is %s an alias of %s?\n", | |
567 | currLoc, resolvedLoc); | |
568 | } | |
374ca955 A |
569 | TestKeyInRootRecursive(root, "root", currentLocale, currLoc); |
570 | ||
571 | testLCID(currentLocale, currLoc); | |
572 | ||
573 | ures_close(currentLocale); | |
574 | } | |
575 | ||
576 | ures_close(root); | |
577 | } | |
51004dcb | 578 | #endif |
374ca955 A |
579 | |
580 | static void | |
581 | compareArrays(const char *keyName, | |
582 | UResourceBundle *fromArray, const char *fromLocale, | |
583 | UResourceBundle *toArray, const char *toLocale, | |
584 | int32_t start, int32_t end) | |
585 | { | |
586 | int32_t fromSize = ures_getSize(fromArray); | |
587 | int32_t toSize = ures_getSize(fromArray); | |
588 | int32_t idx; | |
589 | UErrorCode errorCode = U_ZERO_ERROR; | |
590 | ||
591 | if (fromSize > toSize) { | |
592 | fromSize = toSize; | |
593 | log_err("Arrays are different size from \"%s\" to \"%s\"\n", | |
594 | fromLocale, | |
595 | toLocale); | |
596 | } | |
597 | ||
598 | for (idx = start; idx <= end; idx++) { | |
599 | const UChar *fromBundleStr = ures_getStringByIndex(fromArray, idx, NULL, &errorCode); | |
600 | const UChar *toBundleStr = ures_getStringByIndex(toArray, idx, NULL, &errorCode); | |
601 | if (fromBundleStr && toBundleStr && u_strcmp(fromBundleStr, toBundleStr) != 0) | |
602 | { | |
603 | log_err("Difference for %s at index %d from %s= \"%s\" to %s= \"%s\"\n", | |
604 | keyName, | |
605 | idx, | |
606 | fromLocale, | |
607 | austrdup(fromBundleStr), | |
608 | toLocale, | |
609 | austrdup(toBundleStr)); | |
610 | } | |
611 | } | |
612 | } | |
613 | ||
614 | static void | |
615 | compareConsistentCountryInfo(const char *fromLocale, const char *toLocale) { | |
616 | UErrorCode errorCode = U_ZERO_ERROR; | |
374ca955 A |
617 | UResourceBundle *fromArray, *toArray; |
618 | UResourceBundle *fromLocaleBund = ures_open(NULL, fromLocale, &errorCode); | |
619 | UResourceBundle *toLocaleBund = ures_open(NULL, toLocale, &errorCode); | |
620 | UResourceBundle *toCalendar, *fromCalendar, *toGregorian, *fromGregorian; | |
621 | ||
622 | if(U_FAILURE(errorCode)) { | |
623 | log_err("Can't open resource bundle %s or %s - %s\n", fromLocale, toLocale, u_errorName(errorCode)); | |
624 | return; | |
625 | } | |
626 | fromCalendar = ures_getByKey(fromLocaleBund, "calendar", NULL, &errorCode); | |
627 | fromGregorian = ures_getByKeyWithFallback(fromCalendar, "gregorian", NULL, &errorCode); | |
729e4ab9 | 628 | |
374ca955 A |
629 | toCalendar = ures_getByKey(toLocaleBund, "calendar", NULL, &errorCode); |
630 | toGregorian = ures_getByKeyWithFallback(toCalendar, "gregorian", NULL, &errorCode); | |
374ca955 A |
631 | |
632 | fromArray = ures_getByKey(fromLocaleBund, "CurrencyElements", NULL, &errorCode); | |
633 | toArray = ures_getByKey(toLocaleBund, "CurrencyElements", NULL, &errorCode); | |
634 | if (strcmp(fromLocale, "en_CA") != 0) | |
635 | { | |
636 | /* The first one is probably localized. */ | |
637 | compareArrays("CurrencyElements", fromArray, fromLocale, toArray, toLocale, 1, 2); | |
638 | } | |
639 | ures_close(fromArray); | |
640 | ures_close(toArray); | |
641 | ||
642 | fromArray = ures_getByKey(fromLocaleBund, "NumberPatterns", NULL, &errorCode); | |
643 | toArray = ures_getByKey(toLocaleBund, "NumberPatterns", NULL, &errorCode); | |
644 | if (strcmp(fromLocale, "en_CA") != 0) | |
645 | { | |
646 | compareArrays("NumberPatterns", fromArray, fromLocale, toArray, toLocale, 0, 3); | |
647 | } | |
648 | ures_close(fromArray); | |
649 | ures_close(toArray); | |
650 | ||
651 | /* Difficult to test properly */ | |
652 | /* | |
653 | fromArray = ures_getByKey(fromLocaleBund, "DateTimePatterns", NULL, &errorCode); | |
654 | toArray = ures_getByKey(toLocaleBund, "DateTimePatterns", NULL, &errorCode); | |
655 | { | |
656 | compareArrays("DateTimePatterns", fromArray, fromLocale, toArray, toLocale); | |
657 | } | |
658 | ures_close(fromArray); | |
659 | ures_close(toArray);*/ | |
660 | ||
661 | fromArray = ures_getByKey(fromLocaleBund, "NumberElements", NULL, &errorCode); | |
662 | toArray = ures_getByKey(toLocaleBund, "NumberElements", NULL, &errorCode); | |
663 | if (strcmp(fromLocale, "en_CA") != 0) | |
664 | { | |
665 | compareArrays("NumberElements", fromArray, fromLocale, toArray, toLocale, 0, 3); | |
666 | /* Index 4 is a script based 0 */ | |
667 | compareArrays("NumberElements", fromArray, fromLocale, toArray, toLocale, 5, 10); | |
668 | } | |
669 | ures_close(fromArray); | |
670 | ures_close(toArray); | |
374ca955 A |
671 | ures_close(fromCalendar); |
672 | ures_close(toCalendar); | |
673 | ures_close(fromGregorian); | |
674 | ures_close(toGregorian); | |
675 | ||
676 | ures_close(fromLocaleBund); | |
677 | ures_close(toLocaleBund); | |
678 | } | |
679 | ||
680 | static void | |
681 | TestConsistentCountryInfo(void) { | |
682 | /* UResourceBundle *fromLocale, *toLocale;*/ | |
683 | int32_t locCount = uloc_countAvailable(); | |
684 | int32_t fromLocIndex, toLocIndex; | |
685 | ||
686 | int32_t fromCountryLen, toCountryLen; | |
687 | char fromCountry[ULOC_FULLNAME_CAPACITY], toCountry[ULOC_FULLNAME_CAPACITY]; | |
688 | ||
689 | int32_t fromVariantLen, toVariantLen; | |
690 | char fromVariant[ULOC_FULLNAME_CAPACITY], toVariant[ULOC_FULLNAME_CAPACITY]; | |
691 | ||
692 | UErrorCode errorCode = U_ZERO_ERROR; | |
693 | ||
694 | for (fromLocIndex = 0; fromLocIndex < locCount; fromLocIndex++) { | |
695 | const char *fromLocale = uloc_getAvailable(fromLocIndex); | |
696 | ||
697 | errorCode=U_ZERO_ERROR; | |
698 | fromCountryLen = uloc_getCountry(fromLocale, fromCountry, ULOC_FULLNAME_CAPACITY, &errorCode); | |
699 | if (fromCountryLen <= 0) { | |
700 | /* Ignore countryless locales */ | |
701 | continue; | |
702 | } | |
703 | fromVariantLen = uloc_getVariant(fromLocale, fromVariant, ULOC_FULLNAME_CAPACITY, &errorCode); | |
704 | if (fromVariantLen > 0) { | |
705 | /* Most variants are ignorable like PREEURO, or collation variants. */ | |
706 | continue; | |
707 | } | |
708 | /* Start comparing only after the current index. | |
709 | Previous loop should have already compared fromLocIndex. | |
710 | */ | |
711 | for (toLocIndex = fromLocIndex + 1; toLocIndex < locCount; toLocIndex++) { | |
712 | const char *toLocale = uloc_getAvailable(toLocIndex); | |
713 | ||
714 | toCountryLen = uloc_getCountry(toLocale, toCountry, ULOC_FULLNAME_CAPACITY, &errorCode); | |
715 | if(U_FAILURE(errorCode)) { | |
716 | log_err("Unknown failure fromLocale=%s toLocale=%s errorCode=%s\n", | |
717 | fromLocale, toLocale, u_errorName(errorCode)); | |
718 | continue; | |
719 | } | |
720 | ||
721 | if (toCountryLen <= 0) { | |
722 | /* Ignore countryless locales */ | |
723 | continue; | |
724 | } | |
725 | toVariantLen = uloc_getVariant(toLocale, toVariant, ULOC_FULLNAME_CAPACITY, &errorCode); | |
726 | if (toVariantLen > 0) { | |
727 | /* Most variants are ignorable like PREEURO, or collation variants. */ | |
728 | /* They're a variant for a reason. */ | |
729 | continue; | |
730 | } | |
731 | if (strcmp(fromCountry, toCountry) == 0) { | |
732 | log_verbose("comparing fromLocale=%s toLocale=%s\n", | |
733 | fromLocale, toLocale); | |
734 | compareConsistentCountryInfo(fromLocale, toLocale); | |
735 | } | |
736 | } | |
737 | } | |
738 | } | |
739 | ||
740 | static int32_t | |
741 | findStringSetMismatch(const char *currLoc, const UChar *string, int32_t langSize, | |
57a6839d | 742 | USet * mergedExemplarSet, |
729e4ab9 | 743 | UBool ignoreNumbers, UChar* badCharPtr) { |
374ca955 | 744 | UErrorCode errorCode = U_ZERO_ERROR; |
57a6839d | 745 | USet *exemplarSet; |
374ca955 | 746 | int32_t strIdx; |
57a6839d A |
747 | if (mergedExemplarSet == NULL) { |
748 | return -1; | |
749 | } | |
750 | exemplarSet = createFlattenSet(mergedExemplarSet, &errorCode); | |
374ca955 | 751 | if (U_FAILURE(errorCode)) { |
57a6839d | 752 | log_err("%s: error createFlattenSet returned %s\n", currLoc, u_errorName(errorCode)); |
374ca955 A |
753 | return -1; |
754 | } | |
755 | ||
756 | for (strIdx = 0; strIdx < langSize; strIdx++) { | |
757 | if (!uset_contains(exemplarSet, string[strIdx]) | |
51004dcb | 758 | && string[strIdx] != 0x0020 && string[strIdx] != 0x00A0 && string[strIdx] != 0x002e && string[strIdx] != 0x002c && string[strIdx] != 0x002d && string[strIdx] != 0x0027 && string[strIdx] != 0x005B && string[strIdx] != 0x005D && string[strIdx] != 0x2019 && string[strIdx] != 0x0f0b |
73c04bcf | 759 | && string[strIdx] != 0x200C && string[strIdx] != 0x200D) { |
374ca955 | 760 | if (!ignoreNumbers || (ignoreNumbers && (string[strIdx] < 0x30 || string[strIdx] > 0x39))) { |
73c04bcf | 761 | uset_close(exemplarSet); |
729e4ab9 A |
762 | if (badCharPtr) { |
763 | *badCharPtr = string[strIdx]; | |
764 | } | |
374ca955 A |
765 | return strIdx; |
766 | } | |
767 | } | |
768 | } | |
769 | uset_close(exemplarSet); | |
729e4ab9 A |
770 | if (badCharPtr) { |
771 | *badCharPtr = 0; | |
772 | } | |
374ca955 A |
773 | return -1; |
774 | } | |
73c04bcf A |
775 | /* include non-invariant chars */ |
776 | static int32_t | |
777 | myUCharsToChars(const UChar* us, char* cs, int32_t len){ | |
778 | int32_t i=0; | |
779 | for(; i< len; i++){ | |
780 | if(us[i] < 0x7f){ | |
781 | cs[i] = (char)us[i]; | |
782 | }else{ | |
783 | return -1; | |
784 | } | |
785 | } | |
786 | return i; | |
787 | } | |
729e4ab9 A |
788 | static void |
789 | findSetMatch( UScriptCode *scriptCodes, int32_t scriptsLen, | |
374ca955 A |
790 | USet *exemplarSet, |
791 | const char *locale){ | |
792 | USet *scripts[10]= {0}; | |
793 | char pattern[256] = { '[', ':', 0x000 }; | |
794 | int32_t patternLen; | |
795 | UChar uPattern[256] = {0}; | |
796 | UErrorCode status = U_ZERO_ERROR; | |
797 | int32_t i; | |
798 | ||
799 | /* create the sets with script codes */ | |
800 | for(i = 0; i<scriptsLen; i++){ | |
801 | strcat(pattern, uscript_getShortName(scriptCodes[i])); | |
802 | strcat(pattern, ":]"); | |
803 | patternLen = (int32_t)strlen(pattern); | |
804 | u_charsToUChars(pattern, uPattern, patternLen); | |
805 | scripts[i] = uset_openPattern(uPattern, patternLen, &status); | |
806 | if(U_FAILURE(status)){ | |
46f4442e A |
807 | log_err("Could not create set for pattern %s. Error: %s\n", pattern, u_errorName(status)); |
808 | return; | |
374ca955 | 809 | } |
729e4ab9 | 810 | pattern[2] = 0; |
374ca955 A |
811 | } |
812 | if (strcmp(locale, "uk") == 0 || strcmp(locale, "uk_UA") == 0) { | |
813 | /* Special addition. Add the modifying apostrophe, which isn't in Cyrillic. */ | |
814 | uset_add(scripts[0], 0x2bc); | |
815 | } | |
816 | if(U_SUCCESS(status)){ | |
817 | UBool existsInScript = FALSE; | |
818 | /* iterate over the exemplarSet and ascertain if all | |
819 | * UChars in exemplarSet belong to the scripts returned | |
820 | * by getScript | |
821 | */ | |
822 | int32_t count = uset_getItemCount(exemplarSet); | |
823 | ||
824 | for( i=0; i < count; i++){ | |
825 | UChar32 start = 0; | |
826 | UChar32 end = 0; | |
827 | UChar *str = NULL; | |
828 | int32_t strCapacity = 0; | |
729e4ab9 | 829 | |
374ca955 A |
830 | strCapacity = uset_getItem(exemplarSet, i, &start, &end, str, strCapacity, &status); |
831 | if(U_SUCCESS(status)){ | |
832 | int32_t j; | |
833 | if(strCapacity == 0){ | |
834 | /* ok the item is a range */ | |
835 | for( j = 0; j < scriptsLen; j++){ | |
836 | if(uset_containsRange(scripts[j], start, end) == TRUE){ | |
837 | existsInScript = TRUE; | |
838 | } | |
839 | } | |
840 | if(existsInScript == FALSE){ | |
73c04bcf A |
841 | for( j = 0; j < scriptsLen; j++){ |
842 | UChar toPattern[500]={'\0'}; | |
843 | char pat[500]={'\0'}; | |
844 | int32_t len = uset_toPattern(scripts[j], toPattern, 500, TRUE, &status); | |
845 | len = myUCharsToChars(toPattern, pat, len); | |
846 | log_err("uset_indexOf(\\u%04X)=%i uset_indexOf(\\u%04X)=%i\n", start, uset_indexOf(scripts[0], start), end, uset_indexOf(scripts[0], end)); | |
847 | if(len!=-1){ | |
848 | log_err("Pattern: %s\n",pat); | |
849 | } | |
850 | } | |
374ca955 A |
851 | log_err("ExemplarCharacters and LocaleScript containment test failed for locale %s. \n", locale); |
852 | } | |
853 | }else{ | |
854 | strCapacity++; /* increment for NUL termination */ | |
855 | /* allocate the str and call the api again */ | |
856 | str = (UChar*) malloc(U_SIZEOF_UCHAR * strCapacity); | |
857 | strCapacity = uset_getItem(exemplarSet, i, &start, &end, str, strCapacity, &status); | |
858 | /* iterate over the scripts and figure out if the string contained is actually | |
859 | * in the script set | |
860 | */ | |
861 | for( j = 0; j < scriptsLen; j++){ | |
862 | if(uset_containsString(scripts[j],str, strCapacity) == TRUE){ | |
863 | existsInScript = TRUE; | |
864 | } | |
865 | } | |
866 | if(existsInScript == FALSE){ | |
867 | log_err("ExemplarCharacters and LocaleScript containment test failed for locale %s. \n", locale); | |
868 | } | |
869 | } | |
870 | } | |
871 | } | |
872 | ||
873 | } | |
874 | ||
875 | /* close the sets */ | |
876 | for(i = 0; i<scriptsLen; i++){ | |
877 | uset_close(scripts[i]); | |
878 | } | |
879 | } | |
880 | ||
881 | static void VerifyTranslation(void) { | |
882 | UResourceBundle *root, *currentLocale; | |
883 | int32_t locCount = uloc_countAvailable(); | |
884 | int32_t locIndex; | |
885 | UErrorCode errorCode = U_ZERO_ERROR; | |
374ca955 A |
886 | const char *currLoc; |
887 | UScriptCode scripts[USCRIPT_CODE_LIMIT]; | |
888 | int32_t numScripts; | |
889 | int32_t idx; | |
890 | int32_t end; | |
891 | UResourceBundle *resArray; | |
892 | ||
893 | if (locCount <= 1) { | |
894 | log_data_err("At least root needs to be installed\n"); | |
895 | } | |
896 | ||
897 | root = ures_openDirect(NULL, "root", &errorCode); | |
898 | if(U_FAILURE(errorCode)) { | |
899 | log_data_err("Can't open root\n"); | |
900 | return; | |
901 | } | |
902 | for (locIndex = 0; locIndex < locCount; locIndex++) { | |
57a6839d | 903 | USet * mergedExemplarSet = NULL; |
374ca955 A |
904 | errorCode=U_ZERO_ERROR; |
905 | currLoc = uloc_getAvailable(locIndex); | |
906 | currentLocale = ures_open(NULL, currLoc, &errorCode); | |
907 | if(errorCode != U_ZERO_ERROR) { | |
908 | if(U_SUCCESS(errorCode)) { | |
909 | /* It's installed, but there is no data. | |
910 | It's installed for the g18n white paper [grhoten] */ | |
911 | log_err("ERROR: Locale %-5s not installed, and it should be!\n", | |
912 | uloc_getAvailable(locIndex)); | |
913 | } else { | |
914 | log_err("%%%%%%% Unexpected error %d in %s %%%%%%%", | |
915 | u_errorName(errorCode), | |
916 | uloc_getAvailable(locIndex)); | |
917 | } | |
918 | ures_close(currentLocale); | |
919 | continue; | |
920 | } | |
57a6839d A |
921 | { |
922 | UErrorCode exemplarStatus = U_ZERO_ERROR; | |
923 | ULocaleData * uld = ulocdata_open(currLoc, &exemplarStatus); | |
924 | if (U_SUCCESS(exemplarStatus)) { | |
925 | USet * exemplarSet = ulocdata_getExemplarSet(uld, NULL, USET_ADD_CASE_MAPPINGS, ULOCDATA_ES_STANDARD, &exemplarStatus); | |
926 | if (U_SUCCESS(exemplarStatus)) { | |
927 | mergedExemplarSet = uset_cloneAsThawed(exemplarSet); | |
928 | uset_close(exemplarSet); | |
929 | exemplarSet = ulocdata_getExemplarSet(uld, NULL, USET_ADD_CASE_MAPPINGS, ULOCDATA_ES_AUXILIARY, &exemplarStatus); | |
930 | if (U_SUCCESS(exemplarStatus)) { | |
931 | uset_addAll(mergedExemplarSet, exemplarSet); | |
932 | uset_close(exemplarSet); | |
933 | } | |
934 | exemplarStatus = U_ZERO_ERROR; | |
935 | exemplarSet = ulocdata_getExemplarSet(uld, NULL, 0, ULOCDATA_ES_PUNCTUATION, &exemplarStatus); | |
936 | if (U_SUCCESS(exemplarStatus)) { | |
937 | uset_addAll(mergedExemplarSet, exemplarSet); | |
938 | uset_close(exemplarSet); | |
939 | } | |
940 | } else { | |
941 | log_err("error ulocdata_getExemplarSet (main) for locale %s returned %s\n", currLoc, u_errorName(errorCode)); | |
942 | } | |
943 | ulocdata_close(uld); | |
944 | } else { | |
945 | log_err("error ulocdata_open for locale %s returned %s\n", currLoc, u_errorName(errorCode)); | |
946 | } | |
374ca955 | 947 | } |
57a6839d | 948 | if (mergedExemplarSet == NULL /*|| (getTestOption(QUICK_OPTION) && uset_size() > 2048)*/) { |
374ca955 A |
949 | log_verbose("skipping test for %s\n", currLoc); |
950 | } | |
57a6839d A |
951 | //else if (uprv_strncmp(currLoc,"bem",3) == 0 || uprv_strncmp(currLoc,"mgo",3) == 0 || uprv_strncmp(currLoc,"nl",2) == 0) { |
952 | // log_verbose("skipping test for %s, some month and country names known to use aux exemplars\n", currLoc); | |
953 | //} | |
374ca955 A |
954 | else { |
955 | UChar langBuffer[128]; | |
956 | int32_t langSize; | |
957 | int32_t strIdx; | |
729e4ab9 | 958 | UChar badChar; |
374ca955 A |
959 | langSize = uloc_getDisplayLanguage(currLoc, currLoc, langBuffer, sizeof(langBuffer)/sizeof(langBuffer[0]), &errorCode); |
960 | if (U_FAILURE(errorCode)) { | |
961 | log_err("error uloc_getDisplayLanguage returned %s\n", u_errorName(errorCode)); | |
962 | } | |
963 | else { | |
57a6839d | 964 | strIdx = findStringSetMismatch(currLoc, langBuffer, langSize, mergedExemplarSet, FALSE, &badChar); |
374ca955 | 965 | if (strIdx >= 0) { |
729e4ab9 A |
966 | log_err("getDisplayLanguage(%s) at index %d returned characters not in the exemplar characters: %04X.\n", |
967 | currLoc, strIdx, badChar); | |
374ca955 A |
968 | } |
969 | } | |
970 | langSize = uloc_getDisplayCountry(currLoc, currLoc, langBuffer, sizeof(langBuffer)/sizeof(langBuffer[0]), &errorCode); | |
971 | if (U_FAILURE(errorCode)) { | |
972 | log_err("error uloc_getDisplayCountry returned %s\n", u_errorName(errorCode)); | |
973 | } | |
374ca955 A |
974 | { |
975 | UResourceBundle* cal = ures_getByKey(currentLocale, "calendar", NULL, &errorCode); | |
976 | UResourceBundle* greg = ures_getByKeyWithFallback(cal, "gregorian", NULL, &errorCode); | |
977 | UResourceBundle* names = ures_getByKeyWithFallback(greg, "dayNames", NULL, &errorCode); | |
978 | UResourceBundle* format = ures_getByKeyWithFallback(names, "format", NULL, &errorCode); | |
979 | resArray = ures_getByKeyWithFallback(format, "wide", NULL, &errorCode); | |
980 | ||
981 | if (U_FAILURE(errorCode)) { | |
982 | log_err("error ures_getByKey returned %s\n", u_errorName(errorCode)); | |
983 | } | |
729e4ab9 | 984 | if (getTestOption(QUICK_OPTION)) { |
374ca955 A |
985 | end = 1; |
986 | } | |
987 | else { | |
988 | end = ures_getSize(resArray); | |
989 | } | |
990 | ||
991 | ||
992 | for (idx = 0; idx < end; idx++) { | |
993 | const UChar *fromBundleStr = ures_getStringByIndex(resArray, idx, &langSize, &errorCode); | |
994 | if (U_FAILURE(errorCode)) { | |
995 | log_err("error ures_getStringByIndex(%d) returned %s\n", idx, u_errorName(errorCode)); | |
996 | continue; | |
997 | } | |
57a6839d A |
998 | strIdx = findStringSetMismatch(currLoc, fromBundleStr, langSize, mergedExemplarSet, TRUE, &badChar); |
999 | if (strIdx >= 0) { | |
1000 | log_err("getDayNames(%s, %d) at index %d returned characters not in the exemplar characters: %04X.\n", | |
1001 | currLoc, idx, strIdx, badChar); | |
374ca955 A |
1002 | } |
1003 | } | |
1004 | ures_close(resArray); | |
1005 | ures_close(format); | |
1006 | ures_close(names); | |
1007 | ||
1008 | names = ures_getByKeyWithFallback(greg, "monthNames", NULL, &errorCode); | |
1009 | format = ures_getByKeyWithFallback(names,"format", NULL, &errorCode); | |
1010 | resArray = ures_getByKeyWithFallback(format, "wide", NULL, &errorCode); | |
1011 | if (U_FAILURE(errorCode)) { | |
1012 | log_err("error ures_getByKey returned %s\n", u_errorName(errorCode)); | |
1013 | } | |
729e4ab9 | 1014 | if (getTestOption(QUICK_OPTION)) { |
374ca955 A |
1015 | end = 1; |
1016 | } | |
1017 | else { | |
1018 | end = ures_getSize(resArray); | |
1019 | } | |
1020 | ||
1021 | for (idx = 0; idx < end; idx++) { | |
1022 | const UChar *fromBundleStr = ures_getStringByIndex(resArray, idx, &langSize, &errorCode); | |
1023 | if (U_FAILURE(errorCode)) { | |
1024 | log_err("error ures_getStringByIndex(%d) returned %s\n", idx, u_errorName(errorCode)); | |
1025 | continue; | |
1026 | } | |
57a6839d A |
1027 | strIdx = findStringSetMismatch(currLoc, fromBundleStr, langSize, mergedExemplarSet, TRUE, &badChar); |
1028 | if (strIdx >= 0) { | |
1029 | log_err("getMonthNames(%s, %d) at index %d returned characters not in the exemplar characters: %04X.\n", | |
1030 | currLoc, idx, strIdx, badChar); | |
374ca955 A |
1031 | } |
1032 | } | |
1033 | ures_close(resArray); | |
1034 | ures_close(format); | |
1035 | ures_close(names); | |
1036 | ures_close(greg); | |
1037 | ures_close(cal); | |
1038 | } | |
1039 | errorCode = U_ZERO_ERROR; | |
1040 | numScripts = uscript_getCode(currLoc, scripts, sizeof(scripts)/sizeof(scripts[0]), &errorCode); | |
b331163b A |
1041 | if (strcmp(currLoc, "yi") == 0 && numScripts > 0 && log_knownIssue("11217", "Fix result of uscript_getCode for yi: USCRIPT_YI -> USCRIPT_HEBREW")) { |
1042 | scripts[0] = USCRIPT_HEBREW; | |
1043 | } | |
374ca955 A |
1044 | if (numScripts == 0) { |
1045 | log_err("uscript_getCode(%s) doesn't work.\n", currLoc); | |
1046 | }else if(scripts[0] == USCRIPT_COMMON){ | |
729e4ab9 | 1047 | log_err("uscript_getCode(%s) returned USCRIPT_COMMON.\n", currLoc); |
374ca955 A |
1048 | } |
1049 | ||
1050 | /* test that the scripts are a superset of exemplar characters. */ | |
1051 | { | |
73c04bcf A |
1052 | ULocaleData *uld = ulocdata_open(currLoc,&errorCode); |
1053 | USet *exemplarSet = ulocdata_getExemplarSet(uld, NULL, 0, ULOCDATA_ES_STANDARD, &errorCode); | |
374ca955 A |
1054 | /* test if exemplar characters are part of script code */ |
1055 | findSetMatch(scripts, numScripts, exemplarSet, currLoc); | |
1056 | uset_close(exemplarSet); | |
73c04bcf | 1057 | ulocdata_close(uld); |
374ca955 A |
1058 | } |
1059 | ||
1060 | /* test that the paperSize API works */ | |
1061 | { | |
1062 | int32_t height=0, width=0; | |
1063 | ulocdata_getPaperSize(currLoc, &height, &width, &errorCode); | |
1064 | if(U_FAILURE(errorCode)){ | |
1065 | log_err("ulocdata_getPaperSize failed for locale %s with error: %s \n", currLoc, u_errorName(errorCode)); | |
1066 | } | |
1067 | if(strstr(currLoc, "_US")!=NULL && height != 279 && width != 216 ){ | |
1068 | log_err("ulocdata_getPaperSize did not return expected data for locale %s \n", currLoc); | |
1069 | } | |
1070 | } | |
57a6839d | 1071 | /* test that the MeasurementSystem API works */ |
374ca955 | 1072 | { |
51004dcb | 1073 | char fullLoc[ULOC_FULLNAME_CAPACITY]; |
57a6839d A |
1074 | UMeasurementSystem measurementSystem; |
1075 | int32_t height = 0, width = 0; | |
1076 | ||
1077 | uloc_addLikelySubtags(currLoc, fullLoc, ULOC_FULLNAME_CAPACITY, &errorCode); | |
1078 | ||
1079 | errorCode = U_ZERO_ERROR; | |
1080 | measurementSystem = ulocdata_getMeasurementSystem(currLoc, &errorCode); | |
1081 | if (U_FAILURE(errorCode)) { | |
374ca955 | 1082 | log_err("ulocdata_getMeasurementSystem failed for locale %s with error: %s \n", currLoc, u_errorName(errorCode)); |
57a6839d A |
1083 | } else { |
1084 | if ( strstr(fullLoc, "_US")!=NULL || strstr(fullLoc, "_MM")!=NULL || strstr(fullLoc, "_LR")!=NULL ) { | |
1085 | if(measurementSystem != UMS_US){ | |
1086 | log_err("ulocdata_getMeasurementSystem did not return expected data for locale %s \n", currLoc); | |
1087 | } | |
b331163b A |
1088 | } else if ( strstr(fullLoc, "_GB")!=NULL ) { |
1089 | if(measurementSystem != UMS_UK){ | |
1090 | log_err("ulocdata_getMeasurementSystem did not return expected data for locale %s \n", currLoc); | |
1091 | } | |
57a6839d A |
1092 | } else if (measurementSystem != UMS_SI) { |
1093 | log_err("ulocdata_getMeasurementSystem did not return expected data for locale %s \n", currLoc); | |
1094 | } | |
374ca955 | 1095 | } |
57a6839d A |
1096 | |
1097 | errorCode = U_ZERO_ERROR; | |
1098 | ulocdata_getPaperSize(currLoc, &height, &width, &errorCode); | |
1099 | if (U_FAILURE(errorCode)) { | |
1100 | log_err("ulocdata_getPaperSize failed for locale %s with error: %s \n", currLoc, u_errorName(errorCode)); | |
1101 | } else { | |
1102 | if ( strstr(fullLoc, "_US")!=NULL || strstr(fullLoc, "_BZ")!=NULL || strstr(fullLoc, "_CA")!=NULL || strstr(fullLoc, "_CL")!=NULL || | |
1103 | strstr(fullLoc, "_CO")!=NULL || strstr(fullLoc, "_CR")!=NULL || strstr(fullLoc, "_GT")!=NULL || strstr(fullLoc, "_MX")!=NULL || | |
1104 | strstr(fullLoc, "_NI")!=NULL || strstr(fullLoc, "_PA")!=NULL || strstr(fullLoc, "_PH")!=NULL || strstr(fullLoc, "_PR")!=NULL || | |
1105 | strstr(fullLoc, "_SV")!=NULL || strstr(fullLoc, "_VE")!=NULL ) { | |
1106 | if (height != 279 || width != 216) { | |
1107 | log_err("ulocdata_getPaperSize did not return expected data for locale %s \n", currLoc); | |
1108 | } | |
1109 | } else if (height != 297 || width != 210) { | |
1110 | log_err("ulocdata_getPaperSize did not return expected data for locale %s \n", currLoc); | |
374ca955 | 1111 | } |
374ca955 A |
1112 | } |
1113 | } | |
1114 | } | |
57a6839d A |
1115 | if (mergedExemplarSet != NULL) { |
1116 | uset_close(mergedExemplarSet); | |
1117 | } | |
374ca955 A |
1118 | ures_close(currentLocale); |
1119 | } | |
1120 | ||
1121 | ures_close(root); | |
1122 | } | |
1123 | ||
1124 | /* adjust this limit as appropriate */ | |
1125 | #define MAX_SCRIPTS_PER_LOCALE 8 | |
1126 | ||
1127 | static void TestExemplarSet(void){ | |
1128 | int32_t i, j, k, m, n; | |
1129 | int32_t equalCount = 0; | |
1130 | UErrorCode ec = U_ZERO_ERROR; | |
1131 | UEnumeration* avail; | |
1132 | USet* exemplarSets[2]; | |
73c04bcf | 1133 | USet* unassignedSet; |
374ca955 A |
1134 | UScriptCode code[MAX_SCRIPTS_PER_LOCALE]; |
1135 | USet* codeSets[MAX_SCRIPTS_PER_LOCALE]; | |
1136 | int32_t codeLen; | |
1137 | char cbuf[32]; /* 9 should be enough */ | |
1138 | UChar ubuf[64]; /* adjust as needed */ | |
1139 | UBool existsInScript; | |
1140 | int32_t itemCount; | |
1141 | int32_t strLen; | |
1142 | UChar32 start, end; | |
729e4ab9 | 1143 | |
73c04bcf A |
1144 | unassignedSet = NULL; |
1145 | exemplarSets[0] = NULL; | |
1146 | exemplarSets[1] = NULL; | |
374ca955 A |
1147 | for (i=0; i<MAX_SCRIPTS_PER_LOCALE; ++i) { |
1148 | codeSets[i] = NULL; | |
1149 | } | |
1150 | ||
1151 | avail = ures_openAvailableLocales(NULL, &ec); | |
1152 | if (!assertSuccess("ures_openAvailableLocales", &ec)) goto END; | |
1153 | n = uenum_count(avail, &ec); | |
1154 | if (!assertSuccess("uenum_count", &ec)) goto END; | |
1155 | ||
73c04bcf A |
1156 | u_uastrcpy(ubuf, "[:unassigned:]"); |
1157 | unassignedSet = uset_openPattern(ubuf, -1, &ec); | |
1158 | if (!assertSuccess("uset_openPattern", &ec)) goto END; | |
1159 | ||
374ca955 A |
1160 | for(i=0; i<n; i++){ |
1161 | const char* locale = uenum_next(avail, NULL, &ec); | |
1162 | if (!assertSuccess("uenum_next", &ec)) goto END; | |
1163 | log_verbose("%s\n", locale); | |
1164 | for (k=0; k<2; ++k) { | |
1165 | uint32_t option = (k==0) ? 0 : USET_CASE_INSENSITIVE; | |
729e4ab9 | 1166 | ULocaleData *uld = ulocdata_open(locale,&ec); |
73c04bcf | 1167 | USet* exemplarSet = ulocdata_getExemplarSet(uld,NULL, option, ULOCDATA_ES_STANDARD, &ec); |
374ca955 | 1168 | uset_close(exemplarSets[k]); |
73c04bcf | 1169 | ulocdata_close(uld); |
374ca955 A |
1170 | exemplarSets[k] = exemplarSet; |
1171 | if (!assertSuccess("ulocaledata_getExemplarSet", &ec)) goto END; | |
1172 | ||
73c04bcf A |
1173 | if (uset_containsSome(exemplarSet, unassignedSet)) { |
1174 | log_err("ExemplarSet contains unassigned characters for locale : %s\n", locale); | |
1175 | } | |
374ca955 | 1176 | codeLen = uscript_getCode(locale, code, 8, &ec); |
b331163b A |
1177 | if (strcmp(locale, "yi") == 0 && codeLen > 0 && log_knownIssue("11217", "Fix result of uscript_getCode for yi: USCRIPT_YI -> USCRIPT_HEBREW")) { |
1178 | code[0] = USCRIPT_HEBREW; | |
1179 | } | |
374ca955 A |
1180 | if (!assertSuccess("uscript_getCode", &ec)) goto END; |
1181 | ||
1182 | for (j=0; j<MAX_SCRIPTS_PER_LOCALE; ++j) { | |
1183 | uset_close(codeSets[j]); | |
1184 | codeSets[j] = NULL; | |
1185 | } | |
1186 | for (j=0; j<codeLen; ++j) { | |
1187 | uprv_strcpy(cbuf, "[:"); | |
73c04bcf A |
1188 | if(code[j]==-1){ |
1189 | log_err("USCRIPT_INVALID_CODE returned for locale: %s\n", locale); | |
1190 | continue; | |
1191 | } | |
374ca955 A |
1192 | uprv_strcat(cbuf, uscript_getShortName(code[j])); |
1193 | uprv_strcat(cbuf, ":]"); | |
1194 | u_uastrcpy(ubuf, cbuf); | |
1195 | codeSets[j] = uset_openPattern(ubuf, -1, &ec); | |
1196 | } | |
1197 | if (!assertSuccess("uset_openPattern", &ec)) goto END; | |
1198 | ||
1199 | existsInScript = FALSE; | |
1200 | itemCount = uset_getItemCount(exemplarSet); | |
1201 | for (m=0; m<itemCount && !existsInScript; ++m) { | |
1202 | strLen = uset_getItem(exemplarSet, m, &start, &end, ubuf, | |
1203 | sizeof(ubuf)/sizeof(ubuf[0]), &ec); | |
1204 | /* failure here might mean str[] needs to be larger */ | |
1205 | if (!assertSuccess("uset_getItem", &ec)) goto END; | |
1206 | if (strLen == 0) { | |
1207 | for (j=0; j<codeLen; ++j) { | |
73c04bcf | 1208 | if (codeSets[j]!=NULL && uset_containsRange(codeSets[j], start, end)) { |
374ca955 A |
1209 | existsInScript = TRUE; |
1210 | break; | |
1211 | } | |
1212 | } | |
1213 | } else { | |
1214 | for (j=0; j<codeLen; ++j) { | |
73c04bcf | 1215 | if (codeSets[j]!=NULL && uset_containsString(codeSets[j], ubuf, strLen)) { |
374ca955 A |
1216 | existsInScript = TRUE; |
1217 | break; | |
1218 | } | |
1219 | } | |
1220 | } | |
1221 | } | |
1222 | ||
1223 | if (existsInScript == FALSE){ | |
73c04bcf | 1224 | log_err("ExemplarSet containment failed for locale : %s\n", locale); |
374ca955 A |
1225 | } |
1226 | } | |
1227 | assertTrue("case-folded is a superset", | |
1228 | uset_containsAll(exemplarSets[1], exemplarSets[0])); | |
1229 | if (uset_equals(exemplarSets[1], exemplarSets[0])) { | |
1230 | ++equalCount; | |
1231 | } | |
1232 | } | |
1233 | /* Note: The case-folded set should sometimes be a strict superset | |
1234 | and sometimes be equal. */ | |
1235 | assertTrue("case-folded is sometimes a strict superset, and sometimes equal", | |
1236 | equalCount > 0 && equalCount < n); | |
729e4ab9 | 1237 | |
374ca955 A |
1238 | END: |
1239 | uenum_close(avail); | |
1240 | uset_close(exemplarSets[0]); | |
1241 | uset_close(exemplarSets[1]); | |
73c04bcf | 1242 | uset_close(unassignedSet); |
374ca955 A |
1243 | for (i=0; i<MAX_SCRIPTS_PER_LOCALE; ++i) { |
1244 | uset_close(codeSets[i]); | |
1245 | } | |
1246 | } | |
1247 | ||
57a6839d | 1248 | enum { kUBufMax = 32 }; |
729e4ab9 | 1249 | static void TestLocaleDisplayPattern(void){ |
57a6839d A |
1250 | UErrorCode status; |
1251 | UChar pattern[kUBufMax] = {0,}; | |
1252 | UChar separator[kUBufMax] = {0,}; | |
1253 | ULocaleData *uld; | |
1254 | static const UChar enExpectPat[] = { 0x007B,0x0030,0x007D,0x0020,0x0028,0x007B,0x0031,0x007D,0x0029,0 }; /* "{0} ({1})" */ | |
1255 | static const UChar enExpectSep[] = { 0x002C,0x0020,0 }; /* ", " */ | |
1256 | static const UChar zhExpectPat[] = { 0x007B,0x0030,0x007D,0xFF08,0x007B,0x0031,0x007D,0xFF09,0 }; | |
1257 | static const UChar zhExpectSep[] = { 0x3001,0 }; | |
729e4ab9 | 1258 | |
57a6839d A |
1259 | status = U_ZERO_ERROR; |
1260 | uld = ulocdata_open("en", &status); | |
729e4ab9 | 1261 | if(U_FAILURE(status)){ |
57a6839d A |
1262 | log_data_err("ulocdata_open en error %s", u_errorName(status)); |
1263 | } else { | |
1264 | ulocdata_getLocaleDisplayPattern(uld, pattern, kUBufMax, &status); | |
1265 | if (U_FAILURE(status)){ | |
1266 | log_err("ulocdata_getLocaleDisplayPattern en error %s", u_errorName(status)); | |
1267 | } else if (u_strcmp(pattern, enExpectPat) != 0) { | |
1268 | log_err("ulocdata_getLocaleDisplayPattern en returns unexpected pattern"); | |
1269 | } | |
1270 | status = U_ZERO_ERROR; | |
1271 | ulocdata_getLocaleSeparator(uld, separator, kUBufMax, &status); | |
1272 | if (U_FAILURE(status)){ | |
1273 | log_err("ulocdata_getLocaleSeparator en error %s", u_errorName(status)); | |
1274 | } else if (u_strcmp(separator, enExpectSep) != 0) { | |
1275 | log_err("ulocdata_getLocaleSeparator en returns unexpected string "); | |
1276 | } | |
1277 | ulocdata_close(uld); | |
729e4ab9 | 1278 | } |
57a6839d | 1279 | |
729e4ab9 | 1280 | status = U_ZERO_ERROR; |
57a6839d A |
1281 | uld = ulocdata_open("zh", &status); |
1282 | if(U_FAILURE(status)){ | |
1283 | log_data_err("ulocdata_open zh error %s", u_errorName(status)); | |
1284 | } else { | |
1285 | ulocdata_getLocaleDisplayPattern(uld, pattern, kUBufMax, &status); | |
1286 | if (U_FAILURE(status)){ | |
1287 | log_err("ulocdata_getLocaleDisplayPattern zh error %s", u_errorName(status)); | |
1288 | } else if (u_strcmp(pattern, zhExpectPat) != 0) { | |
1289 | log_err("ulocdata_getLocaleDisplayPattern zh returns unexpected pattern"); | |
1290 | } | |
1291 | status = U_ZERO_ERROR; | |
1292 | ulocdata_getLocaleSeparator(uld, separator, kUBufMax, &status); | |
1293 | if (U_FAILURE(status)){ | |
1294 | log_err("ulocdata_getLocaleSeparator zh error %s", u_errorName(status)); | |
1295 | } else if (u_strcmp(separator, zhExpectSep) != 0) { | |
1296 | log_err("ulocdata_getLocaleSeparator zh returns unexpected string "); | |
1297 | } | |
1298 | ulocdata_close(uld); | |
729e4ab9 | 1299 | } |
729e4ab9 A |
1300 | } |
1301 | ||
73c04bcf A |
1302 | static void TestCoverage(void){ |
1303 | ULocaleDataDelimiterType types[] = { | |
1304 | ULOCDATA_QUOTATION_START, /* Quotation start */ | |
1305 | ULOCDATA_QUOTATION_END, /* Quotation end */ | |
1306 | ULOCDATA_ALT_QUOTATION_START, /* Alternate quotation start */ | |
1307 | ULOCDATA_ALT_QUOTATION_END, /* Alternate quotation end */ | |
1308 | ULOCDATA_DELIMITER_COUNT | |
1309 | }; | |
1310 | int i; | |
1311 | UBool sub; | |
1312 | UErrorCode status = U_ZERO_ERROR; | |
1313 | ULocaleData *uld = ulocdata_open(uloc_getDefault(), &status); | |
1314 | ||
1315 | if(U_FAILURE(status)){ | |
729e4ab9 | 1316 | log_data_err("ulocdata_open error"); |
73c04bcf A |
1317 | return; |
1318 | } | |
1319 | ||
1320 | ||
1321 | for(i = 0; i < ULOCDATA_DELIMITER_COUNT; i++){ | |
1322 | UChar result[32] = {0,}; | |
1323 | status = U_ZERO_ERROR; | |
1324 | ulocdata_getDelimiter(uld, types[i], result, 32, &status); | |
1325 | if (U_FAILURE(status)){ | |
1326 | log_err("ulocdata_getgetDelimiter error with type %d", types[i]); | |
1327 | } | |
1328 | } | |
1329 | ||
1330 | sub = ulocdata_getNoSubstitute(uld); | |
1331 | ulocdata_setNoSubstitute(uld,sub); | |
1332 | ulocdata_close(uld); | |
1333 | } | |
1334 | ||
4388f060 A |
1335 | static void TestIndexChars(void) { |
1336 | /* Very basic test of ULOCDATA_ES_INDEX. | |
1337 | * No comprehensive test of data, just basic check that the code path is alive. | |
1338 | */ | |
1339 | UErrorCode status = U_ZERO_ERROR; | |
1340 | ULocaleData *uld; | |
1341 | USet *exemplarChars; | |
1342 | USet *indexChars; | |
1343 | ||
1344 | uld = ulocdata_open("en", &status); | |
1345 | exemplarChars = uset_openEmpty(); | |
1346 | indexChars = uset_openEmpty(); | |
1347 | ulocdata_getExemplarSet(uld, exemplarChars, 0, ULOCDATA_ES_STANDARD, &status); | |
1348 | ulocdata_getExemplarSet(uld, indexChars, 0, ULOCDATA_ES_INDEX, &status); | |
1349 | if (U_FAILURE(status)) { | |
1350 | log_data_err("File %s, line %d, Failure opening exemplar chars: %s", __FILE__, __LINE__, u_errorName(status)); | |
1351 | goto close_sets; | |
1352 | } | |
1353 | /* en data, standard exemplars are [a-z], lower case. */ | |
1354 | /* en data, index characters are [A-Z], upper case. */ | |
1355 | if ((uset_contains(exemplarChars, (UChar32)0x41) || uset_contains(indexChars, (UChar32)0x61))) { | |
1356 | log_err("File %s, line %d, Exemplar characters incorrect.", __FILE__, __LINE__ ); | |
1357 | goto close_sets; | |
1358 | } | |
1359 | if (!(uset_contains(exemplarChars, (UChar32)0x61) && uset_contains(indexChars, (UChar32)0x41) )) { | |
1360 | log_err("File %s, line %d, Exemplar characters incorrect.", __FILE__, __LINE__ ); | |
1361 | goto close_sets; | |
1362 | } | |
1363 | ||
1364 | close_sets: | |
1365 | uset_close(exemplarChars); | |
1366 | uset_close(indexChars); | |
1367 | ulocdata_close(uld); | |
1368 | } | |
1369 | ||
1370 | ||
1371 | ||
51004dcb | 1372 | #if !UCONFIG_NO_FILE_IO && !UCONFIG_NO_LEGACY_CONVERSION |
73c04bcf A |
1373 | static void TestCurrencyList(void){ |
1374 | #if !UCONFIG_NO_FORMATTING | |
1375 | UErrorCode errorCode = U_ZERO_ERROR; | |
1376 | int32_t structLocaleCount, currencyCount; | |
1377 | UEnumeration *en = ucurr_openISOCurrencies(UCURR_ALL, &errorCode); | |
1378 | const char *isoCode, *structISOCode; | |
1379 | UResourceBundle *subBundle; | |
1380 | UResourceBundle *currencies = ures_openDirect(loadTestData(&errorCode), "structLocale", &errorCode); | |
1381 | if(U_FAILURE(errorCode)) { | |
1382 | log_data_err("Can't open structLocale\n"); | |
1383 | return; | |
1384 | } | |
1385 | currencies = ures_getByKey(currencies, "Currencies", currencies, &errorCode); | |
1386 | currencyCount = uenum_count(en, &errorCode); | |
1387 | structLocaleCount = ures_getSize(currencies); | |
1388 | if (currencyCount != structLocaleCount) { | |
1389 | log_err("structLocale(%d) and ISO4217(%d) currency list are out of sync.\n", structLocaleCount, currencyCount); | |
1390 | #if U_CHARSET_FAMILY == U_ASCII_FAMILY | |
1391 | ures_resetIterator(currencies); | |
1392 | while ((isoCode = uenum_next(en, NULL, &errorCode)) != NULL && ures_hasNext(currencies)) { | |
1393 | subBundle = ures_getNextResource(currencies, NULL, &errorCode); | |
1394 | structISOCode = ures_getKey(subBundle); | |
1395 | ures_close(subBundle); | |
1396 | if (strcmp(structISOCode, isoCode) != 0) { | |
1397 | log_err("First difference found at structLocale(%s) and ISO4217(%s).\n", structISOCode, isoCode); | |
1398 | break; | |
1399 | } | |
1400 | } | |
1401 | #endif | |
1402 | } | |
1403 | ures_close(currencies); | |
1404 | uenum_close(en); | |
1405 | #endif | |
1406 | } | |
51004dcb | 1407 | #endif |
73c04bcf | 1408 | |
4388f060 A |
1409 | static void TestAvailableIsoCodes(void){ |
1410 | #if !UCONFIG_NO_FORMATTING | |
1411 | UErrorCode errorCode = U_ZERO_ERROR; | |
1412 | const char* eurCode = "EUR"; | |
1413 | const char* usdCode = "USD"; | |
1414 | const char* lastCode = "RHD"; | |
1415 | const char* zzzCode = "ZZZ"; | |
1416 | UDate date1950 = (UDate)-630720000000.0;/* year 1950 */ | |
1417 | UDate date1970 = (UDate)0.0; /* year 1970 */ | |
1418 | UDate date1975 = (UDate)173448000000.0; /* year 1975 */ | |
1419 | UDate date1978 = (UDate)260172000000.0; /* year 1978 */ | |
1420 | UDate date1981 = (UDate)346896000000.0; /* year 1981 */ | |
1421 | UDate date1992 = (UDate)693792000000.0; /* year 1992 */ | |
1422 | UChar* isoCode = (UChar*)malloc(sizeof(UChar) * (uprv_strlen(usdCode) + 1)); | |
1423 | ||
1424 | /* testing available codes with no time ranges */ | |
1425 | u_charsToUChars(eurCode, isoCode, uprv_strlen(usdCode) + 1); | |
1426 | if (ucurr_isAvailable(isoCode, U_DATE_MIN, U_DATE_MAX, &errorCode) == FALSE) { | |
1427 | log_data_err("FAIL: ISO code (%s) is not found.\n", eurCode); | |
1428 | } | |
1429 | ||
1430 | u_charsToUChars(usdCode, isoCode, uprv_strlen(zzzCode) + 1); | |
1431 | if (ucurr_isAvailable(isoCode, U_DATE_MIN, U_DATE_MAX, &errorCode) == FALSE) { | |
1432 | log_data_err("FAIL: ISO code (%s) is not found.\n", usdCode); | |
1433 | } | |
1434 | ||
1435 | u_charsToUChars(zzzCode, isoCode, uprv_strlen(zzzCode) + 1); | |
1436 | if (ucurr_isAvailable(isoCode, U_DATE_MIN, U_DATE_MAX, &errorCode) == TRUE) { | |
1437 | log_err("FAIL: ISO code (%s) is reported as available, but it doesn't exist.\n", zzzCode); | |
1438 | } | |
1439 | ||
1440 | u_charsToUChars(lastCode, isoCode, uprv_strlen(zzzCode) + 1); | |
1441 | if (ucurr_isAvailable(isoCode, U_DATE_MIN, U_DATE_MAX, &errorCode) == FALSE) { | |
1442 | log_data_err("FAIL: ISO code (%s) is not found.\n", lastCode); | |
1443 | } | |
1444 | ||
1445 | /* RHD was used from 1970-02-17 to 1980-04-18*/ | |
1446 | ||
1447 | /* to = null */ | |
1448 | if (ucurr_isAvailable(isoCode, date1970, U_DATE_MAX, &errorCode) == FALSE) { | |
1449 | log_data_err("FAIL: ISO code (%s) was available in time range >1970-01-01.\n", lastCode); | |
1450 | } | |
1451 | ||
1452 | if (ucurr_isAvailable(isoCode, date1975, U_DATE_MAX, &errorCode) == FALSE) { | |
1453 | log_data_err("FAIL: ISO code (%s) was available in time range >1975.\n", lastCode); | |
1454 | } | |
1455 | ||
1456 | if (ucurr_isAvailable(isoCode, date1981, U_DATE_MAX, &errorCode) == TRUE) { | |
1457 | log_err("FAIL: ISO code (%s) was not available in time range >1981.\n", lastCode); | |
1458 | } | |
1459 | ||
1460 | /* from = null */ | |
1461 | if (ucurr_isAvailable(isoCode, U_DATE_MIN, date1970, &errorCode) == TRUE) { | |
1462 | log_err("FAIL: ISO code (%s) was not available in time range <1970.\n", lastCode); | |
1463 | } | |
1464 | ||
1465 | if (ucurr_isAvailable(isoCode, U_DATE_MIN, date1975, &errorCode) == FALSE) { | |
1466 | log_data_err("FAIL: ISO code (%s) was available in time range <1975.\n", lastCode); | |
1467 | } | |
1468 | ||
1469 | if (ucurr_isAvailable(isoCode, U_DATE_MIN, date1981, &errorCode) == FALSE) { | |
1470 | log_data_err("FAIL: ISO code (%s) was available in time range <1981.\n", lastCode); | |
1471 | } | |
1472 | ||
1473 | /* full ranges */ | |
1474 | if (ucurr_isAvailable(isoCode, date1975, date1978, &errorCode) == FALSE) { | |
1475 | log_data_err("FAIL: ISO code (%s) was available in time range 1975-1978.\n", lastCode); | |
1476 | } | |
1477 | ||
1478 | if (ucurr_isAvailable(isoCode, date1970, date1975, &errorCode) == FALSE) { | |
1479 | log_data_err("FAIL: ISO code (%s) was available in time range 1970-1975.\n", lastCode); | |
1480 | } | |
1481 | ||
1482 | if (ucurr_isAvailable(isoCode, date1975, date1981, &errorCode) == FALSE) { | |
1483 | log_data_err("FAIL: ISO code (%s) was available in time range 1975-1981.\n", lastCode); | |
1484 | } | |
1485 | ||
1486 | if (ucurr_isAvailable(isoCode, date1970, date1981, &errorCode) == FALSE) { | |
1487 | log_data_err("FAIL: ISO code (%s) was available in time range 1970-1981.\n", lastCode); | |
1488 | } | |
1489 | ||
1490 | if (ucurr_isAvailable(isoCode, date1981, date1992, &errorCode) == TRUE) { | |
1491 | log_err("FAIL: ISO code (%s) was not available in time range 1981-1992.\n", lastCode); | |
1492 | } | |
1493 | ||
1494 | if (ucurr_isAvailable(isoCode, date1950, date1970, &errorCode) == TRUE) { | |
1495 | log_err("FAIL: ISO code (%s) was not available in time range 1950-1970.\n", lastCode); | |
1496 | } | |
1497 | ||
1498 | /* wrong range - from > to*/ | |
1499 | if (ucurr_isAvailable(isoCode, date1975, date1970, &errorCode) == TRUE) { | |
1500 | log_err("FAIL: Wrong range 1975-1970 for ISO code (%s) was not reported.\n", lastCode); | |
1501 | } else if (errorCode != U_ILLEGAL_ARGUMENT_ERROR) { | |
1502 | log_data_err("FAIL: Error code not reported for wrong range 1975-1970 for ISO code (%s).\n", lastCode); | |
1503 | } | |
1504 | ||
1505 | free(isoCode); | |
1506 | #endif | |
1507 | } | |
1508 | ||
374ca955 A |
1509 | #define TESTCASE(name) addTest(root, &name, "tsutil/cldrtest/" #name) |
1510 | ||
1511 | void addCLDRTest(TestNode** root); | |
1512 | ||
1513 | void addCLDRTest(TestNode** root) | |
1514 | { | |
729e4ab9 | 1515 | #if !UCONFIG_NO_FILE_IO && !UCONFIG_NO_LEGACY_CONVERSION |
374ca955 | 1516 | TESTCASE(TestLocaleStructure); |
729e4ab9 A |
1517 | TESTCASE(TestCurrencyList); |
1518 | #endif | |
374ca955 A |
1519 | TESTCASE(TestConsistentCountryInfo); |
1520 | TESTCASE(VerifyTranslation); | |
1521 | TESTCASE(TestExemplarSet); | |
729e4ab9 | 1522 | TESTCASE(TestLocaleDisplayPattern); |
73c04bcf | 1523 | TESTCASE(TestCoverage); |
4388f060 A |
1524 | TESTCASE(TestIndexChars); |
1525 | TESTCASE(TestAvailableIsoCodes); | |
374ca955 | 1526 | } |
4388f060 | 1527 |