]> git.saurik.com Git - wxWidgets.git/commitdiff
added wxCmdLineParser::ConvertStringToArgs(), wxApp::ConertToStandardCommandArgs...
authorVadim Zeitlin <vadim@wxwidgets.org>
Sun, 25 Nov 2001 21:36:28 +0000 (21:36 +0000)
committerVadim Zeitlin <vadim@wxwidgets.org>
Sun, 25 Nov 2001 21:36:28 +0000 (21:36 +0000)
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@12698 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

include/wx/cmdline.h
include/wx/msw/app.h
samples/console/console.cpp
src/common/cmdline.cpp
src/msw/app.cpp

index a3a685ce3fe417c7dafd10c771e52bf909f53f01..dccfc4068758b21f061ddd84b65697fab534b45d 100644 (file)
@@ -191,8 +191,11 @@ public:
     // gets the value of Nth parameter (as string only for now)
     wxString GetParam(size_t n = 0u) const;
 
-       // Resets switches and options
-       void Reset();
+    // Resets switches and options
+    void Reset();
+
+    // break down the command line in arguments
+    static wxArrayString ConvertStringToArgs(const wxChar *cmdline);
 
 private:
     // common part of all ctors
@@ -201,6 +204,17 @@ private:
     struct wxCmdLineParserData *m_data;
 };
 
-#endif // wxUSE_CMDLINE_PARSER
+#else // !wxUSE_CMDLINE_PARSER
+
+// this function is always available (even if !wxUSE_CMDLINE_PARSER) because it
+// is used by wxWin itself under Windows
+class WXDLLEXPORT wxCmdLineParser
+{
+public:
+    static wxArrayString ConvertStringToArgs(const wxChar *cmdline);
+};
+
+#endif // wxUSE_CMDLINE_PARSER/!wxUSE_CMDLINE_PARSER
 
 #endif // _WX_CMDLINE_H_
+
index e361fa3ca8d6c2f627747ec35e908b0dd51294a6..c6e1348015ff006f8b9d87f0a8306ba66f122892 100644 (file)
@@ -81,7 +81,7 @@ public:
     static bool UnregisterWindowClasses();
 
     // Convert Windows to argc, argv style
-    void ConvertToStandardCommandArgs(char* p);
+    void ConvertToStandardCommandArgs(const char* p);
 
     // message processing
     // ------------------
index 662ca1c85a95553815e2b71739e4504650e77848..51b30e31607594609d1ae1f330f89ee051a50eea 100644 (file)
 // conditional compilation
 // ----------------------------------------------------------------------------
 
