]> git.saurik.com Git - wxWidgets.git/blobdiff - src/common/cmdline.cpp
more fixes to radio menu items: fixed Check() for them; allow separators inside the...
[wxWidgets.git] / src / common / cmdline.cpp
index 142cf53dadd93cc920352dd480bcbc1e660d8265..2c5ea56421506699afcbe5e318222bb2e22b30bd 100644 (file)
@@ -109,7 +109,9 @@ struct wxCmdLineOption
 
 public:
     wxCmdLineEntryType kind;
-    wxString shortName, longName, description;
+    wxString shortName,
+             longName,
+             description;
     wxCmdLineParamType type;
     int flags;
 
@@ -458,6 +460,8 @@ size_t wxCmdLineParser::GetParamCount() const
 
 wxString wxCmdLineParser::GetParam(size_t n) const
 {
+    wxCHECK_MSG( n < GetParamCount(), wxEmptyString, _T("invalid param index") );
+
     return m_data->m_parameters[n];
 }
 
@@ -476,7 +480,7 @@ void wxCmdLineParser::Reset()
 // the real work is done here
 // ----------------------------------------------------------------------------
 
-int wxCmdLineParser::Parse()
+int wxCmdLineParser::Parse(bool showUsage)
 {
     bool maybeOption = TRUE;    // can the following arg be an option?
     bool ok = TRUE;             // TRUE until an error is detected
@@ -803,7 +807,7 @@ int wxCmdLineParser::Parse()
         }
     }
 
-    if ( !ok )
+    if ( !ok && showUsage )
     {
         Usage();
     }
@@ -849,13 +853,30 @@ void wxCmdLineParser::Usage()
             brief << _T('[');
         }
 
-        brief << chSwitch << opt.shortName;
+        if ( !opt.shortName.empty() )
+        {
+            brief << chSwitch << opt.shortName;
+        }
+        else if ( !opt.longName.empty() )
+        {
+            brief << _T("--") << opt.longName;
+        }
+        else
+        {
+            wxFAIL_MSG( _T("option without neither short nor long name?") );
+        }
 
         wxString option;
-        option << _T("  ") << chSwitch << opt.shortName;
-        if ( !!opt.longName )
+
+        if ( !opt.shortName.empty() )
+        {
+            option << _T("  ") << chSwitch << opt.shortName;
+        }
+
+        if ( !opt.longName.empty() )
         {
-            option << _T("  --") << opt.longName;
+            option << (option.empty() ? _T("  ") : _T(", "))
+                   << _T("--") << opt.longName;
         }
 
         if ( opt.kind != wxCMD_LINE_SWITCH )
@@ -904,7 +925,13 @@ void wxCmdLineParser::Usage()
         wxLogMessage(m_data->m_logo);
     }
 
+    // in console mode we want to show the brief usage message first, then the
+    // detailed one but in GUI build we give the details first and then the
+    // summary - like this, the brief message appears in the wxLogGui dialog,
+    // as expected
+#if !wxUSE_GUI
     wxLogMessage(brief);
+#endif // !wxUSE_GUI
 
     // now construct the detailed help message
     size_t len, lenMax = 0;
@@ -927,6 +954,11 @@ void wxCmdLineParser::Usage()
     }
 
     wxLogMessage(detailed);
+
+    // do it now if not done above
+#if wxUSE_GUI
+    wxLogMessage(brief);
+#endif // wxUSE_GUI
 }
 
 // ----------------------------------------------------------------------------
@@ -956,6 +988,28 @@ static wxString GetTypeName(wxCmdLineParamType type)
 // global functions
 // ----------------------------------------------------------------------------
 
+/*
+   This function is mainly used under Windows (as under Unix we always get the
+   command line arguments as agrc/argv anyhow) and so it tries to handle the
+   Windows path names (separated by backslashes) correctly. For this it only
+   considers that a backslash may be used to escape another backslash (but
+   normally this is _not_ needed) or a quote but nothing else.
+
+   In particular, to pass a single argument containing a space to the program
+   it should be quoted:
+   
+   myprog.exe foo bar       -> argc = 3, argv[1] = "foo", argv[2] = "bar"
+   myprog.exe "foo bar"     -> argc = 2, argv[1] = "foo bar"
+
+   To pass an argument containing spaces and quotes, the latter should be
+   escaped with a backslash:
+
+   myprog.exe "foo \"bar\"" -> argc = 2, argv[1] = "foo "bar""
+
+   This hopefully matches the conventions used by Explorer/command line
+   interpreter under Windows. If not, this function should be fixed.
+ */
+
 /* static */
 wxArrayString wxCmdLineParser::ConvertStringToArgs(const wxChar *p)
 {
@@ -1015,6 +1069,10 @@ wxArrayString wxCmdLineParser::ConvertStringToArgs(const wxChar *p)
 
                 case _T(' '):
                 case _T('\t'):
+                    // we intentionally don't check for preceding backslash
+                    // here as if we allowed it to be used to escape spaces the
+                    // cmd line of the form "foo.exe a:\ c:\bar" wouldn't be
+                    // parsed correctly
                     if ( isInsideQuotes )
                     {
                         // preserve it, skip endParam below
@@ -1025,6 +1083,15 @@ wxArrayString wxCmdLineParser::ConvertStringToArgs(const wxChar *p)
                 case _T('\0'):
                     endParam = TRUE;
                     break;
+
+                default:
+                    if ( isQuotedByBS )
+                    {
+                        // ignore backslash before an ordinary character - this
+                        // is needed to properly handle the file names under
+                        // Windows appearing in the command line
+                        arg += _T('\\');
+                    }
             }
 
             // end of argument?