Use the phrase "leaving" instead of "pending out".
[ragel.git] / rlgen-dot / main.cpp
blobd5bd5f395480135166144bd28b378abf649e9c53
1 /*
2 * Copyright 2001-2007 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 "common.h"
30 #include "rlgen-dot.h"
31 #include "xmlparse.h"
32 #include "pcheck.h"
33 #include "vector.h"
34 #include "version.h"
35 #include "gvdotgen.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 displayPrintables = 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"
67 "output:\n"
68 " -p Display printable characters on labels\n"
72 /* Print version information. */
73 void version()
75 cout << "Ragel Code Generator for Graphviz" << endl <<
76 "Version " VERSION << ", " PUBDATE << endl <<
77 "Copyright (c) 2001-2007 by Adrian Thurston" << endl;
80 ostream &error()
82 gblErrorCount += 1;
83 cerr << PROGNAME ": ";
84 return cerr;
88 * Callbacks invoked by the XML data parser.
91 /* Invoked by the parser when the root element is opened. */
92 ostream *openOutput( char *inputFile )
94 /* Make sure we are not writing to the same file as the input file. */
95 if ( outputFileName != 0 && strcmp( inputFile, outputFileName ) == 0 ) {
96 error() << "output file \"" << outputFileName <<
97 "\" is the same as the input file" << endl;
100 if ( outputFileName != 0 ) {
101 /* Create the filter on the output and open it. */
102 outFilter = new output_filter( outputFileName );
103 outFilter->open( outputFileName, ios::out|ios::trunc );
104 if ( !outFilter->is_open() ) {
105 error() << "error opening " << outputFileName << " for writing" << endl;
106 exit(1);
109 /* Open the output stream, attaching it to the filter. */
110 outStream = new ostream( outFilter );
112 else {
113 /* Writing out ot std out. */
114 outStream = &cout;
116 return outStream;
119 /* Invoked by the parser when a ragel definition is opened. */
120 CodeGenData *makeCodeGen( char *sourceFileName, char *fsmName,
121 ostream &out, bool wantComplete )
123 CodeGenData *codeGen = new GraphvizDotGen(out);
125 codeGen->sourceFileName = sourceFileName;
126 codeGen->fsmName = fsmName;
127 codeGen->wantComplete = wantComplete;
129 return codeGen;
133 /* Main, process args and call yyparse to start scanning input. */
134 int main(int argc, char **argv)
136 ParamCheck pc("o:pvHh?-:", argc, argv);
137 char *xmlInputFileName = 0;
139 while ( pc.check() ) {
140 switch ( pc.state ) {
141 case ParamCheck::match:
142 switch ( pc.parameter ) {
143 /* Output. */
144 case 'o':
145 if ( *pc.parameterArg == 0 )
146 error() << "a zero length output file name was given" << endl;
147 else if ( outputFileName != 0 )
148 error() << "more than one output file name was given" << endl;
149 else {
150 /* Ok, remember the output file name. */
151 outputFileName = pc.parameterArg;
153 break;
155 case 'p':
156 displayPrintables = true;
157 break;
159 /* Version and help. */
160 case 'v':
161 version();
162 exit(0);
163 case 'H': case 'h': case '?':
164 usage();
165 exit(0);
166 case '-':
167 if ( strcasecmp(pc.parameterArg, "help") == 0 ) {
168 usage();
169 exit(0);
171 else if ( strcasecmp(pc.parameterArg, "version") == 0 ) {
172 version();
173 exit(0);
175 else {
176 error() << "--" << pc.parameterArg <<
177 " is an invalid argument" << endl;
178 break;
181 break;
183 case ParamCheck::invalid:
184 error() << "-" << pc.parameter << " is an invalid argument" << endl;
185 break;
187 case ParamCheck::noparam:
188 if ( *pc.curArg == 0 )
189 error() << "a zero length input file name was given" << endl;
190 else if ( xmlInputFileName != 0 )
191 error() << "more than one input file name was given" << endl;
192 else {
193 /* OK, Remember the filename. */
194 xmlInputFileName = pc.curArg;
196 break;
200 /* Bail on above errors. */
201 if ( gblErrorCount > 0 )
202 exit(1);
204 /* Open the input file for reading. */
205 if ( xmlInputFileName != 0 ) {
206 /* Open the input file for reading. */
207 ifstream *inFile = new ifstream( xmlInputFileName );
208 inStream = inFile;
209 if ( ! inFile->is_open() )
210 error() << "could not open " << xmlInputFileName << " for reading" << endl;
212 else {
213 xmlInputFileName = strdup("<stdin>");
214 inStream = &cin;
217 /* Bail on above errors. */
218 if ( gblErrorCount > 0 )
219 exit(1);
221 bool wantComplete = false;
222 bool outputActive = false;
224 /* Parse the input! */
225 xml_parse( *inStream, xmlInputFileName, outputActive, wantComplete );
227 /* If writing to a file, delete the ostream, causing it to flush.
228 * Standard out is flushed automatically. */
229 if ( outputFileName != 0 ) {
230 delete outStream;
231 delete outFilter;
234 /* Finished, final check for errors.. */
235 if ( gblErrorCount > 0 ) {
236 /* If we opened an output file, remove it. */
237 if ( outputFileName != 0 )
238 unlink( outputFileName );
239 exit(1);
241 return 0;