-// what to test (in alphabetic order)?
-
-//#define TEST_ARRAYS
-//#define TEST_CHARSET
-//#define TEST_CMDLINE
-//#define TEST_DATETIME
-//#define TEST_DIR
-//#define TEST_DLLLOADER
-//#define TEST_ENVIRON
-//#define TEST_EXECUTE
-//#define TEST_FILE
-#define TEST_FILECONF
-//#define TEST_FILENAME
-//#define TEST_FILETIME
-//#define TEST_FTP
-//#define TEST_HASH
-//#define TEST_INFO_FUNCTIONS
-//#define TEST_LIST
-//#define TEST_LOCALE
-//#define TEST_LOG
-//#define TEST_LONGLONG
-//#define TEST_MIME
-//#define TEST_PATHLIST
-//#define TEST_REGCONF
-//#define TEST_REGEX
-//#define TEST_REGISTRY
-//#define TEST_SNGLINST
-//#define TEST_SOCKETS
-//#define TEST_STREAMS
-//#define TEST_STRINGS
-//#define TEST_THREADS
-//#define TEST_TIMER
-//#define TEST_VCARD            -- don't enable this (VZ)
-//#define TEST_WCHAR
-//#define TEST_ZIP
-//#define TEST_ZLIB
+// what to test (in alphabetic order)? uncomment the line below to do all tests
+//#define TEST_ALL
+#ifdef TEST_ALL
+    #define TEST_ARRAYS
+    #define TEST_CHARSET
+    #define TEST_CMDLINE
+    #define TEST_DATETIME
+    #define TEST_DIR
+    #define TEST_DLLLOADER
+    #define TEST_ENVIRON
+    #define TEST_EXECUTE
+    #define TEST_FILE
+    #define TEST_FILECONF
+    #define TEST_FILENAME
+    #define TEST_FILETIME
+    #define TEST_FTP
+    #define TEST_HASH
+    #define TEST_INFO_FUNCTIONS
+    #define TEST_LIST
+    #define TEST_LOCALE
+    #define TEST_LOG
+    #define TEST_LONGLONG
+    #define TEST_MIME
+    #define TEST_PATHLIST
+    #define TEST_REGCONF
+    #define TEST_REGEX
+    #define TEST_REGISTRY
+    #define TEST_SNGLINST
+    #define TEST_SOCKETS
+    #define TEST_STREAMS
+    #define TEST_STRINGS
+    #define TEST_THREADS
+    #define TEST_TIMER
+    // #define TEST_VCARD            -- don't enable this (VZ)
+    #define TEST_WCHAR
+    #define TEST_ZIP
+    #define TEST_ZLIB
+#else
+    #define TEST_CMDLINE
+#endif
 
 #ifdef TEST_SNGLINST
     #include "wx/snglinst.h"
@@ -178,6 +182,8 @@ static void TestCharset()
 #include "wx/cmdline.h"
 #include "wx/datetime.h"
 
+#if wxUSE_CMDLINE_PARSER
+
 static void ShowCmdLine(const wxCmdLineParser& parser)
 {
     wxString s = "Input files: ";
@@ -209,6 +215,32 @@ static void ShowCmdLine(const wxCmdLineParser& parser)
     wxLogMessage(s);
 }
 
+#endif // wxUSE_CMDLINE_PARSER
+
+static void TestCmdLineConvert()
+{
+    static const char *cmdlines[] =
+    {
+        "arg1 arg2",
+        "-a \"-bstring 1\" -c\"string 2\" \"string 3\"",
+        "literal \\\" and \"\"",
+    };
+
+    for ( size_t n = 0; n < WXSIZEOF(cmdlines); n++ )
+    {
+        const char *cmdline = cmdlines[n];
+        printf("Parsing: %s\n", cmdline);
+        wxArrayString args = wxCmdLineParser::ConvertStringToArgs(cmdline);
+
+        size_t count = args.GetCount();
+        printf("\targc = %u\n", count);
+        for ( size_t arg = 0; arg < count; arg++ )
+        {
+            printf("\targv[%u] = %s\n", arg, args[arg]);
+        }
+    }
+}
+
 #endif // TEST_CMDLINE
 
 // ----------------------------------------------------------------------------
@@ -4944,6 +4976,9 @@ int main(int argc, char **argv)
 #endif // TEST_CHARSET
 
 #ifdef TEST_CMDLINE
