diff options
author | Evan Martin <martine@danga.com> | 2012-03-13 06:28:18 (GMT) |
---|---|---|
committer | Evan Martin <martine@danga.com> | 2012-03-13 06:28:18 (GMT) |
commit | eca6bbe32bf3d1263ed1173a774f9d91c9b0f415 (patch) | |
tree | a8220600abd6f31fb3f9e7debc42b0c2589cc0f8 /src | |
parent | fffab7c868482cb8d24f40b42de958c074480226 (diff) | |
parent | 73af0ec4d0074ce1e9b1677b3525ed92f5fd00c7 (diff) | |
download | Ninja-eca6bbe32bf3d1263ed1173a774f9d91c9b0f415.zip Ninja-eca6bbe32bf3d1263ed1173a774f9d91c9b0f415.tar.gz Ninja-eca6bbe32bf3d1263ed1173a774f9d91c9b0f415.tar.bz2 |
Merge pull request #245 from usovalx/unify_depfile_targets
Issue #241 - handle depfiles generated by older versions of GCC
Diffstat (limited to 'src')
-rw-r--r-- | src/depfile_parser.cc | 16 | ||||
-rw-r--r-- | src/depfile_parser.in.cc | 16 | ||||
-rw-r--r-- | src/depfile_parser_test.cc | 17 |
3 files changed, 41 insertions, 8 deletions
diff --git a/src/depfile_parser.cc b/src/depfile_parser.cc index 8f8f9fe..7219eb0 100644 --- a/src/depfile_parser.cc +++ b/src/depfile_parser.cc @@ -32,8 +32,10 @@ bool DepfileParser::Parse(string* content, string* err) { // in: current parser input point. // end: end of input. + // parsing_targets: whether we are parsing targets or dependencies. char* in = &(*content)[0]; char* end = in + content->size(); + bool parsing_targets = true; while (in < end) { // out: current output point (typically same as in, but can fall behind // as we de-escape backslashes). @@ -180,16 +182,22 @@ yy13: } int len = out - filename; - if (len > 0 && filename[len - 1] == ':') + const bool is_target = parsing_targets; + if (len > 0 && filename[len - 1] == ':') { len--; // Strip off trailing colon, if any. + parsing_targets = false; + } if (len == 0) continue; - if (!out_.str_) { - out_ = StringPiece(filename, len); - } else { + if (!is_target) { ins_.push_back(StringPiece(filename, len)); + } else if (!out_.str_) { + out_ = StringPiece(filename, len); + } else if (out_ != StringPiece(filename, len)) { + *err = "depfile has multiple output paths."; + return false; } } return true; diff --git a/src/depfile_parser.in.cc b/src/depfile_parser.in.cc index de1c38f..419ed8d 100644 --- a/src/depfile_parser.in.cc +++ b/src/depfile_parser.in.cc @@ -31,8 +31,10 @@ bool DepfileParser::Parse(string* content, string* err) { // in: current parser input point. // end: end of input. + // parsing_targets: whether we are parsing targets or dependencies. char* in = &(*content)[0]; char* end = in + content->size(); + bool parsing_targets = true; while (in < end) { // out: current output point (typically same as in, but can fall behind // as we de-escape backslashes). @@ -87,16 +89,22 @@ bool DepfileParser::Parse(string* content, string* err) { } int len = out - filename; - if (len > 0 && filename[len - 1] == ':') + const bool is_target = parsing_targets; + if (len > 0 && filename[len - 1] == ':') { len--; // Strip off trailing colon, if any. + parsing_targets = false; + } if (len == 0) continue; - if (!out_.str_) { - out_ = StringPiece(filename, len); - } else { + if (!is_target) { ins_.push_back(StringPiece(filename, len)); + } else if (!out_.str_) { + out_ = StringPiece(filename, len); + } else if (out_ != StringPiece(filename, len)) { + *err = "depfile has multiple output paths."; + return false; } } return true; diff --git a/src/depfile_parser_test.cc b/src/depfile_parser_test.cc index 43e677c..883926a 100644 --- a/src/depfile_parser_test.cc +++ b/src/depfile_parser_test.cc @@ -102,3 +102,20 @@ TEST_F(DepfileParserTest, Escapes) { parser_.out_.AsString()); ASSERT_EQ(0u, parser_.ins_.size()); } + +TEST_F(DepfileParserTest, UnifyMultupleOutputs) { + // check that multiple duplicate targets are properly unified + string err; + EXPECT_TRUE(Parse("foo foo: x y z", &err)); + ASSERT_EQ(parser_.out_.AsString(), "foo"); + ASSERT_EQ(parser_.ins_.size(), 3); + EXPECT_EQ("x", parser_.ins_[0].AsString()); + EXPECT_EQ("y", parser_.ins_[1].AsString()); + EXPECT_EQ("z", parser_.ins_[2].AsString()); +} + +TEST_F(DepfileParserTest, RejectMultipleDifferentOutputs) { + // check that multiple different outputs are rejected by the parser + string err; + EXPECT_FALSE(Parse("foo bar: x y z", &err)); +} |