diff options
author | David 'Digit' Turner <digit+github@google.com> | 2024-03-13 15:26:47 (GMT) |
---|---|---|
committer | David 'Digit' Turner <digit+github@google.com> | 2024-03-15 21:43:16 (GMT) |
commit | 9792634a1762e74552ac14ffc51a81fa5a3f353e (patch) | |
tree | 1e2c1c09ba3d228263544b8fe3f8e6b900ff9278 /src | |
parent | ab510c7a8cccbea0ea2c82531dc23893b551d55e (diff) | |
download | Ninja-9792634a1762e74552ac14ffc51a81fa5a3f353e.zip Ninja-9792634a1762e74552ac14ffc51a81fa5a3f353e.tar.gz Ninja-9792634a1762e74552ac14ffc51a81fa5a3f353e.tar.bz2 |
Support empty depfiles.
Some tools generate completely empty depfiles when
there are no implicit inputs. This patch modifies the
depfile parser to support them.
Fixes #2357
Diffstat (limited to 'src')
-rw-r--r-- | src/depfile_parser.cc | 4 | ||||
-rw-r--r-- | src/depfile_parser.in.cc | 4 | ||||
-rw-r--r-- | src/depfile_parser_test.cc | 21 |
3 files changed, 27 insertions, 2 deletions
diff --git a/src/depfile_parser.cc b/src/depfile_parser.cc index 98fba2e..7ce7290 100644 --- a/src/depfile_parser.cc +++ b/src/depfile_parser.cc @@ -54,6 +54,7 @@ bool DepfileParser::Parse(string* content, string* err) { bool have_target = false; bool parsing_targets = true; bool poisoned_input = false; + bool is_empty = true; while (in < end) { bool have_newline = false; // out: current output point (typically same as in, but can fall behind @@ -335,6 +336,7 @@ yy32: } if (len > 0) { + is_empty = false; StringPiece piece = StringPiece(filename, len); // If we've seen this as an input before, skip it. std::vector<StringPiece>::iterator pos = std::find(ins_.begin(), ins_.end(), piece); @@ -363,7 +365,7 @@ yy32: poisoned_input = false; } } - if (!have_target) { + if (!have_target && !is_empty) { *err = "expected ':' in depfile"; return false; } diff --git a/src/depfile_parser.in.cc b/src/depfile_parser.in.cc index 75ba982..4b5f5fe 100644 --- a/src/depfile_parser.in.cc +++ b/src/depfile_parser.in.cc @@ -53,6 +53,7 @@ bool DepfileParser::Parse(string* content, string* err) { bool have_target = false; bool parsing_targets = true; bool poisoned_input = false; + bool is_empty = true; while (in < end) { bool have_newline = false; // out: current output point (typically same as in, but can fall behind @@ -171,6 +172,7 @@ bool DepfileParser::Parse(string* content, string* err) { } if (len > 0) { + is_empty = false; StringPiece piece = StringPiece(filename, len); // If we've seen this as an input before, skip it. std::vector<StringPiece>::iterator pos = std::find(ins_.begin(), ins_.end(), piece); @@ -199,7 +201,7 @@ bool DepfileParser::Parse(string* content, string* err) { poisoned_input = false; } } - if (!have_target) { + if (!have_target && !is_empty) { *err = "expected ':' in depfile"; return false; } diff --git a/src/depfile_parser_test.cc b/src/depfile_parser_test.cc index 8886258..947ae76 100644 --- a/src/depfile_parser_test.cc +++ b/src/depfile_parser_test.cc @@ -378,3 +378,24 @@ TEST_F(DepfileParserTest, BuggyMP) { "z:\n", &err)); ASSERT_EQ("inputs may not also have inputs", err); } + +TEST_F(DepfileParserTest, EmptyFile) { + std::string err; + EXPECT_TRUE(Parse("", &err)); + ASSERT_EQ(0u, parser_.outs_.size()); + ASSERT_EQ(0u, parser_.ins_.size()); +} + +TEST_F(DepfileParserTest, EmptyLines) { + std::string err; + EXPECT_TRUE(Parse("\n\n", &err)); + ASSERT_EQ(0u, parser_.outs_.size()); + ASSERT_EQ(0u, parser_.ins_.size()); +} + +TEST_F(DepfileParserTest, MissingColon) { + // The file is not empty but is missing a colon separator. + std::string err; + EXPECT_FALSE(Parse("foo.o foo.c\n", &err)); + EXPECT_EQ("expected ':' in depfile", err); +} |