diff options
| author | Mike Buland <eichlan@xagasoft.com> | 2006-08-05 00:04:34 +0000 |
|---|---|---|
| committer | Mike Buland <eichlan@xagasoft.com> | 2006-08-05 00:04:34 +0000 |
| commit | 8dd79b7b5a0309f9bc1185019a4af16b3b52aece (patch) | |
| tree | a703325cb9bc074179aeaf38f4851a4c38ebfd87 /src | |
| parent | 13bda5d4f77ca469bbbe0d9b1f268682a9f0ec71 (diff) | |
| download | build-8dd79b7b5a0309f9bc1185019a4af16b3b52aece.tar.gz build-8dd79b7b5a0309f9bc1185019a4af16b3b52aece.tar.bz2 build-8dd79b7b5a0309f9bc1185019a4af16b3b52aece.tar.xz build-8dd79b7b5a0309f9bc1185019a4af16b3b52aece.zip | |
Build now uses a cachefile for all of it's requires that are generated from
other means (running other programs). It's really fast, and seems to work
pretty well.
Diffstat (limited to 'src')
| -rw-r--r-- | src/builder.cpp | 113 | ||||
| -rw-r--r-- | src/builder.h | 9 | ||||
| -rw-r--r-- | src/cache.cpp | 78 | ||||
| -rw-r--r-- | src/cache.h | 33 | ||||
| -rw-r--r-- | src/filetarget.cpp | 5 | ||||
| -rw-r--r-- | src/main.cpp | 27 |
6 files changed, 193 insertions, 72 deletions
diff --git a/src/builder.cpp b/src/builder.cpp index d3cb2c0..a21bc99 100644 --- a/src/builder.cpp +++ b/src/builder.cpp | |||
| @@ -7,6 +7,8 @@ | |||
| 7 | #include "build.tab.h" | 7 | #include "build.tab.h" |
| 8 | #include "rule.h" | 8 | #include "rule.h" |
| 9 | #include "viewer.h" | 9 | #include "viewer.h" |
| 10 | #include "cache.h" | ||
| 11 | #include "serializerbinary.h" | ||
| 10 | 12 | ||
| 11 | subExceptionDef( BuildException ) | 13 | subExceptionDef( BuildException ) |
| 12 | 14 | ||
| @@ -21,6 +23,18 @@ Builder::Builder( Viewer &rView ) : | |||
| 21 | 23 | ||
| 22 | Builder::~Builder() | 24 | Builder::~Builder() |
| 23 | { | 25 | { |
| 26 | if( sCacheFile.getLength() > 0 ) | ||
| 27 | { | ||
| 28 | try | ||
| 29 | { | ||
| 30 | SerializerBinary ar( sCacheFile, Serializer::save ); | ||
| 31 | |||
| 32 | ar << cRequires; | ||
| 33 | } | ||
| 34 | catch( ExceptionBase &e ) | ||
| 35 | { | ||
| 36 | } | ||
| 37 | } | ||
| 24 | } | 38 | } |
| 25 | 39 | ||
| 26 | void yyparse( Builder &bld ); | 40 | void yyparse( Builder &bld ); |
| @@ -53,6 +67,21 @@ void Builder::build( const char *sAct ) | |||
| 53 | rView.endAction(); | 67 | rView.endAction(); |
| 54 | } | 68 | } |
| 55 | 69 | ||
| 70 | void Builder::setCache( const std::string &sFile ) | ||
| 71 | { | ||
| 72 | sCacheFile = sFile.c_str(); | ||
| 73 | |||
| 74 | try | ||
| 75 | { | ||
| 76 | SerializerBinary ar( sCacheFile, Serializer::load ); | ||
| 77 | |||
| 78 | ar >> cRequires; | ||
| 79 | } | ||
| 80 | catch( ExceptionBase &e ) | ||
| 81 | { | ||
| 82 | } | ||
| 83 | } | ||
| 84 | |||
| 56 | void Builder::execute( Action *pAct ) | 85 | void Builder::execute( Action *pAct ) |
| 57 | { | 86 | { |
| 58 | pAct->execute( *this ); | 87 | pAct->execute( *this ); |
| @@ -247,75 +276,31 @@ void Builder::processRequires( std::list<std::string> &lInput ) | |||
| 247 | } | 276 | } |
| 248 | } | 277 | } |
| 249 | 278 | ||
| 250 | // These are only done on request now, they were too expensive | 279 | } |
| 251 | /* | 280 | |
| 252 | for( regreqlist::iterator i = lRequiresRegexpCommand.begin(); | 281 | void Builder::genRequiresFor( const char *sName, time_t tNewTime ) |
| 253 | i != lRequiresRegexpCommand.end(); i++ ) | 282 | { |
| 283 | Cache::Entry *ent = cRequires.get( sName ); | ||
| 284 | if( ent && tNewTime > 0 ) | ||
| 254 | { | 285 | { |
| 255 | RegExp *re = (*i).first; | 286 | if( ent->tCreated >= tNewTime ) |
| 256 | for( std::list<std::string>::iterator j = lInput.begin(); | ||
| 257 | j != lInput.end(); j++ ) | ||
| 258 | { | 287 | { |
| 259 | if( re->execute( (*j).c_str() ) ) | 288 | for( std::list<std::string>::iterator i = ent->lData.begin(); |
| 289 | i != ent->lData.end(); i++ ) | ||
| 260 | { | 290 | { |
| 261 | varmap *revars = regexVars( re ); | 291 | requiresNormal( |
| 262 | std::string s = varRepl( (*i).second.c_str(), "", revars ); | 292 | sName, |
| 263 | FILE *fcmd = popen( s.c_str(), "r" ); | 293 | (*i).c_str() |
| 264 | std::string rhs; | 294 | ); |
| 265 | bool bHeader = true; | ||
| 266 | for(;;) | ||
| 267 | { | ||
| 268 | if( feof( fcmd ) ) | ||
| 269 | break; | ||
| 270 | int cc = fgetc( fcmd ); | ||
| 271 | if( cc == EOF ) | ||
| 272 | break; | ||
| 273 | unsigned char c = cc; | ||
| 274 | if( bHeader ) | ||
| 275 | { | ||
| 276 | if( c == ':' ) | ||
| 277 | bHeader = false; | ||
| 278 | } | ||
| 279 | else | ||
| 280 | { | ||
| 281 | if( c == ' ' || c == '\t' ) | ||
| 282 | { | ||
| 283 | if( rhs != "" ) | ||
| 284 | { | ||
| 285 | requiresNormal( | ||
| 286 | (*j).c_str(), | ||
| 287 | rhs.c_str() | ||
| 288 | ); | ||
| 289 | rhs = ""; | ||
| 290 | } | ||
| 291 | } | ||
| 292 | else | ||
| 293 | { | ||
| 294 | if( c == '\\' ) | ||
| 295 | c = fgetc( fcmd ); | ||
| 296 | if( c != '\n' ) | ||
| 297 | rhs += c; | ||
| 298 | } | ||
| 299 | } | ||
| 300 | } | ||
| 301 | if( rhs != "" ) | ||
| 302 | { | ||
| 303 | requiresNormal( | ||
| 304 | (*j).c_str(), | ||
| 305 | rhs.c_str() | ||
| 306 | ); | ||
| 307 | rhs = ""; | ||
| 308 | } | ||
| 309 | pclose( fcmd ); | ||
| 310 | delete revars; | ||
| 311 | } | 295 | } |
| 296 | |||
| 297 | return; | ||
| 312 | } | 298 | } |
| 313 | } | 299 | } |
| 314 | */ | ||
| 315 | } | ||
| 316 | 300 | ||
| 317 | void Builder::genRequiresFor( const char *sName ) | 301 | ent = new Cache::Entry; |
| 318 | { | 302 | ent->tCreated = tNewTime; |
| 303 | |||
| 319 | for( regreqlist::iterator i = lRequiresRegexpCommand.begin(); | 304 | for( regreqlist::iterator i = lRequiresRegexpCommand.begin(); |
| 320 | i != lRequiresRegexpCommand.end(); i++ ) | 305 | i != lRequiresRegexpCommand.end(); i++ ) |
| 321 | { | 306 | { |
| @@ -352,6 +337,7 @@ void Builder::genRequiresFor( const char *sName ) | |||
| 352 | sName, | 337 | sName, |
| 353 | rhs.c_str() | 338 | rhs.c_str() |
| 354 | ); | 339 | ); |
| 340 | ent->lData.push_back( rhs ); | ||
| 355 | rhs = ""; | 341 | rhs = ""; |
| 356 | } | 342 | } |
| 357 | } | 343 | } |
| @@ -370,6 +356,7 @@ void Builder::genRequiresFor( const char *sName ) | |||
| 370 | sName, | 356 | sName, |
| 371 | rhs.c_str() | 357 | rhs.c_str() |
| 372 | ); | 358 | ); |
| 359 | ent->lData.push_back( rhs ); | ||
| 373 | rhs = ""; | 360 | rhs = ""; |
| 374 | } | 361 | } |
| 375 | pclose( fcmd ); | 362 | pclose( fcmd ); |
| @@ -377,6 +364,8 @@ void Builder::genRequiresFor( const char *sName ) | |||
| 377 | rView.endExtraRequiresCheck(); | 364 | rView.endExtraRequiresCheck(); |
| 378 | } | 365 | } |
| 379 | } | 366 | } |
| 367 | |||
| 368 | cRequires.put( sName, ent ); | ||
| 380 | } | 369 | } |
| 381 | 370 | ||
| 382 | std::map<std::string, std::string> *Builder::regexVars( RegExp *re ) | 371 | std::map<std::string, std::string> *Builder::regexVars( RegExp *re ) |
diff --git a/src/builder.h b/src/builder.h index 06e84f3..56a7b07 100644 --- a/src/builder.h +++ b/src/builder.h | |||
| @@ -8,6 +8,7 @@ | |||
| 8 | #include "exceptionbase.h" | 8 | #include "exceptionbase.h" |
| 9 | #include "staticstring.h" | 9 | #include "staticstring.h" |
| 10 | #include "regexp.h" | 10 | #include "regexp.h" |
| 11 | #include "cache.h" | ||
| 11 | 12 | ||
| 12 | subExceptionDecl( BuildException ) | 13 | subExceptionDecl( BuildException ) |
| 13 | 14 | ||
| @@ -17,6 +18,7 @@ class Command; | |||
| 17 | class Rule; | 18 | class Rule; |
| 18 | class Target; | 19 | class Target; |
| 19 | class Viewer; | 20 | class Viewer; |
| 21 | class Cache; | ||
| 20 | 22 | ||
| 21 | #define YY_DECL int yylex( YYSTYPE *yylval_param, YYLTYPE *yylloc_param, Builder &bld ) | 23 | #define YY_DECL int yylex( YYSTYPE *yylval_param, YYLTYPE *yylloc_param, Builder &bld ) |
| 22 | YY_DECL; | 24 | YY_DECL; |
| @@ -48,6 +50,8 @@ public: | |||
| 48 | { | 50 | { |
| 49 | return rView; | 51 | return rView; |
| 50 | } | 52 | } |
| 53 | |||
| 54 | void setCache( const std::string &sFile ); | ||
| 51 | void add( Action *pAct ); | 55 | void add( Action *pAct ); |
| 52 | void add( Command *pCmd ); | 56 | void add( Command *pCmd ); |
| 53 | void add( Rule *pRule ); | 57 | void add( Rule *pRule ); |
| @@ -59,7 +63,7 @@ public: | |||
| 59 | void processRequires( std::list<std::string> &lInput ); | 63 | void processRequires( std::list<std::string> &lInput ); |
| 60 | void requires( const char *sBase, const char *sReq ); | 64 | void requires( const char *sBase, const char *sReq ); |
| 61 | void requiresFromCommand( const char *sBase, const char *sReq ); | 65 | void requiresFromCommand( const char *sBase, const char *sReq ); |
| 62 | void genRequiresFor( const char *sName ); | 66 | void genRequiresFor( const char *sName, time_t tNewTime ); |
| 63 | void requiresRegexp( bool on ) | 67 | void requiresRegexp( bool on ) |
| 64 | { | 68 | { |
| 65 | bReqRegexp = on; | 69 | bReqRegexp = on; |
| @@ -152,6 +156,9 @@ private: | |||
| 152 | bool bReqRegexp; | 156 | bool bReqRegexp; |
| 153 | 157 | ||
| 154 | Viewer &rView; | 158 | Viewer &rView; |
| 159 | |||
| 160 | StaticString sCacheFile; | ||
| 161 | class Cache cRequires; | ||
| 155 | }; | 162 | }; |
| 156 | 163 | ||
| 157 | void cleanList( std::list<std::string> &lst ); | 164 | void cleanList( std::list<std::string> &lst ); |
diff --git a/src/cache.cpp b/src/cache.cpp new file mode 100644 index 0000000..43e69dc --- /dev/null +++ b/src/cache.cpp | |||
| @@ -0,0 +1,78 @@ | |||
| 1 | #include "cache.h" | ||
| 2 | #include "serializer.h" | ||
| 3 | |||
| 4 | Cache::Cache() | ||
| 5 | { | ||
| 6 | } | ||
| 7 | |||
| 8 | Cache::~Cache() | ||
| 9 | { | ||
| 10 | for( std::map<std::string, Entry *>::iterator i = mCache.begin(); | ||
| 11 | i != mCache.end(); i++ ) | ||
| 12 | { | ||
| 13 | delete (*i).second; | ||
| 14 | } | ||
| 15 | } | ||
| 16 | |||
| 17 | void Cache::serialize( class Serializer &ar ) | ||
| 18 | { | ||
| 19 | if( ar.isLoading() ) | ||
| 20 | { | ||
| 21 | int sCache, sData; | ||
| 22 | ar >> sCache; | ||
| 23 | std::string sTmp; | ||
| 24 | |||
| 25 | for( int i = 0; i < sCache; i++ ) | ||
| 26 | { | ||
| 27 | Entry *e = new Entry; | ||
| 28 | ar >> e->tCreated; | ||
| 29 | ar >> sData; | ||
| 30 | std::list<std::string> &lData = e->lData; | ||
| 31 | for( int j = 0; j < sData; j++ ) | ||
| 32 | { | ||
| 33 | ar >> sTmp; | ||
| 34 | lData.push_back( sTmp ); | ||
| 35 | } | ||
| 36 | ar >> sTmp; | ||
| 37 | mCache[sTmp] = e; | ||
| 38 | } | ||
| 39 | } | ||
| 40 | else | ||
| 41 | { | ||
| 42 | ar << mCache.size(); | ||
| 43 | for( std::map<std::string, Entry *>::iterator i = mCache.begin(); | ||
| 44 | i != mCache.end(); i++ ) | ||
| 45 | { | ||
| 46 | ar << (*i).second->tCreated; | ||
| 47 | std::list<std::string> &lData = (*i).second->lData; | ||
| 48 | ar << lData.size(); | ||
| 49 | for( std::list<std::string>::iterator j = lData.begin(); | ||
| 50 | j != lData.end(); j++ ) | ||
| 51 | { | ||
| 52 | ar << (*j); | ||
| 53 | } | ||
| 54 | |||
| 55 | std::string str = (*i).first; | ||
| 56 | ar << str; | ||
| 57 | } | ||
| 58 | } | ||
| 59 | } | ||
| 60 | |||
| 61 | Cache::Entry *Cache::get( const std::string &id ) | ||
| 62 | { | ||
| 63 | std::map<std::string, Entry *>::iterator i = mCache.find( id ); | ||
| 64 | if( i != mCache.end() ) | ||
| 65 | return (*i).second; | ||
| 66 | |||
| 67 | return NULL; | ||
| 68 | } | ||
| 69 | |||
| 70 | void Cache::put( const std::string &id, Entry *data ) | ||
| 71 | { | ||
| 72 | std::map<std::string, Entry *>::iterator i = mCache.find( id ); | ||
| 73 | if( i != mCache.end() ) | ||
| 74 | delete (*i).second; | ||
| 75 | |||
| 76 | mCache[id] = data; | ||
| 77 | } | ||
| 78 | |||
diff --git a/src/cache.h b/src/cache.h new file mode 100644 index 0000000..944aa24 --- /dev/null +++ b/src/cache.h | |||
| @@ -0,0 +1,33 @@ | |||
| 1 | #ifndef CACHE_H | ||
| 2 | #define CACHE_H | ||
| 3 | |||
| 4 | #include <stdint.h> | ||
| 5 | #include <time.h> | ||
| 6 | #include "serializable.h" | ||
| 7 | #include <list> | ||
| 8 | #include <map> | ||
| 9 | #include <string> | ||
| 10 | |||
| 11 | class Cache : public Serializable | ||
| 12 | { | ||
| 13 | public: | ||
| 14 | Cache(); | ||
| 15 | virtual ~Cache(); | ||
| 16 | |||
| 17 | virtual void serialize( class Serializer &ar ); | ||
| 18 | |||
| 19 | class Entry | ||
| 20 | { | ||
| 21 | public: | ||
| 22 | int tCreated; | ||
| 23 | std::list<std::string> lData; | ||
| 24 | }; | ||
| 25 | |||
| 26 | Entry *get( const std::string &id ); | ||
| 27 | void put( const std::string &id, Entry *data ); | ||
| 28 | |||
| 29 | private: | ||
| 30 | std::map<std::string, Entry *> mCache; | ||
| 31 | }; | ||
| 32 | |||
| 33 | #endif | ||
diff --git a/src/filetarget.cpp b/src/filetarget.cpp index e89cd5f..7a714a5 100644 --- a/src/filetarget.cpp +++ b/src/filetarget.cpp | |||
| @@ -98,7 +98,8 @@ void FileTarget::check( Builder &bld ) | |||
| 98 | for( std::list<std::string>::iterator j = lReqs->begin(); | 98 | for( std::list<std::string>::iterator j = lReqs->begin(); |
| 99 | j != lReqs->end(); j++ ) | 99 | j != lReqs->end(); j++ ) |
| 100 | { | 100 | { |
| 101 | if( getTime( bld, *j ) > target ) | 101 | time_t srcfile = getTime( bld, *j ); |
| 102 | if( srcfile > target ) | ||
| 102 | { | 103 | { |
| 103 | bld.view().beginExecute(); | 104 | bld.view().beginExecute(); |
| 104 | (*i)->execute( bld ); | 105 | (*i)->execute( bld ); |
| @@ -113,7 +114,7 @@ void FileTarget::check( Builder &bld ) | |||
| 113 | if( k == lReqs->end() ) | 114 | if( k == lReqs->end() ) |
| 114 | { | 115 | { |
| 115 | bExtraReqs = true; | 116 | bExtraReqs = true; |
| 116 | bld.genRequiresFor( (*i)->getTarget() ); | 117 | bld.genRequiresFor( (*i)->getTarget(), srcfile ); |
| 117 | } | 118 | } |
| 118 | } | 119 | } |
| 119 | } | 120 | } |
diff --git a/src/main.cpp b/src/main.cpp index 70a3ffc..009aac5 100644 --- a/src/main.cpp +++ b/src/main.cpp | |||
| @@ -8,13 +8,18 @@ class Param : public ParamProc | |||
| 8 | { | 8 | { |
| 9 | public: | 9 | public: |
| 10 | Param() : | 10 | Param() : |
| 11 | sFile("build.conf") | 11 | sFile("build.conf"), |
| 12 | sCache("build.cache") | ||
| 12 | { | 13 | { |
| 13 | addHelpBanner("Build r?\n\n"); | 14 | addHelpBanner("Build r?\n\n"); |
| 14 | addParam("file", 'f', &sFile, | 15 | addParam("file", 'f', &sFile, |
| 15 | "Set the input script, default: build.conf"); | 16 | "Set the input script, default: build.conf"); |
| 16 | addParam('p', mkproc(Param::procViewPercent), | 17 | addParam('p', mkproc(Param::procViewPercent), |
| 17 | "Switch to percent view."); | 18 | "Switch to percent view."); |
| 19 | addParam("cache", &sCache, | ||
| 20 | "Set an alternative cache file." ); | ||
| 21 | addParam('d', &bDebug, | ||
| 22 | "Print out a debug dump of the read build.conf", "true" ); | ||
| 18 | addParam("help", mkproc(ParamProc::help), | 23 | addParam("help", mkproc(ParamProc::help), |
| 19 | "This help"); | 24 | "This help"); |
| 20 | pViewer = new ViewerPlain; | 25 | pViewer = new ViewerPlain; |
| @@ -42,9 +47,11 @@ public: | |||
| 42 | pViewer = new ViewerPercent; | 47 | pViewer = new ViewerPercent; |
| 43 | } | 48 | } |
| 44 | 49 | ||
| 50 | std::string sCache; | ||
| 45 | std::string sFile; | 51 | std::string sFile; |
| 46 | StaticString sAction; | 52 | StaticString sAction; |
| 47 | Viewer *pViewer; | 53 | Viewer *pViewer; |
| 54 | bool bDebug; | ||
| 48 | 55 | ||
| 49 | private: | 56 | private: |
| 50 | }; | 57 | }; |
| @@ -56,14 +63,20 @@ int main( int argc, char *argv[] ) | |||
| 56 | 63 | ||
| 57 | Builder bld( *prm.pViewer ); | 64 | Builder bld( *prm.pViewer ); |
| 58 | 65 | ||
| 66 | bld.setCache( prm.sCache ); | ||
| 59 | bld.load( prm.sFile.c_str() ); | 67 | bld.load( prm.sFile.c_str() ); |
| 60 | 68 | ||
| 61 | if( prm.sAction > 0 ) | 69 | if( prm.bDebug ) |
| 62 | bld.build( prm.sAction ); | 70 | { |
| 71 | printf("\n\n----------\nDebug dump\n----------\n"); | ||
| 72 | bld.debug(); | ||
| 73 | } | ||
| 63 | else | 74 | else |
| 64 | bld.build(); | 75 | { |
| 65 | /* | 76 | if( prm.sAction > 0 ) |
| 66 | printf("\n\n----------\nDebug dump\n----------\n"); | 77 | bld.build( prm.sAction ); |
| 67 | bld.debug();*/ | 78 | else |
| 79 | bld.build(); | ||
| 80 | } | ||
| 68 | } | 81 | } |
| 69 | 82 | ||
