]> git.saurik.com Git - wxWidgets.git/commitdiff
Add support for negatable command line switches.
authorVadim Zeitlin <vadim@wxwidgets.org>
Wed, 24 Nov 2010 00:42:53 +0000 (00:42 +0000)
committerVadim Zeitlin <vadim@wxwidgets.org>
Wed, 24 Nov 2010 00:42:53 +0000 (00:42 +0000)
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

docs/changes.txt
include/wx/cmdline.h
interface/wx/cmdline.h
src/common/cmdline.cpp

index 5278f00faad380fd0aac2585d7bae6d4bc8fac65..e9cf61edaa5b71584915aa038c0814c6859d6489 100644 (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:
 
index 1ab9966364010b9eb473a9ea4bf9681cb99ebb3d..86bbc2d5ca857a5c5bcc06fa18b95d6a04846b76 100644 (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;
index d0952b5cde67db8769af51debe2e00039f51313c..a9b7630e9a860bb05ebf47c2a056c0edd7b37d26 100644 (file)
     @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).
index ffa7e5ba36eadb7addeab7962664097d219a2306..030f891ea6f583006f26e548952b0856b9aa38e5 100644 (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(']');