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