We don't need to create allocate the outpute file stream and open the file at
[external/ragel.git] / ragel / inputdata.cpp
1 /*
2  *  Copyright 2008 Adrian Thurston <thurston@complang.org>
3  */
4
5 /*  This file is part of Ragel.
6  *
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.
11  * 
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.
16  * 
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 
20  */
21
22 #include "ragel.h"
23 #include "common.h"
24 #include "inputdata.h"
25 #include "parsedata.h"
26 #include "rlparse.h"
27 #include <iostream>
28
29 using std::cout;
30 using std::cerr;
31 using std::endl;
32 using std::ios;
33
34 void InputData::generateSpecificReduced()
35 {
36         if ( parserDict.length() > 0 ) {
37                 /* There is either a machine spec or machine name given. */
38                 ParseData *parseData = 0;
39                 GraphDictEl *graphDictEl = 0;
40
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 )
49                                 {
50                                         /* Have a machine spec and/or machine name that matches
51                                          * the -M/-S options. */
52                                         parseData = checkPd;
53                                         graphDictEl = checkGdEl;
54                                         break;
55                                 }
56                         }
57                 }
58
59                 if ( parseData == 0 )
60                         error() << "could not locate machine specified with -S and/or -M" << endl;
61                 else {
62                         /* Section/Machine to emit was found. Prepare and emit it. */
63                         parseData->prepareMachineGen( graphDictEl );
64                         if ( gblErrorCount == 0 )
65                                 parseData->generateReduced( *this );
66                 }
67         }
68
69         writeOutput();
70 }
71
72
73 void InputData::openOutput()
74 {
75         if ( generateDot )
76                 outStream = dotOpenOutput( inputFileName );
77         else if ( hostLang->lang == HostLang::C )
78                 outStream = cdOpenOutput( inputFileName );
79         else if ( hostLang->lang == HostLang::D )
80                 outStream = cdOpenOutput( inputFileName );
81         else if ( hostLang->lang == HostLang::Java )
82                 outStream = javaOpenOutput( inputFileName );
83         else if ( hostLang->lang == HostLang::Ruby )
84                 outStream = rubyOpenOutput( inputFileName );
85         else if ( hostLang->lang == HostLang::CSharp )
86                 outStream = csharpOpenOutput( inputFileName );
87         else {
88                 assert( false );
89         }
90 }
91
92 void InputData::openOutput2()
93 {
94         if ( outFilter != 0 ) {
95                 outFilter->open( outputFileName, ios::out|ios::trunc );
96                 if ( !outFilter->is_open() ) {
97                         error() << "error opening " << outputFileName << " for writing" << endl;
98                         exit(1);
99                 }
100         }
101 }
102
103 void InputData::prepareMachineGen()
104 {
105         /* No machine spec or machine name given. Generate everything. */
106         for ( ParserDict::Iter parser = parserDict; parser.lte(); parser++ ) {
107                 ParseData *pd = parser->value->pd;
108                 if ( pd->instanceList.length() > 0 )
109                         pd->prepareMachineGen( 0 );
110         }
111 }
112
113 void InputData::generateReduced()
114 {
115         for ( ParserDict::Iter parser = parserDict; parser.lte(); parser++ ) {
116                 ParseData *pd = parser->value->pd;
117                 if ( pd->instanceList.length() > 0 )
118                         pd->generateReduced( *this );
119         }
120 }
121
122 void InputData::writeOutput()
123 {
124         for ( InputItemList::Iter ii = inputItems; ii.lte(); ii++ ) {
125                 if ( ii->type == InputItem::Write ) {
126                         CodeGenMapEl *mapEl = codeGenMap.find( (char*)ii->name.c_str() );
127                         CodeGenData *cgd = mapEl->value;
128                         ::keyOps = &cgd->thisKeyOps;
129
130                         cgd->writeStatement( ii->loc, ii->writeArgs.length()-1, ii->writeArgs.data );
131                 }
132                 else /*if ( /!generateDot )*/ {
133                         *outStream << '\n';
134                         lineDirective( *outStream, inputFileName, ii->loc.line );
135                         *outStream << ii->data.str();
136                 }
137         }
138 }
139