diff options
Diffstat (limited to 'src/buildparser.cpp')
-rw-r--r-- | src/buildparser.cpp | 432 |
1 files changed, 432 insertions, 0 deletions
diff --git a/src/buildparser.cpp b/src/buildparser.cpp new file mode 100644 index 0000000..cb285d4 --- /dev/null +++ b/src/buildparser.cpp | |||
@@ -0,0 +1,432 @@ | |||
1 | #include "buildparser.h" | ||
2 | #include "functionfactory.h" | ||
3 | #include "performfactory.h" | ||
4 | #include "targetfactory.h" | ||
5 | #include "action.h" | ||
6 | #include "build.h" | ||
7 | #include "rule.h" | ||
8 | |||
9 | BuildParser::BuildParser() : | ||
10 | fFunction( FunctionFactory::getInstance() ), | ||
11 | fPerform( PerformFactory::getInstance() ), | ||
12 | fTarget( TargetFactory::getInstance() ) | ||
13 | { | ||
14 | } | ||
15 | |||
16 | BuildParser::~BuildParser() | ||
17 | { | ||
18 | } | ||
19 | |||
20 | void yyparse( BuildParser &bld ); | ||
21 | extern int yydebug; | ||
22 | |||
23 | Build *BuildParser::load( const std::string &sFile ) | ||
24 | { | ||
25 | file = sFile; | ||
26 | scanBegin(); | ||
27 | //yydebug = 1; | ||
28 | yyparse( *this ); | ||
29 | scanEnd(); | ||
30 | |||
31 | return genBuild(); | ||
32 | } | ||
33 | |||
34 | void BuildParser::error( YYLTYPE *locp, const char *msg ) | ||
35 | { | ||
36 | fflush( stdout ); | ||
37 | throw BuildException("%s: %d.%d-%d.%d: %s", | ||
38 | file.c_str(), | ||
39 | locp->first_line, locp->first_column, | ||
40 | locp->last_line, locp->last_column, | ||
41 | msg ); | ||
42 | } | ||
43 | |||
44 | void BuildParser::error( const std::string &msg ) | ||
45 | { | ||
46 | fflush( stdout ); | ||
47 | throw BuildException("%s", msg.c_str() ); | ||
48 | } | ||
49 | |||
50 | // | ||
51 | // Target functions | ||
52 | // | ||
53 | bool BuildParser::isTarget( const char *sType ) | ||
54 | { | ||
55 | return fTarget.hasPlugin( sType ); | ||
56 | } | ||
57 | |||
58 | void BuildParser::newTarget() | ||
59 | { | ||
60 | lTargetTmp.push_back( TargetTmp(lTmp, TargetInfo()) ); | ||
61 | } | ||
62 | |||
63 | void BuildParser::setTargetRule( const char *sRule ) | ||
64 | { | ||
65 | lTargetTmp.back().second.sRule = sRule; | ||
66 | } | ||
67 | |||
68 | void BuildParser::setTargetPrefix( const char *sPrefix ) | ||
69 | { | ||
70 | lTargetTmp.back().second.sPrefix = sPrefix; | ||
71 | } | ||
72 | |||
73 | void BuildParser::setTargetType( const char *sType ) | ||
74 | { | ||
75 | lTargetTmp.back().second.sType = sType; | ||
76 | } | ||
77 | |||
78 | void BuildParser::addTargetInput() | ||
79 | { | ||
80 | lTargetTmp.back().second.lInput.insert( | ||
81 | lTargetTmp.back().second.lInput.end(), | ||
82 | lTmp.begin(), lTmp.end() | ||
83 | ); | ||
84 | } | ||
85 | |||
86 | void BuildParser::addTargetRequires() | ||
87 | { | ||
88 | lTargetTmp.back().second.lRequires.insert( | ||
89 | lTargetTmp.back().second.lRequires.end(), | ||
90 | lTmp.begin(), lTmp.end() | ||
91 | ); | ||
92 | } | ||
93 | |||
94 | void BuildParser::addTargetSet( const char *sVar, const char *sVal, int nHow ) | ||
95 | { | ||
96 | lTargetTmp.back().second.lVar.push_back( SetVar( sVar, sVal, nHow ) ); | ||
97 | } | ||
98 | |||
99 | // | ||
100 | // Function functions | ||
101 | // | ||
102 | bool BuildParser::isFunction( const char *sFunc ) | ||
103 | { | ||
104 | return fFunction.hasPlugin( sFunc ); | ||
105 | } | ||
106 | |||
107 | void BuildParser::newFunctionCall( const char *sName ) | ||
108 | { | ||
109 | pTmpFunc = fFunction.instantiate( sName ); | ||
110 | } | ||
111 | |||
112 | void BuildParser::addFunctionParam( const char *sParam ) | ||
113 | { | ||
114 | pTmpFunc->addParam( sParam ); | ||
115 | } | ||
116 | |||
117 | // | ||
118 | // List functions | ||
119 | // | ||
120 | void BuildParser::newList() | ||
121 | { | ||
122 | lTmp.clear(); | ||
123 | } | ||
124 | |||
125 | void BuildParser::addListString( const char *str ) | ||
126 | { | ||
127 | lTmp.push_back( BuildListItem(str, NULL) ); | ||
128 | } | ||
129 | |||
130 | void BuildParser::addListFunc() | ||
131 | { | ||
132 | lTmp.push_back( BuildListItem("", pTmpFunc ) ); | ||
133 | } | ||
134 | |||
135 | void BuildParser::filterList() | ||
136 | { | ||
137 | StringList lTmp2; | ||
138 | StringList lIn = buildToStringList( lTmp, StringList() ); | ||
139 | pTmpFunc->execute( lIn, lTmp2 ); | ||
140 | lTmp.clear(); | ||
141 | for( StringList::iterator i = lTmp2.begin(); i != lTmp2.end(); i++ ) | ||
142 | { | ||
143 | lTmp.push_back( BuildListItem( *i, NULL ) ); | ||
144 | } | ||
145 | } | ||
146 | |||
147 | StringList BuildParser::buildToStringList( const BuildList &lSrc, const StringList &lIn ) | ||
148 | { | ||
149 | StringList lOut; | ||
150 | |||
151 | for( BuildList::const_iterator i = lSrc.begin(); i != lSrc.end(); i++ ) | ||
152 | { | ||
153 | if( (*i).second ) | ||
154 | { | ||
155 | (*i).second->execute( lIn, lOut ); | ||
156 | } | ||
157 | else | ||
158 | { | ||
159 | lOut.push_back( (*i).first ); | ||
160 | } | ||
161 | } | ||
162 | |||
163 | return lOut; | ||
164 | } | ||
165 | |||
166 | // | ||
167 | // Rule functions | ||
168 | // | ||
169 | void BuildParser::addRule( const char *sName ) | ||
170 | { | ||
171 | lRuleTmp.push_back( RuleInfo() ); | ||
172 | lRuleTmp.back().sName = sName; | ||
173 | } | ||
174 | |||
175 | void BuildParser::addRuleMatches() | ||
176 | { | ||
177 | lRuleTmp.back().pMatches = pTmpFunc; | ||
178 | } | ||
179 | |||
180 | void BuildParser::addRuleProduces() | ||
181 | { | ||
182 | lRuleTmp.back().lProduces.insert( | ||
183 | lRuleTmp.back().lProduces.end(), | ||
184 | lTmp.begin(), lTmp.end() | ||
185 | ); | ||
186 | } | ||
187 | |||
188 | void BuildParser::addRuleRequires() | ||
189 | { | ||
190 | lRuleTmp.back().lRequires.insert( | ||
191 | lRuleTmp.back().lRequires.end(), | ||
192 | lTmp.begin(), lTmp.end() | ||
193 | ); | ||
194 | } | ||
195 | |||
196 | void BuildParser::addRuleInputFilter() | ||
197 | { | ||
198 | lRuleTmp.back().lFilter.push_back( pTmpFunc ); | ||
199 | } | ||
200 | |||
201 | void BuildParser::addRulePerform() | ||
202 | { | ||
203 | lRuleTmp.back().lPerform.push_back( pTmpPerform ); | ||
204 | } | ||
205 | |||
206 | // | ||
207 | // Perform functions | ||
208 | // | ||
209 | bool BuildParser::isPerform( const char *sPerf ) | ||
210 | { | ||
211 | return fPerform.hasPlugin( sPerf ); | ||
212 | } | ||
213 | |||
214 | void BuildParser::newPerform( const char *sName ) | ||
215 | { | ||
216 | pTmpPerform = fPerform.instantiate( sName ); | ||
217 | } | ||
218 | |||
219 | void BuildParser::addPerformParam( const char *sParam ) | ||
220 | { | ||
221 | pTmpPerform->addParam( sParam ); | ||
222 | } | ||
223 | |||
224 | // | ||
225 | // Functions for dealing with actions | ||
226 | // | ||
227 | void BuildParser::addAction() | ||
228 | { | ||
229 | lActions.push_back( ActionTmp("", ActionTmpCmdList()) ); | ||
230 | } | ||
231 | |||
232 | void BuildParser::addAction( const char *sName ) | ||
233 | { | ||
234 | lActions.push_back( ActionTmp(sName, ActionTmpCmdList()) ); | ||
235 | } | ||
236 | |||
237 | void BuildParser::addCommand( int nType ) | ||
238 | { | ||
239 | lActions.back().second.push_back( ActionTmpCmd( nType, lTmp ) ); | ||
240 | } | ||
241 | |||
242 | // | ||
243 | // Global variable functions | ||
244 | // | ||
245 | void BuildParser::addGlobalSet( const char *sVar, const char *sValue, int nHow ) | ||
246 | { | ||
247 | lGlobalVars.push_back( SetVar( sVar, sValue, nHow ) ); | ||
248 | } | ||
249 | |||
250 | // | ||
251 | // Debug | ||
252 | // | ||
253 | void BuildParser::debugDump() | ||
254 | { | ||
255 | printf("Actions:\n"); | ||
256 | for( ActionTmpList::iterator i = lActions.begin(); | ||
257 | i != lActions.end(); i++ ) | ||
258 | { | ||
259 | if( (*i).first == "" ) | ||
260 | { | ||
261 | printf(" default:\n"); | ||
262 | } | ||
263 | else | ||
264 | { | ||
265 | printf(" \"%s\":\n", (*i).first.c_str() ); | ||
266 | } | ||
267 | for( ActionTmpCmdList::iterator j = (*i).second.begin(); | ||
268 | j != (*i).second.end(); j++ ) | ||
269 | { | ||
270 | printf(" %d ", (*j).first ); | ||
271 | printBuildList( (*j).second ); | ||
272 | printf("\n"); | ||
273 | } | ||
274 | } | ||
275 | |||
276 | printf("\nTargets:\n"); | ||
277 | for( TargetTmpList::iterator i = lTargetTmp.begin(); | ||
278 | i != lTargetTmp.end(); i++ ) | ||
279 | { | ||
280 | printf(" "); | ||
281 | printBuildList( (*i).first ); | ||
282 | printf(":\n"); | ||
283 | |||
284 | printf(" Rule: %s\n", (*i).second.sRule.c_str() ); | ||
285 | printf(" Prefix: %s\n", (*i).second.sPrefix.c_str() ); | ||
286 | printf(" Type: %s\n", (*i).second.sType.c_str() ); | ||
287 | printf(" Input: "); | ||
288 | printBuildList( (*i).second.lInput ); | ||
289 | printf("\n Requires: "); | ||
290 | printBuildList( (*i).second.lRequires ); | ||
291 | printf("\n Vars:\n"); | ||
292 | |||
293 | for( SetVarList::iterator j = (*i).second.lVar.begin(); | ||
294 | j != (*i).second.lVar.end(); j++ ) | ||
295 | { | ||
296 | char *op; | ||
297 | switch( (*j).third ) | ||
298 | { | ||
299 | case setSet: op = "="; break; | ||
300 | case setAdd: op = "+="; break; | ||
301 | } | ||
302 | printf(" %s %s %s\n", (*j).first.c_str(), op, (*j).second.c_str() ); | ||
303 | } | ||
304 | } | ||
305 | |||
306 | printf("\nGlobals:\n"); | ||
307 | for( SetVarList::iterator j = lGlobalVars.begin(); | ||
308 | j != lGlobalVars.end(); j++ ) | ||
309 | { | ||
310 | char *op; | ||
311 | switch( (*j).third ) | ||
312 | { | ||
313 | case setSet: op = "="; break; | ||
314 | case setAdd: op = "+="; break; | ||
315 | } | ||
316 | printf(" %s %s %s\n", (*j).first.c_str(), op, (*j).second.c_str() ); | ||
317 | } | ||
318 | |||
319 | printf("\nRules:\n"); | ||
320 | for( RuleTmpList::iterator i = lRuleTmp.begin(); | ||
321 | i != lRuleTmp.end(); i++ ) | ||
322 | { | ||
323 | printf(" %s:\n", (*i).sName.c_str() ); | ||
324 | printf(" Matches: func()\n"); | ||
325 | printf(" Produces: "); | ||
326 | printBuildList( (*i).lProduces ); | ||
327 | printf("\n Requires: "); | ||
328 | printBuildList( (*i).lRequires ); | ||
329 | printf("\n Filters: %d\n", (*i).lFilter.size() ); | ||
330 | printf(" Performs: %d\n", (*i).lPerform.size() ); | ||
331 | } | ||
332 | } | ||
333 | |||
334 | void BuildParser::printBuildList( const BuildList &lst ) | ||
335 | { | ||
336 | printf("["); | ||
337 | for( BuildList::const_iterator k = lst.begin(); | ||
338 | k != lst.end(); k++ ) | ||
339 | { | ||
340 | if( k != lst.begin() ) | ||
341 | { | ||
342 | printf(", "); | ||
343 | } | ||
344 | if( (*k).second ) | ||
345 | { | ||
346 | printf("func()"); | ||
347 | } | ||
348 | else | ||
349 | { | ||
350 | printf("\"%s\"", (*k).first.c_str() ); | ||
351 | } | ||
352 | } | ||
353 | printf("]"); | ||
354 | } | ||
355 | |||
356 | // | ||
357 | // Actually make a build object | ||
358 | // | ||
359 | Build *BuildParser::genBuild() | ||
360 | { | ||
361 | Build *bld = new Build; | ||
362 | |||
363 | for( SetVarList::iterator i = lGlobalVars.begin(); | ||
364 | i != lGlobalVars.end(); i++ ) | ||
365 | { | ||
366 | switch( (*i).third ) | ||
367 | { | ||
368 | case setSet: | ||
369 | bld->set( "", (*i).first, (*i).second ); | ||
370 | break; | ||
371 | |||
372 | case setAdd: | ||
373 | bld->setAdd( "", (*i).first, (*i).second ); | ||
374 | break; | ||
375 | } | ||
376 | } | ||
377 | |||
378 | for( TargetTmpList::iterator i = lTargetTmp.begin(); | ||
379 | i != lTargetTmp.end(); i++ ) | ||
380 | { | ||
381 | StringList lTargetNames = buildToStringList( | ||
382 | (*i).first, StringList() | ||
383 | ); | ||
384 | for( StringList::iterator j = lTargetNames.begin(); | ||
385 | j != lTargetNames.end(); j++ ) | ||
386 | { | ||
387 | if( (*i).second.sType != "" ) | ||
388 | { | ||
389 | Target *pTarget = fTarget.instantiate( | ||
390 | (*i).second.sType.c_str() | ||
391 | ); | ||
392 | pTarget->setName( *j ); | ||
393 | pTarget->setRule( (*i).second.sRule ); | ||
394 | |||
395 | StringList lInputs = buildToStringList( | ||
396 | (*i).second.lInput, StringList() | ||
397 | ); | ||
398 | pTarget->getInput().insert( | ||
399 | pTarget->getInput().end(), | ||
400 | lInputs.begin(), lInputs.end() | ||
401 | ); | ||
402 | |||
403 | bld->addTarget( pTarget ); | ||
404 | } | ||
405 | StringList lReqs = buildToStringList( | ||
406 | (*i).second.lRequires, StringList() | ||
407 | ); | ||
408 | for( StringList::iterator k = lReqs.begin(); | ||
409 | k != lReqs.end(); k++ ) | ||
410 | { | ||
411 | bld->addRequires( (*j), (*k) ); | ||
412 | } | ||
413 | for( SetVarList::iterator k = (*i).second.lVar.begin(); | ||
414 | k != (*i).second.lVar.end(); k++ ) | ||
415 | { | ||
416 | switch( (*k).third ) | ||
417 | { | ||
418 | case setSet: | ||
419 | bld->set( *j, (*k).first, (*k).second ); | ||
420 | break; | ||
421 | |||
422 | case setAdd: | ||
423 | bld->setAdd( *j, (*k).first, (*k).second ); | ||
424 | break; | ||
425 | } | ||
426 | } | ||
427 | } | ||
428 | } | ||
429 | |||
430 | return bld; | ||
431 | } | ||
432 | |||