When quoting a shell command argument (using shell_quoting_style or shell_always_quoting_style), quotearg.c uses the '..' style of quoting. This doesn't work for MinGW, which supports only the ".." style. This causes, e.g., diff3 to fail for file names with embedded whitespace or other special characters, when compiled for MinGW.
The changes to quotearg.c to support this are quite minor. The following somewhat kludgey change demonstrates what needs to be done. Is there a more elegant way? 2012-05-05 Eli Zaretskii <e...@gnu.org> * lib/quotearg.c (shell_quoting_char): New static variable. [__MINGW32__]: Set shell_quoting_char to '"'. (quotearg_buffer_restyled): Use shell_quoting_char instead of literal '\''. --- lib/quotearg.c~0 2011-05-18 21:31:30.000000000 +0300 +++ lib/quotearg.c 2012-05-05 19:40:41.904625000 +0300 @@ -91,6 +91,13 @@ enum quoting_style const quoting_style_v /* The default quoting options. */ static struct quoting_options default_quoting_options; +/* The (system-dependent) shell quoting character. */ +#ifdef __MINGW32__ +static int shell_quoting_char = '"'; +#else +static int shell_quoting_char = '\''; +#endif + /* Allocate a new set of quoting options, with contents initially identical to O if O is not null, or to the default if O is null. It is the caller's responsibility to free the result. */ @@ -286,8 +293,11 @@ quotearg_buffer_restyled (char *buffer, /* Fall through. */ case shell_always_quoting_style: if (!elide_outer_quotes) - STORE ('\''); - quote_string = "'"; + STORE (shell_quoting_char); + if (shell_quoting_char == '\'') + quote_string = "'"; + else + quote_string = "\""; quote_string_len = 1; break; @@ -389,7 +399,10 @@ quotearg_buffer_restyled (char *buffer, case '\r': esc = 'r'; goto c_and_shell_escape; case '\t': esc = 't'; goto c_and_shell_escape; case '\v': esc = 'v'; goto c_escape; - case '\\': esc = c; + case '\\': + if (shell_quoting_char == '"') + break; + esc = c; /* No need to escape the escape if we are trying to elide outer quotes and nothing else is problematic. */ if (backslash_escapes && elide_outer_quotes && quote_string_len) @@ -429,13 +442,22 @@ quotearg_buffer_restyled (char *buffer, be the first bytes of multibyte characters, which means we should check them with mbrtowc, but in practice this doesn't happen so it's not worth worrying about. */ - if (quoting_style == shell_always_quoting_style - && elide_outer_quotes) - goto force_outer_quoting_style; + if (quoting_style == shell_always_quoting_style) + { + if (elide_outer_quotes) + goto force_outer_quoting_style; + if (c == '"' && c == shell_quoting_char) + { + STORE ('"'); + STORE ('\\'); + STORE ('"'); + } + } break; case '\'': - if (quoting_style == shell_always_quoting_style) + if (quoting_style == shell_always_quoting_style + && shell_quoting_char == '\'') { if (elide_outer_quotes) goto force_outer_quoting_style;