ICU-1616 Move the TestLocaleStructure test from crestest to cloctest
X-SVN-Rev: 7571
This commit is contained in:
parent
0e581f3cb4
commit
616ee23932
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -61,6 +61,8 @@ static void TestDisplayNames(void);
|
||||
**/
|
||||
static void TestVariantParsing(void);
|
||||
|
||||
static void TestLocaleStructure(void);
|
||||
|
||||
/**
|
||||
* routine to perform subtests, used by TestDisplayNames
|
||||
*/
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user