]> git.saurik.com Git - wxWidgets.git/blobdiff - src/common/strvararg.cpp
Allow retrieving the descent and external leading of empty strings.
[wxWidgets.git] / src / common / strvararg.cpp
index dc86bf2bb6abe29da9ed945a2c98f663fb7c57b1..656359a6b275b81c345cce20317ad46ea6c22110 100644 (file)
@@ -72,14 +72,14 @@ wxString wxArgNormalizedString::GetString() const
         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 )
-            return wxString(wx_reinterpret_cast(const char*, m_ptr));
+            return wxString(reinterpret_cast<const char*>(m_ptr));
         else
     #endif
-        return wxString(wx_reinterpret_cast(const wxChar*, m_ptr));
+        return wxString(reinterpret_cast<const wxChar*>(m_ptr));
 #endif // !wxUSE_UTF8_LOCALE_ONLY
 }
 
@@ -152,30 +152,43 @@ public:
         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 )
         {
-            if ( CopyFmtChar(*format++) == _T('%') )
+            if ( CopyFmtChar(*format++) == wxT('%') )
             {
+#if wxUSE_PRINTF_POS_PARAMS
+                if ( *format >= '0' && *format <= '9' )
+                {
+                    SkipDigits(&format);
+                    if ( *format == '$' )
+                    {
+                        // It was a positional argument specification.
+                        CopyFmtChar(*format++);
+                    }
+                    //else: it was a width specification, nothing else to do.
+                }
+#endif // wxUSE_PRINTF_POS_PARAMS
+
                 // skip any flags
                 while ( IsFlagChar(*format) )
                     CopyFmtChar(*format++);
 
                 // and possible width
-                if ( *format == _T('*') )
+                if ( *format == wxT('*') )
                     CopyFmtChar(*format++);
                 else
                     SkipDigits(&format);
 
                 // precision?
-                if ( *format == _T('.') )
+                if ( *format == wxT('.') )
                 {
                     CopyFmtChar(*format++);
-                    if ( *format == _T('*') )
+                    if ( *format == wxT('*') )
                         CopyFmtChar(*format++);
                     else
                         SkipDigits(&format);
@@ -211,16 +224,16 @@ public:
                 // 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;
 
-                    case _T('C'):
-                    case _T('c'):
+                    case wxT('C'):
+                    case wxT('c'):
                         HandleChar(*format, size, outConv, outSize);
                         break;
 
@@ -240,11 +253,11 @@ public:
                     switch ( outSize )
                     {
                         case Size_Long:
-                            InsertFmtChar(_T('l'));
+                            InsertFmtChar(wxT('l'));
                             break;
 
                         case Size_Short:
-                            InsertFmtChar(_T('h'));
+                            InsertFmtChar(wxT('h'));
                             break;
 
                         case Size_Default:
@@ -263,12 +276,14 @@ public:
         // format
         if ( m_fmtOrig )
         {
-            return wxCharTypeBuffer<CharType>::CreateNonOwned(m_fmtOrig);
+            return wxScopedCharTypeBuffer<CharType>::CreateNonOwned(m_fmtOrig);
         }
         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;
         }
     }
@@ -351,13 +366,13 @@ private:
 
     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)
     {
-        while ( **ptpc >= _T('0') && **ptpc <= _T('9') )
+        while ( **ptpc >= wxT('0') && **ptpc <= wxT('9') )
             CopyFmtChar(*(*ptpc)++);
     }
 
@@ -373,9 +388,7 @@ private:
     size_t m_nCopied;
 };
 
-
-
-#ifdef __WINDOWS
+#if defined(__WINDOWS__) && !defined(__CYGWIN__)
 
 // on Windows, we should use %s and %c regardless of the build:
 class wxPrintfFormatConverterWchar : public wxFormatConverterBase<wchar_t>
@@ -422,6 +435,8 @@ class wxPrintfFormatConverterWchar : public wxFormatConverterBase<wchar_t>
 };
 #endif // !wxUSE_UTF8_LOCALE_ONLY
 
