summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNicolas Despres <nicolas.despres@gmail.com>2016-05-24 10:12:28 (GMT)
committerNicolas Despres <nicolas.despres@gmail.com>2016-05-25 07:11:38 (GMT)
commitccaa3d1c9c8a581ce0cd696a3b0d6ab713908e40 (patch)
tree542cd73d33789eb7b979d3b23223baf8dc603fea
parent63a8584b069a32b871237fc80dcb4c397b863ef7 (diff)
downloadNinja-ccaa3d1c9c8a581ce0cd696a3b0d6ab713908e40.zip
Ninja-ccaa3d1c9c8a581ce0cd696a3b0d6ab713908e40.tar.gz
Ninja-ccaa3d1c9c8a581ce0cd696a3b0d6ab713908e40.tar.bz2
Parser accepts no explicit outputs.
There is a class of commands that take an output directory where they create their output files. Among them are cp(1), tar(1) to name a few. These commands have one or more implicit outputs but no explicit output. With this patch, Ninja's parser accepts build edge with an empty list of explicit outputs.
-rw-r--r--src/graph_test.cc39
-rw-r--r--src/manifest_parser.cc10
-rw-r--r--src/manifest_parser_test.cc5
3 files changed, 45 insertions, 9 deletions
diff --git a/src/graph_test.cc b/src/graph_test.cc
index 723e8ea..be08b19 100644
--- a/src/graph_test.cc
+++ b/src/graph_test.cc
@@ -149,6 +149,45 @@ TEST_F(GraphTest, ImplicitOutputOutOfDate) {
EXPECT_TRUE(GetNode("out.imp")->dirty());
}
+TEST_F(GraphTest, ImplicitOutputOnlyParse) {
+ ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
+"build | out.imp: cat in\n"));
+
+ Edge* edge = GetNode("out.imp")->in_edge();
+ EXPECT_EQ(1, edge->outputs_.size());
+ EXPECT_EQ("out.imp", edge->outputs_[0]->path());
+ EXPECT_EQ(1, edge->implicit_outs_);
+ EXPECT_EQ(edge, GetNode("out.imp")->in_edge());
+}
+
+TEST_F(GraphTest, ImplicitOutputOnlyMissing) {
+ ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
+"build | out.imp: cat in\n"));
+ fs_.Create("in", "");
+
+ Edge* edge = GetNode("out.imp")->in_edge();
+ string err;
+ EXPECT_TRUE(scan_.RecomputeDirty(edge, &err));
+ ASSERT_EQ("", err);
+
+ EXPECT_TRUE(GetNode("out.imp")->dirty());
+}
+
+TEST_F(GraphTest, ImplicitOutputOnlyOutOfDate) {
+ ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
+"build | out.imp: cat in\n"));
+ fs_.Create("out.imp", "");
+ fs_.Tick();
+ fs_.Create("in", "");
+
+ Edge* edge = GetNode("out.imp")->in_edge();
+ string err;
+ EXPECT_TRUE(scan_.RecomputeDirty(edge, &err));
+ ASSERT_EQ("", err);
+
+ EXPECT_TRUE(GetNode("out.imp")->dirty());
+}
+
TEST_F(GraphTest, PathWithCurrentDirectory) {
ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
"rule catdep\n"
diff --git a/src/manifest_parser.cc b/src/manifest_parser.cc
index a4f489e..d6dcf22 100644
--- a/src/manifest_parser.cc
+++ b/src/manifest_parser.cc
@@ -236,16 +236,13 @@ bool ManifestParser::ParseEdge(string* err) {
EvalString out;
if (!lexer_.ReadPath(&out, err))
return false;
- if (out.empty())
- return lexer_.Error("expected path", err);
-
- do {
+ while (!out.empty()) {
outs.push_back(out);
out.Clear();
if (!lexer_.ReadPath(&out, err))
return false;
- } while (!out.empty());
+ }
}
// Add all implicit outs, counting how many as we go.
@@ -262,6 +259,9 @@ bool ManifestParser::ParseEdge(string* err) {
}
}
+ if (outs.empty())
+ return lexer_.Error("expected path", err);
+
if (!ExpectToken(Lexer::COLON, err))
return false;
diff --git a/src/manifest_parser_test.cc b/src/manifest_parser_test.cc
index 1312d26..3c82dc5 100644
--- a/src/manifest_parser_test.cc
+++ b/src/manifest_parser_test.cc
@@ -976,13 +976,10 @@ TEST_F(ParserTest, ImplicitOutputDupes) {
TEST_F(ParserTest, NoExplicitOutput) {
ManifestParser parser(&state, NULL, kDupeEdgeActionWarn);
string err;
- EXPECT_FALSE(parser.ParseTest(
+ EXPECT_TRUE(parser.ParseTest(
"rule cat\n"
" command = cat $in > $out\n"
"build | imp : cat bar\n", &err));
- ASSERT_EQ("input:3: expected path\n"
- "build | imp : cat bar\n"
- " ^ near here", err);
}
TEST_F(ParserTest, DefaultDefault) {