diff --git a/docs/changes.txt b/docs/changes.txt index 94b701ca75..4f1df26741 100644 --- a/docs/changes.txt +++ b/docs/changes.txt @@ -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): diff --git a/include/wx/cmdline.h b/include/wx/cmdline.h index 3dd41b9fe4..7533160c83 100644 --- a/include/wx/cmdline.h +++ b/include/wx/cmdline.h @@ -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); }; diff --git a/interface/wx/cmdline.h b/interface/wx/cmdline.h index 9fe6c70cb9..776addb4bf 100644 --- a/interface/wx/cmdline.h +++ b/interface/wx/cmdline.h @@ -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 diff --git a/src/common/cmdline.cpp b/src/common/cmdline.cpp index e8892831ac..980777f842 100644 --- a/src/common/cmdline.cpp +++ b/src/common/cmdline.cpp @@ -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) ) { diff --git a/tests/cmdline/cmdlinetest.cpp b/tests/cmdline/cmdlinetest.cpp index 2e5728971a..6fa782b291 100644 --- a/tests/cmdline/cmdlinetest.cpp +++ b/tests/cmdline/cmdlinetest.cpp @@ -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