From 1528e0b85fed193f8a4a25f20dcc36064bb71d2a Mon Sep 17 00:00:00 2001 From: =?utf8?q?V=C3=A1clav=20Slav=C3=ADk?= Date: Fri, 4 May 2007 10:41:08 +0000 Subject: [PATCH] use wxFormatString helper class for 'vararg' functions' format argument; this prepares the code for removal of implicit wxString conversion to char* in STL build and also fixes VC6 compilation git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@45803 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- include/wx/generic/dcpsg.h | 2 +- include/wx/log.h | 4 +-- include/wx/msgout.h | 2 +- include/wx/string.h | 16 ++++----- include/wx/strvararg.h | 54 +++++++++++++++++++++++++++++ include/wx/wxcrtvararg.h | 12 +++---- src/common/string.cpp | 2 +- src/common/strvararg.cpp | 71 ++++++++++++++++++++++++++++++++++++++ 8 files changed, 144 insertions(+), 19 deletions(-) diff --git a/include/wx/generic/dcpsg.h b/include/wx/generic/dcpsg.h index d8e44192df..8a1f5dfa90 100644 --- a/include/wx/generic/dcpsg.h +++ b/include/wx/generic/dcpsg.h @@ -95,7 +95,7 @@ public: static void SetResolution(int ppi); static int GetResolution(); - WX_DEFINE_VARARG_FUNC_VOID(PsPrintf, 1, (const wxString&), + WX_DEFINE_VARARG_FUNC_VOID(PsPrintf, 1, (const wxFormatString&), DoPsPrintfFormatWchar, DoPsPrintfFormatUtf8) #ifdef __WATCOMC__ // workaround for http://bugzilla.openwatcom.org/show_bug.cgi?id=351 diff --git a/include/wx/log.h b/include/wx/log.h index f118a2fe29..8b02aff700 100644 --- a/include/wx/log.h +++ b/include/wx/log.h @@ -477,7 +477,7 @@ WXDLLIMPEXP_BASE const wxChar* wxSysErrorMsg(unsigned long nErrCode = 0); extern void WXDLLIMPEXP_BASE \ wxDoLog##level##Utf8(const char *format, ...); \ WX_DEFINE_VARARG_FUNC_VOID(wxLog##level, \ - 1, (const wxString&), \ + 1, (const wxFormatString&), \ wxDoLog##level##Wchar, wxDoLog##level##Utf8) \ DECLARE_LOG_FUNCTION_WATCOM(level) \ extern void WXDLLIMPEXP_BASE wxVLog##level(const wxString& format, \ @@ -511,7 +511,7 @@ WXDLLIMPEXP_BASE const wxChar* wxSysErrorMsg(unsigned long nErrCode = 0); extern void expdecl wxDoLog##level##Utf8(argclass arg, \ const char *format, ...); \ WX_DEFINE_VARARG_FUNC_VOID(wxLog##level, \ - 2, (argclass, const wxString&), \ + 2, (argclass, const wxFormatString&), \ wxDoLog##level##Wchar, wxDoLog##level##Utf8) \ DECLARE_LOG_FUNCTION2_EXP_WATCOM(level, argclass, arg, expdecl) \ extern void expdecl wxVLog##level(argclass arg, \ diff --git a/include/wx/msgout.h b/include/wx/msgout.h index 24b7450091..b2029e252d 100755 --- a/include/wx/msgout.h +++ b/include/wx/msgout.h @@ -37,7 +37,7 @@ public: // show a message to the user // void Printf(const wxString& format, ...) = 0; - WX_DEFINE_VARARG_FUNC_VOID(Printf, 1, (const wxString&), + WX_DEFINE_VARARG_FUNC_VOID(Printf, 1, (const wxFormatString&), DoPrintfWchar, DoPrintfUtf8) #ifdef __WATCOMC__ // workaround for http://bugzilla.openwatcom.org/show_bug.cgi?id=351 diff --git a/include/wx/string.h b/include/wx/string.h index 20e6ca1cb4..3da1f2f10d 100644 --- a/include/wx/string.h +++ b/include/wx/string.h @@ -329,7 +329,7 @@ public: // static wxString Format(const wString& format, ...) ATTRIBUTE_PRINTF_1; WX_DEFINE_VARARG_FUNC_SANS_N0(static typename StringReturnType::type, - Format, 1, (const wxString&), + Format, 1, (const wxFormatString&), DoFormatWchar, DoFormatUtf8) // We have to implement the version without template arguments manually // because of the StringReturnType<> hack, although WX_DEFINE_VARARG_FUNC @@ -339,16 +339,16 @@ public: template inline static typename StringReturnType::type - Format(const wxString& fmt, FormatDummyArg dummy = FormatDummyArg()) + Format(const wxFormatString& fmt, FormatDummyArg dummy = FormatDummyArg()) { - return DoFormat(fmt); + return DoFormatWchar(fmt); } // int Printf(const wxString& format, ...); - WX_DEFINE_VARARG_FUNC(int, Printf, 1, (const wxString&), + WX_DEFINE_VARARG_FUNC(int, Printf, 1, (const wxFormatString&), DoPrintfWchar, DoPrintfUtf8) // int sprintf(const wxString& format, ...) ATTRIBUTE_PRINTF_2; - WX_DEFINE_VARARG_FUNC(int, sprintf, 1, (const wxString&), + WX_DEFINE_VARARG_FUNC(int, sprintf, 1, (const wxFormatString&), DoPrintfWchar, DoPrintfUtf8) protected: @@ -1542,7 +1542,7 @@ public: // as sprintf(), returns the number of characters written or < 0 on error // (take 'this' into account in attribute parameter count) // int Printf(const wxString& format, ...); - WX_DEFINE_VARARG_FUNC(int, Printf, 1, (const wxString&), + WX_DEFINE_VARARG_FUNC(int, Printf, 1, (const wxFormatString&), DoPrintfWchar, DoPrintfUtf8) #ifdef __WATCOMC__ WX_DEFINE_VARARG_FUNC(int, Printf, 1, (const char*), @@ -1559,7 +1559,7 @@ public: #ifndef wxNEEDS_WXSTRING_PRINTF_MIXIN // returns the string containing the result of Printf() to it // static wxString Format(const wxString& format, ...) ATTRIBUTE_PRINTF_1; - WX_DEFINE_VARARG_FUNC(static wxString, Format, 1, (const wxString&), + WX_DEFINE_VARARG_FUNC(static wxString, Format, 1, (const wxFormatString&), DoFormatWchar, DoFormatUtf8) #ifdef __WATCOMC__ // workaround for http://bugzilla.openwatcom.org/show_bug.cgi?id=351 @@ -1606,7 +1606,7 @@ public: // use Printf() // (take 'this' into account in attribute parameter count) // int sprintf(const wxString& format, ...) ATTRIBUTE_PRINTF_2; - WX_DEFINE_VARARG_FUNC(int, sprintf, 1, (const wxString&), + WX_DEFINE_VARARG_FUNC(int, sprintf, 1, (const wxFormatString&), DoPrintfWchar, DoPrintfUtf8) #ifdef __WATCOMC__ // workaround for http://bugzilla.openwatcom.org/show_bug.cgi?id=351 diff --git a/include/wx/strvararg.h b/include/wx/strvararg.h index 9af6ace517..729b41069b 100644 --- a/include/wx/strvararg.h +++ b/include/wx/strvararg.h @@ -106,6 +106,60 @@ class WXDLLIMPEXP_BASE wxString; _WX_VARARG_DEFINE_FUNC_CTOR, \ void, name, impl, implUtf8, numfixed, fixed) + +// ---------------------------------------------------------------------------- +// wxFormatString +// ---------------------------------------------------------------------------- + +// This class should be used for format string argument of the functions +// defined using WX_DEFINE_VARARG_FUNC_* macros. It converts the string to +// char* or wchar_t* for passing to implementation function efficiently (i.e. +// without keeping the converted string in memory for longer than necessary, +// like c_str()) +// +// Note that this class can _only_ be used for function arguments! +class WXDLLIMPEXP_BASE wxFormatString +{ +public: + wxFormatString(const char *str) + : m_char(wxCharBuffer::CreateNonOwned(str)), m_str(NULL), m_cstr(NULL) {} + wxFormatString(const wchar_t *str) + : m_wchar(wxWCharBuffer::CreateNonOwned(str)), m_str(NULL), m_cstr(NULL) {} + wxFormatString(const wxString& str) + : m_str(&str), m_cstr(NULL) {} + wxFormatString(const wxCStrData& str) + : m_str(NULL), m_cstr(&str) {} + wxFormatString(const wxCharBuffer& str) + : m_char(str), m_str(NULL), m_cstr(NULL) {} + wxFormatString(const wxWCharBuffer& str) + : m_wchar(str), m_str(NULL), m_cstr(NULL) {} + +#if !wxUSE_UNICODE_WCHAR + operator const char*() const + { return wx_const_cast(wxFormatString*, this)->AsChar(); } +private: + const char* AsChar(); +#endif // !wxUSE_UNICODE_WCHAR + +#if wxUSE_UNICODE && !wxUSE_UTF8_LOCALE_ONLY + operator const wchar_t*() const + { return wx_const_cast(wxFormatString*, this)->AsWChar(); } +private: + const wchar_t* AsWChar(); +#endif // wxUSE_UNICODE && !wxUSE_UTF8_LOCALE_ONLY + +private: + wxCharBuffer m_char; + wxWCharBuffer m_wchar; + // NB: we can use a pointer here, because wxFormatString is only used + // as function argument, so it has shorter life than the string + // passed to the ctor + const wxString * const m_str; + const wxCStrData * const m_cstr; + + DECLARE_NO_COPY_CLASS(wxFormatString) +}; + // ---------------------------------------------------------------------------- // wxArgNormalizer* converters // ---------------------------------------------------------------------------- diff --git a/include/wx/wxcrtvararg.h b/include/wx/wxcrtvararg.h index c8747eba14..a93872de9d 100644 --- a/include/wx/wxcrtvararg.h +++ b/include/wx/wxcrtvararg.h @@ -259,9 +259,9 @@ // we'll also need wxArgNormalizer specializations for char, // wchar_t, wxUniChar and wxUniCharRef to handle this correctly -WX_DEFINE_VARARG_FUNC(int, wxPrintf, 1, (const wxString&), +WX_DEFINE_VARARG_FUNC(int, wxPrintf, 1, (const wxFormatString&), wxCRT_Printf, printf) -WX_DEFINE_VARARG_FUNC(int, wxFprintf, 2, (FILE*, const wxString&), +WX_DEFINE_VARARG_FUNC(int, wxFprintf, 2, (FILE*, const wxFormatString&), wxCRT_Fprintf, fprintf) // va_list versions of printf functions simply forward to the respective @@ -305,7 +305,7 @@ int WXDLLIMPEXP_BASE wxDoSprintfWchar(char *str, const wxChar *format, ...); #if wxUSE_UNICODE_UTF8 int WXDLLIMPEXP_BASE wxDoSprintfUtf8(char *str, const char *format, ...); #endif -WX_DEFINE_VARARG_FUNC(int, wxSprintf, 2, (char*, const wxString&), +WX_DEFINE_VARARG_FUNC(int, wxSprintf, 2, (char*, const wxFormatString&), wxDoSprintfWchar, wxDoSprintfUtf8) int WXDLLIMPEXP_BASE @@ -317,7 +317,7 @@ int WXDLLIMPEXP_BASE wxDoSnprintfWchar(char *str, size_t size, const wxChar *for #if wxUSE_UNICODE_UTF8 int WXDLLIMPEXP_BASE wxDoSnprintfUtf8(char *str, size_t size, const char *format, ...); #endif -WX_DEFINE_VARARG_FUNC(int, wxSnprintf, 3, (char*, size_t, const wxString&), +WX_DEFINE_VARARG_FUNC(int, wxSnprintf, 3, (char*, size_t, const wxFormatString&), wxDoSnprintfWchar, wxDoSnprintfUtf8) int WXDLLIMPEXP_BASE @@ -331,7 +331,7 @@ int WXDLLIMPEXP_BASE wxDoSprintfWchar(wchar_t *str, const wxChar *format, ...); #if wxUSE_UNICODE_UTF8 int WXDLLIMPEXP_BASE wxDoSprintfUtf8(wchar_t *str, const char *format, ...); #endif -WX_DEFINE_VARARG_FUNC(int, wxSprintf, 2, (wchar_t*, const wxString&), +WX_DEFINE_VARARG_FUNC(int, wxSprintf, 2, (wchar_t*, const wxFormatString&), wxDoSprintfWchar, wxDoSprintfUtf8) int WXDLLIMPEXP_BASE @@ -343,7 +343,7 @@ int WXDLLIMPEXP_BASE wxDoSnprintfWchar(wchar_t *str, size_t size, const wxChar * #if wxUSE_UNICODE_UTF8 int WXDLLIMPEXP_BASE wxDoSnprintfUtf8(wchar_t *str, size_t size, const char *format, ...); #endif -WX_DEFINE_VARARG_FUNC(int, wxSnprintf, 3, (wchar_t*, size_t, const wxString&), +WX_DEFINE_VARARG_FUNC(int, wxSnprintf, 3, (wchar_t*, size_t, const wxFormatString&), wxDoSnprintfWchar, wxDoSnprintfUtf8) int WXDLLIMPEXP_BASE diff --git a/src/common/string.cpp b/src/common/string.cpp index daa4901016..dac95cc926 100644 --- a/src/common/string.cpp +++ b/src/common/string.cpp @@ -1467,7 +1467,7 @@ bool wxString::ToDouble(double *val) const #if !wxUSE_UTF8_LOCALE_ONLY /* static */ #ifdef wxNEEDS_WXSTRING_PRINTF_MIXIN -wxString wxStringPrintfMixinBase::DoFormat(const wxChar *format, ...) +wxString wxStringPrintfMixinBase::DoFormatWchar(const wxChar *format, ...) #else wxString wxString::DoFormatWchar(const wxChar *format, ...) #endif diff --git a/src/common/strvararg.cpp b/src/common/strvararg.cpp index dc59f13556..0fdb2052b0 100644 --- a/src/common/strvararg.cpp +++ b/src/common/strvararg.cpp @@ -30,6 +30,9 @@ // implementation // ============================================================================ +// ---------------------------------------------------------------------------- +// wxArgNormalizer<> +// ---------------------------------------------------------------------------- const wxStringCharType *wxArgNormalizerNative::get() const { @@ -53,6 +56,10 @@ wxArgNormalizerWchar::wxArgNormalizerWchar(const wxCStrData& } #endif // wxUSE_UNICODE_UTF8 && !wxUSE_UTF8_LOCALE_ONLY +// ---------------------------------------------------------------------------- +// wxArgNormalizedString +// ---------------------------------------------------------------------------- + wxString wxArgNormalizedString::GetString() const { if ( !IsValid() ) @@ -74,3 +81,67 @@ wxArgNormalizedString::operator wxString() const { return GetString(); } + +// ---------------------------------------------------------------------------- +// wxFormatString +// ---------------------------------------------------------------------------- + +#if !wxUSE_UNICODE_WCHAR +const char* wxFormatString::AsChar() +{ + if ( m_char ) + return m_char.data(); + + // in ANSI build, wx_str() returns char*, in UTF-8 build, this function + // is only called under UTF-8 locales, so we should return UTF-8 string, + // which is, again, what wx_str() returns: + if ( m_str ) + return m_str->wx_str(); + + // ditto wxCStrData: + if ( m_cstr ) + return m_cstr->AsInternal(); + + // the last case is that wide string was passed in: in that case, we need + // to convert it: + wxASSERT( m_wchar ); + + m_char = wxConvLibc.cWC2MB(m_wchar.data()); + + return m_char.data(); +} +#endif // !wxUSE_UNICODE_WCHAR + +#if wxUSE_UNICODE && !wxUSE_UTF8_LOCALE_ONLY +const wchar_t* wxFormatString::AsWChar() +{ + if ( m_wchar ) + return m_wchar.data(); + +#if wxUSE_UNICODE_WCHAR + if ( m_str ) + return m_str->wc_str(); + if ( m_cstr ) + return m_cstr->AsInternal(); +#else // wxUSE_UNICODE_UTF8 + if ( m_str ) + { + m_wchar = m_str->wc_str(); + return m_wchar.data(); + } + if ( m_cstr ) + { + m_wchar = m_cstr->AsWCharBuf(); + return m_wchar.data(); + } +#endif // wxUSE_UNICODE_WCHAR/UTF8 + + // the last case is that narrow string was passed in: in that case, we need + // to convert it: + wxASSERT( m_char ); + + m_wchar = wxConvLibc.cMB2WC(m_char.data()); + + return m_wchar.data(); +} +#endif // wxUSE_UNICODE && !wxUSE_UTF8_LOCALE_ONLY -- 2.45.2