]> git.saurik.com Git - wxWidgets.git/blobdiff - src/common/strvararg.cpp
Correct cell alignment computation for too small column sizes.
[wxWidgets.git] / src / common / strvararg.cpp
index 4559748fb4ff8d875c94c1878b064f441c1f6a82..09b8ca0b98001033a5b798ff3da7f41e04aa2417 100644 (file)
@@ -26,6 +26,7 @@
 #include "wx/strvararg.h"
 #include "wx/string.h"
 #include "wx/crt.h"
 #include "wx/strvararg.h"
 #include "wx/string.h"
 #include "wx/crt.h"
+#include "wx/private/wxprintf.h"
 
 // ============================================================================
 // implementation
 
 // ============================================================================
 // implementation
@@ -46,13 +47,17 @@ const wxStringCharType *wxArgNormalizerNative<const wxCStrData&>::get() const
 }
 
 #if wxUSE_UNICODE_UTF8 && !wxUSE_UTF8_LOCALE_ONLY
 }
 
 #if wxUSE_UNICODE_UTF8 && !wxUSE_UTF8_LOCALE_ONLY
-wxArgNormalizerWchar<const wxString&>::wxArgNormalizerWchar(const wxString& s)
-    : wxArgNormalizerWithBuffer<wchar_t>(s.wc_str())
+wxArgNormalizerWchar<const wxString&>::wxArgNormalizerWchar(
+                            const wxString& s,
+                            const wxFormatString *fmt, unsigned index)
+    : wxArgNormalizerWithBuffer<wchar_t>(s.wc_str(), fmt, index)
 {
 }
 
 {
 }
 
-wxArgNormalizerWchar<const wxCStrData&>::wxArgNormalizerWchar(const wxCStrData& s)
-    : wxArgNormalizerWithBuffer<wchar_t>(s.AsWCharBuf())
+wxArgNormalizerWchar<const wxCStrData&>::wxArgNormalizerWchar(
+                            const wxCStrData& s,
+                            const wxFormatString *fmt, unsigned index)
+    : wxArgNormalizerWithBuffer<wchar_t>(s.AsWCharBuf(), fmt, index)
 {
 }
 #endif // wxUSE_UNICODE_UTF8 && !wxUSE_UTF8_LOCALE_ONLY
 {
 }
 #endif // wxUSE_UNICODE_UTF8 && !wxUSE_UTF8_LOCALE_ONLY
@@ -67,14 +72,14 @@ wxString wxArgNormalizedString::GetString() const
         return wxEmptyString;
 
 #if wxUSE_UTF8_LOCALE_ONLY
         return wxEmptyString;
 
 #if wxUSE_UTF8_LOCALE_ONLY
-    return wxString(wx_reinterpret_cast(const char*, m_ptr));
+    return wxString(reinterpret_cast<const char*>(m_ptr));
 #else
     #if wxUSE_UNICODE_UTF8
         if ( wxLocaleIsUtf8 )
 #else
     #if wxUSE_UNICODE_UTF8
         if ( wxLocaleIsUtf8 )
-            return wxString(wx_reinterpret_cast(const char*, m_ptr));
+            return wxString(reinterpret_cast<const char*>(m_ptr));
         else
     #endif
         else
     #endif
-        return wxString(wx_reinterpret_cast(const wxChar*, m_ptr));
+        return wxString(reinterpret_cast<const wxChar*>(m_ptr));
 #endif // !wxUSE_UTF8_LOCALE_ONLY
 }
 
 #endif // !wxUSE_UTF8_LOCALE_ONLY
 }
 
@@ -128,10 +133,6 @@ wxArgNormalizedString::operator wxString() const
 
    And, of course, the same should be done for %c as well.
 
 
    And, of course, the same should be done for %c as well.
 
-   4) Finally, in UTF-8 build when calling ANSI printf() function, we need to
-      translate %c to %s, because not every Unicode character can be
-      represented by a char.
-
 
    wxScanf() family of functions is simpler, because we don't normalize their
    variadic arguments and we only have to handle 2) above and only for widechar
 
    wxScanf() family of functions is simpler, because we don't normalize their
    variadic arguments and we only have to handle 2) above and only for widechar
@@ -151,30 +152,30 @@ public:
         m_nCopied = 0;
     }
 
         m_nCopied = 0;
     }
 
