]> granicus.if.org Git - re2c/commitdiff
Code cleanup in input/output:
authorUlya Trofimovich <skvadrik@gmail.com>
Mon, 2 Mar 2015 12:41:53 +0000 (12:41 +0000)
committerUlya Trofimovich <skvadrik@gmail.com>
Mon, 2 Mar 2015 12:41:53 +0000 (12:41 +0000)
- 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.

re2c/bootstrap/parser.cc
re2c/code.cc
re2c/input.cc
re2c/input.h
re2c/main.cc
re2c/output.cc
re2c/output.h
re2c/parser.y
re2c/re.h

index bd3132078886c382f9771cf1bdd5929cd9c080f9..5bfba40d97071d7c3229d1e6c88c9f514819cd39 100644 (file)
@@ -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
                {
index 8a6f70b96ab6ae622deec62e11d78c45daec0cfb..b7d828b6556cc325c1a04bafb195c93472dd190e 100644 (file)
@@ -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<std::string> & types)
+void output_types (std::ostream & o, uint ind, const std::vector<std::string> & 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<std::string> & 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)
index 2b16d3b04a057691ef7532a7a3eb64613fc62827..0056394cdb8681bc208e2e4389651f959884bcb3 100644 (file)
@@ -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 == "<stdin>")
        {
@@ -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 ()
index 646db943ce9eea09395097ab13711b092acfedde..8d1c9bbf641864a42c051a70e588b1ce9a7eb444 100644 (file)
@@ -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
index 10320df6c1872a4c71ed9f42f1d3878ce2451fe9..b4cee085102ce32495f2cf060c913e1201f8fd07 100644 (file)
@@ -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;
 }
index 3c81f2e7f7154cb9cc73147ae61c7d5cbbed9ba5..e4e18357d511545044e8102ee0a38ef201068ef3 100644 (file)
@@ -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, "<stdout>") == 0)
        {
-               if (strcmp (filename, "<stdout>") == 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<std::string> & 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
index b4ad27a6c9e0db2b53e828ac2facdc1dde0f67fb..4379ee3936179bdce3dff472d7a8839daf437cb4 100644 (file)
@@ -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<OutputBlock *> 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<std::string> & types);
+
+private:
+       std::ostringstream stream;
+       const char * file_name;
+       FILE * file;
+};
+
 struct Output
 {
        OutputFile source;
-       OutputFile header;
+       HeaderFile header;
        std::vector<std::string> 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
index 820858e9207797cf943e3fe7f8e92a631227b4c1..5766befa1658155e4595263fb4f4f78c4693ac19 100644 (file)
@@ -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
                {
index d758af1df1e1916a7f35cfa2c316ad1cd6514790..3a61330facbd2794638dbb5cb657684c629af9c0 100644 (file)
--- 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<std::string> &);
-extern void output_version_time (OutputFile &);
+extern void output_types (std::ostream &, uint, const std::vector<std::string> &);
+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*);