aboutsummaryrefslogtreecommitdiff
path: root/src/rule.cpp
diff options
context:
space:
mode:
authorMike Buland <eichlan@xagasoft.com>2006-07-31 22:50:47 +0000
committerMike Buland <eichlan@xagasoft.com>2006-07-31 22:50:47 +0000
commit73d53b0962cb19a6d2a7686de658a5540ab07017 (patch)
tree9a8fd737b8f77ec9ccab43d89dc54b7e72d4d90d /src/rule.cpp
parentb672fa69c4c98509f8ee251b87300e3fcbe6bdc8 (diff)
downloadbuild-73d53b0962cb19a6d2a7686de658a5540ab07017.tar.gz
build-73d53b0962cb19a6d2a7686de658a5540ab07017.tar.bz2
build-73d53b0962cb19a6d2a7686de658a5540ab07017.tar.xz
build-73d53b0962cb19a6d2a7686de658a5540ab07017.zip
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.
Diffstat (limited to 'src/rule.cpp')
-rw-r--r--src/rule.cpp141
1 files changed, 122 insertions, 19 deletions
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