// 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;
yy3:
{
// Got a filename.
- int len = p - start;;
+ int len = p - start;
if (start[len - 1] == ':')
len--; // Strip off trailing colon, if any.
#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_;
// 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;
[ \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.
#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"
&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());
}