Removed arg passing from frontend to backend functions.
[external/ragel.git] / rlgen-java / main.cpp
index 8cfcf33..06398c2 100644 (file)
@@ -1,5 +1,5 @@
 /*
- *  Copyright 2001-2005 Adrian Thurston <thurston@cs.queensu.ca>
+ *  Copyright 2001-2007 Adrian Thurston <thurston@cs.queensu.ca>
  */
 
 /*  This file is part of Ragel.
@@ -43,189 +43,66 @@ using std::cout;
 using std::cerr;
 using std::endl;
 
-/* Target language and output style. */
-OutputFormat outputFormat = OutCode;
-CodeStyleEnum codeStyle = GenTables;
-
 /* Io globals. */
-istream *inStream = 0;
-ostream *outStream = 0;
-output_filter *outFilter = 0;
-char *outputFileName = 0;
-
-/* Graphviz dot file generation. */
-bool graphvizDone = false;
+extern istream *inStream;
+extern ostream *outStream;
+extern output_filter *outFilter;
+extern const char *outputFileName;
 
-int numSplitPartitions = 0;
-bool printPrintables = false;
+extern int numSplitPartitions;
 
 /* Print a summary of the options. */
-void usage()
+void java_usage()
 {
        cout <<
-"usage: rlcodegen-java [options] file\n"
+"usage: " PROGNAME " [options] file\n"
 "general:\n"
 "   -h, -H, -?, --help    Print this usage and exit\n"
 "   -v, --version         Print version information and exit\n"
 "   -o <file>             Write output to <file>\n"
-"output:\n"
-"   -V                    Generate a Graphviz dotfile instead of code\n"
-"   -p                    Print printable characters in Graphviz output\n"
-"generated code style:\n"
-"   -T0                   Table driven FSM (default)\n"
-"   -T1                   Faster table driven FSM\n"
-"   -F0                   Flat table driven FSM\n"
-"   -F1                   Faster flat table-driven FSM\n"
-"   -G0                   Goto-driven FSM\n"
-"   -G1                   Faster goto-driven FSM\n"
-"   -G2                   Really fast goto-driven FSM\n"
-"   -P<N>                 N-Way Split really fast goto-driven FSM\n"
        ;       
 }
 
 /* Print version information. */
-void version()
+void java_version()
 {
-       cout << "Ragel Code Generator version " VERSION << " " PUBDATE << endl <<
-                       "Copyright (c) 2001-2006 by Adrian Thurston" << endl;
-}
-
-/* Scans a string looking for the file extension. If there is a file
- * extension then pointer returned points to inside the string
- * passed in. Otherwise returns null. */
-char *findFileExtension( char *stemFile )
-{
-       char *ppos = stemFile + strlen(stemFile) - 1;
-
-       /* Scan backwards from the end looking for the first dot.
-        * If we encounter a '/' before the first dot, then stop the scan. */
-       while ( 1 ) {
-               /* If we found a dot or got to the beginning of the string then
-                * we are done. */
-               if ( ppos == stemFile || *ppos == '.' )
-                       break;
-
-               /* If we hit a / then there is no extension. Done. */
-               if ( *ppos == '/' ) {
-                       ppos = stemFile;
-                       break;
-               }
-               ppos--;
-       } 
-
-       /* If we got to the front of the string then bail we 
-        * did not find an extension  */
-       if ( ppos == stemFile )
-               ppos = 0;
-
-       return ppos;
+       cout << "Ragel Code Generator for Java" << endl <<
+                       "Version " VERSION << ", " PUBDATE << endl <<
+                       "Copyright (c) 2001-2007 by Adrian Thurston" << endl;
 }
 
-/* Make a file name from a stem. Removes the old filename suffix and
- * replaces it with a new one. Returns a newed up string. */
-char *fileNameFromStem( char *stemFile, char *suffix )
-{
-       int len = strlen( stemFile );
-       assert( len > 0 );
-
-       /* Get the extension. */
-       char *ppos = findFileExtension( stemFile );
-
-       /* If an extension was found, then shorten what we think the len is. */
-       if ( ppos != 0 )
-               len = ppos - stemFile;
-
-       /* Make the return string from the stem and the suffix. */
-       char *retVal = new char[ len + strlen( suffix ) + 1 ];
-       strncpy( retVal, stemFile, len );
-       strcpy( retVal + len, suffix );
-
-       return retVal;
-}
-
-/* Total error count. */
-int gblErrorCount = 0;
-
-ostream &error()
+ostream &java_error()
 {
        gblErrorCount += 1;
        cerr << PROGNAME ": ";
        return cerr;
 }
 
