diff options
Diffstat (limited to '')
-rw-r--r-- | src/builder.cpp | 235 |
1 files changed, 235 insertions, 0 deletions
diff --git a/src/builder.cpp b/src/builder.cpp index e5017e2..8e29c81 100644 --- a/src/builder.cpp +++ b/src/builder.cpp | |||
@@ -32,6 +32,28 @@ void Builder::load( const char *sFN ) | |||
32 | scanEnd(); | 32 | scanEnd(); |
33 | } | 33 | } |
34 | 34 | ||
35 | void Builder::build( const char *sAct ) | ||
36 | { | ||
37 | Action *pAct; | ||
38 | if( sAct == NULL ) | ||
39 | pAct = pDefaultAction; | ||
40 | else | ||
41 | { | ||
42 | if( mAction.find( sAct ) == mAction.end() ) | ||
43 | throw BuildException("No action matches '%s'.", sAct ); | ||
44 | pAct = mAction[sAct]; | ||
45 | } | ||
46 | |||
47 | printf("--- %s ---\n", pAct->getName() ); | ||
48 | |||
49 | pAct->execute( *this ); | ||
50 | } | ||
51 | |||
52 | void Builder::execute( Action *pAct ) | ||
53 | { | ||
54 | pAct->execute( *this ); | ||
55 | } | ||
56 | |||
35 | void Builder::add( Action *pAct ) | 57 | void Builder::add( Action *pAct ) |
36 | { | 58 | { |
37 | if( pAct->isDefault() ) | 59 | if( pAct->isDefault() ) |
@@ -185,8 +207,125 @@ void Builder::varAddSet( const char *sName, const char *sValue ) | |||
185 | } | 207 | } |
186 | } | 208 | } |
187 | 209 | ||
210 | void Builder::processRequires( std::list<std::string> &lInput ) | ||
211 | { | ||
212 | for( regreqlist::iterator i = lRequiresRegexp.begin(); | ||
213 | i != lRequiresRegexp.end(); i++ ) | ||
214 | { | ||
215 | RegExp *re = (*i).first; | ||
216 | for( std::list<std::string>::iterator j = lInput.begin(); | ||
217 | j != lInput.end(); j++ ) | ||
218 | { | ||
219 | if( re->execute( (*j).c_str() ) ) | ||
220 | { | ||
221 | varmap *revars = regexVars( re ); | ||
222 | requiresNormal( | ||
223 | (*j).c_str(), | ||
224 | varRepl( | ||
225 | (*i).second.c_str(), | ||
226 | "", | ||
227 | revars | ||
228 | ).c_str() | ||
229 | ); | ||
230 | delete revars; | ||
231 | } | ||
232 | } | ||
233 | } | ||
234 | |||
235 | for( regreqlist::iterator i = lRequiresRegexpCommand.begin(); | ||
236 | i != lRequiresRegexpCommand.end(); i++ ) | ||
237 | { | ||
238 | RegExp *re = (*i).first; | ||
239 | for( std::list<std::string>::iterator j = lInput.begin(); | ||
240 | j != lInput.end(); j++ ) | ||
241 | { | ||
242 | if( re->execute( (*j).c_str() ) ) | ||
243 | { | ||
244 | varmap *revars = regexVars( re ); | ||
245 | FILE *fcmd = popen( | ||
246 | varRepl( (*i).second.c_str(), "", revars ).c_str(), | ||
247 | "r" ); | ||
248 | std::string rhs; | ||
249 | bool bHeader = true; | ||
250 | for(;;) | ||
251 | { | ||
252 | if( feof( fcmd ) ) | ||
253 | break; | ||
254 | int cc = fgetc( fcmd ); | ||
255 | if( cc == EOF ) | ||
256 | break; | ||
257 | unsigned char c = cc; | ||
258 | if( bHeader ) | ||
259 | { | ||
260 | if( c == ':' ) | ||
261 | bHeader = false; | ||
262 | } | ||
263 | else | ||
264 | { | ||
265 | if( c == ' ' || c == '\t' ) | ||
266 | { | ||
267 | if( rhs != "" ) | ||
268 | { | ||
269 | requiresNormal( | ||
270 | (*j).c_str(), | ||
271 | rhs.c_str() | ||
272 | ); | ||
273 | rhs = ""; | ||
274 | } | ||
275 | } | ||
276 | else | ||
277 | { | ||
278 | if( c == '\\' ) | ||
279 | c = fgetc( fcmd ); | ||
280 | if( c != '\n' ) | ||
281 | rhs += c; | ||
282 | } | ||
283 | } | ||
284 | } | ||
285 | if( rhs != "" ) | ||
286 | { | ||
287 | requiresNormal( | ||
288 | (*j).c_str(), | ||
289 | rhs.c_str() | ||
290 | ); | ||
291 | rhs = ""; | ||
292 | } | ||
293 | fclose( fcmd ); | ||
294 | delete revars; | ||
295 | } | ||
296 | } | ||
297 | } | ||
298 | } | ||
299 | |||
300 | std::map<std::string, std::string> *Builder::regexVars( RegExp *re ) | ||
301 | { | ||
302 | varmap *map = new varmap; | ||
303 | |||
304 | int jmax = re->getNumSubStrings(); | ||
305 | for( int j = 0; j < jmax; j++ ) | ||
306 | { | ||
307 | char buf[8]; | ||
308 | sprintf( buf, "re:%d", j ); | ||
309 | (*map)[buf] = re->getSubString( j ); | ||
310 | } | ||
311 | |||
312 | return map; | ||
313 | } | ||
314 | |||
188 | void Builder::requires( const char *sBase, const char *sReq ) | 315 | void Builder::requires( const char *sBase, const char *sReq ) |
189 | { | 316 | { |
317 | if( bReqRegexp ) | ||
318 | { | ||
319 | requiresRegexp( sBase, sReq ); | ||
320 | } | ||
321 | else | ||
322 | { | ||
323 | requiresNormal( sBase, sReq ); | ||
324 | } | ||
325 | } | ||
326 | |||
327 | void Builder::requiresNormal( const char *sBase, const char *sReq ) | ||
328 | { | ||
190 | std::list<std::string> *pList = NULL; | 329 | std::list<std::string> *pList = NULL; |
191 | if( mRequires.find(sBase) == mRequires.end() ) | 330 | if( mRequires.find(sBase) == mRequires.end() ) |
192 | { | 331 | { |
@@ -201,6 +340,26 @@ void Builder::requires( const char *sBase, const char *sReq ) | |||
201 | pList->push_back( sReq ); | 340 | pList->push_back( sReq ); |
202 | } | 341 | } |
203 | 342 | ||
343 | void Builder::requiresRegexp( const char *sBase, const char *sReq ) | ||
344 | { | ||
345 | lRequiresRegexp.push_back( | ||
346 | std::pair<RegExp *, std::string>( | ||
347 | new RegExp( sBase ), | ||
348 | sReq | ||
349 | ) | ||
350 | ); | ||
351 | } | ||
352 | |||
353 | void Builder::requiresFromCommand( const char *sBase, const char *sCmd ) | ||
354 | { | ||
355 | lRequiresRegexpCommand.push_back( | ||
356 | std::pair<RegExp *, std::string>( | ||
357 | new RegExp( sBase ), | ||
358 | sCmd | ||
359 | ) | ||
360 | ); | ||
361 | } | ||
362 | |||
204 | void Builder::setContext( const char *sCont ) | 363 | void Builder::setContext( const char *sCont ) |
205 | { | 364 | { |
206 | sContext = sCont; | 365 | sContext = sCont; |
@@ -211,3 +370,79 @@ void Builder::setContext() | |||
211 | setContext(""); | 370 | setContext(""); |
212 | } | 371 | } |
213 | 372 | ||
373 | bool Builder::hasVar( varmap *pMap, std::string &var ) | ||
374 | { | ||
375 | if( pMap == NULL ) | ||
376 | return false; | ||
377 | if( pMap->find( var ) == pMap->end() ) | ||
378 | return false; | ||
379 | return true; | ||
380 | } | ||
381 | |||
382 | std::string Builder::varRepl( const char *sSrc, const char *cont, varmap *mExtra ) | ||
383 | { | ||
384 | varmap *mCont = NULL; | ||
385 | if( cont[0] != '\0' ) | ||
386 | { | ||
387 | if( mContVar.find( cont ) != mContVar.end() ) | ||
388 | mCont = &mContVar[cont]; | ||
389 | } | ||
390 | |||
391 | std::string out; | ||
392 | std::string var; | ||
393 | bool bVar = false; | ||
394 | |||
395 | for( const char *s = sSrc; *s; s++ ) | ||
396 | { | ||
397 | if( *s == '{' ) | ||
398 | { | ||
399 | bVar = true; | ||
400 | continue; | ||
401 | } | ||
402 | else if( *s == '}' && bVar ) | ||
403 | { | ||
404 | if( hasVar( &mVar, var ) ) | ||
405 | { | ||
406 | out += mVar[var]; | ||
407 | } | ||
408 | else if( hasVar( mCont, var ) ) | ||
409 | { | ||
410 | out += (*mCont)[var]; | ||
411 | } | ||
412 | else if( hasVar( mExtra, var ) ) | ||
413 | { | ||
414 | out += (*mExtra)[var]; | ||
415 | } | ||
416 | var = ""; | ||
417 | bVar = false; | ||
418 | continue; | ||
419 | } | ||
420 | |||
421 | if( bVar == true ) | ||
422 | { | ||
423 | var += *s; | ||
424 | } | ||
425 | else | ||
426 | { | ||
427 | out += *s; | ||
428 | } | ||
429 | } | ||
430 | |||
431 | return out; | ||
432 | } | ||
433 | |||
434 | Rule *Builder::getRule( const char *sName ) | ||
435 | { | ||
436 | if( mRule.find( sName ) != mRule.end() ) | ||
437 | return mRule[sName]; | ||
438 | |||
439 | return NULL; | ||
440 | } | ||
441 | |||
442 | std::list<Rule *> Builder::findRuleChain( Rule *pRule ) | ||
443 | { | ||
444 | std::list<Rule *> ret; | ||
445 | |||
446 | return ret; | ||
447 | } | ||
448 | |||