2 * Copyright 2008 Adrian Thurston <thurston@complang.org>
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
24 #include "inputdata.h"
25 #include "parsedata.h"
34 void InputData::generateSpecificReduced()
36 if ( parserDict.length() > 0 ) {
37 /* There is either a machine spec or machine name given. */
38 ParseData *parseData = 0;
39 GraphDictEl *graphDictEl = 0;
41 /* Traverse the sections, break out when we find a section/machine
42 * that matches the one specified. */
43 for ( ParserDict::Iter parser = parserDict; parser.lte(); parser++ ) {
44 ParseData *checkPd = parser->value->pd;
45 if ( machineSpec == 0 || strcmp( checkPd->sectionName, machineSpec ) == 0 ) {
46 GraphDictEl *checkGdEl = 0;
47 if ( machineName == 0 || (checkGdEl =
48 checkPd->graphDict.find( machineName )) != 0 )
50 /* Have a machine spec and/or machine name that matches
51 * the -M/-S options. */
53 graphDictEl = checkGdEl;
60 error() << "could not locate machine specified with -S and/or -M" << endl;
62 /* Section/Machine to emit was found. Prepare and emit it. */
63 parseData->prepareMachineGen( graphDictEl );
64 if ( gblErrorCount == 0 )
65 parseData->generateReduced( *this );
72 /* Invoked by the parser when the root element is opened. */
73 void InputData::dotDefaultFileName( const char *inputFile )
78 /* Invoked by the parser when the root element is opened. */
79 void InputData::cdDefaultFileName( const char *inputFile )
81 /* If the output format is code and no output file name is given, then
83 if ( outputFileName == 0 ) {
84 const char *ext = findFileExtension( inputFile );
85 if ( ext != 0 && strcmp( ext, ".rh" ) == 0 )
86 outputFileName = fileNameFromStem( inputFile, ".h" );
88 const char *defExtension = 0;
89 switch ( hostLang->lang ) {
90 case HostLang::C: defExtension = ".c"; break;
91 case HostLang::D: defExtension = ".d"; break;
94 outputFileName = fileNameFromStem( inputFile, defExtension );
99 /* Invoked by the parser when the root element is opened. */
100 void InputData::javaDefaultFileName( const char *inputFile )
102 /* If the output format is code and no output file name is given, then
104 if ( outputFileName == 0 )
105 outputFileName = fileNameFromStem( inputFile, ".java" );
108 /* Invoked by the parser when the root element is opened. */
109 void InputData::rubyDefaultFileName( const char *inputFile )
111 /* If the output format is code and no output file name is given, then
113 if ( outputFileName == 0 )
114 outputFileName = fileNameFromStem( inputFile, ".rb" );
117 /* Invoked by the parser when the root element is opened. */
118 void InputData::csharpDefaultFileName( const char *inputFile )
120 /* If the output format is code and no output file name is given, then
122 if ( outputFileName == 0 ) {
123 const char *ext = findFileExtension( inputFile );
124 if ( ext != 0 && strcmp( ext, ".rh" ) == 0 )
125 outputFileName = fileNameFromStem( inputFile, ".h" );
127 outputFileName = fileNameFromStem( inputFile, ".cs" );
131 void InputData::openOutput()
134 dotDefaultFileName( inputFileName );
135 else if ( hostLang->lang == HostLang::C )
136 cdDefaultFileName( inputFileName );
137 else if ( hostLang->lang == HostLang::D )
138 cdDefaultFileName( inputFileName );
139 else if ( hostLang->lang == HostLang::Java )
140 javaDefaultFileName( inputFileName );
141 else if ( hostLang->lang == HostLang::Ruby )
142 rubyDefaultFileName( inputFileName );
143 else if ( hostLang->lang == HostLang::CSharp )
144 csharpDefaultFileName( inputFileName );
146 /* Make sure we are not writing to the same file as the input file. */
147 if ( outputFileName != 0 && strcmp( inputFileName, outputFileName ) == 0 ) {
148 error() << "output file \"" << outputFileName <<
149 "\" is the same as the input file" << endl;
152 if ( outputFileName != 0 ) {
153 /* Create the filter on the output and open it. */
154 outFilter = new output_filter( outputFileName );
156 /* Open the output stream, attaching it to the filter. */
157 outStream = new ostream( outFilter );
160 /* Writing out ot std out. */
165 void InputData::openOutput2()
167 if ( outFilter != 0 ) {
168 outFilter->open( outputFileName, ios::out|ios::trunc );
169 if ( !outFilter->is_open() ) {
170 error() << "error opening " << outputFileName << " for writing" << endl;
176 void InputData::prepareMachineGen()
178 /* No machine spec or machine name given. Generate everything. */
179 for ( ParserDict::Iter parser = parserDict; parser.lte(); parser++ ) {
180 ParseData *pd = parser->value->pd;
181 if ( pd->instanceList.length() > 0 )
182 pd->prepareMachineGen( 0 );
186 void InputData::generateReduced()
188 for ( ParserDict::Iter parser = parserDict; parser.lte(); parser++ ) {
189 ParseData *pd = parser->value->pd;
190 if ( pd->instanceList.length() > 0 )
191 pd->generateReduced( *this );
195 void InputData::writeOutput()
197 for ( InputItemList::Iter ii = inputItems; ii.lte(); ii++ ) {
198 if ( ii->type == InputItem::Write ) {
199 CodeGenMapEl *mapEl = codeGenMap.find( (char*)ii->name.c_str() );
200 CodeGenData *cgd = mapEl->value;
201 ::keyOps = &cgd->thisKeyOps;
203 cgd->writeStatement( ii->loc, ii->writeArgs.length()-1, ii->writeArgs.data );
205 else /*if ( /!generateDot )*/ {
207 lineDirective( *outStream, inputFileName, ii->loc.line );
208 *outStream << ii->data.str();