summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorEvan Martin <martine@danga.com>2011-12-19 19:14:35 (GMT)
committerEvan Martin <martine@danga.com>2011-12-19 19:18:47 (GMT)
commitbbf180d581ada47011c66c735bffdd87cddd0bd1 (patch)
treeeee9a168a0d1ba0f786d1a78bd10d59b82172aa6 /src
parent8b929cf7c82b5ff84a874c5a25e919446c3874d5 (diff)
downloadNinja-bbf180d581ada47011c66c735bffdd87cddd0bd1.zip
Ninja-bbf180d581ada47011c66c735bffdd87cddd0bd1.tar.gz
Ninja-bbf180d581ada47011c66c735bffdd87cddd0bd1.tar.bz2
handle backslashes and isolated colons in depfile parser
The logic was wrong if the input looked like foo : bar baz with a space before the colon. Test from Frances <frances.buontempo@gmail.com>.
Diffstat (limited to 'src')
-rw-r--r--src/depfile_parser.cc60
-rw-r--r--src/depfile_parser.in.cc15
-rw-r--r--src/depfile_parser_test.cc16
3 files changed, 54 insertions, 37 deletions
diff --git a/src/depfile_parser.cc b/src/depfile_parser.cc
index 10ab1d9..b6166e6 100644
--- a/src/depfile_parser.cc
+++ b/src/depfile_parser.cc
@@ -1,5 +1,4 @@
/* Generated by re2c 0.13.5 */
-#line 1 "src/depfile_parser.in.cc"
// Copyright 2011 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
@@ -35,7 +34,6 @@ bool DepfileParser::Parse(const string& content, string* err) {
const char* start = p;
char yych;
-#line 39 "src/depfile_parser.cc"
{
static const unsigned char yybm[] = {
0, 0, 0, 0, 0, 0, 0, 0,
@@ -49,7 +47,7 @@ bool DepfileParser::Parse(const string& content, string* err) {
0, 64, 64, 64, 64, 64, 64, 64,
64, 64, 64, 64, 64, 64, 64, 64,
64, 64, 64, 64, 64, 64, 64, 64,
- 64, 64, 64, 0, 0, 0, 0, 64,
+ 64, 64, 64, 0, 64, 0, 0, 64,
0, 64, 64, 64, 64, 64, 64, 64,
64, 64, 64, 64, 64, 64, 64, 64,
64, 64, 64, 64, 64, 64, 64, 64,
@@ -77,60 +75,59 @@ bool DepfileParser::Parse(const string& content, string* err) {
if (yych <= '@') {
if (yych <= 0x1F) {
if (yych == '\n') goto yy5;
- goto yy8;
+ goto yy7;
} else {
if (yych <= ' ') goto yy5;
- if (yych <= '*') goto yy8;
+ if (yych <= '*') goto yy7;
if (yych <= ':') goto yy6;
- goto yy8;
+ goto yy7;
}
} else {
if (yych <= '^') {
if (yych <= 'Z') goto yy6;
if (yych == '\\') goto yy3;
- goto yy8;
+ goto yy7;
} else {
- if (yych == '`') goto yy8;
+ if (yych == '`') goto yy7;
if (yych <= 'z') goto yy6;
- goto yy8;
+ goto yy7;
}
}
yy2:
-#line 50 "src/depfile_parser.in.cc"
{ continue; }
-#line 102 "src/depfile_parser.cc"
yy3:
++p;
if ((yych = *p) == '\n') goto yy13;
+ goto yy10;
yy4:
-#line 60 "src/depfile_parser.in.cc"
{
- *err = "BUG: depfile lexer encountered unknown state";
- return false;
+ // Got a filename.
+ int len = p - start;;
+ if (start[len - 1] == ':')
+ len--; // Strip off trailing colon, if any.
+
+ if (len == 0)
+ continue; // Drop isolated colons.
+
+ if (!out_.str_) {
+ out_ = StringPiece(start, len);
+ } else {
+ ins_.push_back(StringPiece(start, len));
+ }
+ continue;
}
-#line 112 "src/depfile_parser.cc"
yy5:
yych = *++p;
goto yy12;
yy6:
- ++p;
- yych = *p;
+ yych = *++p;
goto yy10;
yy7:
-#line 51 "src/depfile_parser.in.cc"
+ ++p;
{
- // Got a filename.
- if (p[-1] == ':') {
- out_ = StringPiece(start, p - start - 1);
- } else {
- ins_.push_back(StringPiece(start, p - start));
- }
- continue;
+ *err = "BUG: depfile lexer encountered unknown state";
+ return false;
}
-#line 131 "src/depfile_parser.cc"
-yy8:
- yych = *++p;
- goto yy4;
yy9:
++p;
if (end <= p) break;
@@ -139,7 +136,7 @@ yy10:
if (yybm[0+yych] & 64) {
goto yy9;
}
- goto yy7;
+ goto yy4;
yy11:
++p;
if (end <= p) break;
@@ -151,11 +148,8 @@ yy12:
goto yy2;
yy13:
++p;
-#line 49 "src/depfile_parser.in.cc"
{ continue; }
-#line 157 "src/depfile_parser.cc"
}
-#line 64 "src/depfile_parser.in.cc"
}
return true;
diff --git a/src/depfile_parser.in.cc b/src/depfile_parser.in.cc
index 3d9a77e..8c04bdd 100644
--- a/src/depfile_parser.in.cc
+++ b/src/depfile_parser.in.cc
@@ -48,12 +48,19 @@ bool DepfileParser::Parse(const string& content, string* err) {
'\\\n' { continue; }
[ \n]* { continue; }
- [a-zA-Z0-9+,/_:.-]+ {
+ [a-zA-Z0-9+,/\\_:.-]+ {
// Got a filename.
- if (p[-1] == ':') {
- out_ = StringPiece(start, p - start - 1);
+ int len = p - start;;
+ if (start[len] == ':')
+ len--; // Strip off trailing colon, if any.
+
+ if (len == 0)
+ continue; // Drop isolated colons.
+
+ if (!out_.str_) {
+ out_ = StringPiece(start, len);
} else {
- ins_.push_back(StringPiece(start, p - start));
+ ins_.push_back(StringPiece(start, len));
}
continue;
}
diff --git a/src/depfile_parser_test.cc b/src/depfile_parser_test.cc
index 3258529..52a1e5c 100644
--- a/src/depfile_parser_test.cc
+++ b/src/depfile_parser_test.cc
@@ -48,3 +48,19 @@ TEST(DepfileParser, Continuation) {
EXPECT_EQ("foo.o", parser.out_.AsString());
EXPECT_EQ(2u, parser.ins_.size());
}
+
+TEST(DepfileParser, BackSlashes) {
+ DepfileParser parser;
+ string err;
+ EXPECT_TRUE(parser.Parse(
+"Project\\Dir\\Build\\Release8\\Foo\\Foo.res : \\\n"
+" Dir\\Library\\Foo.rc \\\n"
+" Dir\\Library\\Version\\Bar.h \\\n"
+" Dir\\Library\\Foo.ico \\\n"
+" Project\\Thing\\Bar.tlb \\\n",
+ &err));
+ ASSERT_EQ("", err);
+ EXPECT_EQ("Project\\Dir\\Build\\Release8\\Foo\\Foo.res",
+ parser.out_.AsString());
+ EXPECT_EQ(4u, parser.ins_.size());
+}