bug-diffutils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[bug-diffutils] [PATCH] quoting in diff3 on win32


From: Claudio Bley
Subject: [bug-diffutils] [PATCH] quoting in diff3 on win32
Date: Thu, 25 Aug 2011 21:58:15 +0200
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/23.1 (gnu/linux)

Hi.

I compiled diffutils for MinGW.

diff3.exe does not work with special characters in path names (like
spaces et cetera) because it does not quote special characters
correctly for the cmd shell when invoking diff.exe.

Here's a patch:

(apply with "patch -p1" inside the toplevel source directory)

--- diffutils-3.0\src\diff3.c   2010-04-15 14:58:08 +0200
+++ diffutils-3.0_mod\src\diff3.c       2011-07-18 15:45:36 +0200
@@ -1133,6 +1133,49 @@
   return type;
 }
 
+#if defined(WIN32) && !defined(__CYGWIN__)
+#  define shell_quote_length cmd_quote_length
+#  define shell_quote_copy   cmd_quote_copy
+
+/* parameter delimiters */
+/* static const char* cmd_delims = ",;= \t"; */
+static const char* cmd_special = "&|><^";
+static const char cmd_escape = '^';
+
+/* enclose in double quotes and escape double quotes with
+ * backslash, escape special chars with ^
+ */
+size_t cmd_quote_length(const char *string) {
+    size_t count = 0;
+    const char* s = string;
+    for (; *s; ++s) {
+        if (strchr(cmd_special, *s) ||
+            *s == '"')
+        {
+            count += 2;
+        } else ++count;
+    }
+    return count + 2;
+}
+
+char *
+shell_quote_copy (char *p, const char *string) {
+    const char* s = string;
+    *p++ = '"';
+    for (; *s; ++s) {
+        if (*s == '"')
+            *p++ = '\\';
+        else if (strchr(cmd_special, *s))
+            *p++ = '^';
+        *p++ = *s;
+    }
+    *p++ = '"';
+    *p = '\0';
+    return p;
+}
+
+#endif
+
 static char *
 read_diff (char const *filea,
           char const *fileb,
@@ -1199,8 +1242,15 @@
                           + sizeof "--strip-trailing-cr"
                           + sizeof args - 1
                           + shell_quote_length (filea) + 1
-                          + shell_quote_length (fileb) + 1);
+                          + shell_quote_length (fileb) + 1
+#if defined(WIN32) && !defined(__CYGWIN__)
+                           + 2  /* enclose _entire_ command in double quotes */
+#endif
+      );
   char *p = command;
+#if defined(WIN32) && !defined(__CYGWIN__)
+  *p++ = '"';
+#endif
   p = shell_quote_copy (p, diff_program);
   if (text)
     {
@@ -1217,6 +1267,9 @@
   p = shell_quote_copy (p, filea);
   *p++ = ' ';
   p = shell_quote_copy (p, fileb);
+#if defined(WIN32) && !defined(__CYGWIN__)
+  *p++ = '"';
+#endif
   *p = 0;
   errno = 0;
   fpipe = popen (command, "r");


Cheers,
-- 
Claudio




reply via email to

[Prev in Thread] Current Thread [Next in Thread]