Skip to content

Commit 3881bbd

Browse files
author
Wouter van Oortmerssen
committed
Multiple schemas parsed by flatc are now parsed independently.
It used to be such that later schemas could depend on earlier schemas. This was a convenience from days before include files were implemented. Nowadays they cause subtle bugs rather than being useful, so this functionality has been removed. You now need to explicitly include files you depend upon. Change-Id: Id8292c3c621fc38fbd796da2d2cbdd63efc230d1 Tested: on Linux.
1 parent 7b06041 commit 3881bbd

File tree

5 files changed

+35
-25
lines changed

5 files changed

+35
-25
lines changed

docs/html/md__compiler.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,8 +63,8 @@
6363
<div class="contents">
6464
<div class="textblock"><p>Usage: </p><pre class="fragment">flatc [ GENERATOR OPTIONS ] [ -o PATH ] [ -I PATH ] [ -S ] FILES...
6565
[ -- FILES...]
66-
</pre><p>The files are read and parsed in order, and can contain either schemas or data (see below). Later files can make use of definitions in earlier files.</p>
67-
<p><code>--</code> indicates that the following files are binary files in FlatBuffer format conforming to the schema(s) indicated before it. Incompatible binary files currently will give unpredictable results (!)</p>
66+
</pre><p>The files are read and parsed in order, and can contain either schemas or data (see below). Data files are processed according to the definitions of the most recent schema specified.</p>
67+
<p><code>--</code> indicates that the following files are binary files in FlatBuffer format conforming to the schema indicated before it.</p>
6868
<p>Depending on the flags passed, additional files may be generated for each file processed:</p>
6969
<p>For any schema input files, one or more generators can be specified:</p>
7070
<ul>

docs/source/Compiler.md

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,11 @@ Usage:
66
[ -- FILES...]
77

88
The files are read and parsed in order, and can contain either schemas
9-
or data (see below). Later files can make use of definitions in earlier
10-
files.
9+
or data (see below). Data files are processed according to the definitions of
10+
the most recent schema specified.
1111

1212
`--` indicates that the following files are binary files in
13-
FlatBuffer format conforming to the schema(s) indicated before it.
14-
Incompatible binary files currently will give unpredictable results (!)
13+
FlatBuffer format conforming to the schema indicated before it.
1514

1615
Depending on the flags passed, additional files may
1716
be generated for each file processed:

include/flatbuffers/util.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,12 @@ inline std::string StripExtension(const std::string &filepath) {
174174
return i != std::string::npos ? filepath.substr(0, i) : filepath;
175175
}
176176

177+
// Returns the extension, if any.
178+
inline std::string GetExtension(const std::string &filepath) {
179+
size_t i = filepath.find_last_of(".");
180+
return i != std::string::npos ? filepath.substr(i + 1) : "";
181+
}
182+
177183
// Return the last component of the path, after the last separator.
178184
inline std::string StripPath(const std::string &filepath) {
179185
size_t i = filepath.find_last_of(PathSeparatorSet);

src/flatc.cpp

Lines changed: 21 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,8 @@ const Generator generators[] = {
7979
flatbuffers::GeneralMakeRule },
8080
};
8181

82-
const char *program_name = NULL;
82+
const char *program_name = nullptr;
83+
flatbuffers::Parser *parser = nullptr;
8384

8485
static void Error(const std::string &err, bool usage, bool show_exe_name) {
8586
if (show_exe_name) printf("%s: ", program_name);
@@ -122,6 +123,7 @@ static void Error(const std::string &err, bool usage, bool show_exe_name) {
122123
"example: %s -c -b schema1.fbs schema2.fbs data.json\n",
123124
program_name);
124125
}
126+
if (parser) delete parser;
125127
exit(1);
126128
}
127129

