]> git.saurik.com Git - wxWidgets.git/blobdiff - include/wx/private/wxprintf.h
fix wxBitmapComboBox Gtk-CRITICAL assertion `GTK_IS_ENTRY (entry)' failed
[wxWidgets.git] / include / wx / private / wxprintf.h
index 67f05f6f576589fdc5874c16aed17e5a91991160..682adfbc50ff72667b28cb602971fdff80ac2c25 100644 (file)
 
 #include <string.h>
 
 
 #include <string.h>
 
-#if defined(__MWERKS__) && __MSL__ >= 0x6000
-namespace std {}
-using namespace std ;
-#endif
-
 // prefer snprintf over sprintf
 #if defined(__VISUALC__) || \
         (defined(__BORLANDC__) && __BORLANDC__ >= 0x540)
 // prefer snprintf over sprintf
 #if defined(__VISUALC__) || \
         (defined(__BORLANDC__) && __BORLANDC__ >= 0x540)
@@ -65,7 +60,7 @@ enum wxPrintfArgType
 #ifdef wxLongLong_t
     wxPAT_LONGLONGINT,  // %Ld, etc
 #endif
 #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
 
     wxPAT_DOUBLE,       // %e, %E, %f, %g, %G
     wxPAT_LONGDOUBLE,   // %le, etc
@@ -93,7 +88,7 @@ union wxPrintfArg
 #ifdef wxLongLong_t
     wxLongLong_t pad_longlongint;       // %Ld, etc
 #endif
 #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
 
     double pad_double;                  // %e, %E, %f, %g, %G
     long double pad_longdouble;         // %le, etc
@@ -161,7 +156,7 @@ public:
     //       it's task of the caller ensure that memory is still valid !
     const CharType *m_pArgEnd;
 
     //       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];
 
     // for use in Process()
     char m_szFlags[wxMAX_SVNPRINTF_FLAGBUFFER_LEN];
 
@@ -201,6 +196,7 @@ void wxPrintfConvSpec<CharType>::Init()
     m_pArgPos = m_pArgEnd = NULL;
     m_type = wxPAT_INVALID;
 
     m_pArgPos = m_pArgEnd = NULL;
     m_type = wxPAT_INVALID;
 
+    memset(m_szFlags, 0, sizeof(m_szFlags));
     // this character will never be removed from m_szFlags array and
     // is important when calling sprintf() in wxPrintfConvSpec::Process() !
     m_szFlags[0] = '%';
     // this character will never be removed from m_szFlags array and
     // is important when calling sprintf() in wxPrintfConvSpec::Process() !
     m_szFlags[0] = '%';
@@ -288,27 +284,31 @@ bool wxPrintfConvSpec<CharType>::Parse(const CharType *format)
                 CHECK_PREC
                 m_szFlags[flagofs++] = char(ch);
                 break;
                 CHECK_PREC
                 m_szFlags[flagofs++] = char(ch);
                 break;
-#ifdef __WXMSW__
+#ifdef __WINDOWS__
             // under Windows we support the special '%I64' notation as longlong
             // integer conversion specifier for MSVC compatibility
             // (it behaves exactly as '%lli' or '%Li' or '%qi')
             case wxT('I'):
             // under Windows we support the special '%I64' notation as longlong
             // 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;
-#endif      // __WXMSW__
+                    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      // __WINDOWS__
 
 
+            case wxT('z'):
             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);
                 ilen = 3;
                 CHECK_PREC
                 m_szFlags[flagofs++] = char(ch);
@@ -387,7 +387,6 @@ bool wxPrintfConvSpec<CharType>::Parse(const CharType *format)
             case wxT('X'):
                 CHECK_PREC
                 m_szFlags[flagofs++] = char(ch);
             case wxT('X'):
                 CHECK_PREC
                 m_szFlags[flagofs++] = char(ch);
-                m_szFlags[flagofs] = '\0';
                 if (ilen == 0)
                     m_type = wxPAT_INT;
                 else if (ilen == -1)
                 if (ilen == 0)
                     m_type = wxPAT_INT;
                 else if (ilen == -1)
@@ -415,7 +414,6 @@ bool wxPrintfConvSpec<CharType>::Parse(const CharType *format)
             case wxT('G'):
                 CHECK_PREC
                 m_szFlags[flagofs++] = char(ch);
             case wxT('G'):
                 CHECK_PREC
                 m_szFlags[flagofs++] = char(ch);
-                m_szFlags[flagofs] = '\0';
                 if (ilen == 2)
                     m_type = wxPAT_LONGDOUBLE;
                 else
                 if (ilen == 2)
                     m_type = wxPAT_LONGDOUBLE;
                 else
@@ -426,7 +424,6 @@ bool wxPrintfConvSpec<CharType>::Parse(const CharType *format)
             case wxT('p'):
                 m_type = wxPAT_POINTER;
                 m_szFlags[flagofs++] = char(ch);
             case wxT('p'):
                 m_type = wxPAT_POINTER;
                 m_szFlags[flagofs++] = char(ch);
-                m_szFlags[flagofs] = '\0';
                 done = true;
                 break;
 
                 done = true;
                 break;
 
@@ -698,11 +695,16 @@ int wxPrintfConvSpec<CharType>::Process(CharType *buf, size_t lenMax, wxPrintfAr
         case wxPAT_PCHAR:
         case wxPAT_PWCHAR:
             {
         case wxPAT_PCHAR:
         case wxPAT_PWCHAR:
             {
-                wxArgNormalizedString arg(p->pad_str);
-                wxString s = arg;
-
-                if ( !arg.IsValid() && m_nMaxWidth >= 6 )
-                    s = wxT("(null)");
+                wxString s;
+                if ( !p->pad_str )
+                {
+                    if ( m_nMaxWidth >= 6 )
+                        s = wxT("(null)");
+                }
+                else if (m_type == wxPAT_PCHAR)
+                    s.assign(static_cast<const char *>(p->pad_str));
+                else // m_type == wxPAT_PWCHAR
+                    s.assign(static_cast<const wchar_t *>(p->pad_str));
 
                 typename wxPrintfStringHelper<CharType>::ConvertedType strbuf(
                         wxPrintfStringHelper<CharType>::Convert(s));
 
                 typename wxPrintfStringHelper<CharType>::ConvertedType strbuf(
                         wxPrintfStringHelper<CharType>::Convert(s));
@@ -829,43 +831,49 @@ struct wxPrintfConvSpecParser
             // special handling for specifications including asterisks: we need
             // to reserve an extra slot (or two if asterisks were used for both
             // width and precision) in specs array in this case
             // special handling for specifications including asterisks: we need
             // to reserve an extra slot (or two if asterisks were used for both
             // width and precision) in specs array in this case
-            for ( const char *f = strchr(spec->m_szFlags, '*');
-                  f;
-                  f = strchr(f + 1, '*') )
+            if ( const char *f = strchr(spec->m_szFlags, '*') )
             {
             {
-                if ( nargs++ == wxMAX_SVNPRINTF_ARGUMENTS )
-                    break;
+                unsigned numAsterisks = 1;
+                if ( strchr(++f, '*') )
+                    numAsterisks++;
 
 
-                // TODO: we need to support specifiers of the form "%2$*1$s"
-                // (this is the same as "%*s") as if any positional arguments
-                // are used all asterisks must be positional as well but this
-                // requires a lot of changes in this code (basically we'd need
-                // to rewrite Parse() to return "*" and conversion itself as
-                // separate entries)
-                if ( posarg_present )
+                for ( unsigned n = 0; n < numAsterisks; n++ )
                 {
                 {
-                    wxFAIL_MSG
-                    (
-                        wxString::Format
+                    if ( nargs++ == wxMAX_SVNPRINTF_ARGUMENTS )
+                        break;
+
+                    // TODO: we need to support specifiers of the form "%2$*1$s"
+                    // (this is the same as "%*s") as if any positional arguments
+                    // are used all asterisks must be positional as well but this
+                    // requires a lot of changes in this code (basically we'd need
+                    // to rewrite Parse() to return "*" and conversion itself as
+                    // separate entries)
+                    if ( posarg_present )
+                    {
+                        wxFAIL_MSG
                         (
                         (
-                            "Format string \"%s\" uses both positional "
-                            "parameters and '*' but this is not currently "
-                            "supported by this implementation, sorry.",
-                            fmt
-                        )
-                    );
-                }
+                            wxString::Format
+                            (
+                                "Format string \"%s\" uses both positional "
+                                "parameters and '*' but this is not currently "
+                                "supported by this implementation, sorry.",
+                                fmt
+                            )
+                        );
+                    }
 
 
-                specs[nargs] = *spec;
+                    specs[nargs] = *spec;
 
 
-                // make an entry for '*' and point to it from pspec
-                spec->Init();
-                spec->m_type = wxPAT_STAR;
-                pspec[nargs - 1] = spec;
+                    // make an entry for '*' and point to it from pspec
+                    spec->Init();
+                    spec->m_type = wxPAT_STAR;
+                    pspec[nargs - 1] = spec;
 
 
-                spec = &specs[nargs];
+                    spec = &specs[nargs];
+                }
             }
 
             }
 
+
             // check if this is a positional or normal argument
             if ( spec->m_pos > 0 )
             {
             // check if this is a positional or normal argument
             if ( spec->m_pos > 0 )
             {