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

@@ -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) )
{