Re: [RFC] Do not treat '\' as escape character on MinGW Windows hosts

Joel Brobecker
2010-04-22T11:51:56Z

[-- Attachment #1: Type: text/plain, Size: 5082 bytes --]

Ooops - I had intended to start this email thread on GCC-patches,
Cc'ing GDB-patches, but I made a typo, and sent it to GDB-patches
Cc'ing the very same GDB-patches. I hope you'll forgive the cross post,
but since this is common code...

Here is what has been discussed, so far... I'm mostly trying to discuss
the idea of making backslash a normal character as opposed to an escape
character in arguments when on (MinGW) windows, whether the idea gets
sufficiently positive feedback that we can move ahead an implement this
suggestion (patch attached FYI).

Joel Brobecker:
> With the MinGW debugger, it is currently not possible to use a path
> that follows the Windows convention. For instance:
>
> (gdb) file c:\foo\bar.exe
> c:foobar.exe: No such file or directory.
>
> This is because the routine that parses arguments treats all backslashes
> as an escape character. With a MinGW tool, this does not make sense
> when the argument is a path, since the canonical directory separator
> on Windows is a backslash...
>
> What the user has to do, at this point, is escape every backslash,
> which can be quite painful when the path starts getting longer...
>
> (gdb) file c:\\foo\\bar.exe
> Reading symbols from c:\foo\bar.exe...done.
>
> What we have done, at AdaCore, is disabling the special nature of
> the backslash character when the host is MinGW (we left cygwin alone,
> since cygwin users most likely expect a unix-y type of behavior).
> It's a incompatible change, and as you'll see with the attached patch,
> it changes the behavior for all arguments, not just path names.
> Polling the few Windows users we have a AdaCore, they all seem to agree
> that they did not expect backslash to be a special character in any
> context, so the change seemed right to them.
>
> Before officially submitting this patch for inclusion (including
> formal testing), I wanted to see what the feeling towards this sort
> of change was...
>
> Note that GDB uses a wrapper around this routine, mostly to add
> an out-of-memory exception raised when the routine returns null.
> One possible way of achieving the same result, while limiting the
> change to GDB alone, would be to modify the gdb_buildargv routine
> to escape all backslashes before calling libiberty's buildargv.
> But I think that other tools should also consider this change as
> beneficial.

Chris Faylor:
> > (gdb) file c:\\foo\\bar.exe
> > Reading symbols from c:\foo\bar.exe...done.
> Why not just use a "forward" slash?

Joel Brobecker:
> It's not always that easy - A lot of times, the user wants to copy/paste
> a path that's been printed by another tool. Also, the typical Windows
> user seems to think that he should be able to use a valid Windows path
> (which I agree)...

Chris Faylor:
> >It's not always that easy - A lot of times, the user wants to copy/paste
> >a path that's been printed by another tool. Also, the typical Windows
> >user seems to think that he should be able to use a valid Windows path
> >(which I agree)...
>
> I agree too except when we're talking about something that is
> essentially a UNIX tool. And, I don't see how you can talk about the
> pain of doubling up the backslashes if you're talking about cutting and
> pasting.
>
> I know I'll be outvoted here but I I hate cluttering code with MS-DOS
> workarounds.

Mark Kettenis:
> > I know I'll be outvoted here but I I hate cluttering code with MS-DOS
> > workarounds.
>
> You're not alone.

Joel Brobecker answered Chris:
> > I agree too except when we're talking about something that is
> > essentially a UNIX tool. And, I don't see how you can talk about the
> > pain of doubling up the backslashes if you're talking about cutting and
> > pasting.
>
> Perhaps I shouldn't have based some of my argumentation on convenience,
> since the degree of convenience varies from user to user [1], and thus
> is a weak argument at best.
>
> What we need to decide, as a group, is whether GDB is indeed a Unix tool,
> and whether GDB should treat the Windows users as Unix users stuck on
> Windows (I definitely feel that way everytime I have to do Windows work).
> However, my observation of the group of users that sent me some feedback
> do not have that perception at all. For them GDB is just a tool, not
> a Unix tool, so they do not understand why GDB does not accept valid
> Windows paths.
>
> > I know I'll be outvoted here but I I hate cluttering code with MS-DOS
> > workarounds.
>
> Understood, and it's not obvious to me that you'll be outvoted. This
> is why I am asking for comments more than a review at this point.
> I would like to challenge the "workaround" term, though :-P. I much as
> I dislike Windows (and believe me, I really dislike this platform),
> I think that if we are going to support Windows, we should support it
> as a first class citizen.
>
> --
> Joel
>
> [1]: Most of my Windows work is done remotely from a Linux machine,
> where copy/pasting is super easy (I have ctrl-y configured to paste
> in my xterm).

--
Joel

[-- Attachment #2: argv-mingw.diff --]
[-- Type: text/x-diff, Size: 1104 bytes --]

diff --git a/libiberty/argv.c b/libiberty/argv.c
index 3084248..b5cf71f 100644
--- a/libiberty/argv.c
+++ b/libiberty/argv.c
@@ -177,7 +177,8 @@ returned, as appropriate.

*/

-char **buildargv (const char *input)
+char **
+buildargv (const char *input)
{
char *arg;
char *copybuf;
@@ -189,6 +190,15 @@ char **buildargv (const char *input)
char **argv = NULL;
char **nargv;

+/* On Windows hosts, the backslash character should not be treated
+ as an escape character. Define a constant bs_is_escape whose value
+ is non-zero when the backslash is an escape character. */
+#if !defined (__MINGW32__)
+ const int bs_is_escape = 1;
+#else
+ const int bs_is_escape = 0;
+#endif
+
if (input != NULL)
{
copybuf = (char *) alloca (strlen (input) + 1);
@@ -234,12 +244,12 @@ char **buildargv (const char *input)
}
else
{
- if (bsquote)
+ if (bs_is_escape && bsquote)
{
bsquote = 0;
*arg++ = *input;
}
- else if (*input == '\\')
+ else if (bs_is_escape && (*input == '\\'))
{
bsquote = 1;
}