Added option to flatc to generate dependent header statements.

Bug: 17322776
Change-Id: I3a4d3cb4ccd40bc3200a87653aa0ab8ecb90ce60
Tested: on Linux.
parent 517c964f
...@@ -66,7 +66,8 @@ $(document).ready(function(){initNavTree('md__compiler.html','');}); ...@@ -66,7 +66,8 @@ $(document).ready(function(){initNavTree('md__compiler.html','');});
<li><code>-o PATH</code> : 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. <code>/</code> or <code>\</code>.</li> <li><code>-o PATH</code> : 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. <code>/</code> or <code>\</code>.</li>
<li><code>-I PATH</code> : when encountering <code>include</code> 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.</li> <li><code>-I PATH</code> : when encountering <code>include</code> 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.</li>
<li><code>-S</code> : Generate strict JSON (field names are enclosed in quotes). By default, no quotes are generated.</li> <li><code>-S</code> : Generate strict JSON (field names are enclosed in quotes). By default, no quotes are generated.</li>
<li><code>-P</code> : Don't prefix enum values in generated C++ by their enum type. </li> <li><code>-P</code> : Don't prefix enum values in generated C++ by their enum type.</li>
<li><code>-H</code> : Generate include statements for included schemas the generated file depends on (C++). </li>
</ul> </ul>
</div></div><!-- contents --> </div></div><!-- contents -->
</div><!-- doc-content --> </div><!-- doc-content -->
......
...@@ -42,3 +42,5 @@ be generated for each file processed: ...@@ -42,3 +42,5 @@ be generated for each file processed:
- `-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++).
...@@ -282,7 +282,10 @@ class Parser { ...@@ -282,7 +282,10 @@ class Parser {
// include_paths must be nullptr terminated if specified. // include_paths must be nullptr terminated if specified.
// If include_paths is nullptr, it will attempt to load from the current // If include_paths is nullptr, it will attempt to load from the current
// directory. // 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. // Set the root type. May override the one set in the schema.
bool SetRootType(const char *name); bool SetRootType(const char *name);
...@@ -324,6 +327,8 @@ class Parser { ...@@ -324,6 +327,8 @@ class Parser {
std::string file_identifier_; std::string file_identifier_;
std::string file_extension_; std::string file_extension_;
std::map<std::string, bool> included_files_;
private: private:
const char *source_, *cursor_; const char *source_, *cursor_;
int line_; // the current line being parsed int line_; // the current line being parsed
...@@ -332,8 +337,6 @@ class Parser { ...@@ -332,8 +337,6 @@ class Parser {
std::vector<std::pair<Value, FieldDef *>> field_stack_; std::vector<std::pair<Value, FieldDef *>> field_stack_;
std::vector<uint8_t> struct_stack_; std::vector<uint8_t> struct_stack_;
std::map<std::string, bool> included_files_;
}; };
// Utility functions for multiple generators: // Utility functions for multiple generators:
...@@ -348,6 +351,7 @@ struct GeneratorOptions { ...@@ -348,6 +351,7 @@ struct GeneratorOptions {
int indent_step; int indent_step;
bool output_enum_identifiers; bool output_enum_identifiers;
bool prefixed_enums; bool prefixed_enums;
bool include_dependence_headers;
// Possible options for the more general generator below. // Possible options for the more general generator below.
enum Language { kJava, kCSharp, kMAX }; enum Language { kJava, kCSharp, kMAX };
...@@ -356,6 +360,7 @@ struct GeneratorOptions { ...@@ -356,6 +360,7 @@ struct GeneratorOptions {
GeneratorOptions() : strict_json(false), indent_step(2), GeneratorOptions() : strict_json(false), indent_step(2),
output_enum_identifiers(true), prefixed_enums(true), output_enum_identifiers(true), prefixed_enums(true),
include_dependence_headers(false),
lang(GeneratorOptions::kJava) {} lang(GeneratorOptions::kJava) {}
}; };
......
...@@ -101,6 +101,8 @@ static void Error(const char *err, const char *obj, bool usage) { ...@@ -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" " -I PATH Search for includes in the specified path.\n"
" -S Strict JSON: add quotes to field names.\n" " -S Strict JSON: add quotes to field names.\n"
" -P Don\'t prefix enum values with the enum name in C++.\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 may depend on declarations in earlier files.\n"
"FILEs after the -- must be binary flatbuffer format files.\n" "FILEs after the -- must be binary flatbuffer format files.\n"
"Output files are named using the base file name of the input," "Output files are named using the base file name of the input,"
...@@ -144,6 +146,9 @@ int main(int argc, const char *argv[]) { ...@@ -144,6 +146,9 @@ int main(int argc, const char *argv[]) {
case 'P': case 'P':
opts.prefixed_enums = false; opts.prefixed_enums = false;
break; break;
case 'H':
opts.include_dependence_headers = true;
break;
case '-': // Separator between text and binary input files. case '-': // Separator between text and binary input files.
binary_files_from = filenames.size(); binary_files_from = filenames.size();
break; break;
...@@ -189,7 +194,8 @@ int main(int argc, const char *argv[]) { ...@@ -189,7 +194,8 @@ int main(int argc, const char *argv[]) {
auto local_include_directory = flatbuffers::StripFileName(*file_it); auto local_include_directory = flatbuffers::StripFileName(*file_it);
include_directories.push_back(local_include_directory.c_str()); include_directories.push_back(local_include_directory.c_str());
include_directories.push_back(nullptr); 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()); Error((*file_it + ": " + parser.error_).c_str());
include_directories.pop_back(); include_directories.pop_back();
include_directories.pop_back(); include_directories.pop_back();
......
...@@ -547,6 +547,20 @@ std::string GenerateCPP(const Parser &parser, ...@@ -547,6 +547,20 @@ std::string GenerateCPP(const Parser &parser,
code += "#include \"flatbuffers/flatbuffers.h\"\n\n"; 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 += forward_decl_code_other_namespace;
code += "\n"; code += "\n";
......
...@@ -866,7 +866,9 @@ void Parser::MarkGenerated() { ...@@ -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; source_ = cursor_ = source;
line_ = 1; line_ = 1;
error_.clear(); error_.clear();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment