From c559eb451e7783b72c44e27db375158edaa498b7 Mon Sep 17 00:00:00 2001 From: Wouter van Oortmerssen Date: Fri, 12 May 2017 15:58:26 -0700 Subject: Made codegen always output a file, even on an empty schema. Previously, we had a check to simply skip such files, but this tends to make build systems unhappy. This only affects C++ and JS, since other language output per-class files. Change-Id: I54224642725bbafb9f6e1654ed3693e62ca9f7d7 Tested: on Linux. --- src/code_generators.cpp | 12 ---- src/flatc.cpp | 168 ++++++++++++++++++++++++------------------------ src/flatc_main.cpp | 20 +++--- src/idl_gen_cpp.cpp | 5 +- src/idl_gen_js.cpp | 2 - 5 files changed, 96 insertions(+), 111 deletions(-) (limited to 'src') diff --git a/src/code_generators.cpp b/src/code_generators.cpp index b9e73c62..7838cedf 100644 --- a/src/code_generators.cpp +++ b/src/code_generators.cpp @@ -89,18 +89,6 @@ std::string BaseGenerator::NamespaceDir(const Namespace &ns) const { return BaseGenerator::NamespaceDir(parser_, path_, ns); } -bool BaseGenerator::IsEverythingGenerated() const { - for (auto it = parser_.enums_.vec.begin(); it != parser_.enums_.vec.end(); - ++it) { - if (!(*it)->generated) return false; - } - for (auto it = parser_.structs_.vec.begin(); - it != parser_.structs_.vec.end(); ++it) { - if (!(*it)->generated) return false; - } - return true; - } - std::string BaseGenerator::FullNamespace(const char *separator, const Namespace &ns) { std::string namespace_name; diff --git a/src/flatc.cpp b/src/flatc.cpp index d940d3ac..b791fb09 100644 --- a/src/flatc.cpp +++ b/src/flatc.cpp @@ -267,101 +267,103 @@ int FlatCompiler::Compile(int argc, const char** argv) { 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); + auto &filename = *file_it; + std::string contents; + if (!flatbuffers::LoadFile(filename.c_str(), true, &contents)) + Error("unable to load file: " + filename); - bool is_binary = static_cast(file_it - filenames.begin()) >= - binary_files_from; - if (is_binary) { - parser->builder_.Clear(); - parser->builder_.PushFlatBuffer( - reinterpret_cast(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); - } - auto is_schema = flatbuffers::GetExtension(*file_it) == "fbs"; - if (is_schema) { - // 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. - parser.reset(new flatbuffers::Parser(opts)); - } - ParseFile(*parser.get(), *file_it, contents, include_directories); - if (is_schema && !conform_to_schema.empty()) { - auto err = parser->ConformTo(conform_parser); - if (!err.empty()) Error("schemas don\'t conform: " + err); - } - if (schema_binary) { - parser->Serialize(); - parser->file_extension_ = reflection::SchemaExtension(); + bool is_binary = static_cast(file_it - filenames.begin()) >= + binary_files_from; + auto is_schema = flatbuffers::GetExtension(filename) == "fbs"; + if (is_binary) { + parser->builder_.Clear(); + parser->builder_.PushFlatBuffer( + reinterpret_cast(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 \"" + + filename + + "\" 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 \"" + + filename + + "\" 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: " + filename, true); + } + if (is_schema) { + // 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. + parser.reset(new flatbuffers::Parser(opts)); + } + ParseFile(*parser.get(), filename, contents, include_directories); + if (is_schema && !conform_to_schema.empty()) { + auto err = parser->ConformTo(conform_parser); + if (!err.empty()) Error("schemas don\'t conform: " + err); + } + if (schema_binary) { + parser->Serialize(); + parser->file_extension_ = reflection::SchemaExtension(); + } + } - std::string filebase = flatbuffers::StripPath( - flatbuffers::StripExtension(*file_it)); + std::string filebase = flatbuffers::StripPath( + flatbuffers::StripExtension(filename)); - for (size_t i = 0; i < params_.num_generators; ++i) { - parser->opts.lang = params_.generators[i].lang; - if (generator_enabled[i]) { - if (!print_make_rules) { - flatbuffers::EnsureDirExists(output_path); - if (!params_.generators[i].generate(*parser.get(), output_path, filebase)) { - Error(std::string("Unable to generate ") + - params_.generators[i].lang_name + - " for " + - filebase); - } - } else { - std::string make_rule = params_.generators[i].make_rule( - *parser.get(), output_path, *file_it); - if (!make_rule.empty()) - printf("%s\n", flatbuffers::WordWrap( - make_rule, 80, " ", " \\").c_str()); + for (size_t i = 0; i < params_.num_generators; ++i) { + parser->opts.lang = params_.generators[i].lang; + if (generator_enabled[i]) { + if (!print_make_rules) { + flatbuffers::EnsureDirExists(output_path); + if ((!params_.generators[i].schema_only || is_schema) && + !params_.generators[i].generate(*parser.get(), output_path, filebase)) { + Error(std::string("Unable to generate ") + + params_.generators[i].lang_name + + " for " + + filebase); } - if (grpc_enabled) { - if (params_.generators[i].generateGRPC != nullptr) { - if (!params_.generators[i].generateGRPC(*parser.get(), output_path, - filebase)) { - Error(std::string("Unable to generate GRPC interface for") + - params_.generators[i].lang_name); - } - } else { - Warn(std::string("GRPC interface generator not implemented for ") - + params_.generators[i].lang_name); + } else { + std::string make_rule = params_.generators[i].make_rule( + *parser.get(), output_path, filename); + if (!make_rule.empty()) + printf("%s\n", flatbuffers::WordWrap( + make_rule, 80, " ", " \\").c_str()); + } + if (grpc_enabled) { + if (params_.generators[i].generateGRPC != nullptr) { + if (!params_.generators[i].generateGRPC(*parser.get(), output_path, + filebase)) { + Error(std::string("Unable to generate GRPC interface for") + + params_.generators[i].lang_name); } + } else { + Warn(std::string("GRPC interface generator not implemented for ") + + params_.generators[i].lang_name); } } } + } - if (opts.proto_mode) GenerateFBS(*parser.get(), output_path, filebase); + if (opts.proto_mode) GenerateFBS(*parser.get(), output_path, filebase); - // We do not want to generate code for the definitions in this file - // in any files coming up next. - parser->MarkGenerated(); + // We do not want to generate code for the definitions in this file + // in any files coming up next. + parser->MarkGenerated(); } return 0; } diff --git a/src/flatc_main.cpp b/src/flatc_main.cpp index d838bac8..cb8f217b 100644 --- a/src/flatc_main.cpp +++ b/src/flatc_main.cpp @@ -46,52 +46,52 @@ int main(int argc, const char *argv[]) { g_program_name = argv[0]; const flatbuffers::FlatCompiler::Generator generators[] = { - { flatbuffers::GenerateBinary, "-b", "--binary", "binary", + { flatbuffers::GenerateBinary, "-b", "--binary", "binary", false, nullptr, flatbuffers::IDLOptions::kBinary, "Generate wire format binaries for any data definitions", flatbuffers::BinaryMakeRule }, - { flatbuffers::GenerateTextFile, "-t", "--json", "text", + { flatbuffers::GenerateTextFile, "-t", "--json", "text", false, nullptr, flatbuffers::IDLOptions::kJson, "Generate text output for any data definitions", flatbuffers::TextMakeRule }, - { flatbuffers::GenerateCPP, "-c", "--cpp", "C++", + { flatbuffers::GenerateCPP, "-c", "--cpp", "C++", true, flatbuffers::GenerateCppGRPC, flatbuffers::IDLOptions::kCpp, "Generate C++ headers for tables/structs", flatbuffers::CPPMakeRule }, - { flatbuffers::GenerateGo, "-g", "--go", "Go", + { flatbuffers::GenerateGo, "-g", "--go", "Go", true, flatbuffers::GenerateGoGRPC, flatbuffers::IDLOptions::kGo, "Generate Go files for tables/structs", flatbuffers::GeneralMakeRule }, - { flatbuffers::GenerateGeneral, "-j", "--java", "Java", + { flatbuffers::GenerateGeneral, "-j", "--java", "Java", true, nullptr, flatbuffers::IDLOptions::kJava, "Generate Java classes for tables/structs", flatbuffers::GeneralMakeRule }, - { flatbuffers::GenerateJS, "-s", "--js", "JavaScript", + { flatbuffers::GenerateJS, "-s", "--js", "JavaScript", true, nullptr, flatbuffers::IDLOptions::kJs, "Generate JavaScript code for tables/structs", flatbuffers::JSMakeRule }, - { flatbuffers::GenerateJS, "-T", "--ts", "TypeScript", + { flatbuffers::GenerateJS, "-T", "--ts", "TypeScript", true, nullptr, flatbuffers::IDLOptions::kTs, "Generate TypeScript code for tables/structs", flatbuffers::JSMakeRule }, - { flatbuffers::GenerateGeneral, "-n", "--csharp", "C#", + { flatbuffers::GenerateGeneral, "-n", "--csharp", "C#", true, nullptr, flatbuffers::IDLOptions::kCSharp, "Generate C# classes for tables/structs", flatbuffers::GeneralMakeRule }, - { flatbuffers::GeneratePython, "-p", "--python", "Python", + { flatbuffers::GeneratePython, "-p", "--python", "Python", true, nullptr, flatbuffers::IDLOptions::kPython, "Generate Python files for tables/structs", flatbuffers::GeneralMakeRule }, - { flatbuffers::GeneratePhp, nullptr, "--php", "PHP", + { flatbuffers::GeneratePhp, nullptr, "--php", "PHP", true, nullptr, flatbuffers::IDLOptions::kPhp, "Generate PHP files for tables/structs", diff --git a/src/idl_gen_cpp.cpp b/src/idl_gen_cpp.cpp index 3fe447ef..169acd58 100644 --- a/src/idl_gen_cpp.cpp +++ b/src/idl_gen_cpp.cpp @@ -87,8 +87,6 @@ class CppGenerator : public BaseGenerator { // Iterate through all definitions we haven't generate code for (enums, // structs, and tables) and output them to a single file. bool generate() { - if (IsEverythingGenerated()) return true; - code_.Clear(); code_ += "// " + std::string(FlatBuffersGeneratedWarning()); @@ -261,8 +259,7 @@ class CppGenerator : public BaseGenerator { } } - assert(cur_name_space_); - SetNameSpace(nullptr); + if (cur_name_space_) SetNameSpace(nullptr); // Close the include guard. code_ += "#endif // " + include_guard; diff --git a/src/idl_gen_js.cpp b/src/idl_gen_js.cpp index 9fe0b4fc..a07d5f11 100644 --- a/src/idl_gen_js.cpp +++ b/src/idl_gen_js.cpp @@ -83,8 +83,6 @@ class JsGenerator : public BaseGenerator { // Iterate through all definitions we haven't generate code for (enums, // structs, and tables) and output them to a single file. bool generate() { - if (IsEverythingGenerated()) return true; - imported_fileset imported_files; reexport_map reexports; -- cgit v1.2.3