diff options
Diffstat (limited to 'src/rule.cpp')
-rw-r--r-- | src/rule.cpp | 141 |
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 | ||
4 | Rule::Rule( const char *sName ) : | 6 | Rule::Rule( const char *sName ) : |
5 | sName( sName ) | 7 | sName( sName ), |
8 | bNoProduces( true ) | ||
6 | { | 9 | { |
10 | lProduces.push_back("{target}"); | ||
7 | } | 11 | } |
8 | 12 | ||
9 | Rule::~Rule() | 13 | Rule::~Rule() |
10 | { | 14 | { |
11 | regfree( &rWhat ); | ||
12 | } | 15 | } |
13 | 16 | ||
14 | void Rule::debug() | 17 | void 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 | ||
45 | void Rule::addProduces( const char *sP ) | 48 | void 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 | ||
50 | void Rule::setMatches( Matches how, const char *sW ) | 58 | void 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 | ||
67 | void Rule::setPerforms( Perform pwhat, const char *sperfcmd ) | 64 | void 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 | ||
73 | std::list<std::string> Rule::execute( Builder &bld, std::list<std::string> lInput ) | 70 | Perform *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 | |||
78 | std::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 | |||
122 | std::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 | |||
174 | bool 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 | ||