diff options
author | Nico Weber <nicolasweber@gmx.de> | 2013-04-02 16:39:05 (GMT) |
---|---|---|
committer | Nico Weber <nicolasweber@gmx.de> | 2013-04-02 16:39:07 (GMT) |
commit | e2701da32d223f2ce165f2e59c2c396da80debc6 (patch) | |
tree | 37235867d7eee7e7438c1a46d0d7cb3a308f6dcb | |
parent | 7ab6dcbdb6447861eefafc47fc3e10f3273cede2 (diff) | |
download | Ninja-e2701da32d223f2ce165f2e59c2c396da80debc6.zip Ninja-e2701da32d223f2ce165f2e59c2c396da80debc6.tar.gz Ninja-e2701da32d223f2ce165f2e59c2c396da80debc6.tar.bz2 |
Dollar signs in depfiles are escaped as "$$", not "\$".
See http://llvm.org/PR15642. I checked that gcc does produce depfiles
containing "$$" for files with "$" signs in their name (and as of
r178540, so does clang). I also checked that .d files that escape dollar
signs with "\$" are not read correctly by make.
-rw-r--r-- | src/depfile_parser.cc | 77 | ||||
-rw-r--r-- | src/depfile_parser.in.cc | 7 | ||||
-rw-r--r-- | src/depfile_parser_test.cc | 2 |
3 files changed, 54 insertions, 32 deletions
diff --git a/src/depfile_parser.cc b/src/depfile_parser.cc index c8fb92e..5a30c6b 100644 --- a/src/depfile_parser.cc +++ b/src/depfile_parser.cc @@ -84,44 +84,48 @@ bool DepfileParser::Parse(string* content, string* err) { }; yych = *in; - if (yych <= '\\') { - if (yych <= '=') { - if (yych <= 0x00) goto yy6; - if (yych <= ' ') goto yy8; + if (yych <= '[') { + if (yych <= '$') { + if (yych <= 0x00) goto yy7; + if (yych <= ' ') goto yy9; + if (yych <= '#') goto yy6; goto yy4; } else { - if (yych <= '?') goto yy8; - if (yych <= 'Z') goto yy4; - if (yych <= '[') goto yy8; + if (yych <= '=') goto yy6; + if (yych <= '?') goto yy9; + if (yych <= 'Z') goto yy6; + goto yy9; } } else { if (yych <= '`') { - if (yych == '_') goto yy4; - goto yy8; + if (yych <= '\\') goto yy2; + if (yych == '_') goto yy6; + goto yy9; } else { - if (yych <= 'z') goto yy4; - if (yych == '~') goto yy4; - goto yy8; + if (yych <= 'z') goto yy6; + if (yych == '~') goto yy6; + goto yy9; } } +yy2: ++in; - if ((yych = *in) <= '$') { + if ((yych = *in) <= '#') { if (yych <= '\n') { if (yych <= 0x00) goto yy3; - if (yych <= '\t') goto yy11; + if (yych <= '\t') goto yy14; } else { - if (yych == ' ') goto yy13; - if (yych <= '"') goto yy11; - goto yy13; + if (yych == ' ') goto yy16; + if (yych <= '"') goto yy14; + goto yy16; } } else { if (yych <= 'Z') { - if (yych == '*') goto yy13; - goto yy11; + if (yych == '*') goto yy16; + goto yy14; } else { - if (yych <= '\\') goto yy13; - if (yych == '|') goto yy13; - goto yy11; + if (yych <= '\\') goto yy16; + if (yych == '|') goto yy16; + goto yy14; } } yy3: @@ -132,8 +136,8 @@ yy3: } yy4: ++in; - yych = *in; - goto yy10; + if ((yych = *in) == '$') goto yy12; + goto yy11; yy5: { // Got a span of plain text. @@ -145,22 +149,35 @@ yy5: continue; } yy6: + yych = *++in; + goto yy11; +yy7: ++in; { break; } -yy8: +yy9: yych = *++in; goto yy3; -yy9: +yy10: ++in; yych = *in; -yy10: +yy11: if (yybm[0+yych] & 128) { - goto yy9; + goto yy10; } goto yy5; -yy11: +yy12: + ++in; + if (yybm[0+(yych = *in)] & 128) { + goto yy10; + } + { + // De-escape dollar character. + *out++ = '$'; + continue; + } +yy14: ++in; { // Let backslash before other characters through verbatim. @@ -168,7 +185,7 @@ yy11: *out++ = yych; continue; } -yy13: +yy16: ++in; { // De-escape backslashed character. diff --git a/src/depfile_parser.in.cc b/src/depfile_parser.in.cc index f96cdb3..cf24a09 100644 --- a/src/depfile_parser.in.cc +++ b/src/depfile_parser.in.cc @@ -55,13 +55,18 @@ bool DepfileParser::Parse(string* content, string* err) { re2c:indent:string = " "; nul = "\000"; - escape = [ \\#*$[|]; + escape = [ \\#*[|]; '\\' escape { // De-escape backslashed character. *out++ = yych; continue; } + '$$' { + // De-escape dollar character. + *out++ = '$'; + continue; + } '\\' [^\000\n] { // Let backslash before other characters through verbatim. *out++ = '\\'; diff --git a/src/depfile_parser_test.cc b/src/depfile_parser_test.cc index 552975c..0f6771a 100644 --- a/src/depfile_parser_test.cc +++ b/src/depfile_parser_test.cc @@ -95,7 +95,7 @@ TEST_F(DepfileParserTest, Escapes) { // it through. string err; EXPECT_TRUE(Parse( -"\\!\\@\\#\\$\\%\\^\\&\\\\", +"\\!\\@\\#$$\\%\\^\\&\\\\", &err)); ASSERT_EQ("", err); EXPECT_EQ("\\!\\@#$\\%\\^\\&\\", |