Updated Victor's email address. The frontend parameter check must accept -R.
[ragel.git] / rlgen-java / main.cpp
blobe15ef06d7b246877bfd8faf5e94ef0160a0e611d
1 /*
2 * Copyright 2001-2005 Adrian Thurston <thurston@cs.queensu.ca>
3 */
5 /* This file is part of Ragel.
7 * Ragel is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * Ragel is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with Ragel; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 #include <stdlib.h>
23 #include <string.h>
24 #include <stdio.h>
25 #include <iostream>
26 #include <fstream>
27 #include <unistd.h>
29 #include "rlgen-java.h"
30 #include "xmlparse.h"
31 #include "pcheck.h"
32 #include "vector.h"
33 #include "version.h"
34 #include "common.h"
35 #include "javacodegen.h"
37 using std::istream;
38 using std::ifstream;
39 using std::ostream;
40 using std::ios;
41 using std::cin;
42 using std::cout;
43 using std::cerr;
44 using std::endl;
46 /* Io globals. */
47 istream *inStream = 0;
48 ostream *outStream = 0;
49 output_filter *outFilter = 0;
50 char *outputFileName = 0;
52 /* Graphviz dot file generation. */
53 bool graphvizDone = false;
55 int numSplitPartitions = 0;
56 bool printPrintables = false;
58 /* Print a summary of the options. */
59 void usage()
61 cout <<
62 "usage: " PROGNAME " [options] file\n"
63 "general:\n"
64 " -h, -H, -?, --help Print this usage and exit\n"
65 " -v, --version Print version information and exit\n"
66 " -o <file> Write output to <file>\n"
70 /* Print version information. */
71 void version()
73 cout << "Ragel Code Generator for Java" << endl <<
74 "Version " VERSION << ", " PUBDATE << endl <<
75 "Copyright (c) 2001-2007 by Adrian Thurston" << endl;
78 /* Total error count. */
79 int gblErrorCount = 0;
81 ostream &error()
83 gblErrorCount += 1;
84 cerr << PROGNAME ": ";
85 return cerr;
89 * Callbacks invoked by the XML data parser.
92 /* Invoked by the parser when the root element is opened. */
93 ostream *openOutput( char *inputFile )
95 if ( hostLangType != JavaCode )
96 error() << "this code generator is for Java only" << endl;
98 /* If the output format is code and no output file name is given, then
99 * make a default. */
100 if ( outputFileName == 0 ) {
101 char *ext = findFileExtension( inputFile );
102 if ( ext != 0 && strcmp( ext, ".rh" ) == 0 )
103 outputFileName = fileNameFromStem( inputFile, ".h" );
104 else
105 outputFileName = fileNameFromStem( inputFile, ".java" );
108 /* Make sure we are not writing to the same file as the input file. */
109 if ( outputFileName != 0 && strcmp( inputFile, outputFileName ) == 0 ) {
110 error() << "output file \"" << outputFileName <<
111 "\" is the same as the input file" << endl;
114 if ( outputFileName != 0 ) {
115 /* Create the filter on the output and open it. */
116 outFilter = new output_filter( outputFileName );
117 outFilter->open( outputFileName, ios::out|ios::trunc );
118 if ( !outFilter->is_open() ) {
119 error() << "error opening " << outputFileName << " for writing" << endl;
120 exit(1);
123 /* Open the output stream, attaching it to the filter. */
124 outStream = new ostream( outFilter );
126 else {
127 /* Writing out ot std out. */
128 outStream = &cout;
130 return outStream;
133 /* Invoked by the parser when a ragel definition is opened. */
134 CodeGenData *makeCodeGen( char *sourceFileName, char *fsmName,
135 ostream &out, bool wantComplete )
137 CodeGenData *codeGen = new JavaTabCodeGen(out);
139 codeGen->sourceFileName = sourceFileName;
140 codeGen->fsmName = fsmName;
141 codeGen->wantComplete = wantComplete;
143 return codeGen;
146 /* Main, process args and call yyparse to start scanning input. */
147 int main(int argc, char **argv)
149 ParamCheck pc("o:VpT:F:G:vHh?-:P:", argc, argv);
150 char *xmlInputFileName = 0;
152 while ( pc.check() ) {
153 switch ( pc.state ) {
154 case ParamCheck::match:
155 switch ( pc.parameter ) {
156 /* Output. */
157 case 'o':
158 if ( *pc.parameterArg == 0 )
159 error() << "a zero length output file name was given" << endl;
160 else if ( outputFileName != 0 )
161 error() << "more than one output file name was given" << endl;
162 else {
163 /* Ok, remember the output file name. */
164 outputFileName = pc.parameterArg;
166 break;
168 /* Version and help. */
169 case 'v':
170 version();
171 exit(0);
172 case 'H': case 'h': case '?':
173 usage();
174 exit(0);
175 case '-':
176 if ( strcasecmp(pc.parameterArg, "help") == 0 ) {
177 usage();
178 exit(0);
180 else if ( strcasecmp(pc.parameterArg, "version") == 0 ) {
181 version();
182 exit(0);
184 else {
185 error() << "--" << pc.parameterArg <<
186 " is an invalid argument" << endl;
187 break;
190 break;
192 case ParamCheck::invalid:
193 error() << "-" << pc.parameter << " is an invalid argument" << endl;
194 break;
196 case ParamCheck::noparam:
197 if ( *pc.curArg == 0 )
198 error() << "a zero length input file name was given" << endl;
199 else if ( xmlInputFileName != 0 )
200 error() << "more than one input file name was given" << endl;
201 else {
202 /* OK, Remember the filename. */
203 xmlInputFileName = pc.curArg;
205 break;
209 /* Bail on above errors. */
210 if ( gblErrorCount > 0 )
211 exit(1);
213 /* Open the input file for reading. */
214 if ( xmlInputFileName != 0 ) {
215 /* Open the input file for reading. */
216 ifstream *inFile = new ifstream( xmlInputFileName );
217 inStream = inFile;
218 if ( ! inFile->is_open() )
219 error() << "could not open " << xmlInputFileName << " for reading" << endl;
221 else {
222 xmlInputFileName = "<stdin>";
223 inStream = &cin;
226 /* Bail on above errors. */
227 if ( gblErrorCount > 0 )
228 exit(1);
230 bool wantComplete = true;
231 bool outputActive = true;
233 /* Parse the input! */
234 xml_parse( *inStream, xmlInputFileName, outputActive, wantComplete );
236 /* If writing to a file, delete the ostream, causing it to flush.
237 * Standard out is flushed automatically. */
238 if ( outputFileName != 0 ) {
239 delete outStream;
240 delete outFilter;
243 /* Finished, final check for errors.. */
244 if ( gblErrorCount > 0 ) {
245 /* If we opened an output file, remove it. */
246 if ( outputFileName != 0 )
247 unlink( outputFileName );
248 exit(1);
250 return 0;