Allow iterating over wxCmdLineParser arguments in order.

This allows the meaning of the options to depend on their order relatively to
the other options which wasn't possible before.

See http://review.bakefile.org/r/557/

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@75723 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin 2014-01-28 13:04:55 +00:00
parent ded7644999
commit 5cfbf0dc4d
5 changed files with 582 additions and 77 deletions

View File

@ -20,6 +20,7 @@ Changes in behaviour not resulting in compilation errors
All:
- Allow iterating over wxCmdLineParser arguments in order (Armel Asselin).
- Add wxScopedArray ctor taking the number of elements to allocate.
All (GUI):

View File

@ -93,6 +93,90 @@ struct wxCmdLineEntryDesc
#define wxCMD_LINE_DESC_END \
{ wxCMD_LINE_NONE, NULL, NULL, NULL, wxCMD_LINE_VAL_NONE, 0x0 }
// ----------------------------------------------------------------------------
// wxCmdLineArg contains the value for one command line argument
// ----------------------------------------------------------------------------
class WXDLLIMPEXP_BASE wxCmdLineArg
{
public:
virtual ~wxCmdLineArg() {}
virtual double GetDoubleVal() const = 0;
virtual long GetLongVal() const = 0;
virtual const wxString& GetStrVal() const = 0;
#if wxUSE_DATETIME
virtual const wxDateTime& GetDateVal() const = 0;
#endif // wxUSE_DATETIME
virtual bool IsNegated() const = 0;
virtual wxCmdLineEntryType GetKind() const = 0;
virtual wxString GetShortName() const = 0;
virtual wxString GetLongName() const = 0;
virtual wxCmdLineParamType GetType() const = 0;
};
// ----------------------------------------------------------------------------
// wxCmdLineArgs is a container of command line arguments actually parsed and
// allows enumerating them using the standard iterator-based approach.
// ----------------------------------------------------------------------------
class WXDLLIMPEXP_BASE wxCmdLineArgs
{
public:
class WXDLLIMPEXP_BASE const_iterator
{
public:
typedef int difference_type;
typedef wxCmdLineArg value_type;
typedef const wxCmdLineArg* pointer;
typedef const wxCmdLineArg& reference;
// We avoid dependency on standard library by default but if we do use
// std::string, then it's ok to use iterator tags as well.
#if wxUSE_STD_STRING
typedef std::bidirectional_iterator_tag iterator_category;
#endif // wx_USE_STD_STRING
const_iterator() : m_parser(NULL), m_index(0) {}
reference operator *() const;
pointer operator ->() const;
const_iterator &operator ++ ();
const_iterator operator ++ (int);
const_iterator &operator -- ();
const_iterator operator -- (int);
bool operator == (const const_iterator &other) const {
return m_parser==other.m_parser && m_index==other.m_index;
}
bool operator != (const const_iterator &other) const {
return !operator==(other);
}
private:
const_iterator (const wxCmdLineParser& parser, size_t index)
: m_parser(&parser), m_index(index) {
}
const wxCmdLineParser* m_parser;
size_t m_index;
friend class wxCmdLineArgs;
};
wxCmdLineArgs (const wxCmdLineParser& parser) : m_parser(parser) {}
const_iterator begin() const { return const_iterator(m_parser, 0); }
const_iterator end() const { return const_iterator(m_parser, size()); }
size_t size() const;
private:
const wxCmdLineParser& m_parser;
wxDECLARE_NO_ASSIGN_CLASS(wxCmdLineArgs);
};
// ----------------------------------------------------------------------------
// wxCmdLineParser is a class for parsing command line.
//
@ -263,6 +347,9 @@ public:
// gets the value of Nth parameter (as string only for now)
wxString GetParam(size_t n = 0u) const;
// returns a reference to the container of all command line arguments
wxCmdLineArgs GetArguments() const { return wxCmdLineArgs(*this); }
// Resets switches and options
void Reset();
@ -277,6 +364,8 @@ private:
struct wxCmdLineParserData *m_data;
friend class wxCmdLineArgs;
friend class wxCmdLineArgs::const_iterator;
wxDECLARE_NO_COPY_CLASS(wxCmdLineParser);
};

View File

