]> git.saurik.com Git - android/aapt.git/blobdiff - ResourceTable.cpp
Merge "Make AaptGroupEntry::getMncName accept mnc00"
[android/aapt.git] / ResourceTable.cpp
index 755b93bc24c54b83bb64efb3545629e3ef67645d..818c3c64cdb67033ad817b5b74ec01d4b3078973 100644 (file)
@@ -574,6 +574,7 @@ status_t parseAndAddBag(Bundle* bundle,
                         const String16& itemIdent,
                         int32_t curFormat,
                         bool isFormatted,
+                        const String16& product,
                         bool pseudolocalize,
                         const bool overwrite,
                         ResourceTable* outTable)
@@ -606,6 +607,32 @@ status_t parseAndAddBag(Bundle* bundle,
     return err;
 }
 
+/*
+ * Returns true if needle is one of the elements in the comma-separated list
+ * haystack, false otherwise.
+ */
+bool isInProductList(const String16& needle, const String16& haystack) {
+    const char16_t *needle2 = needle.string();
+    const char16_t *haystack2 = haystack.string();
+    size_t needlesize = needle.size();
+
+    while (*haystack2 != '\0') {
+        if (strncmp16(haystack2, needle2, needlesize) == 0) {
+            if (haystack2[needlesize] == '\0' || haystack2[needlesize] == ',') {
+                return true;
+            }
+        }
+
+        while (*haystack2 != '\0' && *haystack2 != ',') {
+            haystack2++;
+        }
+        if (*haystack2 == ',') {
+            haystack2++;
+        }
+    }
+
+    return false;
+}
 
 status_t parseAndAddEntry(Bundle* bundle,
                         const sp<AaptFile>& in,
@@ -618,6 +645,7 @@ status_t parseAndAddEntry(Bundle* bundle,
                         bool curIsStyled,
                         int32_t curFormat,
                         bool isFormatted,
+                        const String16& product,
                         bool pseudolocalize,
                         const bool overwrite,
                         ResourceTable* outTable)
@@ -634,6 +662,47 @@ status_t parseAndAddEntry(Bundle* bundle,
         return err;
     }
 
+    /*
+     * If a product type was specified on the command line
+     * and also in the string, and the two are not the same,
+     * return without adding the string.
+     */
+
+    const char *bundleProduct = bundle->getProduct();
+    if (bundleProduct == NULL) {
+        bundleProduct = "";
+    }
+
+    if (product.size() != 0) {
+        /*
+         * If the command-line-specified product is empty, only "default"
+         * matches.  Other variants are skipped.  This is so generation
+         * of the R.java file when the product is not known is predictable.
+         */
+
+        if (bundleProduct[0] == '\0') {
+            if (strcmp16(String16("default").string(), product.string()) != 0) {
+                return NO_ERROR;
+            }
+        } else {
+            /*
+             * The command-line product is not empty.
+             * If the product for this string is on the command-line list,
+             * it matches.  "default" also matches, but only if nothing
+             * else has matched already.
+             */
+
+            if (isInProductList(product, String16(bundleProduct))) {
+                ;
+            } else if (strcmp16(String16("default").string(), product.string()) == 0 &&
+                       !outTable->hasBagOrEntry(myPackage, curType, ident)) {
+                ;
+            } else {
+                return NO_ERROR;
+            }
+        }
+    }
+
     NOISY(printf("Adding resource entry l=%c%c c=%c%c orien=%d d=%d id=%s: %s\n",
                  config.language[0], config.language[1],
                  config.country[0], config.country[1],
@@ -1253,6 +1322,22 @@ status_t compileResourceFile(Bundle* bundle,
                     }
                 }
             } else if (strcmp16(block.getElementName(&len), string_array16.string()) == 0) {
+                // Check whether these strings need valid formats.
+                // (simplified form of what string16 does above)
+                size_t n = block.getAttributeCount();
+                for (size_t i = 0; i < n; i++) {
+                    size_t length;
+                    const uint16_t* attr = block.getAttributeName(i, &length);
+                    if (strcmp16(attr, translatable16.string()) == 0
+                            || strcmp16(attr, formatted16.string()) == 0) {
+                        const uint16_t* value = block.getAttributeStringValue(i, &length);
+                        if (strcmp16(value, false16.string()) == 0) {
+                            curIsFormatted = false;
+                            break;
+                        }
+                    }
+                }
+
                 curTag = &string_array16;
                 curType = array16;
                 curFormat = ResTable_map::TYPE_REFERENCE|ResTable_map::TYPE_STRING;
@@ -1283,6 +1368,12 @@ status_t compileResourceFile(Bundle* bundle,
                 hasErrors = localHasErrors = true;
             }
 
+            String16 product;
+            identIdx = block.indexOfAttribute(NULL, "product");
+            if (identIdx >= 0) {
+                product = String16(block.getAttributeStringValue(identIdx, &len));
+            }
+
             String16 comment(block.getComment(&len) ? block.getComment(&len) : nulStr);
             
             if (curIsBag) {
@@ -1374,7 +1465,7 @@ status_t compileResourceFile(Bundle* bundle,
 
                         err = parseAndAddBag(bundle, in, &block, curParams, myPackage, curType,
                                 ident, parentIdent, itemIdent, curFormat, curIsFormatted,
-                                false, overwrite, outTable);
+                                product, false, overwrite, outTable);
                         if (err == NO_ERROR) {
                             if (curIsPseudolocalizable && localeIsDefined(curParams)
                                     && bundle->getPseudolocalize()) {
@@ -1383,7 +1474,7 @@ status_t compileResourceFile(Bundle* bundle,
                                 block.setPosition(parserPosition);
                                 err = parseAndAddBag(bundle, in, &block, pseudoParams, myPackage,
                                         curType, ident, parentIdent, itemIdent, curFormat,
-                                        curIsFormatted, true, overwrite, outTable);
+                                        curIsFormatted, product, true, overwrite, outTable);
 #endif
                             }
                         } 
@@ -1407,7 +1498,7 @@ status_t compileResourceFile(Bundle* bundle,
 
                 err = parseAndAddEntry(bundle, in, &block, curParams, myPackage, curType, ident,
                         *curTag, curIsStyled, curFormat, curIsFormatted,
-                        false, overwrite, outTable);
+                        product, false, overwrite, outTable);
 
                 if (err < NO_ERROR) { // Why err < NO_ERROR instead of err != NO_ERROR?
                     hasErrors = localHasErrors = true;
@@ -1419,7 +1510,8 @@ status_t compileResourceFile(Bundle* bundle,
                         block.setPosition(parserPosition);
                         err = parseAndAddEntry(bundle, in, &block, pseudoParams, myPackage, curType,
                                 ident, *curTag, curIsStyled, curFormat,
-                                curIsFormatted, true, overwrite, outTable);
+                                curIsFormatted, product,
+                                true, overwrite, outTable);
                         if (err != NO_ERROR) {
                             hasErrors = localHasErrors = true;
                         }
@@ -1648,13 +1740,6 @@ status_t ResourceTable::startBag(const SourcePos& sourcePos,
     
     // If a parent is explicitly specified, set it.
     if (bagParent.size() > 0) {
-        String16 curPar = e->getParent();
-        if (curPar.size() > 0 && curPar != bagParent) {
-            sourcePos.error("Conflicting parents specified, was '%s', now '%s'\n",
-                            String8(e->getParent()).string(),
-                            String8(bagParent).string());
-            return UNKNOWN_ERROR;
-        }
         e->setParent(bagParent);
     }
 
@@ -1702,13 +1787,6 @@ status_t ResourceTable::addBag(const SourcePos& sourcePos,
 
     // If a parent is explicitly specified, set it.
     if (bagParent.size() > 0) {
-        String16 curPar = e->getParent();
-        if (curPar.size() > 0 && curPar != bagParent) {
-            sourcePos.error("Conflicting parents specified, was '%s', now '%s'\n",
-                    String8(e->getParent()).string(),
-                    String8(bagParent).string());
-            return UNKNOWN_ERROR;
-        }
         e->setParent(bagParent);
     }