diff options
Diffstat (limited to 'src/manifest_parser.cc')
-rw-r--r-- | src/manifest_parser.cc | 68 |
1 files changed, 44 insertions, 24 deletions
diff --git a/src/manifest_parser.cc b/src/manifest_parser.cc index 860a8fc..8db6eb3 100644 --- a/src/manifest_parser.cc +++ b/src/manifest_parser.cc @@ -190,26 +190,24 @@ bool ManifestParser::ParseDefault(string* err) { do { string path = eval.Evaluate(env_); - string path_err; + if (path.empty()) + return lexer_.Error("empty path", err); uint64_t slash_bits; // Unused because this only does lookup. - if (!CanonicalizePath(&path, &slash_bits, &path_err)) - return lexer_.Error(path_err, err); - if (!state_->AddDefault(path, &path_err)) - return lexer_.Error(path_err, err); + CanonicalizePath(&path, &slash_bits); + std::string default_err; + if (!state_->AddDefault(path, &default_err)) + return lexer_.Error(default_err, err); eval.Clear(); if (!lexer_.ReadPath(&eval, err)) return false; } while (!eval.empty()); - if (!ExpectToken(Lexer::NEWLINE, err)) - return false; - - return true; + return ExpectToken(Lexer::NEWLINE, err); } bool ManifestParser::ParseEdge(string* err) { - vector<EvalString> ins, outs; + vector<EvalString> ins, outs, validations; { EvalString out; @@ -290,6 +288,18 @@ bool ManifestParser::ParseEdge(string* err) { } } + // Add all validations, counting how many as we go. + if (lexer_.PeekToken(Lexer::PIPEAT)) { + for (;;) { + EvalString validation; + if (!lexer_.ReadPath(&validation, err)) + return false; + if (validation.empty()) + break; + validations.push_back(validation); + } + } + if (!ExpectToken(Lexer::NEWLINE, err)) return false; @@ -320,27 +330,27 @@ bool ManifestParser::ParseEdge(string* err) { edge->outputs_.reserve(outs.size()); for (size_t i = 0, e = outs.size(); i != e; ++i) { string path = outs[i].Evaluate(env); - string path_err; + if (path.empty()) + return lexer_.Error("empty path", err); uint64_t slash_bits; - if (!CanonicalizePath(&path, &slash_bits, &path_err)) - return lexer_.Error(path_err, err); + CanonicalizePath(&path, &slash_bits); if (!state_->AddOut(edge, path, slash_bits)) { if (options_.dupe_edge_action_ == kDupeEdgeActionError) { - lexer_.Error("multiple rules generate " + path + " [-w dupbuild=err]", - err); + lexer_.Error("multiple rules generate " + path, err); return false; } else { if (!quiet_) { - Warning("multiple rules generate %s. " - "builds involving this target will not be correct; " - "continuing anyway [-w dupbuild=warn]", - path.c_str()); + Warning( + "multiple rules generate %s. builds involving this target will " + "not be correct; continuing anyway", + path.c_str()); } if (e - i <= static_cast<size_t>(implicit_outs)) --implicit_outs; } } } + if (edge->outputs_.empty()) { // All outputs of the edge are already created by other edges. Don't add // this edge. Do this check before input nodes are connected to the edge. @@ -353,15 +363,26 @@ bool ManifestParser::ParseEdge(string* err) { edge->inputs_.reserve(ins.size()); for (vector<EvalString>::iterator i = ins.begin(); i != ins.end(); ++i) { string path = i->Evaluate(env); - string path_err; + if (path.empty()) + return lexer_.Error("empty path", err); uint64_t slash_bits; - if (!CanonicalizePath(&path, &slash_bits, &path_err)) - return lexer_.Error(path_err, err); + CanonicalizePath(&path, &slash_bits); state_->AddIn(edge, path, slash_bits); } edge->implicit_deps_ = implicit; edge->order_only_deps_ = order_only; + edge->validations_.reserve(validations.size()); + for (std::vector<EvalString>::iterator v = validations.begin(); + v != validations.end(); ++v) { + string path = v->Evaluate(env); + if (path.empty()) + return lexer_.Error("empty path", err); + uint64_t slash_bits; + CanonicalizePath(&path, &slash_bits); + state_->AddValidation(edge, path, slash_bits); + } + if (options_.phony_cycle_action_ == kPhonyCycleActionWarn && edge->maybe_phonycycle_diagnostic()) { // CMake 2.8.12.x and 3.0.x incorrectly write phony build statements @@ -387,8 +408,7 @@ bool ManifestParser::ParseEdge(string* err) { string dyndep = edge->GetUnescapedDyndep(); if (!dyndep.empty()) { uint64_t slash_bits; - if (!CanonicalizePath(&dyndep, &slash_bits, err)) - return false; + CanonicalizePath(&dyndep, &slash_bits); edge->dyndep_ = state_->GetNode(dyndep, slash_bits); edge->dyndep_->set_dyndep_pending(true); vector<Node*>::iterator dgi = |