diff options
author | Mike Buland <eichlan@xagasoft.com> | 2006-08-18 17:21:02 +0000 |
---|---|---|
committer | Mike Buland <eichlan@xagasoft.com> | 2006-08-18 17:21:02 +0000 |
commit | df5286fe3bca619beb4771da1ffa8ace9613e9e5 (patch) | |
tree | 0ad268267325c586527b8d36461ab0040e9ae8ec /src/builder.cpp | |
parent | 4f94dfde7cbe043dfeb11a8712636bac348d3177 (diff) | |
download | build-df5286fe3bca619beb4771da1ffa8ace9613e9e5.tar.gz build-df5286fe3bca619beb4771da1ffa8ace9613e9e5.tar.bz2 build-df5286fe3bca619beb4771da1ffa8ace9613e9e5.tar.xz build-df5286fe3bca619beb4771da1ffa8ace9613e9e5.zip |
Gutted, deleted almost all the source, too many changes to keep it around, we'll
see what happens next.
Diffstat (limited to 'src/builder.cpp')
-rw-r--r-- | src/builder.cpp | 825 |
1 files changed, 0 insertions, 825 deletions
diff --git a/src/builder.cpp b/src/builder.cpp deleted file mode 100644 index 8c3bbbb..0000000 --- a/src/builder.cpp +++ /dev/null | |||
@@ -1,825 +0,0 @@ | |||
1 | #include <iostream> | ||
2 | #include <sstream> | ||
3 | #include <errno.h> | ||
4 | #include <dirent.h> | ||
5 | |||
6 | #include "builder.h" | ||
7 | #include "action.h" | ||
8 | #include "command.h" | ||
9 | #include "target.h" | ||
10 | #include "filetarget.h" | ||
11 | #include "build.tab.h" | ||
12 | #include "rule.h" | ||
13 | #include "viewer.h" | ||
14 | #include "cache.h" | ||
15 | #include "serializerbinary.h" | ||
16 | |||
17 | subExceptionDef( BuildException ) | ||
18 | |||
19 | Builder::Builder( Viewer &rView ) : | ||
20 | pDefaultAction( NULL ), | ||
21 | pLastAddedAction( NULL ), | ||
22 | sTmp(""), | ||
23 | sContext(""), | ||
24 | rView( rView ), | ||
25 | bUsingList( false ) | ||
26 | { | ||
27 | } | ||
28 | |||
29 | Builder::~Builder() | ||
30 | { | ||
31 | if( sCacheFile.getLength() > 0 ) | ||
32 | { | ||
33 | try | ||
34 | { | ||
35 | SerializerBinary ar( sCacheFile, Serializer::save ); | ||
36 | |||
37 | ar << cRequires; | ||
38 | } | ||
39 | catch( ExceptionBase &e ) | ||
40 | { | ||
41 | } | ||
42 | } | ||
43 | } | ||
44 | |||
45 | void yyparse( Builder &bld ); | ||
46 | |||
47 | void Builder::load( const char *sFN ) | ||
48 | { | ||
49 | file = sFN; | ||
50 | |||
51 | scanBegin(); | ||
52 | yyparse( *this ); | ||
53 | scanEnd(); | ||
54 | } | ||
55 | |||
56 | void Builder::build( const char *sAct ) | ||
57 | { | ||
58 | Action *pAct; | ||
59 | if( sAct == NULL ) | ||
60 | pAct = pDefaultAction; | ||
61 | else | ||
62 | { | ||
63 | if( mAction.find( sAct ) == mAction.end() ) | ||
64 | throw BuildException("No action matches '%s'.", sAct ); | ||
65 | pAct = mAction[sAct]; | ||
66 | } | ||
67 | |||
68 | rView.beginAction( sAct, pAct->getNumCommands() ); | ||
69 | |||
70 | pAct->execute( *this ); | ||
71 | |||
72 | rView.endAction(); | ||
73 | } | ||
74 | |||
75 | void Builder::setCache( const std::string &sFile ) | ||
76 | { | ||
77 | sCacheFile = sFile.c_str(); | ||
78 | |||
79 | try | ||
80 | { | ||
81 | SerializerBinary ar( sCacheFile, Serializer::load ); | ||
82 | |||
83 | ar >> cRequires; | ||
84 | } | ||
85 | catch( ExceptionBase &e ) | ||
86 | { | ||
87 | } | ||
88 | } | ||
89 | |||
90 | void Builder::execute( Action *pAct ) | ||
91 | { | ||
92 | pAct->execute( *this ); | ||
93 | } | ||
94 | |||
95 | void Builder::add( Action *pAct ) | ||
96 | { | ||
97 | if( pAct->isDefault() ) | ||
98 | { | ||
99 | if( pDefaultAction ) | ||
100 | throw BuildException("There's already a default exception"); | ||
101 | pDefaultAction = pAct; | ||
102 | } | ||
103 | else | ||
104 | { | ||
105 | mAction[pAct->getName()] = pAct; | ||
106 | } | ||
107 | pLastAddedAction = pAct; | ||
108 | } | ||
109 | |||
110 | void Builder::add( Command *pCmd ) | ||
111 | { | ||
112 | if( pLastAddedAction ) | ||
113 | { | ||
114 | pLastAddedAction->add( pCmd ); | ||
115 | } | ||
116 | } | ||
117 | |||
118 | void Builder::addRegexCommand( int nType, const char *sReg ) | ||
119 | { | ||
120 | if( pLastAddedAction ) | ||
121 | { | ||
122 | pLastAddedAction->add( nType, sReg ); | ||
123 | } | ||
124 | } | ||
125 | |||
126 | void Builder::add( Rule *pRule ) | ||
127 | { | ||
128 | pLastAddedRule = pRule; | ||
129 | mRule[pRule->getName()] = pRule; | ||
130 | } | ||
131 | |||
132 | void Builder::add( Target *pTarg ) | ||
133 | { | ||
134 | pLastAddedTarget = pTarg; | ||
135 | mTarget[pTarg->getName()] = pTarg; | ||
136 | } | ||
137 | |||
138 | void Builder::addTarget( int tokType, const char *sName ) | ||
139 | { | ||
140 | nTargetType = tokType; | ||
141 | sTargetName = sName; | ||
142 | } | ||
143 | |||
144 | void Builder::setTargetInputType( int tokType ) | ||
145 | { | ||
146 | nTargetInputType = tokType; | ||
147 | } | ||
148 | |||
149 | void Builder::addTargetInput( const char *sInput ) | ||
150 | { | ||
151 | lsTargetInput.push_back( sInput ); | ||
152 | } | ||
153 | |||
154 | void Builder::setTargetRule( const char *sRule ) | ||
155 | { | ||
156 | sTargetRule = sRule; | ||
157 | } | ||
158 | |||
159 | void Builder::endTarget() | ||
160 | { | ||
161 | if( bUsingList == false ) | ||
162 | { | ||
163 | switch( nTargetType ) | ||
164 | { | ||
165 | case TOK_FILE: | ||
166 | add( new FileTarget( sTargetName.c_str() ) ); | ||
167 | switch( nTargetInputType ) | ||
168 | { | ||
169 | case TOK_FILES: | ||
170 | for( std::list<std::string>::iterator | ||
171 | i = lsTargetInput.begin(); | ||
172 | i != lsTargetInput.end(); i++ ) | ||
173 | { | ||
174 | ((FileTarget *)lastTarget())->addInputDir( | ||
175 | (*i).c_str() | ||
176 | ); | ||
177 | } | ||
178 | break; | ||
179 | } | ||
180 | lastTarget()->setRule( sTargetRule.c_str() ); | ||
181 | break; | ||
182 | } | ||
183 | } | ||
184 | else | ||
185 | { | ||
186 | switch( nTargetType ) | ||
187 | { | ||
188 | case TOK_FILE: | ||
189 | for( std::list<std::pair<std::string,std::map<std::string,std::string> > >::iterator j = lTok.begin(); j != lTok.end(); j++ ) | ||
190 | { | ||
191 | std::string sName = varRepl( sTargetName.c_str(), "", &(*j).second ); | ||
192 | add( new FileTarget( sName.c_str() ) ); | ||
193 | switch( nTargetInputType ) | ||
194 | { | ||
195 | case TOK_FILES: | ||
196 | for( std::list<std::string>::iterator | ||
197 | i = lsTargetInput.begin(); | ||
198 | i != lsTargetInput.end(); i++ ) | ||
199 | { | ||
200 | std::string sInput = varRepl( | ||
201 | (*i).c_str(), "", | ||
202 | &(*j).second | ||
203 | ); | ||
204 | ((FileTarget *)lastTarget())->addInputDir( | ||
205 | sInput.c_str() | ||
206 | ); | ||
207 | } | ||
208 | break; | ||
209 | } | ||
210 | lastTarget()->setRule( sTargetRule.c_str() ); | ||
211 | } | ||
212 | break; | ||
213 | } | ||
214 | } | ||
215 | |||
216 | clearList(); | ||
217 | } | ||
218 | |||
219 | void Builder::debug() | ||
220 | { | ||
221 | printf("Actions:\n"); | ||
222 | pDefaultAction->debug(); | ||
223 | for( std::map<const char *, Action *, ltstr>::iterator i = mAction.begin(); | ||
224 | i != mAction.end(); i++ ) | ||
225 | { | ||
226 | (*i).second->debug(); | ||
227 | } | ||
228 | |||
229 | printf("Targets:\n"); | ||
230 | for( std::map<const char *, Target *, ltstr>::iterator i = mTarget.begin(); | ||
231 | i != mTarget.end(); i++ ) | ||
232 | { | ||
233 | (*i).second->debug(); | ||
234 | } | ||
235 | |||
236 | printf("Rules:\n"); | ||
237 | for( std::map<const char *, Rule *, ltstr>::iterator i = mRule.begin(); | ||
238 | i != mRule.end(); i++ ) | ||
239 | { | ||
240 | (*i).second->debug(); | ||
241 | } | ||
242 | |||
243 | printf("Variables:\n"); | ||
244 | for( varmap::iterator i = mVar.begin(); i != mVar.end(); i++ ) | ||
245 | { | ||
246 | printf(" %s = \"%s\"\n", (*i).first.c_str(), (*i).second.c_str() ); | ||
247 | } | ||
248 | |||
249 | printf("Variables (by context):\n"); | ||
250 | for( std::map<std::string, varmap>::iterator j = mContVar.begin(); | ||
251 | j != mContVar.end(); j++ ) | ||
252 | { | ||
253 | printf(" %s:\n", (*j).first.c_str() ); | ||
254 | for( varmap::iterator i = (*j).second.begin(); | ||
255 | i != (*j).second.end(); i++ ) | ||
256 | { | ||
257 | printf(" %s = \"%s\"\n", | ||
258 | (*i).first.c_str(), (*i).second.c_str() ); | ||
259 | } | ||
260 | } | ||
261 | |||
262 | printf("Dependancies:\n"); | ||
263 | for( std::map<std::string, std::list<std::string> *>::iterator i = | ||
264 | mRequires.begin(); i != mRequires.end(); i++ ) | ||
265 | { | ||
266 | printf(" %s: ", (*i).first.c_str() ); | ||
267 | std::list<std::string> *pList = (*i).second; | ||
268 | int i = 0; | ||
269 | for( std::list<std::string>::iterator j = pList->begin(); | ||
270 | j != pList->end(); j++ ) | ||
271 | { | ||
272 | if( j != pList->begin() ) | ||
273 | printf(", "); | ||
274 | printf("%s", (*j).c_str() ); | ||
275 | if( i++ >= 3 ) | ||
276 | { | ||
277 | printf("..."); | ||
278 | break; | ||
279 | } | ||
280 | } | ||
281 | printf("\n"); | ||
282 | } | ||
283 | } | ||
284 | |||
285 | void Builder::checkVar( const char *cont, const char *sName ) | ||
286 | { | ||
287 | if( cont[0] != '\0' ) | ||
288 | { | ||
289 | varmap &mmVar = mContVar[cont]; | ||
290 | if( mmVar.find( sName ) == mmVar.end() ) | ||
291 | { | ||
292 | checkVar( "", sName ); | ||
293 | mmVar[sName] = mVar[sName]; | ||
294 | } | ||
295 | } | ||
296 | else | ||
297 | { | ||
298 | if( mVar.find( sName ) == mVar.end() ) | ||
299 | { | ||
300 | char *env = getenv( sName ); | ||
301 | if( env ) | ||
302 | mVar[sName] = env; | ||
303 | else | ||
304 | mVar[sName] = ""; | ||
305 | } | ||
306 | } | ||
307 | } | ||
308 | |||
309 | void Builder::varSet( const char *sName, const char *sValue ) | ||
310 | { | ||
311 | if( bUsingList ) | ||
312 | { | ||
313 | for( std::list<std::pair<std::string,std::map<std::string,std::string> > >::iterator i = lTok.begin(); i != lTok.end(); i++ ) | ||
314 | { | ||
315 | checkVar( (*i).first.c_str(), sName ); | ||
316 | |||
317 | std::string newVal = varRepl( sValue, (*i).first.c_str(), &(*i).second ); | ||
318 | |||
319 | mContVar[(*i).first.c_str()][sName] = newVal; | ||
320 | } | ||
321 | } | ||
322 | else | ||
323 | { | ||
324 | checkVar( sContext, sName ); | ||
325 | |||
326 | std::string newVal = varRepl( sValue, sContext, NULL ); | ||
327 | |||
328 | if( sContext[0] == '\0' ) | ||
329 | { | ||
330 | mVar[sName] = newVal; | ||
331 | } | ||
332 | else | ||
333 | { | ||
334 | mContVar[sContext.getString()][sName] = newVal; | ||
335 | } | ||
336 | } | ||
337 | } | ||
338 | |||
339 | void Builder::varAddSet( const char *sName, const char *sValue ) | ||
340 | { | ||
341 | checkVar( sContext, sName ); | ||
342 | |||
343 | std::string newVal = varRepl( sValue, sContext, NULL ); | ||
344 | |||
345 | if( sContext[0] == '\0' ) | ||
346 | { | ||
347 | std::string s = mVar[sName]; | ||
348 | s += " "; | ||
349 | s += newVal; | ||
350 | mVar[sName] = s; | ||
351 | } | ||
352 | else | ||
353 | { | ||
354 | std::string s = mContVar[sContext.getString()][sName]; | ||
355 | s += " "; | ||
356 | s += newVal; | ||
357 | mContVar[sContext.getString()][sName] = s; | ||
358 | } | ||
359 | } | ||
360 | |||
361 | void Builder::processRequires( std::list<std::string> &lInput ) | ||
362 | { | ||
363 | // These are cheap and handy to have all the time | ||
364 | for( regreqlist::iterator i = lRequiresRegexp.begin(); | ||
365 | i != lRequiresRegexp.end(); i++ ) | ||
366 | { | ||
367 | RegExp *re = (*i).first; | ||
368 | for( std::list<std::string>::iterator j = lInput.begin(); | ||
369 | j != lInput.end(); j++ ) | ||
370 | { | ||
371 | if( re->execute( (*j).c_str() ) ) | ||
372 | { | ||
373 | varmap *revars = regexVars( re ); | ||
374 | requiresNormal( | ||
375 | (*j).c_str(), | ||
376 | varRepl( | ||
377 | (*i).second.c_str(), | ||
378 | "", | ||
379 | revars | ||
380 | ).c_str() | ||
381 | ); | ||
382 | delete revars; | ||
383 | } | ||
384 | } | ||
385 | } | ||
386 | |||
387 | } | ||
388 | |||
389 | void Builder::genRequiresFor( const char *sName, time_t tNewTime ) | ||
390 | { | ||
391 | Cache::Entry *ent = cRequires.get( sName ); | ||
392 | if( ent && tNewTime > 0 ) | ||
393 | { | ||
394 | if( ent->tCreated >= tNewTime ) | ||
395 | { | ||
396 | for( std::list<std::string>::iterator i = ent->lData.begin(); | ||
397 | i != ent->lData.end(); i++ ) | ||
398 | { | ||
399 | requiresNormal( | ||
400 | sName, | ||
401 | (*i).c_str() | ||
402 | ); | ||
403 | } | ||
404 | |||
405 | return; | ||
406 | } | ||
407 | } | ||
408 | |||
409 | ent = new Cache::Entry; | ||
410 | ent->tCreated = tNewTime; | ||
411 | |||
412 | for( regreqlist::iterator i = lRequiresRegexpCommand.begin(); | ||
413 | i != lRequiresRegexpCommand.end(); i++ ) | ||
414 | { | ||
415 | RegExp *re = (*i).first; | ||
416 | if( re->execute( sName ) ) | ||
417 | { | ||
418 | varmap *revars = regexVars( re ); | ||
419 | std::string s = varRepl( (*i).second.c_str(), "", revars ); | ||
420 | rView.beginExtraRequiresCheck( s.c_str() ); | ||
421 | rView.executeCmd( s.c_str() ); | ||
422 | FILE *fcmd = popen( s.c_str(), "r" ); | ||
423 | std::string rhs; | ||
424 | bool bHeader = true; | ||
425 | for(;;) | ||
426 | { | ||
427 | if( feof( fcmd ) ) | ||
428 | break; | ||
429 | int cc = fgetc( fcmd ); | ||
430 | if( cc == EOF ) | ||
431 | break; | ||
432 | unsigned char c = cc; | ||
433 | if( bHeader ) | ||
434 | { | ||
435 | if( c == ':' ) | ||
436 | bHeader = false; | ||
437 | } | ||
438 | else | ||
439 | { | ||
440 | if( c == ' ' || c == '\t' ) | ||
441 | { | ||
442 | if( rhs != "" ) | ||
443 | { | ||
444 | requiresNormal( | ||
445 | sName, | ||
446 | rhs.c_str() | ||
447 | ); | ||
448 | ent->lData.push_back( rhs ); | ||
449 | rhs = ""; | ||
450 | } | ||
451 | } | ||
452 | else | ||
453 | { | ||
454 | if( c == '\\' ) | ||
455 | c = fgetc( fcmd ); | ||
456 | if( c != '\n' ) | ||
457 | rhs += c; | ||
458 | } | ||
459 | } | ||
460 | } | ||
461 | if( rhs != "" ) | ||
462 | { | ||
463 | requiresNormal( | ||
464 | sName, | ||
465 | rhs.c_str() | ||
466 | ); | ||
467 | ent->lData.push_back( rhs ); | ||
468 | rhs = ""; | ||
469 | } | ||
470 | pclose( fcmd ); | ||
471 | delete revars; | ||
472 | rView.endExtraRequiresCheck(); | ||
473 | } | ||
474 | } | ||
475 | |||
476 | cRequires.put( sName, ent ); | ||
477 | } | ||
478 | |||
479 | std::map<std::string, std::string> *Builder::regexVars( RegExp *re ) | ||
480 | { | ||
481 | varmap *map = new varmap; | ||
482 | |||
483 | int jmax = re->getNumSubStrings(); | ||
484 | for( int j = 0; j < jmax; j++ ) | ||
485 | { | ||
486 | char buf[8]; | ||
487 | sprintf( buf, "re:%d", j ); | ||
488 | (*map)[buf] = re->getSubString( j ); | ||
489 | } | ||
490 | |||
491 | return map; | ||
492 | } | ||
493 | |||
494 | void Builder::regexVars( RegExp *re, varmap &map ) | ||
495 | { | ||
496 | int jmax = re->getNumSubStrings(); | ||
497 | for( int j = 0; j < jmax; j++ ) | ||
498 | { | ||
499 | char buf[8]; | ||
500 | sprintf( buf, "re:%d", j ); | ||
501 | map[buf] = re->getSubString( j ); | ||
502 | } | ||
503 | } | ||
504 | |||
505 | void Builder::requires( const char *sBase, const char *sReq ) | ||
506 | { | ||
507 | if( bReqRegexp ) | ||
508 | { | ||
509 | requiresRegexp( sBase, sReq ); | ||
510 | } | ||
511 | else | ||
512 | { | ||
513 | requiresNormal( sBase, sReq ); | ||
514 | } | ||
515 | } | ||
516 | |||
517 | void Builder::requiresNormal( const char *sBase, const char *sReq ) | ||
518 | { | ||
519 | std::list<std::string> *pList = NULL; | ||
520 | if( mRequires.find(sBase) == mRequires.end() ) | ||
521 | { | ||
522 | pList = new std::list<std::string>; | ||
523 | mRequires[sBase] = pList; | ||
524 | } | ||
525 | else | ||
526 | { | ||
527 | pList = mRequires[sBase]; | ||
528 | } | ||
529 | |||
530 | pList->push_back( sReq ); | ||
531 | } | ||
532 | |||
533 | void Builder::requiresRegexp( const char *sBase, const char *sReq ) | ||
534 | { | ||
535 | lRequiresRegexp.push_back( | ||
536 | std::pair<RegExp *, std::string>( | ||
537 | new RegExp( sBase ), | ||
538 | sReq | ||
539 | ) | ||
540 | ); | ||
541 | } | ||
542 | |||
543 | void Builder::requiresFromCommand( const char *sBase, const char *sCmd ) | ||
544 | { | ||
545 | lRequiresRegexpCommand.push_back( | ||
546 | std::pair<RegExp *, std::string>( | ||
547 | new RegExp( sBase ), | ||
548 | sCmd | ||
549 | ) | ||
550 | ); | ||
551 | } | ||
552 | |||
553 | void Builder::setContext( const char *sCont ) | ||
554 | { | ||
555 | sContext = sCont; | ||
556 | } | ||
557 | |||
558 | void Builder::setContext() | ||
559 | { | ||
560 | setContext(""); | ||
561 | } | ||
562 | |||
563 | bool Builder::hasVar( varmap *pMap, std::string &var ) | ||
564 | { | ||
565 | if( pMap == NULL ) | ||
566 | return false; | ||
567 | if( pMap->find( var ) == pMap->end() ) | ||
568 | return false; | ||
569 | return true; | ||
570 | } | ||
571 | |||
572 | std::string Builder::varRepl( const char *sSrc, const char *cont, varmap *mExtra ) | ||
573 | { | ||
574 | varmap *mCont = NULL; | ||
575 | if( cont[0] != '\0' ) | ||
576 | { | ||
577 | if( mContVar.find( cont ) != mContVar.end() ) | ||
578 | mCont = &mContVar[cont]; | ||
579 | } | ||
580 | |||
581 | std::string out; | ||
582 | std::string var; | ||
583 | bool bVar = false; | ||
584 | |||
585 | for( const char *s = sSrc; *s; s++ ) | ||
586 | { | ||
587 | if( *s == '{' ) | ||
588 | { | ||
589 | bVar = true; | ||
590 | continue; | ||
591 | } | ||
592 | else if( *s == '}' && bVar ) | ||
593 | { | ||
594 | if( hasVar( mExtra, var ) ) | ||
595 | { | ||
596 | out += (*mExtra)[var]; | ||
597 | } | ||
598 | else if( hasVar( mCont, var ) ) | ||
599 | { | ||
600 | out += (*mCont)[var]; | ||
601 | } | ||
602 | else if( hasVar( &mVar, var ) ) | ||
603 | { | ||
604 | out += mVar[var]; | ||
605 | } | ||
606 | var = ""; | ||
607 | bVar = false; | ||
608 | continue; | ||
609 | } | ||
610 | |||
611 | if( bVar == true ) | ||
612 | { | ||
613 | var += *s; | ||
614 | } | ||
615 | else | ||
616 | { | ||
617 | out += *s; | ||
618 | } | ||
619 | } | ||
620 | |||
621 | return out; | ||
622 | } | ||
623 | |||
624 | Rule *Builder::getRule( const char *sName ) | ||
625 | { | ||
626 | if( mRule.find( sName ) != mRule.end() ) | ||
627 | return mRule[sName]; | ||
628 | |||
629 | throw BuildException("No rule named %s registered.", sName ); | ||
630 | return NULL; | ||
631 | } | ||
632 | |||
633 | std::list<Rule *> Builder::findRuleChain( Rule *pRule ) | ||
634 | { | ||
635 | std::list<Rule *> ret; | ||
636 | |||
637 | for( std::map<const char *, Rule *, ltstr>::iterator i = mRule.begin(); | ||
638 | i != mRule.end(); i++ ) | ||
639 | { | ||
640 | if( pRule == (*i).second ) | ||
641 | continue; | ||
642 | |||
643 | if( pRule->willChain( (*i).second ) ) | ||
644 | { | ||
645 | ret.push_back( (*i).second ); | ||
646 | } | ||
647 | } | ||
648 | |||
649 | return ret; | ||
650 | } | ||
651 | |||
652 | void cleanList( std::list<std::string> &lst ) | ||
653 | { | ||
654 | std::map<std::string, bool> m; | ||
655 | |||
656 | for( std::list<std::string>::iterator i = lst.begin(); i != lst.end(); i++ ) | ||
657 | { | ||
658 | if( m.find( *i ) == m.end() ) | ||
659 | m[ *i ] = true; | ||
660 | else | ||
661 | { | ||
662 | std::list<std::string>::iterator j = i; | ||
663 | j--; | ||
664 | lst.erase( i ); | ||
665 | i = j; | ||
666 | } | ||
667 | } | ||
668 | } | ||
669 | |||
670 | void Builder::error( const std::string &err ) | ||
671 | { | ||
672 | throw BuildException( err.c_str() ); | ||
673 | } | ||
674 | |||
675 | void Builder::error( YYLTYPE *locp, const std::string &err ) | ||
676 | { | ||
677 | std::stringstream s; | ||
678 | s << file << ":" << locp->first_line << "." << locp->first_column; | ||
679 | if( locp->first_line != locp->last_line ) | ||
680 | s << "-" << locp->last_line << "." << locp->last_column; | ||
681 | else if( locp->first_column != locp->last_column ) | ||
682 | s << "-" << locp->last_column; | ||
683 | s << ": " << err; | ||
684 | throw BuildException( s.str().c_str() ); | ||
685 | } | ||
686 | |||
687 | void Builder::startList( int tokType ) | ||
688 | { | ||
689 | bUsingList = true; | ||
690 | lTok.clear(); | ||
691 | bTokFiltered = false; | ||
692 | nTokType = tokType; | ||
693 | } | ||
694 | |||
695 | void Builder::setFilter( const char *sRegExp ) | ||
696 | { | ||
697 | rTok.compile( sRegExp ); | ||
698 | bTokFiltered = true; | ||
699 | } | ||
700 | |||
701 | void Builder::augmentList( const char *sFrom ) | ||
702 | { | ||
703 | switch( nTokType ) | ||
704 | { | ||
705 | case TOK_DIRECTORIES: | ||
706 | { | ||
707 | DIR *dir = opendir( sFrom ); | ||
708 | if( dir == NULL ) | ||
709 | { | ||
710 | printf("dir: %s\n", sFrom ); | ||
711 | throw BuildException( strerror( errno ) ); | ||
712 | } | ||
713 | |||
714 | std::string base; | ||
715 | base += sFrom; | ||
716 | base += "/"; | ||
717 | |||
718 | struct dirent *de; | ||
719 | |||
720 | while( (de = readdir( dir )) ) | ||
721 | { | ||
722 | if( de->d_type != DT_DIR ) | ||
723 | continue; | ||
724 | if( de->d_name[0] == '.' || de->d_name[0] == '\0' ) | ||
725 | continue; | ||
726 | |||
727 | std::string s( base ); | ||
728 | s += de->d_name; | ||
729 | addListItem( s.c_str() ); | ||
730 | } | ||
731 | |||
732 | closedir( dir ); | ||
733 | } | ||
734 | break; | ||
735 | |||
736 | default: | ||
737 | break; | ||
738 | } | ||
739 | } | ||
740 | |||
741 | void Builder::endList() | ||
742 | { | ||
743 | switch( nTokType ) | ||
744 | { | ||
745 | case TOK_TARGETS: | ||
746 | for( std::map<const char *, Target *, ltstr>::iterator i = | ||
747 | mTarget.begin(); i != mTarget.end(); i++ ) | ||
748 | { | ||
749 | addListItem( (*i).first ); | ||
750 | } | ||
751 | break; | ||
752 | } | ||
753 | } | ||
754 | |||
755 | void Builder::addListItem( const char *sItem ) | ||
756 | { | ||
757 | std::map<std::string,std::string> mVars; | ||
758 | mVars["match"] = sItem; | ||
759 | if( bTokFiltered ) | ||
760 | { | ||
761 | if( rTok.execute( sItem ) ) | ||
762 | { | ||
763 | regexVars( &rTok, mVars ); | ||
764 | } | ||
765 | else | ||
766 | { | ||
767 | return; | ||
768 | } | ||
769 | } | ||
770 | lTok.push_back( | ||
771 | std::pair<std::string,std::map<std::string,std::string> >( | ||
772 | sItem, mVars | ||
773 | ) | ||
774 | ); | ||
775 | } | ||
776 | |||
777 | void Builder::clearList() | ||
778 | { | ||
779 | lTok.clear(); | ||
780 | lsTargetInput.clear(); | ||
781 | bUsingList = false; | ||
782 | } | ||
783 | |||
784 | std::list<std::string> Builder::findTargets( const char *sRegex ) | ||
785 | { | ||
786 | RegExp r( sRegex ); | ||
787 | |||
788 | std::list<std::string> lTmp; | ||
789 | |||
790 | for( std::map<const char *, Target *, ltstr>::iterator i = mTarget.begin(); | ||
791 | i != mTarget.end(); i++ ) | ||
792 | { | ||
793 | if( r.execute( (*i).first ) ) | ||
794 | { | ||
795 | lTmp.push_back( (*i).first ); | ||
796 | } | ||
797 | } | ||
798 | |||
799 | return lTmp; | ||
800 | } | ||
801 | |||
802 | std::string Builder::cmdToString( const char *sCmd ) | ||
803 | { | ||
804 | std::string buf; | ||
805 | FILE *pr = popen( sCmd, "r" ); | ||
806 | if( pr == NULL ) | ||
807 | throw BuildException("Couldn't execute program \"%s\"", sCmd ); | ||
808 | |||
809 | char cbuf[2048]; | ||
810 | |||
811 | for(;;) | ||
812 | { | ||
813 | int nRead = fread( cbuf, 1, 2048, pr ); | ||
814 | for( int j = 0; j < nRead; j++ ) | ||
815 | if( cbuf[j] != '\n' && cbuf[j] != '\r' ) | ||
816 | buf.append( cbuf+j, 1 ); | ||
817 | if( feof( pr ) ) | ||
818 | break; | ||
819 | } | ||
820 | |||
821 | pclose( pr ); | ||
822 | |||
823 | return buf; | ||
824 | } | ||
825 | |||