1 /*
2 * Copyright 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include <dirent.h>
18 #include <stdlib.h>
19 #include <string.h>
20 #include <sys/stat.h>
21 #include <unistd.h>
22
23 #include <iostream>
24
25 #include <android-base/logging.h>
26 #include "VtsCompilerUtils.h"
27 #include "code_gen/CodeGenBase.h"
28
29 using namespace std;
30
31 // To generate both header and source files,
32 // Usage: vtsc -mDRIVER | -mPROFILER <.vts input file path> \
33 // <header output dir> <C/C++ source output file path>
34 // To generate only a header file,
35 // Usage: vtsc -mDRIVER | -mPROFILER -tHEADER -b<base path> \
36 // <.vts input file or dir path> <header output file or dir path>
37 // To generate only a source file,
38 // Usage: vtsc -mDRIVER | -mPROFILER -tSOURCE -b<base path> \
39 // <.vts input file or dir path> \
40 // <C/C++ source output file or dir path>
41 // where <base path> is a base path of where .vts input file or dir is
42 // stored but should be excluded when computing the package path of generated
43 // source or header output file(s).
44
main(int argc,char * argv[])45 int main(int argc, char* argv[]) {
46 #ifdef VTS_DEBUG
47 cout << "Android VTS Compiler (AVTSC)" << endl;
48 #endif
49 int opt_count = 0;
50 android::vts::VtsCompileMode mode = android::vts::kDriver;
51 android::vts::VtsCompileFileType type = android::vts::VtsCompileFileType::kBoth;
52 string vts_base_dir;
53 for (int i = 0; i < argc; i++) {
54 #ifdef VTS_DEBUG
55 cout << "- args[" << i << "] " << argv[i] << endl;
56 #endif
57 if (argv[i] && strlen(argv[i]) > 1 && argv[i][0] == '-') {
58 opt_count++;
59 if (argv[i][1] == 'm') {
60 if (!strcmp(&argv[i][2], "PROFILER")) {
61 mode = android::vts::kProfiler;
62 #ifdef VTS_DEBUG
63 cout << "- mode: PROFILER" << endl;
64 #endif
65 } else if (!strcmp(&argv[i][2], "FUZZER")) {
66 mode = android::vts::kFuzzer;
67 #ifdef VTS_DEBUG
68 cout << "- mode: FUZZER" << endl;
69 #endif
70 }
71 }
72 if (argv[i][1] == 't') {
73 if (!strcmp(&argv[i][2], "HEADER")) {
74 type = android::vts::kHeader;
75 #ifdef VTS_DEBUG
76 cout << "- type: HEADER" << endl;
77 #endif
78 } else if (!strcmp(&argv[i][2], "SOURCE")) {
79 type = android::vts::kSource;
80 #ifdef VTS_DEBUG
81 cout << "- type: SOURCE" << endl;
82 #endif
83 }
84 }
85 if (argv[i][1] == 'b') {
86 vts_base_dir = &argv[i][2];
87 #ifdef VTS_DEBUG
88 cout << "- VTS base dir: " << vts_base_dir << endl;
89 #endif
90 }
91 }
92 }
93 if (argc < 5) {
94 cerr << "argc " << argc << " < 5" << endl;
95 return -1;
96 }
97 switch (type) {
98 case android::vts::kBoth:
99 android::vts::Translate(
100 mode, argv[opt_count + 1], argv[opt_count + 2], argv[opt_count + 3]);
101 break;
102 case android::vts::kHeader:
103 case android::vts::kSource: {
104 struct stat s;
105 bool is_dir = false;
106 if (vts_base_dir.length() > 0) {
107 if (chdir(vts_base_dir.c_str())) {
108 cerr << __func__ << " can't chdir to " << vts_base_dir << endl;
109 exit(-1);
110 }
111 }
112 if (stat(argv[opt_count + 1], &s) == 0) {
113 if (s.st_mode & S_IFDIR) {
114 is_dir = true;
115 }
116 }
117 if (!is_dir) {
118 android::vts::TranslateToFile(
119 mode, argv[opt_count + 1], argv[opt_count + 2], type);
120 } else {
121 DIR* input_dir;
122 struct dirent* ent;
123 if ((input_dir = opendir(argv[opt_count + 1])) != NULL) {
124 // argv[opt_count + 2] should be a directory. if that dir does not exist,
125 // that dir is created as part of the translation operation.
126 while ((ent = readdir(input_dir)) != NULL) {
127 if (!strncmp(&ent->d_name[strlen(ent->d_name)-4], ".vts", 4)) {
128 string src_file = android::vts::RemoveBaseDir(
129 android::vts::PathJoin(
130 argv[opt_count + 1], ent->d_name), vts_base_dir);
131 string dst_file = android::vts::RemoveBaseDir(
132 android::vts::PathJoin(
133 argv[opt_count + 2], ent->d_name), vts_base_dir);
134 if (type == android::vts::kHeader) {
135 dst_file = android::vts::PathJoin(dst_file.c_str(), ".h");
136 } else {
137 dst_file = android::vts::PathJoin(dst_file.c_str(), ".cpp");
138 }
139 #ifdef VTS_DEBUG
140 cout << ent->d_name << endl;
141 cout << "<- " << src_file.c_str() << endl;
142 cout << "-> " << dst_file.c_str() << endl;
143 #endif
144 android::vts::TranslateToFile(
145 mode, src_file.c_str(), dst_file.c_str(), type);
146 }
147 }
148 closedir(input_dir);
149 } else {
150 cerr << __func__ << " can't open the given input dir, "
151 << argv[opt_count + 1] << "." << endl;
152 exit(-1);
153 }
154 }
155 break;
156 }
157 }
158 return 0;
159 }
160