-    wxCharTypeBuffer<CharType> Convert(const CharType *format)
+    wxScopedCharTypeBuffer<CharType> Convert(const CharType *format)
     {
         // this is reset to NULL if we modify the format string
         m_fmtOrig = format;
 
         while ( *format )
         {
     {
         // this is reset to NULL if we modify the format string
         m_fmtOrig = format;
 
         while ( *format )
         {
-            if ( CopyFmtChar(*format++) == _T('%') )
+            if ( CopyFmtChar(*format++) == wxT('%') )
             {
                 // skip any flags
                 while ( IsFlagChar(*format) )
                     CopyFmtChar(*format++);
 
                 // and possible width
             {
                 // skip any flags
                 while ( IsFlagChar(*format) )
                     CopyFmtChar(*format++);
 
                 // and possible width
-                if ( *format == _T('*') )
+                if ( *format == wxT('*') )
                     CopyFmtChar(*format++);
                 else
                     SkipDigits(&format);
 
                 // precision?
                     CopyFmtChar(*format++);
                 else
                     SkipDigits(&format);
 
                 // precision?
-                if ( *format == _T('.') )
+                if ( *format == wxT('.') )
                 {
                     CopyFmtChar(*format++);
                 {
                     CopyFmtChar(*format++);
-                    if ( *format == _T('*') )
+                    if ( *format == wxT('*') )
                         CopyFmtChar(*format++);
                     else
                         SkipDigits(&format);
                         CopyFmtChar(*format++);
                     else
                         SkipDigits(&format);
@@ -210,16 +211,16 @@ public:
                 // and finally we should have the type
                 switch ( *format )
                 {
                 // and finally we should have the type
                 switch ( *format )
                 {
-                    case _T('S'):
-                    case _T('s'):
+                    case wxT('S'):
+                    case wxT('s'):
                         // all strings were converted into the same form by
                         // wxArgNormalizer<T>, this form depends on the context
                         // in which the value is used (scanf/printf/wprintf):
                         HandleString(*format, size, outConv, outSize);
                         break;
 
                         // all strings were converted into the same form by
                         // wxArgNormalizer<T>, this form depends on the context
                         // in which the value is used (scanf/printf/wprintf):
                         HandleString(*format, size, outConv, outSize);
                         break;
 
-                    case _T('C'):
-                    case _T('c'):
+                    case wxT('C'):
+                    case wxT('c'):
                         HandleChar(*format, size, outConv, outSize);
                         break;
 
                         HandleChar(*format, size, outConv, outSize);
                         break;
 
@@ -239,11 +240,11 @@ public:
                     switch ( outSize )
                     {
                         case Size_Long:
                     switch ( outSize )
                     {
                         case Size_Long:
-                            InsertFmtChar(_T('l'));
+                            InsertFmtChar(wxT('l'));
                             break;
 
                         case Size_Short:
                             break;
 
                         case Size_Short:
-                            InsertFmtChar(_T('h'));
+                            InsertFmtChar(wxT('h'));
                             break;
 
                         case Size_Default:
                             break;
 
                         case Size_Default:
@@ -262,12 +263,14 @@ public:
         // format
         if ( m_fmtOrig )
         {
         // format
         if ( m_fmtOrig )
         {
-            return wxCharTypeBuffer<CharType>::CreateNonOwned(m_fmtOrig);
+            return wxScopedCharTypeBuffer<CharType>::CreateNonOwned(m_fmtOrig);
         }
         else
         {
         }
         else
         {
-            // NULL-terminate converted format string:
-            *m_fmtLast = 0;
+            // shrink converted format string to actual size (instead of
+            // over-sized allocation from CopyAllBefore()) and NUL-terminate
+            // it:
+            m_fmt.shrink(m_fmtLast - m_fmt.data());
             return m_fmt;
         }
     }
             return m_fmt;
         }
     }
@@ -350,13 +353,13 @@ private:
 
     static bool IsFlagChar(CharType ch)
     {
 
     static bool IsFlagChar(CharType ch)
     {
-        return ch == _T('-') || ch == _T('+') ||
-               ch == _T('0') || ch == _T(' ') || ch == _T('#');
+        return ch == wxT('-') || ch == wxT('+') ||
+               ch == wxT('0') || ch == wxT(' ') || ch == wxT('#');
     }
 
     void SkipDigits(const CharType **ptpc)
     {
     }
 
     void SkipDigits(const CharType **ptpc)
     {
-        while ( **ptpc >= _T('0') && **ptpc <= _T('9') )
+        while ( **ptpc >= wxT('0') && **ptpc <= wxT('9') )
             CopyFmtChar(*(*ptpc)++);
     }
 
             CopyFmtChar(*(*ptpc)++);
     }
 
@@ -372,9 +375,7 @@ private:
     size_t m_nCopied;
 };
 
     size_t m_nCopied;
 };
 
-
-
-#ifdef __WINDOWS
+#ifdef __WINDOWS__
 
 // on Windows, we should use %s and %c regardless of the build:
 class wxPrintfFormatConverterWchar : public wxFormatConverterBase<wchar_t>
 
 // on Windows, we should use %s and %c regardless of the build:
 class wxPrintfFormatConverterWchar : public wxFormatConverterBase<wchar_t>
@@ -436,9 +437,10 @@ class wxPrintfFormatConverterUtf8 : public wxFormatConverterBase<char>
                             SizeModifier WXUNUSED(size),
                             CharType& outConv, SizeModifier& outSize)
     {
                             SizeModifier WXUNUSED(size),
                             CharType& outConv, SizeModifier& outSize)
     {
-        // added complication: %c should be translated to %s in UTF-8 build
-        outConv = 's';
-        outSize = Size_Default;
+        // chars are represented using wchar_t in both builds, so this is
+        // the same as above
+        outConv = 'c';
+        outSize = Size_Long;
     }
 };
 #endif // wxUSE_UNICODE_UTF8
     }
 };
 #endif // wxUSE_UNICODE_UTF8
@@ -518,7 +520,7 @@ class wxScanfFormatConverterWchar : public wxFormatConverterBase<wchar_t>
     }
 };
 
     }
 };
 