+    TestCmdLineConvert();
+
+#if wxUSE_CMDLINE_PARSER
     static const wxCmdLineEntryDesc cmdLineDesc[] =
     {
         { wxCMD_LINE_SWITCH, _T("h"), _T("help"), "show this help message",
@@ -4984,6 +5019,8 @@ int main(int argc, char **argv)
             wxLogMessage("Syntax error detected, aborting.");
             break;
     }
+#endif // wxUSE_CMDLINE_PARSER
+
 #endif // TEST_CMDLINE
 
 #ifdef TEST_STRINGS
index 46517df3a2700ad2668214ba7cd2d8d72580cde5..142cf53dadd93cc920352dd480bcbc1e660d8265 100644 (file)
@@ -28,6 +28,8 @@
     #pragma hdrstop
 #endif
 
+#include "wx/cmdline.h"
+
 #if wxUSE_CMDLINE_PARSER
 
 #ifndef WX_PRECOMP
@@ -42,7 +44,6 @@
 #include <ctype.h>
 
 #include "wx/datetime.h"
-#include "wx/cmdline.h"
 
 // ----------------------------------------------------------------------------
 // private functions
@@ -201,44 +202,9 @@ void wxCmdLineParserData::SetArguments(const wxString& cmdLine)
 
     m_arguments.Add(wxTheApp->GetAppName());
 
-    // Break up string
-    // Treat strings enclosed in double-quotes as single arguments
-    int i = 0;
-    int len = cmdLine.Length();
-    while (i < len)
-    {
-        // Skip whitespace
-        while ((i < len) && wxIsspace(cmdLine.GetChar(i)))
-            i ++;
-
-        if (i < len)
-        {
-            if (cmdLine.GetChar(i) == wxT('"')) // We found the start of a string
-            {
-                i ++;
-                int first = i;
-                while ((i < len) && (cmdLine.GetChar(i) != wxT('"')))
-                    i ++;
-
-                wxString arg(cmdLine.Mid(first, (i - first)));
+    wxArrayString args = wxCmdLineParser::ConvertStringToArgs(cmdLine);
 
-                m_arguments.Add(arg);
-
-                if (i < len)
-                    i ++; // Skip past 2nd quote
-            }
-            else // Unquoted argument
-            {
-                int first = i;
-                while ((i < len) && !wxIsspace(cmdLine.GetChar(i)))
-                    i ++;
-
-                wxString arg(cmdLine.Mid(first, (i - first)));
-
-                m_arguments.Add(arg);
-            }
-        }
-    }
+    WX_APPEND_ARRAY(m_arguments, args);
 }
 
 int wxCmdLineParserData::FindOption(const wxString& name)
@@ -964,7 +930,7 @@ void wxCmdLineParser::Usage()
 }
 
 // ----------------------------------------------------------------------------
-// global functions
+// private functions
 // ----------------------------------------------------------------------------
 
 static wxString GetTypeName(wxCmdLineParamType type)
@@ -985,3 +951,96 @@ static wxString GetTypeName(wxCmdLineParamType type)
 }
 
 #endif // wxUSE_CMDLINE_PARSER
+
+// ----------------------------------------------------------------------------
+// global functions
+// ----------------------------------------------------------------------------
+
+/* static */
+wxArrayString wxCmdLineParser::ConvertStringToArgs(const wxChar *p)
+{
+    wxArrayString args;
+
+    wxString arg;
+    arg.reserve(1024);
+
+    bool isInsideQuotes = FALSE;
+    for ( ;; )
+    {
+        // skip white space
+        while ( *p == _T(' ') || *p == _T('\t') )
+            p++;
+
+        // anything left?
+        if ( *p == _T('\0') )
+            break;
+
+        // parse this parameter
+        arg.clear();
+        for ( ;; p++ )
+        {
+            // do we have a (lone) backslash?
+            bool isQuotedByBS = FALSE;
+            while ( *p == _T('\\') )
+            {
+                p++;
+
+                // if we have 2 backslashes in a row, output one
+                if ( isQuotedByBS )
+                {
+                    arg += _T('\\');
+                    isQuotedByBS = FALSE;
+                }
+                else // the next char is quoted
+                {
+                    isQuotedByBS = TRUE;
+                }
+            }
+
+            bool skipChar = FALSE,
+                 endParam = FALSE;
+            switch ( *p )
+            {
+                case _T('"'):
+                    if ( !isQuotedByBS )
+                    {
+                        // don't put the quote itself in the arg
+                        skipChar = TRUE;
+
+                        isInsideQuotes = !isInsideQuotes;
+                    }
+                    //else: insert a literal quote
+
+                    break;
+
+                case _T(' '):
+                case _T('\t'):
+                    if ( isInsideQuotes )
+                    {
+                        // preserve it, skip endParam below
+                        break;
+                    }
+                    //else: fall through
+
+                case _T('\0'):
+                    endParam = TRUE;
+                    break;
+            }
+
+            // end of argument?
+            if ( endParam )
+                break;
+
+            // otherwise copy this char to arg
+            if ( !skipChar )
+            {
+                arg += *p;
+            }
+        }
+
+        args.Add(arg);
+    }
+
+    return args;
+}
+
index 91a7290854fd1c57628e86f49ad9b237a1459869..67e6a44eae81920f6a5a978bb007ad2aa424c18a 100644 (file)
     #include "wx/dynarray.h"
     #include "wx/wxchar.h"
     #include "wx/icon.h"
