From 616ee239325924868fb4e21b7bebc4696d7c135e Mon Sep 17 00:00:00 2001 From: George Rhoten Date: Tue, 5 Feb 2002 23:47:41 +0000 Subject: [PATCH] ICU-1616 Move the TestLocaleStructure test from crestest to cloctest X-SVN-Rev: 7571 --- icu4c/source/test/cintltst/cloctst.c | 408 +++++++++++++++++++++++++++ icu4c/source/test/cintltst/cloctst.h | 2 + icu4c/source/test/cintltst/crestst.c | 401 -------------------------- 3 files changed, 410 insertions(+), 401 deletions(-) diff --git a/icu4c/source/test/cintltst/cloctst.c b/icu4c/source/test/cintltst/cloctst.c index b6d00d77c9..e906016883 100644 --- a/icu4c/source/test/cintltst/cloctst.c +++ b/icu4c/source/test/cintltst/cloctst.c @@ -23,6 +23,12 @@ #include "cintltst.h" #include "ccolltst.h" +#include "unicode/ures.h" +#ifdef WIN32 +/* Get the private functions. This is a hack! [grhoten] */ +#include "locmap.c" +#endif + void PrintDataTable(); /*--------------------------------------------------- @@ -136,6 +142,7 @@ void addLocaleTest(TestNode** root) addTest(root, &TestUninstalledISO3Names, "tsutil/cloctst/TestUninstalledISO3Names"); addTest(root, &TestSimpleDisplayNames, "tsutil/cloctst/TestSimpleDisplayNames"); addTest(root, &TestVariantParsing, "tsutil/cloctst/TestVariantParsing"); + addTest(root, &TestLocaleStructure, "tsutil/cloctst/TestLocaleStructure"); } @@ -1213,3 +1220,404 @@ static void TestObsoleteNames(void) #endif } + +static void +TestKeyInRootRecursive(UResourceBundle *root, UResourceBundle *currentBundle, const char *locale) { + UErrorCode errorCode = U_ZERO_ERROR; + UResourceBundle *subRootBundle = NULL, *subBundle = NULL; + + ures_resetIterator(root); + ures_resetIterator(currentBundle); + while (ures_hasNext(currentBundle)) { + const char *subBundleKey = NULL; + + errorCode = U_ZERO_ERROR; + subBundle = ures_getNextResource(currentBundle, NULL, &errorCode); + if (U_FAILURE(errorCode)) { + log_err("Can't open a resource for locale %s\n", locale); + continue; + } + subBundleKey = ures_getKey(subBundle); + + subRootBundle = ures_getByKey(root, subBundleKey, NULL, &errorCode); + if (U_FAILURE(errorCode)) { +/* if (ures_hasNext(root)) { + errorCode = U_ZERO_ERROR; + subRootBundle = ures_getNextResource(root, NULL, &errorCode); + } + if (errorCode!=U_ZERO_ERROR) { + if (ures_getKey(currentBundle) != 0 && strcmp(ures_getKey(currentBundle), "zoneStrings") == 0) { + break; + } + else {*/ + if (subBundleKey == NULL + || (strcmp(subBundleKey, "TransliterateLATIN") != 0 /* Ignore these special cases */ + && strcmp(subBundleKey, "BreakDictionaryData") != 0)) + { + log_err("Can't open a resource with key \"%s\" in \"%s\" from root for locale \"%s\"\n", + subBundleKey, + ures_getKey(currentBundle), + locale); + } + continue; +/* } + }*/ + } + if (ures_getType(subRootBundle) != ures_getType(subBundle)) { + log_err("key \"%s\" in \"%s\" has a different type from root for locale \"%s\"\n" + "\troot=%d, locale=%d\n", + subBundleKey, + ures_getKey(currentBundle), + locale, + ures_getType(subRootBundle), + ures_getType(subBundle)); + continue; + } + else if (ures_getType(subBundle) == RES_ARRAY) { + UResourceBundle *subSubBundle = ures_getByIndex(subBundle, 0, NULL, &errorCode); + UResourceBundle *subSubRootBundle = ures_getByIndex(subRootBundle, 0, NULL, &errorCode); + + if (U_SUCCESS(errorCode) + && (ures_getType(subSubBundle) == RES_ARRAY || ures_getType(subSubRootBundle) == RES_ARRAY)) + { + /* TODO: Properly check for 2D arrays and zoneStrings */ + if (subBundleKey != NULL && strcmp(subBundleKey, "zoneStrings") == 0) { +/* int32_t minSize = ures_getSize(subBundle); + int32_t idx; + + for (idx = 0; idx < minSize; idx++) { + UResourceBundle *subSubBundleAtIndex = ures_getByIndex(subBundle, idx, NULL, &errorCode); + if (ures_getSize(subSubBundleAtIndex) != 6) { + log_err("zoneStrings at index %d has wrong size for locale \"%s\". array size=%d\n", + idx, + locale, + ures_getSize(subSubBundleAtIndex)); + } + ures_close(subSubBundleAtIndex); + }*/ + } + else { + /* Here is one of the recursive parts */ + TestKeyInRootRecursive(subRootBundle, subBundle, locale); + } + } + else { + int32_t minSize = ures_getSize(subRootBundle); + int32_t idx; + UBool sameArray = TRUE; + + if (minSize > ures_getSize(subBundle)) { + minSize = ures_getSize(subBundle); + } + + if ((subBundleKey == NULL + || (subBundleKey != NULL && strcmp(subBundleKey, "LocaleScript") != 0)) + && ures_getSize(subRootBundle) != ures_getSize(subBundle)) + { + log_err("Different size array with key \"%s\" in \"%s\" from root for locale \"%s\"\n" + "\troot array size=%d, locale array size=%d\n", + subBundleKey, + ures_getKey(currentBundle), + locale, + ures_getSize(subRootBundle), + ures_getSize(subBundle)); + } + + for (idx = 0; idx < minSize && sameArray; idx++) { + int32_t rootStrLen, localeStrLen; + const UChar *rootStr = ures_getStringByIndex(subRootBundle,idx,&rootStrLen,&errorCode); + const UChar *localeStr = ures_getStringByIndex(subBundle,idx,&localeStrLen,&errorCode); + if (rootStr && localeStr && U_SUCCESS(errorCode)) { + sameArray = (u_strcmp(rootStr, localeStr) == 0); + } + else { + log_err("Got a NULL string with key \"%s\" in \"%s\" at index %d for root or locale \"%s\"\n", + subBundleKey, + ures_getKey(currentBundle), + idx, + locale); + continue; + } + if (localeStr[0] == (UChar)0x20) { + log_err("key \"%s\" at index %d in \"%s\" starts with a space in locale \"%s\"\n", + subBundleKey, + idx, + ures_getKey(currentBundle), + locale); + } + else if (localeStr[localeStrLen - 1] == (UChar)0x20) { + log_err("key \"%s\" at index %d in \"%s\" ends with a space in locale \"%s\"\n", + subBundleKey, + idx, + ures_getKey(currentBundle), + locale); + } + else if (subBundleKey != NULL + && strcmp(subBundleKey, "DateTimePatterns") == 0) + { + int32_t quoted = 0; + const UChar *localeStrItr = localeStr; + while (*localeStrItr) { + if (*localeStrItr == (UChar)0x27 /* ' */) { + quoted++; + } + else if ((quoted % 2) == 0) { + /* Search for unquoted characters */ + if (*localeStrItr == (UChar)0x64 /* d */ + && (*localeStrItr == (UChar)0x6B /* k */ + || *localeStrItr == (UChar)0x48 /* H */ + || *localeStrItr == (UChar)0x6D /* m */ + || *localeStrItr == (UChar)0x73 /* s */ + || *localeStrItr == (UChar)0x53 /* S */ + || *localeStrItr == (UChar)0x61 /* a */ + || *localeStrItr == (UChar)0x68 /* h */ + || *localeStrItr == (UChar)0x7A /* z */)) + { + log_err("key \"%s\" at index %d has time pattern chars in date for locale \"%s\"\n", + subBundleKey, + idx, + locale); + } + else if (*localeStrItr == (UChar)0x6D /* m */ + && (*localeStrItr == (UChar)0x47 /* G */ + || *localeStrItr == (UChar)0x79 /* y */ + || *localeStrItr == (UChar)0x4D /* M */ + || *localeStrItr == (UChar)0x64 /* d */ + || *localeStrItr == (UChar)0x45 /* E */ + || *localeStrItr == (UChar)0x44 /* D */ + || *localeStrItr == (UChar)0x46 /* F */ + || *localeStrItr == (UChar)0x77 /* w */ + || *localeStrItr == (UChar)0x57 /* W */)) + { + log_err("key \"%s\" at index %d has date pattern chars in time for locale \"%s\"\n", + subBundleKey, + idx, + locale); + } + } + localeStrItr++; + } + } + } + if (sameArray) { + log_err("Arrays are the same with key \"%s\" in \"%s\" from root for locale \"%s\"\n", + subBundleKey, + ures_getKey(currentBundle), + locale); + } + } + ures_close(subSubBundle); + ures_close(subSubRootBundle); + } + else if (ures_getType(subBundle) == RES_STRING) { + int32_t len = 0; + const UChar *string = ures_getString(subBundle, &len, &errorCode); + if (U_FAILURE(errorCode) || string == NULL) { + log_err("Can't open a string with key \"%s\" in \"%s\" for locale \"%s\"\n", + subBundleKey, + ures_getKey(currentBundle), + locale); + } else if (string[0] == (UChar)0x20) { + log_err("key \"%s\" in \"%s\" starts with a space in locale \"%s\"\n", + subBundleKey, + ures_getKey(currentBundle), + locale); + } else if (string[len - 1] == (UChar)0x20) { + log_err("key \"%s\" in \"%s\" ends with a space in locale \"%s\"\n", + subBundleKey, + ures_getKey(currentBundle), + locale); + } else if (strcmp(subBundleKey, "localPatternChars") == 0 && len != 20) { + log_err("key \"%s\" has the wrong number of characters in locale \"%s\"\n", + subBundleKey, + locale); + } + /* No fallback was done. Check for duplicate data */ + /* The ures_* API does not do fallback of sub-resource bundles, + So we can't do this now. */ + else if (strcmp(locale, "root") != 0 && errorCode == U_ZERO_ERROR) { + + const UChar *rootString = ures_getString(subRootBundle, &len, &errorCode); + if (U_FAILURE(errorCode) || rootString == NULL) { + log_err("Can't open a string with key \"%s\" in \"%s\" in root\n", + ures_getKey(subRootBundle), + ures_getKey(currentBundle)); + continue; + } else if (u_strcmp(string, rootString) == 0) { + if (strcmp(locale, "de_CH") != 0 && strcmp(subBundleKey, "Countries") != 0) { + log_err("Found duplicate data with key \"%s\" in \"%s\" in locale \"%s\"\n", + ures_getKey(subRootBundle), + ures_getKey(currentBundle), + locale); + } + else { + /* Ignore for now. */ + /* Can be fixed if fallback through de locale was done. */ + log_verbose("Skipping key %s in %s\n", subBundleKey, locale); + } + } + } + } + else if (ures_getType(subBundle) == RES_TABLE) { + /* Here is one of the recursive parts */ + TestKeyInRootRecursive(subRootBundle, subBundle, locale); + } + else if (ures_getType(subBundle) == RES_BINARY) { + /* Can't do anything to check it */ + /* We'll assume it's all correct */ + log_verbose("Skipping key \"%s\" in \"%s\" for locale \"%s\"\n", + subBundleKey, + ures_getKey(currentBundle), + locale); + } + else { + log_err("Type %d for key \"%s\" in \"%s\" is unknown for locale \"%s\"\n", + ures_getType(subBundle), + subBundleKey, + ures_getKey(currentBundle), + locale); + } + ures_close(subRootBundle); + ures_close(subBundle); + } +} + + +#ifdef WIN32 + +static void +testLCID(UResourceBundle *currentBundle, + const char *localeName) +{ + UErrorCode status = U_ZERO_ERROR; + uint32_t lcid; + uint32_t expectedLCID; + char lcidStringC[64] = {0}; + int32_t lcidStringLen = 0; + const UChar *lcidString = NULL; + + lcidString = ures_getStringByKey(currentBundle, "LocaleID", &lcidStringLen, &status); + + if (U_FAILURE(status)) { + log_err("ERROR: %s does not have a LocaleID (%s)\n", + localeName, u_errorName(status)); + return; + } + + u_UCharsToChars(lcidString, lcidStringC, lcidStringLen + 1); + expectedLCID = uprv_strtoul(lcidStringC, NULL, 16); + + lcid = T_convertToLCID(localeName, &status); + if (U_FAILURE(status)) { + if (expectedLCID == 0) { + log_verbose("INFO: %-5s does not have any LCID mapping\n", + localeName); + } + else { + log_err("ERROR: %-5s does not have an LCID mapping to 0x%.4X\n", + localeName, expectedLCID); + } + return; + } + + status = U_ZERO_ERROR; + uprv_strcpy(lcidStringC, T_convertToPosix(expectedLCID, &status)); + if (U_FAILURE(status)) { + log_err("ERROR: %.4x does not have a POSIX mapping due to %s\n", + expectedLCID, u_errorName(status)); + } + + if(lcid != expectedLCID) { + log_err("ERROR: %-5s wrongfully has 0x%.4x instead of 0x%.4x for LCID\n", + localeName, expectedLCID, lcid); + } + if(strcmp(localeName, lcidStringC) != 0) { + char langName[1024]; + char langLCID[1024]; + uloc_getLanguage(localeName, langName, sizeof(langName), &status); + uloc_getLanguage(lcidStringC, langLCID, sizeof(langLCID), &status); + + if (expectedLCID == lcid && strcmp(langName, langLCID) == 0) { + log_verbose("WARNING: %-5s resolves to %s (0x%.4x)\n", + localeName, lcidStringC, lcid); + } + else if (expectedLCID == lcid) { + log_err("ERROR: %-5s has 0x%.4x and the number resolves wrongfully to %s\n", + localeName, expectedLCID, lcidStringC); + } + else { + log_err("ERROR: %-5s has 0x%.4x and the number resolves wrongfully to %s. It should be 0x%x.\n", + localeName, expectedLCID, lcidStringC, lcid); + } + } +} + +#endif + +static void +TestLocaleStructure(void) { + UResourceBundle *root, *currentLocale; + int32_t locCount = uloc_countAvailable(); + int32_t locIndex; + UErrorCode errorCode = U_ZERO_ERROR; + + /* TODO: Compare against parent's data too. This code can't handle fallbacks that some tools do already. */ +/* char locName[ULOC_FULLNAME_CAPACITY]; + char *locNamePtr; + + for (locIndex = 0; locIndex < locCount; locIndex++) { + errorCode=U_ZERO_ERROR; + strcpy(locName, uloc_getAvailable(locIndex)); + locNamePtr = strrchr(locName, '_'); + if (locNamePtr) { + *locNamePtr = 0; + } + else { + strcpy(locName, "root"); + } + + root = ures_openDirect(NULL, locName, &errorCode); + if(U_FAILURE(errorCode)) { + log_err("Can't open %s\n", locName); + continue; + } +*/ + root = ures_openDirect(NULL, "root", &errorCode); + if(U_FAILURE(errorCode)) { + log_err("Can't open root\n"); + return; + } + for (locIndex = 0; locIndex < locCount; locIndex++) { + errorCode=U_ZERO_ERROR; + currentLocale = ures_open(NULL, uloc_getAvailable(locIndex), &errorCode); + if(errorCode != U_ZERO_ERROR) { + if(U_SUCCESS(errorCode)) { + if (strcmp(uloc_getAvailable(locIndex),"sv_FI_AL") != 0) { + /* It's installed, but there is no data. + It's installed for the g18n white paper [grhoten] */ + log_err("ERROR: Locale %-5s not installed, and it should be!\n", + uloc_getAvailable(locIndex)); + } + } else { + log_err("%%%%%%% Unexpected error %d in %s %%%%%%%", + u_errorName(errorCode), + uloc_getAvailable(locIndex)); + } + continue; + } + ures_getStringByKey(currentLocale, "Version", NULL, &errorCode); + if(errorCode != U_ZERO_ERROR) { + log_err("No version information is available for locale %s, and it should be!\n", + uloc_getAvailable(locIndex)); + } + else if (ures_getStringByKey(currentLocale, "Version", NULL, &errorCode)[0] == (UChar)(0x78)) { + log_err("The locale %s is experimental! It shouldn't be listed as an installed locale.\n", + uloc_getAvailable(locIndex)); + } + TestKeyInRootRecursive(root, currentLocale, uloc_getAvailable(locIndex)); +#ifdef WIN32 + testLCID(currentLocale, uloc_getAvailable(locIndex)); +#endif + ures_close(currentLocale); + } +} diff --git a/icu4c/source/test/cintltst/cloctst.h b/icu4c/source/test/cintltst/cloctst.h index 38954cb969..0f566b3ad7 100644 --- a/icu4c/source/test/cintltst/cloctst.h +++ b/icu4c/source/test/cintltst/cloctst.h @@ -61,6 +61,8 @@ static void TestDisplayNames(void); **/ static void TestVariantParsing(void); + static void TestLocaleStructure(void); + /** * routine to perform subtests, used by TestDisplayNames */ diff --git a/icu4c/source/test/cintltst/crestst.c b/icu4c/source/test/cintltst/crestst.c index 6998ad8fef..2522a893c0 100644 --- a/icu4c/source/test/cintltst/crestst.c +++ b/icu4c/source/test/cintltst/crestst.c @@ -22,19 +22,12 @@ #define RESTEST_HEAP_CHECK 0 -#include "unicode/uloc.h" #include "unicode/ures.h" #include "crestst.h" #include "unicode/ctest.h" -#ifdef WIN32 -/* Get the private functions. This is a hack! [grhoten] */ -#include "locmap.c" -#endif - static void TestOpenDirect(void); static void TestFallback(void); -static void TestLocaleStructure(void); /*****************************************************************************/ @@ -99,7 +92,6 @@ void addResourceBundleTest(TestNode** root) addTest(root, &TestResourceBundles, "tsutil/crestst/TestResourceBundle"); addTest(root, &TestFallback, "tsutil/crestst/TestFallback"); addTest(root, &TestAliasConflict, "tsutil/crestst/TestAliasConflict"); - /*addTest(root, &TestLocaleStructure, "tsutil/crestst/TestLocaleStructure");*/ } @@ -556,396 +548,3 @@ TestOpenDirect(void) { ures_close(translit_index); } -static void -TestKeyInRootRecursive(UResourceBundle *root, UResourceBundle *currentBundle, const char *locale) { - UErrorCode errorCode = U_ZERO_ERROR; - UResourceBundle *subRootBundle = NULL, *subBundle = NULL; - - ures_resetIterator(root); - ures_resetIterator(currentBundle); - while (ures_hasNext(currentBundle)) { - const char *subBundleKey = NULL; - - errorCode = U_ZERO_ERROR; - subBundle = ures_getNextResource(currentBundle, NULL, &errorCode); - if (U_FAILURE(errorCode)) { - log_err("Can't open a resource for locale %s\n", locale); - continue; - } - subBundleKey = ures_getKey(subBundle); - - subRootBundle = ures_getByKey(root, subBundleKey, NULL, &errorCode); - if (U_FAILURE(errorCode)) { -/* if (ures_hasNext(root)) { - errorCode = U_ZERO_ERROR; - subRootBundle = ures_getNextResource(root, NULL, &errorCode); - } - if (errorCode!=U_ZERO_ERROR) { - if (ures_getKey(currentBundle) != 0 && strcmp(ures_getKey(currentBundle), "zoneStrings") == 0) { - break; - } - else {*/ - if (subBundleKey == NULL - || (strcmp(subBundleKey, "TransliterateLATIN") != 0 /* Ignore these special cases */ - && strcmp(subBundleKey, "BreakDictionaryData") != 0)) - { - log_err("Can't open a resource with key \"%s\" in \"%s\" from root for locale \"%s\"\n", - subBundleKey, - ures_getKey(currentBundle), - locale); - } - continue; -/* } - }*/ - } - if (ures_getType(subRootBundle) != ures_getType(subBundle)) { - log_err("key \"%s\" in \"%s\" has a different type from root for locale \"%s\"\n" - "\troot=%d, locale=%d\n", - subBundleKey, - ures_getKey(currentBundle), - locale, - ures_getType(subRootBundle), - ures_getType(subBundle)); - continue; - } - else if (ures_getType(subBundle) == RES_ARRAY) { - UResourceBundle *subSubBundle = ures_getByIndex(subBundle, 0, NULL, &errorCode); - UResourceBundle *subSubRootBundle = ures_getByIndex(subRootBundle, 0, NULL, &errorCode); - - if (U_SUCCESS(errorCode) - && ures_getType(subSubBundle) == RES_ARRAY || ures_getType(subSubRootBundle) == RES_ARRAY) - { - /* TODO: Properly check for 2D arrays and zoneStrings */ - if (subBundleKey != NULL && strcmp(subBundleKey, "zoneStrings") == 0) { -/* int32_t minSize = ures_getSize(subBundle); - int32_t idx; - - for (idx = 0; idx < minSize; idx++) { - UResourceBundle *subSubBundleAtIndex = ures_getByIndex(subBundle, idx, NULL, &errorCode); - if (ures_getSize(subSubBundleAtIndex) != 6) { - log_err("zoneStrings at index %d has wrong size for locale \"%s\". array size=%d\n", - idx, - locale, - ures_getSize(subSubBundleAtIndex)); - } - ures_close(subSubBundleAtIndex); - }*/ - } - else { - /* Here is one of the recursive parts */ - TestKeyInRootRecursive(subRootBundle, subBundle, locale); - } - } - else { - int32_t minSize = ures_getSize(subRootBundle); - int32_t idx; - UBool sameArray = TRUE; - - if (minSize > ures_getSize(subBundle)) { - minSize = ures_getSize(subBundle); - } - - if ((subBundleKey == NULL - || (subBundleKey != NULL && strcmp(subBundleKey, "LocaleScript") != 0)) - && ures_getSize(subRootBundle) != ures_getSize(subBundle)) - { - log_err("Different size array with key \"%s\" in \"%s\" from root for locale \"%s\"\n" - "\troot array size=%d, locale array size=%d\n", - subBundleKey, - ures_getKey(currentBundle), - locale, - ures_getSize(subRootBundle), - ures_getSize(subBundle)); - } - - for (idx = 0; idx < minSize && sameArray; idx++) { - int32_t rootStrLen, localeStrLen; - const UChar *rootStr = ures_getStringByIndex(subRootBundle,idx,&rootStrLen,&errorCode); - const UChar *localeStr = ures_getStringByIndex(subBundle,idx,&localeStrLen,&errorCode); - if (rootStr && localeStr && U_SUCCESS(errorCode)) { - sameArray = (u_strcmp(rootStr, localeStr) == 0); - } - else { - log_err("Got a NULL string with key \"%s\" in \"%s\" at index %d for root or locale \"%s\"\n", - subBundleKey, - ures_getKey(currentBundle), - idx, - locale); - continue; - } - if (localeStr[0] == (UChar)0x20) { - log_err("key \"%s\" at index %d in \"%s\" starts with a space in locale \"%s\"\n", - subBundleKey, - idx, - ures_getKey(currentBundle), - locale); - } - else if (localeStr[localeStrLen - 1] == (UChar)0x20) { - log_err("key \"%s\" at index %d in \"%s\" ends with a space in locale \"%s\"\n", - subBundleKey, - idx, - ures_getKey(currentBundle), - locale); - } - else if (subBundleKey != NULL - && strcmp(subBundleKey, "DateTimePatterns") == 0) - { - int32_t quoted = 0; - const UChar *localeStrItr = localeStr; - while (*localeStrItr) { - if (*localeStrItr == (UChar)0x27 /* ' */) { - quoted++; - } - else if ((quoted % 2) == 0) { - /* Search for unquoted characters */ - if (*localeStrItr == (UChar)0x64 /* d */ - && (*localeStrItr == (UChar)0x6B /* k */ - || *localeStrItr == (UChar)0x48 /* H */ - || *localeStrItr == (UChar)0x6D /* m */ - || *localeStrItr == (UChar)0x73 /* s */ - || *localeStrItr == (UChar)0x53 /* S */ - || *localeStrItr == (UChar)0x61 /* a */ - || *localeStrItr == (UChar)0x68 /* h */ - || *localeStrItr == (UChar)0x7A /* z */)) - { - log_err("key \"%s\" at index %d has time pattern chars in date for locale \"%s\"\n", - subBundleKey, - idx, - locale); - } - else if (*localeStrItr == (UChar)0x6D /* m */ - && (*localeStrItr == (UChar)0x47 /* G */ - || *localeStrItr == (UChar)0x79 /* y */ - || *localeStrItr == (UChar)0x4D /* M */ - || *localeStrItr == (UChar)0x64 /* d */ - || *localeStrItr == (UChar)0x45 /* E */ - || *localeStrItr == (UChar)0x44 /* D */ - || *localeStrItr == (UChar)0x46 /* F */ - || *localeStrItr == (UChar)0x77 /* w */ - || *localeStrItr == (UChar)0x57 /* W */)) - { - log_err("key \"%s\" at index %d has date pattern chars in time for locale \"%s\"\n", - subBundleKey, - idx, - locale); - } - } - localeStrItr++; - } - } - } - if (sameArray) { - log_err("Arrays are the same with key \"%s\" in \"%s\" from root for locale \"%s\"\n", - subBundleKey, - ures_getKey(currentBundle), - locale); - } - } - ures_close(subSubBundle); - ures_close(subSubRootBundle); - } - else if (ures_getType(subBundle) == RES_STRING) { - int32_t len = 0; - const UChar *string = ures_getString(subBundle, &len, &errorCode); - if (U_FAILURE(errorCode) || string == NULL) { - log_err("Can't open a string with key \"%s\" in \"%s\" for locale \"%s\"\n", - subBundleKey, - ures_getKey(currentBundle), - locale); - } else if (string[0] == (UChar)0x20) { - log_err("key \"%s\" in \"%s\" starts with a space in locale \"%s\"\n", - subBundleKey, - ures_getKey(currentBundle), - locale); - } else if (string[len - 1] == (UChar)0x20) { - log_err("key \"%s\" in \"%s\" ends with a space in locale \"%s\"\n", - subBundleKey, - ures_getKey(currentBundle), - locale); - } else if (strcmp(subBundleKey, "localPatternChars") == 0 && len != 20) { - log_err("key \"%s\" has the wrong number of characters in locale \"%s\"\n", - subBundleKey, - locale); - } - /* No fallback was done. Check for duplicate data */ - /* The ures_* API does not do fallback of sub-resource bundles, - So we can't do this now. */ - else if (strcmp(locale, "root") != 0 && errorCode == U_ZERO_ERROR) { - - const UChar *rootString = ures_getString(subRootBundle, &len, &errorCode); - if (U_FAILURE(errorCode) || rootString == NULL) { - log_err("Can't open a string with key \"%s\" in \"%s\" in root\n", - ures_getKey(subRootBundle), - ures_getKey(currentBundle)); - continue; - } else if (u_strcmp(string, rootString) == 0) { - log_err("Found duplicate data with key \"%s\" in \"%s\" in locale \"%s\"\n", - ures_getKey(subRootBundle), - ures_getKey(currentBundle), - locale); - } - } - } - else if (ures_getType(subBundle) == RES_TABLE) { - /* Here is one of the recursive parts */ - TestKeyInRootRecursive(subRootBundle, subBundle, locale); - } - else if (ures_getType(subBundle) == RES_BINARY) { - /* Can't do anything to check it */ - /* We'll assume it's all correct */ - log_verbose("Skipping key \"%s\" in \"%s\" for locale \"%s\"\n", - subBundleKey, - ures_getKey(currentBundle), - locale); - } - else { - log_err("Type %d for key \"%s\" in \"%s\" is unknown for locale \"%s\"\n", - ures_getType(subBundle), - subBundleKey, - ures_getKey(currentBundle), - locale); - } - ures_close(subRootBundle); - ures_close(subBundle); - } -} - - -#ifdef WIN32 - -static void -testLCID(UResourceBundle *currentBundle, - const char *localeName) -{ - UErrorCode status = U_ZERO_ERROR; - uint32_t lcid; - uint32_t expectedLCID; - char lcidStringC[64] = {0}; - int32_t lcidStringLen = 0; - const UChar *lcidString = NULL; - - lcidString = ures_getStringByKey(currentBundle, "LocaleID", &lcidStringLen, &status); - - if (U_FAILURE(status)) { - log_err("ERROR: %s does not have a LocaleID (%s)\n", - localeName, u_errorName(status)); - return; - } - - u_UCharsToChars(lcidString, lcidStringC, lcidStringLen + 1); - expectedLCID = uprv_strtoul(lcidStringC, NULL, 16); - - lcid = T_convertToLCID(localeName, &status); - if (U_FAILURE(status)) { - if (expectedLCID == 0) { - log_verbose("INFO: %-5s does not have any LCID mapping\n", - localeName); - } - else { - log_err("ERROR: %-5s does not have an LCID mapping to 0x%.4X\n", - localeName, expectedLCID); - } - return; - } - - status = U_ZERO_ERROR; - uprv_strcpy(lcidStringC, T_convertToPosix(expectedLCID, &status)); - if (U_FAILURE(status)) { - log_err("ERROR: %.4x does not have a POSIX mapping due to %s\n", - expectedLCID, u_errorName(status)); - } - - if(lcid != expectedLCID) { - log_err("ERROR: %-5s wrongfully has 0x%.4x instead of 0x%.4x for LCID\n", - localeName, expectedLCID, lcid); - } - if(strcmp(localeName, lcidStringC) != 0) { - char langName[1024]; - char langLCID[1024]; - uloc_getLanguage(localeName, langName, sizeof(langName), &status); - uloc_getLanguage(lcidStringC, langLCID, sizeof(langLCID), &status); - - if (expectedLCID == lcid && strcmp(langName, langLCID) == 0) { - log_verbose("WARNING: %-5s resolves to %s (0x%.4x)\n", - localeName, lcidStringC, lcid); - } - else if (expectedLCID == lcid) { - log_err("ERROR: %-5s has 0x%.4x and the number resolves wrongfully to %s\n", - localeName, expectedLCID, lcidStringC); - } - else { - log_err("ERROR: %-5s has 0x%.4x and the number resolves wrongfully to %s. It should be 0x%x.\n", - localeName, expectedLCID, lcidStringC, lcid); - } - } -} - -#endif - -static void -TestLocaleStructure(void) { - UResourceBundle *root, *currentLocale; - int32_t locCount = uloc_countAvailable(); - int32_t locIndex; - UErrorCode errorCode = U_ZERO_ERROR; - - /* TODO: Compare against parent's data too. This code can't handle fallbacks that some tools do already. */ -/* char locName[ULOC_FULLNAME_CAPACITY]; - char *locNamePtr; - - for (locIndex = 0; locIndex < locCount; locIndex++) { - errorCode=U_ZERO_ERROR; - strcpy(locName, uloc_getAvailable(locIndex)); - locNamePtr = strrchr(locName, '_'); - if (locNamePtr) { - *locNamePtr = 0; - } - else { - strcpy(locName, "root"); - } - - root = ures_openDirect(NULL, locName, &errorCode); - if(U_FAILURE(errorCode)) { - log_err("Can't open %s\n", locName); - continue; - } -*/ - root = ures_openDirect(NULL, "root", &errorCode); - if(U_FAILURE(errorCode)) { - log_err("Can't open root\n"); - return; - } - for (locIndex = 0; locIndex < locCount; locIndex++) { - errorCode=U_ZERO_ERROR; - currentLocale = ures_open(NULL, uloc_getAvailable(locIndex), &errorCode); - if(errorCode != U_ZERO_ERROR) { - if(U_SUCCESS(errorCode)) { - if (strcmp(uloc_getAvailable(locIndex),"sv_FI_AL") != 0) { - /* It's installed, but there is no data. - It's installed for the g18n white paper [grhoten] */ - log_err("ERROR: Locale %-5s not installed, and it should be!\n", - uloc_getAvailable(locIndex)); - } - } else { - log_err("%%%%%%% Unexpected error %d in %s %%%%%%%", - u_errorName(errorCode), - uloc_getAvailable(locIndex)); - } - continue; - } - ures_getStringByKey(currentLocale, "Version", NULL, &errorCode); - if(errorCode != U_ZERO_ERROR) { - log_err("No version information is available for locale %s, and it should be!\n", - uloc_getAvailable(locIndex)); - } - else if (ures_getStringByKey(currentLocale, "Version", NULL, &errorCode)[0] == (UChar)(0x78)) { - log_err("The locale %s is experimental! It shouldn't be listed as an installed locale.\n", - uloc_getAvailable(locIndex)); - } - TestKeyInRootRecursive(root, currentLocale, uloc_getAvailable(locIndex)); -#ifdef WIN32 - testLCID(currentLocale, uloc_getAvailable(locIndex)); -#endif - ures_close(currentLocale); - } -} \ No newline at end of file