]> git.saurik.com Git - wxWidgets.git/blobdiff - src/common/cmdline.cpp
Compilation fix for r74440 and STL builds.
[wxWidgets.git] / src / common / cmdline.cpp
index 030f891ea6f583006f26e548952b0856b9aa38e5..2d6feae46b7082a1af04b6814f896a51f5939703 100644 (file)
@@ -106,8 +106,7 @@ struct wxCmdLineOption
         type = typ;
         flags = fl;
 
-        m_hasVal = false;
-        m_isNegated = false;
+        Reset();
     }
 
     // can't use union easily here, so just store all possible data fields, we
@@ -142,12 +141,19 @@ struct wxCmdLineOption
         { Check(wxCMD_LINE_VAL_DATE); m_dateVal = val; m_hasVal = true; }
 #endif // wxUSE_DATETIME
 
-    void SetHasValue(bool hasValue = true) { m_hasVal = hasValue; }
+    void SetHasValue() { m_hasVal = true; }
     bool HasValue() const { return m_hasVal; }
 
     void SetNegated() { m_isNegated = true; }
     bool IsNegated() const { return m_isNegated; }
 
+    // Reset to the initial state, called before parsing another command line.
+    void Reset()
+    {
+        m_hasVal =
+        m_isNegated = false;
+    }
+
 public:
     wxCmdLineEntryType kind;
     wxString shortName,
@@ -637,8 +643,7 @@ void wxCmdLineParser::Reset()
 {
     for ( size_t i = 0; i < m_data->m_options.GetCount(); i++ )
     {
-        wxCmdLineOption& opt = m_data->m_options[i];
-        opt.SetHasValue(false);
+        m_data->m_options[i].Reset();
     }
 }
 
@@ -702,11 +707,45 @@ int wxCmdLineParser::Parse(bool showUsage)
 
                 if (longOptionsEnabled)
                 {
+                    wxString errorOpt;
+
                     optInd = m_data->FindOptionByLongName(name);
                     if ( optInd == wxNOT_FOUND )
                     {
-                        errorMsg << wxString::Format(_("Unknown long option '%s'"), name.c_str())
-                                 << wxT('\n');
+                        // Check if this could be a negatable long option.
+                        if ( name.Last() == '-' )
+                        {
+                            name.RemoveLast();
+
+                            optInd = m_data->FindOptionByLongName(name);
+                            if ( optInd != wxNOT_FOUND )
+                            {
+                                if ( !(m_data->m_options[optInd].flags &
+                                        wxCMD_LINE_SWITCH_NEGATABLE) )
+                                {
+                                    errorOpt.Printf
+                                             (
+                                              _("Option '%s' can't be negated"),
+                                              name
+                                             );
+                                    optInd = wxNOT_FOUND;
+                                }
+                            }
+                        }
+
+                        if ( optInd == wxNOT_FOUND )
+                        {
+                            if ( errorOpt.empty() )
+                            {
+                                errorOpt.Printf
+                                         (
+                                          _("Unknown long option '%s'"),
+                                          name
+                                         );
+                            }
+
+                            errorMsg << errorOpt << wxT('\n');
+                        }
                     }
                 }
                 else
@@ -930,8 +969,8 @@ int wxCmdLineParser::Parse(bool showUsage)
                         case wxCMD_LINE_VAL_DATE:
                             {
                                 wxDateTime dt;
-                                wxString::const_iterator end;
-                                if ( !dt.ParseDate(value, &end) || end != value.end() )
+                                wxString::const_iterator endDate;
+                                if ( !dt.ParseDate(value, &endDate) || endDate != value.end() )
                                 {
                                     errorMsg << wxString::Format(_("Option '%s': '%s' cannot be converted to a date."),
                                                                  name.c_str(), value.c_str())
@@ -1171,7 +1210,6 @@ wxString wxCmdLineParser::GetUsageString() const
                 option << (!opt.longName ? wxT(':') : wxT('=')) << val;
             }
 
-            usage << negator;
             if ( !(opt.flags & wxCMD_LINE_OPTION_MANDATORY) )
             {
                 usage << wxT(']');
@@ -1339,6 +1377,23 @@ static wxString GetLongOptionName(wxString::const_iterator p,
    Windows conventions for the command line handling, not Unix ones. For
    instance, backslash is not special except when it precedes double quote when
    it does quote it.
+
+   TODO: Rewrite this to follow the even more complicated rule used by Windows
+         CommandLineToArgv():
+
+    * A string of backslashes not followed by a quotation mark has no special
+      meaning.
+    * An even number of backslashes followed by a quotation mark is treated as
+      pairs of protected backslashes, followed by a word terminator.
+    * An odd number of backslashes followed by a quotation mark is treated as
+      pairs of protected backslashes, followed by a protected quotation mark.
+
+    See http://blogs.msdn.com/b/oldnewthing/archive/2010/09/17/10063629.aspx
+
+    It could also be useful to provide a converse function which is also
+    non-trivial, see
+
+    http://blogs.msdn.com/b/twistylittlepassagesallalike/archive/2011/04/23/everyone-quotes-arguments-the-wrong-way.aspx
  */
 
 /* static */