-/* Generated by re2c 0.16 on Tue May 10 13:30:37 2016 */
+/* Generated by re2c 0.16 on Wed May 11 11:08:20 2016 */
#line 1 "../src/conf/parse_opts.re"
#include "src/codegen/input_api.h"
#include "src/conf/msg.h"
yy605:
++YYCURSOR;
#line 173 "../src/conf/parse_opts.re"
- { if (!opts.output (*argv)) return EXIT_FAIL; goto opt; }
+ { opts.set_output_file(*argv); goto opt; }
#line 2463 "src/conf/parse_opts.cc"
yy607:
++YYCURSOR;
-/* Generated by re2c 0.16 on Tue May 10 16:46:34 2016 */
+/* Generated by re2c 0.16 on Wed May 11 11:08:20 2016 */
#line 1 "../src/parse/lex_conf.re"
#include "src/util/c99_stdint.h"
#include <string>
if (yych == 'u') goto yy159;
yy115:
#line 68 "../src/parse/lex_conf.re"
- { if (!opts.output(lex_conf_string())) exit(1); return; }
+ { opts.set_output_file(lex_conf_string()); return; }
#line 656 "src/parse/lex_conf.cc"
yy116:
yyaccept = 8;
if (opts->target == opt_t::SKELETON) {
if (output.skeletons.insert (name).second)
{
- emit_data(*skeleton, o.file_name);
+ emit_data(*skeleton);
emit_start(*skeleton, o, max_fill, need_backup, need_backupctx,
need_accept, basetag, tagnames);
uint32_t i = 2;
#include "src/codegen/indent.h"
#include "src/codegen/output.h"
#include "src/codegen/print.h"
+#include "src/conf/msg.h"
#include "src/conf/opt.h"
#include "src/conf/warn.h"
#include "src/util/strrreplace.h"
}
}
-OutputFile::OutputFile(const std::string &fn)
- : file_name (fn)
- , file (NULL)
- , blocks ()
+OutputFile::OutputFile()
+ : blocks ()
, label_counter ()
, warn_condition_order (!opts->tFlag) // see note [condition order]
, default_tags (true)
new_block ();
}
-bool OutputFile::open ()
-{
- if (file_name.empty())
- {
- file_name = "<stdout>";
- file = stdout;
- }
- else
- {
- file = fopen (file_name.c_str(), "wb");
- }
- return file != NULL;
-}
-
OutputFile::~OutputFile ()
{
- if (file != NULL && file != stdout)
- {
- fclose (file);
- }
- for (unsigned int i = 0; i < blocks.size (); ++i)
- {
+ for (unsigned int i = 0; i < blocks.size(); ++i) {
delete blocks[i];
}
}
}
}
-void OutputFile::emit(
- const uniq_vector_t<std::string> &global_types,
+bool OutputFile::emit(const uniq_vector_t<std::string> &global_types,
const std::set<std::string> &global_tags,
size_t max_fill)
{
- if (file != NULL)
- {
- unsigned int line_count = 1;
- for (unsigned int j = 0; j < blocks.size (); ++j)
- {
- OutputBlock & b = * blocks[j];
- for (unsigned int i = 0; i < b.fragments.size (); ++i)
- {
- OutputFragment & f = * b.fragments[i];
- switch (f.type)
- {
- case OutputFragment::CODE:
- break;
- case OutputFragment::LINE_INFO:
- output_line_info (f.stream, line_count + 1, file_name);
- break;
- case OutputFragment::STATE_GOTO:
- output_state_goto (f.stream, f.indent, 0);
- break;
- case OutputFragment::TAGS:
- if (f.tags) {
- output_tags(f.stream, *f.tags, global_tags);
- } else if (default_tags) {
- output_tags_default(f.stream, f.indent, b.tags);
- }
- break;
- case OutputFragment::TYPES:
- output_types (f.stream, f.indent, global_types);
- break;
- case OutputFragment::WARN_CONDITION_ORDER:
- if (warn_condition_order) // see note [condition order]
- {
- warn.condition_order (b.line);
- }
- break;
- case OutputFragment::YYACCEPT_INIT:
- output_yyaccept_init (f.stream, f.indent, b.used_yyaccept);
- break;
- case OutputFragment::YYMAXFILL:
- output_yymaxfill (f.stream, max_fill);
- break;
- }
- std::string content = f.stream.str ();
- fwrite (content.c_str (), 1, content.size (), file);
- line_count += f.count_lines ();
+ FILE *file = NULL;
+ std::string filename = opts->output_file;
+ if (filename.empty()) {
+ filename = "<stdout>";
+ file = stdout;
+ } else {
+ file = fopen(filename.c_str(), "wb");
+ if (!file) {
+ error("cannot open output file: %s", filename.c_str());
+ return false;
+ }
+ }
+
+ unsigned int line_count = 1;
+ for (unsigned int j = 0; j < blocks.size(); ++j) {
+ OutputBlock & b = * blocks[j];
+ for (unsigned int i = 0; i < b.fragments.size(); ++i) {
+ OutputFragment & f = * b.fragments[i];
+ switch (f.type) {
+ case OutputFragment::CODE: break;
+ case OutputFragment::LINE_INFO:
+ output_line_info(f.stream, line_count + 1, filename);
+ break;
+ case OutputFragment::STATE_GOTO:
+ output_state_goto(f.stream, f.indent, 0);
+ break;
+ case OutputFragment::TAGS:
+ if (f.tags) {
+ output_tags(f.stream, *f.tags, global_tags);
+ } else if (default_tags) {
+ output_tags_default(f.stream, f.indent, b.tags);
+ }
+ break;
+ case OutputFragment::TYPES:
+ output_types(f.stream, f.indent, global_types);
+ break;
+ case OutputFragment::WARN_CONDITION_ORDER:
+ if (warn_condition_order) {// see note [condition order]
+ warn.condition_order (b.line);
+ }
+ break;
+ case OutputFragment::YYACCEPT_INIT:
+ output_yyaccept_init(f.stream, f.indent, b.used_yyaccept);
+ break;
+ case OutputFragment::YYMAXFILL:
+ output_yymaxfill(f.stream, max_fill);
+ break;
}
+ std::string content = f.stream.str();
+ fwrite(content.c_str(), 1, content.size(), file);
+ line_count += f.count_lines();
}
}
+
+ fclose(file);
+ return true;
}
-HeaderFile::HeaderFile(const std::string &fn)
- : stream ()
- // header is always generated, but not always dumped to file
- // NULL filename crashes 'operator <<' on some platforms
- // TODO: generate header only if necessary
- , file_name (fn)
- , file (NULL)
+bool HeaderFile::emit(const uniq_vector_t<std::string> &types)
{
- if (file_name.empty()) {
- file_name = "<stdout>.h";
+ if (!opts->tFlag) {
+ return true;
}
-}
-bool HeaderFile::open ()
-{
- file = fopen (file_name.c_str(), "wb");
- return file != NULL;
-}
+ FILE *file = NULL;
+ std::string filename = opts->header_file;
+ if (filename.empty()) {
+ filename = "<stdout>.h";
+ file = stdout;
+ } else {
+ file = fopen(filename.c_str(), "wb");
+ if (!file) {
+ error("cannot open header file: %s", filename.c_str());
+ return false;
+ }
+ }
-void HeaderFile::emit(const uniq_vector_t<std::string> &types)
-{
- output_version_time (stream);
- output_line_info (stream, 3, file_name);
+ output_version_time(stream);
+ output_line_info(stream, 3, filename);
stream << "\n";
output_types(stream, 0, types);
-}
-HeaderFile::~HeaderFile ()
-{
- if (file != NULL)
- {
- std::string content = stream.str ();
- fwrite (content.c_str (), 1, content.size (), file);
- fclose (file);
- }
+ std::string content = stream.str();
+ fwrite(content.c_str(), 1, content.size(), file);
+
+ fclose(file);
+ return true;
}
-Output::Output(const std::string &source_name, const std::string &header_name)
- : source(source_name)
- , header(header_name)
+Output::Output()
+ : source()
+ , header()
, skeletons()
, max_fill(1)
{}
-Output::~Output ()
+bool Output::emit()
{
- if (!warn.error ())
- {
- uniq_vector_t<std::string> types;
- std::set<std::string> tags;
- source.global_lists(types, tags);
-
- source.emit(types, tags, max_fill);
- header.emit(types);
+ if (warn.error()) {
+ return false;
}
+
+ uniq_vector_t<std::string> types;
+ std::set<std::string> tags;
+ source.global_lists(types, tags);
+
+ return source.emit(types, tags, max_fill)
+ && header.emit(types);
}
void output_tags(std::ostream &o, const ConfTags &conf,
~OutputBlock ();
};
-struct OutputFile
+class OutputFile
{
-public:
- std::string file_name;
-
-private:
- FILE * file;
std::vector<OutputBlock *> blocks;
public:
bool warn_condition_order;
bool default_tags;
- OutputFile(const std::string &fn);
- ~OutputFile ();
+ OutputFile();
+ ~OutputFile();
std::ostream & stream ();
OutputBlock &block();
void global_lists(uniq_vector_t<std::string> &types,
std::set<std::string> &tags) const;
- void emit(const uniq_vector_t<std::string> &global_types,
+ bool emit(const uniq_vector_t<std::string> &global_types,
const std::set<std::string> &global_tags, size_t max_fill);
FORBID_COPY (OutputFile);
};
-struct HeaderFile
+class HeaderFile
{
- HeaderFile(const std::string &fn);
- ~HeaderFile ();
- bool open ();
- void emit(const uniq_vector_t<std::string> &types);
-
-private:
std::ostringstream stream;
- std::string file_name;
- FILE * file;
+public:
+ HeaderFile(): stream() {}
+ bool emit(const uniq_vector_t<std::string> &types);
FORBID_COPY (HeaderFile);
};
std::set<std::string> skeletons;
size_t max_fill;
- Output(const std::string &source_name, const std::string &header_name);
- ~Output ();
+ Output();
+ bool emit();
};
void output_tags(std::ostream &o, const ConfTags &conf,
}
}
-bool Opt::output (const std::string &s)
-{
- if (!output_file.empty())
- {
- error ("multiple output files: %s, %s", output_file.c_str(), s.c_str());
- return false;
- }
- else
- {
- output_file = s;
- return true;
- }
-}
-
void Opt::reset_encoding (const Enc & enc)
{
useropt->encoding = enc;
#define RE2C_OPTS \
/* target */ \
OPT1 (opt_t::target_t, target, CODE) \
+ /* output file */ \
+ OPT (std::string, output_file, "") \
/* fingerprint */ \
OPT (bool, bNoGenerationDate, false) \
OPT (bool, version, true) \
/* conditions */ \
OPT (bool, cFlag, false) \
OPT (bool, tFlag, false) \
- OPT (std::string, header_file, "") \
+ OPT (std::string, header_file, "") \
OPT (std::string, yycondtype, "YYCONDTYPE") \
OPT (std::string, cond_get, "YYGETCONDITION") \
OPT (bool, cond_get_naked, false) \
static const opt_t baseopt;
const char *source_file;
- std::string output_file;
private:
useropt_t useropt;
public:
Opt ()
: source_file (NULL)
- , output_file ()
, useropt ()
, realopt (useropt)
{}
}
bool source (const char *s);
- bool output (const std::string &s);
// Inplace configurations are applied immediately when parsed.
// This is very bad: first, re2c behaviour is changed in the middle
error ("bad argument to option -o, --output: %s", *argv);
return EXIT_FAIL;
}
- filename end { if (!opts.output (*argv)) return EXIT_FAIL; goto opt; }
+ filename end { opts.set_output_file(*argv); goto opt; }
*/
opt_header:
sizeof_key = skel.sizeof_key;
const size_t norule = skel.rule2key(Rule::NONE);
const std::string &name = skel.name;
+ std::string filename = opts->output_file;
+ if (filename.empty()) {
+ filename = "<stdout>";
+ }
o.ws("\n#define YYCTYPE ");
exact_uint (o, sizeof_cunit);
o.ws("\n").wind(1).ws("unsigned int i = 0;");
o.ws("\n");
o.ws("\n").wind(1).ws("input = (YYCTYPE *) read_file");
- o.ws("\n").wind(2).ws("(\"").wstring(o.file_name).ws(".").wstring(name).ws(".input\"");
+ o.ws("\n").wind(2).ws("(\"").wstring(filename).ws(".").wstring(name).ws(".input\"");
o.ws("\n").wind(2).ws(", sizeof (YYCTYPE)");
o.ws("\n").wind(2).ws(", padding");
o.ws("\n").wind(2).ws(", &input_len");
o.ws("\n");
}
o.ws("\n").wind(1).ws("keys = (YYKEYTYPE *) read_file");
- o.ws("\n").wind(2).ws("(\"").wstring(o.file_name).ws(".").wstring(name).ws(".keys\"");
+ o.ws("\n").wind(2).ws("(\"").wstring(filename).ws(".").wstring(name).ws(".keys\"");
o.ws("\n").wind(2).ws(", 3 * sizeof (YYKEYTYPE)");
o.ws("\n").wind(2).ws(", 0");
o.ws("\n").wind(2).ws(", &keys_count");
}
}
-void emit_data(const Skeleton &skel, const std::string &fname)
+void emit_data(const Skeleton &skel)
{
+ std::string fname = opts->output_file;
+ if (fname.empty()) {
+ fname = "<stdout>";
+ }
+
const std::string input_name = fname + "." + skel.name + ".input";
FILE *input = fopen(input_name.c_str(), "wb");
if (!input) {
void warn_undefined_control_flow(const Skeleton &skel);
void fprint_default_path(FILE *f, const Skeleton &skel, const path_t &p);
void warn_unreachable_nullable_rules(const Skeleton &skel);
-void emit_data(const Skeleton &skel, const std::string &fname);
+void emit_data(const Skeleton &skel);
void emit_prolog(OutputFile & o);
void emit_start(const Skeleton &skel, OutputFile &o, size_t maxfill,
bool backup, bool backupctx, bool accept, bool basetag,
}
// set up the output streams
- re2c::Output output (opts.output_file, opts->header_file);
- if (!output.source.open ())
- {
- error ("cannot open output file: %s", opts.output_file.c_str());
- return 1;
- }
- if (opts->tFlag && !output.header.open ())
- {
- error ("cannot open header file: %s", opts->header_file.c_str());
- return 1;
- }
+ re2c::Output output;
Scanner scanner (input, output.source);
parse (scanner, output);
+ if (!output.emit()) {
+ return 1;
+ }
return warn.error () ? 1 : 0;
}
"flags:" ("x" | "utf-16") { lex_conf_enc(Enc::UTF16); return; }
"flags:" ("8" | "utf-8") { lex_conf_enc(Enc::UTF8); return; }
- "flags:" ("o" | "output") { if (!opts.output(lex_conf_string())) exit(1); return; }
+ "flags:" ("o" | "output") { opts.set_output_file(lex_conf_string()); return; }
"flags:" ("t" | "type-header") { opts.set_header_file(lex_conf_string()); return; }
"flags:encoding-policy" { lex_conf_encoding_policy(); return; }
/* Generated by re2c */
-#line 1 "flags.re"
+#line 1 "config/flags.re"
int main()
{
re2c:flags:8 = 1;
re2c:flags:utf-8 = 0;
+ re2c:flags:o = "flags_x.c";
+ re2c:flags:output = "flags.c";
+ re2c:flags:t = "flags_x.h";
+ re2c:flags:type-header = "flags.h";
+
re2c:flags:encoding-policy = ignore;
re2c:flags:encoding-policy = substitute;
re2c:flags:encoding-policy = fail;
--- /dev/null
+/* Generated by re2c */
+#line 1 "config/flags_output.re"
+#line 5 "config/flags_output.re"
+
--- /dev/null
+/*!re2c
+ // 2nd configuration overrides 1st
+ re2c:flags:o = "flags_output_x.c";
+ re2c:flags:output = "flags_output.c";
+*/
--- /dev/null
+/* Generated by re2c */
+#line 1 "config/flags_type-header.re"
+#line 6 "config/flags_type-header.re"
+
+/* Generated by re2c */
+#line 3 "flags_type-header.h"
+
+enum YYCONDTYPE {
+};
--- /dev/null
+/*!re2c
+ // 2nd configuration overrides 1st
+ re2c:flags:t = "flags_type-header_x.h";
+ re2c:flags:type-header = "flags_type-header.h";
+ re2c:flags:c = 1;
+*/