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/arrstr.h"
|
||||||
#include "wx/cmdargs.h"
|
#include "wx/cmdargs.h"
|
||||||
|
|
||||||
|
// determines ConvertStringToArgs() behaviour
|
||||||
|
enum wxCmdLineSplitType
|
||||||
|
{
|
||||||
|
wxCMD_LINE_SPLIT_DOS,
|
||||||
|
wxCMD_LINE_SPLIT_UNIX
|
||||||
|
};
|
||||||
|
|
||||||
#if wxUSE_CMDLINE_PARSER
|
#if wxUSE_CMDLINE_PARSER
|
||||||
|
|
||||||
class WXDLLIMPEXP_FWD_BASE wxDateTime;
|
class WXDLLIMPEXP_FWD_BASE wxDateTime;
|
||||||
@ -233,7 +240,9 @@ public:
|
|||||||
void Reset();
|
void Reset();
|
||||||
|
|
||||||
// break down the command line in arguments
|
// 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:
|
private:
|
||||||
// common part of all ctors
|
// common part of all ctors
|
||||||
@ -251,7 +260,9 @@ private:
|
|||||||
class WXDLLIMPEXP_BASE wxCmdLineParser
|
class WXDLLIMPEXP_BASE wxCmdLineParser
|
||||||
{
|
{
|
||||||
public:
|
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
|
#endif // wxUSE_CMDLINE_PARSER/!wxUSE_CMDLINE_PARSER
|
||||||
|
@ -59,6 +59,15 @@ enum wxCmdLineEntryType
|
|||||||
wxCMD_LINE_NONE ///< Use this to terminate the list.
|
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
|
The structure wxCmdLineEntryDesc is used to describe the one command line
|
||||||
switch, option or parameter. An array of such structures should be passed
|
switch, option or parameter. An array of such structures should be passed
|
||||||
@ -301,12 +310,20 @@ public:
|
|||||||
bool AreLongOptionsEnabled() const;
|
bool AreLongOptionsEnabled() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Breaks down the string containing the full command line in words. The
|
Breaks down the string containing the full command line in words.
|
||||||
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
|
Words are separated by whitespace and double quotes can be used to
|
||||||
quote the quotes.
|
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).
|
Identical to EnableLongOptions(@false).
|
||||||
|
@ -1280,15 +1280,15 @@ static wxString GetLongOptionName(wxString::const_iterator p,
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/* static */
|
/* static */
|
||||||
wxArrayString wxCmdLineParser::ConvertStringToArgs(const wxString& cmdline)
|
wxArrayString
|
||||||
|
wxCmdLineParser::ConvertStringToArgs(const wxString& cmdline,
|
||||||
|
wxCmdLineSplitType type)
|
||||||
{
|
{
|
||||||
wxArrayString args;
|
wxArrayString args;
|
||||||
|
|
||||||
wxString arg;
|
wxString arg;
|
||||||
arg.reserve(1024);
|
arg.reserve(1024);
|
||||||
|
|
||||||
bool isInsideQuotes = false;
|
|
||||||
|
|
||||||
const wxString::const_iterator end = cmdline.end();
|
const wxString::const_iterator end = cmdline.end();
|
||||||
wxString::const_iterator p = cmdline.begin();
|
wxString::const_iterator p = cmdline.begin();
|
||||||
|
|
||||||
@ -1303,31 +1303,76 @@ wxArrayString wxCmdLineParser::ConvertStringToArgs(const wxString& cmdline)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
// parse this parameter
|
// parse this parameter
|
||||||
bool lastBS = false;
|
bool lastBS = false,
|
||||||
|
isInsideQuotes = false;
|
||||||
|
wxChar chDelim = '\0';
|
||||||
for ( arg.clear(); p != end; ++p )
|
for ( arg.clear(); p != end; ++p )
|
||||||
{
|
{
|
||||||
const wxChar ch = *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 )
|
if ( !lastBS )
|
||||||
{
|
{
|
||||||
isInsideQuotes = !isInsideQuotes;
|
if ( isInsideQuotes )
|
||||||
|
{
|
||||||
|
if ( ch == chDelim )
|
||||||
|
{
|
||||||
|
isInsideQuotes = false;
|
||||||
|
|
||||||
// don't put quote in arg
|
continue; // don't use the quote itself
|
||||||
continue;
|
}
|
||||||
|
}
|
||||||
|
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;
|
arg += ch;
|
||||||
}
|
}
|
||||||
|
@ -55,12 +55,26 @@ CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( CmdLineTestCase, "CmdLineTestCase" );
|
|||||||
|
|
||||||
void CmdLineTestCase::ConvertStringTestCase()
|
void CmdLineTestCase::ConvertStringTestCase()
|
||||||
{
|
{
|
||||||
#define WX_ASSERT_ARGS_EQUAL(s, args) \
|
#define WX_ASSERT_DOS_ARGS_EQUAL(s, args) \
|
||||||
{ \
|
{ \
|
||||||
const wxArrayString a(wxCmdLineParser::ConvertStringToArgs(args));\
|
const wxArrayString \
|
||||||
WX_ASSERT_STRARRAY_EQUAL(s, a); \
|
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
|
// normal cases
|
||||||
WX_ASSERT_ARGS_EQUAL( "foo", "foo" )
|
WX_ASSERT_ARGS_EQUAL( "foo", "foo" )
|
||||||
WX_ASSERT_ARGS_EQUAL( "foo bar", "\"foo bar\"" )
|
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", "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_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
|
// check for (broken) Windows semantics: backslash doesn't escape spaces
|
||||||
WX_ASSERT_ARGS_EQUAL( "foo|bar\\|baz", "foo bar\\ baz" );
|
WX_ASSERT_DOS_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\"" );
|
||||||
|
|
||||||
|
// 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
|
#undef WX_ASSERT_ARGS_EQUAL
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user