|
10 | 10 | #include <boost/dll/library_info.hpp>
|
11 | 11 | #include "docopt.h"
|
12 | 12 | #include "ecsact/interpret/eval.hh"
|
| 13 | +#include "ecsact/cli/commands/codegen/codegen.hh" |
13 | 14 | #include "ecsact/cli/commands/common.hh"
|
14 | 15 | #include "ecsact/cli/report.hh"
|
15 | 16 | #include "ecsact/runtime/dynamic.h"
|
@@ -37,36 +38,12 @@ constexpr auto USAGE = R"(Ecsact Codegen Command
|
37 | 38 | --report_filter=<filter> Filtering out report logs [default: none]
|
38 | 39 | )";
|
39 | 40 |
|
40 |
| -static void stdout_write_fn(const char* str, int32_t str_len) { |
41 |
| - std::cout << std::string_view(str, str_len); |
42 |
| -} |
43 |
| - |
44 |
| -static bool received_fatal_codegen_report = false; |
45 |
| - |
46 |
| -static auto codegen_report_fn( |
47 |
| - ecsact_codegen_report_message_type type, |
48 |
| - const char* str, |
49 |
| - int32_t str_len |
| 41 | +static auto stdout_write_fn( |
| 42 | + int32_t filename_index, |
| 43 | + const char* str, |
| 44 | + int32_t str_len |
50 | 45 | ) -> void {
|
51 |
| - auto msg = std::string{str, static_cast<size_t>(str_len)}; |
52 |
| - switch(type) { |
53 |
| - default: |
54 |
| - case ECSACT_CODEGEN_REPORT_INFO: |
55 |
| - return report(ecsact::cli::info_message{msg}); |
56 |
| - case ECSACT_CODEGEN_REPORT_WARNING: |
57 |
| - return report(ecsact::cli::warning_message{msg}); |
58 |
| - case ECSACT_CODEGEN_REPORT_ERROR: |
59 |
| - return report(ecsact::cli::error_message{msg}); |
60 |
| - case ECSACT_CODEGEN_REPORT_FATAL: |
61 |
| - received_fatal_codegen_report = true; |
62 |
| - return report(ecsact::cli::error_message{msg}); |
63 |
| - } |
64 |
| -} |
65 |
| - |
66 |
| -static thread_local std::ofstream file_write_stream; |
67 |
| - |
68 |
| -static void file_write_fn(const char* str, int32_t str_len) { |
69 |
| - file_write_stream << std::string_view(str, str_len); |
| 46 | + std::cout << std::string_view(str, str_len); |
70 | 47 | }
|
71 | 48 |
|
72 | 49 | int ecsact::cli::detail::codegen_command(int argc, const char* argv[]) {
|
@@ -161,135 +138,37 @@ int ecsact::cli::detail::codegen_command(int argc, const char* argv[]) {
|
161 | 138 | return 1;
|
162 | 139 | }
|
163 | 140 |
|
164 |
| - std::vector<ecsact_package_id> package_ids; |
165 |
| - package_ids.resize(static_cast<int32_t>(ecsact_meta_count_packages())); |
166 |
| - ecsact_meta_get_package_ids( |
167 |
| - static_cast<int32_t>(package_ids.size()), |
168 |
| - package_ids.data(), |
169 |
| - nullptr |
170 |
| - ); |
171 |
| - |
172 |
| - std::unordered_set<std::string> output_paths; |
173 |
| - bool has_plugin_error = false; |
174 |
| - |
175 |
| - for(auto& plugin : plugins) { |
176 |
| - // precondition: these methods should've been checked in validation |
177 |
| - assert(plugin.has("ecsact_codegen_plugin")); |
178 |
| - assert(plugin.has("ecsact_codegen_plugin_name")); |
179 |
| - assert(plugin.has("ecsact_dylib_set_fn_addr")); |
180 |
| - |
181 |
| - auto plugin_fn = |
182 |
| - plugin.get<decltype(ecsact_codegen_plugin)>("ecsact_codegen_plugin"); |
183 |
| - auto plugin_name_fn = plugin.get<decltype(ecsact_codegen_plugin_name)>( |
184 |
| - "ecsact_codegen_plugin_name" |
185 |
| - ); |
186 |
| - std::string plugin_name = plugin_name_fn(); |
187 |
| - |
188 |
| - decltype(&ecsact_dylib_has_fn) dylib_has_fn = nullptr; |
189 |
| - |
190 |
| - if(plugin.has("ecsact_dylib_has_fn")) { |
191 |
| - dylib_has_fn = |
192 |
| - plugin.get<decltype(ecsact_dylib_has_fn)>("ecsact_dylib_has_fn"); |
193 |
| - } |
194 |
| - |
195 |
| - auto dylib_set_fn_addr = |
196 |
| - plugin.get<decltype(ecsact_dylib_set_fn_addr)>("ecsact_dylib_set_fn_addr" |
197 |
| - ); |
198 |
| - |
199 |
| - auto set_meta_fn_ptr = [&](const char* fn_name, auto fn_ptr) { |
200 |
| - if(dylib_has_fn && !dylib_has_fn(fn_name)) { |
201 |
| - return; |
202 |
| - } |
203 |
| - dylib_set_fn_addr(fn_name, reinterpret_cast<void (*)()>(fn_ptr)); |
204 |
| - }; |
205 |
| - |
206 |
| -#define CALL_SET_META_FN_PTR(fn_name, unused) \ |
207 |
| - set_meta_fn_ptr(#fn_name, &::fn_name) |
208 |
| - FOR_EACH_ECSACT_META_API_FN(CALL_SET_META_FN_PTR); |
209 |
| -#undef CALL_SET_META_FN_PTR |
210 |
| - |
211 |
| - std::optional<fs::path> outdir; |
212 |
| - if(args.at("--outdir").isString()) { |
213 |
| - outdir = fs::path(args.at("--outdir").asString()); |
214 |
| - if(!fs::exists(*outdir)) { |
215 |
| - std::error_code ec; |
216 |
| - fs::create_directories(*outdir, ec); |
217 |
| - if(ec) { |
218 |
| - report_error( |
219 |
| - "Failed to create out directory {}: {}", |
220 |
| - outdir->string(), |
221 |
| - ec.message() |
222 |
| - ); |
223 |
| - return 3; |
224 |
| - } |
225 |
| - } |
226 |
| - } |
227 |
| - |
228 |
| - if(args.at("--stdout").asBool()) { |
229 |
| - plugin_fn(*package_ids.begin(), &stdout_write_fn, &codegen_report_fn); |
230 |
| - std::cout.flush(); |
231 |
| - if(received_fatal_codegen_report) { |
232 |
| - received_fatal_codegen_report = false; |
233 |
| - has_plugin_error = true; |
234 |
| - report_error("Codegen plugin '{}' reported fatal error", plugin_name); |
235 |
| - } |
236 |
| - } else { |
237 |
| - for(auto package_id : package_ids) { |
238 |
| - fs::path output_file_path = ecsact_meta_package_file_path(package_id); |
239 |
| - if(output_file_path.empty()) { |
240 |
| - report_error( |
241 |
| - "Could not find package source file path from " |
242 |
| - "'ecsact_meta_package_file_path'" |
243 |
| - ); |
244 |
| - continue; |
245 |
| - } |
246 |
| - |
247 |
| - output_file_path.replace_extension( |
248 |
| - output_file_path.extension().string() + "." + plugin_name |
| 141 | + std::optional<fs::path> outdir; |
| 142 | + if(args.at("--outdir").isString()) { |
| 143 | + outdir = fs::path(args.at("--outdir").asString()); |
| 144 | + if(!fs::exists(*outdir)) { |
| 145 | + std::error_code ec; |
| 146 | + fs::create_directories(*outdir, ec); |
| 147 | + if(ec) { |
| 148 | + report_error( |
| 149 | + "Failed to create out directory {}: {}", |
| 150 | + outdir->string(), |
| 151 | + ec.message() |
249 | 152 | );
|
250 |
| - |
251 |
| - if(outdir) { |
252 |
| - output_file_path = *outdir / output_file_path.filename(); |
253 |
| - } |
254 |
| - |
255 |
| - if(output_paths.contains(output_file_path.string())) { |
256 |
| - has_plugin_error = true; |
257 |
| - report_error( |
258 |
| - "Plugin '{}' has conflicts with another plugin output file '{}'", |
259 |
| - plugin.location().filename().string(), |
260 |
| - output_file_path.string() |
261 |
| - ); |
262 |
| - continue; |
263 |
| - } |
264 |
| - |
265 |
| - output_paths.emplace(output_file_path.string()); |
266 |
| - if(fs::exists(output_file_path)) { |
267 |
| - fs::permissions(output_file_path, fs::perms::all); |
268 |
| - } |
269 |
| - file_write_stream.open(output_file_path); |
270 |
| - plugin_fn(package_id, &file_write_fn, &codegen_report_fn); |
271 |
| - file_write_stream.flush(); |
272 |
| - file_write_stream.close(); |
273 |
| - fs::permissions(output_file_path, file_readonly_perms); |
274 |
| - if(received_fatal_codegen_report) { |
275 |
| - received_fatal_codegen_report = false; |
276 |
| - report_error( |
277 |
| - "Codegen plugin '{}' reported fatal error while processing package " |
278 |
| - "'{}'", |
279 |
| - plugin_name, |
280 |
| - ecsact::meta::package_name(package_id) |
281 |
| - ); |
282 |
| - has_plugin_error = true; |
283 |
| - } |
| 153 | + return 3; |
284 | 154 | }
|
285 | 155 | }
|
| 156 | + } |
286 | 157 |
|
287 |
| - plugin.unload(); |
| 158 | + auto codegen_options = ecsact::cli::codegen_options{ |
| 159 | + .plugin_paths = plugin_paths, |
| 160 | + .outdir = outdir, |
| 161 | + }; |
| 162 | + |
| 163 | + if(args.at("--stdout").asBool()) { |
| 164 | + codegen_options.write_fn = &stdout_write_fn; |
288 | 165 | }
|
289 | 166 |
|
290 |
| - if(has_plugin_error) { |
291 |
| - return 2; |
| 167 | + auto exit_code = ecsact::cli::codegen(codegen_options); |
| 168 | + |
| 169 | + if(args.at("--stdout").asBool()) { |
| 170 | + std::cout.flush(); |
292 | 171 | }
|
293 | 172 |
|
294 |
| - return 0; |
| 173 | + return exit_code; |
295 | 174 | }
|
0 commit comments