blob: 6592b68fce435bb5c8a5daf18d3a54dd0b33024c [file] [log] [blame]
Andreas Huberc9410c72016-07-28 12:18:40 -07001#include "AST.h"
Andreas Huber5345ec22016-07-29 13:33:27 -07002#include "Coordinator.h"
Andreas Huber84f89de2016-07-28 15:39:51 -07003#include "FQName.h"
Andreas Huberc9410c72016-07-28 12:18:40 -07004
Andreas Huber68f24592016-07-29 14:53:48 -07005#include <android-base/logging.h>
Andreas Huberc9410c72016-07-28 12:18:40 -07006#include <stdio.h>
Andreas Huberb82318c2016-08-02 14:45:54 -07007#include <unistd.h>
Andreas Huberc9410c72016-07-28 12:18:40 -07008
9using namespace android;
10
Andreas Huberb82318c2016-08-02 14:45:54 -070011static void usage(const char *me) {
12 fprintf(stderr, "usage: %s -o output-path fqname ...\n", me);
13}
14
15int main(int argc, char **argv) {
16 std::string outputDir;
17
Andreas Huber737080b2016-08-02 15:38:04 -070018 const char *me = argv[0];
19
Andreas Huberb82318c2016-08-02 14:45:54 -070020 int res;
21 while ((res = getopt(argc, argv, "ho:")) >= 0) {
22 switch (res) {
23 case 'o':
24 {
25 outputDir = optarg;
26 break;
27 }
28
29 case '?':
30 case 'h':
31 default:
32 {
Andreas Huber737080b2016-08-02 15:38:04 -070033 usage(me);
Andreas Huberb82318c2016-08-02 14:45:54 -070034 exit(1);
35 break;
36 }
37 }
38 }
39
40 argc -= optind;
41 argv += optind;
42
Andreas Huber737080b2016-08-02 15:38:04 -070043 // Valid options are now in argv[0] .. argv[argc - 1].
44
Andreas Huberb82318c2016-08-02 14:45:54 -070045 if (outputDir.empty()) {
Andreas Huber737080b2016-08-02 15:38:04 -070046 usage(me);
Andreas Huberb82318c2016-08-02 14:45:54 -070047 exit(1);
48 } else {
49 const size_t len = outputDir.size();
50 if (outputDir[len - 1] != '/') {
51 outputDir += "/";
52 }
53 }
54
Andreas Huberdc981332016-07-29 15:46:54 -070055 const char *TOP = getenv("TOP");
56 if (TOP == NULL) {
57 LOG(ERROR) << "Your environment does not define $TOP.";
58 return 1;
59 }
60
61 std::string interfacesPath = TOP;
62 interfacesPath.append("/hardware/interfaces/");
63
64 Coordinator coordinator(interfacesPath);
Andreas Huber5345ec22016-07-29 13:33:27 -070065
Andreas Huber737080b2016-08-02 15:38:04 -070066 for (int i = 0; i < argc; ++i) {
Andreas Huber68f24592016-07-29 14:53:48 -070067 FQName fqName(argv[i]);
68 CHECK(fqName.isValid() && fqName.isFullyQualified());
69
70 AST *ast = coordinator.parse(fqName);
Andreas Huberc9410c72016-07-28 12:18:40 -070071
Andreas Hubere61e3f72016-08-03 10:22:03 -070072 if (ast == NULL) {
73 fprintf(stderr,
74 "Could not parse %s. Aborting.\n",
75 fqName.string().c_str());
Andreas Huber881227d2016-08-02 14:20:21 -070076
Andreas Hubere61e3f72016-08-03 10:22:03 -070077 exit(1);
78 }
Andreas Hubereb1081f2016-07-28 13:13:24 -070079 }
Andreas Huberc9410c72016-07-28 12:18:40 -070080
Andreas Hubere61e3f72016-08-03 10:22:03 -070081 // Now that we've found the transitive hull of all necessary interfaces
82 // and types to process, go ahead and do the work.
83 status_t err = coordinator.forEachAST(
84 [&](const AST *ast) {
85 return ast->generateCpp(outputDir);
86 });
87
88 return (err == OK) ? 0 : 1;
Andreas Huberc9410c72016-07-28 12:18:40 -070089}