]> git.saurik.com Git - wxWidgets.git/commitdiff
fix handling of % in our printf implementation (part of patch 1462778)
authorVadim Zeitlin <vadim@wxwidgets.org>
Tue, 27 Jun 2006 14:21:15 +0000 (14:21 +0000)
committerVadim Zeitlin <vadim@wxwidgets.org>
Tue, 27 Jun 2006 14:21:15 +0000 (14:21 +0000)
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@39849 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

src/common/wxchar.cpp
tests/strings/vsnprintf.cpp

index 56095eefa816f62417332e8072a4e5d5033901b9..d6fd73b0a3b06285bc6d5adff9ffd529fb011fee 100644 (file)
@@ -1,8 +1,8 @@
 /////////////////////////////////////////////////////////////////////////////
 // Name:        src/common/wxchar.cpp
 // Purpose:     wxChar implementation
-// Author:      Ove Kåven
-// Modified by: Ron Lee
+// Author:      Ove Kaven
+// Modified by: Ron Lee, Francesco Montorsi
 // Created:     09/04/99
 // RCS-ID:      $Id$
 // Copyright:   (c) wxWidgets copyright
@@ -901,6 +901,36 @@ int wxPrintfConvSpec::Process(wxChar *buf, size_t lenMax, wxPrintfArg *p)
     return lenCur;
 }
 
+// differences from standard strncpy:
+// 1) copies everything from 'source' except for '%%' sequence which is copied as '%'
+// 2) returns the number of written characters in 'dest' as it could differ from given 'n'
+// 3) much less optimized, unfortunately...
+static int wxCopyStrWithPercents(wxChar *dest, const wxChar *source, size_t n)
+{
+    size_t written = 0;
+
+    if (n == 0)
+        return 0;
+
+    size_t i;
+    for ( i = 0; i < n-1; source++, i++)
+    {
+        dest[written++] = *source;
+        if (*(source+1) == wxT('%'))
+        {
+            // skip this additional '%' character
+            source++;
+            i++;
+        }
+    }
+
+    if (i < n)
+        // copy last character inconditionally
+        dest[written++] = *source;
+
+    return written;
+}
+
 int WXDLLEXPORT wxVsnprintf_(wxChar *buf, size_t lenMax,
                              const wxChar *format, va_list argptr)
 {
@@ -974,6 +1004,7 @@ int WXDLLEXPORT wxVsnprintf_(wxChar *buf, size_t lenMax,
 
     va_end(ap);
 
+    // something failed while loading arguments from the variable list...
     if (!ok)
         return -1;
 
@@ -987,8 +1018,7 @@ int WXDLLEXPORT wxVsnprintf_(wxChar *buf, size_t lenMax,
         if (lenCur+tocopy >= lenMax)
             return -1;      // not enough space in the output buffer !
 
-        wxStrncpy(buf+lenCur, toparse, tocopy);
-        lenCur += tocopy;
+        lenCur += wxCopyStrWithPercents(buf+lenCur, toparse, tocopy);
 
         // process this specifier directly in the output buffer
         int n = arg[i].Process(buf+lenCur, lenMax - lenCur, &argdata[arg[i].pos]);
@@ -1008,8 +1038,9 @@ int WXDLLEXPORT wxVsnprintf_(wxChar *buf, size_t lenMax,
     size_t tocopy = wxStrlen(format) + 1  - ( toparse - format ) ;
     if (lenCur+tocopy >= lenMax)
         return -1;      // not enough space in the output buffer !
-    wxStrncpy(buf+lenCur, toparse, tocopy);
-    lenCur += tocopy - 1;   // the -1 is because of the '\0'
+
+    // the -1 is because of the '\0'
+    lenCur += wxCopyStrWithPercents(buf+lenCur, toparse, tocopy) - 1;
 
     // clean the static array portion used...
     // NOTE: other arrays do not need cleanup!
index 8167b5be49a73a78c1791b42d82e8a457503ecb3..749c09078a134d6e59a130fd45808add5fa4a577 100644 (file)
@@ -184,6 +184,11 @@ void VsnprintfTestCase::S()
     CMP("abcdefghi", "%-5s", wxT("abcdefghi"));
 
     CMP("abcde", "%.5s", wxT("abcdefghi"));
+
+    // some tests without any argument:
+    Compare(wxT("%"), wxT("%%"));
+    Compare(wxT("%%%"), wxT("%%%%%%"));
+    Compare(wxT("%%"), wxT("%%%"));
 }
 
 void VsnprintfTestCase::Misc(wxChar *buffer, int size)
@@ -197,7 +202,7 @@ void VsnprintfTestCase::Misc(wxChar *buffer, int size)
     if (ret >= 0)
     {
         CPPUNIT_ASSERT_STR_EQUAL(
-            wxT("\n\naa 1.231230e+102 1.231231e+123 456 33333333 - test - 789 999 %% -       0.1-\n\n"),
+            wxT("\n\naa 1.231230e+102 1.231231e+123 456 33333333 - test - 789 999 % -       0.1-\n\n"),
             buffer);
     }
 
@@ -208,7 +213,7 @@ void VsnprintfTestCase::Misc(wxChar *buffer, int size)
     if (ret >= 0)
     {
         CPPUNIT_ASSERT_STR_EQUAL(
-            wxT("\n\naa 1.231230e+102 1.231231e+123 456 33333333 - test - 789 999 %% 0.1231\n\n"),
+            wxT("\n\naa 1.231230e+102 1.231231e+123 456 33333333 - test - 789 999 % 0.1231\n\n"),
             buffer);
     }