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 "test/vts/proto/ComponentSpecificationMessage.pb.h"
34 #include "utils/InterfaceSpecUtil.h"
35
36 #include "VtsCompilerUtils.h"
37 #include "code_gen/driver/HalCodeGen.h"
38 #include "code_gen/driver/HalSubmoduleCodeGen.h"
39 #include "code_gen/driver/HalHidlCodeGen.h"
40 #include "code_gen/driver/LegacyHalCodeGen.h"
41 #include "code_gen/driver/LibSharedCodeGen.h"
42 #include "code_gen/fuzzer/FuzzerCodeGenBase.h"
43 #include "code_gen/fuzzer/HalHidlFuzzerCodeGen.h"
44 #include "code_gen/profiler/ProfilerCodeGenBase.h"
45 #include "code_gen/profiler/HalHidlProfilerCodeGen.h"
46
47 using namespace std;
48
49 namespace android {
50 namespace vts {
51
CodeGenBase(const char * input_vts_file_path)52 CodeGenBase::CodeGenBase(const char* input_vts_file_path)
53 : input_vts_file_path_(input_vts_file_path) {}
54
~CodeGenBase()55 CodeGenBase::~CodeGenBase() {}
56
Translate(VtsCompileMode mode,const char * input_vts_file_path,const char * output_header_dir_path,const char * output_cpp_file_path)57 void Translate(VtsCompileMode mode,
58 const char* input_vts_file_path,
59 const char* output_header_dir_path,
60 const char* output_cpp_file_path) {
61 string output_header_file_path = string(output_header_dir_path) + "/"
62 + string(input_vts_file_path);
63 output_header_file_path = output_header_file_path + ".h";
64
65 TranslateToFile(mode, input_vts_file_path, output_header_file_path.c_str(),
66 android::vts::kHeader);
67
68 TranslateToFile(mode, input_vts_file_path, output_cpp_file_path,
69 android::vts::kSource);
70 }
71
TranslateToFile(VtsCompileMode mode,const char * input_vts_file_path,const char * output_file_path,VtsCompileFileType file_type)72 void TranslateToFile(VtsCompileMode mode,
73 const char* input_vts_file_path,
74 const char* output_file_path,
75 VtsCompileFileType file_type) {
76 string output_cpp_file_path_str = string(output_file_path);
77
78 size_t found;
79 found = output_cpp_file_path_str.find_last_of("/");
80 string output_dir = output_cpp_file_path_str.substr(0, found + 1);
81
82 ComponentSpecificationMessage message;
83 if (!ParseInterfaceSpec(input_vts_file_path, &message)) {
84 cerr << __func__ << " can't parse " << input_vts_file_path << endl;
85 }
86
87 vts_fs_mkdirs(&output_dir[0], 0777);
88
89 FILE* output_file = fopen(output_file_path, "w+");
90 if (output_file == NULL) {
91 cerr << __func__ << " could not open file " << output_file_path << endl;
92 exit(-1);
93 }
94 Formatter out(output_file);
95
96 if (mode == kDriver) {
97 unique_ptr<CodeGenBase> code_generator;
98 switch (message.component_class()) {
99 case HAL_CONVENTIONAL:
100 code_generator.reset(new HalCodeGen(input_vts_file_path));
101 break;
102 case HAL_CONVENTIONAL_SUBMODULE:
103 code_generator.reset(new HalSubmoduleCodeGen(input_vts_file_path));
104 break;
105 case HAL_LEGACY:
106 code_generator.reset(new LegacyHalCodeGen(input_vts_file_path));
107 break;
108 case LIB_SHARED:
109 code_generator.reset(new LibSharedCodeGen(input_vts_file_path));
110 break;
111 case HAL_HIDL:
112 code_generator.reset(new HalHidlCodeGen(input_vts_file_path));
113 break;
114 default:
115 cerr << "not yet supported component_class "
116 << message.component_class();
117 exit(-1);
118 }
119 if (file_type == kHeader) {
120 code_generator->GenerateHeaderFile(out, message);
121 } else if (file_type == kSource){
122 code_generator->GenerateSourceFile(out, message);
123 } else {
124 cerr << __func__ << " doesn't support file_type = kBoth." << endl;
125 exit(-1);
126 }
127 } else if (mode == kFuzzer) {
128 unique_ptr<FuzzerCodeGenBase> fuzzer_generator;
129 switch (message.component_class()) {
130 case HAL_HIDL:
131 {
132 fuzzer_generator = make_unique<HalHidlFuzzerCodeGen>(message);
133 break;
134 }
135 default:
136 cerr << "not yet supported component_class "
137 << message.component_class();
138 exit(-1);
139 }
140 if (file_type == kHeader) {
141 fuzzer_generator->GenerateHeaderFile(out);
142 } else if (file_type == kSource){
143 fuzzer_generator->GenerateSourceFile(out);
144 } else {
145 cerr << __func__ << " doesn't support file_type = kBoth." << endl;
146 exit(-1);
147 }
148 } else if (mode == kProfiler) {
149 unique_ptr<ProfilerCodeGenBase> profiler_generator;
150 switch (message.component_class()) {
151 case HAL_HIDL:
152 profiler_generator.reset(new HalHidlProfilerCodeGen());
153 break;
154 default:
155 cerr << "not yet supported component_class "
156 << message.component_class();
157 exit(-1);
158 }
159 if (file_type == kHeader) {
160 profiler_generator->GenerateHeaderFile(out, message);
161 } else if (file_type == kSource){
162 profiler_generator->GenerateSourceFile(out, message);
163 } else {
164 cerr << __func__ << " doesn't support file_type = kBoth." << endl;
165 exit(-1);
166 }
167 }
168 }
169
170 } // namespace vts
171 } // namespace android
172