• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "code_gen/CodeGenBase.h"
18 
19 #include <limits.h>
20 #include <stdlib.h>
21 #include <sys/stat.h>
22 #include <sys/types.h>
23 #include <unistd.h>
24 
25 #include <cstdint>
26 #include <fstream>
27 #include <iostream>
28 #include <sstream>
29 #include <string>
30 
31 #include <hidl-util/Formatter.h>
32 
33 #include "specification_parser/InterfaceSpecificationParser.h"
34 #include "utils/InterfaceSpecUtil.h"
35 
36 #include "test/vts/proto/ComponentSpecificationMessage.pb.h"
37 
38 #include "VtsCompilerUtils.h"
39 #include "code_gen/driver/HalCodeGen.h"
40 #include "code_gen/driver/HalSubmoduleCodeGen.h"
41 #include "code_gen/driver/HalHidlCodeGen.h"
42 #include "code_gen/driver/LegacyHalCodeGen.h"
43 #include "code_gen/driver/LibSharedCodeGen.h"
44 #include "code_gen/fuzzer/FuzzerCodeGenBase.h"
45 #include "code_gen/fuzzer/HalHidlFuzzerCodeGen.h"
46 #include "code_gen/profiler/ProfilerCodeGenBase.h"
47 #include "code_gen/profiler/HalHidlProfilerCodeGen.h"
48 
49 using namespace std;
50 
51 namespace android {
52 namespace vts {
53 
CodeGenBase(const char * input_vts_file_path,const string & vts_name)54 CodeGenBase::CodeGenBase(const char* input_vts_file_path, const string& vts_name)
55     : input_vts_file_path_(input_vts_file_path), vts_name_(vts_name) {}
56 
~CodeGenBase()57 CodeGenBase::~CodeGenBase() {}
58 
59 // TODO(yim): deprecate this function after type specific translate functions
60 //            are used.
Translate(VtsCompileMode mode,const char * input_vts_file_path,const char * output_header_dir_path,const char * output_cpp_file_path)61 void Translate(VtsCompileMode mode,
62                const char* input_vts_file_path,
63                const char* output_header_dir_path,
64                const char* output_cpp_file_path) {
65   string output_cpp_file_path_str = string(output_cpp_file_path);
66 
67   size_t found;
68   found = output_cpp_file_path_str.find_last_of("/");
69   string vts_name = output_cpp_file_path_str
70       .substr(found + 1, output_cpp_file_path_str.length() - found - 5);
71 
72   ComponentSpecificationMessage message;
73   if (!InterfaceSpecificationParser::parse(input_vts_file_path, &message)) {
74     cerr << "can't parse " << input_vts_file_path << endl;
75     exit(-1);
76   }
77 
78   string output_header_file_path = string(output_header_dir_path) + "/"
79       + string(input_vts_file_path);
80   output_header_file_path = output_header_file_path + ".h";
81 
82   vts_fs_mkdirs(&output_header_file_path[0], 0777);
83 
84   FILE* header_file = fopen(output_header_file_path.c_str(), "w");
85   if (header_file == NULL) {
86     cerr << "could not open file " << output_header_file_path;
87     exit(-1);
88   }
89   Formatter header_out(header_file);
90 
91   FILE* source_file = fopen(output_cpp_file_path, "w");
92   if (source_file == NULL) {
93     cerr << "could not open file " << output_cpp_file_path;
94     exit(-1);
95   }
96   Formatter source_out(source_file);
97 
98   if (mode == kDriver) {
99     unique_ptr<CodeGenBase> code_generator;
100     switch (message.component_class()) {
101       case HAL_CONVENTIONAL:
102         code_generator.reset(new HalCodeGen(input_vts_file_path, vts_name));
103         break;
104       case HAL_CONVENTIONAL_SUBMODULE:
105         code_generator.reset(
106             new HalSubmoduleCodeGen(input_vts_file_path, vts_name));
107         break;
108       case HAL_LEGACY:
109         code_generator.reset(
110             new LegacyHalCodeGen(input_vts_file_path, vts_name));
111         break;
112       case LIB_SHARED:
113         code_generator.reset(
114             new LibSharedCodeGen(input_vts_file_path, vts_name));
115         break;
116       case HAL_HIDL:
117         code_generator.reset(new HalHidlCodeGen(input_vts_file_path, vts_name));
118         break;
119       default:
120         cerr << "not yet supported component_class "
121              << message.component_class();
122         exit(-1);
123     }
124     code_generator->GenerateAll(header_out, source_out, message);
125   } else if (mode == kFuzzer) {
126     unique_ptr<FuzzerCodeGenBase> fuzzer_generator;
127     switch (message.component_class()) {
128       case HAL_HIDL:
129         fuzzer_generator = make_unique<HalHidlFuzzerCodeGen>(message);
130         break;
131       default:
132         cerr << "not yet supported component_class "
133              << message.component_class();
134         exit(-1);
135     }
136     fuzzer_generator->GenerateAll(header_out, source_out);
137   } else if (mode == kProfiler) {
138     unique_ptr<ProfilerCodeGenBase> profiler_generator;
139     switch (message.component_class()) {
140       case HAL_HIDL:
141         profiler_generator.reset(
142             new HalHidlProfilerCodeGen(input_vts_file_path));
143         break;
144       default:
145         cerr << "not yet supported component_class "
146              << message.component_class();
147         exit(-1);
148     }
149     profiler_generator->GenerateAll(header_out, source_out, message);
150   }
151 }
152 
TranslateToFile(VtsCompileMode mode,const char * input_vts_file_path,const char * output_file_path,VtsCompileFileType file_type)153 void TranslateToFile(VtsCompileMode mode,
154                      const char* input_vts_file_path,
155                      const char* output_file_path,
156                      VtsCompileFileType file_type) {
157   string output_cpp_file_path_str = string(output_file_path);
158 
159   size_t found;
160   found = output_cpp_file_path_str.find_last_of("/");
161   string vts_name = output_cpp_file_path_str
162       .substr(found + 1, output_cpp_file_path_str.length() - found - 5);
163 
164   ComponentSpecificationMessage message;
165   if (!InterfaceSpecificationParser::parse(input_vts_file_path, &message)) {
166     cerr << __func__ << " can't parse " << input_vts_file_path << endl;
167   }
168 
169   FILE* output_file = fopen(output_file_path, "w");
170   if (output_file == NULL) {
171     cerr << __func__ << " could not open file " << output_file_path << endl;
172     exit(-1);
173   }
174   Formatter out(output_file);
175 
176   if (mode == kDriver) {
177     unique_ptr<CodeGenBase> code_generator;
178     switch (message.component_class()) {
179       case HAL_CONVENTIONAL:
180         code_generator.reset(new HalCodeGen(input_vts_file_path, vts_name));
181         break;
182       case HAL_CONVENTIONAL_SUBMODULE:
183         code_generator.reset(
184             new HalSubmoduleCodeGen(input_vts_file_path, vts_name));
185         break;
186       case HAL_LEGACY:
187         code_generator.reset(
188             new LegacyHalCodeGen(input_vts_file_path, vts_name));
189         break;
190       case LIB_SHARED:
191         code_generator.reset(
192             new LibSharedCodeGen(input_vts_file_path, vts_name));
193         break;
194       case HAL_HIDL:
195         code_generator.reset(new HalHidlCodeGen(input_vts_file_path, vts_name));
196         break;
197       default:
198         cerr << "not yet supported component_class "
199              << message.component_class();
200         exit(-1);
201     }
202     if (file_type == kHeader) {
203       code_generator->GenerateHeaderFile(out, message);
204     } else if (file_type == kSource){
205       code_generator->GenerateSourceFile(out, message);
206     } else {
207       cerr << __func__ << " doesn't support file_type = kBoth." << endl;
208       exit(-1);
209     }
210   } else if (mode == kFuzzer) {
211     unique_ptr<FuzzerCodeGenBase> fuzzer_generator;
212     switch (message.component_class()) {
213       case HAL_HIDL:
214         {
215           fuzzer_generator = make_unique<HalHidlFuzzerCodeGen>(message);
216           break;
217         }
218       default:
219         cerr << "not yet supported component_class "
220              << message.component_class();
221         exit(-1);
222     }
223     if (file_type == kHeader) {
224       fuzzer_generator->GenerateHeaderFile(out);
225     } else if (file_type == kSource){
226       fuzzer_generator->GenerateSourceFile(out);
227     } else {
228       cerr << __func__ << " doesn't support file_type = kBoth." << endl;
229       exit(-1);
230     }
231   } else if (mode == kProfiler) {
232     unique_ptr<ProfilerCodeGenBase> profiler_generator;
233     switch (message.component_class()) {
234       case HAL_HIDL:
235         profiler_generator.reset(
236             new HalHidlProfilerCodeGen(input_vts_file_path));
237         break;
238       default:
239         cerr << "not yet supported component_class "
240              << message.component_class();
241         exit(-1);
242     }
243     if (file_type == kHeader) {
244       profiler_generator->GenerateHeaderFile(out, message);
245     } else if (file_type == kSource){
246       profiler_generator->GenerateSourceFile(out, message);
247     } else {
248       cerr << __func__ << " doesn't support file_type = kBoth." << endl;
249       exit(-1);
250     }
251   }
252 }
253 
254 }  // namespace vts
255 }  // namespace android
256