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>.
This commit is contained in:
Evan Martin 2011-12-19 11:14:35 -08:00
parent 8b929cf7c8
commit bbf180d581
4 changed files with 55 additions and 38 deletions

View File

@ -143,7 +143,7 @@ if platform != 'mingw':
n.comment('the depfile parser is generated using re2c.')
n.rule('re2c',
command='re2c -b --no-generation-date -o $out $in',
command='re2c -b -i --no-generation-date -o $out $in',
description='RE2C $out')
# Generate the .cc file in the source directory so we can check it in.
n.build(src('depfile_parser.cc'), 're2c', src('depfile_parser.in.cc'))

View File

@ -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;

View File

@ -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;
}

View File

@ -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());
}