diff options
author | Mike Buland <eichlan@xagasoft.com> | 2006-07-31 17:23:04 +0000 |
---|---|---|
committer | Mike Buland <eichlan@xagasoft.com> | 2006-07-31 17:23:04 +0000 |
commit | b672fa69c4c98509f8ee251b87300e3fcbe6bdc8 (patch) | |
tree | 064212cec710fc5bfd5f2b75dd2a502ba9f66eba | |
parent | 9139f1df4cda80b91ab68e5de27e85eaa4c54682 (diff) | |
download | build-b672fa69c4c98509f8ee251b87300e3fcbe6bdc8.tar.gz build-b672fa69c4c98509f8ee251b87300e3fcbe6bdc8.tar.bz2 build-b672fa69c4c98509f8ee251b87300e3fcbe6bdc8.tar.xz build-b672fa69c4c98509f8ee251b87300e3fcbe6bdc8.zip |
We're almost to rule/command generation, then only a couple of steps before it
will do it all!
-rw-r--r-- | build.conf | 22 | ||||
-rw-r--r-- | src/action.cpp | 10 | ||||
-rw-r--r-- | src/action.h | 3 | ||||
-rw-r--r-- | src/build.y | 46 | ||||
-rw-r--r-- | src/builder.cpp | 235 | ||||
-rw-r--r-- | src/builder.h | 39 | ||||
-rw-r--r-- | src/command.cpp | 16 | ||||
-rw-r--r-- | src/command.h | 4 | ||||
-rw-r--r-- | src/filetarget.cpp | 65 | ||||
-rw-r--r-- | src/filetarget.h | 5 | ||||
-rw-r--r-- | src/main.cpp | 5 | ||||
-rw-r--r-- | src/regexp.cpp | 71 | ||||
-rw-r--r-- | src/regexp.h | 36 | ||||
-rw-r--r-- | src/rule.cpp | 37 | ||||
-rw-r--r-- | src/rule.h | 8 | ||||
-rw-r--r-- | src/target.cpp | 16 | ||||
-rw-r--r-- | src/target.h | 13 |
17 files changed, 611 insertions, 20 deletions
diff --git a/build.conf b/build.conf new file mode 100644 index 0000000..b4792fb --- /dev/null +++ b/build.conf | |||
@@ -0,0 +1,22 @@ | |||
1 | # This is a build file for build | ||
2 | |||
3 | default action: check build | ||
4 | |||
5 | create file build from files in src using rule exe | ||
6 | |||
7 | set CXXFLAGS += "-Ilibbu++/src" | ||
8 | set LDFLAGS += "-Llibbu++ -lbu++" | ||
9 | |||
10 | /(.*)\.o/ requires from command "g++ {CXXFLAGS} -M {re:1}.c*" | ||
11 | |||
12 | rule exe matches all /(.*)\.o/ perform command ... | ||
13 | "g++ {LDFLAGS} -o {target} {matches}" | ||
14 | |||
15 | rule cpp matches one /(.*)\.c(pp)?/ produces {1}.o perform command ... | ||
16 | "g++ {CXXFLAGS} -o {target} {match}" | ||
17 | |||
18 | rule bison matches one /(.*)\.y/ produces {1}.tab.c, {1}.tab.h perform ... | ||
19 | command "bison {match}" | ||
20 | |||
21 | rule flex matches one /(.*)\.l/ produces {1}.yy.c perform ... | ||
22 | command "flex --bison-bridge --bison-locations -o {target} {match}" | ||
diff --git a/src/action.cpp b/src/action.cpp index c594792..8907816 100644 --- a/src/action.cpp +++ b/src/action.cpp | |||
@@ -1,5 +1,6 @@ | |||
1 | #include "action.h" | 1 | #include "action.h" |
2 | #include "command.h" | 2 | #include "command.h" |
3 | #include "builder.h" | ||
3 | 4 | ||
4 | Action::Action() : | 5 | Action::Action() : |
5 | bDefault( true ), | 6 | bDefault( true ), |
@@ -36,3 +37,12 @@ void Action::debug() | |||
36 | } | 37 | } |
37 | } | 38 | } |
38 | 39 | ||
40 | void Action::execute( Builder &bld ) | ||
41 | { | ||
42 | for( std::list<Command *>::iterator i = lCommand.begin(); | ||
43 | i != lCommand.end(); i++ ) | ||
44 | { | ||
45 | (*i)->execute( bld ); | ||
46 | } | ||
47 | } | ||
48 | |||
diff --git a/src/action.h b/src/action.h index 12c2cc4..7518ed2 100644 --- a/src/action.h +++ b/src/action.h | |||
@@ -5,6 +5,7 @@ | |||
5 | #include "staticstring.h" | 5 | #include "staticstring.h" |
6 | 6 | ||
7 | class Command; | 7 | class Command; |
8 | class Builder; | ||
8 | 9 | ||
9 | class Action | 10 | class Action |
10 | { | 11 | { |
@@ -26,6 +27,8 @@ public: | |||
26 | 27 | ||
27 | void debug(); | 28 | void debug(); |
28 | 29 | ||
30 | void execute( class Builder &bld ); | ||
31 | |||
29 | private: | 32 | private: |
30 | bool bDefault; | 33 | bool bDefault; |
31 | StaticString sName; | 34 | StaticString sName; |
diff --git a/src/build.y b/src/build.y index 8345b1f..ecc5d59 100644 --- a/src/build.y +++ b/src/build.y | |||
@@ -78,8 +78,15 @@ line: TOK_DEFAULT TOK_ACTION ':' | |||
78 | | STRING TOK_REQUIRES | 78 | | STRING TOK_REQUIRES |
79 | { | 79 | { |
80 | bld.setTmp( $1 ); | 80 | bld.setTmp( $1 ); |
81 | bld.requiresRegexp( false ); | ||
81 | } | 82 | } |
82 | reqlst | 83 | reqcompletion |
84 | | REGEXP TOK_REQUIRES | ||
85 | { | ||
86 | bld.setTmp( $1 ); | ||
87 | bld.requiresRegexp( true ); | ||
88 | } | ||
89 | reqcompletion | ||
83 | | listcmds | 90 | | listcmds |
84 | | TOK_FOR STRING | 91 | | TOK_FOR STRING |
85 | { | 92 | { |
@@ -92,6 +99,13 @@ line: TOK_DEFAULT TOK_ACTION ':' | |||
92 | | rule | 99 | | rule |
93 | ; | 100 | ; |
94 | 101 | ||
102 | reqcompletion: reqlst | ||
103 | | TOK_FROM TOK_COMMAND STRING | ||
104 | { | ||
105 | bld.requiresFromCommand( bld.getTmp(), $3 ); | ||
106 | } | ||
107 | ; | ||
108 | |||
95 | reqlst: STRING | 109 | reqlst: STRING |
96 | { | 110 | { |
97 | bld.requires( bld.getTmp(), $1 ); | 111 | bld.requires( bld.getTmp(), $1 ); |
@@ -118,7 +132,20 @@ createfromdirlst: createfromdir | |||
118 | | createfromdirlst ',' createfromdir | 132 | | createfromdirlst ',' createfromdir |
119 | ; | 133 | ; |
120 | 134 | ||
121 | createfromdir: STRING { printf(" srcdir: %s\n", $1 ); } | 135 | createfromdir: STRING |
136 | { | ||
137 | try | ||
138 | { | ||
139 | ((FileTarget *)bld.lastTarget())->addInputDir( $1 ); | ||
140 | } | ||
141 | catch( BuildException &e ) | ||
142 | { | ||
143 | std::string s( $1 ); | ||
144 | s +=": "; | ||
145 | s += e.what(); | ||
146 | yyerror( &yyloc, bld, s.c_str() ); | ||
147 | } | ||
148 | } | ||
122 | ; | 149 | ; |
123 | 150 | ||
124 | createusing: TOK_RULE STRING | 151 | createusing: TOK_RULE STRING |
@@ -159,12 +186,19 @@ rulesublst: rulesub | |||
159 | ; | 186 | ; |
160 | 187 | ||
161 | rulesub: TOK_MATCHES rulematches | 188 | rulesub: TOK_MATCHES rulematches |
162 | | TOK_PRODUCES STRING | 189 | | TOK_PRODUCES produceslst |
163 | { | ||
164 | bld.lastRule()->setProduces( $2 ); | ||
165 | } | ||
166 | ; | 190 | ; |
167 | 191 | ||
192 | produceslst: STRING | ||
193 | { | ||
194 | bld.lastRule()->addProduces( $1 ); | ||
195 | } | ||
196 | | produceslst ',' STRING | ||
197 | { | ||
198 | bld.lastRule()->addProduces( $3 ); | ||
199 | } | ||
200 | ; | ||
201 | |||
168 | rulematches: TOK_ALL REGEXP | 202 | rulematches: TOK_ALL REGEXP |
169 | { | 203 | { |
170 | try | 204 | try |
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 | |||
diff --git a/src/builder.h b/src/builder.h index 89810c0..d7c0891 100644 --- a/src/builder.h +++ b/src/builder.h | |||
@@ -7,6 +7,7 @@ | |||
7 | #include "build.tab.h" | 7 | #include "build.tab.h" |
8 | #include "exceptionbase.h" | 8 | #include "exceptionbase.h" |
9 | #include "staticstring.h" | 9 | #include "staticstring.h" |
10 | #include "regexp.h" | ||
10 | 11 | ||
11 | subExceptionDecl( BuildException ) | 12 | subExceptionDecl( BuildException ) |
12 | 13 | ||
@@ -34,6 +35,8 @@ public: | |||
34 | virtual ~Builder(); | 35 | virtual ~Builder(); |
35 | 36 | ||
36 | void load( const char *sFN ); | 37 | void load( const char *sFN ); |
38 | void build( const char *sAct=NULL ); | ||
39 | void execute( Action *pAct ); | ||
37 | 40 | ||
38 | //void error( const yy::location &l, const std::string &m ); | 41 | //void error( const yy::location &l, const std::string &m ); |
39 | //void error( const std::string &m ); | 42 | //void error( const std::string &m ); |
@@ -46,7 +49,19 @@ public: | |||
46 | void add( Target *pTarg ); | 49 | void add( Target *pTarg ); |
47 | void varSet( const char *sName, const char *sValue ); | 50 | void varSet( const char *sName, const char *sValue ); |
48 | void varAddSet( const char *sName, const char *sValue ); | 51 | void varAddSet( const char *sName, const char *sValue ); |
52 | Rule *getRule( const char *sName ); | ||
53 | std::list<Rule *> findRuleChain( Rule *pRule ); | ||
54 | void processRequires( std::list<std::string> &lInput ); | ||
49 | void requires( const char *sBase, const char *sReq ); | 55 | void requires( const char *sBase, const char *sReq ); |
56 | void requiresFromCommand( const char *sBase, const char *sReq ); | ||
57 | void requiresRegexp( bool on ) | ||
58 | { | ||
59 | bReqRegexp = on; | ||
60 | } | ||
61 | bool isRequiresRegexp() | ||
62 | { | ||
63 | return bReqRegexp; | ||
64 | } | ||
50 | void setContext( const char *sCont ); | 65 | void setContext( const char *sCont ); |
51 | void setContext(); | 66 | void setContext(); |
52 | 67 | ||
@@ -77,10 +92,26 @@ public: | |||
77 | return sTmp; | 92 | return sTmp; |
78 | } | 93 | } |
79 | 94 | ||
95 | Target *getTarget( const char *sName ) | ||
96 | { | ||
97 | if( mTarget.find( sName ) == mTarget.end() ) | ||
98 | throw BuildException("Target %s not found.", sName ); | ||
99 | |||
100 | return mTarget[sName]; | ||
101 | } | ||
102 | |||
80 | private: | 103 | private: |
104 | typedef std::map<std::string, std::string> varmap; | ||
105 | |||
106 | void requiresNormal( const char *sBase, const char *sReq ); | ||
107 | void requiresRegexp( const char *sBase, const char *sReq ); | ||
81 | void checkVar( const char *cont, const char *sName ); | 108 | void checkVar( const char *cont, const char *sName ); |
82 | void scanBegin(); | 109 | void scanBegin(); |
83 | void scanEnd(); | 110 | void scanEnd(); |
111 | varmap *regexVars( RegExp *re ); | ||
112 | |||
113 | bool hasVar( varmap *pMap, std::string &var ); | ||
114 | std::string varRepl( const char *sSrc, const char *cont, varmap *mExtra ); | ||
84 | 115 | ||
85 | Action *pDefaultAction; | 116 | Action *pDefaultAction; |
86 | Action *pLastAddedAction; | 117 | Action *pLastAddedAction; |
@@ -92,14 +123,20 @@ private: | |||
92 | Target *pLastAddedTarget; | 123 | Target *pLastAddedTarget; |
93 | std::map<const char *, Target *, ltstr> mTarget; | 124 | std::map<const char *, Target *, ltstr> mTarget; |
94 | 125 | ||
95 | typedef std::map<std::string, std::string> varmap; | ||
96 | varmap mVar; | 126 | varmap mVar; |
127 | |||
97 | std::map<std::string, std::list<std::string> *> mRequires; | 128 | std::map<std::string, std::list<std::string> *> mRequires; |
98 | 129 | ||
130 | typedef std::list<std::pair<RegExp *, std::string> > regreqlist; | ||
131 | regreqlist lRequiresRegexp; | ||
132 | regreqlist lRequiresRegexpCommand; | ||
133 | |||
99 | std::map<std::string, varmap> mContVar; | 134 | std::map<std::string, varmap> mContVar; |
100 | StaticString sContext; | 135 | StaticString sContext; |
101 | 136 | ||
102 | StaticString sTmp; | 137 | StaticString sTmp; |
138 | |||
139 | bool bReqRegexp; | ||
103 | }; | 140 | }; |
104 | 141 | ||
105 | #endif | 142 | #endif |
diff --git a/src/command.cpp b/src/command.cpp index 72f9a4c..ea5ade3 100644 --- a/src/command.cpp +++ b/src/command.cpp | |||
@@ -1,4 +1,6 @@ | |||
1 | #include "command.h" | 1 | #include "command.h" |
2 | #include "builder.h" | ||
3 | #include "target.h" | ||
2 | 4 | ||
3 | Command::Command( CmdType cmd, const char *sTarget ) : | 5 | Command::Command( CmdType cmd, const char *sTarget ) : |
4 | nType( cmd ), | 6 | nType( cmd ), |
@@ -16,3 +18,17 @@ void Command::debug() | |||
16 | printf(" command: %s %s\n", cmdt[ nType ], sTarget.getString() ); | 18 | printf(" command: %s %s\n", cmdt[ nType ], sTarget.getString() ); |
17 | } | 19 | } |
18 | 20 | ||
21 | void Command::execute( Builder &bld ) | ||
22 | { | ||
23 | switch( nType ) | ||
24 | { | ||
25 | case cmdCheck: | ||
26 | bld.getTarget( sTarget )->check( bld ); | ||
27 | break; | ||
28 | |||
29 | case cmdClean: | ||
30 | bld.getTarget( sTarget )->clean( bld ); | ||
31 | break; | ||
32 | } | ||
33 | } | ||
34 | |||
diff --git a/src/command.h b/src/command.h index aa00eae..495c749 100644 --- a/src/command.h +++ b/src/command.h | |||
@@ -4,6 +4,8 @@ | |||
4 | #include <stdint.h> | 4 | #include <stdint.h> |
5 | #include "staticstring.h" | 5 | #include "staticstring.h" |
6 | 6 | ||
7 | class Builder; | ||
8 | |||
7 | class Command | 9 | class Command |
8 | { | 10 | { |
9 | public: | 11 | public: |
@@ -29,6 +31,8 @@ public: | |||
29 | 31 | ||
30 | void debug(); | 32 | void debug(); |
31 | 33 | ||
34 | void execute( class Builder &bld ); | ||
35 | |||
32 | private: | 36 | private: |
33 | CmdType nType; | 37 | CmdType nType; |
34 | StaticString sTarget; | 38 | StaticString sTarget; |
diff --git a/src/filetarget.cpp b/src/filetarget.cpp index b9d7946..65f9d70 100644 --- a/src/filetarget.cpp +++ b/src/filetarget.cpp | |||
@@ -1,4 +1,9 @@ | |||
1 | #include <errno.h> | ||
2 | #include <dirent.h> | ||
3 | |||
4 | #include "rule.h" | ||
1 | #include "filetarget.h" | 5 | #include "filetarget.h" |
6 | #include "builder.h" // for BuildException | ||
2 | 7 | ||
3 | FileTarget::FileTarget( const char *sName ) : | 8 | FileTarget::FileTarget( const char *sName ) : |
4 | Target( sName ) | 9 | Target( sName ) |
@@ -15,3 +20,63 @@ void FileTarget::debug() | |||
15 | printf(" type: FileTarget\n"); | 20 | printf(" type: FileTarget\n"); |
16 | } | 21 | } |
17 | 22 | ||
23 | char *gnu_getcwd() | ||
24 | { | ||
25 | size_t size = 1024; | ||
26 | |||
27 | while (1) | ||
28 | { | ||
29 | char *buffer = new char[size]; | ||
30 | if (getcwd (buffer, size) == buffer) | ||
31 | return buffer; | ||
32 | delete[] buffer; | ||
33 | if (errno != ERANGE) | ||
34 | return 0; | ||
35 | size *= 2; | ||
36 | } | ||
37 | } | ||
38 | |||
39 | void FileTarget::addInputDir( const char *sDir ) | ||
40 | { | ||
41 | DIR *dir = opendir( sDir ); | ||
42 | if( dir == NULL ) | ||
43 | { | ||
44 | throw BuildException( strerror( errno ) ); | ||
45 | } | ||
46 | |||
47 | char *cwd = gnu_getcwd(); | ||
48 | std::string base( cwd ); | ||
49 | base += "/"; | ||
50 | base += sDir; | ||
51 | delete[] cwd; | ||
52 | |||
53 | struct dirent *de; | ||
54 | |||
55 | while( (de = readdir( dir )) ) | ||
56 | { | ||
57 | if( de->d_name[0] == '.' || de->d_name[0] == '\0' ) | ||
58 | continue; | ||
59 | |||
60 | std::string s( base ); | ||
61 | s += "/"; | ||
62 | s += de->d_name; | ||
63 | addInput( s.c_str() ); | ||
64 | } | ||
65 | |||
66 | closedir( dir ); | ||
67 | } | ||
68 | |||
69 | void FileTarget::check( Builder &bld ) | ||
70 | { | ||
71 | Rule *pRule = bld.getRule( sRule ); | ||
72 | |||
73 | std::list<std::string> tmp = pRule->execute( bld, lInput ); | ||
74 | lOutput.insert( lOutput.end(), tmp.begin(), tmp.end() ); | ||
75 | |||
76 | bld.processRequires( lInput ); | ||
77 | } | ||
78 | |||
79 | void FileTarget::clean( Builder &bld ) | ||
80 | { | ||
81 | } | ||
82 | |||
diff --git a/src/filetarget.h b/src/filetarget.h index cf4b3d6..11dc180 100644 --- a/src/filetarget.h +++ b/src/filetarget.h | |||
@@ -11,6 +11,11 @@ public: | |||
11 | virtual ~FileTarget(); | 11 | virtual ~FileTarget(); |
12 | 12 | ||
13 | virtual void debug(); | 13 | virtual void debug(); |
14 | |||
15 | void addInputDir( const char *sDir ); | ||
16 | |||
17 | virtual void check( class Builder &bld ); | ||
18 | virtual void clean( class Builder &bld ); | ||
14 | 19 | ||
15 | private: | 20 | private: |
16 | 21 | ||
diff --git a/src/main.cpp b/src/main.cpp index 995009d..2e13b16 100644 --- a/src/main.cpp +++ b/src/main.cpp | |||
@@ -4,10 +4,11 @@ int main() | |||
4 | { | 4 | { |
5 | Builder bld; | 5 | Builder bld; |
6 | 6 | ||
7 | bld.load("congo"); | 7 | bld.load("build.conf"); |
8 | 8 | ||
9 | printf("\n\n----------\nDebug dump\n----------\n"); | 9 | bld.build(); |
10 | 10 | ||
11 | printf("\n\n----------\nDebug dump\n----------\n"); | ||
11 | bld.debug(); | 12 | bld.debug(); |
12 | } | 13 | } |
13 | 14 | ||
diff --git a/src/regexp.cpp b/src/regexp.cpp new file mode 100644 index 0000000..ff2d09a --- /dev/null +++ b/src/regexp.cpp | |||
@@ -0,0 +1,71 @@ | |||
1 | #include "regexp.h" | ||
2 | #include "builder.h" // For BuildException | ||
3 | #include "staticstring.h" | ||
4 | |||
5 | RegExp::RegExp() : | ||
6 | bCompiled( false ), | ||
7 | aSubStr( NULL ) | ||
8 | { | ||
9 | } | ||
10 | |||
11 | RegExp::RegExp( const char *sSrc ) : | ||
12 | bCompiled( false ), | ||
13 | aSubStr( NULL ) | ||
14 | { | ||
15 | compile( sSrc ); | ||
16 | } | ||
17 | |||
18 | RegExp::~RegExp() | ||
19 | { | ||
20 | regfree( &re ); | ||
21 | delete[] aSubStr; | ||
22 | } | ||
23 | |||
24 | void RegExp::compile( const char *sSrc ) | ||
25 | { | ||
26 | if( bCompiled ) | ||
27 | throw BuildException("Already compiled."); | ||
28 | |||
29 | int nErr = regcomp( &re, sSrc, REG_EXTENDED|REG_NEWLINE ); | ||
30 | if( nErr ) | ||
31 | { | ||
32 | size_t length = regerror( nErr, &re, NULL, 0 ); | ||
33 | char *buffer = new char[length]; | ||
34 | (void) regerror( nErr, &re, buffer, length ); | ||
35 | StaticString s( buffer ); | ||
36 | delete[] buffer; | ||
37 | throw BuildException( s.getString() ); | ||
38 | } | ||
39 | bCompiled = true; | ||
40 | this->sSrc = sSrc; | ||
41 | |||
42 | nSubStr = re.re_nsub+1; | ||
43 | aSubStr = new regmatch_t[nSubStr]; | ||
44 | } | ||
45 | |||
46 | int RegExp::getNumSubStrings() | ||
47 | { | ||
48 | return nSubStr; | ||
49 | } | ||
50 | |||
51 | bool RegExp::execute( const char *sSrc ) | ||
52 | { | ||
53 | sTest = sSrc; | ||
54 | if( regexec( &re, sSrc, nSubStr, aSubStr, 0 ) ) | ||
55 | return false; | ||
56 | return true; | ||
57 | } | ||
58 | |||
59 | std::pair<int,int> RegExp::getSubStringRange( int nIndex ) | ||
60 | { | ||
61 | return std::pair<int,int>( aSubStr[nIndex].rm_so, aSubStr[nIndex].rm_eo ); | ||
62 | } | ||
63 | |||
64 | std::string RegExp::getSubString( int nIndex ) | ||
65 | { | ||
66 | return std::string( | ||
67 | sTest.getString()+aSubStr[nIndex].rm_so, | ||
68 | aSubStr[nIndex].rm_eo - aSubStr[nIndex].rm_so | ||
69 | ); | ||
70 | } | ||
71 | |||
diff --git a/src/regexp.h b/src/regexp.h new file mode 100644 index 0000000..96f3747 --- /dev/null +++ b/src/regexp.h | |||
@@ -0,0 +1,36 @@ | |||
1 | #ifndef REG_EXP_H | ||
2 | #define REG_EXP_H | ||
3 | |||
4 | #include <string> | ||
5 | #include <stdint.h> | ||
6 | #include <regex.h> | ||
7 | #include <utility> | ||
8 | #include "staticstring.h" | ||
9 | |||
10 | class RegExp | ||
11 | { | ||
12 | public: | ||
13 | RegExp(); | ||
14 | RegExp( const char *sSrc ); | ||
15 | virtual ~RegExp(); | ||
16 | |||
17 | void compile( const char *sSrc ); | ||
18 | int getNumSubStrings(); | ||
19 | bool execute( const char *sSrc ); | ||
20 | std::pair<int,int> getSubStringRange( int nIndex ); | ||
21 | std::string getSubString( int nIndex ); | ||
22 | const char *getSource() | ||
23 | { | ||
24 | return sSrc; | ||
25 | } | ||
26 | |||
27 | private: | ||
28 | StaticString sSrc; | ||
29 | StaticString sTest; | ||
30 | regex_t re; | ||
31 | bool bCompiled; | ||
32 | int nSubStr; | ||
33 | regmatch_t *aSubStr; | ||
34 | }; | ||
35 | |||
36 | #endif | ||
diff --git a/src/rule.cpp b/src/rule.cpp index a7ebf9b..a240855 100644 --- a/src/rule.cpp +++ b/src/rule.cpp | |||
@@ -2,8 +2,7 @@ | |||
2 | #include "builder.h" // for BuildException | 2 | #include "builder.h" // for BuildException |
3 | 3 | ||
4 | Rule::Rule( const char *sName ) : | 4 | Rule::Rule( const char *sName ) : |
5 | sName( sName ), | 5 | sName( sName ) |
6 | sProduces("{target}") | ||
7 | { | 6 | { |
8 | } | 7 | } |
9 | 8 | ||
@@ -14,11 +13,23 @@ Rule::~Rule() | |||
14 | 13 | ||
15 | void Rule::debug() | 14 | void Rule::debug() |
16 | { | 15 | { |
17 | printf(" Rule %s produces %s:\n", | 16 | printf(" Rule %s:\n", |
18 | sName.getString(), | 17 | sName.getString() |
19 | sProduces.getString() | ||
20 | ); | 18 | ); |
21 | printf(" Matches "); | 19 | printf(" Produces: "); |
20 | if( lProduces.empty() ) | ||
21 | printf("{target}"); | ||
22 | else | ||
23 | { | ||
24 | for( std::list<std::string>::iterator i = lProduces.begin(); | ||
25 | i != lProduces.end(); i++ ) | ||
26 | { | ||
27 | if( i != lProduces.begin() ) | ||
28 | printf(", "); | ||
29 | printf("%s", (*i).c_str() ); | ||
30 | } | ||
31 | } | ||
32 | printf("\n Matches "); | ||
22 | if( mHow == matchOne ) | 33 | if( mHow == matchOne ) |
23 | printf("one "); | 34 | printf("one "); |
24 | else if( mHow == matchAll ) | 35 | else if( mHow == matchAll ) |
@@ -31,9 +42,9 @@ void Rule::debug() | |||
31 | printf("\"%s\"\n", sPerfCmd.getString() ); | 42 | printf("\"%s\"\n", sPerfCmd.getString() ); |
32 | } | 43 | } |
33 | 44 | ||
34 | void Rule::setProduces( const char *sP ) | 45 | void Rule::addProduces( const char *sP ) |
35 | { | 46 | { |
36 | sProduces = sP; | 47 | lProduces.push_back( sP ); |
37 | } | 48 | } |
38 | 49 | ||
39 | void Rule::setMatches( Matches how, const char *sW ) | 50 | void Rule::setMatches( Matches how, const char *sW ) |
@@ -59,3 +70,13 @@ void Rule::setPerforms( Perform pwhat, const char *sperfcmd ) | |||
59 | sPerfCmd = sperfcmd; | 70 | sPerfCmd = sperfcmd; |
60 | } | 71 | } |
61 | 72 | ||
73 | std::list<std::string> Rule::execute( Builder &bld, std::list<std::string> lInput ) | ||
74 | { | ||
75 | std::list<Rule *> lRule = bld.findRuleChain( this ); | ||
76 | |||
77 | std::list<std::string> ret; | ||
78 | |||
79 | return ret; | ||
80 | |||
81 | } | ||
82 | |||
@@ -1,6 +1,8 @@ | |||
1 | #ifndef RULE_H | 1 | #ifndef RULE_H |
2 | #define RULE_H | 2 | #define RULE_H |
3 | 3 | ||
4 | #include <list> | ||
5 | #include <string> | ||
4 | #include <stdint.h> | 6 | #include <stdint.h> |
5 | #include <regex.h> | 7 | #include <regex.h> |
6 | #include "staticstring.h" | 8 | #include "staticstring.h" |
@@ -30,13 +32,15 @@ public: | |||
30 | 32 | ||
31 | void debug(); | 33 | void debug(); |
32 | 34 | ||
33 | void setProduces( const char *sProduces ); | 35 | void addProduces( const char *sProduces ); |
34 | void setMatches( Matches how, const char *sWhat ); | 36 | void setMatches( Matches how, const char *sWhat ); |
35 | void setPerforms( Perform pwhat, const char *sPerfCmd ); | 37 | void setPerforms( Perform pwhat, const char *sPerfCmd ); |
36 | 38 | ||
39 | std::list<std::string> execute( class Builder &bld, std::list<std::string> lInput ); | ||
40 | |||
37 | private: | 41 | private: |
38 | StaticString sName; | 42 | StaticString sName; |
39 | StaticString sProduces; | 43 | std::list<std::string> lProduces; |
40 | 44 | ||
41 | Matches mHow; | 45 | Matches mHow; |
42 | StaticString sWhat; | 46 | StaticString sWhat; |
diff --git a/src/target.cpp b/src/target.cpp index b0967bf..00d16b4 100644 --- a/src/target.cpp +++ b/src/target.cpp | |||
@@ -20,5 +20,21 @@ void Target::debug() | |||
20 | sName.getString(), | 20 | sName.getString(), |
21 | sRule.getString() | 21 | sRule.getString() |
22 | ); | 22 | ); |
23 | printf(" Input list:\n"); | ||
24 | for( std::list<std::string>::iterator i = lInput.begin(); | ||
25 | i != lInput.end(); i++ ) | ||
26 | { | ||
27 | printf(" %s\n", (*i).c_str() ); | ||
28 | } | ||
29 | } | ||
30 | |||
31 | void Target::addInput( const char *sInput ) | ||
32 | { | ||
33 | lInput.push_back( sInput ); | ||
34 | } | ||
35 | |||
36 | void Target::addOutput( const char *sOutput ) | ||
37 | { | ||
38 | lOutput.push_back( sOutput ); | ||
23 | } | 39 | } |
24 | 40 | ||
diff --git a/src/target.h b/src/target.h index 667c467..59c5d7e 100644 --- a/src/target.h +++ b/src/target.h | |||
@@ -1,6 +1,8 @@ | |||
1 | #ifndef TARGET_H | 1 | #ifndef TARGET_H |
2 | #define TARGET_H | 2 | #define TARGET_H |
3 | 3 | ||
4 | #include <list> | ||
5 | #include <string> | ||
4 | #include <stdint.h> | 6 | #include <stdint.h> |
5 | #include "staticstring.h" | 7 | #include "staticstring.h" |
6 | 8 | ||
@@ -19,10 +21,19 @@ public: | |||
19 | 21 | ||
20 | virtual void debug(); | 22 | virtual void debug(); |
21 | 23 | ||
22 | private: | 24 | void addInput( const char *sInput ); |
25 | void addOutput( const char *sOutput ); | ||
26 | |||
27 | virtual void check( class Builder &bld ) = 0; | ||
28 | virtual void clean( class Builder &bld ) = 0; | ||
29 | |||
30 | protected: | ||
23 | StaticString sName; | 31 | StaticString sName; |
24 | StaticString sRule; | 32 | StaticString sRule; |
25 | 33 | ||
34 | std::list<std::string> lInput; | ||
35 | std::list<std::string> lOutput; | ||
36 | |||
26 | }; | 37 | }; |
27 | 38 | ||
28 | #endif | 39 | #endif |