]> git.saurik.com Git - wxWidgets.git/commitdiff
Fix format strings parsing to understand C99 %zu etc.
authorVáclav Slavík <vslavik@fastmail.fm>
Sat, 3 Jul 2010 14:24:23 +0000 (14:24 +0000)
committerVáclav Slavík <vslavik@fastmail.fm>
Sat, 3 Jul 2010 14:24:23 +0000 (14:24 +0000)
The parser used to understand only 'Z' specifier for size_t/ptrdiff_t,
which is non-standard libc5 extension. C99 defines 'z' for this purpose,
so use that. Compatibility with 'Z' is preserved.

Also support Visual C++'s non-standard 'I' modifier with the same
meaning.

Fixes #12192.

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@64800 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

include/wx/private/wxprintf.h
tests/strings/vararg.cpp

index 35eec0de1269198d2457b77a2c04eee29f12aece..7b7b290fd647c43130211bda92e2e5ebcca3e487 100644 (file)
@@ -65,7 +65,7 @@ enum wxPrintfArgType
 #ifdef wxLongLong_t
     wxPAT_LONGLONGINT,  // %Ld, etc
 #endif
-    wxPAT_SIZET,        // %Zd, etc
+    wxPAT_SIZET,        // %zd, etc
 
     wxPAT_DOUBLE,       // %e, %E, %f, %g, %G
     wxPAT_LONGDOUBLE,   // %le, etc
@@ -93,7 +93,7 @@ union wxPrintfArg
 #ifdef wxLongLong_t
     wxLongLong_t pad_longlongint;       // %Ld, etc
 #endif
-    size_t pad_sizet;                   // %Zd, etc
+    size_t pad_sizet;                   // %zd, etc
 
     double pad_double;                  // %e, %E, %f, %g, %G
     long double pad_longdouble;         // %le, etc
@@ -161,7 +161,7 @@ public:
     //       it's task of the caller ensure that memory is still valid !
     const CharType *m_pArgEnd;
 
-    // a little buffer where formatting flags like #+\.hlqLZ are stored by Parse()
+    // a little buffer where formatting flags like #+\.hlqLz are stored by Parse()
     // for use in Process()
     char m_szFlags[wxMAX_SVNPRINTF_FLAGBUFFER_LEN];
 
@@ -294,22 +294,26 @@ bool wxPrintfConvSpec<CharType>::Parse(const CharType *format)
             // integer conversion specifier for MSVC compatibility
             // (it behaves exactly as '%lli' or '%Li' or '%qi')
             case wxT('I'):
-                if (*(m_pArgEnd+1) != wxT('6') ||
-                    *(m_pArgEnd+2) != wxT('4'))
-                    return false;       // bad format
-
-                m_pArgEnd++;
-                m_pArgEnd++;
+                if (*(m_pArgEnd+1) == wxT('6') &&
+                    *(m_pArgEnd+2) == wxT('4'))
+                {
+                    m_pArgEnd++;
+                    m_pArgEnd++;
 
-                ilen = 2;
-                CHECK_PREC
-                m_szFlags[flagofs++] = char(ch);
-                m_szFlags[flagofs++] = '6';
-                m_szFlags[flagofs++] = '4';
-                break;
+                    ilen = 2;
+                    CHECK_PREC
+                    m_szFlags[flagofs++] = char(ch);
+                    m_szFlags[flagofs++] = '6';
+                    m_szFlags[flagofs++] = '4';
+                    break;
+                }
+                // else: fall-through, 'I' is MSVC equivalent of C99 'z'
 #endif      // __WXMSW__
 
+            case wxT('z'):
             case wxT('Z'):
+                // 'z' is C99 standard for size_t and ptrdiff_t, 'Z' was used
+                // for this purpose in libc5 and by wx <= 2.8
                 ilen = 3;
                 CHECK_PREC
                 m_szFlags[flagofs++] = char(ch);
index f778fec4be0a007e0b95e46c1d27b2e6f7634ec0..c40ebf4c58059532ed33cb73abd2f75e4a1454f6 100644 (file)
@@ -219,4 +219,12 @@ void VarArgTestCase::ArgsValidation()
     // %c should accept integers too
     wxString::Format("%c", 80);
     wxString::Format("%c", wxChar(80) + wxChar(1));
+
+    // check size_t handling
+    size_t len = sizeof(*this);
+#ifdef __WXMSW__
+    wxString::Format("%Iu", len);
+#else
+    wxString::Format("%zu", len);
+#endif
 }