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
This commit is contained in:
Václav Slavík
2007-05-04 10:41:08 +00:00
parent cef590ee27
commit 1528e0b85f
8 changed files with 144 additions and 19 deletions

View File

@@ -95,7 +95,7 @@ public:
static void SetResolution(int ppi); static void SetResolution(int ppi);
static int GetResolution(); static int GetResolution();
WX_DEFINE_VARARG_FUNC_VOID(PsPrintf, 1, (const wxString&), WX_DEFINE_VARARG_FUNC_VOID(PsPrintf, 1, (const wxFormatString&),
DoPsPrintfFormatWchar, DoPsPrintfFormatUtf8) DoPsPrintfFormatWchar, DoPsPrintfFormatUtf8)
#ifdef __WATCOMC__ #ifdef __WATCOMC__
// workaround for http://bugzilla.openwatcom.org/show_bug.cgi?id=351 // workaround for http://bugzilla.openwatcom.org/show_bug.cgi?id=351

View File

@@ -477,7 +477,7 @@ WXDLLIMPEXP_BASE const wxChar* wxSysErrorMsg(unsigned long nErrCode = 0);
extern void WXDLLIMPEXP_BASE \ extern void WXDLLIMPEXP_BASE \
wxDoLog##level##Utf8(const char *format, ...); \ wxDoLog##level##Utf8(const char *format, ...); \
WX_DEFINE_VARARG_FUNC_VOID(wxLog##level, \ WX_DEFINE_VARARG_FUNC_VOID(wxLog##level, \
1, (const wxString&), \ 1, (const wxFormatString&), \
wxDoLog##level##Wchar, wxDoLog##level##Utf8) \ wxDoLog##level##Wchar, wxDoLog##level##Utf8) \
DECLARE_LOG_FUNCTION_WATCOM(level) \ DECLARE_LOG_FUNCTION_WATCOM(level) \
extern void WXDLLIMPEXP_BASE wxVLog##level(const wxString& format, \ 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, \ extern void expdecl wxDoLog##level##Utf8(argclass arg, \
const char *format, ...); \ const char *format, ...); \
WX_DEFINE_VARARG_FUNC_VOID(wxLog##level, \ WX_DEFINE_VARARG_FUNC_VOID(wxLog##level, \
2, (argclass, const wxString&), \ 2, (argclass, const wxFormatString&), \
wxDoLog##level##Wchar, wxDoLog##level##Utf8) \ wxDoLog##level##Wchar, wxDoLog##level##Utf8) \
DECLARE_LOG_FUNCTION2_EXP_WATCOM(level, argclass, arg, expdecl) \ DECLARE_LOG_FUNCTION2_EXP_WATCOM(level, argclass, arg, expdecl) \
extern void expdecl wxVLog##level(argclass arg, \ extern void expdecl wxVLog##level(argclass arg, \

View File

@@ -37,7 +37,7 @@ public:
// show a message to the user // show a message to the user
// void Printf(const wxString& format, ...) = 0; // 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) DoPrintfWchar, DoPrintfUtf8)
#ifdef __WATCOMC__ #ifdef __WATCOMC__
// workaround for http://bugzilla.openwatcom.org/show_bug.cgi?id=351 // workaround for http://bugzilla.openwatcom.org/show_bug.cgi?id=351

View File

@@ -329,7 +329,7 @@ public:
// static wxString Format(const wString& format, ...) ATTRIBUTE_PRINTF_1; // static wxString Format(const wString& format, ...) ATTRIBUTE_PRINTF_1;
WX_DEFINE_VARARG_FUNC_SANS_N0(static typename StringReturnType<T1>::type, WX_DEFINE_VARARG_FUNC_SANS_N0(static typename StringReturnType<T1>::type,
Format, 1, (const wxString&), Format, 1, (const wxFormatString&),
DoFormatWchar, DoFormatUtf8) DoFormatWchar, DoFormatUtf8)
// We have to implement the version without template arguments manually // We have to implement the version without template arguments manually
// because of the StringReturnType<> hack, although WX_DEFINE_VARARG_FUNC // because of the StringReturnType<> hack, although WX_DEFINE_VARARG_FUNC
@@ -339,16 +339,16 @@ public:
template<typename T> template<typename T>
inline static typename StringReturnType<T>::type inline static typename StringReturnType<T>::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, ...); // 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) DoPrintfWchar, DoPrintfUtf8)
// int sprintf(const wxString& format, ...) ATTRIBUTE_PRINTF_2; // 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) DoPrintfWchar, DoPrintfUtf8)
protected: protected:
@@ -1542,7 +1542,7 @@ public:
// as sprintf(), returns the number of characters written or < 0 on error // as sprintf(), returns the number of characters written or < 0 on error
// (take 'this' into account in attribute parameter count) // (take 'this' into account in attribute parameter count)
// int Printf(const wxString& format, ...); // 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) DoPrintfWchar, DoPrintfUtf8)
#ifdef __WATCOMC__ #ifdef __WATCOMC__
WX_DEFINE_VARARG_FUNC(int, Printf, 1, (const char*), WX_DEFINE_VARARG_FUNC(int, Printf, 1, (const char*),
@@ -1559,7 +1559,7 @@ public:
#ifndef wxNEEDS_WXSTRING_PRINTF_MIXIN #ifndef wxNEEDS_WXSTRING_PRINTF_MIXIN
// returns the string containing the result of Printf() to it // returns the string containing the result of Printf() to it
// static wxString Format(const wxString& format, ...) ATTRIBUTE_PRINTF_1; // 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) DoFormatWchar, DoFormatUtf8)
#ifdef __WATCOMC__ #ifdef __WATCOMC__
// workaround for http://bugzilla.openwatcom.org/show_bug.cgi?id=351 // workaround for http://bugzilla.openwatcom.org/show_bug.cgi?id=351
@@ -1606,7 +1606,7 @@ public:
// use Printf() // use Printf()
// (take 'this' into account in attribute parameter count) // (take 'this' into account in attribute parameter count)
// int sprintf(const wxString& format, ...) ATTRIBUTE_PRINTF_2; // 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) DoPrintfWchar, DoPrintfUtf8)
#ifdef __WATCOMC__ #ifdef __WATCOMC__
// workaround for http://bugzilla.openwatcom.org/show_bug.cgi?id=351 // workaround for http://bugzilla.openwatcom.org/show_bug.cgi?id=351

View File

@@ -106,6 +106,60 @@ class WXDLLIMPEXP_BASE wxString;
_WX_VARARG_DEFINE_FUNC_CTOR, \ _WX_VARARG_DEFINE_FUNC_CTOR, \
void, name, impl, implUtf8, numfixed, fixed) 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*<T> converters // wxArgNormalizer*<T> converters
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------

View File

@@ -259,9 +259,9 @@
// we'll also need wxArgNormalizer<T> specializations for char, // we'll also need wxArgNormalizer<T> specializations for char,
// wchar_t, wxUniChar and wxUniCharRef to handle this correctly // 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) 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) wxCRT_Fprintf, fprintf)
// va_list versions of printf functions simply forward to the respective // 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 #if wxUSE_UNICODE_UTF8
int WXDLLIMPEXP_BASE wxDoSprintfUtf8(char *str, const char *format, ...); int WXDLLIMPEXP_BASE wxDoSprintfUtf8(char *str, const char *format, ...);
#endif #endif
WX_DEFINE_VARARG_FUNC(int, wxSprintf, 2, (char*, const wxString&), WX_DEFINE_VARARG_FUNC(int, wxSprintf, 2, (char*, const wxFormatString&),
wxDoSprintfWchar, wxDoSprintfUtf8) wxDoSprintfWchar, wxDoSprintfUtf8)
int WXDLLIMPEXP_BASE int WXDLLIMPEXP_BASE
@@ -317,7 +317,7 @@ int WXDLLIMPEXP_BASE wxDoSnprintfWchar(char *str, size_t size, const wxChar *for
#if wxUSE_UNICODE_UTF8 #if wxUSE_UNICODE_UTF8
int WXDLLIMPEXP_BASE wxDoSnprintfUtf8(char *str, size_t size, const char *format, ...); int WXDLLIMPEXP_BASE wxDoSnprintfUtf8(char *str, size_t size, const char *format, ...);
#endif #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) wxDoSnprintfWchar, wxDoSnprintfUtf8)
int WXDLLIMPEXP_BASE int WXDLLIMPEXP_BASE
@@ -331,7 +331,7 @@ int WXDLLIMPEXP_BASE wxDoSprintfWchar(wchar_t *str, const wxChar *format, ...);
#if wxUSE_UNICODE_UTF8 #if wxUSE_UNICODE_UTF8
int WXDLLIMPEXP_BASE wxDoSprintfUtf8(wchar_t *str, const char *format, ...); int WXDLLIMPEXP_BASE wxDoSprintfUtf8(wchar_t *str, const char *format, ...);
#endif #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) wxDoSprintfWchar, wxDoSprintfUtf8)
int WXDLLIMPEXP_BASE int WXDLLIMPEXP_BASE
@@ -343,7 +343,7 @@ int WXDLLIMPEXP_BASE wxDoSnprintfWchar(wchar_t *str, size_t size, const wxChar *
#if wxUSE_UNICODE_UTF8 #if wxUSE_UNICODE_UTF8
int WXDLLIMPEXP_BASE wxDoSnprintfUtf8(wchar_t *str, size_t size, const char *format, ...); int WXDLLIMPEXP_BASE wxDoSnprintfUtf8(wchar_t *str, size_t size, const char *format, ...);
#endif #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) wxDoSnprintfWchar, wxDoSnprintfUtf8)
int WXDLLIMPEXP_BASE int WXDLLIMPEXP_BASE

View File

@@ -1467,7 +1467,7 @@ bool wxString::ToDouble(double *val) const
#if !wxUSE_UTF8_LOCALE_ONLY #if !wxUSE_UTF8_LOCALE_ONLY
/* static */ /* static */
#ifdef wxNEEDS_WXSTRING_PRINTF_MIXIN #ifdef wxNEEDS_WXSTRING_PRINTF_MIXIN
wxString wxStringPrintfMixinBase::DoFormat(const wxChar *format, ...) wxString wxStringPrintfMixinBase::DoFormatWchar(const wxChar *format, ...)
#else #else
wxString wxString::DoFormatWchar(const wxChar *format, ...) wxString wxString::DoFormatWchar(const wxChar *format, ...)
#endif #endif

View File

@@ -30,6 +30,9 @@
// implementation // implementation
// ============================================================================ // ============================================================================
// ----------------------------------------------------------------------------
// wxArgNormalizer<>
// ----------------------------------------------------------------------------
const wxStringCharType *wxArgNormalizerNative<const wxString&>::get() const const wxStringCharType *wxArgNormalizerNative<const wxString&>::get() const
{ {
@@ -53,6 +56,10 @@ wxArgNormalizerWchar<const wxCStrData&>::wxArgNormalizerWchar(const wxCStrData&
} }
#endif // wxUSE_UNICODE_UTF8 && !wxUSE_UTF8_LOCALE_ONLY #endif // wxUSE_UNICODE_UTF8 && !wxUSE_UTF8_LOCALE_ONLY
// ----------------------------------------------------------------------------
// wxArgNormalizedString
// ----------------------------------------------------------------------------
wxString wxArgNormalizedString::GetString() const wxString wxArgNormalizedString::GetString() const
{ {
if ( !IsValid() ) if ( !IsValid() )
@@ -74,3 +81,67 @@ wxArgNormalizedString::operator wxString() const
{ {
return GetString(); 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