diff options
author | Evan Martin <martine@danga.com> | 2011-12-19 19:14:35 (GMT) |
---|---|---|
committer | Evan Martin <martine@danga.com> | 2011-12-19 19:18:47 (GMT) |
commit | bbf180d581ada47011c66c735bffdd87cddd0bd1 (patch) | |
tree | eee9a168a0d1ba0f786d1a78bd10d59b82172aa6 | |
parent | 8b929cf7c82b5ff84a874c5a25e919446c3874d5 (diff) | |
download | Ninja-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>.
-rwxr-xr-x | configure.py | 2 | ||||
-rw-r--r-- | src/depfile_parser.cc | 60 | ||||
-rw-r--r-- | src/depfile_parser.in.cc | 15 | ||||
-rw-r--r-- | src/depfile_parser_test.cc | 16 |
4 files changed, 55 insertions, 38 deletions
diff --git a/configure.py b/configure.py index 400cf42..c342677 100755 --- a/configure.py +++ b/configure.py @@ -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')) 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()); +} |