X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/f6e3890101f661d543fa0eea7882cc64a4f8b02e..6cab4fcac7fe26d9ae5a1d29066e0893d689bb38:/src/common/strvararg.cpp?ds=sidebyside diff --git a/src/common/strvararg.cpp b/src/common/strvararg.cpp index 4559748fb4..a10cdc26dd 100644 --- a/src/common/strvararg.cpp +++ b/src/common/strvararg.cpp @@ -26,6 +26,7 @@ #include "wx/strvararg.h" #include "wx/string.h" #include "wx/crt.h" +#include "wx/private/wxprintf.h" // ============================================================================ // implementation @@ -46,13 +47,17 @@ const wxStringCharType *wxArgNormalizerNative::get() const } #if wxUSE_UNICODE_UTF8 && !wxUSE_UTF8_LOCALE_ONLY -wxArgNormalizerWchar::wxArgNormalizerWchar(const wxString& s) - : wxArgNormalizerWithBuffer(s.wc_str()) +wxArgNormalizerWchar::wxArgNormalizerWchar( + const wxString& s, + const wxFormatString *fmt, unsigned index) + : wxArgNormalizerWithBuffer(s.wc_str(), fmt, index) { } -wxArgNormalizerWchar::wxArgNormalizerWchar(const wxCStrData& s) - : wxArgNormalizerWithBuffer(s.AsWCharBuf()) +wxArgNormalizerWchar::wxArgNormalizerWchar( + const wxCStrData& s, + const wxFormatString *fmt, unsigned index) + : wxArgNormalizerWithBuffer(s.AsWCharBuf(), fmt, index) { } #endif // wxUSE_UNICODE_UTF8 && !wxUSE_UTF8_LOCALE_ONLY @@ -67,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(m_ptr)); #else #if wxUSE_UNICODE_UTF8 if ( wxLocaleIsUtf8 ) - return wxString(wx_reinterpret_cast(const char*, m_ptr)); + return wxString(reinterpret_cast(m_ptr)); else #endif - return wxString(wx_reinterpret_cast(const wxChar*, m_ptr)); + return wxString(reinterpret_cast(m_ptr)); #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. - 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 @@ -436,9 +437,10 @@ class wxPrintfFormatConverterUtf8 : public wxFormatConverterBase 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 @@ -608,3 +610,65 @@ const wchar_t* wxFormatString::AsWChar() 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 +wxFormatString::ArgumentType DoGetArgumentType(const CharType *format, + unsigned n) +{ + wxCHECK_MSG( format, wxFormatString::Arg_Other, + "empty format string not allowed here" ); + + wxPrintfConvSpecParser 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; +}