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