+    #include "wx/log.h"
 #endif
 
-#include "wx/log.h"
+#include "wx/cmdline.h"
 #include "wx/module.h"
 
 #include "wx/msw/private.h"
@@ -548,73 +549,28 @@ bool wxApp::UnregisterWindowClasses()
 // Convert Windows to argc, argv style
 // ---------------------------------------------------------------------------
 
-void wxApp::ConvertToStandardCommandArgs(char* lpCmdLine)
+void wxApp::ConvertToStandardCommandArgs(const char* lpCmdLine)
 {
-    wxStringList args;
+    // break the command line in words
+    wxArrayString args =
+        wxCmdLineParser::ConvertStringToArgs(wxConvertMB2WX(lpCmdLine));
 
-    wxString cmdLine(lpCmdLine);
-    int count = 0;
+    // +1 here for the program name
+    argc = args.GetCount() + 1;
 
-    // Get application name
-    wxChar name[260]; // 260 is MAX_PATH value from windef.h
-    ::GetModuleFileName(wxhInstance, name, WXSIZEOF(name));
+    // and +1 here for the terminating NULL
+    argv = new wxChar *[argc + 1];
 
-    args.Add(name);
-    count++;
+    argv[0] = new wxChar[260]; // 260 is MAX_PATH value from windef.h
+    ::GetModuleFileName(wxhInstance, argv[0], 260);
 
-    wxStrcpy(name, wxFileNameFromPath(name));
-    wxStripExtension(name);
-    wxTheApp->SetAppName(name);
-
-    // Break up string
-    // Treat strings enclosed in double-quotes as single arguments
-    int i = 0;
-    int len = cmdLine.Length();
-    while (i < len)
+    for ( int i = 1; i < argc; i++ )
     {
-        // Skip whitespace
-        while ((i < len) && wxIsspace(cmdLine.GetChar(i)))
-            i ++;
-
-        if (i < len)
-        {
-            if (cmdLine.GetChar(i) == wxT('"')) // We found the start of a string
-            {
-                i ++;
-                int first = i;
-                while ((i < len) && (cmdLine.GetChar(i) != wxT('"')))
-                    i ++;
-
-                wxString arg(cmdLine.Mid(first, (i - first)));
-
-                args.Add(arg);
-                count ++;
-
-                if (i < len)
-                    i ++; // Skip past 2nd quote
-            }
-            else // Unquoted argument
-            {
-                int first = i;
-                while ((i < len) && !wxIsspace(cmdLine.GetChar(i)))
-                    i ++;
-
-                wxString arg(cmdLine.Mid(first, (i - first)));
-
-                args.Add(arg);
-                count ++;
-            }
-        }
+        argv[i] = copystring(args[i - 1]);
     }
 
-    wxTheApp->argv = new wxChar*[count + 1];
-    for (i = 0; i < count; i++)
-    {
-        wxString arg(args[i]);
-        wxTheApp->argv[i] = copystring((const wxChar*)arg);
-    }
-    wxTheApp->argv[count] = NULL; // argv[] is a NULL-terminated list
-    wxTheApp->argc = count;
+    // argv[] must be NULL-terminated
+    argv[argc] = NULL;
 }
 
 //// Cleans up any wxWindows internal structures left lying around