@@ -205,7 +207,7 @@ int main(int argc, const char *argv[]) {
205207
Error("no options: specify one of -c -g -j -t -b etc.", true);
206208

207209
// Now process the files:
208-
flatbuffers::Parser parser(opts.strict_json, proto_mode);
210+
parser = new flatbuffers::Parser(opts.strict_json, proto_mode);
209211
for (auto file_it = filenames.begin();
210212
file_it != filenames.end();
211213
++file_it) {
@@ -216,8 +218,8 @@ int main(int argc, const char *argv[]) {
216218
bool is_binary = static_cast<size_t>(file_it - filenames.begin()) >=
217219
binary_files_from;
218220
if (is_binary) {
219-
parser.builder_.Clear();
220-
parser.builder_.PushFlatBuffer(
221+
parser->builder_.Clear();
222+
parser->builder_.PushFlatBuffer(
221223
reinterpret_cast<const uint8_t *>(contents.c_str()),
222224
contents.length());
223225
if (!raw_binary) {
@@ -226,30 +228,37 @@ int main(int argc, const char *argv[]) {
226228
// does not contain a file identifier.
227229
// We'd expect that typically any binary used as a file would have
228230
// such an identifier, so by default we require them to match.
229-
if (!parser.file_identifier_.length()) {
231+
if (!parser->file_identifier_.length()) {
230232
Error("current schema has no file_identifier: cannot test if \"" +
231233
*file_it +
232234
"\" matches the schema, use --raw-binary to read this file"
233235
" anyway.");
234236
} else if (!flatbuffers::BufferHasIdentifier(contents.c_str(),
235-
parser.file_identifier_.c_str())) {
237+
parser->file_identifier_.c_str())) {
236238
Error("binary \"" +
237239
*file_it +
238240
"\" does not have expected file_identifier \"" +
239-
parser.file_identifier_ +
241+
parser->file_identifier_ +
240242
"\", use --raw-binary to read this file anyway.");
241243
}
242244
}
243245
} else {
246+
if (flatbuffers::GetExtension(*file_it) == "fbs") {
247+
// If we're processing multiple schemas, make sure to start each
248+
// one from scratch. If it depends on previous schemas it must do
249+
// so explicitly using an include.
250+
delete parser;
251+
parser = new flatbuffers::Parser(opts.strict_json, proto_mode);
252+
}
244253
auto local_include_directory = flatbuffers::StripFileName(*file_it);
245254
include_directories.push_back(local_include_directory.c_str());
246255
include_directories.push_back(nullptr);
247-
if (!parser.Parse(contents.c_str(), &include_directories[0],
256+
if (!parser->Parse(contents.c_str(), &include_directories[0],
248257
file_it->c_str()))
249-
Error(parser.error_, false, false);
258+
Error(parser->error_, false, false);
250259
if (schema_binary) {
251-
parser.Serialize();
252-
parser.file_extension_ = reflection::SchemaExtension();
260+
parser->Serialize();
261+
parser->file_extension_ = reflection::SchemaExtension();
253262
}
254263
include_directories.pop_back();
255264
include_directories.pop_back();
@@ -280,11 +289,8 @@ int main(int argc, const char *argv[]) {
280289
}
281290

282291
if (proto_mode) GenerateFBS(parser, output_path, filebase, opts);
283-
284-
// We do not want to generate code for the definitions in this file
285-
// in any files coming up next.
286-
parser.MarkGenerated();
287292
}
288293

294+
delete parser;
289295
return 0;
290296
}

src/idl_parser.cpp

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1072,10 +1072,9 @@ bool Parser::SetRootType(const char *name) {
10721072
}
10731073

10741074
void Parser::MarkGenerated() {
1075-
// Since the Parser object retains definitions across files, we must
1076-
// ensure we only output code for definitions once, in the file they are first
1077-
// declared. This function marks all existing definitions as having already
1078-
// been generated.
1075+
// This function marks all existing definitions as having already
1076+
// been generated, which signals no code for included files should be
1077+
// generated.
10791078
for (auto it = enums_.vec.begin();
10801079
it != enums_.vec.end(); ++it) {
10811080
(*it)->generated = true;

0 commit comments

Comments
 (0)