aboutsummaryrefslogtreecommitdiff
path: root/src/rule.cpp
diff options
context:
space:
mode:
Diffstat (limited to '')
-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