aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorShinichiro Hamaji <shinichiro.hamaji@gmail.com>2015-06-19 15:30:49 +0900
committerShinichiro Hamaji <shinichiro.hamaji@gmail.com>2015-06-22 15:46:23 +0900
commit0562c301e9e359ca32abf647e32300aaea75d8f7 (patch)
treec226363ee2dbc512f577a621d64d442934ce348e
parent4a7113136b40e77d65ffd2ed22d1162a9e6f126b (diff)
downloadandroid_build_kati-0562c301e9e359ca32abf647e32300aaea75d8f7.tar.gz
android_build_kati-0562c301e9e359ca32abf647e32300aaea75d8f7.tar.bz2
android_build_kati-0562c301e9e359ca32abf647e32300aaea75d8f7.zip
[C++] Implement suffix rule
-rw-r--r--dep.cc106
-rw-r--r--dep.h3
-rw-r--r--eval.cc7
-rw-r--r--eval.h5
-rw-r--r--rule.cc4
-rw-r--r--rule.h1
6 files changed, 89 insertions, 37 deletions
diff --git a/dep.cc b/dep.cc
index b0874c4..8dd851c 100644
--- a/dep.cc
+++ b/dep.cc
@@ -3,6 +3,7 @@
#include <algorithm>
#include <memory>
+#include "fileutil.h"
#include "log.h"
#include "rule.h"
#include "strutil.h"
@@ -10,6 +11,14 @@
static vector<DepNode*>* g_dep_node_pool;
+static StringPiece ReplaceSuffix(StringPiece s, StringPiece newsuf) {
+ string r;
+ AppendString(StripExt(s), &r);
+ r += '.';
+ AppendString(newsuf, &r);
+ return Intern(r);
+}
+
DepNode::DepNode(StringPiece o, bool p)
: output(o),
has_rule(false),
@@ -21,7 +30,7 @@ DepNode::DepNode(StringPiece o, bool p)
class DepBuilder {
public:
- DepBuilder(const vector<Rule*>& rules,
+ DepBuilder(const vector<shared_ptr<Rule>>& rules,
const Vars& vars,
const unordered_map<StringPiece, Vars*>& rule_vars)
: vars_(vars),
@@ -31,9 +40,6 @@ class DepBuilder {
}
~DepBuilder() {
- for (Rule* r : implicit_rules_) {
- delete r;
- }
}
void Build(vector<StringPiece> targets,
@@ -56,8 +62,8 @@ class DepBuilder {
}
private:
- void PopulateRules(const vector<Rule*>& rules) {
- for (Rule* rule : rules) {
+ void PopulateRules(const vector<shared_ptr<Rule>>& rules) {
+ for (shared_ptr<Rule> rule : rules) {
if (rule->outputs.empty()) {
PopulateImplicitRule(rule);
} else {
@@ -67,8 +73,32 @@ class DepBuilder {
reverse(implicit_rules_.begin(), implicit_rules_.end());
}
- void PopulateExplicitRule(Rule* rule) {
+ bool PopulateSuffixRule(shared_ptr<Rule> rule, StringPiece output) {
+ if (output.empty() || output[0] != '.')
+ return false;
+
+ StringPiece rest = output.substr(1);
+ size_t dot_index = rest.find('.');
+ // If there is only a single dot or the third dot, this is not a
+ // suffix rule.
+ if (dot_index == string::npos ||
+ rest.substr(dot_index+1).find('.') != string::npos) {
+ return false;
+ }
+
+ StringPiece input_suffix = rest.substr(0, dot_index);
+ StringPiece output_suffix = rest.substr(dot_index+1);
+ shared_ptr<Rule> r = make_shared<Rule>(*rule);
+ r->inputs.clear();
+ r->inputs.push_back(input_suffix);
+ r->is_suffix_rule = true;
+ suffix_rules_[output_suffix].push_back(r);
+ return true;
+ }
+
+ void PopulateExplicitRule(shared_ptr<Rule> rule) {
for (StringPiece output : rule->outputs) {
+ const bool is_suffix_rule = PopulateSuffixRule(rule, output);
// isSuffixRule := db.populateSuffixRule(rule, output)
@@ -96,17 +126,16 @@ class DepBuilder {
}
}
- void PopulateImplicitRule(Rule* rule) {
+ void PopulateImplicitRule(shared_ptr<Rule> rule) {
for (StringPiece output_pattern : rule->output_patterns) {
- Rule* r = new Rule(*rule);
- r->is_temporary = false;
+ shared_ptr<Rule> r = make_shared<Rule>(*rule);
r->output_patterns.clear();
r->output_patterns.push_back(output_pattern);
implicit_rules_.push_back(r);
}
}
- Rule* LookupRule(StringPiece o) {
+ shared_ptr<Rule> LookupRule(StringPiece o) {
auto found = rules_.find(o);
if (found != rules_.end())
return found->second;
@@ -120,8 +149,9 @@ class DepBuilder {
return NULL;
}
- bool PickRule(StringPiece output, Rule** out_rule, Vars** out_var) {
- Rule* rule = LookupRule(output);
+ bool PickRule(StringPiece output,
+ shared_ptr<Rule>* out_rule, Vars** out_var) {
+ shared_ptr<Rule> rule = LookupRule(output);
Vars* vars = LookupRuleVars(output);
*out_rule = rule;
*out_var = vars;
@@ -131,13 +161,13 @@ class DepBuilder {
}
}
- for (Rule* irule : implicit_rules_) {
+ for (shared_ptr<Rule> irule : implicit_rules_) {
CHECK(irule->output_patterns.size() == 1);
if (!Pattern(irule->output_patterns[0]).Match(output)) {
continue;
}
if (rule) {
- Rule* r = new Rule(*rule);
+ shared_ptr<Rule> r = make_shared<Rule>(*rule);
r->output_patterns = irule->output_patterns;
for (StringPiece input : irule->inputs)
r->inputs.push_back(input);
@@ -148,16 +178,43 @@ class DepBuilder {
return true;
}
if (vars) {
- // Merge implicit rule variables...
+ // TODO: Merge implicit variables...
CHECK(false);
}
*out_rule = irule;
return true;
}
- // Suffix rule.
+ StringPiece output_suffix = GetExt(output);
+ if (output_suffix.get(0) != '.')
+ return rule.get();
+
+ SuffixRuleMap::const_iterator found = suffix_rules_.find(output_suffix);
+ if (found == suffix_rules_.end())
+ return rule.get();
+
+ for (shared_ptr<Rule> irule : found->second) {
+ CHECK(irule->inputs.size() != 1);
+ StringPiece input = ReplaceSuffix(output, irule->inputs[0]);
+ if (!Exists(input))
+ continue;
+
+ if (rule) {
+ shared_ptr<Rule> r = make_shared<Rule>(*rule);
+ r->inputs.insert(r->inputs.begin(), input);
+ r->cmds = irule->cmds;
+ r->loc = irule->loc;
+ r->cmd_lineno = irule->cmd_lineno;
+ *out_rule = r;
+ return true;
+ }
+ if (vars) {
+ // TODO: Merge implicit variables...
+ CHECK(false);
+ }
+ }
- return rule;
+ return rule.get();
}
DepNode* BuildPlan(StringPiece output, StringPiece needed_by, Vars* tsvs) {
@@ -173,7 +230,7 @@ class DepBuilder {
DepNode* n = new DepNode(output, phony_[output]);
done_[output] = n;
- Rule* rule;
+ shared_ptr<Rule> rule;
Vars* vars;
if (!PickRule(output, &rule, &vars)) {
return n;
@@ -203,21 +260,22 @@ class DepBuilder {
return n;
}
- unordered_map<StringPiece, Rule*> rules_;
+ unordered_map<StringPiece, shared_ptr<Rule>> rules_;
const Vars& vars_;
const unordered_map<StringPiece, Vars*>& rule_vars_;
- vector<Rule*> implicit_rules_; // pattern=%. no prefix,suffix.
+ vector<shared_ptr<Rule>> implicit_rules_; // pattern=%. no prefix,suffix.
//vector<Rule*> iprefix_rules_; // pattern=prefix%.. may have suffix
//vector<Rule*> isuffix_rules_; // pattern=%suffix no prefix
+ typedef unordered_map<StringPiece, vector<shared_ptr<Rule>>> SuffixRuleMap;
+ SuffixRuleMap suffix_rules_;
- unordered_map<StringPiece, vector<Rule*>> suffix_rules_;
- Rule* first_rule_;
+ shared_ptr<Rule> first_rule_;
unordered_map<StringPiece, DepNode*> done_;
unordered_map<StringPiece, bool> phony_;
};
-void MakeDep(const vector<Rule*>& rules,
+void MakeDep(const vector<shared_ptr<Rule>>& rules,
const Vars& vars,
const unordered_map<StringPiece, Vars*>& rule_vars,
const vector<StringPiece>& targets,
diff --git a/dep.h b/dep.h
index d829b10..490fe46 100644
--- a/dep.h
+++ b/dep.h
@@ -1,6 +1,7 @@
#ifndef DEP_H_
#define DEP_H_
+#include <memory>
#include <string>
#include <unordered_map>
#include <vector>
@@ -30,7 +31,7 @@ struct DepNode {
void InitDepNodePool();
void QuitDepNodePool();
-void MakeDep(const vector<Rule*>& rules,
+void MakeDep(const vector<shared_ptr<Rule>>& rules,
const Vars& vars,
const unordered_map<StringPiece, Vars*>& rule_vars,
const vector<StringPiece>& targets,
diff --git a/eval.cc b/eval.cc
index 16791fa..28d4e16 100644
--- a/eval.cc
+++ b/eval.cc
@@ -11,8 +11,6 @@
#include "var.h"
EvalResult::~EvalResult() {
- for (Rule* r : rules)
- delete r;
for (auto p : rule_vars)
delete p.second;
delete vars;
@@ -25,9 +23,6 @@ Evaluator::Evaluator(const Vars* vars)
}
Evaluator::~Evaluator() {
- for (Rule* r : rules_) {
- delete r;
- }
delete vars_;
// for (auto p : rule_vars) {
// delete p.second;
@@ -93,7 +88,7 @@ void Evaluator::EvalRule(const RuleAST* ast) {
if (rule) {
LOG("Rule: %s", rule->DebugString().c_str());
- rules_.push_back(rule);
+ rules_.push_back(shared_ptr<Rule>(rule));
last_rule_ = rule;
return;
}
diff --git a/eval.h b/eval.h
index d99c778..adb3700 100644
--- a/eval.h
+++ b/eval.h
@@ -1,6 +1,7 @@
#ifndef EVAL_H_
#define EVAL_H_
+#include <memory>
#include <unordered_map>
#include <vector>
@@ -22,7 +23,7 @@ class Vars;
struct EvalResult {
~EvalResult();
- vector<Rule*> rules;
+ vector<shared_ptr<Rule>> rules;
Vars* vars;
unordered_map<StringPiece, Vars*> rule_vars;
// TODO: read_mks
@@ -60,7 +61,7 @@ class Evaluator {
const Vars* in_vars_;
Vars* vars_;
unordered_map<StringPiece, Vars*> rule_vars_;
- vector<Rule*> rules_;
+ vector<shared_ptr<Rule>> rules_;
Rule* last_rule_;
Loc loc_;
diff --git a/rule.cc b/rule.cc
index f0b9f63..6ddd55a 100644
--- a/rule.cc
+++ b/rule.cc
@@ -42,8 +42,7 @@ bool IsPatternRule(StringPiece s) {
Rule::Rule()
: is_double_colon(false),
is_suffix_rule(false),
- cmd_lineno(0),
- is_temporary(true) {
+ cmd_lineno(0) {
}
void ParseRule(Loc& loc, StringPiece line,
@@ -88,7 +87,6 @@ void ParseRule(Loc& loc, StringPiece line,
Rule* rule = new Rule();
*out_rule = rule;
- rule->is_temporary = false;
rule->loc = loc;
rule->is_double_colon = is_double_colon;
if (is_first_pattern) {
diff --git a/rule.h b/rule.h
index 2f68536..6434281 100644
--- a/rule.h
+++ b/rule.h
@@ -28,7 +28,6 @@ class Rule {
vector<Value*> cmds;
Loc loc;
int cmd_lineno;
- bool is_temporary;
private:
void Error(const string& msg) {