X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/de4983f3236c2043479abb21857aca958a7b61f0..bf2c43c76e2819be443ab1d830ab68d9569d66b1:/src/common/strvararg.cpp diff --git a/src/common/strvararg.cpp b/src/common/strvararg.cpp index 32775972bd..9112bbf8f9 100644 --- a/src/common/strvararg.cpp +++ b/src/common/strvararg.cpp @@ -3,7 +3,6 @@ // Purpose: macros for implementing type-safe vararg passing of strings // Author: Vaclav Slavik // Created: 2007-02-19 -// RCS-ID: $Id$ // Copyright: (c) 2007 REA Elektronik GmbH // Licence: wxWindows licence /////////////////////////////////////////////////////////////////////////////// @@ -152,30 +151,43 @@ public: m_nCopied = 0; } - wxCharTypeBuffer Convert(const CharType *format) + wxScopedCharTypeBuffer 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 +223,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, 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 +252,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 +275,14 @@ public: // format if ( m_fmtOrig ) { - return wxCharTypeBuffer::CreateNonOwned(m_fmtOrig); + return wxScopedCharTypeBuffer::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 +365,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 +387,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 @@ -422,6 +434,8 @@ class wxPrintfFormatConverterWchar : public wxFormatConverterBase }; #endif // !wxUSE_UTF8_LOCALE_ONLY +#endif // __WINDOWS__/!__WINDOWS__ + #if wxUSE_UNICODE_UTF8 class wxPrintfFormatConverterUtf8 : public wxFormatConverterBase { @@ -445,8 +459,6 @@ class wxPrintfFormatConverterUtf8 : public wxFormatConverterBase }; #endif // wxUSE_UNICODE_UTF8 -#endif // __WINDOWS__/!__WINDOWS__ - #if !wxUSE_UNICODE // FIXME-UTF8: remove class wxPrintfFormatConverterANSI : public wxFormatConverterBase { @@ -637,12 +649,15 @@ template 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 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 ) @@ -651,9 +666,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 @@ -670,5 +724,5 @@ wxFormatString::ArgumentType wxFormatString::GetArgumentType(unsigned n) const return DoGetArgumentType(m_cstr->AsInternal(), n); wxFAIL_MSG( "unreachable code" ); - return Arg_Other; + return Arg_Unknown; }