attempt to split cmd line into words in the same way as Windows does
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@24177 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -1121,24 +1121,10 @@ static wxString GetLongOptionName(const wxChar *p)
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
This function is mainly used under Windows (as under Unix we always get the
|
This function is mainly used under Windows (as under Unix we always get the
|
||||||
command line arguments as argc/argv anyhow) and so it tries to handle the
|
command line arguments as argc/argv anyhow) and so it tries to follow
|
||||||
Windows path names (separated by backslashes) correctly. For this it only
|
Windows conventions for the command line handling, not Unix ones. For
|
||||||
considers that a backslash may be used to escape another backslash (but
|
instance, backslash is not special except when it precedes double quote when
|
||||||
normally this is _not_ needed) or a quote but nothing else.
|
it does quote it.
|
||||||
|
|
||||||
In particular, to pass a single argument containing a space to the program
|
|
||||||
it should be quoted:
|
|
||||||
|
|
||||||
myprog.exe foo bar -> argc = 3, argv[1] = "foo", argv[2] = "bar"
|
|
||||||
myprog.exe "foo bar" -> argc = 2, argv[1] = "foo bar"
|
|
||||||
|
|
||||||
To pass an argument containing spaces and quotes, the latter should be
|
|
||||||
escaped with a backslash:
|
|
||||||
|
|
||||||
myprog.exe "foo \"bar\"" -> argc = 2, argv[1] = "foo "bar""
|
|
||||||
|
|
||||||
This hopefully matches the conventions used by Explorer/command line
|
|
||||||
interpreter under Windows. If not, this function should be fixed.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* static */
|
/* static */
|
||||||
@@ -1149,7 +1135,7 @@ wxArrayString wxCmdLineParser::ConvertStringToArgs(const wxChar *p)
|
|||||||
wxString arg;
|
wxString arg;
|
||||||
arg.reserve(1024);
|
arg.reserve(1024);
|
||||||
|
|
||||||
bool isInsideQuotes = FALSE;
|
bool isInsideQuotes = false;
|
||||||
for ( ;; )
|
for ( ;; )
|
||||||
{
|
{
|
||||||
// skip white space
|
// skip white space
|
||||||
@@ -1161,80 +1147,43 @@ wxArrayString wxCmdLineParser::ConvertStringToArgs(const wxChar *p)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
// parse this parameter
|
// parse this parameter
|
||||||
arg.clear();
|
bool endParam = false;
|
||||||
for ( ;; p++ )
|
bool lastBS = false;
|
||||||
|
for ( arg.clear(); !endParam; p++ )
|
||||||
{
|
{
|
||||||
// do we have a (lone) backslash?
|
|
||||||
bool isQuotedByBS = FALSE;
|
|
||||||
while ( *p == _T('\\') )
|
|
||||||
{
|
|
||||||
p++;
|
|
||||||
|
|
||||||
// if we have 2 backslashes in a row, output one
|
|
||||||
// unless it looks like a UNC path \\machine\dir\file.ext
|
|
||||||
if ( isQuotedByBS || arg.Len() == 0 )
|
|
||||||
{
|
|
||||||
arg += _T('\\');
|
|
||||||
isQuotedByBS = FALSE;
|
|
||||||
}
|
|
||||||
else // the next char is quoted
|
|
||||||
{
|
|
||||||
isQuotedByBS = TRUE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool skipChar = FALSE,
|
|
||||||
endParam = FALSE;
|
|
||||||
switch ( *p )
|
switch ( *p )
|
||||||
{
|
{
|
||||||
case _T('"'):
|
case _T('"'):
|
||||||
if ( !isQuotedByBS )
|
if ( !lastBS )
|
||||||
{
|
{
|
||||||
// don't put the quote itself in the arg
|
|
||||||
skipChar = TRUE;
|
|
||||||
|
|
||||||
isInsideQuotes = !isInsideQuotes;
|
isInsideQuotes = !isInsideQuotes;
|
||||||
}
|
|
||||||
//else: insert a literal quote
|
|
||||||
|
|
||||||
|
// don't put quote in arg
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
//else: quote has no special meaning but the backslash
|
||||||
|
// still remains -- makes no sense but this is what
|
||||||
|
// Windows does
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case _T(' '):
|
case _T(' '):
|
||||||
case _T('\t'):
|
case _T('\t'):
|
||||||
// we intentionally don't check for preceding backslash
|
// backslash does *not* quote the space, only quotes do
|
||||||
// here as if we allowed it to be used to escape spaces the
|
|
||||||
// cmd line of the form "foo.exe a:\ c:\bar" wouldn't be
|
|
||||||
// parsed correctly
|
|
||||||
if ( isInsideQuotes )
|
if ( isInsideQuotes )
|
||||||
{
|
{
|
||||||
// preserve it, skip endParam below
|
// skip assignment below
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
//else: fall through
|
// fall through
|
||||||
|
|
||||||
case _T('\0'):
|
case _T('\0'):
|
||||||
endParam = TRUE;
|
endParam = TRUE;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
|
||||||
if ( isQuotedByBS )
|
|
||||||
{
|
|
||||||
// ignore backslash before an ordinary character - this
|
|
||||||
// is needed to properly handle the file names under
|
|
||||||
// Windows appearing in the command line
|
|
||||||
arg += _T('\\');
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// end of argument?
|
lastBS = *p == _T('\\');
|
||||||
if ( endParam )
|
|
||||||
break;
|
|
||||||
|
|
||||||
// otherwise copy this char to arg
|
arg += *p;
|
||||||
if ( !skipChar )
|
|
||||||
{
|
|
||||||
arg += *p;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
args.push_back(arg);
|
args.push_back(arg);
|
||||||
|
Reference in New Issue
Block a user