1f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland/* 2f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland * Copyright (C) 2016 The Android Open Source Project 3f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland * 4f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland * Licensed under the Apache License, Version 2.0 (the "License"); 5f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland * you may not use this file except in compliance with the License. 6f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland * You may obtain a copy of the License at 7f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland * 8f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland * http://www.apache.org/licenses/LICENSE-2.0 9f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland * 10f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland * Unless required by applicable law or agreed to in writing, software 11f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland * distributed under the License is distributed on an "AS IS" BASIS, 12f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland * See the License for the specific language governing permissions and 14f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland * limitations under the License. 15f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland */ 16f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland 17f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland#include "AST.h" 18f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland 19f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland#include <android-base/logging.h> 20f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland#include <android-base/macros.h> 21f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland#include <set> 22f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland#include <map> 23f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland#include <stdio.h> 24f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland#include <string> 25f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland#include <unistd.h> 26f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland#include <vector> 27f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland 28f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Morelandusing namespace android; 29f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland 30f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Morelandextern status_t parseFile(android::AST *ast); 31f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland 32f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Morelandstatic void usage(const char *me) { 33f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland fprintf(stderr, 342b02118f0cf27fabdb76e01bf60ca75dd1ad905bSteven Moreland "usage: %s [-g] [-o dir] -p package (-r interface-root)+ (header-filepath)+\n", 35f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland me); 36f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland 37cd16ae4797a0ee318ac08026330732e03016956dSteven Moreland fprintf(stderr, " -h print this message\n"); 38f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland fprintf(stderr, " -o output path\n"); 39f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland fprintf(stderr, " (example: ~/android/master)\n"); 40f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland fprintf(stderr, " -p package\n"); 41f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland fprintf(stderr, " (example: android.hardware.baz@1.0)\n"); 42f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland fprintf(stderr, " -g (enable open-gl mode) \n"); 43f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland fprintf(stderr, " -r package:path root " 44f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland "(e.g., android.hardware:hardware/interfaces)\n"); 45f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland} 46f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland 47f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Morelandstatic void addPackageRootToMap(const std::string &val, 48f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland std::map<std::string, std::string> &packageRootPaths) { 49f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland auto index = val.find_first_of(':'); 50f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland CHECK(index != std::string::npos); 51f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland 52f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland auto package = val.substr(0, index); 53f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland auto path = val.substr(index + 1); 54f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland 55f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland packageRootPaths[package] = path; 56f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland} 57f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland 58f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Morelandstatic bool isPathPrefix(const std::string &prefix, const std::string &base) { 59f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland if (prefix.size() >= base.size()) { 6092a1fbbb744a279bb43874200cc12dac6ab2326aDiego Wilson LOG(DEBUG) << "Not long enough"; 61f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland return false; 62f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland } 63f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland 64f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland if (base[prefix.size()] != '.') { 6592a1fbbb744a279bb43874200cc12dac6ab2326aDiego Wilson LOG(DEBUG) << "not full"; 66f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland return false; 67f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland } 68f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland 69f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland return prefix == base.substr(0, prefix.size()); 70f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland} 71f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland 72f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Morelandstatic void applyPackageRootPath( 73f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland const std::map<std::string, std::string> &packageRootPaths, 74f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland const std::string &package, 75f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland std::string &outputPath) { 76f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland 77f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland auto index = package.find_first_of('@'); 78f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland CHECK(index != std::string::npos); 79f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland 80f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland auto packagePath = package.substr(0, index); 81f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland auto packageVersion = package.substr(index + 1); 82f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland 83f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland for (auto const& pair : packageRootPaths) { 84f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland const std::string& rootPackage = pair.first; 85f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland const std::string& rootPath = pair.second; 86f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland 87f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland if (isPathPrefix(rootPackage, packagePath)) { 88f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland 89f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland packagePath = packagePath.substr(rootPackage.size() + 1); 90f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland std::replace(packagePath.begin(), packagePath.end(), '.', '/'); 91f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland packagePath += '/' + packageVersion; 92f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland 93f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland if (outputPath.empty()) { 94f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland outputPath = rootPath; 95f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland } 96f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland 97f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland outputPath += '/' + packagePath + '/'; 98f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland return; 99f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland } 100f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland } 101f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland 102d3a82b5d9a5c1d755bc2e7a02d08d8b8fb1aa8efSteven Moreland CHECK(!outputPath.empty()) << "No package root path provided for: " << package; 103d3a82b5d9a5c1d755bc2e7a02d08d8b8fb1aa8efSteven Moreland 104d3a82b5d9a5c1d755bc2e7a02d08d8b8fb1aa8efSteven Moreland outputPath += '/'; 105f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland} 106f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland 107f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Morelandint main(int argc, char **argv) { 108f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland const char *me = argv[0]; 109f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland 110f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland std::string outputDir; 111f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland std::string package; 112f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland std::map<std::string, std::string> packageRootPaths; 113f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland bool isOpenGl = false; 11492a1fbbb744a279bb43874200cc12dac6ab2326aDiego Wilson bool verbose = false; 115f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland 116f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland int res; 11792a1fbbb744a279bb43874200cc12dac6ab2326aDiego Wilson while ((res = getopt(argc, argv, "ghvo:p:r:")) >= 0) { 118f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland switch (res) { 119f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland case 'o': { 120f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland outputDir = optarg; 121f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland break; 122f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland } 123f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland case 'p': { 124f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland package = optarg; 125f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland break; 126f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland } 127f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland case 'g': { 128f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland isOpenGl = true; 129f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland break; 130f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland } 13192a1fbbb744a279bb43874200cc12dac6ab2326aDiego Wilson case 'v': { 13292a1fbbb744a279bb43874200cc12dac6ab2326aDiego Wilson verbose = true; 13392a1fbbb744a279bb43874200cc12dac6ab2326aDiego Wilson break; 13492a1fbbb744a279bb43874200cc12dac6ab2326aDiego Wilson } 135f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland case 'r': 136f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland { 137f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland addPackageRootToMap(optarg, packageRootPaths); 138f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland break; 139f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland } 140f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland case 'h': 141f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland default: 142f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland { 143f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland usage(me); 144f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland exit(1); 145f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland break; 146f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland } 147f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland } 148f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland } 149f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland 150f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland // if no arguments are provided, show usage instead of specific errors 151f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland if (optind == 1) { 152f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland usage(me); 153f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland exit(0); 154f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland } 155f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland 15692a1fbbb744a279bb43874200cc12dac6ab2326aDiego Wilson if (verbose) { 15792a1fbbb744a279bb43874200cc12dac6ab2326aDiego Wilson SetMinimumLogSeverity(android::base::VERBOSE); 15892a1fbbb744a279bb43874200cc12dac6ab2326aDiego Wilson } 15992a1fbbb744a279bb43874200cc12dac6ab2326aDiego Wilson 160f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland applyPackageRootPath(packageRootPaths, package, outputDir); 161f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland 162f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland if (package.empty()) { 163f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland LOG(WARNING) << "You must provide a package."; 164f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland usage(me); 165f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland exit(0); 166f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland } 167f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland 168f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland if (optind == argc) { 169f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland LOG(WARNING) << "You must provide a header-filepath."; 170f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland usage(me); 171f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland exit(0); 172f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland } 173f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland 174f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland for(int i = optind; i < argc; i++) { 175f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland std::string path = argv[i]; 176f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland 17792a1fbbb744a279bb43874200cc12dac6ab2326aDiego Wilson LOG(DEBUG) << "Processing " << path; 178f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland 179f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland AST ast(path, outputDir, package, isOpenGl); 180f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland 181f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland int res = parseFile(&ast); 182f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland 183f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland if (res != 0) { 184f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland LOG(ERROR) << "Could not parse: " << res; 185f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland exit(1); 186f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland } 187f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland 188f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland ast.processContents(); 189f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland 190f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland ast.generateCode(); 191f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland } 192f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland 193f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland return 0; 194f1a35f7d73f38e0d30d7a4343e33c3f4777cf87eSteven Moreland} 195