aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--build.conf16
-rw-r--r--pymake.conf6
-rw-r--r--src/builder.cpp20
-rw-r--r--src/builder.h6
-rw-r--r--src/filetarget.cpp8
-rw-r--r--src/perform.cpp9
-rw-r--r--src/perform.h18
-rw-r--r--src/performcmd.cpp19
-rw-r--r--src/performcmd.h22
-rw-r--r--src/rule.cpp141
-rw-r--r--src/rule.h23
-rw-r--r--src/target.cpp6
12 files changed, 250 insertions, 44 deletions
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
7set CXXFLAGS += "-Ilibbu++/src" 7set CXXFLAGS += "-Ilibbu++/src"
8set LDFLAGS += "-Llibbu++ -lbu++" 8set LDFLAGS += "-Llibbu++ -lbu++"
9 9
10build requires src/libbu++/libbu++.a
11
10/(.*)\.o/ requires from command "g++ {CXXFLAGS} -M {re:1}.c*" 12/(.*)\.o/ requires from command "g++ {CXXFLAGS} -M {re:1}.c*"
11 13
12rule exe matches all /(.*)\.o/ perform command ... 14rule exe matches all /(.*)\.o$/ perform command ...
13 "g++ {LDFLAGS} -o {target} {matches}" 15 "g++ {match} {LDFLAGS} -o {target}"
14 16
15rule cpp matches one /(.*)\.c(pp)?/ produces {1}.o perform command ... 17rule cpp matches one /(.*)\.c(pp)?$/ produces "{re:1}.o" perform command ...
16 "g++ {CXXFLAGS} -o {target} {match}" 18 "g++ {CXXFLAGS} -c -o {target} {match}"
17 19
18rule bison matches one /(.*)\.y/ produces {1}.tab.c, {1}.tab.h perform ... 20rule bison matches one /(.*)\.y$/ produces "{re:1}.tab.c", "{re:1}.tab.h" ...
19 command "bison {match}" 21 perform command "bison {match}"
20 22
21rule flex matches one /(.*)\.l/ produces {1}.yy.c perform ... 23rule flex matches one /(.*)\.l$/ produces "{re:1}.yy.c" perform ...
22 command "flex --bison-bridge --bison-locations -o {target} {match}" 24 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}
68CHECK: g++ -M {INPUT} {CXXFLAGS} -I{DIR} 68CHECK: g++ -M {INPUT} {CXXFLAGS} -I{DIR}
69 69
70[TRIGGER] 70[TRIGGER]
71INPUT .y 71INPUT: .y
72OUTPUT: .tab.c 72OUTPUT: .tab.c
73COMMAND: bison {INPUT} 73COMMAND: bison {INPUT}
74 74
75[TRIGGER] 75[TRIGGER]
76INPUT .l 76INPUT: .l
77OUTPUT: .yy.c 77OUTPUT: .yy.c
78COMMAND: flex --bison-bridge -o {OUTPUT} {INPUT} 78COMMAND: flex --bison-bridge --bison-locations -o {OUTPUT} {INPUT}
79 79
80### Executable command ### 80### Executable command ###
81## Use this command if you want a simple executable 81## 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()
132 } 132 }
133 } 133 }
134 134
135 printf("Additional dependancies:\n"); 135 printf("Dependancies:\n");
136 for( std::map<std::string, std::list<std::string> *>::iterator i = 136 for( std::map<std::string, std::list<std::string> *>::iterator i =
137 mRequires.begin(); i != mRequires.end(); i++ ) 137 mRequires.begin(); i != mRequires.end(); i++ )
138 { 138 {
139 printf(" %s: ", (*i).first.c_str() ); 139 printf(" %s: ", (*i).first.c_str() );
140 std::list<std::string> *pList = (*i).second; 140 std::list<std::string> *pList = (*i).second;
141 int i = 0;
141 for( std::list<std::string>::iterator j = pList->begin(); 142 for( std::list<std::string>::iterator j = pList->begin();
142 j != pList->end(); j++ ) 143 j != pList->end(); j++ )
143 { 144 {
144 if( j != pList->begin() ) 145 if( j != pList->begin() )
145 printf(", "); 146 printf(", ");
146 printf("%s", (*j).c_str() ); 147 printf("%s", (*j).c_str() );
148 if( i++ >= 3 )
149 {
150 printf("...");
151 break;
152 }
147 } 153 }
148 printf("\n"); 154 printf("\n");
149 } 155 }
@@ -443,6 +449,18 @@ std::list<Rule *> Builder::findRuleChain( Rule *pRule )
443{ 449{
444 std::list<Rule *> ret; 450 std::list<Rule *> ret;
445 451
452 for( std::map<const char *, Rule *, ltstr>::iterator i = mRule.begin();
453 i != mRule.end(); i++ )
454 {
455 if( pRule == (*i).second )
456 continue;
457
458 if( pRule->willChain( (*i).second ) )
459 {
460 ret.push_back( (*i).second );
461 }
462 }
463
446 return ret; 464 return ret;
447} 465}
448 466
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:
100 return mTarget[sName]; 100 return mTarget[sName];
101 } 101 }
102 102
103private:
104 typedef std::map<std::string, std::string> varmap; 103 typedef std::map<std::string, std::string> varmap;
104 varmap *regexVars( RegExp *re );
105 std::string varRepl( const char *sSrc, const char *cont, varmap *mExtra );
106private:
105 107
106 void requiresNormal( const char *sBase, const char *sReq ); 108 void requiresNormal( const char *sBase, const char *sReq );
107 void requiresRegexp( const char *sBase, const char *sReq ); 109 void requiresRegexp( const char *sBase, const char *sReq );
108 void checkVar( const char *cont, const char *sName ); 110 void checkVar( const char *cont, const char *sName );
109 void scanBegin(); 111 void scanBegin();
110 void scanEnd(); 112 void scanEnd();
111 varmap *regexVars( RegExp *re );
112 113
113 bool hasVar( varmap *pMap, std::string &var ); 114 bool hasVar( varmap *pMap, std::string &var );
114 std::string varRepl( const char *sSrc, const char *cont, varmap *mExtra );
115 115
116 Action *pDefaultAction; 116 Action *pDefaultAction;
117 Action *pLastAddedAction; 117 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 )
45 } 45 }
46 46
47 char *cwd = gnu_getcwd(); 47 char *cwd = gnu_getcwd();
48 std::string base( cwd ); 48 std::string base;//( cwd );
49 base += "/"; 49 //base += "/";
50 base += sDir; 50 base += sDir;
51 base += "/";
51 delete[] cwd; 52 delete[] cwd;
52 53
53 struct dirent *de; 54 struct dirent *de;
@@ -58,7 +59,6 @@ void FileTarget::addInputDir( const char *sDir )
58 continue; 59 continue;
59 60
60 std::string s( base ); 61 std::string s( base );
61 s += "/";
62 s += de->d_name; 62 s += de->d_name;
63 addInput( s.c_str() ); 63 addInput( s.c_str() );
64 } 64 }
@@ -70,7 +70,7 @@ void FileTarget::check( Builder &bld )
70{ 70{
71 Rule *pRule = bld.getRule( sRule ); 71 Rule *pRule = bld.getRule( sRule );
72 72
73 std::list<std::string> tmp = pRule->execute( bld, lInput ); 73 std::list<std::string> tmp = pRule->execute( bld, lInput, getName() );
74 lOutput.insert( lOutput.end(), tmp.begin(), tmp.end() ); 74 lOutput.insert( lOutput.end(), tmp.begin(), tmp.end() );
75 75
76 bld.processRequires( lInput ); 76 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 @@
1#include "perform.h"
2
3Perform::Perform()
4{
5}
6
7Perform::~Perform()
8{
9}
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 @@
1#ifndef PERFORM_H
2#define PERFORM_H
3
4#include <stdint.h>
5
6class Perform
7{
8public:
9 Perform();
10 virtual ~Perform();
11
12 virtual void execute( class Builder &bld ) = 0;
13
14private:
15
16};
17
18#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 @@
1#include "performcmd.h"
2#include "builder.h"
3
4PerformCmd::PerformCmd( const char *sCmd, const char *sTarget ) :
5 sCommand( sCmd ),
6 sTarget( sTarget )
7{
8}
9
10PerformCmd::~PerformCmd()
11{
12}
13
14void PerformCmd::execute( class Builder &bld )
15{
16 printf("%s\n", sCommand.getString() );
17 system( sCommand.getString() );
18}
19
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 @@
1#ifndef PERFORM_CMD_H
2#define PERFORM_CMD_H
3
4#include <stdint.h>
5
6#include "perform.h"
7#include "staticstring.h"
8
9class PerformCmd : public Perform
10{
11public:
12 PerformCmd( const char *sCmd, const char *sTarget );
13 virtual ~PerformCmd();
14
15 virtual void execute( class Builder &bld );
16
17private:
18 StaticString sCommand;
19 StaticString sTarget;
20};
21
22#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 @@
1#include "rule.h" 1#include "rule.h"
2#include "perform.h"
3#include "performcmd.h"
2#include "builder.h" // for BuildException 4#include "builder.h" // for BuildException
3 5
4Rule::Rule( const char *sName ) : 6Rule::Rule( const char *sName ) :
5 sName( sName ) 7 sName( sName ),
8 bNoProduces( true )
6{ 9{
10 lProduces.push_back("{target}");
7} 11}
8 12
9Rule::~Rule() 13Rule::~Rule()
10{ 14{
11 regfree( &rWhat );
12} 15}
13 16
14void Rule::debug() 17void Rule::debug()
@@ -34,7 +37,7 @@ void Rule::debug()
34 printf("one "); 37 printf("one ");
35 else if( mHow == matchAll ) 38 else if( mHow == matchAll )
36 printf("all "); 39 printf("all ");
37 printf("/%s/\n", sWhat.getString() ); 40 printf("/%s/\n", rWhat.getSource() );
38 41
39 printf(" Performs "); 42 printf(" Performs ");
40 if( pHow == perfCommand ) 43 if( pHow == perfCommand )
@@ -44,39 +47,139 @@ void Rule::debug()
44 47
45void Rule::addProduces( const char *sP ) 48void Rule::addProduces( const char *sP )
46{ 49{
50 if( bNoProduces )
51 {
52 lProduces.clear();
53 bNoProduces = false;
54 }
47 lProduces.push_back( sP ); 55 lProduces.push_back( sP );
48} 56}
49 57
50void Rule::setMatches( Matches how, const char *sW ) 58void Rule::setMatches( Matches how, const char *sW )
51{ 59{
52 sWhat = sW; 60 rWhat.compile( sW );
53 mHow = how; 61 mHow = how;
54
55 int nErr = regcomp( &rWhat, sW, REG_EXTENDED|REG_NEWLINE );
56 if( nErr )
57 {
58 size_t length = regerror( nErr, &rWhat, NULL, 0 );
59 char *buffer = new char[length];
60 (void) regerror( nErr, &rWhat, buffer, length );
61 StaticString s( buffer );
62 delete[] buffer;
63 throw BuildException( s.getString() );
64 }
65} 62}
66 63
67void Rule::setPerforms( Perform pwhat, const char *sperfcmd ) 64void Rule::setPerforms( ePerform pwhat, const char *sperfcmd )
68{ 65{
69 pHow = pwhat; 66 pHow = pwhat;
70 sPerfCmd = sperfcmd; 67 sPerfCmd = sperfcmd;
71} 68}
72 69
73std::list<std::string> Rule::execute( Builder &bld, std::list<std::string> lInput ) 70Perform *Rule::buildCommand( Builder &bld, const char *sCmd, const char *sTarget, const char *sMatches )
71{
72 Builder::varmap vars;
73 vars["target"] = sTarget;
74 vars["match"] = sMatches;
75 return new PerformCmd( bld.varRepl( sCmd, "", &vars ).c_str(), sTarget );
76}
77
78std::list<std::string> Rule::findTargets( Builder &bld, std::list<std::string> &lIn, std::string &sMatches, const char *sTarget )
79{
80 std::list<std::string> lTmp;
81
82 for( std::list<std::string>::iterator i = lIn.begin();
83 i != lIn.end(); i++ )
84 {
85 if( rWhat.execute( (*i).c_str() ) )
86 {
87 Builder::varmap *revars = bld.regexVars( &rWhat );
88 for( std::list<std::string>::iterator j = lProduces.begin();
89 j != lProduces.end(); j++ )
90 {
91 if( mHow == matchOne )
92 {
93 lTmp.push_back(
94 bld.varRepl(
95 (*j).c_str(),
96 "",
97 revars
98 )
99 );
100 Perform *p = buildCommand(
101 bld,
102 sPerfCmd,
103 (sTarget==NULL)?(lTmp.back().c_str()):(sTarget),
104 (*i).c_str()
105 );
106 p->execute( bld );
107 delete p;
108 }
109 else if( mHow == matchAll )
110 {
111 sMatches += " ";
112 sMatches += (*i);
113 }
114 }
115 delete revars;
116 }
117 }
118
119 return lTmp;
120}
121
122std::list<std::string> Rule::execute( Builder &bld, std::list<std::string> lInput, const char *sTarget )
74{ 123{
75 std::list<Rule *> lRule = bld.findRuleChain( this ); 124 std::list<Rule *> lRule = bld.findRuleChain( this );
76 125
77 std::list<std::string> ret; 126 if( !lRule.empty() )
127 {
128 printf("Rule %s chains to: ", sName.getString() );
129 for( std::list<Rule *>::iterator i = lRule.begin();
130 i != lRule.end(); i++ )
131 {
132 if( i != lRule.begin() )
133 printf(", ");
134 printf("%s", (*i)->sName.getString() );
135 }
136 printf("\n");
137 }
138
139 std::list<std::string> lOutput;
140 std::string sMatches;
141
142 for( std::list<Rule *>::iterator i = lRule.begin(); i != lRule.end(); i++ )
143 {
144 std::list<std::string> lTmp = (*i)->execute( bld, lInput );
145 lOutput.insert( lOutput.end(), lTmp.begin(), lTmp.end() );
146 }
147
148 std::list<std::string> lTmp = findTargets( bld, lInput, sMatches, sTarget );
149 lOutput.insert( lOutput.end(), lTmp.begin(), lTmp.end() );
150 lTmp = findTargets( bld, lOutput, sMatches, sTarget );
151 lOutput.insert( lOutput.end(), lTmp.begin(), lTmp.end() );
78 152
79 return ret; 153 if( mHow == matchAll )
154 {
155 lOutput.push_back(
156 bld.varRepl(
157 sTarget,
158 "",
159 NULL
160 )
161 );
162 Perform *p = buildCommand(
163 bld,
164 sPerfCmd,
165 sTarget,
166 sMatches.c_str()
167 );
168 p->execute( bld );
169 }
170
171 return lOutput;
172}
173
174bool Rule::willChain( Rule *pRule )
175{
176 for( std::list<std::string>::iterator i = pRule->lProduces.begin();
177 i != pRule->lProduces.end(); i++ )
178 {
179 if( rWhat.execute( (*i).c_str() ) )
180 return true;
181 }
80 182
183 return false;
81} 184}
82 185
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 @@
4#include <list> 4#include <list>
5#include <string> 5#include <string>
6#include <stdint.h> 6#include <stdint.h>
7#include <regex.h> 7#include "regexp.h"
8#include "staticstring.h" 8#include "staticstring.h"
9 9
10class Perform;
11
10class Rule 12class Rule
11{ 13{
12public: 14public:
@@ -16,7 +18,7 @@ public:
16 matchAll 18 matchAll
17 }; 19 };
18 20
19 enum Perform 21 enum ePerform
20 { 22 {
21 perfCommand 23 perfCommand
22 }; 24 };
@@ -34,20 +36,27 @@ public:
34 36
35 void addProduces( const char *sProduces ); 37 void addProduces( const char *sProduces );
36 void setMatches( Matches how, const char *sWhat ); 38 void setMatches( Matches how, const char *sWhat );
37 void setPerforms( Perform pwhat, const char *sPerfCmd ); 39 void setPerforms( ePerform pwhat, const char *sPerfCmd );
40
41 bool willChain( Rule *pRule );
38 42
39 std::list<std::string> execute( class Builder &bld, std::list<std::string> lInput ); 43 std::list<std::string> execute( class Builder &bld, std::list<std::string> lInput, const char *sTarget=NULL );
40 44
41private: 45private:
46 class Perform *buildCommand( class Builder &bld, const char *sCmd, const char *sTarget, const char *sMatches );
47 std::list<std::string> findTargets( class Builder &bld, std::list<std::string> &lIn, std::string &sMatches, const char *sTarget );
42 StaticString sName; 48 StaticString sName;
43 std::list<std::string> lProduces; 49 std::list<std::string> lProduces;
44 50
45 Matches mHow; 51 Matches mHow;
46 StaticString sWhat; 52 RegExp rWhat;
47 regex_t rWhat; 53 //StaticString sWhat;
54 //regex_t rWhat;
48 55
49 Perform pHow; 56 ePerform pHow;
50 StaticString sPerfCmd; 57 StaticString sPerfCmd;
58
59 bool bNoProduces;
51}; 60};
52 61
53#endif 62#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()
26 { 26 {
27 printf(" %s\n", (*i).c_str() ); 27 printf(" %s\n", (*i).c_str() );
28 } 28 }
29 printf(" Output list:\n");
30 for( std::list<std::string>::iterator i = lOutput.begin();
31 i != lOutput.end(); i++ )
32 {
33 printf(" %s\n", (*i).c_str() );
34 }
29} 35}
30 36
31void Target::addInput( const char *sInput ) 37void Target::addInput( const char *sInput )