Add support for negatable command line switches.

Add wxCMD_LINE_SWITCH_NEGATABLE which allows to use a dash after a command
line switch to inverse its meaning (i.e. use "/X-" form). Also add new
wxCmdLineParser::FoundSwitch() allowing to check for whether the switch was
specified in normal or negated form.

Closes #11643.

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@66253 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin 2010-11-24 00:42:53 +00:00
parent 94803e4ec8
commit a6bf0c9533
4 changed files with 97 additions and 9 deletions

View File

@ -415,6 +415,7 @@ All:
- Added "rest" argument to wxString::Before{First,Last}().
- Added wxThread::OnKill() and OnDelete() callbacks.
- Added wxFile::GetLastError() and ClearLastError() (ryazanov).
- Added negatable command line switches (Armel Asselin).
Unix:

View File

@ -42,7 +42,8 @@ enum wxCmdLineEntryFlags
wxCMD_LINE_PARAM_OPTIONAL = 0x02, // the parameter may be omitted
wxCMD_LINE_PARAM_MULTIPLE = 0x04, // the parameter may be repeated
wxCMD_LINE_OPTION_HELP = 0x08, // this option is a help request
wxCMD_LINE_NEEDS_SEPARATOR = 0x10 // must have sep before the value
wxCMD_LINE_NEEDS_SEPARATOR = 0x10, // must have sep before the value
wxCMD_LINE_SWITCH_NEGATABLE = 0x20 // this switch can be negated (e.g. /S-)
};
// an option value or parameter may be a string (the most common case), a
@ -66,6 +67,14 @@ enum wxCmdLineEntryType
wxCMD_LINE_NONE // to terminate the list
};
// Possible return values of wxCmdLineParser::FoundSwitch()
enum wxCmdLineSwitchState
{
wxCMD_SWITCH_OFF = -1, // Found but turned off/negated.
wxCMD_SWITCH_NOT_FOUND, // Not found at all.
wxCMD_SWITCH_ON // Found in normal state.
};
// ----------------------------------------------------------------------------
// wxCmdLineEntryDesc is a description of one command line
// switch/option/parameter
@ -212,6 +221,12 @@ public:
// returns true if the given switch was found
bool Found(const wxString& name) const;
// Returns wxCMD_SWITCH_NOT_FOUND if the switch was not found at all,
// wxCMD_SWITCH_ON if it was found in normal state and wxCMD_SWITCH_OFF if
// it was found but negated (i.e. followed by "-", this can only happen for
// the switches with wxCMD_LINE_SWITCH_NEGATABLE flag).
wxCmdLineSwitchState FoundSwitch(const wxString& name) const;
// returns true if an option taking a string value was found and stores the
// value in the provided pointer
bool Found(const wxString& name, wxString *value) const;

View File

