Dollar signs in depfiles are escaped as "$$", not "\$".
authorNico Weber <nicolasweber@gmx.de>
Tue, 2 Apr 2013 16:39:05 +0000 (09:39 -0700)
committerNico Weber <nicolasweber@gmx.de>
Tue, 2 Apr 2013 16:39:07 +0000 (09:39 -0700)
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.

src/depfile_parser.cc
src/depfile_parser.in.cc
src/depfile_parser_test.cc

index c8fb92e..5a30c6b 100644 (file)
@@ -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.
index f96cdb3..cf24a09 100644 (file)
@@ -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++ = '\\';
index 552975c..0f6771a 100644 (file)
@@ -95,7 +95,7 @@ TEST_F(DepfileParserTest, Escapes) {
   // it through.
   string err;
   EXPECT_TRUE(Parse(
-"\\!\\@\\#\\$\\%\\^\\&\\\\",
+"\\!\\@\\#$$\\%\\^\\&\\\\",
       &err));
   ASSERT_EQ("", err);
   EXPECT_EQ("\\!\\@#$\\%\\^\\&\\",