From: Ulya Trofimovich Date: Mon, 2 Mar 2015 12:41:53 +0000 (+0000) Subject: Code cleanup in input/output: X-Git-Tag: 0.15~374 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=f7af77b370d322376d5fda78577c0f2138c72a55;p=re2c Code cleanup in input/output: - Use 'open' function instead of checking return status (one may forget to check return status, but if one forgets to open file, the error will be obvious) - Introduced separate file type for header. Header is much simpler than output, it doesn't need delayed code fragments and can be generated in destructor. --- diff --git a/re2c/bootstrap/parser.cc b/re2c/bootstrap/parser.cc index bd313207..5bfba40d 100644 --- a/re2c/bootstrap/parser.cc +++ b/re2c/bootstrap/parser.cc @@ -2233,9 +2233,8 @@ void parse(Scanner& i, Output & o) in = &i; - output_version_time (o.source); + output_version_time (o.source.fragment ()); output_line_info (o.source.fragment (), in->get_cline (), in->get_fname ().c_str ()); - output_version_time (o.header); Enc encodingOld = encoding; @@ -2387,12 +2386,6 @@ void parse(Scanner& i, Output & o) } genTypes (o, specMap); - if (o.header.status != OutputFile::NO_FILE) - { - o.header.insert_line_info (); - o.header << "\n"; - o.header.insert_types (); - } } else { diff --git a/re2c/code.cc b/re2c/code.cc index 8a6f70b9..b7d828b6 100644 --- a/re2c/code.cc +++ b/re2c/code.cc @@ -2115,17 +2115,16 @@ void output_yymaxfill (OutputFragment & o, uint max_fill) o << "#define YYMAXFILL " << max_fill << "\n"; } -void output_line_info (OutputFragment & o, uint line_number, const char * filename) +void output_line_info (std::ostream & o, uint line_number, const char * file_name) { if (!iFlag) { - o << "#line " << line_number << " \"" << filename << "\"\n"; + o << "#line " << line_number << " \"" << file_name << "\"\n"; } } -void output_types (OutputFragment & o, const std::vector & types) +void output_types (std::ostream & o, uint ind, const std::vector & types) { - uint ind = o.indent; o << indent (ind++) << "enum " << mapCodeName["YYCONDTYPE"] << " {\n"; for (unsigned int i = 0; i < types.size (); ++i) { @@ -2134,7 +2133,7 @@ void output_types (OutputFragment & o, const std::vector & types) o << indent (--ind) << "};\n"; } -void output_version_time (OutputFile & o) +void output_version_time (std::ostream & o) { o << "/* Generated by re2c " PACKAGE_VERSION; if (!bNoGenerationDate) diff --git a/re2c/input.cc b/re2c/input.cc index 2b16d3b0..0056394c 100644 --- a/re2c/input.cc +++ b/re2c/input.cc @@ -3,9 +3,11 @@ namespace re2c { Input::Input (const char * fn) - : status (OK) - , file (NULL) + : file (NULL) , file_name (fn) +{} + +bool Input::open () { if (file_name == "") { @@ -14,11 +16,8 @@ Input::Input (const char * fn) else { file = fopen (file_name.c_str (), "rb"); - if (file == NULL) - { - status = FAIL_OPEN; - } } + return file != NULL; } Input::~Input () diff --git a/re2c/input.h b/re2c/input.h index 646db943..8d1c9bbf 100644 --- a/re2c/input.h +++ b/re2c/input.h @@ -8,15 +8,12 @@ namespace re2c { struct Input { - enum status_t - { OK - , FAIL_OPEN - } status; FILE * file; std::string file_name; Input (const char * fn); ~Input (); + bool open (); }; } // namespace re2c diff --git a/re2c/main.cc b/re2c/main.cc index 10320df6..b4cee085 100644 --- a/re2c/main.cc +++ b/re2c/main.cc @@ -437,7 +437,7 @@ int main(int argc, char *argv[]) // set up the source stream re2c::Input input (sourceFileName); - if (input.status == Input::FAIL_OPEN) + if (!input.open ()) { cerr << "re2c: error: cannot open " << sourceFileName << "\n"; return 1; @@ -445,12 +445,12 @@ int main(int argc, char *argv[]) // set up the output streams re2c::Output output (outputFileName, headerFileName); - if (output.source.status == OutputFile::FAIL_OPEN) + if (!output.source.open ()) { cerr << "re2c: error: cannot open " << outputFileName << "\n"; return 1; } - if (output.header.status == OutputFile::FAIL_OPEN) + if (tFlag && !output.header.open ()) { cerr << "re2c: error: cannot open " << headerFileName << "\n"; return 1; @@ -459,8 +459,5 @@ int main(int argc, char *argv[]) Scanner scanner (input, output.source); parse (scanner, output); - // output generated code - output.emit (); - return 0; } diff --git a/re2c/output.cc b/re2c/output.cc index 3c81f2e7..e4e18357 100644 --- a/re2c/output.cc +++ b/re2c/output.cc @@ -38,28 +38,25 @@ OutputBlock::~OutputBlock () } OutputFile::OutputFile (const char * fn) - : status (NO_FILE) - , filename (fn) + : file_name (fn) , file (NULL) , blocks () , prolog_label (0) { - if (filename != NULL) + new_block (); +} + +bool OutputFile::open () +{ + if (strcmp (file_name, "") == 0) { - if (strcmp (filename, "") == 0) - { - file = stdout; - status = OK; - } - else - { - file = fopen (filename, "wb"); - status = file == NULL - ? FAIL_OPEN - : OK; - } + file = stdout; } - new_block (); + else + { + file = fopen (file_name, "wb"); + } + return file != NULL; } OutputFile::~OutputFile () @@ -198,13 +195,13 @@ void OutputFile::emit case OutputFragment::CODE: break; case OutputFragment::LINE_INFO: - output_line_info (f, line_count + 1, filename); + output_line_info (f, line_count + 1, file_name); break; case OutputFragment::STATE_GOTO: output_state_goto (f, prolog_label); break; case OutputFragment::TYPES: - output_types (f, types); + output_types (f, f.indent, types); break; case OutputFragment::YYACCEPT_INIT: output_yyaccept_init (f, b.used_yyaccept); @@ -224,10 +221,47 @@ void OutputFile::emit } } -void Output::emit () +HeaderFile::HeaderFile (const char * fn) + : stream () + , file_name (fn) + , file (NULL) +{} + +bool HeaderFile::open () +{ + file = fopen (file_name, "wb"); + return file != NULL; +} + +void HeaderFile::emit (const std::vector & types) +{ + output_version_time (stream); + output_line_info (stream, 3, file_name); + 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); + } +} + +Output::Output (const char * source_name, const char * header_name) + : source (source_name) + , header (header_name) + , types () + , max_fill (1) +{} + +Output::~Output () { source.emit (types, max_fill); - header.emit (types, max_fill); + header.emit (types); } } // namespace re2c diff --git a/re2c/output.h b/re2c/output.h index b4ad27a6..4379ee39 100644 --- a/re2c/output.h +++ b/re2c/output.h @@ -64,14 +64,9 @@ struct OutputBlock struct OutputFile { - enum status_t - { NO_FILE - , OK - , FAIL_OPEN - } status; - - OutputFile (const char * filename); + OutputFile (const char * fn); ~OutputFile (); + bool open (); OutputFragment & fragment (); void write (const char * s, std::streamsize n); void insert_line_info (); @@ -91,7 +86,7 @@ struct OutputFile friend OutputFile & operator << (OutputFile & o, const Setw & s); private: - const char * filename; + const char * file_name; FILE * file; std::vector blocks; uint prolog_label; @@ -99,21 +94,28 @@ private: void insert_code (); }; +struct HeaderFile +{ + HeaderFile (const char * fn); + ~HeaderFile (); + bool open (); + void emit (const std::vector & types); + +private: + std::ostringstream stream; + const char * file_name; + FILE * file; +}; + struct Output { OutputFile source; - OutputFile header; + HeaderFile header; std::vector types; uint max_fill; - Output (const char * source_name, const char * header_name) - : source (source_name) - , header (header_name) - , types () - , max_fill (1) - {} - - void emit (); + Output (const char * source_name, const char * header_name); + ~Output (); }; } // namespace re2c diff --git a/re2c/parser.y b/re2c/parser.y index 820858e9..5766befa 100644 --- a/re2c/parser.y +++ b/re2c/parser.y @@ -513,9 +513,8 @@ void parse(Scanner& i, Output & o) in = &i; - output_version_time (o.source); + output_version_time (o.source.fragment ()); output_line_info (o.source.fragment (), in->get_cline (), in->get_fname ().c_str ()); - output_version_time (o.header); Enc encodingOld = encoding; @@ -667,12 +666,6 @@ void parse(Scanner& i, Output & o) } genTypes (o, specMap); - if (o.header.status != OutputFile::NO_FILE) - { - o.header.insert_line_info (); - o.header << "\n"; - o.header.insert_types (); - } } else { diff --git a/re2c/re.h b/re2c/re.h index d758af1d..3a61330f 100644 --- a/re2c/re.h +++ b/re2c/re.h @@ -397,12 +397,12 @@ extern void genCondGoto(OutputFile &, uint, const RegExpMap&); extern void genTypes(Output &, const RegExpMap&); extern void output_state_goto (OutputFragment &, uint); -extern void output_types (OutputFragment &, const std::vector &); -extern void output_version_time (OutputFile &); +extern void output_types (std::ostream &, uint, const std::vector &); +extern void output_version_time (std::ostream &); extern void output_yyaccept_init (OutputFragment &, bool); extern void output_yyaccept_selector (OutputFragment &, bool); extern void output_yymaxfill (OutputFragment &, uint); -extern void output_line_info (OutputFragment &, uint, const char *); +extern void output_line_info (std::ostream &, uint, const char *); extern RegExp *mkDiff(RegExp*, RegExp*); extern RegExp *mkAlt(RegExp*, RegExp*);