aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Buland <eichlan@xagasoft.com>2006-08-05 00:04:34 +0000
committerMike Buland <eichlan@xagasoft.com>2006-08-05 00:04:34 +0000
commit8dd79b7b5a0309f9bc1185019a4af16b3b52aece (patch)
treea703325cb9bc074179aeaf38f4851a4c38ebfd87
parent13bda5d4f77ca469bbbe0d9b1f268682a9f0ec71 (diff)
downloadbuild-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.
-rw-r--r--src/builder.cpp113
-rw-r--r--src/builder.h9
-rw-r--r--src/cache.cpp78
-rw-r--r--src/cache.h33
-rw-r--r--src/filetarget.cpp5
-rw-r--r--src/main.cpp27
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
11subExceptionDef( BuildException ) 13subExceptionDef( BuildException )
12 14
@@ -21,6 +23,18 @@ Builder::Builder( Viewer &rView ) :
21 23
22Builder::~Builder() 24Builder::~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
26void yyparse( Builder &bld ); 40void yyparse( Builder &bld );
@@ -53,6 +67,21 @@ void Builder::build( const char *sAct )
53 rView.endAction(); 67 rView.endAction();
54} 68}
55 69
70void 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
56void Builder::execute( Action *pAct ) 85void 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(); 281void 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
317void 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
382std::map<std::string, std::string> *Builder::regexVars( RegExp *re ) 371std::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
12subExceptionDecl( BuildException ) 13subExceptionDecl( BuildException )
13 14
@@ -17,6 +18,7 @@ class Command;
17class Rule; 18class Rule;
18class Target; 19class Target;
19class Viewer; 20class Viewer;
21class 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 )
22YY_DECL; 24YY_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
157void cleanList( std::list<std::string> &lst ); 164void 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
4Cache::Cache()
5{
6}
7
8Cache::~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
17void 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
61Cache::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
70void 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
11class Cache : public Serializable
12{
13public:
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
29private:
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{
9public: 9public:
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
49private: 56private:
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