summaryrefslogtreecommitdiffstats
path: root/src/parsers.cc
diff options
context:
space:
mode:
authorEvan Martin <martine@danga.com>2010-12-19 22:53:38 (GMT)
committerEvan Martin <martine@danga.com>2010-12-19 22:54:15 (GMT)
commitac4cc82452ec145e2f567b8edab6c14d642d41c8 (patch)
tree65667e1d2d13ea2ef2e1db9043084e2fd0149237 /src/parsers.cc
parentcd5dd9e74df2accca52c85cbb1c0e7075660919e (diff)
downloadNinja-ac4cc82452ec145e2f567b8edab6c14d642d41c8.zip
Ninja-ac4cc82452ec145e2f567b8edab6c14d642d41c8.tar.gz
Ninja-ac4cc82452ec145e2f567b8edab6c14d642d41c8.tar.bz2
expand variables in build paths
Diffstat (limited to 'src/parsers.cc')
-rw-r--r--src/parsers.cc22
1 files changed, 18 insertions, 4 deletions
diff --git a/src/parsers.cc b/src/parsers.cc
index 4d6c058..c66b91b 100644
--- a/src/parsers.cc
+++ b/src/parsers.cc
@@ -82,7 +82,7 @@ static bool IsIdentChar(char c) {
('a' <= c && c <= 'z') ||
('+' <= c && c <= '9') || // +,-./ and numbers
('A' <= c && c <= 'Z') ||
- (c == '_') || (c == '@');
+ (c == '_') || (c == '@') || (c == '$');
}
bool Tokenizer::ExpectToken(Token::Type expected, string* err) {
@@ -379,7 +379,7 @@ bool ManifestParser::ParseEdge(string* err) {
string out;
if (!tokenizer_.ReadIdent(&out))
return tokenizer_.Error("expected output file list", err);
- outs.push_back(ExpandFile(out));
+ outs.push_back(out);
}
// XXX check outs not empty
@@ -402,7 +402,7 @@ bool ManifestParser::ParseEdge(string* err) {
string in;
if (!tokenizer_.ReadIdent(&in))
break;
- ins.push_back(ExpandFile(in));
+ ins.push_back(in);
}
// Add all order-only deps, counting how many as we go.
@@ -413,7 +413,7 @@ bool ManifestParser::ParseEdge(string* err) {
string in;
if (!tokenizer_.ReadIdent(&in))
break;
- ins.push_back(ExpandFile(in));
+ ins.push_back(in);
++order_only;
}
}
@@ -440,6 +440,20 @@ bool ManifestParser::ParseEdge(string* err) {
tokenizer_.ConsumeToken();
}
+ // Evaluate all variables in paths.
+ // XXX: fast path skip the eval parse if there's no $ in the path?
+ vector<string>* paths[2] = { &ins, &outs };
+ for (int p = 0; p < 2; ++p) {
+ for (vector<string>::iterator i = paths[p]->begin();
+ i != paths[p]->end(); ++i) {
+ EvalString eval;
+ string eval_err;
+ if (!eval.Parse(*i, &eval_err))
+ return tokenizer_.Error(eval_err, err);
+ *i = ExpandFile(eval.Evaluate(env));
+ }
+ }
+
Edge* edge = state_->AddEdge(rule);
edge->env_ = env;
for (vector<string>::iterator i = ins.begin(); i != ins.end(); ++i)