From 73d53b0962cb19a6d2a7686de658a5540ab07017 Mon Sep 17 00:00:00 2001 From: Mike Buland Date: Mon, 31 Jul 2006 22:50:47 +0000 Subject: It almost builds, we need to get rid of duplicate list entries and actually store the commands somewhere so the target handler can decide if they need to be run. --- build.conf | 16 +++--- pymake.conf | 6 +-- src/builder.cpp | 20 +++++++- src/builder.h | 6 +-- src/filetarget.cpp | 8 +-- src/perform.cpp | 9 ++++ src/perform.h | 18 +++++++ src/performcmd.cpp | 19 ++++++++ src/performcmd.h | 22 +++++++++ src/rule.cpp | 141 +++++++++++++++++++++++++++++++++++++++++++++-------- src/rule.h | 23 ++++++--- src/target.cpp | 6 +++ 12 files changed, 250 insertions(+), 44 deletions(-) create mode 100644 src/perform.cpp create mode 100644 src/perform.h create mode 100644 src/performcmd.cpp create mode 100644 src/performcmd.h diff --git a/build.conf b/build.conf index b4792fb..9f6f5ab 100644 --- a/build.conf +++ b/build.conf @@ -7,16 +7,18 @@ create file build from files in src using rule exe set CXXFLAGS += "-Ilibbu++/src" set LDFLAGS += "-Llibbu++ -lbu++" +build requires src/libbu++/libbu++.a + /(.*)\.o/ requires from command "g++ {CXXFLAGS} -M {re:1}.c*" -rule exe matches all /(.*)\.o/ perform command ... - "g++ {LDFLAGS} -o {target} {matches}" +rule exe matches all /(.*)\.o$/ perform command ... + "g++ {match} {LDFLAGS} -o {target}" -rule cpp matches one /(.*)\.c(pp)?/ produces {1}.o perform command ... - "g++ {CXXFLAGS} -o {target} {match}" +rule cpp matches one /(.*)\.c(pp)?$/ produces "{re:1}.o" perform command ... + "g++ {CXXFLAGS} -c -o {target} {match}" -rule bison matches one /(.*)\.y/ produces {1}.tab.c, {1}.tab.h perform ... - command "bison {match}" +rule bison matches one /(.*)\.y$/ produces "{re:1}.tab.c", "{re:1}.tab.h" ... + perform command "bison {match}" -rule flex matches one /(.*)\.l/ produces {1}.yy.c perform ... +rule flex matches one /(.*)\.l$/ produces "{re:1}.yy.c" perform ... command "flex --bison-bridge --bison-locations -o {target} {match}" diff --git a/pymake.conf b/pymake.conf index 4775d78..a941a7c 100644 --- a/pymake.conf +++ b/pymake.conf @@ -68,14 +68,14 @@ COMMAND: g++ -c {INPUT} {CXXFLAGS} -I{DIR} -o {OUTPUT} CHECK: g++ -M {INPUT} {CXXFLAGS} -I{DIR} [TRIGGER] -INPUT .y +INPUT: .y OUTPUT: .tab.c COMMAND: bison {INPUT} [TRIGGER] -INPUT .l +INPUT: .l OUTPUT: .yy.c -COMMAND: flex --bison-bridge -o {OUTPUT} {INPUT} +COMMAND: flex --bison-bridge --bison-locations -o {OUTPUT} {INPUT} ### Executable command ### ## Use this command if you want a simple executable diff --git a/src/builder.cpp b/src/builder.cpp index 8e29c81..852d70d 100644 --- a/src/builder.cpp +++ b/src/builder.cpp @@ -132,18 +132,24 @@ void Builder::debug() } } - printf("Additional dependancies:\n"); + printf("Dependancies:\n"); for( std::map *>::iterator i = mRequires.begin(); i != mRequires.end(); i++ ) { printf(" %s: ", (*i).first.c_str() ); std::list *pList = (*i).second; + int i = 0; for( std::list::iterator j = pList->begin(); j != pList->end(); j++ ) { if( j != pList->begin() ) printf(", "); printf("%s", (*j).c_str() ); + if( i++ >= 3 ) + { + printf("..."); + break; + } } printf("\n"); } @@ -443,6 +449,18 @@ std::list Builder::findRuleChain( Rule *pRule ) { std::list ret; + for( std::map::iterator i = mRule.begin(); + i != mRule.end(); i++ ) + { + if( pRule == (*i).second ) + continue; + + if( pRule->willChain( (*i).second ) ) + { + ret.push_back( (*i).second ); + } + } + return ret; } diff --git a/src/builder.h b/src/builder.h index d7c0891..faa82c2 100644 --- a/src/builder.h +++ b/src/builder.h @@ -100,18 +100,18 @@ public: return mTarget[sName]; } -private: typedef std::map varmap; + varmap *regexVars( RegExp *re ); + std::string varRepl( const char *sSrc, const char *cont, varmap *mExtra ); +private: void requiresNormal( const char *sBase, const char *sReq ); void requiresRegexp( const char *sBase, const char *sReq ); void checkVar( const char *cont, const char *sName ); void scanBegin(); void scanEnd(); - varmap *regexVars( RegExp *re ); bool hasVar( varmap *pMap, std::string &var ); - std::string varRepl( const char *sSrc, const char *cont, varmap *mExtra ); Action *pDefaultAction; Action *pLastAddedAction; diff --git a/src/filetarget.cpp b/src/filetarget.cpp index 65f9d70..3fefd9f 100644 --- a/src/filetarget.cpp +++ b/src/filetarget.cpp @@ -45,9 +45,10 @@ void FileTarget::addInputDir( const char *sDir ) } char *cwd = gnu_getcwd(); - std::string base( cwd ); - base += "/"; + std::string base;//( cwd ); + //base += "/"; base += sDir; + base += "/"; delete[] cwd; struct dirent *de; @@ -58,7 +59,6 @@ void FileTarget::addInputDir( const char *sDir ) continue; std::string s( base ); - s += "/"; s += de->d_name; addInput( s.c_str() ); } @@ -70,7 +70,7 @@ void FileTarget::check( Builder &bld ) { Rule *pRule = bld.getRule( sRule ); - std::list tmp = pRule->execute( bld, lInput ); + std::list tmp = pRule->execute( bld, lInput, getName() ); lOutput.insert( lOutput.end(), tmp.begin(), tmp.end() ); bld.processRequires( lInput ); diff --git a/src/perform.cpp b/src/perform.cpp new file mode 100644 index 0000000..937a76c --- /dev/null +++ b/src/perform.cpp @@ -0,0 +1,9 @@ +#include "perform.h" + +Perform::Perform() +{ +} + +Perform::~Perform() +{ +} diff --git a/src/perform.h b/src/perform.h new file mode 100644 index 0000000..fefb05e --- /dev/null +++ b/src/perform.h @@ -0,0 +1,18 @@ +#ifndef PERFORM_H +#define PERFORM_H + +#include + +class Perform +{ +public: + Perform(); + virtual ~Perform(); + + virtual void execute( class Builder &bld ) = 0; + +private: + +}; + +#endif diff --git a/src/performcmd.cpp b/src/performcmd.cpp new file mode 100644 index 0000000..21ba737 --- /dev/null +++ b/src/performcmd.cpp @@ -0,0 +1,19 @@ +#include "performcmd.h" +#include "builder.h" + +PerformCmd::PerformCmd( const char *sCmd, const char *sTarget ) : + sCommand( sCmd ), + sTarget( sTarget ) +{ +} + +PerformCmd::~PerformCmd() +{ +} + +void PerformCmd::execute( class Builder &bld ) +{ + printf("%s\n", sCommand.getString() ); + system( sCommand.getString() ); +} + diff --git a/src/performcmd.h b/src/performcmd.h new file mode 100644 index 0000000..3bc83aa --- /dev/null +++ b/src/performcmd.h @@ -0,0 +1,22 @@ +#ifndef PERFORM_CMD_H +#define PERFORM_CMD_H + +#include + +#include "perform.h" +#include "staticstring.h" + +class PerformCmd : public Perform +{ +public: + PerformCmd( const char *sCmd, const char *sTarget ); + virtual ~PerformCmd(); + + virtual void execute( class Builder &bld ); + +private: + StaticString sCommand; + StaticString sTarget; +}; + +#endif diff --git a/src/rule.cpp b/src/rule.cpp index a240855..4425ea5 100644 --- a/src/rule.cpp +++ b/src/rule.cpp @@ -1,14 +1,17 @@ #include "rule.h" +#include "perform.h" +#include "performcmd.h" #include "builder.h" // for BuildException Rule::Rule( const char *sName ) : - sName( sName ) + sName( sName ), + bNoProduces( true ) { + lProduces.push_back("{target}"); } Rule::~Rule() { - regfree( &rWhat ); } void Rule::debug() @@ -34,7 +37,7 @@ void Rule::debug() printf("one "); else if( mHow == matchAll ) printf("all "); - printf("/%s/\n", sWhat.getString() ); + printf("/%s/\n", rWhat.getSource() ); printf(" Performs "); if( pHow == perfCommand ) @@ -44,39 +47,139 @@ void Rule::debug() void Rule::addProduces( const char *sP ) { + if( bNoProduces ) + { + lProduces.clear(); + bNoProduces = false; + } lProduces.push_back( sP ); } void Rule::setMatches( Matches how, const char *sW ) { - sWhat = sW; + rWhat.compile( sW ); mHow = how; - - int nErr = regcomp( &rWhat, sW, REG_EXTENDED|REG_NEWLINE ); - if( nErr ) - { - size_t length = regerror( nErr, &rWhat, NULL, 0 ); - char *buffer = new char[length]; - (void) regerror( nErr, &rWhat, buffer, length ); - StaticString s( buffer ); - delete[] buffer; - throw BuildException( s.getString() ); - } } -void Rule::setPerforms( Perform pwhat, const char *sperfcmd ) +void Rule::setPerforms( ePerform pwhat, const char *sperfcmd ) { pHow = pwhat; sPerfCmd = sperfcmd; } -std::list Rule::execute( Builder &bld, std::list lInput ) +Perform *Rule::buildCommand( Builder &bld, const char *sCmd, const char *sTarget, const char *sMatches ) +{ + Builder::varmap vars; + vars["target"] = sTarget; + vars["match"] = sMatches; + return new PerformCmd( bld.varRepl( sCmd, "", &vars ).c_str(), sTarget ); +} + +std::list Rule::findTargets( Builder &bld, std::list &lIn, std::string &sMatches, const char *sTarget ) +{ + std::list lTmp; + + for( std::list::iterator i = lIn.begin(); + i != lIn.end(); i++ ) + { + if( rWhat.execute( (*i).c_str() ) ) + { + Builder::varmap *revars = bld.regexVars( &rWhat ); + for( std::list::iterator j = lProduces.begin(); + j != lProduces.end(); j++ ) + { + if( mHow == matchOne ) + { + lTmp.push_back( + bld.varRepl( + (*j).c_str(), + "", + revars + ) + ); + Perform *p = buildCommand( + bld, + sPerfCmd, + (sTarget==NULL)?(lTmp.back().c_str()):(sTarget), + (*i).c_str() + ); + p->execute( bld ); + delete p; + } + else if( mHow == matchAll ) + { + sMatches += " "; + sMatches += (*i); + } + } + delete revars; + } + } + + return lTmp; +} + +std::list Rule::execute( Builder &bld, std::list lInput, const char *sTarget ) { std::list lRule = bld.findRuleChain( this ); - std::list ret; + if( !lRule.empty() ) + { + printf("Rule %s chains to: ", sName.getString() ); + for( std::list::iterator i = lRule.begin(); + i != lRule.end(); i++ ) + { + if( i != lRule.begin() ) + printf(", "); + printf("%s", (*i)->sName.getString() ); + } + printf("\n"); + } + + std::list lOutput; + std::string sMatches; + + for( std::list::iterator i = lRule.begin(); i != lRule.end(); i++ ) + { + std::list lTmp = (*i)->execute( bld, lInput ); + lOutput.insert( lOutput.end(), lTmp.begin(), lTmp.end() ); + } + + std::list lTmp = findTargets( bld, lInput, sMatches, sTarget ); + lOutput.insert( lOutput.end(), lTmp.begin(), lTmp.end() ); + lTmp = findTargets( bld, lOutput, sMatches, sTarget ); + lOutput.insert( lOutput.end(), lTmp.begin(), lTmp.end() ); - return ret; + if( mHow == matchAll ) + { + lOutput.push_back( + bld.varRepl( + sTarget, + "", + NULL + ) + ); + Perform *p = buildCommand( + bld, + sPerfCmd, + sTarget, + sMatches.c_str() + ); + p->execute( bld ); + } + + return lOutput; +} + +bool Rule::willChain( Rule *pRule ) +{ + for( std::list::iterator i = pRule->lProduces.begin(); + i != pRule->lProduces.end(); i++ ) + { + if( rWhat.execute( (*i).c_str() ) ) + return true; + } + return false; } diff --git a/src/rule.h b/src/rule.h index 8371649..8246cc9 100644 --- a/src/rule.h +++ b/src/rule.h @@ -4,9 +4,11 @@ #include #include #include -#include +#include "regexp.h" #include "staticstring.h" +class Perform; + class Rule { public: @@ -16,7 +18,7 @@ public: matchAll }; - enum Perform + enum ePerform { perfCommand }; @@ -34,20 +36,27 @@ public: void addProduces( const char *sProduces ); void setMatches( Matches how, const char *sWhat ); - void setPerforms( Perform pwhat, const char *sPerfCmd ); + void setPerforms( ePerform pwhat, const char *sPerfCmd ); + + bool willChain( Rule *pRule ); - std::list execute( class Builder &bld, std::list lInput ); + std::list execute( class Builder &bld, std::list lInput, const char *sTarget=NULL ); private: + class Perform *buildCommand( class Builder &bld, const char *sCmd, const char *sTarget, const char *sMatches ); + std::list findTargets( class Builder &bld, std::list &lIn, std::string &sMatches, const char *sTarget ); StaticString sName; std::list lProduces; Matches mHow; - StaticString sWhat; - regex_t rWhat; + RegExp rWhat; + //StaticString sWhat; + //regex_t rWhat; - Perform pHow; + ePerform pHow; StaticString sPerfCmd; + + bool bNoProduces; }; #endif diff --git a/src/target.cpp b/src/target.cpp index 00d16b4..8f4cc4b 100644 --- a/src/target.cpp +++ b/src/target.cpp @@ -26,6 +26,12 @@ void Target::debug() { printf(" %s\n", (*i).c_str() ); } + printf(" Output list:\n"); + for( std::list::iterator i = lOutput.begin(); + i != lOutput.end(); i++ ) + { + printf(" %s\n", (*i).c_str() ); + } } void Target::addInput( const char *sInput ) -- cgit v1.2.3