From: Vadim Zeitlin Date: Wed, 24 Nov 2010 00:42:53 +0000 (+0000) Subject: Add support for negatable command line switches. X-Git-Url: https://git.saurik.com/wxWidgets.git/commitdiff_plain/a6bf0c9533b2ed4434e667936c0e3d2f534de0e4 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 --- diff --git a/docs/changes.txt b/docs/changes.txt index 5278f00faa..e9cf61edaa 100644 --- a/docs/changes.txt +++ b/docs/changes.txt @@ -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: diff --git a/include/wx/cmdline.h b/include/wx/cmdline.h index 1ab9966364..86bbc2d5ca 100644 --- a/include/wx/cmdline.h +++ b/include/wx/cmdline.h @@ -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; diff --git a/interface/wx/cmdline.h b/interface/wx/cmdline.h index d0952b5cde..a9b7630e9a 100644 --- a/interface/wx/cmdline.h +++ b/interface/wx/cmdline.h @@ -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). diff --git a/src/common/cmdline.cpp b/src/common/cmdline.cpp index ffa7e5ba36..030f891ea6 100644 --- a/src/common/cmdline.cpp +++ b/src/common/cmdline.cpp @@ -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(']');