implement flag for Unix-like behaviour in wxCmdLineParser::ConverStringToArgs()
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@54648 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
parent
fec42c21ef
commit
a4761b4c08
@ -19,6 +19,13 @@
|
||||
#include "wx/arrstr.h"
|
||||
#include "wx/cmdargs.h"
|
||||
|
||||
// determines ConvertStringToArgs() behaviour
|
||||
enum wxCmdLineSplitType
|
||||
{
|
||||
wxCMD_LINE_SPLIT_DOS,
|
||||
wxCMD_LINE_SPLIT_UNIX
|
||||
};
|
||||
|
||||
#if wxUSE_CMDLINE_PARSER
|
||||
|
||||
class WXDLLIMPEXP_FWD_BASE wxDateTime;
|
||||
@ -233,7 +240,9 @@ public:
|
||||
void Reset();
|
||||
|
||||
// break down the command line in arguments
|
||||
static wxArrayString ConvertStringToArgs(const wxString& cmdline);
|
||||
static wxArrayString
|
||||
ConvertStringToArgs(const wxString& cmdline,
|
||||
wxCmdLineSplitType type = wxCMD_LINE_SPLIT_DOS);
|
||||
|
||||
private:
|
||||
// common part of all ctors
|
||||
@ -251,7 +260,9 @@ private:
|
||||
class WXDLLIMPEXP_BASE wxCmdLineParser
|
||||
{
|
||||
public:
|
||||
static wxArrayString ConvertStringToArgs(const wxString& cmdline);
|
||||
static wxArrayString
|
||||
ConvertStringToArgs(const wxString& cmdline,
|
||||
wxCmdLineSplitType type = wxCMD_LINE_SPLIT_DOS);
|
||||
};
|
||||
|
||||
#endif // wxUSE_CMDLINE_PARSER/!wxUSE_CMDLINE_PARSER
|
||||
|
@ -59,6 +59,15 @@ enum wxCmdLineEntryType
|
||||
wxCMD_LINE_NONE ///< Use this to terminate the list.
|
||||
};
|
||||
|
||||
/**
|
||||
Flags determining ConvertStringToArgs() behaviour.
|
||||
*/
|
||||
enum wxCmdLineSplitType
|
||||
{
|
||||
wxCMD_LINE_SPLIT_DOS,
|
||||
wxCMD_LINE_SPLIT_UNIX
|
||||
};
|
||||
|
||||
/**
|
||||
The structure wxCmdLineEntryDesc is used to describe the one command line
|
||||
switch, option or parameter. An array of such structures should be passed
|
||||
@ -301,12 +310,20 @@ public:
|
||||
bool AreLongOptionsEnabled() const;
|
||||
|
||||
/**
|
||||
Breaks down the string containing the full command line in words. The
|
||||
words are separated by whitespace. The quotes can be used in the input
|
||||
string to quote the white space and the back slashes can be used to
|
||||
quote the quotes.
|
||||
Breaks down the string containing the full command line in words.
|
||||
|
||||
Words are separated by whitespace and double quotes can be used to
|
||||
preserve the spaces inside the words.
|
||||
|
||||
By default, this function uses Windows-like word splitting algorithm,
|
||||
i.e. single quotes have no special meaning and backslash can't be used
|
||||
to escape spaces neither. With @c wxCMD_LINE_SPLIT_UNIX flag Unix
|
||||
semantics is used, i.e. both single and double quotes can be used and
|
||||
backslash can be used to escape all the other special characters.
|
||||
*/
|
||||
static wxArrayString ConvertStringToArgs(const wxChar cmdline);
|
||||
static wxArrayString
|
||||
ConvertStringToArgs(const wxChar cmdline,
|
||||
wxCmdLineSplitType flags = wxCMD_LINE_SPLIT_DOS);
|
||||
|
||||
/**
|
||||
Identical to EnableLongOptions(@false).
|
||||
|
@ -1280,15 +1280,15 @@ static wxString GetLongOptionName(wxString::const_iterator p,
|
||||
*/
|
||||
|
||||
/* static */
|
||||
wxArrayString wxCmdLineParser::ConvertStringToArgs(const wxString& cmdline)
|
||||
wxArrayString
|
||||
wxCmdLineParser::ConvertStringToArgs(const wxString& cmdline,
|
||||
wxCmdLineSplitType type)
|
||||
{
|
||||
wxArrayString args;
|
||||
|
||||
wxString arg;
|
||||
arg.reserve(1024);
|
||||
|
||||
bool isInsideQuotes = false;
|
||||
|
||||
const wxString::const_iterator end = cmdline.end();
|
||||
wxString::const_iterator p = cmdline.begin();
|
||||
|
||||
@ -1303,31 +1303,76 @@ wxArrayString wxCmdLineParser::ConvertStringToArgs(const wxString& cmdline)
|
||||
break;
|
||||
|
||||
// parse this parameter
|
||||
bool lastBS = false;
|
||||
bool lastBS = false,
|
||||
isInsideQuotes = false;
|
||||
wxChar chDelim = '\0';
|
||||
for ( arg.clear(); p != end; ++p )
|
||||
{
|
||||
const wxChar ch = *p;
|
||||
if ( ch == '"' )
|
||||
|
||||
if ( type == wxCMD_LINE_SPLIT_DOS )
|
||||
{
|
||||
if ( ch == '"' )
|
||||
{
|
||||
if ( !lastBS )
|
||||
{
|
||||
isInsideQuotes = !isInsideQuotes;
|
||||
|
||||
// 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
|
||||
}
|
||||
// note that backslash does *not* quote the space, only quotes do
|
||||
else if ( !isInsideQuotes && (ch == ' ' || ch == '\t') )
|
||||
{
|
||||
++p; // skip this space anyhow
|
||||
break;
|
||||
}
|
||||
|
||||
lastBS = ch == '\\';
|
||||
}
|
||||
else // type == wxCMD_LINE_SPLIT_UNIX
|
||||
{
|
||||
if ( !lastBS )
|
||||
{
|
||||
isInsideQuotes = !isInsideQuotes;
|
||||
if ( isInsideQuotes )
|
||||
{
|
||||
if ( ch == chDelim )
|
||||
{
|
||||
isInsideQuotes = false;
|
||||
|
||||
// don't put quote in arg
|
||||
continue;
|
||||
continue; // don't use the quote itself
|
||||
}
|
||||
}
|
||||
else // not in quotes and not escaped
|
||||
{
|
||||
if ( ch == '\'' || ch == '"' )
|
||||
{
|
||||
isInsideQuotes = true;
|
||||
chDelim = ch;
|
||||
|
||||
continue; // don't use the quote itself
|
||||
}
|
||||
|
||||
if ( ch == ' ' || ch == '\t' )
|
||||
{
|
||||
++p; // skip this space anyhow
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
lastBS = ch == '\\';
|
||||
if ( lastBS )
|
||||
continue;
|
||||
}
|
||||
else // escaped by backslash, just use as is
|
||||
{
|
||||
lastBS = false;
|
||||
}
|
||||
//else: quote has no special meaning but the backslash
|
||||
// still remains -- makes no sense but this is what
|
||||
// Windows does
|
||||
}
|
||||
// note that backslash does *not* quote the space, only quotes do
|
||||
else if ( !isInsideQuotes && (ch == ' ' || ch == '\t') )
|
||||
{
|
||||
++p; // skip this space anyhow
|
||||
break;
|
||||
}
|
||||
|
||||
lastBS = ch == '\\';
|
||||
|
||||
arg += ch;
|
||||
}
|
||||
|
@ -55,12 +55,26 @@ CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( CmdLineTestCase, "CmdLineTestCase" );
|
||||
|
||||
void CmdLineTestCase::ConvertStringTestCase()
|
||||
{
|
||||
#define WX_ASSERT_ARGS_EQUAL(s, args) \
|
||||
#define WX_ASSERT_DOS_ARGS_EQUAL(s, args) \
|
||||
{ \
|
||||
const wxArrayString a(wxCmdLineParser::ConvertStringToArgs(args));\
|
||||
WX_ASSERT_STRARRAY_EQUAL(s, a); \
|
||||
const wxArrayString \
|
||||
argsDOS(wxCmdLineParser::ConvertStringToArgs(args, \
|
||||
wxCMD_LINE_SPLIT_DOS)); \
|
||||
WX_ASSERT_STRARRAY_EQUAL(s, argsDOS); \
|
||||
}
|
||||
|
||||
#define WX_ASSERT_UNIX_ARGS_EQUAL(s, args) \
|
||||
{ \
|
||||
const wxArrayString \
|
||||
argsUnix(wxCmdLineParser::ConvertStringToArgs(args, \
|
||||
wxCMD_LINE_SPLIT_UNIX)); \
|
||||
WX_ASSERT_STRARRAY_EQUAL(s, argsUnix); \
|
||||
}
|
||||
|
||||
#define WX_ASSERT_ARGS_EQUAL(s, args) \
|
||||
WX_ASSERT_DOS_ARGS_EQUAL(s, args) \
|
||||
WX_ASSERT_UNIX_ARGS_EQUAL(s, args)
|
||||
|
||||
// normal cases
|
||||
WX_ASSERT_ARGS_EQUAL( "foo", "foo" )
|
||||
WX_ASSERT_ARGS_EQUAL( "foo bar", "\"foo bar\"" )
|
||||
@ -74,12 +88,31 @@ void CmdLineTestCase::ConvertStringTestCase()
|
||||
WX_ASSERT_ARGS_EQUAL( "foo", "foo \t " )
|
||||
WX_ASSERT_ARGS_EQUAL( "foo|bar", "foo bar " )
|
||||
WX_ASSERT_ARGS_EQUAL( "foo|bar|", "foo bar \"" )
|
||||
WX_ASSERT_ARGS_EQUAL( "foo|bar|\\", "foo bar \\" )
|
||||
WX_ASSERT_DOS_ARGS_EQUAL( "foo|bar|\\", "foo bar \\" )
|
||||
WX_ASSERT_UNIX_ARGS_EQUAL( "foo|bar|", "foo bar \\" )
|
||||
|
||||
WX_ASSERT_ARGS_EQUAL( "12 34", "1\"2 3\"4" );
|
||||
WX_ASSERT_ARGS_EQUAL( "1|2 34", "1 \"2 3\"4" );
|
||||
WX_ASSERT_ARGS_EQUAL( "1|2 3|4", "1 \"2 3\" 4" );
|
||||
|
||||
// check for (broken) Windows semantics: backslash doesn't escape spaces
|
||||
WX_ASSERT_ARGS_EQUAL( "foo|bar\\|baz", "foo bar\\ baz" );
|
||||
WX_ASSERT_ARGS_EQUAL( "foo|bar\\\"baz", "foo \"bar\\\"baz\"" );
|
||||
WX_ASSERT_DOS_ARGS_EQUAL( "foo|bar\\|baz", "foo bar\\ baz" );
|
||||
WX_ASSERT_DOS_ARGS_EQUAL( "foo|bar\\\"baz", "foo \"bar\\\"baz\"" );
|
||||
|
||||
// check for more sane Unix semantics: backslash does escape spaces and
|
||||
// quotes
|
||||
WX_ASSERT_UNIX_ARGS_EQUAL( "foo|bar baz", "foo bar\\ baz" );
|
||||
WX_ASSERT_UNIX_ARGS_EQUAL( "foo|bar\"baz", "foo \"bar\\\"baz\"" );
|
||||
|
||||
// check that single quotes work too with Unix semantics
|
||||
WX_ASSERT_UNIX_ARGS_EQUAL( "foo bar", "'foo bar'" )
|
||||
WX_ASSERT_UNIX_ARGS_EQUAL( "foo|bar baz", "foo 'bar baz'" )
|
||||
WX_ASSERT_UNIX_ARGS_EQUAL( "foo|bar baz", "foo 'bar baz'" )
|
||||
WX_ASSERT_UNIX_ARGS_EQUAL( "O'Henry", "\"O'Henry\"" )
|
||||
WX_ASSERT_UNIX_ARGS_EQUAL( "O'Henry", "O\\'Henry" )
|
||||
|
||||
#undef WX_ASSERT_DOS_ARGS_EQUAL
|
||||
#undef WX_ASSERT_UNIX_ARGS_EQUAL
|
||||
#undef WX_ASSERT_ARGS_EQUAL
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user