summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNico Weber <nicolasweber@gmx.de>2013-04-02 16:39:05 (GMT)
committerNico Weber <nicolasweber@gmx.de>2013-04-02 16:39:07 (GMT)
commite2701da32d223f2ce165f2e59c2c396da80debc6 (patch)
tree37235867d7eee7e7438c1a46d0d7cb3a308f6dcb
parent7ab6dcbdb6447861eefafc47fc3e10f3273cede2 (diff)
downloadNinja-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.cc77
-rw-r--r--src/depfile_parser.in.cc7
-rw-r--r--src/depfile_parser_test.cc2
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("\\!\\@#$\\%\\^\\&\\",