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