@ -25,6 +25,12 @@
@c wxCMD_LINE_NEEDS_SEPARATOR can be specified to require a separator (either
a colon, an equal sign or white space) between the option name and its
value. By default, no separator is required.
@c wxCMD_LINE_SWITCH_NEGATABLE can be specified if you want to allow the
user to specify the switch in both normal form and in negated one (e.g.
/R-). You will need to use wxCmdLineParser::FoundSwitch() to distinguish
between the normal and negated forms of the switch. This flag is new since
wxWidgets 2.9.2.
*/
enum wxCmdLineEntryFlags
{
@ -32,7 +38,8 @@ enum wxCmdLineEntryFlags
wxCMD_LINE_PARAM_OPTIONAL = 0x02, ///< The parameter may be omitted.
wxCMD_LINE_PARAM_MULTIPLE = 0x04, ///< The parameter may be repeated.
wxCMD_LINE_OPTION_HELP = 0x08, ///< This option is a help request.
wxCMD_LINE_NEEDS_SEPARATOR = 0x10 ///< Must have a separator before the value.
wxCMD_LINE_NEEDS_SEPARATOR = 0x10, ///< Must have a separator before the value.
wxCMD_LINE_SWITCH_NEGATABLE = 0x20 ///< This switch can be negated (e.g. /S-)
};
/**
@ -69,6 +76,24 @@ enum wxCmdLineEntryType
wxCMD_LINE_NONE ///< Use this to terminate the list.
};
/**
The state of a switch as returned by wxCmdLineParser::FoundSwitch().
@since 2.9.2
*/
enum wxCmdLineSwitchState
{
/// The switch was found in negated form, i.e. followed by a '-'.
wxCMD_SWITCH_OFF,
/// The switch was not found at all on the command line.
wxCMD_SWITCH_NOT_FOUND
/// The switch was found (and was not negated)
wxCMD_SWITCH_ON
};
/**
Flags determining wxCmdLineParser::ConvertStringToArgs() behaviour.
*/
@ -389,6 +414,26 @@ public:
*/
bool Found(const wxString& name) const;
/**
Returns whether the switch was found on the command line and whether it
was negated.
This method can be used for any kind of switch but is especially useful
for switches that can be negated, i.e. were added with
wxCMD_LINE_SWITCH_NEGATABLE flag, as otherwise Found() is simpler to
use.
However Found() doesn't allow to distinguish between switch specified
normally, i.e. without dash following it, and negated switch, i.e. with
the following dash. This method will return @c wxCMD_SWITCH_ON or @c
wxCMD_SWITCH_OFF depending on whether the switch was negated or not.
And if the switch was not found at all, @c wxCMD_SWITCH_NOT_FOUND is
returned.
@since 2.9.2
*/
wxCmdLineSwitchState FoundSwitch(const wxString& name) const;
/**
Returns true if an option taking a string value was found and stores
the value in the provided pointer (which should not be @NULL).

View File

@ -107,6 +107,7 @@ struct wxCmdLineOption
flags = fl;
m_hasVal = false;
m_isNegated = false;
}
// can't use union easily here, so just store all possible data fields, we
@ -144,6 +145,9 @@ struct wxCmdLineOption
void SetHasValue(bool hasValue = true) { m_hasVal = hasValue; }
bool HasValue() const { return m_hasVal; }
void SetNegated() { m_isNegated = true; }
bool IsNegated() const { return m_isNegated; }
public:
wxCmdLineEntryType kind;
wxString shortName,
@ -154,6 +158,7 @@ public:
private:
bool m_hasVal;
bool m_isNegated;
double m_doubleVal;
long m_longVal;
@ -518,18 +523,23 @@ void wxCmdLineParser::AddUsageText(const wxString& text)
// ----------------------------------------------------------------------------
bool wxCmdLineParser::Found(const wxString& name) const
{
return FoundSwitch(name) != wxCMD_SWITCH_NOT_FOUND;
}
wxCmdLineSwitchState wxCmdLineParser::FoundSwitch(const wxString& name) const
{
int i = m_data->FindOption(name);
if ( i == wxNOT_FOUND )
i = m_data->FindOptionByLongName(name);
wxCHECK_MSG( i != wxNOT_FOUND, false, wxT("unknown switch") );
wxCHECK_MSG( i != wxNOT_FOUND, wxCMD_SWITCH_NOT_FOUND, wxT("unknown switch") );
wxCmdLineOption& opt = m_data->m_options[(size_t)i];
if ( !opt.HasValue() )
return false;
return wxCMD_SWITCH_NOT_FOUND;
return true;
return opt.IsNegated() ? wxCMD_SWITCH_OFF : wxCMD_SWITCH_ON;
}
bool wxCmdLineParser::Found(const wxString& name, wxString *value) const
@ -755,6 +765,14 @@ int wxCmdLineParser::Parse(bool showUsage)
if ( m_data->m_options[(size_t)optInd].kind
== wxCMD_LINE_SWITCH )
{
// if the switch is negatable and it is just followed
// by '-' the '-' is considered to be part of this
// switch
if ( (m_data->m_options[(size_t)optInd].flags &
wxCMD_LINE_SWITCH_NEGATABLE) &&
arg[len] == '-' )
++len;
// pretend that all the rest of the argument is the
// next argument, in fact
wxString arg2 = arg[0u];
@ -792,7 +810,10 @@ int wxCmdLineParser::Parse(bool showUsage)
if ( opt.kind == wxCMD_LINE_SWITCH )
{
// we must check that there is no value following the switch
if ( p != arg.end() )
bool negated = (opt.flags & wxCMD_LINE_SWITCH_NEGATABLE) &&
p != arg.end() && *p == '-';
if ( !negated && p != arg.end() )
{
errorMsg << wxString::Format(_("Unexpected characters following option '%s'."), name.c_str())
<< wxT('\n');
@ -802,6 +823,8 @@ int wxCmdLineParser::Parse(bool showUsage)
{
// nothing more to do
opt.SetHasValue();
if ( negated )
opt.SetNegated();
if ( opt.flags & wxCMD_LINE_OPTION_HELP )
{
@ -1095,7 +1118,7 @@ wxString wxCmdLineParser::GetUsageString() const
for ( n = 0; n < count; n++ )
{
wxCmdLineOption& opt = m_data->m_options[n];
wxString option;
wxString option, negator;
if ( opt.kind != wxCMD_LINE_USAGE_TEXT )
{
@ -1105,13 +1128,16 @@ wxString wxCmdLineParser::GetUsageString() const
usage << wxT('[');
}
if ( opt.flags & wxCMD_LINE_SWITCH_NEGATABLE )
negator = wxT("[-]");
if ( !opt.shortName.empty() )
{
usage << chSwitch << opt.shortName;
usage << chSwitch << opt.shortName << negator;
}
else if ( areLongOptionsEnabled && !opt.longName.empty() )
{
usage << wxT("--") << opt.longName;
usage << wxT("--") << opt.longName << negator;
}
else
{
@ -1145,6 +1171,7 @@ wxString wxCmdLineParser::GetUsageString() const
option << (!opt.longName ? wxT(':') : wxT('=')) << val;
}
usage << negator;
if ( !(opt.flags & wxCMD_LINE_OPTION_MANDATORY) )
{
usage << wxT(']');