]> git.saurik.com Git - wxWidgets.git/commitdiff
fix bugs introduced in wxCmdLineParser::ConvertStringToArgs() during Unicode transiti...
authorVadim Zeitlin <vadim@wxwidgets.org>
Sat, 12 Apr 2008 17:03:09 +0000 (17:03 +0000)
committerVadim Zeitlin <vadim@wxwidgets.org>
Sat, 12 Apr 2008 17:03:09 +0000 (17:03 +0000)
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@53142 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

12 files changed:
include/wx/cppunit.h
src/common/cmdline.cpp
tests/Makefile.in
tests/cmdline/cmdlinetest.cpp [new file with mode: 0644]
tests/makefile.bcc
tests/makefile.gcc
tests/makefile.vc
tests/makefile.wat
tests/test.bkl
tests/test_test.dsp
tests/test_vc7_test.vcproj
tests/test_vc8_test.vcproj

index e87892b5a2ef5a7be8bf0833e2a8a0807f6d13da..a7affd50ae9c9a03d42ac45fdb3996bf47a7873f 100644 (file)
 // Use this macro to compare a size_t with a literal integer
 #define WX_ASSERT_SIZET_EQUAL(n, m) CPPUNIT_ASSERT_EQUAL(((size_t)n), m)
 
+// Use this macro to compare a wxArrayString with the pipe-separated elements
+// of the given string
+//
+// NB: it's a macro and not a function to have the correct line numbers in the
+//     test failure messages
+#define WX_ASSERT_STRARRAY_EQUAL(s, a)                                        \
+    {                                                                         \
+        wxArrayString expected(wxSplit(s, '|', '\0'));                        \
+                                                                              \
+        CPPUNIT_ASSERT_EQUAL( expected.size(), a.size() );                    \
+                                                                              \
+        for ( size_t n = 0; n < a.size(); n++ )                               \
+        {                                                                     \
+            CPPUNIT_ASSERT_EQUAL( expected[n], a[n] );                        \
+        }                                                                     \
+    }
 
 // Use this macro to assert with the given formatted message (it should contain
 // the format string and arguments in a separate pair of parentheses)
index 63ee43c1a82c3498481d9f7bec6930608e8d84dc..6f3b1860e5c552707b74a9e39b7909cabdb25067 100644 (file)
@@ -1255,62 +1255,47 @@ wxArrayString wxCmdLineParser::ConvertStringToArgs(const wxString& cmdline)
 
     bool isInsideQuotes = false;
 
