2 * Copyright 2001-2007 Adrian Thurston <thurston@cs.queensu.ca>
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
30 #include "rlgen-dot.h"
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. */
62 "usage: " PROGNAME
" [options] file\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"
68 " -p Display printable characters on labels\n"
72 /* Print version information. */
75 cout
<< "Ragel Code Generator for Graphviz" << endl
<<
76 "Version " VERSION
<< ", " PUBDATE
<< endl
<<
77 "Copyright (c) 2001-2007 by Adrian Thurston" << endl
;
83 cerr
<< PROGNAME
": ";
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
;
109 /* Open the output stream, attaching it to the filter. */
110 outStream
= new ostream( outFilter
);
113 /* Writing out ot std out. */
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
;
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
) {
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
;
150 /* Ok, remember the output file name. */
151 outputFileName
= pc
.parameterArg
;
156 displayPrintables
= true;
159 /* Version and help. */
163 case 'H': case 'h': case '?':
167 if ( strcasecmp(pc
.parameterArg
, "help") == 0 ) {
171 else if ( strcasecmp(pc
.parameterArg
, "version") == 0 ) {
176 error() << "--" << pc
.parameterArg
<<
177 " is an invalid argument" << endl
;
183 case ParamCheck::invalid
:
184 error() << "-" << pc
.parameter
<< " is an invalid argument" << endl
;
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
;
193 /* OK, Remember the filename. */
194 xmlInputFileName
= pc
.curArg
;
200 /* Bail on above errors. */
201 if ( gblErrorCount
> 0 )
204 /* Open the input file for reading. */
205 if ( xmlInputFileName
!= 0 ) {
206 /* Open the input file for reading. */
207 ifstream
*inFile
= new ifstream( xmlInputFileName
);
209 if ( ! inFile
->is_open() )
210 error() << "could not open " << xmlInputFileName
<< " for reading" << endl
;
213 xmlInputFileName
= strdup("<stdin>");
217 /* Bail on above errors. */
218 if ( gblErrorCount
> 0 )
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 ) {
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
);