From fe7e51531e5df3149538007c40b8d115ceebb805 Mon Sep 17 00:00:00 2001 From: Evan Martin Date: Tue, 27 Dec 2011 13:48:17 -0800 Subject: switch DepfileParser to take a string* to make memory clearer Add some comments as well. --- src/depfile_parser.cc | 8 ++++---- src/depfile_parser.h | 5 ++++- src/depfile_parser.in.cc | 11 +++++------ src/depfile_parser_test.cc | 44 ++++++++++++++++++++++++++------------------ src/graph.cc | 2 +- 5 files changed, 40 insertions(+), 30 deletions(-) diff --git a/src/depfile_parser.cc b/src/depfile_parser.cc index 5e718d9..b547661 100644 --- a/src/depfile_parser.cc +++ b/src/depfile_parser.cc @@ -27,9 +27,9 @@ // Rather than implement the above, we do the simpler thing here. // If anyone actually has depfiles that rely on the more complicated // behavior we can adjust this. -bool DepfileParser::Parse(const string& content, string* err) { - const char* p = content.data(); - const char* end = content.data() + content.size(); +bool DepfileParser::Parse(string* content, string* err) { + char* p = &(*content)[0]; + char* end = p + content->size(); for (;;) { const char* start = p; char yych; @@ -98,7 +98,7 @@ bool DepfileParser::Parse(const string& content, string* err) { yy3: { // Got a filename. - int len = p - start;; + int len = p - start; if (start[len - 1] == ':') len--; // Strip off trailing colon, if any. diff --git a/src/depfile_parser.h b/src/depfile_parser.h index fd94be9..08bf68a 100644 --- a/src/depfile_parser.h +++ b/src/depfile_parser.h @@ -18,8 +18,11 @@ using namespace std; #include "string_piece.h" +/// Parser for the dependency information emitted by gcc's -M flags. struct DepfileParser { - bool Parse(const string& content, string* err); + /// Parse an input file. Warning: may mutate the content in-place + /// and parsed StringPieces are pointers within it. + bool Parse(string* content, string* err); StringPiece out_; vector ins_; diff --git a/src/depfile_parser.in.cc b/src/depfile_parser.in.cc index 4699e8f..7ac95c6 100644 --- a/src/depfile_parser.in.cc +++ b/src/depfile_parser.in.cc @@ -26,16 +26,15 @@ // Rather than implement the above, we do the simpler thing here. // If anyone actually has depfiles that rely on the more complicated // behavior we can adjust this. -bool DepfileParser::Parse(const string& content, string* err) { - const char* p = content.data(); - const char* end = content.data() + content.size(); +bool DepfileParser::Parse(string* content, string* err) { + char* p = &(*content)[0]; + char* end = p + content->size(); for (;;) { const char* start = p; char yych; /*!re2c - re2c:define:YYCTYPE = "const char"; + re2c:define:YYCTYPE = "char"; re2c:define:YYCURSOR = p; - re2c:define:YYMARKER = q; re2c:define:YYLIMIT = end; re2c:yyfill:parameter = 0; @@ -50,7 +49,7 @@ bool DepfileParser::Parse(const string& content, string* err) { [ \n]+ { continue; } [a-zA-Z0-9+,/\\_:.-]+ { // Got a filename. - int len = p - start;; + int len = p - start; if (start[len - 1] == ':') len--; // Strip off trailing colon, if any. diff --git a/src/depfile_parser_test.cc b/src/depfile_parser_test.cc index 52a1e5c..f867c8e 100644 --- a/src/depfile_parser_test.cc +++ b/src/depfile_parser_test.cc @@ -16,43 +16,51 @@ #include -TEST(DepfileParser, Basic) { - DepfileParser parser; +struct DepfileParserTest : public testing::Test { + bool Parse(const char* input, string* err); + + DepfileParser parser_; + string input_; +}; + +bool DepfileParserTest::Parse(const char* input, string* err) { + input_ = input; + return parser_.Parse(&input_, err); +} + +TEST_F(DepfileParserTest, Basic) { string err; - EXPECT_TRUE(parser.Parse( + EXPECT_TRUE(Parse( "build/ninja.o: ninja.cc ninja.h eval_env.h manifest_parser.h\n", &err)); ASSERT_EQ("", err); - EXPECT_EQ("build/ninja.o", parser.out_.AsString()); - EXPECT_EQ(4u, parser.ins_.size()); + EXPECT_EQ("build/ninja.o", parser_.out_.AsString()); + EXPECT_EQ(4u, parser_.ins_.size()); } -TEST(DepfileParser, EarlyNewlineAndWhitespace) { - DepfileParser parser; +TEST_F(DepfileParserTest, EarlyNewlineAndWhitespace) { string err; - EXPECT_TRUE(parser.Parse( + EXPECT_TRUE(Parse( " \\\n" " out: in\n", &err)); ASSERT_EQ("", err); } -TEST(DepfileParser, Continuation) { - DepfileParser parser; +TEST_F(DepfileParserTest, Continuation) { string err; - EXPECT_TRUE(parser.Parse( + EXPECT_TRUE(Parse( "foo.o: \\\n" " bar.h baz.h\n", &err)); ASSERT_EQ("", err); - EXPECT_EQ("foo.o", parser.out_.AsString()); - EXPECT_EQ(2u, parser.ins_.size()); + EXPECT_EQ("foo.o", parser_.out_.AsString()); + EXPECT_EQ(2u, parser_.ins_.size()); } -TEST(DepfileParser, BackSlashes) { - DepfileParser parser; +TEST_F(DepfileParserTest, BackSlashes) { string err; - EXPECT_TRUE(parser.Parse( + EXPECT_TRUE(Parse( "Project\\Dir\\Build\\Release8\\Foo\\Foo.res : \\\n" " Dir\\Library\\Foo.rc \\\n" " Dir\\Library\\Version\\Bar.h \\\n" @@ -61,6 +69,6 @@ TEST(DepfileParser, BackSlashes) { &err)); ASSERT_EQ("", err); EXPECT_EQ("Project\\Dir\\Build\\Release8\\Foo\\Foo.res", - parser.out_.AsString()); - EXPECT_EQ(4u, parser.ins_.size()); + parser_.out_.AsString()); + EXPECT_EQ(4u, parser_.ins_.size()); } diff --git a/src/graph.cc b/src/graph.cc index 0656bdc..9f7fc76 100644 --- a/src/graph.cc +++ b/src/graph.cc @@ -220,7 +220,7 @@ bool Edge::LoadDepFile(State* state, DiskInterface* disk_interface, DepfileParser depfile; string depfile_err; - if (!depfile.Parse(content, &depfile_err)) { + if (!depfile.Parse(&content, &depfile_err)) { *err = path + ": " + depfile_err; return false; } -- cgit v0.12