-/* Counts newlines before sending sync. */
-int output_filter::sync( )
-{
-       line += 1;
-       return std::filebuf::sync();
-}
-
-/* Counts newlines before sending data out to file. */
-std::streamsize output_filter::xsputn( const char *s, std::streamsize n )
-{
-       for ( int i = 0; i < n; i++ ) {
-               if ( s[i] == '\n' )
-                       line += 1;
-       }
-       return std::filebuf::xsputn( s, n );
-}
-
-void escapeLineDirectivePath( std::ostream &out, char *path )
-{
-       for ( char *pc = path; *pc != 0; pc++ ) {
-               if ( *pc == '\\' )
-                       out << "\\\\";
-               else
-                       out << *pc;
-       }
-}
-
 /*
  * Callbacks invoked by the XML data parser.
  */
 
 /* Invoked by the parser when the root element is opened. */
-ostream *openOutput( char *inputFile, char *language )
+ostream *javaOpenOutput( char *inputFile )
 {
-       if ( strcmp( language, "C" ) == 0 ) {
-               hostLangType = CCode;
-               hostLang = &hostLangC;
-       }
-       else if ( strcmp( language, "D" ) == 0 ) {
-               hostLangType = DCode;
-               hostLang = &hostLangD;
-       }
-       else if ( strcmp( language, "Java" ) == 0 ) {
-               hostLangType = JavaCode;
-               hostLang = &hostLangJava;
-       }
-
-       /* Eventually more types will be supported. */
-       if ( hostLangType == JavaCode && codeStyle != GenTables ) {
-               error() << "java: only the table code style -T0 is "
-                                       "currently supported" << endl;
+       if ( hostLang->lang != HostLang::Java ) {
+               java_error() << "this code generator is for Java only" << endl;
+               exit(1);
        }
 
        /* If the output format is code and no output file name is given, then
         * make a default. */
-       if ( outputFormat == OutCode && outputFileName == 0 ) {
+       if ( outputFileName == 0 ) {
                char *ext = findFileExtension( inputFile );
                if ( ext != 0 && strcmp( ext, ".rh" ) == 0 )
                        outputFileName = fileNameFromStem( inputFile, ".h" );
-               else {
-                       char *defExtension = 0;
-                       switch ( hostLangType ) {
-                               case CCode: defExtension = ".c"; break;
-                               case DCode: defExtension = ".d"; break;
-                               case JavaCode: defExtension = ".java"; break;
-                       }
-                       outputFileName = fileNameFromStem( inputFile, defExtension );
-               }
+               else
+                       outputFileName = fileNameFromStem( inputFile, ".java" );
        }
 
        /* Make sure we are not writing to the same file as the input file. */
        if ( outputFileName != 0 && strcmp( inputFile, outputFileName  ) == 0 ) {
-               error() << "output file \"" << outputFileName  << 
+               java_error() << "output file \"" << outputFileName  << 
                                "\" is the same as the input file" << endl;
        }
 
@@ -234,7 +111,7 @@ ostream *openOutput( char *inputFile, char *language )
                outFilter = new output_filter( outputFileName );
                outFilter->open( outputFileName, ios::out|ios::trunc );
                if ( !outFilter->is_open() ) {
-                       error() << "error opening " << outputFileName << " for writing" << endl;
+                       java_error() << "error opening " << outputFileName << " for writing" << endl;
                        exit(1);
                }
 
@@ -249,7 +126,7 @@ ostream *openOutput( char *inputFile, char *language )
 }
 
 /* Invoked by the parser when a ragel definition is opened. */
-CodeGenData *makeCodeGen( char *sourceFileName, char *fsmName, 
+CodeGenData *javaMakeCodeGen( char *sourceFileName, char *fsmName, 
                ostream &out, bool wantComplete )
 {
        CodeGenData *codeGen = new JavaTabCodeGen(out);
@@ -262,141 +139,20 @@ CodeGenData *makeCodeGen( char *sourceFileName, char *fsmName,
 }
 
 /* Main, process args and call yyparse to start scanning input. */
-int main(int argc, char **argv)
+int java_main( const char *xmlInputFileName )
 {
-       ParamCheck pc("o:VpT:F:G:vHh?-:P:", argc, argv);
-       char *xmlInputFileName = 0;
-
-       while ( pc.check() ) {
-               switch ( pc.state ) {
-               case ParamCheck::match:
-                       switch ( pc.parameter ) {
-                       /* Output. */
-                       case 'o':
-                               if ( *pc.parameterArg == 0 )
-                                       error() << "a zero length output file name was given" << endl;
-                               else if ( outputFileName != 0 )
-                                       error() << "more than one output file name was given" << endl;
-                               else {
-                                       /* Ok, remember the output file name. */
-                                       outputFileName = pc.parameterArg;
-                               }
-                               break;
-
-                       /* Output formats. */
-                       case 'V':
-                               outputFormat = OutGraphvizDot;
-                               break;
-
-                       case 'p':
-                               printPrintables = true;
-                               break;
-
-                       /* Code style. */
-                       case 'T':
-                               if ( pc.parameterArg[0] == '0' )
-                                       codeStyle = GenTables;
-                               else if ( pc.parameterArg[0] == '1' )
-                                       codeStyle = GenFTables;
-                               else {
-                                       error() << "-T" << pc.parameterArg[0] << 
-                                                       " is an invalid argument" << endl;
-                                       exit(1);
-                               }
-                               break;
-                       case 'F':
-                               if ( pc.parameterArg[0] == '0' )
-                                       codeStyle = GenFlat;
-                               else if ( pc.parameterArg[0] == '1' )
-                                       codeStyle = GenFFlat;
-                               else {
-                                       error() << "-F" << pc.parameterArg[0] << 
-                                                       " is an invalid argument" << endl;
-                                       exit(1);
-                               }
-                               break;
-                       case 'G':
-                               if ( pc.parameterArg[0] == '0' )
-                                       codeStyle = GenGoto;
-                               else if ( pc.parameterArg[0] == '1' )
-                                       codeStyle = GenFGoto;
-                               else if ( pc.parameterArg[0] == '2' )
-                                       codeStyle = GenIpGoto;
-                               else {
-                                       error() << "-G" << pc.parameterArg[0] << 
-                                                       " is an invalid argument" << endl;
-                                       exit(1);
-                               }
-                               break;
-                       case 'P':
-                               codeStyle = GenSplit;
-                               numSplitPartitions = atoi( pc.parameterArg );
-                               break;
-
-                       /* Version and help. */
-                       case 'v':
-                               version();
-                               exit(0);
-                       case 'H': case 'h': case '?':
-                               usage();
-                               exit(0);
-                       case '-':
-                               if ( strcasecmp(pc.parameterArg, "help") == 0 ) {
-                                       usage();
-                                       exit(0);
-                               }
-                               else if ( strcasecmp(pc.parameterArg, "version") == 0 ) {
-                                       version();
-                                       exit(0);
-                               }
-                               else {
-                                       error() << "--" << pc.parameterArg << 
-                                                       " is an invalid argument" << endl;
-                                       break;
-                               }
-                       }
-                       break;
-
-               case ParamCheck::invalid:
-                       error() << "-" << pc.parameter << " is an invalid argument" << endl;
-                       break;
-
-               case ParamCheck::noparam:
-                       if ( *pc.curArg == 0 )
-                               error() << "a zero length input file name was given" << endl;
-                       else if ( xmlInputFileName != 0 )
-                               error() << "more than one input file name was given" << endl;
-                       else {
-                               /* OK, Remember the filename. */
-                               xmlInputFileName = pc.curArg;
-                       }
-                       break;
-               }
-       }
-
-       /* Bail on above errors. */
-       if ( gblErrorCount > 0 )
-               exit(1);
-
        /* Open the input file for reading. */
-       if ( xmlInputFileName != 0 ) {
-               /* 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;
-       }
-       else {
-               xmlInputFileName = "<stdin>";
-               inStream = &cin;
-       }
+       ifstream *inFile = new ifstream( xmlInputFileName );
+       inStream = inFile;
+       if ( ! inFile->is_open() )
+               java_error() << "could not open " << xmlInputFileName << " for reading" << endl;
 
        /* Bail on above errors. */
        if ( gblErrorCount > 0 )
                exit(1);
 
-       bool wantComplete = outputFormat != OutGraphvizDot;
-       bool outputActive = outputFormat == OutCode;
+       bool wantComplete = true;
+       bool outputActive = true;
 
        /* Parse the input! */
        xml_parse( *inStream, xmlInputFileName, outputActive, wantComplete );