@ -153,6 +153,169 @@ struct wxCmdLineEntryDesc
int flags;
};
/**
The interface wxCmdLineArg provides information for an instance of argument
passed on command line.
Example of use:
@code
wxCmdLineParser parser;
for (wxCmdLineArgs::const_iterator itarg=parser.GetArguments().begin();
itarg!=parser.GetArguments().end();
++itarg)
{
wxString optionName;
switch (itarg->GetKind())
{
case wxCMD_LINE_SWITCH:
if (itarg->IsNegated()) {
}
else {
}
break;
case wxCMD_LINE_OPTION:
// assuming that all the options have a short name
optionName = itarg->GetShortName();
switch (itarg->GetType()) {
case wxCMD_LINE_VAL_NUMBER:
// do something with itarg->GetLongVal();
break;
case wxCMD_LINE_VAL_DOUBLE:
// do something with itarg->GetDoubleVal();
break;
case wxCMD_LINE_VAL_DATE:
// do something with itarg->GetDateVal();
break;
case wxCMD_LINE_VAL_STRING:
// do something with itarg->GetStrVal();
break;
}
break;
case wxCMD_LINE_PARAM:
// do something with itarg->GetStrVal();
break;
}
}
@endcode
With C++11, the for loop could be written:
@code
for (const auto &arg : parser.GetArguments()) {
// working on arg as with *itarg above
}
@endcode
@since 3.1.0
*/
class wxCmdLineArg
{
public:
virtual ~wxCmdLineArg() {}
/**
Returns the command line argument value as a wxDateTime.
@note This call works only for @c wxCMD_LINE_VAL_DATE options
*/
virtual const wxDateTime& GetDateVal() const = 0;
/**
Returns the command line argument value as a double.
@note This call works only for @c wxCMD_LINE_VAL_DOUBLE options
*/
virtual double GetDoubleVal() const = 0;
/**
Returns the command line argument entry kind.
@note Parameters can only be retrieved as strings, with GetStrVal()
@see wxCmdLineEntryType, GetType()
*/
virtual wxCmdLineEntryType GetKind() const = 0;
/**
Returns the command line argument value as a long.
@note This call works only for @c wxCMD_LINE_VAL_NUMBER options
*/
virtual long GetLongVal() const = 0;
/**
Returns the command line argument long name if any.
@note This call makes sense only for options and switches
*/
virtual wxString GetLongName() const = 0;
/**
Returns the command line argument short name if any.
@note This call makes sense only for options and switches
*/
virtual wxString GetShortName() const = 0;
/**
Returns the command line argument value as a string.
@note This call works only for @c wxCMD_LINE_VAL_STRING options
and parameters
*/
virtual const wxString& GetStrVal() const = 0;
/**
Returns the command line argument parameter type
@note This call makes sense only for options
(i.e. GetKind() == @c wxCMD_LINE_OPTION).
@see wxCmdLineParamType, GetKind()
*/
virtual wxCmdLineParamType GetType() const = 0;
/**
Returns true if the switch was negated
@note This call works only for switches.
*/
virtual bool IsNegated() const = 0;
};
/**
An ordered collection of wxCmdLineArg providing an iterator to enumerate
the arguments passed on command line.
@see wxCmdLineParser::GetArguments()
@since 3.1.0
*/
class wxCmdLineArgs
{
public:
/**
A bidirectional constant iterator exposing the command line arguments as
wxCmdLineArg references.
*/
class const_iterator;
const_iterator begin() const;
const_iterator end() const;
/**
Returns the number of command line arguments in this collection.
*/
size_t size() const;
};
/**
@class wxCmdLineParser
@ -494,6 +657,17 @@ public:
*/
size_t GetParamCount() const;
/**
Returns the collection of arguments
@note The returned object just refers to the command line parser. The
command line parser must live longer than it.
@see wxCmdLineArgs
@since 3.1.0
*/
wxCmdLineArgs GetArguments() const;
/**
Parse the command line, return 0 if ok, -1 if @c "-h" or @c "\--help"
option was encountered and the help message was given or a positive

View File

@ -64,87 +64,26 @@ static wxString GetLongOptionName(wxString::const_iterator p,
// private structs
// ----------------------------------------------------------------------------
// an internal representation of an option
struct wxCmdLineOption
class wxCmdLineArgImpl: public wxCmdLineArg
{
wxCmdLineOption(wxCmdLineEntryType k,
const wxString& shrt,
const wxString& lng,
const wxString& desc,
wxCmdLineParamType typ,
int fl)
{
// wxCMD_LINE_USAGE_TEXT uses only description, shortName and longName is empty
if ( k != wxCMD_LINE_USAGE_TEXT )
{
wxASSERT_MSG
(
!shrt.empty() || !lng.empty(),
wxT("option should have at least one name")
);
public:
wxCmdLineArgImpl(wxCmdLineEntryType k,
const wxString& shrt,
const wxString& lng,
wxCmdLineParamType typ);
wxASSERT_MSG
(
GetShortOptionName(shrt.begin(), shrt.end()).Len() == shrt.Len(),
wxT("Short option contains invalid characters")
);
wxASSERT_MSG
(
GetLongOptionName(lng.begin(), lng.end()).Len() == lng.Len(),
wxT("Long option contains invalid characters")
);
}
kind = k;
shortName = shrt;
longName = lng;
description = desc;
type = typ;
flags = fl;
Reset();
}
// can't use union easily here, so just store all possible data fields, we
// don't waste much (might still use union later if the number of supported
// types increases, so always use the accessor functions and don't access
// the fields directly!)
void Check(wxCmdLineParamType WXUNUSED_UNLESS_DEBUG(typ)) const
{
wxASSERT_MSG( type == typ, wxT("type mismatch in wxCmdLineOption") );
}
double GetDoubleVal() const
{ Check(wxCMD_LINE_VAL_DOUBLE); return m_doubleVal; }
long GetLongVal() const
{ Check(wxCMD_LINE_VAL_NUMBER); return m_longVal; }
const wxString& GetStrVal() const
{ Check(wxCMD_LINE_VAL_STRING); return m_strVal; }
wxCmdLineArgImpl& SetDoubleVal(double val);
wxCmdLineArgImpl& SetLongVal(long val);
wxCmdLineArgImpl& SetStrVal(const wxString& val);
#if wxUSE_DATETIME
const wxDateTime& GetDateVal() const
{ Check(wxCMD_LINE_VAL_DATE); return m_dateVal; }
wxCmdLineArgImpl& SetDateVal(const wxDateTime& val);
#endif // wxUSE_DATETIME
void SetDoubleVal(double val)
{ Check(wxCMD_LINE_VAL_DOUBLE); m_doubleVal = val; m_hasVal = true; }
void SetLongVal(long val)
{ Check(wxCMD_LINE_VAL_NUMBER); m_longVal = val; m_hasVal = true; }
void SetStrVal(const wxString& val)
{ Check(wxCMD_LINE_VAL_STRING); m_strVal = val; m_hasVal = true; }
#if wxUSE_DATETIME
void SetDateVal(const wxDateTime& val)
{ Check(wxCMD_LINE_VAL_DATE); m_dateVal = val; m_hasVal = true; }
#endif // wxUSE_DATETIME
void SetHasValue() { m_hasVal = true; }
bool HasValue() const { return m_hasVal; }
wxCmdLineArgImpl& SetHasValue() { m_hasVal = true; return *this; }
void SetNegated() { m_isNegated = true; }
bool IsNegated() const { return m_isNegated; }
wxCmdLineArgImpl& SetNegated() { m_isNegated = true; return *this; }
// Reset to the initial state, called before parsing another command line.
void Reset()
@ -156,12 +95,45 @@ struct wxCmdLineOption
public:
wxCmdLineEntryType kind;
wxString shortName,
longName,
description;
longName;
wxCmdLineParamType type;
int flags;
// from wxCmdLineArg
virtual wxCmdLineEntryType GetKind() const { return kind; }
virtual wxString GetShortName() const {
wxASSERT_MSG( kind == wxCMD_LINE_OPTION || kind == wxCMD_LINE_SWITCH,
wxT("kind mismatch in wxCmdLineArg") );
return shortName;
}
virtual wxString GetLongName() const {
wxASSERT_MSG( kind == wxCMD_LINE_OPTION || kind == wxCMD_LINE_SWITCH,
wxT("kind mismatch in wxCmdLineArg") );
return longName;
}
virtual wxCmdLineParamType GetType() const {
wxASSERT_MSG( kind == wxCMD_LINE_OPTION,
wxT("kind mismatch in wxCmdLineArg") );
return type;
}
double GetDoubleVal() const;
long GetLongVal() const;
const wxString& GetStrVal() const;
#if wxUSE_DATETIME
const wxDateTime& GetDateVal() const;
#endif // wxUSE_DATETIME
bool IsNegated() const {
wxASSERT_MSG( kind == wxCMD_LINE_SWITCH,
wxT("kind mismatch in wxCmdLineArg") );
return m_isNegated;
}
private:
// can't use union easily here, so just store all possible data fields, we
// don't waste much (might still use union later if the number of supported
// types increases)
void Check(wxCmdLineParamType typ) const;
bool m_hasVal;
bool m_isNegated;
@ -171,6 +143,27 @@ private:
#if wxUSE_DATETIME
wxDateTime m_dateVal;
#endif // wxUSE_DATETIME
};
// an internal representation of an option
struct wxCmdLineOption: public wxCmdLineArgImpl
{
wxCmdLineOption(wxCmdLineEntryType k,
const wxString& shrt,
const wxString& lng,
const wxString& desc,
wxCmdLineParamType typ,
int fl)
: wxCmdLineArgImpl(k, shrt, lng, typ)
{
description = desc;
flags = fl;
}
wxString description;
int flags;
};
struct wxCmdLineParam
@ -191,11 +184,13 @@ struct wxCmdLineParam
WX_DECLARE_OBJARRAY(wxCmdLineOption, wxArrayOptions);
WX_DECLARE_OBJARRAY(wxCmdLineParam, wxArrayParams);
WX_DECLARE_OBJARRAY(wxCmdLineArgImpl, wxArrayArgs);
#include "wx/arrimpl.cpp"
WX_DEFINE_OBJARRAY(wxArrayOptions)
WX_DEFINE_OBJARRAY(wxArrayParams)
WX_DEFINE_OBJARRAY(wxArrayArgs)
// the parser internal state
struct wxCmdLineParserData
@ -210,6 +205,7 @@ struct wxCmdLineParserData
wxArrayOptions m_options; // all possible options and switches
wxArrayParams m_paramDesc; // description of all possible params
wxArrayString m_parameters; // all params found
wxArrayArgs m_parsedArguments; // all options and parameters in parsing order
// methods
wxCmdLineParserData();
@ -228,6 +224,167 @@ struct wxCmdLineParserData
// implementation
// ============================================================================
// ----------------------------------------------------------------------------
// wxCmdLineArg
// ----------------------------------------------------------------------------
wxCmdLineArgImpl::wxCmdLineArgImpl(wxCmdLineEntryType k,
const wxString& shrt,
const wxString& lng,
wxCmdLineParamType typ)
{
// wxCMD_LINE_USAGE_TEXT uses only description, shortName and longName is empty
if ( k != wxCMD_LINE_USAGE_TEXT && k != wxCMD_LINE_PARAM)
{
wxASSERT_MSG
(
!shrt.empty() || !lng.empty(),
wxT("option should have at least one name")
);
wxASSERT_MSG
(
GetShortOptionName(shrt.begin(), shrt.end()).Len() == shrt.Len(),
wxT("Short option contains invalid characters")
);
wxASSERT_MSG
(
GetLongOptionName(lng.begin(), lng.end()).Len() == lng.Len(),
wxT("Long option contains invalid characters")
);
}
kind = k;
shortName = shrt;
longName = lng;
type = typ;
Reset();
}
void wxCmdLineArgImpl::Check(wxCmdLineParamType WXUNUSED_UNLESS_DEBUG(typ)) const
{
// NB: Type is always wxCMD_LINE_VAL_NONE for booleans, so mismatch between
// switches / options / params is well checked by this test
// The parameters have type == wxCMD_LINE_VAL_STRING and thus can be
// retrieved only by GetStrVal()
wxASSERT_MSG( type == typ, wxT("type mismatch in wxCmdLineArg") );
}
double wxCmdLineArgImpl::GetDoubleVal() const
{
Check(wxCMD_LINE_VAL_DOUBLE);
return m_doubleVal;
}
long wxCmdLineArgImpl::GetLongVal() const
{
Check(wxCMD_LINE_VAL_NUMBER);
return m_longVal;
}
const wxString& wxCmdLineArgImpl::GetStrVal() const
{
Check(wxCMD_LINE_VAL_STRING);
return m_strVal;
}
#if wxUSE_DATETIME
const wxDateTime& wxCmdLineArgImpl::GetDateVal() const
{
Check(wxCMD_LINE_VAL_DATE);
return m_dateVal;
}
#endif // wxUSE_DATETIME
wxCmdLineArgImpl& wxCmdLineArgImpl::SetDoubleVal(double val)
{
Check(wxCMD_LINE_VAL_DOUBLE);
m_doubleVal = val;
m_hasVal = true;
return *this;
}
wxCmdLineArgImpl& wxCmdLineArgImpl::SetLongVal(long val)
{
Check(wxCMD_LINE_VAL_NUMBER);
m_longVal = val;
m_hasVal = true;
return *this;
}
wxCmdLineArgImpl& wxCmdLineArgImpl::SetStrVal(const wxString& val)
{
Check(wxCMD_LINE_VAL_STRING);
m_strVal = val;
m_hasVal = true;
return *this;
}
#if wxUSE_DATETIME
wxCmdLineArgImpl& wxCmdLineArgImpl::SetDateVal(const wxDateTime& val)
{
Check(wxCMD_LINE_VAL_DATE);
m_dateVal = val;
m_hasVal = true;
return *this;
}
#endif // wxUSE_DATETIME
// ----------------------------------------------------------------------------
// wxCmdLineArgsArrayRef
// ----------------------------------------------------------------------------
size_t wxCmdLineArgs::size() const
{
return m_parser.m_data->m_parsedArguments.GetCount();
}
// ----------------------------------------------------------------------------
// wxCmdLineArgsArrayRef::const_iterator
// ----------------------------------------------------------------------------
wxCmdLineArgs::const_iterator::reference
wxCmdLineArgs::const_iterator::operator *() const
{
return m_parser->m_data->m_parsedArguments[m_index];
}
wxCmdLineArgs::const_iterator::pointer
wxCmdLineArgs::const_iterator::operator ->() const
{
return &**this;
}
wxCmdLineArgs::const_iterator &wxCmdLineArgs::const_iterator::operator ++ ()
{
++m_index;
return *this;
}
wxCmdLineArgs::const_iterator wxCmdLineArgs::const_iterator::operator ++ (int)
{
wxCmdLineArgs::const_iterator tmp(*this);
++*this;
return tmp;
}
wxCmdLineArgs::const_iterator &wxCmdLineArgs::const_iterator::operator -- ()
{
--m_index;
return *this;
}
wxCmdLineArgs::const_iterator wxCmdLineArgs::const_iterator::operator -- (int)
{
wxCmdLineArgs::const_iterator tmp(*this);
--*this;
return tmp;
}
// ----------------------------------------------------------------------------
// wxCmdLineParserData
// ----------------------------------------------------------------------------
@ -644,6 +801,8 @@ void wxCmdLineParser::Reset()
{
m_data->m_options[i].Reset();
}
m_data->m_parsedArguments.Empty();
}
@ -995,6 +1154,9 @@ int wxCmdLineParser::Parse(bool showUsage)
}
}
}
if (ok)
m_data->m_parsedArguments.push_back (opt);
}
else // not an option, must be a parameter
{
@ -1005,6 +1167,9 @@ int wxCmdLineParser::Parse(bool showUsage)
// TODO check the param type
m_data->m_parameters.push_back(arg);
m_data->m_parsedArguments.push_back (
wxCmdLineArgImpl(wxCMD_LINE_PARAM, wxString(), wxString(),
wxCMD_LINE_VAL_STRING).SetStrVal(arg));
if ( !(param.flags & wxCMD_LINE_PARAM_MULTIPLE) )
{

View File

@ -23,6 +23,8 @@
#include "wx/msgout.h"
#include "wx/scopeguard.h"
#include "testdate.h"
// --------------------------------------------------------------------------
// test class
// --------------------------------------------------------------------------
@ -36,11 +38,13 @@ private:
CPPUNIT_TEST_SUITE( CmdLineTestCase );
CPPUNIT_TEST( ConvertStringTestCase );
CPPUNIT_TEST( ParseSwitches );
CPPUNIT_TEST( ArgumentsCollection );
CPPUNIT_TEST( Usage );
CPPUNIT_TEST_SUITE_END();
void ConvertStringTestCase();
void ParseSwitches();
void ArgumentsCollection();
void Usage();
DECLARE_NO_COPY_CLASS(CmdLineTestCase)
@ -202,6 +206,78 @@ void CmdLineTestCase::ParseSwitches()
CPPUNIT_ASSERT_EQUAL(wxCMD_SWITCH_OFF, p.FoundSwitch("n") );
}
void CmdLineTestCase::ArgumentsCollection()
{
wxCmdLineParser p;
p.AddLongSwitch ("verbose");
p.AddOption ("l", "long", wxEmptyString, wxCMD_LINE_VAL_NUMBER);
p.AddOption ("d", "date", wxEmptyString, wxCMD_LINE_VAL_DATE);
p.AddOption ("f", "double", wxEmptyString, wxCMD_LINE_VAL_DOUBLE);
p.AddOption ("s", "string", wxEmptyString, wxCMD_LINE_VAL_STRING);
p.AddParam (wxEmptyString, wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_MULTIPLE);
wxDateTime wasNow = wxDateTime::Now().GetDateOnly();
p.SetCmdLine (wxString::Format ("--verbose param1 -l 22 -d \"%s\" -f 50.12e-1 param2 --string \"some string\"",
wasNow.FormatISODate()));
CPPUNIT_ASSERT_EQUAL(0, p.Parse(false) );
wxCmdLineArgs::const_iterator itargs = p.GetArguments().begin();
// --verbose
CPPUNIT_ASSERT_EQUAL(wxCMD_LINE_SWITCH, itargs->GetKind());
CPPUNIT_ASSERT_EQUAL("verbose", itargs->GetLongName());
CPPUNIT_ASSERT_EQUAL(false, itargs->IsNegated());
// param1
++itargs; // pre incrementation test
CPPUNIT_ASSERT_EQUAL(wxCMD_LINE_PARAM, itargs->GetKind());
CPPUNIT_ASSERT_EQUAL("param1", itargs->GetStrVal());
// -l 22
itargs++; // post incrementation test
CPPUNIT_ASSERT_EQUAL(wxCMD_LINE_OPTION, itargs->GetKind());
CPPUNIT_ASSERT_EQUAL(wxCMD_LINE_VAL_NUMBER, itargs->GetType());
CPPUNIT_ASSERT_EQUAL("l", itargs->GetShortName());
CPPUNIT_ASSERT_EQUAL(22, itargs->GetLongVal());
// -d (some date)
++itargs;
CPPUNIT_ASSERT_EQUAL(wxCMD_LINE_OPTION, itargs->GetKind());
CPPUNIT_ASSERT_EQUAL(wxCMD_LINE_VAL_DATE, itargs->GetType());
CPPUNIT_ASSERT_EQUAL("d", itargs->GetShortName());
CPPUNIT_ASSERT_EQUAL(wasNow, itargs->GetDateVal());
// -f 50.12e-1
++itargs;
CPPUNIT_ASSERT_EQUAL(wxCMD_LINE_OPTION, itargs->GetKind());
CPPUNIT_ASSERT_EQUAL(wxCMD_LINE_VAL_DOUBLE, itargs->GetType());
CPPUNIT_ASSERT_EQUAL("f", itargs->GetShortName());
CPPUNIT_ASSERT_DOUBLES_EQUAL(50.12e-1, itargs->GetDoubleVal(), 0.000001);
// param2
++itargs;
CPPUNIT_ASSERT_EQUAL (wxCMD_LINE_PARAM, itargs->GetKind());
CPPUNIT_ASSERT_EQUAL ("param2", itargs->GetStrVal());
// --string "some string"
++itargs;
CPPUNIT_ASSERT_EQUAL(wxCMD_LINE_OPTION, itargs->GetKind());
CPPUNIT_ASSERT_EQUAL(wxCMD_LINE_VAL_STRING, itargs->GetType());
CPPUNIT_ASSERT_EQUAL("s", itargs->GetShortName());
CPPUNIT_ASSERT_EQUAL("string", itargs->GetLongName());
CPPUNIT_ASSERT_EQUAL("some string", itargs->GetStrVal());
// testing pre and post-increment
--itargs;
itargs--;
CPPUNIT_ASSERT_EQUAL(wxCMD_LINE_VAL_DOUBLE, itargs->GetType());
++itargs;++itargs;++itargs;
CPPUNIT_ASSERT(itargs == p.GetArguments().end());
}
void CmdLineTestCase::Usage()
{
// check that Usage() returns roughly what we expect (don't check all the