From 30642c5a6f0fe2728d5b05cd272880d325c18cf6 Mon Sep 17 00:00:00 2001 From: Wouter van Oortmerssen Date: Mon, 22 Sep 2014 15:49:43 -0700 Subject: [PATCH] Added option to flatc to generate dependent header statements. Bug: 17322776 Change-Id: I3a4d3cb4ccd40bc3200a87653aa0ab8ecb90ce60 Tested: on Linux. --- docs/html/md__compiler.html | 3 ++- docs/source/Compiler.md | 2 ++ include/flatbuffers/idl.h | 11 ++++++++--- src/flatc.cpp | 8 +++++++- src/idl_gen_cpp.cpp | 14 ++++++++++++++ src/idl_parser.cpp | 4 +++- 6 files changed, 36 insertions(+), 6 deletions(-) diff --git a/docs/html/md__compiler.html b/docs/html/md__compiler.html index f1f6665c6..cf7a0c8d3 100644 --- a/docs/html/md__compiler.html +++ b/docs/html/md__compiler.html @@ -66,7 +66,8 @@ $(document).ready(function(){initNavTree('md__compiler.html','');});
  • -o PATH : Output all generated files to PATH (either absolute, or relative to the current directory). If omitted, PATH will be the current directory. PATH should end in your systems path separator, e.g. / or \.
  • -I PATH : when encountering include statements, attempt to load the files from this path. Paths will be tried in the order given, and if all fail (or none are specified) it will try to load relative to the path of the schema file being parsed.
  • -S : Generate strict JSON (field names are enclosed in quotes). By default, no quotes are generated.
  • -
  • -P : Don't prefix enum values in generated C++ by their enum type.
  • +
  • -P : Don't prefix enum values in generated C++ by their enum type.
  • +
  • -H : Generate include statements for included schemas the generated file depends on (C++).
  • diff --git a/docs/source/Compiler.md b/docs/source/Compiler.md index 4845b45e3..3f7675aeb 100755 --- a/docs/source/Compiler.md +++ b/docs/source/Compiler.md @@ -42,3 +42,5 @@ be generated for each file processed: - `-P` : Don't prefix enum values in generated C++ by their enum type. +- `-H` : Generate include statements for included schemas the generated file + depends on (C++). diff --git a/include/flatbuffers/idl.h b/include/flatbuffers/idl.h index 0ab3ae151..9d171e88c 100644 --- a/include/flatbuffers/idl.h +++ b/include/flatbuffers/idl.h @@ -282,7 +282,10 @@ class Parser { // include_paths must be nullptr terminated if specified. // If include_paths is nullptr, it will attempt to load from the current // directory. - bool Parse(const char *_source, const char **include_paths = nullptr); + // If the source was loaded from a file and isn't an include file, + // supply its name in source_filename. + bool Parse(const char *_source, const char **include_paths = nullptr, + const char *source_filename = nullptr); // Set the root type. May override the one set in the schema. bool SetRootType(const char *name); @@ -324,6 +327,8 @@ class Parser { std::string file_identifier_; std::string file_extension_; + std::map included_files_; + private: const char *source_, *cursor_; int line_; // the current line being parsed @@ -332,8 +337,6 @@ class Parser { std::vector> field_stack_; std::vector struct_stack_; - - std::map included_files_; }; // Utility functions for multiple generators: @@ -348,6 +351,7 @@ struct GeneratorOptions { int indent_step; bool output_enum_identifiers; bool prefixed_enums; + bool include_dependence_headers; // Possible options for the more general generator below. enum Language { kJava, kCSharp, kMAX }; @@ -356,6 +360,7 @@ struct GeneratorOptions { GeneratorOptions() : strict_json(false), indent_step(2), output_enum_identifiers(true), prefixed_enums(true), + include_dependence_headers(false), lang(GeneratorOptions::kJava) {} }; diff --git a/src/flatc.cpp b/src/flatc.cpp index 425f78c0a..dc697ec53 100755 --- a/src/flatc.cpp +++ b/src/flatc.cpp @@ -101,6 +101,8 @@ static void Error(const char *err, const char *obj, bool usage) { " -I PATH Search for includes in the specified path.\n" " -S Strict JSON: add quotes to field names.\n" " -P Don\'t prefix enum values with the enum name in C++.\n" + " -H Generate include statements for included schemas the\n" + " generated file depends on (C++).\n" "FILEs may depend on declarations in earlier files.\n" "FILEs after the -- must be binary flatbuffer format files.\n" "Output files are named using the base file name of the input," @@ -144,6 +146,9 @@ int main(int argc, const char *argv[]) { case 'P': opts.prefixed_enums = false; break; + case 'H': + opts.include_dependence_headers = true; + break; case '-': // Separator between text and binary input files. binary_files_from = filenames.size(); break; @@ -189,7 +194,8 @@ int main(int argc, const char *argv[]) { 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])) + if (!parser.Parse(contents.c_str(), &include_directories[0], + file_it->c_str())) Error((*file_it + ": " + parser.error_).c_str()); include_directories.pop_back(); include_directories.pop_back(); diff --git a/src/idl_gen_cpp.cpp b/src/idl_gen_cpp.cpp index 8dfd0248f..715a84f24 100644 --- a/src/idl_gen_cpp.cpp +++ b/src/idl_gen_cpp.cpp @@ -547,6 +547,20 @@ std::string GenerateCPP(const Parser &parser, code += "#include \"flatbuffers/flatbuffers.h\"\n\n"; + if (opts.include_dependence_headers) { + int num_includes = 0; + for (auto it = parser.included_files_.begin(); + it != parser.included_files_.end(); ++it) { + auto basename = flatbuffers::StripPath( + flatbuffers::StripExtension(it->first)); + if (basename != file_name) { + code += "#include \"" + basename + "_generated.h\"\n"; + num_includes++; + } + } + if (num_includes) code += "\n"; + } + code += forward_decl_code_other_namespace; code += "\n"; diff --git a/src/idl_parser.cpp b/src/idl_parser.cpp index e1f180cc0..03067737c 100644 --- a/src/idl_parser.cpp +++ b/src/idl_parser.cpp @@ -866,7 +866,9 @@ void Parser::MarkGenerated() { } } -bool Parser::Parse(const char *source, const char **include_paths) { +bool Parser::Parse(const char *source, const char **include_paths, + const char *source_filename) { + if (source_filename) included_files_[source_filename] = true; source_ = cursor_ = source; line_ = 1; error_.clear();