summaryrefslogtreecommitdiff
path: root/src/manifest_parser.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/manifest_parser.cc')
-rw-r--r--src/manifest_parser.cc68
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 =