aboutsummaryrefslogtreecommitdiff
path: root/dep.cc
diff options
context:
space:
mode:
authorShinichiro Hamaji <shinichiro.hamaji@gmail.com>2015-09-26 12:07:22 +0900
committerShinichiro Hamaji <shinichiro.hamaji@gmail.com>2015-09-27 15:51:03 +0900
commit53ffb0779af6bba369721b28a0e83f6c6bf34ea9 (patch)
tree40fa160cfcac4e4f1a68e5cb9ea722df970274a8 /dep.cc
parent645cca7910dccf4811dbf65d4c83a068a83b48c9 (diff)
[C++] Fix merge of rules with output patterns
Diffstat (limited to 'dep.cc')
-rw-r--r--dep.cc82
1 files changed, 51 insertions, 31 deletions
diff --git a/dep.cc b/dep.cc
index 2b9390e..b2480f7 100644
--- a/dep.cc
+++ b/dep.cc
@@ -208,6 +208,31 @@ class DepBuilder {
return true;
}
+ void ApplyOutputPattern(const Rule& r,
+ Symbol output,
+ const vector<Symbol>& inputs,
+ vector<Symbol>* out_inputs) {
+ if (inputs.empty())
+ return;
+ if (r.is_suffix_rule) {
+ for (Symbol input : inputs) {
+ out_inputs->push_back(ReplaceSuffix(output, input));
+ }
+ return;
+ }
+ if (r.output_patterns.empty()) {
+ copy(inputs.begin(), inputs.end(), back_inserter(*out_inputs));
+ return;
+ }
+ CHECK(r.output_patterns.size() == 1);
+ Pattern pat(r.output_patterns[0].str());
+ for (Symbol input : inputs) {
+ string buf;
+ pat.AppendSubst(output.str(), input.str(), &buf);
+ out_inputs->push_back(Intern(buf));
+ }
+ }
+
shared_ptr<Rule> MergeRules(const Rule& old_rule,
const Rule& rule,
Symbol output,
@@ -231,6 +256,11 @@ class DepBuilder {
r->cmds.push_back(c);
for (Value* c : rule.cmds)
r->cmds.push_back(c);
+ if (!rule.output_patterns.empty() && !old_rule.output_patterns.empty() &&
+ rule.output_patterns != old_rule.output_patterns) {
+ ERROR("%s:%d: TODO: merging two double rules with output patterns "
+ "is not supported", LOCF(rule.loc));
+ }
} else if (!old_rule.cmds.empty() && rule.cmds.empty()) {
r->cmds = old_rule.cmds;
}
@@ -239,31 +269,27 @@ class DepBuilder {
// |old_rule|), inputs in the latter rule has a priority.
if (rule.cmds.empty()) {
r->inputs = old_rule.inputs;
- copy(rule.inputs.begin(), rule.inputs.end(),
- back_inserter(r->inputs));
+ ApplyOutputPattern(rule, output, rule.inputs, &r->inputs);
r->order_only_inputs = old_rule.order_only_inputs;
- copy(rule.order_only_inputs.begin(), rule.order_only_inputs.end(),
- back_inserter(r->order_only_inputs));
+ ApplyOutputPattern(rule, output, rule.order_only_inputs,
+ &r->order_only_inputs);
+ r->output_patterns = old_rule.output_patterns;
} else {
- copy(old_rule.inputs.begin(), old_rule.inputs.end(),
- back_inserter(r->inputs));
- copy(old_rule.order_only_inputs.begin(),
- old_rule.order_only_inputs.end(),
- back_inserter(r->inputs));
- }
- for (Symbol p : old_rule.output_patterns) {
- r->output_patterns.push_back(p);
+ ApplyOutputPattern(old_rule, output, old_rule.inputs, &r->inputs);
+ ApplyOutputPattern(old_rule, output, old_rule.order_only_inputs,
+ &r->order_only_inputs);
}
return r;
}
- void PopulateExplicitRule(shared_ptr<Rule> rule) {
- for (Symbol output : rule->outputs) {
- const bool is_suffix_rule = PopulateSuffixRule(rule, output);
+ void PopulateExplicitRule(shared_ptr<Rule> orig_rule) {
+ for (Symbol output : orig_rule->outputs) {
+ const bool is_suffix_rule = PopulateSuffixRule(orig_rule, output);
- rule = make_shared<Rule>(*rule);
+ shared_ptr<Rule> rule = make_shared<Rule>(*orig_rule);
rule->outputs.clear();
rule->outputs.push_back(output);
+
auto p = rules_.insert(make_pair(output, rule));
if (p.second) {
if (!first_rule_ && output.get(0) != '.') {
@@ -424,6 +450,9 @@ class DepBuilder {
}
if (rule->output_patterns.size() >= 1) {
+ if (rule->output_patterns.size() != 1) {
+ fprintf(stderr, "hmm %s\n", rule->DebugString().c_str());
+ }
CHECK(rule->output_patterns.size() == 1);
n->output_pattern = rule->output_patterns[0];
}
@@ -456,25 +485,16 @@ class DepBuilder {
}
}
- for (Symbol input : rule->inputs) {
- if (rule->output_patterns.size() > 0) {
- if (rule->output_patterns.size() > 1) {
- ERROR("TODO: multiple output pattern is not supported yet");
- }
- string o;
- Pattern(rule->output_patterns[0].str()).AppendSubst(
- output.str(), input.str(), &o);
- input = Intern(o);
- } else if (rule->is_suffix_rule) {
- input = ReplaceSuffix(output, input);
- }
-
- n->actual_inputs.push_back(input);
+ ApplyOutputPattern(*rule, output, rule->inputs, &n->actual_inputs);
+ for (Symbol input : n->actual_inputs) {
DepNode* c = BuildPlan(input, output);
n->deps.push_back(c);
}
- for (Symbol input : rule->order_only_inputs) {
+ vector<Symbol> order_only_inputs;
+ ApplyOutputPattern(*rule, output, rule->order_only_inputs,
+ &order_only_inputs);
+ for (Symbol input : order_only_inputs) {
DepNode* c = BuildPlan(input, output);
n->order_onlys.push_back(c);
}