diff options
author | Evan Martin <martine@danga.com> | 2012-12-29 21:36:00 (GMT) |
---|---|---|
committer | Evan Martin <martine@danga.com> | 2012-12-29 21:47:41 (GMT) |
commit | 2c953d1501de5195e2485185fa24a2ebfd76bbb5 (patch) | |
tree | 2fc88e378a6df571bb125d282b14475f2b9ba05c /src/manifest_parser.cc | |
parent | 7096bf1507f98be981aa14ffd9ed5a4a8b1c1494 (diff) | |
parent | 3249938cdf574058a066436aea06b0541ded6958 (diff) | |
download | Ninja-1.1.0.zip Ninja-1.1.0.tar.gz Ninja-1.1.0.tar.bz2 |
version 1.1.0v1.1.0
Diffstat (limited to 'src/manifest_parser.cc')
-rw-r--r-- | src/manifest_parser.cc | 72 |
1 files changed, 68 insertions, 4 deletions
diff --git a/src/manifest_parser.cc b/src/manifest_parser.cc index 405e244..2d052b5 100644 --- a/src/manifest_parser.cc +++ b/src/manifest_parser.cc @@ -47,6 +47,10 @@ bool ManifestParser::Parse(const string& filename, const string& input, for (;;) { Lexer::Token token = lexer_.ReadToken(); switch (token) { + case Lexer::POOL: + if (!ParsePool(err)) + return false; + break; case Lexer::BUILD: if (!ParseEdge(err)) return false; @@ -91,6 +95,44 @@ bool ManifestParser::Parse(const string& filename, const string& input, return false; // not reached } + +bool ManifestParser::ParsePool(string* err) { + string name; + if (!lexer_.ReadIdent(&name)) + return lexer_.Error("expected pool name", err); + + if (!ExpectToken(Lexer::NEWLINE, err)) + return false; + + if (state_->LookupPool(name) != NULL) + return lexer_.Error("duplicate pool '" + name + "'", err); + + int depth = -1; + + while (lexer_.PeekToken(Lexer::INDENT)) { + string key; + EvalString value; + if (!ParseLet(&key, &value, err)) + return false; + + if (key == "depth") { + string depth_string = value.Evaluate(env_); + depth = atol(depth_string.c_str()); + if (depth < 0) + return lexer_.Error("invalid pool depth", err); + } else { + return lexer_.Error("unexpected variable '" + key + "'", err); + } + } + + if (depth < 0) + return lexer_.Error("expected 'depth =' line", err); + + state_->AddPool(new Pool(name, depth)); + return true; +} + + bool ManifestParser::ParseRule(string* err) { string name; if (!lexer_.ReadIdent(&name)) @@ -126,6 +168,8 @@ bool ManifestParser::ParseRule(string* err) { rule->rspfile_ = value; } else if (key == "rspfile_content") { rule->rspfile_content_ = value; + } else if (key == "pool") { + rule->pool_ = value; } else { // Die on other keyvals for now; revisit if we want to add a // scope here. @@ -133,8 +177,10 @@ bool ManifestParser::ParseRule(string* err) { } } - if (rule->rspfile_.empty() != rule->rspfile_content_.empty()) - return lexer_.Error("rspfile and rspfile_content need to be both specified", err); + if (rule->rspfile_.empty() != rule->rspfile_content_.empty()) { + return lexer_.Error("rspfile and rspfile_content need to be both specified", + err); + } if (rule->command_.empty()) return lexer_.Error("expected 'command =' line", err); @@ -252,6 +298,7 @@ bool ManifestParser::ParseEdge(string* err) { // Default to using outer env. BindingEnv* env = env_; + Pool* pool = NULL; // But create and fill a nested env if there are variables in scope. if (lexer_.PeekToken(Lexer::INDENT)) { @@ -262,11 +309,28 @@ bool ManifestParser::ParseEdge(string* err) { EvalString val; if (!ParseLet(&key, &val, err)) return false; - env->AddBinding(key, val.Evaluate(env_)); + if (key == "pool") { + string pool_name = val.Evaluate(env_); + pool = state_->LookupPool(pool_name); + if (pool == NULL) + return lexer_.Error("undefined pool '" + pool_name + "'", err); + } else { + env->AddBinding(key, val.Evaluate(env_)); + } } while (lexer_.PeekToken(Lexer::INDENT)); } - Edge* edge = state_->AddEdge(rule); + if (pool == NULL) { + if (!rule->pool_.empty()) { + pool = state_->LookupPool(rule->pool_.Evaluate(env_)); + if (pool == NULL) + return lexer_.Error("cannot resolve pool for this edge.", err); + } else { + pool = &State::kDefaultPool; + } + } + + Edge* edge = state_->AddEdge(rule, pool); edge->env_ = env; for (vector<EvalString>::iterator i = ins.begin(); i != ins.end(); ++i) { string path = i->Evaluate(env); |