-const wxWCharBuffer wxScanfConvertFormatW(const wchar_t *format)
+const wxScopedWCharBuffer wxScanfConvertFormatW(const wchar_t *format)
 {
     return wxScanfFormatConverterWchar().Convert(format);
 }
 {
     return wxScanfFormatConverterWchar().Convert(format);
 }
@@ -608,3 +610,65 @@ const wchar_t* wxFormatString::AsWChar()
     return m_convertedWChar.data();
 }
 #endif // wxUSE_UNICODE && !wxUSE_UTF8_LOCALE_ONLY
     return m_convertedWChar.data();
 }
 #endif // wxUSE_UNICODE && !wxUSE_UTF8_LOCALE_ONLY
+
+wxString wxFormatString::InputAsString() const
+{
+    if ( m_str )
+        return *m_str;
+    if ( m_cstr )
+        return m_cstr->AsString();
+    if ( m_wchar )
+        return wxString(m_wchar);
+    if ( m_char )
+        return wxString(m_char);
+
+    wxFAIL_MSG( "invalid wxFormatString - not initialized?" );
+    return wxString();
+}
+
+// ----------------------------------------------------------------------------
+// wxFormatString::GetArgumentType()
+// ----------------------------------------------------------------------------
+
+namespace
+{
+
+template<typename CharType>
+wxFormatString::ArgumentType DoGetArgumentType(const CharType *format,
+                                               unsigned n)
+{
+    wxCHECK_MSG( format, wxFormatString::Arg_Other,
+                 "empty format string not allowed here" );
+
+    wxPrintfConvSpecParser<CharType> parser(format);
+
+    wxCHECK_MSG( parser.pspec[n-1] != NULL, wxFormatString::Arg_Other,
+                 "requested argument not found - invalid format string?" );
+
+    switch ( parser.pspec[n-1]->m_type )
+    {
+        case wxPAT_CHAR:
+        case wxPAT_WCHAR:
+            return wxFormatString::Arg_Char;
+
+        default:
+            return wxFormatString::Arg_Other;
+    }
+}
+
+} // anonymous namespace
+
+wxFormatString::ArgumentType wxFormatString::GetArgumentType(unsigned n) const
+{
+    if ( m_char )
+        return DoGetArgumentType(m_char.data(), n);
+    else if ( m_wchar )
+        return DoGetArgumentType(m_wchar.data(), n);
+    else if ( m_str )
+        return DoGetArgumentType(m_str->wx_str(), n);
+    else if ( m_cstr )
+        return DoGetArgumentType(m_cstr->AsInternal(), n);
+
+    wxFAIL_MSG( "unreachable code" );
+    return Arg_Other;
+}