Coordinator.cpp revision 0d0f9a2e0195a8609f1939c35bd8907253b68249
15345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber#include "Coordinator.h" 25345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber 35345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber#include "AST.h" 45345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber 55345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber#include <android-base/logging.h> 6dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber#include <iterator> 7d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber#include <sys/dir.h> 8d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber#include <sys/stat.h> 95345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber 100d0f9a2e0195a8609f1939c35bd8907253b68249Andreas Huberextern android::status_t parseFile(android::AST *ast); 115345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber 125345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Hubernamespace android { 135345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber 14dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas HuberCoordinator::Coordinator( 15dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber const std::vector<std::string> &packageRootPaths, 16dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber const std::vector<std::string> &packageRoots) 17dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber : mPackageRootPaths(packageRootPaths), 18dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber mPackageRoots(packageRoots) { 19dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber // empty 20dc981333b38f47f416b9b810dc80e5cf2d7ac68aAndreas Huber} 21dc981333b38f47f416b9b810dc80e5cf2d7ac68aAndreas Huber 22dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas HuberCoordinator::~Coordinator() { 23dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber // empty 24dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber} 255345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber 2668f24590cda230fb92eac44ed0247f54f9b31ad0Andreas HuberAST *Coordinator::parse(const FQName &fqName) { 2768f24590cda230fb92eac44ed0247f54f9b31ad0Andreas Huber CHECK(fqName.isFullyQualified()); 2868f24590cda230fb92eac44ed0247f54f9b31ad0Andreas Huber 296e584b70065ce37615980aba5ed60d27a54da1c3Andreas Huber // LOG(INFO) << "parsing " << fqName.string(); 306e584b70065ce37615980aba5ed60d27a54da1c3Andreas Huber 3168f24590cda230fb92eac44ed0247f54f9b31ad0Andreas Huber ssize_t index = mCache.indexOfKey(fqName); 325345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber if (index >= 0) { 335345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber AST *ast = mCache.valueAt(index); 345345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber 355345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber return ast; 365345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber } 375345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber 3868f24590cda230fb92eac44ed0247f54f9b31ad0Andreas Huber // Add this to the cache immediately, so we can discover circular imports. 3968f24590cda230fb92eac44ed0247f54f9b31ad0Andreas Huber mCache.add(fqName, NULL); 4068f24590cda230fb92eac44ed0247f54f9b31ad0Andreas Huber 4168f24590cda230fb92eac44ed0247f54f9b31ad0Andreas Huber if (fqName.name() != "types") { 4268f24590cda230fb92eac44ed0247f54f9b31ad0Andreas Huber // Any interface file implicitly imports its package's types.hal. 4368f24590cda230fb92eac44ed0247f54f9b31ad0Andreas Huber FQName typesName(fqName.package(), fqName.version(), "types"); 4468f24590cda230fb92eac44ed0247f54f9b31ad0Andreas Huber (void)parse(typesName); 4568f24590cda230fb92eac44ed0247f54f9b31ad0Andreas Huber 4668f24590cda230fb92eac44ed0247f54f9b31ad0Andreas Huber // fall through. 4768f24590cda230fb92eac44ed0247f54f9b31ad0Andreas Huber } 4868f24590cda230fb92eac44ed0247f54f9b31ad0Andreas Huber 49dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber std::string path = getPackagePath(fqName); 50dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber 5168f24590cda230fb92eac44ed0247f54f9b31ad0Andreas Huber path.append(fqName.name()); 5268f24590cda230fb92eac44ed0247f54f9b31ad0Andreas Huber path.append(".hal"); 535345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber 540d0f9a2e0195a8609f1939c35bd8907253b68249Andreas Huber AST *ast = new AST(this, path); 550d0f9a2e0195a8609f1939c35bd8907253b68249Andreas Huber status_t err = parseFile(ast); 5668f24590cda230fb92eac44ed0247f54f9b31ad0Andreas Huber 5768f24590cda230fb92eac44ed0247f54f9b31ad0Andreas Huber if (err != OK) { 586e584b70065ce37615980aba5ed60d27a54da1c3Andreas Huber // LOG(ERROR) << "parsing '" << path << "' FAILED."; 596e584b70065ce37615980aba5ed60d27a54da1c3Andreas Huber 6068f24590cda230fb92eac44ed0247f54f9b31ad0Andreas Huber delete ast; 6168f24590cda230fb92eac44ed0247f54f9b31ad0Andreas Huber ast = NULL; 625345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber 6368f24590cda230fb92eac44ed0247f54f9b31ad0Andreas Huber return NULL; 6468f24590cda230fb92eac44ed0247f54f9b31ad0Andreas Huber } 6568f24590cda230fb92eac44ed0247f54f9b31ad0Andreas Huber 66a2723d26427f7db19777dfed330047253e7a4e1bAndreas Huber if (ast->package().package() != fqName.package() 67a2723d26427f7db19777dfed330047253e7a4e1bAndreas Huber || ast->package().version() != fqName.version()) { 6870a59e1dc3dcf32f791d2dd7966111d4adf32ecaAndreas Huber fprintf(stderr, 6970a59e1dc3dcf32f791d2dd7966111d4adf32ecaAndreas Huber "ERROR: File at '%s' does not match expected package and/or " 700d0f9a2e0195a8609f1939c35bd8907253b68249Andreas Huber "version.\n", 7170a59e1dc3dcf32f791d2dd7966111d4adf32ecaAndreas Huber path.c_str()); 72a2723d26427f7db19777dfed330047253e7a4e1bAndreas Huber 73a2723d26427f7db19777dfed330047253e7a4e1bAndreas Huber err = UNKNOWN_ERROR; 74a2723d26427f7db19777dfed330047253e7a4e1bAndreas Huber } else { 75a2723d26427f7db19777dfed330047253e7a4e1bAndreas Huber std::string ifaceName; 76a2723d26427f7db19777dfed330047253e7a4e1bAndreas Huber if (ast->isInterface(&ifaceName)) { 77a2723d26427f7db19777dfed330047253e7a4e1bAndreas Huber if (fqName.name() == "types") { 7870a59e1dc3dcf32f791d2dd7966111d4adf32ecaAndreas Huber fprintf(stderr, 7970a59e1dc3dcf32f791d2dd7966111d4adf32ecaAndreas Huber "ERROR: File at '%s' declares an interface '%s' " 800d0f9a2e0195a8609f1939c35bd8907253b68249Andreas Huber "instead of the expected types common to the package.\n", 8170a59e1dc3dcf32f791d2dd7966111d4adf32ecaAndreas Huber path.c_str(), 8270a59e1dc3dcf32f791d2dd7966111d4adf32ecaAndreas Huber ifaceName.c_str()); 83a2723d26427f7db19777dfed330047253e7a4e1bAndreas Huber 84a2723d26427f7db19777dfed330047253e7a4e1bAndreas Huber err = UNKNOWN_ERROR; 85a2723d26427f7db19777dfed330047253e7a4e1bAndreas Huber } else if (ifaceName != fqName.name()) { 8670a59e1dc3dcf32f791d2dd7966111d4adf32ecaAndreas Huber fprintf(stderr, 8770a59e1dc3dcf32f791d2dd7966111d4adf32ecaAndreas Huber "ERROR: File at '%s' does not declare interface type " 880d0f9a2e0195a8609f1939c35bd8907253b68249Andreas Huber "'%s'.\n", 8970a59e1dc3dcf32f791d2dd7966111d4adf32ecaAndreas Huber path.c_str(), 9070a59e1dc3dcf32f791d2dd7966111d4adf32ecaAndreas Huber fqName.name().c_str()); 91a2723d26427f7db19777dfed330047253e7a4e1bAndreas Huber 92a2723d26427f7db19777dfed330047253e7a4e1bAndreas Huber err = UNKNOWN_ERROR; 93a2723d26427f7db19777dfed330047253e7a4e1bAndreas Huber } 94a2723d26427f7db19777dfed330047253e7a4e1bAndreas Huber } else if (fqName.name() != "types") { 9570a59e1dc3dcf32f791d2dd7966111d4adf32ecaAndreas Huber fprintf(stderr, 9670a59e1dc3dcf32f791d2dd7966111d4adf32ecaAndreas Huber "ERROR: File at '%s' declares types rather than the " 970d0f9a2e0195a8609f1939c35bd8907253b68249Andreas Huber "expected interface type '%s'.\n", 9870a59e1dc3dcf32f791d2dd7966111d4adf32ecaAndreas Huber path.c_str(), 9970a59e1dc3dcf32f791d2dd7966111d4adf32ecaAndreas Huber fqName.name().c_str()); 100a2723d26427f7db19777dfed330047253e7a4e1bAndreas Huber 101a2723d26427f7db19777dfed330047253e7a4e1bAndreas Huber err = UNKNOWN_ERROR; 102a2723d26427f7db19777dfed330047253e7a4e1bAndreas Huber } 103a2723d26427f7db19777dfed330047253e7a4e1bAndreas Huber } 104a2723d26427f7db19777dfed330047253e7a4e1bAndreas Huber 105a2723d26427f7db19777dfed330047253e7a4e1bAndreas Huber if (err != OK) { 106a2723d26427f7db19777dfed330047253e7a4e1bAndreas Huber delete ast; 107a2723d26427f7db19777dfed330047253e7a4e1bAndreas Huber ast = NULL; 108a2723d26427f7db19777dfed330047253e7a4e1bAndreas Huber 109a2723d26427f7db19777dfed330047253e7a4e1bAndreas Huber return NULL; 110a2723d26427f7db19777dfed330047253e7a4e1bAndreas Huber } 111a2723d26427f7db19777dfed330047253e7a4e1bAndreas Huber 11268f24590cda230fb92eac44ed0247f54f9b31ad0Andreas Huber mCache.add(fqName, ast); 1135345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber 1145345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber return ast; 1155345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber} 1165345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber 117dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huberstd::vector<std::string>::const_iterator 118dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas HuberCoordinator::findPackageRoot(const FQName &fqName) const { 1195345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber CHECK(!fqName.package().empty()); 1205345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber CHECK(!fqName.version().empty()); 1215345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber 122dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber // Find the right package prefix and path for this FQName. For 123dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber // example, if FQName is "android.hardware.nfc@1.0::INfc", and the 124dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber // prefix:root is set to [ "android.hardware:hardware/interfaces", 125dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber // "vendor.qcom.hardware:vendor/qcom"], then we will identify the 126dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber // prefix "android.hardware" and the package root 127dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber // "hardware/interfaces". 128dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber 129dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber // TODO: This now returns on the first match. Throw an error if 130dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber // there are multiple hits. 131dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber auto it = mPackageRoots.begin(); 132dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber for (; it != mPackageRoots.end(); it++) { 133dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber if (fqName.package().find(*it) != std::string::npos) { 134dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber break; 135dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber } 136dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber } 137dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber CHECK(it != mPackageRoots.end()); 138dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber 139dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber return it; 140dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber} 141dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber 142dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huberstd::string Coordinator::getPackageRoot(const FQName &fqName) const { 143dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber auto it = findPackageRoot(fqName); 144dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber auto prefix = *it; 145dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber return prefix; 146dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber} 147dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber 1485bb14024064a51a044e51c14466e5b2ae8352505Iliyan Malchevstd::string Coordinator::getPackageRootPath(const FQName &fqName) const { 1495bb14024064a51a044e51c14466e5b2ae8352505Iliyan Malchev auto it = findPackageRoot(fqName); 1505bb14024064a51a044e51c14466e5b2ae8352505Iliyan Malchev auto root = mPackageRootPaths[std::distance(mPackageRoots.begin(), it)]; 1515bb14024064a51a044e51c14466e5b2ae8352505Iliyan Malchev return root; 1525bb14024064a51a044e51c14466e5b2ae8352505Iliyan Malchev} 1535bb14024064a51a044e51c14466e5b2ae8352505Iliyan Malchev 154dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huberstd::string Coordinator::getPackagePath( 155dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber const FQName &fqName, bool relative) const { 156dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber 157dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber auto it = findPackageRoot(fqName); 158dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber auto prefix = *it; 159dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber auto root = mPackageRootPaths[std::distance(mPackageRoots.begin(), it)]; 160dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber 161dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber // Make sure the prefix ends on a '.' and the root path on a '/' 162dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber if ((*--prefix.end()) != '.') { 163dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber prefix += '.'; 164dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber } 165dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber 166dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber if ((*--root.end()) != '/') { 167dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber root += '/'; 168dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber } 169dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber 170dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber // Given FQName of "android.hardware.nfc@1.0::IFoo" and a prefix 171dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber // "android.hardware.", the suffix is "nfc@1.0::IFoo". 172dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber const std::string packageSuffix = fqName.package().substr(prefix.length()); 1735345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber 174881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber std::string packagePath; 175881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber if (!relative) { 176dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber packagePath = root; 177881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber } 1785345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber 1795345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber size_t startPos = 0; 1805345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber size_t dotPos; 1815345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber while ((dotPos = packageSuffix.find('.', startPos)) != std::string::npos) { 1825345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber packagePath.append(packageSuffix.substr(startPos, dotPos - startPos)); 1835345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber packagePath.append("/"); 1845345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber 1855345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber startPos = dotPos + 1; 1865345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber } 1875345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber CHECK_LT(startPos + 1, packageSuffix.length()); 1885345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber packagePath.append(packageSuffix.substr(startPos)); 1895345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber packagePath.append("/"); 1905345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber 1915345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber CHECK_EQ(fqName.version().find('@'), 0u); 1925345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber packagePath.append(fqName.version().substr(1)); 1935345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber packagePath.append("/"); 1945345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber 1955345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber return packagePath; 1965345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber} 1975345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber 198fd4afabde8fb9bbdd0021addeb9fbb62428f2c17Andreas HuberType *Coordinator::lookupType(const FQName &fqName) const { 1995345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber // Fully qualified. 20068f24590cda230fb92eac44ed0247f54f9b31ad0Andreas Huber CHECK(fqName.isFullyQualified()); 2015345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber 2025345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber std::string topType; 2035345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber size_t dotPos = fqName.name().find('.'); 2045345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber if (dotPos == std::string::npos) { 2055345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber topType = fqName.name(); 2065345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber } else { 2075345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber topType = fqName.name().substr(0, dotPos); 2085345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber } 2095345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber 21068f24590cda230fb92eac44ed0247f54f9b31ad0Andreas Huber // Assuming {topType} is the name of an interface type, let's see if the 21168f24590cda230fb92eac44ed0247f54f9b31ad0Andreas Huber // associated {topType}.hal file was imported. 21268f24590cda230fb92eac44ed0247f54f9b31ad0Andreas Huber FQName ifaceName(fqName.package(), fqName.version(), topType); 21368f24590cda230fb92eac44ed0247f54f9b31ad0Andreas Huber ssize_t index = mCache.indexOfKey(ifaceName); 2145345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber if (index >= 0) { 2155345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber AST *ast = mCache.valueAt(index); 2166e584b70065ce37615980aba5ed60d27a54da1c3Andreas Huber CHECK(ast != NULL); 2176e584b70065ce37615980aba5ed60d27a54da1c3Andreas Huber 2185345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber Type *type = ast->lookupTypeInternal(fqName.name()); 2195345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber 2205345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber if (type != NULL) { 221fd4afabde8fb9bbdd0021addeb9fbb62428f2c17Andreas Huber return type->ref(); 2225345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber } 2235345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber } 2245345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber 22568f24590cda230fb92eac44ed0247f54f9b31ad0Andreas Huber FQName typesName(fqName.package(), fqName.version(), "types"); 22668f24590cda230fb92eac44ed0247f54f9b31ad0Andreas Huber index = mCache.indexOfKey(typesName); 2275345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber if (index >= 0) { 2285345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber AST *ast = mCache.valueAt(index); 2296e584b70065ce37615980aba5ed60d27a54da1c3Andreas Huber if (ast != NULL) { 2306e584b70065ce37615980aba5ed60d27a54da1c3Andreas Huber // ast could be NULL if types.hal didn't exist, which is valid. 2316e584b70065ce37615980aba5ed60d27a54da1c3Andreas Huber Type *type = ast->lookupTypeInternal(fqName.name()); 2325345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber 2336e584b70065ce37615980aba5ed60d27a54da1c3Andreas Huber if (type != NULL) { 234fd4afabde8fb9bbdd0021addeb9fbb62428f2c17Andreas Huber return type->ref(); 2356e584b70065ce37615980aba5ed60d27a54da1c3Andreas Huber } 2365345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber } 2375345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber } 2385345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber 2395345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber return NULL; 2405345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber} 2415345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber 242d2943e11533697b97aa5330f05fc144493748c0bAndreas Huberstatus_t Coordinator::getPackageInterfaceFiles( 243d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber const FQName &package, 244d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber std::vector<std::string> *fileNames) const { 245d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber fileNames->clear(); 2466cb08cf9f021a01d9d2b1eaec6729aac6ae70708Andreas Huber 247d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber const std::string packagePath = getPackagePath(package); 248d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber 249d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber DIR *dir = opendir(packagePath.c_str()); 250d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber 251d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber if (dir == NULL) { 252d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber return -errno; 253d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber } 254d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber 255d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber struct dirent *ent; 256d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber while ((ent = readdir(dir)) != NULL) { 257d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber if (ent->d_type != DT_REG) { 2586cb08cf9f021a01d9d2b1eaec6729aac6ae70708Andreas Huber continue; 2596cb08cf9f021a01d9d2b1eaec6729aac6ae70708Andreas Huber } 2606cb08cf9f021a01d9d2b1eaec6729aac6ae70708Andreas Huber 261d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber const auto suffix = ".hal"; 262d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber const auto suffix_len = std::strlen(suffix); 263d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber const auto d_namelen = strlen(ent->d_name); 264e61e3f7b138a992047a60c4b8c27f1c752ed57baAndreas Huber 265d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber if (d_namelen < suffix_len 266d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber || strcmp(ent->d_name + d_namelen - suffix_len, suffix)) { 267d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber continue; 268e61e3f7b138a992047a60c4b8c27f1c752ed57baAndreas Huber } 269d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber 270d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber fileNames->push_back(std::string(ent->d_name, d_namelen - suffix_len)); 271e61e3f7b138a992047a60c4b8c27f1c752ed57baAndreas Huber } 272e61e3f7b138a992047a60c4b8c27f1c752ed57baAndreas Huber 273d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber closedir(dir); 274d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber dir = NULL; 275d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber 276e61e3f7b138a992047a60c4b8c27f1c752ed57baAndreas Huber return OK; 277e61e3f7b138a992047a60c4b8c27f1c752ed57baAndreas Huber} 278e61e3f7b138a992047a60c4b8c27f1c752ed57baAndreas Huber 2795bb14024064a51a044e51c14466e5b2ae8352505Iliyan Malchevstatus_t Coordinator::appendPackageInterfacesToSet( 280d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber const FQName &package, 281d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber std::vector<FQName> *packageInterfaces) const { 282d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber packageInterfaces->clear(); 283d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber 284d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber std::vector<std::string> fileNames; 285d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber status_t err = getPackageInterfaceFiles(package, &fileNames); 286d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber 287d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber if (err != OK) { 288d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber return err; 289d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber } 290d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber 291d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber for (const auto &fileName : fileNames) { 292d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber FQName subFQName( 293d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber package.package() + package.version() + "::" + fileName); 294d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber 295d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber if (!subFQName.isValid()) { 296d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber LOG(WARNING) 297d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber << "Whole-package import encountered invalid filename '" 298d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber << fileName 299d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber << "' in package " 300d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber << package.package() 301d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber << package.version(); 302d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber 303d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber continue; 304d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber } 305d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber 306d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber packageInterfaces->push_back(subFQName); 307d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber } 308d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber 309d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber return OK; 310d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber} 311d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber 312d2943e11533697b97aa5330f05fc144493748c0bAndreas Huberstd::string Coordinator::convertPackageRootToPath(const FQName &fqName) const { 313d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber std::string packageRoot = getPackageRoot(fqName); 314d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber 315d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber if (*(packageRoot.end()--) != '.') { 316d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber packageRoot += '.'; 317d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber } 318d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber 319d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber std::replace(packageRoot.begin(), packageRoot.end(), '.', '/'); 320d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber 321d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber return packageRoot; // now converted to a path 322d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber} 323d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber 324d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber// static 325d2943e11533697b97aa5330f05fc144493748c0bAndreas Huberbool Coordinator::MakeParentHierarchy(const std::string &path) { 326d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber static const mode_t kMode = 0755; 327d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber 328d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber size_t start = 1; // Ignore leading '/' 329d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber size_t slashPos; 330d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber while ((slashPos = path.find("/", start)) != std::string::npos) { 331d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber std::string partial = path.substr(0, slashPos); 332d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber 333d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber struct stat st; 334d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber if (stat(partial.c_str(), &st) < 0) { 335d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber if (errno != ENOENT) { 336d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber return false; 337d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber } 338d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber 339d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber int res = mkdir(partial.c_str(), kMode); 340d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber if (res < 0) { 341d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber return false; 342d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber } 343d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber } else if (!S_ISDIR(st.st_mode)) { 344d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber return false; 345d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber } 346d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber 347d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber start = slashPos + 1; 348d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber } 349d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber 350d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber return true; 351d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber} 352d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber 3535345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber} // namespace android 3545345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber 355