diff options
-rw-r--r-- | tools/aapt/ResourceTable.cpp | 64 | ||||
-rw-r--r-- | tools/aapt/ResourceTable.h | 12 |
2 files changed, 58 insertions, 18 deletions
diff --git a/tools/aapt/ResourceTable.cpp b/tools/aapt/ResourceTable.cpp index e87c7d40f1d4..f979c8423500 100644 --- a/tools/aapt/ResourceTable.cpp +++ b/tools/aapt/ResourceTable.cpp @@ -308,29 +308,13 @@ struct PendingAttribute } added = true; - String16 attr16("attr"); - - if (outTable->hasBagOrEntry(myPackage, attr16, ident)) { + if (!outTable->makeAttribute(myPackage, ident, sourcePos, type, comment, appendComment)) { sourcePos.error("Attribute \"%s\" has already been defined\n", String8(ident).string()); hasErrors = true; return UNKNOWN_ERROR; } - - char numberStr[16]; - sprintf(numberStr, "%d", type); - status_t err = outTable->addBag(sourcePos, myPackage, - attr16, ident, String16(""), - String16("^type"), - String16(numberStr), NULL, NULL); - if (err != NO_ERROR) { - hasErrors = true; - return err; - } - outTable->appendComment(myPackage, attr16, ident, comment, appendComment); - //printf("Attribute %s comment: %s\n", String8(ident).string(), - // String8(comment).string()); - return err; + return UNKNOWN_ERROR; } }; @@ -2115,6 +2099,50 @@ bool ResourceTable::appendTypeComment(const String16& package, return false; } +bool ResourceTable::makeAttribute(const String16& package, + const String16& name, + const SourcePos& source, + int32_t format, + const String16& comment, + bool shouldAppendComment) { + const String16 attr16("attr"); + + // First look for this in the included resources... + uint32_t rid = mAssets->getIncludedResources() + .identifierForName(name.string(), name.size(), + attr16.string(), attr16.size(), + package.string(), package.size()); + if (rid != 0) { + return false; + } + + sp<ResourceTable::Entry> entry = getEntry(package, attr16, name, source, false); + if (entry == NULL) { + return false; + } + + if (entry->makeItABag(source) != NO_ERROR) { + return false; + } + + const String16 formatKey16("^type"); + const String16 formatValue16(String8::format("%d", format)); + + ssize_t idx = entry->getBag().indexOfKey(formatKey16); + if (idx >= 0) { + // We have already set a format for this attribute, check if they are different. + // We allow duplicate attribute definitions so long as they are identical. + // This is to ensure interoperation with libraries that define the same generic attribute. + if (entry->getBag().valueAt(idx).value != formatValue16) { + return false; + } + } else { + entry->addToBag(source, formatKey16, formatValue16); + } + appendComment(package, attr16, name, comment, shouldAppendComment); + return true; +} + void ResourceTable::canAddEntry(const SourcePos& pos, const String16& package, const String16& type, const String16& name) { diff --git a/tools/aapt/ResourceTable.h b/tools/aapt/ResourceTable.h index 4b7b3cdcef2b..cf1e992ec330 100644 --- a/tools/aapt/ResourceTable.h +++ b/tools/aapt/ResourceTable.h @@ -571,6 +571,18 @@ public: void getDensityVaryingResources(KeyedVector<Symbol, Vector<SymbolDefinition> >& resources); + /** + * Make an attribute with the specified format. If another attribute with the same name but + * different format exists, this method returns false. If the name is not taken, or if the + * format is identical, this returns true. + */ + bool makeAttribute(const String16& package, + const String16& name, + const SourcePos& source, + int32_t format, + const String16& comment, + bool appendComment); + private: void writePublicDefinitions(const String16& package, FILE* fp, bool pub); sp<Package> getPackage(const String16& package); |