diff options
| -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 |
