Coordinator.cpp revision 5bb14024064a51a044e51c14466e5b2ae8352505
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 1068f24590cda230fb92eac44ed0247f54f9b31ad0Andreas Huberextern android::status_t parseFile(android::AST *ast, const char *path); 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 545345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber AST *ast = new AST(this); 5568f24590cda230fb92eac44ed0247f54f9b31ad0Andreas Huber status_t err = parseFile(ast, path.c_str()); 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()) { 68a2723d26427f7db19777dfed330047253e7a4e1bAndreas Huber LOG(ERROR) 69a2723d26427f7db19777dfed330047253e7a4e1bAndreas Huber << "File at '" << path << "' does not match expected package " 70a2723d26427f7db19777dfed330047253e7a4e1bAndreas Huber << "and/or version."; 71a2723d26427f7db19777dfed330047253e7a4e1bAndreas Huber 72a2723d26427f7db19777dfed330047253e7a4e1bAndreas Huber err = UNKNOWN_ERROR; 73a2723d26427f7db19777dfed330047253e7a4e1bAndreas Huber } else { 74a2723d26427f7db19777dfed330047253e7a4e1bAndreas Huber std::string ifaceName; 75a2723d26427f7db19777dfed330047253e7a4e1bAndreas Huber if (ast->isInterface(&ifaceName)) { 76a2723d26427f7db19777dfed330047253e7a4e1bAndreas Huber if (fqName.name() == "types") { 77a2723d26427f7db19777dfed330047253e7a4e1bAndreas Huber LOG(ERROR) 78a2723d26427f7db19777dfed330047253e7a4e1bAndreas Huber << "File at '" << path << "' declares an interface '" 79a2723d26427f7db19777dfed330047253e7a4e1bAndreas Huber << ifaceName 80a2723d26427f7db19777dfed330047253e7a4e1bAndreas Huber << "' instead of the expected types common to the package."; 81a2723d26427f7db19777dfed330047253e7a4e1bAndreas Huber 82a2723d26427f7db19777dfed330047253e7a4e1bAndreas Huber err = UNKNOWN_ERROR; 83a2723d26427f7db19777dfed330047253e7a4e1bAndreas Huber } else if (ifaceName != fqName.name()) { 84a2723d26427f7db19777dfed330047253e7a4e1bAndreas Huber LOG(ERROR) 85a2723d26427f7db19777dfed330047253e7a4e1bAndreas Huber << "File at '" << path << "' does not declare interface type '" 86a2723d26427f7db19777dfed330047253e7a4e1bAndreas Huber << fqName.name() 87a2723d26427f7db19777dfed330047253e7a4e1bAndreas Huber << "'."; 88a2723d26427f7db19777dfed330047253e7a4e1bAndreas Huber 89a2723d26427f7db19777dfed330047253e7a4e1bAndreas Huber err = UNKNOWN_ERROR; 90a2723d26427f7db19777dfed330047253e7a4e1bAndreas Huber } 91a2723d26427f7db19777dfed330047253e7a4e1bAndreas Huber } else if (fqName.name() != "types") { 92a2723d26427f7db19777dfed330047253e7a4e1bAndreas Huber LOG(ERROR) 93a2723d26427f7db19777dfed330047253e7a4e1bAndreas Huber << "File at '" << path << "' declares types rather than the " 94a2723d26427f7db19777dfed330047253e7a4e1bAndreas Huber << "expected interface type '" << fqName.name() << "'."; 95a2723d26427f7db19777dfed330047253e7a4e1bAndreas Huber 96a2723d26427f7db19777dfed330047253e7a4e1bAndreas Huber err = UNKNOWN_ERROR; 97a2723d26427f7db19777dfed330047253e7a4e1bAndreas Huber } 98a2723d26427f7db19777dfed330047253e7a4e1bAndreas Huber } 99a2723d26427f7db19777dfed330047253e7a4e1bAndreas Huber 100a2723d26427f7db19777dfed330047253e7a4e1bAndreas Huber if (err != OK) { 101a2723d26427f7db19777dfed330047253e7a4e1bAndreas Huber delete ast; 102a2723d26427f7db19777dfed330047253e7a4e1bAndreas Huber ast = NULL; 103a2723d26427f7db19777dfed330047253e7a4e1bAndreas Huber 104a2723d26427f7db19777dfed330047253e7a4e1bAndreas Huber return NULL; 105a2723d26427f7db19777dfed330047253e7a4e1bAndreas Huber } 106a2723d26427f7db19777dfed330047253e7a4e1bAndreas Huber 10768f24590cda230fb92eac44ed0247f54f9b31ad0Andreas Huber mCache.add(fqName, ast); 1085345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber 1095345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber return ast; 1105345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber} 1115345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber 112dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huberstd::vector<std::string>::const_iterator 113dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas HuberCoordinator::findPackageRoot(const FQName &fqName) const { 1145345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber CHECK(!fqName.package().empty()); 1155345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber CHECK(!fqName.version().empty()); 1165345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber 117dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber // Find the right package prefix and path for this FQName. For 118dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber // example, if FQName is "android.hardware.nfc@1.0::INfc", and the 119dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber // prefix:root is set to [ "android.hardware:hardware/interfaces", 120dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber // "vendor.qcom.hardware:vendor/qcom"], then we will identify the 121dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber // prefix "android.hardware" and the package root 122dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber // "hardware/interfaces". 123dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber 124dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber // TODO: This now returns on the first match. Throw an error if 125dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber // there are multiple hits. 126dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber auto it = mPackageRoots.begin(); 127dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber for (; it != mPackageRoots.end(); it++) { 128dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber if (fqName.package().find(*it) != std::string::npos) { 129dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber break; 130dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber } 131dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber } 132dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber CHECK(it != mPackageRoots.end()); 133dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber 134dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber return it; 135dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber} 136dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber 137dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huberstd::string Coordinator::getPackageRoot(const FQName &fqName) const { 138dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber auto it = findPackageRoot(fqName); 139dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber auto prefix = *it; 140dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber return prefix; 141dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber} 142dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber 1435bb14024064a51a044e51c14466e5b2ae8352505Iliyan Malchevstd::string Coordinator::getPackageRootPath(const FQName &fqName) const { 1445bb14024064a51a044e51c14466e5b2ae8352505Iliyan Malchev auto it = findPackageRoot(fqName); 1455bb14024064a51a044e51c14466e5b2ae8352505Iliyan Malchev auto root = mPackageRootPaths[std::distance(mPackageRoots.begin(), it)]; 1465bb14024064a51a044e51c14466e5b2ae8352505Iliyan Malchev return root; 1475bb14024064a51a044e51c14466e5b2ae8352505Iliyan Malchev} 1485bb14024064a51a044e51c14466e5b2ae8352505Iliyan Malchev 149dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huberstd::string Coordinator::getPackagePath( 150dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber const FQName &fqName, bool relative) const { 151dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber 152dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber auto it = findPackageRoot(fqName); 153dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber auto prefix = *it; 154dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber auto root = mPackageRootPaths[std::distance(mPackageRoots.begin(), it)]; 155dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber 156dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber // Make sure the prefix ends on a '.' and the root path on a '/' 157dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber if ((*--prefix.end()) != '.') { 158dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber prefix += '.'; 159dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber } 160dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber 161dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber if ((*--root.end()) != '/') { 162dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber root += '/'; 163dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber } 164dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber 165dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber // Given FQName of "android.hardware.nfc@1.0::IFoo" and a prefix 166dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber // "android.hardware.", the suffix is "nfc@1.0::IFoo". 167dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber const std::string packageSuffix = fqName.package().substr(prefix.length()); 1685345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber 169881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber std::string packagePath; 170881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber if (!relative) { 171dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber packagePath = root; 172881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber } 1735345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber 1745345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber size_t startPos = 0; 1755345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber size_t dotPos; 1765345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber while ((dotPos = packageSuffix.find('.', startPos)) != std::string::npos) { 1775345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber packagePath.append(packageSuffix.substr(startPos, dotPos - startPos)); 1785345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber packagePath.append("/"); 1795345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber 1805345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber startPos = dotPos + 1; 1815345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber } 1825345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber CHECK_LT(startPos + 1, packageSuffix.length()); 1835345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber packagePath.append(packageSuffix.substr(startPos)); 1845345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber packagePath.append("/"); 1855345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber 1865345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber CHECK_EQ(fqName.version().find('@'), 0u); 1875345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber packagePath.append(fqName.version().substr(1)); 1885345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber packagePath.append("/"); 1895345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber 1905345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber return packagePath; 1915345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber} 1925345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber 193fd4afabde8fb9bbdd0021addeb9fbb62428f2c17Andreas HuberType *Coordinator::lookupType(const FQName &fqName) const { 1945345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber // Fully qualified. 19568f24590cda230fb92eac44ed0247f54f9b31ad0Andreas Huber CHECK(fqName.isFullyQualified()); 1965345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber 1975345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber std::string topType; 1985345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber size_t dotPos = fqName.name().find('.'); 1995345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber if (dotPos == std::string::npos) { 2005345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber topType = fqName.name(); 2015345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber } else { 2025345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber topType = fqName.name().substr(0, dotPos); 2035345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber } 2045345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber 20568f24590cda230fb92eac44ed0247f54f9b31ad0Andreas Huber // Assuming {topType} is the name of an interface type, let's see if the 20668f24590cda230fb92eac44ed0247f54f9b31ad0Andreas Huber // associated {topType}.hal file was imported. 20768f24590cda230fb92eac44ed0247f54f9b31ad0Andreas Huber FQName ifaceName(fqName.package(), fqName.version(), topType); 20868f24590cda230fb92eac44ed0247f54f9b31ad0Andreas Huber ssize_t index = mCache.indexOfKey(ifaceName); 2095345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber if (index >= 0) { 2105345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber AST *ast = mCache.valueAt(index); 2116e584b70065ce37615980aba5ed60d27a54da1c3Andreas Huber CHECK(ast != NULL); 2126e584b70065ce37615980aba5ed60d27a54da1c3Andreas Huber 2135345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber Type *type = ast->lookupTypeInternal(fqName.name()); 2145345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber 2155345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber if (type != NULL) { 216fd4afabde8fb9bbdd0021addeb9fbb62428f2c17Andreas Huber return type->ref(); 2175345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber } 2185345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber } 2195345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber 22068f24590cda230fb92eac44ed0247f54f9b31ad0Andreas Huber FQName typesName(fqName.package(), fqName.version(), "types"); 22168f24590cda230fb92eac44ed0247f54f9b31ad0Andreas Huber index = mCache.indexOfKey(typesName); 2225345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber if (index >= 0) { 2235345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber AST *ast = mCache.valueAt(index); 2246e584b70065ce37615980aba5ed60d27a54da1c3Andreas Huber if (ast != NULL) { 2256e584b70065ce37615980aba5ed60d27a54da1c3Andreas Huber // ast could be NULL if types.hal didn't exist, which is valid. 2266e584b70065ce37615980aba5ed60d27a54da1c3Andreas Huber Type *type = ast->lookupTypeInternal(fqName.name()); 2275345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber 2286e584b70065ce37615980aba5ed60d27a54da1c3Andreas Huber if (type != NULL) { 229fd4afabde8fb9bbdd0021addeb9fbb62428f2c17Andreas Huber return type->ref(); 2306e584b70065ce37615980aba5ed60d27a54da1c3Andreas Huber } 2315345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber } 2325345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber } 2335345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber 2345345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber return NULL; 2355345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber} 2365345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber 237d2943e11533697b97aa5330f05fc144493748c0bAndreas Huberstatus_t Coordinator::getPackageInterfaceFiles( 238d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber const FQName &package, 239d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber std::vector<std::string> *fileNames) const { 240d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber fileNames->clear(); 2416cb08cf9f021a01d9d2b1eaec6729aac6ae70708Andreas Huber 242d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber const std::string packagePath = getPackagePath(package); 243d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber 244d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber DIR *dir = opendir(packagePath.c_str()); 245d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber 246d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber if (dir == NULL) { 247d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber return -errno; 248d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber } 249d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber 250d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber struct dirent *ent; 251d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber while ((ent = readdir(dir)) != NULL) { 252d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber if (ent->d_type != DT_REG) { 2536cb08cf9f021a01d9d2b1eaec6729aac6ae70708Andreas Huber continue; 2546cb08cf9f021a01d9d2b1eaec6729aac6ae70708Andreas Huber } 2556cb08cf9f021a01d9d2b1eaec6729aac6ae70708Andreas Huber 256d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber const auto suffix = ".hal"; 257d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber const auto suffix_len = std::strlen(suffix); 258d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber const auto d_namelen = strlen(ent->d_name); 259e61e3f7b138a992047a60c4b8c27f1c752ed57baAndreas Huber 260d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber if (d_namelen < suffix_len 261d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber || strcmp(ent->d_name + d_namelen - suffix_len, suffix)) { 262d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber continue; 263e61e3f7b138a992047a60c4b8c27f1c752ed57baAndreas Huber } 264d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber 265d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber fileNames->push_back(std::string(ent->d_name, d_namelen - suffix_len)); 266e61e3f7b138a992047a60c4b8c27f1c752ed57baAndreas Huber } 267e61e3f7b138a992047a60c4b8c27f1c752ed57baAndreas Huber 268d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber closedir(dir); 269d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber dir = NULL; 270d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber 271e61e3f7b138a992047a60c4b8c27f1c752ed57baAndreas Huber return OK; 272e61e3f7b138a992047a60c4b8c27f1c752ed57baAndreas Huber} 273e61e3f7b138a992047a60c4b8c27f1c752ed57baAndreas Huber 2745bb14024064a51a044e51c14466e5b2ae8352505Iliyan Malchevstatus_t Coordinator::appendPackageInterfacesToSet( 275d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber const FQName &package, 276d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber std::vector<FQName> *packageInterfaces) const { 277d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber packageInterfaces->clear(); 278d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber 279d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber std::vector<std::string> fileNames; 280d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber status_t err = getPackageInterfaceFiles(package, &fileNames); 281d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber 282d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber if (err != OK) { 283d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber return err; 284d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber } 285d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber 286d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber for (const auto &fileName : fileNames) { 287d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber FQName subFQName( 288d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber package.package() + package.version() + "::" + fileName); 289d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber 290d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber if (!subFQName.isValid()) { 291d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber LOG(WARNING) 292d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber << "Whole-package import encountered invalid filename '" 293d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber << fileName 294d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber << "' in package " 295d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber << package.package() 296d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber << package.version(); 297d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber 298d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber continue; 299d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber } 300d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber 301d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber packageInterfaces->push_back(subFQName); 302d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber } 303d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber 304d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber return OK; 305d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber} 306d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber 307d2943e11533697b97aa5330f05fc144493748c0bAndreas Huberstd::string Coordinator::convertPackageRootToPath(const FQName &fqName) const { 308d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber std::string packageRoot = getPackageRoot(fqName); 309d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber 310d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber if (*(packageRoot.end()--) != '.') { 311d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber packageRoot += '.'; 312d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber } 313d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber 314d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber std::replace(packageRoot.begin(), packageRoot.end(), '.', '/'); 315d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber 316d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber return packageRoot; // now converted to a path 317d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber} 318d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber 319d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber// static 320d2943e11533697b97aa5330f05fc144493748c0bAndreas Huberbool Coordinator::MakeParentHierarchy(const std::string &path) { 321d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber static const mode_t kMode = 0755; 322d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber 323d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber size_t start = 1; // Ignore leading '/' 324d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber size_t slashPos; 325d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber while ((slashPos = path.find("/", start)) != std::string::npos) { 326d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber std::string partial = path.substr(0, slashPos); 327d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber 328d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber struct stat st; 329d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber if (stat(partial.c_str(), &st) < 0) { 330d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber if (errno != ENOENT) { 331d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber return false; 332d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber } 333d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber 334d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber int res = mkdir(partial.c_str(), kMode); 335d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber if (res < 0) { 336d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber return false; 337d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber } 338d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber } else if (!S_ISDIR(st.st_mode)) { 339d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber return false; 340d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber } 341d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber 342d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber start = slashPos + 1; 343d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber } 344d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber 345d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber return true; 346d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber} 347d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber 3485345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber} // namespace android 3495345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber 350