A bit more cleanup.
[external/ragel.git] / ragel / main.cpp
index 1e11cef..120fae7 100644 (file)
@@ -1,5 +1,5 @@
 /*
- *  Copyright 2001-2007 Adrian Thurston <thurston@cs.queensu.ca>
+ *  Copyright 2001-2007 Adrian Thurston <thurston@complang.org>
  */
 
 /*  This file is part of Ragel.
@@ -55,6 +55,7 @@
 #include "version.h"
 #include "common.h"
 #include "xmlparse.h"
+#include "inputdata.h"
 
 using std::istream;
 using std::ostream;
@@ -124,8 +125,8 @@ void usage()
 "   -x                   Run the frontend only: emit XML intermediate format\n"
 "   -V                   Generate a dot file for Graphviz\n"
 "   -p                   Display printable characters on labels\n"
-"   -S <spec>            FSM specification to output (for rlgen-dot)\n"
-"   -M <machine>         Machine definition/instantiation to output (for rlgen-dot)\n"
+"   -S <spec>            FSM specification to output (for graphviz output)\n"
+"   -M <machine>         Machine definition/instantiation to output (for graphviz output)\n"
 "host language:\n"
 "   -C                   The host language is C, C++, Obj-C or Obj-C++ (default)\n"
 "   -D                   The host language is D\n"
@@ -154,7 +155,7 @@ void usage()
 void version()
 {
        cout << "Ragel State Machine Compiler version " VERSION << " " PUBDATE << endl <<
-                       "Copyright (c) 2001-2007 by Adrian Thurston" << endl;
+                       "Copyright (c) 2001-2008 by Adrian Thurston" << endl;
        exit(0);
 }
 
@@ -441,50 +442,91 @@ void processArgs( int argc, const char **argv, const char *&inputFileName )
        }
 }
 
-int frontend( const char *inputFileName, const char *intermed )
+void process( const char *inputFileName )
 {
+       bool wantComplete = true;
+       bool outputActive = true;
+
        /* Open the input file for reading. */
        assert( inputFileName != 0 );
        ifstream *inFile = new ifstream( inputFileName );
-       istream *inStream = inFile;
        if ( ! inFile->is_open() )
                error() << "could not open " << inputFileName << " for reading" << endp;
 
        /* Used for just a few things. */
        std::ostringstream hostData;
 
-       if ( machineSpec == 0 && machineName == 0 )
-               hostData << "<host line=\"1\" col=\"1\">";
+       /* Make the first input item. */
+       InputItem *firstInputItem = new InputItem;
+       firstInputItem->type = InputItem::HostData;
+       firstInputItem->loc.line = 1;
+       firstInputItem->loc.col = 1;
+       inputItems.append( firstInputItem );
 
-       Scanner scanner( inputFileName, *inStream, hostData, 0, 0, 0, false );
+       Scanner scanner( inputFileName, *inFile, 0, 0, 0, false );
        scanner.do_scan();
 
        /* Finished, final check for errors.. */
        if ( gblErrorCount > 0 )
-               return 1;
+               exit(1);
        
        /* Now send EOF to all parsers. */
        terminateAllParsers();
 
        /* Finished, final check for errors.. */
        if ( gblErrorCount > 0 )
-               return 1;
+               exit(1);
+
+       /* Bail on above error. */
+       if ( gblErrorCount > 0 )
+               exit(1);
+
+       /* Locate the backend program */
+       if ( generateDot ) {
+               wantComplete = false;
+               outputActive = false;
+       }
 
-       if ( machineSpec == 0 && machineName == 0 )
-               hostData << "</host>\n";
+       InputData inputData( inputFileName, outputActive, wantComplete );
+
+       /* Compiles machines. */
+       inputData.prepareMachineGen();
 
        if ( gblErrorCount > 0 )
-               return 1;
-       
-       ostream *outputFile = new ofstream( intermed );
+               exit(1);
+
+       inputData.openOutput();
+
+       /* Generates the reduced machine, which we use to write output. */
+       inputData.generateReduced();
 
-       /* Write the machines, then the surrounding code. */
-       writeMachines( *outputFile, hostData.str(), inputFileName );
+       if ( gblErrorCount > 0 )
+               exit(1);
+
+       inputData.openOutput2();
+       inputData.writeOutput();
+
+       /* Close the input and the intermediate file. */
+       delete inFile;
+
+       /* Bail on above error. */
+       if ( gblErrorCount > 0 )
+               exit(1);
 
-       /* Close the intermediate file. */
-       delete outputFile;
+       /* If writing to a file, delete the ostream, causing it to flush.
+        * Standard out is flushed automatically. */
+       if ( outputFileName != 0 ) {
+               delete outStream;
+               delete outFilter;
+       }
 
-       return gblErrorCount > 0;
+       /* Finished, final check for errors.. */
+       if ( gblErrorCount > 0 ) {
+               /* If we opened an output file, remove it. */
+               if ( outputFileName != 0 )
+                       unlink( outputFileName );
+               exit(1);
+       }
 }
 
 char *makeIntermedTemplate( const char *baseFileName )
@@ -548,58 +590,13 @@ const char *openIntermed( const char *inputFileName, const char *outputFileName
 }
 
 
-void cleanExit( const char *intermed, int status )
-{
-       unlink( intermed );
-       exit( status );
-}
-
-void backend( const char *intermed )
-{
-       const char *xmlInputFileName = intermed;
-
-       bool wantComplete = true;
-       bool outputActive = true;
-
-       /* Open the input file for reading. */
-       ifstream *inFile = new ifstream( xmlInputFileName );
-       inStream = inFile;
-       if ( ! inFile->is_open() )
-               error() << "could not open " << xmlInputFileName << " for reading" << endl;
-
-       /* Bail on above error. */
-       if ( gblErrorCount > 0 )
-               exit(1);
-
-       /* Locate the backend program */
-       if ( generateDot ) {
-               wantComplete = false;
-               outputActive = false;
-       }
-
-       xml_parse( *inStream, xmlInputFileName, outputActive, wantComplete );
-
-       /* If writing to a file, delete the ostream, causing it to flush.
-        * Standard out is flushed automatically. */
-       if ( outputFileName != 0 ) {
-               delete outStream;
-               delete outFilter;
-       }
-
-       /* Finished, final check for errors.. */
-       if ( gblErrorCount > 0 ) {
-               /* If we opened an output file, remove it. */
-               if ( outputFileName != 0 )
-                       unlink( outputFileName );
-               exit(1);
-       }
-}
 
 /* Main, process args and call yyparse to start scanning input. */
 int main( int argc, const char **argv )
 {
        const char *inputFileName = 0;
        processArgs( argc, argv, inputFileName );
+       
 
        /* If -M or -S are given and we're not generating a dot file then invoke
         * the frontend. These options are not useful with code generators. */
@@ -625,12 +622,10 @@ int main( int argc, const char **argv )
                                "\" is the same as the input file" << endp;
        }
 
-       const char *intermed = openIntermed( inputFileName, outputFileName );
-       frontend( inputFileName, intermed );
-       backend( intermed );
+       process( inputFileName );
 
        /* Clean up the intermediate. */
-       cleanExit( intermed, 0 );
+       exit( 0 );
 
        return 0;
 }