+#endif // __WINDOWS__/!__WINDOWS__
+
 #if wxUSE_UNICODE_UTF8
 class wxPrintfFormatConverterUtf8 : public wxFormatConverterBase<char>
 {
@@ -445,8 +460,6 @@ class wxPrintfFormatConverterUtf8 : public wxFormatConverterBase<char>
 };
 #endif // wxUSE_UNICODE_UTF8
 
-#endif // __WINDOWS__/!__WINDOWS__
-
 #if !wxUSE_UNICODE // FIXME-UTF8: remove
 class wxPrintfFormatConverterANSI : public wxFormatConverterBase<char>
 {
@@ -520,7 +533,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);
 }
@@ -611,6 +624,21 @@ const wchar_t* wxFormatString::AsWChar()
 }
 #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()
 // ----------------------------------------------------------------------------
@@ -622,12 +650,15 @@ template<typename CharType>
 wxFormatString::ArgumentType DoGetArgumentType(const CharType *format,
                                                unsigned n)
 {
-    wxCHECK_MSG( format, wxFormatString::Arg_Other,
+    wxCHECK_MSG( format, wxFormatString::Arg_Unknown,
                  "empty format string not allowed here" );
 
     wxPrintfConvSpecParser<CharType> parser(format);
 
-    wxCHECK_MSG( parser.pspec[n-1] != NULL, wxFormatString::Arg_Other,
+    wxCHECK_MSG( n <= parser.nargs, wxFormatString::Arg_Unknown,
+                 "more arguments than format string specifiers?" );
+
+    wxCHECK_MSG( parser.pspec[n-1] != NULL, wxFormatString::Arg_Unknown,
                  "requested argument not found - invalid format string?" );
 
     switch ( parser.pspec[n-1]->m_type )
@@ -636,9 +667,48 @@ wxFormatString::ArgumentType DoGetArgumentType(const CharType *format,
         case wxPAT_WCHAR:
             return wxFormatString::Arg_Char;
 
-        default:
-            return wxFormatString::Arg_Other;
+        case wxPAT_PCHAR:
+        case wxPAT_PWCHAR:
+            return wxFormatString::Arg_String;
+
+        case wxPAT_INT:
+            return wxFormatString::Arg_Int;
+        case wxPAT_LONGINT:
+            return wxFormatString::Arg_LongInt;
+#ifdef wxLongLong_t
+        case wxPAT_LONGLONGINT:
+            return wxFormatString::Arg_LongLongInt;
+#endif
+        case wxPAT_SIZET:
+            return wxFormatString::Arg_Size_t;
+
+        case wxPAT_DOUBLE:
+            return wxFormatString::Arg_Double;
+        case wxPAT_LONGDOUBLE:
+            return wxFormatString::Arg_LongDouble;
+
+        case wxPAT_POINTER:
+            return wxFormatString::Arg_Pointer;
+
+        case wxPAT_NINT:
+            return wxFormatString::Arg_IntPtr;
+        case wxPAT_NSHORTINT:
+            return wxFormatString::Arg_ShortIntPtr;
+        case wxPAT_NLONGINT:
+            return wxFormatString::Arg_LongIntPtr;
+
+        case wxPAT_STAR:
+            // "*" requires argument of type int
+            return wxFormatString::Arg_Int;
+
+        case wxPAT_INVALID:
+            // (handled after the switch statement)
+            break;
     }
+
+    // silence warning
+    wxFAIL_MSG( "unexpected argument type" );
+    return wxFormatString::Arg_Unknown;
 }
 
 } // anonymous namespace
@@ -655,5 +725,5 @@ wxFormatString::ArgumentType wxFormatString::GetArgumentType(unsigned n) const
         return DoGetArgumentType(m_cstr->AsInternal(), n);
 
     wxFAIL_MSG( "unreachable code" );
-    return Arg_Other;
+    return Arg_Unknown;
 }