ICU-4739 check for resource bundle dependencies on parent bundles if the "no fallback" flag exists and is FALSE

X-SVN-Rev: 18837
This commit is contained in:
Markus Scherer 2005-11-29 00:13:56 +00:00
parent e08d580655
commit 3771029ec0
4 changed files with 103 additions and 15 deletions

View file

@ -428,6 +428,12 @@ main(int argc, char *argv[]) {
pkg->listItems(stdout);
}
/* check dependencies between items */
if(!pkg->checkDependencies()) {
/* some dependencies are not fulfilled */
return U_MISSING_RESOURCE_ERROR;
}
/* write the output .dat package if there are any modifications */
if(isModified) {
char outFilenameBuffer[1024]; // for auto-generated output filename, if necessary

View file

@ -1129,17 +1129,28 @@ Package::listItems(FILE *file) {
for(i=0; i<itemCount; ++i) {
fprintf(file, "%s\n", items[i].name);
enumDependencies(items+i);
}
}
void
Package::checkDependency(void *context, const char *itemName, const char *targetName) {
// TODO
// check dependency: make sure target is in the package
// list dependencies?
// check dependency: make sure the target item is in the package
Package *me=(Package *)context;
fprintf(stderr, "item %s depends on %s\n", itemName, targetName);
if(me->findItem(targetName)<0) {
me->isMissingItems=TRUE;
fprintf(stderr, "Item %s depends on missing item %s\n", itemName, targetName);
}
}
UBool
Package::checkDependencies() {
int32_t i;
isMissingItems=FALSE;
for(i=0; i<itemCount; ++i) {
enumDependencies(items+i);
}
return (UBool)!isMissingItems;
}
char *

View file

@ -105,6 +105,11 @@ public:
void listItems(FILE *file);
/*
* Check dependencies and return TRUE if all dependencies are fulfilled.
*/
UBool checkDependencies();
private:
void enumDependencies(Item *pItem);
@ -140,6 +145,9 @@ private:
const char *findPrefix, *findSuffix;
int32_t findPrefixLength, findSuffixLength;
int32_t findNextIndex;
// state for checkDependencies()
UBool isMissingItems;
};
U_NAMESPACE_END

View file

@ -64,17 +64,17 @@ readSwapUInt16(uint16_t x) {
/*
* assemble the target item name from the source item name, an ID
* and a prefix
* and a suffix
*/
static void
checkDependency(const char *itemName, const char *id, const char *suffix,
CheckDependency check, void *context,
UErrorCode *pErrorCode) {
checkIDSuffix(const char *itemName, const char *id, int32_t idLength, const char *suffix,
CheckDependency check, void *context,
UErrorCode *pErrorCode) {
char target[200];
const char *itemID;
int32_t treeLength, idLength, suffixLength, targetLength;
int32_t treeLength, suffixLength, targetLength;
// build the target string
// get the item basename
itemID=strrchr(itemName, '/');
if(itemID!=NULL) {
++itemID;
@ -82,12 +82,15 @@ checkDependency(const char *itemName, const char *id, const char *suffix,
itemID=itemName;
}
// build the target string
treeLength=(int32_t)(itemID-itemName);
idLength=(int32_t)strlen(id);
if(idLength<0) {
idLength=(int32_t)strlen(id);
}
suffixLength=(int32_t)strlen(suffix);
targetLength=treeLength+idLength+suffixLength;
if(targetLength>=(int32_t)sizeof(target)) {
fprintf(stderr, "icupkg/checkDependency(%s) alias target item name length %ld too long\n",
fprintf(stderr, "icupkg/checkIDSuffix(%s) alias target item name length %ld too long\n",
itemName, targetLength);
*pErrorCode=U_BUFFER_OVERFLOW_ERROR;
return;
@ -100,6 +103,47 @@ checkDependency(const char *itemName, const char *id, const char *suffix,
check(context, itemName, target);
}
/* assemble the target item name from the item's parent item name */
static void
checkParent(const char *itemName, CheckDependency check, void *context,
UErrorCode *pErrorCode) {
const char *itemID, *parent, *parentLimit, *suffix;
int32_t parentLength;
// get the item basename
itemID=strrchr(itemName, '/');
if(itemID!=NULL) {
++itemID;
} else {
itemID=itemName;
}
// get the item suffix
suffix=strrchr(itemID, '.');
if(suffix==NULL) {
// empty suffix, point to the end of the string
suffix=strrchr(itemID, 0);
}
// get the position of the last '_'
for(parentLimit=suffix; parentLimit>itemID && *--parentLimit!='_';) {}
if(parentLimit!=itemID) {
// get the parent item name by truncating the last part of this item's name */
parent=itemID;
parentLength=(int32_t)(parentLimit-itemID);
} else {
// no '_' in the item name: the parent is the root bundle
parent="root";
parentLength=4;
if((suffix-itemID)==parentLength && 0==memcmp(itemID, parent, parentLength)) {
// the item itself is "root", which does not depend on a parent
return;
}
}
checkIDSuffix(itemName, parent, parentLength, suffix, check, context, pErrorCode);
}
// get dependencies from resource bundles ---------------------------------- ***
static const char *const gAliasKey="%%ALIAS";
@ -254,7 +298,7 @@ ures_enumDependencies(const UDataSwapper *ds,
# error Unknown U_CHARSET_FAMILY value!
#endif
checkDependency(itemName, localeID, ".res", check, context, pErrorCode);
checkIDSuffix(itemName, localeID, -1, ".res", check, context, pErrorCode);
}
break;
case URES_TABLE:
@ -395,6 +439,25 @@ ures_enumDependencies(const UDataSwapper *ds,
rootRes, NULL, 0,
check, context,
pErrorCode);
/*
* if the bundle attributes are present and the nofallback flag is not set,
* then add the parent bundle as a dependency
*/
if(pInfo->formatVersion[1]>=1) {
int32_t indexes[URES_INDEX_TOP];
const int32_t *inIndexes;
inIndexes=(const int32_t *)inBundle+1;
indexes[URES_INDEX_LENGTH]=udata_readInt32(ds, inIndexes[URES_INDEX_LENGTH]);
if(indexes[URES_INDEX_LENGTH]>URES_INDEX_ATTRIBUTES) {
indexes[URES_INDEX_ATTRIBUTES]=udata_readInt32(ds, inIndexes[URES_INDEX_ATTRIBUTES]);
if(0==(indexes[URES_INDEX_ATTRIBUTES]&URES_ATT_NO_FALLBACK)) {
/* this bundle participates in locale fallback */
checkParent(itemName, check, context, pErrorCode);
}
}
}
}
// get dependencies from conversion tables --------------------------------- ***
@ -489,7 +552,7 @@ ucnv_enumDependencies(const UDataSwapper *ds,
}
ds->swapInvChars(ds, inMBCSHeader+1, baseNameLength+1, baseName, pErrorCode);
checkDependency(itemName, baseName, ".cnv", check, context, pErrorCode);
checkIDSuffix(itemName, baseName, -1, ".cnv", check, context, pErrorCode);
}
}
}