ICU-1616 Move the TestLocaleStructure test from crestest to cloctest

X-SVN-Rev: 7571
This commit is contained in:
George Rhoten 2002-02-05 23:47:41 +00:00
parent 0e581f3cb4
commit 616ee23932
3 changed files with 410 additions and 401 deletions

View File

@ -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);
}
}

View File

@ -61,6 +61,8 @@ static void TestDisplayNames(void);
**/
static void TestVariantParsing(void);
static void TestLocaleStructure(void);
/**
* routine to perform subtests, used by TestDisplayNames
*/

View File

@ -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);
}
}