+    const wxString::const_iterator end = cmdline.end();
     wxString::const_iterator p = cmdline.begin();
 
     for ( ;; )
     {
         // skip white space
-        while ( p != cmdline.end() && (*p == _T(' ') || *p == _T('\t')) )
+        while ( p != end && (*p == ' ' || *p == '\t') )
             ++p;
 
         // anything left?
-        if ( p == cmdline.end() )
+        if ( p == end )
             break;
 
         // parse this parameter
-        bool endParam = false;
         bool lastBS = false;
-        for ( arg.clear(); !endParam; p++ )
+        for ( arg.clear(); p != end; ++p )
         {
-            switch ( (*p).GetValue() )
+            const wxChar ch = *p;
+            if ( ch == '"' )
             {
-                case _T('"'):
-                    if ( !lastBS )
-                    {
-                        isInsideQuotes = !isInsideQuotes;
-
-                        // don't put quote in arg
-                        continue;
-                    }
-                    //else: quote has no special meaning but the backslash
-                    //      still remains -- makes no sense but this is what
-                    //      Windows does
-                    break;
-
-                case _T(' '):
-                case _T('\t'):
-                    // backslash does *not* quote the space, only quotes do
-                    if ( isInsideQuotes )
-                    {
-                        // skip assignment below
-                        break;
-                    }
-                    // fall through
-
-                case _T('\0'):
-                    endParam = true;
+                if ( !lastBS )
+                {
+                    isInsideQuotes = !isInsideQuotes;
 
-                    break;
+                    // don't put quote in arg
+                    continue;
+                }
+                //else: quote has no special meaning but the backslash
+                //      still remains -- makes no sense but this is what
+                //      Windows does
             }
-
-            if ( endParam )
+            // note that backslash does *not* quote the space, only quotes do
+            else if ( !isInsideQuotes && (ch == ' ' || ch == '\t') )
             {
+                ++p;    // skip this space anyhow
                 break;
             }
 
-            lastBS = *p == _T('\\');
+            lastBS = ch == '\\';
 
-            arg += *p;
+            arg += ch;
         }
 
         args.push_back(arg);
index 950d9703af34ed610013a1f4ec8660fbce125765..562680c0f7026da3f7900a5547d69c46136a3a1b 100644 (file)
@@ -57,6 +57,7 @@ TEST_OBJECTS =  \
        test_tartest.o \
        test_arrays.o \
        test_base64.o \
+       test_cmdlinetest.o \
        test_fileconf.o \
        test_datetimetest.o \
        test_filekind.o \
@@ -344,6 +345,9 @@ test_arrays.o: $(srcdir)/arrays/arrays.cpp $(TEST_ODEP)
 test_base64.o: $(srcdir)/base64/base64.cpp $(TEST_ODEP)
        $(CXXC) -c -o $@ $(TEST_CXXFLAGS) $(srcdir)/base64/base64.cpp
 
+test_cmdlinetest.o: $(srcdir)/cmdline/cmdlinetest.cpp $(TEST_ODEP)
+       $(CXXC) -c -o $@ $(TEST_CXXFLAGS) $(srcdir)/cmdline/cmdlinetest.cpp
+
 test_fileconf.o: $(srcdir)/config/fileconf.cpp $(TEST_ODEP)
        $(CXXC) -c -o $@ $(TEST_CXXFLAGS) $(srcdir)/config/fileconf.cpp
 
diff --git a/tests/cmdline/cmdlinetest.cpp b/tests/cmdline/cmdlinetest.cpp
new file mode 100644 (file)
index 0000000..8e87964
--- /dev/null
@@ -0,0 +1,82 @@
+///////////////////////////////////////////////////////////////////////////////
+// Name:        tests/cmdline/cmdlinetest.cpp
+// Purpose:     wxCmdLineParser unit test
+// Author:      Vadim Zeitlin
+// Created:     2008-04-12
+// RCS-ID:      $Id$
+// Copyright:   (c) 2008 Vadim Zeitlin <vadim@wxwidgets.org>
+///////////////////////////////////////////////////////////////////////////////
+
+// ----------------------------------------------------------------------------
+// headers
+// ----------------------------------------------------------------------------
+
+#include "testprec.h"
+
+#ifdef __BORLANDC__
+    #pragma hdrstop
+#endif
+
+#ifndef WX_PRECOMP
+#endif // WX_PRECOMP
+
+#include "wx/cmdline.h"
+
+// --------------------------------------------------------------------------
+// test class
+// --------------------------------------------------------------------------
+
+class CmdLineTestCase : public CppUnit::TestCase
+{
+public:
+    CmdLineTestCase() {}
+
+private:
+    CPPUNIT_TEST_SUITE( CmdLineTestCase );
+        CPPUNIT_TEST( ConvertStringTestCase );
+    CPPUNIT_TEST_SUITE_END();
+
+    void ConvertStringTestCase();
+
+    DECLARE_NO_COPY_CLASS(CmdLineTestCase)
+};
+
+// register in the unnamed registry so that these tests are run by default
+CPPUNIT_TEST_SUITE_REGISTRATION( CmdLineTestCase );
+
+// also include in it's own registry so that these tests can be run alone
+CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( CmdLineTestCase, "CmdLineTestCase" );
+
+// ============================================================================
+// implementation
+// ============================================================================
+
+void CmdLineTestCase::ConvertStringTestCase()
+{
+    #define WX_ASSERT_ARGS_EQUAL(s, args)                                     \
+        {                                                                     \
+            const wxArrayString a(wxCmdLineParser::ConvertStringToArgs(args));\
+            WX_ASSERT_STRARRAY_EQUAL(s, a);                                   \
+        }
+
+    // normal cases
+    WX_ASSERT_ARGS_EQUAL( "foo", "foo" )
+    WX_ASSERT_ARGS_EQUAL( "foo bar", "\"foo bar\"" )
+    WX_ASSERT_ARGS_EQUAL( "foo|bar", "foo bar" )
+    WX_ASSERT_ARGS_EQUAL( "foo|bar|baz", "foo bar baz" )
+    WX_ASSERT_ARGS_EQUAL( "foo|bar baz", "foo \"bar baz\"" )
+
+    // special cases
+    WX_ASSERT_ARGS_EQUAL( "", "" )
+    WX_ASSERT_ARGS_EQUAL( "foo", "foo " )
+    WX_ASSERT_ARGS_EQUAL( "foo", "foo \t   " )
+    WX_ASSERT_ARGS_EQUAL( "foo|bar", "foo bar " )
+    WX_ASSERT_ARGS_EQUAL( "foo|bar|", "foo bar \"" )
+    WX_ASSERT_ARGS_EQUAL( "foo|bar|\\", "foo bar \\" )
+
+    // check for (broken) Windows semantics: backslash doesn't escape spaces
+    WX_ASSERT_ARGS_EQUAL( "foo|bar\\|baz", "foo bar\\ baz" );
+    WX_ASSERT_ARGS_EQUAL( "foo|bar\\\"baz", "foo \"bar\\\"baz\"" );
+
+    #undef WX_ASSERT_ARGS_EQUAL
+}
index ecf68202c7df1173ff308fb1ddf9aa0d75ca29f9..ee35fe01e1a87675f2c7a536fd58f69fa7caea7b 100644 (file)
@@ -43,6 +43,7 @@ TEST_OBJECTS =  \
        $(OBJS)\test_tartest.obj \
        $(OBJS)\test_arrays.obj \
        $(OBJS)\test_base64.obj \
+       $(OBJS)\test_cmdlinetest.obj \
        $(OBJS)\test_fileconf.obj \
        $(OBJS)\test_datetimetest.obj \
        $(OBJS)\test_filekind.obj \
@@ -376,6 +377,9 @@ $(OBJS)\test_arrays.obj: .\arrays\arrays.cpp
 $(OBJS)\test_base64.obj: .\base64\base64.cpp
        $(CXX) -q -c -P -o$@ $(TEST_CXXFLAGS) .\base64\base64.cpp
 
+$(OBJS)\test_cmdlinetest.obj: .\cmdline\cmdlinetest.cpp
+       $(CXX) -q -c -P -o$@ $(TEST_CXXFLAGS) .\cmdline\cmdlinetest.cpp
+
 $(OBJS)\test_fileconf.obj: .\config\fileconf.cpp
        $(CXX) -q -c -P -o$@ $(TEST_CXXFLAGS) .\config\fileconf.cpp
 
index 1678a05f72a4d60409acc36d6ec6359fc6e77113..49dd117b90b31ff292a3699efa5a561ebd70bf73 100644 (file)
@@ -35,6 +35,7 @@ TEST_OBJECTS =  \
        $(OBJS)\test_tartest.o \
        $(OBJS)\test_arrays.o \
        $(OBJS)\test_base64.o \
+       $(OBJS)\test_cmdlinetest.o \
        $(OBJS)\test_fileconf.o \
        $(OBJS)\test_datetimetest.o \
        $(OBJS)\test_filekind.o \
@@ -354,6 +355,9 @@ $(OBJS)\test_arrays.o: ./arrays/arrays.cpp
 $(OBJS)\test_base64.o: ./base64/base64.cpp
        $(CXX) -c -o $@ $(TEST_CXXFLAGS) $(CPPDEPS) $<
 
+$(OBJS)\test_cmdlinetest.o: ./cmdline/cmdlinetest.cpp
+       $(CXX) -c -o $@ $(TEST_CXXFLAGS) $(CPPDEPS) $<
+
 $(OBJS)\test_fileconf.o: ./config/fileconf.cpp
        $(CXX) -c -o $@ $(TEST_CXXFLAGS) $(CPPDEPS) $<
 
index 6477522b046da3dd5cba4a27197af2f4fb307215..ada13d91f58d152f96b5c2421b1434b536851844 100644 (file)
@@ -36,6 +36,7 @@ TEST_OBJECTS =  \
        $(OBJS)\test_tartest.obj \
        $(OBJS)\test_arrays.obj \
        $(OBJS)\test_base64.obj \
+       $(OBJS)\test_cmdlinetest.obj \
        $(OBJS)\test_fileconf.obj \
        $(OBJS)\test_datetimetest.obj \
        $(OBJS)\test_filekind.obj \
@@ -461,6 +462,9 @@ $(OBJS)\test_arrays.obj: .\arrays\arrays.cpp
 $(OBJS)\test_base64.obj: .\base64\base64.cpp
        $(CXX) /c /nologo /TP /Fo$@ $(TEST_CXXFLAGS) .\base64\base64.cpp
 
+$(OBJS)\test_cmdlinetest.obj: .\cmdline\cmdlinetest.cpp
+       $(CXX) /c /nologo /TP /Fo$@ $(TEST_CXXFLAGS) .\cmdline\cmdlinetest.cpp
+
 $(OBJS)\test_fileconf.obj: .\config\fileconf.cpp
        $(CXX) /c /nologo /TP /Fo$@ $(TEST_CXXFLAGS) .\config\fileconf.cpp
 
index 875a094a6c0613eab7950c6d3f5f457d41359c8e..f17975db60d8f5b5fbff87d4e61f059499dce4df 100644 (file)
@@ -248,6 +248,7 @@ TEST_OBJECTS =  &
        $(OBJS)\test_tartest.obj &
        $(OBJS)\test_arrays.obj &
        $(OBJS)\test_base64.obj &
+       $(OBJS)\test_cmdlinetest.obj &
        $(OBJS)\test_fileconf.obj &
        $(OBJS)\test_datetimetest.obj &
        $(OBJS)\test_filekind.obj &
@@ -407,6 +408,9 @@ $(OBJS)\test_arrays.obj :  .AUTODEPEND .\arrays\arrays.cpp
 $(OBJS)\test_base64.obj :  .AUTODEPEND .\base64\base64.cpp
        $(CXX) -bt=nt -zq -fo=$^@ $(TEST_CXXFLAGS) $<
 
+$(OBJS)\test_cmdlinetest.obj :  .AUTODEPEND .\cmdline\cmdlinetest.cpp
+       $(CXX) -bt=nt -zq -fo=$^@ $(TEST_CXXFLAGS) $<
+
 $(OBJS)\test_fileconf.obj :  .AUTODEPEND .\config\fileconf.cpp
        $(CXX) -bt=nt -zq -fo=$^@ $(TEST_CXXFLAGS) $<
 
index b9acc86aff25f3673924e0b34c612140c14c62a7..4d3d5caa3c28e85c9e9e43a71a49867a3f0572c4 100644 (file)
@@ -29,6 +29,7 @@
             archive/tartest.cpp
             arrays/arrays.cpp
             base64/base64.cpp
+            cmdline/cmdlinetest.cpp
             config/fileconf.cpp
             datetime/datetimetest.cpp
             filekind/filekind.cpp
index 8191d2c212a0699fa26131996d6a65c42aadae3c..97269386757f076ca1bc3413c332e1727660b722 100644 (file)
@@ -255,6 +255,10 @@ SOURCE=.\streams\bstream.cpp
 # End Source File\r
 # Begin Source File\r
 \r
+SOURCE=.\cmdline\cmdlinetest.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
 SOURCE=.\mbconv\convautotest.cpp\r
 # End Source File\r
 # Begin Source File\r
index f5be6007e4370cddf06b6c35121470aba63c30bd..0332add3813f0ccb5d65b8c378b0f14eae73c73d 100644 (file)
                                RelativePath=".\base64\base64.cpp"/>\r
                        <File\r
                                RelativePath=".\streams\bstream.cpp"/>\r
+                       <File\r
+                               RelativePath=".\cmdline\cmdlinetest.cpp"/>\r
                        <File\r
                                RelativePath=".\mbconv\convautotest.cpp"/>\r
                        <File\r
index c401ce3bdabec5855086fb11799b5a5ffa8c34c4..0629254fdd96b2f6c80241c8969394de53d8b199 100644 (file)
                        <File\r
                                RelativePath=".\streams\bstream.cpp"\r
                        />\r
+                       <File\r
+                               RelativePath=".\cmdline\cmdlinetest.cpp"\r
+                       />\r
                        <File\r
                                RelativePath=".\mbconv\convautotest.cpp"\r
                        />\r