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:
@@ -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) )
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user