bool GenerateFBS(const Parser &parser, const std::string &path, const std::string &file_name, const GeneratorOptions &opts) { return SaveFile((path + file_name + ".fbs").c_str(), GenerateFBS(parser, file_name, opts), false); }
int main(int argc, const char *argv[]) { program_name = argv[0]; flatbuffers::IDLOptions opts; std::string output_path; const size_t num_generators = sizeof(generators) / sizeof(generators[0]); bool generator_enabled[num_generators] = { false }; bool any_generator = false; bool print_make_rules = false; bool raw_binary = false; bool schema_binary = false; std::vector<std::string> filenames; std::vector<const char *> include_directories; size_t binary_files_from = std::numeric_limits<size_t>::max(); for (int argi = 1; argi < argc; argi++) { std::string arg = argv[argi]; if (arg[0] == '-') { if (filenames.size() && arg[1] != '-') Error("invalid option location: " + arg, true); if (arg == "-o") { if (++argi >= argc) Error("missing path following: " + arg, true); output_path = flatbuffers::ConCatPathFileName(argv[argi], ""); } else if(arg == "-I") { if (++argi >= argc) Error("missing path following" + arg, true); include_directories.push_back(argv[argi]); } else if(arg == "--strict-json") { opts.strict_json = true; } else if(arg == "--no-js-exports") { opts.skip_js_exports = true; } else if(arg == "--defaults-json") { opts.output_default_scalars_in_json = true; } else if (arg == "--unknown-json") { opts.skip_unexpected_fields_in_json = true; } else if(arg == "--no-prefix") { opts.prefixed_enums = false; } else if(arg == "--scoped-enums") { opts.prefixed_enums = false; opts.scoped_enums = true; } else if(arg == "--gen-mutable") { opts.mutable_buffer = true; } else if(arg == "--gen-all") { opts.generate_all = true; opts.include_dependence_headers = false; } else if(arg == "--gen-includes") { // Deprecated, remove this option some time in the future. printf("warning: --gen-includes is deprecated (it is now default)\n"); } else if(arg == "--no-includes") { opts.include_dependence_headers = false; } else if (arg == "--gen-onefile") { opts.one_file = true; } else if (arg == "--raw-binary") { raw_binary = true; } else if(arg == "--") { // Separator between text and binary inputs. binary_files_from = filenames.size(); } else if(arg == "--proto") { opts.proto_mode = true; } else if(arg == "--schema") { schema_binary = true; } else if(arg == "-M") { print_make_rules = true; } else { for (size_t i = 0; i < num_generators; ++i) { if (arg == generators[i].generator_opt_long || (generators[i].generator_opt_short && arg == generators[i].generator_opt_short)) { generator_enabled[i] = true; any_generator = true; goto found; } } Error("unknown commandline argument" + arg, true); found:; } } else { filenames.push_back(argv[argi]); } } if (!filenames.size()) Error("missing input files", false, true); if (opts.proto_mode) { if (any_generator) Error("cannot generate code directly from .proto files", true); } else if (!any_generator) { Error("no options: specify at least one generator.", true); } // Now process the files: parser = new flatbuffers::Parser(opts); for (auto file_it = filenames.begin(); file_it != filenames.end(); ++file_it) { std::string contents; if (!flatbuffers::LoadFile(file_it->c_str(), true, &contents)) Error("unable to load file: " + *file_it); bool is_binary = static_cast<size_t>(file_it - filenames.begin()) >= binary_files_from; if (is_binary) { parser->builder_.Clear(); parser->builder_.PushFlatBuffer( reinterpret_cast<const uint8_t *>(contents.c_str()), contents.length()); if (!raw_binary) { // Generally reading binaries that do not correspond to the schema // will crash, and sadly there's no way around that when the binary // does not contain a file identifier. // We'd expect that typically any binary used as a file would have // such an identifier, so by default we require them to match. if (!parser->file_identifier_.length()) { Error("current schema has no file_identifier: cannot test if \"" + *file_it + "\" matches the schema, use --raw-binary to read this file" " anyway."); } else if (!flatbuffers::BufferHasIdentifier(contents.c_str(), parser->file_identifier_.c_str())) { Error("binary \"" + *file_it + "\" does not have expected file_identifier \"" + parser->file_identifier_ + "\", use --raw-binary to read this file anyway."); } } } else { // Check if file contains 0 bytes. if (contents.length() != strlen(contents.c_str())) { Error("input file appears to be binary: " + *file_it, true); } if (flatbuffers::GetExtension(*file_it) == "fbs") { // If we're processing multiple schemas, make sure to start each // one from scratch. If it depends on previous schemas it must do // so explicitly using an include. delete parser; parser = new flatbuffers::Parser(opts); } auto local_include_directory = flatbuffers::StripFileName(*file_it); include_directories.push_back(local_include_directory.c_str()); include_directories.push_back(nullptr); if (!parser->Parse(contents.c_str(), &include_directories[0], file_it->c_str())) Error(parser->error_, false, false); if (schema_binary) { parser->Serialize(); parser->file_extension_ = reflection::SchemaExtension(); } include_directories.pop_back(); include_directories.pop_back(); } std::string filebase = flatbuffers::StripPath( flatbuffers::StripExtension(*file_it)); for (size_t i = 0; i < num_generators; ++i) { parser->opts.lang = generators[i].lang; if (generator_enabled[i]) { if (!print_make_rules) { flatbuffers::EnsureDirExists(output_path); if (!generators[i].generate(*parser, output_path, filebase)) { Error(std::string("Unable to generate ") + generators[i].lang_name + " for " + filebase); } } else { std::string make_rule = generators[i].make_rule( *parser, output_path, *file_it); if (!make_rule.empty()) printf("%s\n", flatbuffers::WordWrap( make_rule, 80, " ", " \\").c_str()); } } } if (opts.proto_mode) GenerateFBS(*parser, output_path, filebase); // We do not want to generate code for the definitions in this file // in any files coming up next. parser->MarkGenerated(); } delete parser; return 0; }
int main(int argc, const char *argv[]) { program_name = argv[0]; flatbuffers::GeneratorOptions opts; std::string output_path; const size_t num_generators = sizeof(generators) / sizeof(generators[0]); bool generator_enabled[num_generators] = { false }; bool any_generator = false; bool proto_mode = false; std::vector<std::string> filenames; std::vector<const char *> include_directories; size_t binary_files_from = std::numeric_limits<size_t>::max(); for (int i = 1; i < argc; i++) { const char *arg = argv[i]; if (arg[0] == '-') { if (filenames.size() && arg[1] != '-') Error("invalid option location", arg, true); std::string opt = arg; if (opt == "-o") { if (++i >= argc) Error("missing path following", arg, true); output_path = flatbuffers::ConCatPathFileName(argv[i], ""); } else if(opt == "-I") { if (++i >= argc) Error("missing path following", arg, true); include_directories.push_back(argv[i]); } else if(opt == "--strict-json") { opts.strict_json = true; } else if(opt == "--no-prefix") { opts.prefixed_enums = false; } else if(opt == "--gen-includes") { opts.include_dependence_headers = true; } else if(opt == "--") { // Separator between text and binary inputs. binary_files_from = filenames.size(); } else if(opt == "--proto") { proto_mode = true; any_generator = true; } else { for (size_t j = 0; j < num_generators; ++j) { if(opt == generators[j].opt) { generator_enabled[j] = true; any_generator = true; goto found; } } Error("unknown commandline argument", arg, true); found:; } } else { filenames.push_back(argv[i]); } } if (!filenames.size()) Error("missing input files", nullptr, true); if (!any_generator) Error("no options: no output files generated.", "specify one of -c -g -j -t -b etc.", true); // Now process the files: flatbuffers::Parser parser(proto_mode); for (auto file_it = filenames.begin(); file_it != filenames.end(); ++file_it) { std::string contents; if (!flatbuffers::LoadFile(file_it->c_str(), true, &contents)) Error("unable to load file", file_it->c_str()); bool is_binary = static_cast<size_t>(file_it - filenames.begin()) >= binary_files_from; if (is_binary) { parser.builder_.Clear(); parser.builder_.PushBytes( reinterpret_cast<const uint8_t *>(contents.c_str()), contents.length()); } else { auto local_include_directory = flatbuffers::StripFileName(*file_it); include_directories.push_back(local_include_directory.c_str()); include_directories.push_back(nullptr); if (!parser.Parse(contents.c_str(), &include_directories[0], file_it->c_str())) Error(parser.error_.c_str(), nullptr, false, false); include_directories.pop_back(); include_directories.pop_back(); } std::string filebase = flatbuffers::StripPath( flatbuffers::StripExtension(*file_it)); for (size_t i = 0; i < num_generators; ++i) { if (generator_enabled[i]) { flatbuffers::EnsureDirExists(output_path); opts.lang = generators[i].lang; if (!generators[i].generate(parser, output_path, filebase, opts)) { Error((std::string("Unable to generate ") + generators[i].name + " for " + filebase).c_str()); } } } if (proto_mode) GenerateFBS(parser, output_path, filebase, opts); // We do not want to generate code for the definitions in this file // in any files coming up next. parser.MarkGenerated(); } return 0; }