switch DepfileParser to take a string* to make memory clearer
authorEvan Martin <martine@danga.com>
Tue, 27 Dec 2011 21:48:17 +0000 (13:48 -0800)
committerEvan Martin <martine@danga.com>
Tue, 27 Dec 2011 21:48:17 +0000 (13:48 -0800)
Add some comments as well.

src/depfile_parser.cc
src/depfile_parser.h
src/depfile_parser.in.cc
src/depfile_parser_test.cc
src/graph.cc

index 5e718d9..b547661 100644 (file)
@@ -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.
 
index fd94be9..08bf68a 100644 (file)
@@ -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<StringPiece> ins_;
index 4699e8f..7ac95c6 100644 (file)
 // 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.
 
index 52a1e5c..f867c8e 100644 (file)
 
 #include <gtest/gtest.h>
 
-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());
 }
index 0656bdc..9f7fc76 100644 (file)
@@ -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;
   }