use UTF8-encoded char* strings in UTF8 build instead of wchar_t* if the current locale uses UTF8;

fall back to widechar CRT functions in the locale is not UTF8


git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@45663 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Václav Slavík
2007-04-26 11:40:04 +00:00
parent 210bb741b9
commit 2523e9b700
23 changed files with 1368 additions and 656 deletions

View File

@@ -86,12 +86,18 @@ public:
static void SetResolution(int ppi); static void SetResolution(int ppi);
static int GetResolution(); static int GetResolution();
WX_DEFINE_VARARG_FUNC_VOID(PsPrintf, DoPsPrintfFormat) WX_DEFINE_VARARG_FUNC_VOID(PsPrintf, 1, (const wxString&), DoPsPrintfFormat)
#ifdef __WATCOMC__
// workaround for http://bugzilla.openwatcom.org/show_bug.cgi?id=351
WX_DEFINE_VARARG_FUNC_VOID(PsPrintf, 1, (const char*), DoPsPrintfFormat)
WX_DEFINE_VARARG_FUNC_VOID(PsPrintf, 1, (const wchar_t*), DoPsPrintfFormat)
#endif
void PsPrint( const wxString& psdata ); void PsPrint( const wxString& psdata );
void PsPrint( int ch ); void PsPrint( int ch );
private: private:
void DoPsPrintfFormat(const wxChar *fmt, ... ); void DoPsPrintfFormat(const wxString& fmt, ... );
static float ms_PSScaleFactor; static float ms_PSScaleFactor;

View File

@@ -471,39 +471,93 @@ WXDLLIMPEXP_BASE const wxChar* wxSysErrorMsg(unsigned long nErrCode = 0);
// define wxLog<level> // define wxLog<level>
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
#define DECLARE_LOG_FUNCTION_PUBLIC(level) \ #ifdef __WATCOMC__
/* void wxLog##level(const wxChar *szFormat, ...); */ \ // workaround for http://bugzilla.openwatcom.org/show_bug.cgi?id=351
WX_DEFINE_VARARG_FUNC_VOID(wxLog##level, wxDoLog##level) #define WX_WATCOM_ONLY_CODE( x ) x
#else
#define WX_WATCOM_ONLY_CODE( x )
#endif
#define DECLARE_LOG_FUNCTION_IMPL(level) \ #define DECLARE_LOG_FUNCTION(level) \
extern void WXDLLIMPEXP_BASE wxVLog##level(const wxString& format, \
va_list argptr); \
extern void WXDLLIMPEXP_BASE \ extern void WXDLLIMPEXP_BASE \
wxDoLog##level(const wxChar *szFormat, ...) ATTRIBUTE_PRINTF_1 wxDoLog##level(const wxString& format, ...); \
WX_DEFINE_VARARG_FUNC_VOID(wxLog##level, \
1, (const wxString&), wxDoLog##level) \
DECLARE_LOG_FUNCTION_WATCOM(level) \
extern void WXDLLIMPEXP_BASE wxVLog##level(const wxString& format, \
va_list argptr)
#define DECLARE_LOG_FUNCTION2_EXP_IMPL(level, argclass, arg, expdecl) \ #ifdef __WATCOMC__
// workaround for http://bugzilla.openwatcom.org/show_bug.cgi?id=351;
// can't use WX_WATCOM_ONLY_CODE here because the macro would expand to
// something too big for Borland C++ to handle
#define DECLARE_LOG_FUNCTION_WATCOM(level) \
WX_DEFINE_VARARG_FUNC_VOID(wxLog##level, \
1, (const char*), wxDoLog##level) \
WX_DEFINE_VARARG_FUNC_VOID(wxLog##level, \
1, (const wchar_t*), wxDoLog##level) \
WX_DEFINE_VARARG_FUNC_VOID(wxLog##level, \
1, (const wxCStrData&), wxDoLog##level)
#else
#define DECLARE_LOG_FUNCTION_WATCOM(level)
#endif
#define DECLARE_LOG_FUNCTION2_EXP(level, argclass, arg, expdecl) \
extern void expdecl wxDoLog##level(argclass arg, \
const wxString& format, ...); \
WX_DEFINE_VARARG_FUNC_VOID(wxLog##level, \
2, (argclass, const wxString&), \
wxDoLog##level) \
DECLARE_LOG_FUNCTION2_EXP_WATCOM(level, argclass, arg, expdecl) \
extern void expdecl wxVLog##level(argclass arg, \ extern void expdecl wxVLog##level(argclass arg, \
const wxString& format, \ const wxString& format, \
va_list argptr); \ va_list argptr)
extern void expdecl wxDoLog##level(argclass arg, \
const wxChar *szFormat, \ #ifdef __WATCOMC__
...) ATTRIBUTE_PRINTF_2 // workaround for http://bugzilla.openwatcom.org/show_bug.cgi?id=351;
// can't use WX_WATCOM_ONLY_CODE here because the macro would expand to
// something too big for Borland C++ to handle
#define DECLARE_LOG_FUNCTION2_EXP_WATCOM(level, argclass, arg, expdecl) \
WX_DEFINE_VARARG_FUNC_VOID(wxLog##level, \
2, (argclass, const char*), \
wxDoLog##level) \
WX_DEFINE_VARARG_FUNC_VOID(wxLog##level, \
2, (argclass, const wchar_t*), \
wxDoLog##level) \
WX_DEFINE_VARARG_FUNC_VOID(wxLog##level, \
2, (argclass, const wxCStrData&), \
wxDoLog##level)
#else
#define DECLARE_LOG_FUNCTION2_EXP_WATCOM(level, argclass, arg, expdecl)
#endif
#else // !wxUSE_LOG #else // !wxUSE_LOG
// log functions do nothing at all // log functions do nothing at all
#define DECLARE_LOG_FUNCTION_PUBLIC(level) \ #define DECLARE_LOG_FUNCTION(level) \
/* void wxLog##level(const wxChar *szFormat, ...) {} */ \ WX_DEFINE_VARARG_FUNC_NOP(wxLog##level, 1, (const wxString&)) \
WX_DEFINE_VARARG_FUNC_NOP(wxLog##level) WX_WATCOM_ONLY_CODE( \
WX_DEFINE_VARARG_FUNC_NOP(wxLog##level, 1, (const char*)) \
#define DECLARE_LOG_FUNCTION_IMPL(level) \ WX_DEFINE_VARARG_FUNC_NOP(wxLog##level, 1, (const wchar_t*)) \
WX_DEFINE_VARARG_FUNC_NOP(wxLog##level, 1, (const wxCStrData&)) \
) \
inline void wxVLog##level(const wxString& WXUNUSED(format), \ inline void wxVLog##level(const wxString& WXUNUSED(format), \
va_list WXUNUSED(argptr)) { } \ va_list WXUNUSED(argptr)) { } \
#define DECLARE_LOG_FUNCTION2_EXP_IMPL(level, argclass, arg, expdecl) \ #define DECLARE_LOG_FUNCTION2_EXP(level, argclass, arg, expdecl) \
WX_DEFINE_VARARG_FUNC_NOP(wxLog##level, 2, (argclass, const wxString&)) \
WX_WATCOM_ONLY_CODE( \
WX_DEFINE_VARARG_FUNC_NOP(wxLog##level, 2, (argclass, const char*)) \
WX_DEFINE_VARARG_FUNC_NOP(wxLog##level, 2, (argclass, const wchar_t*)) \
WX_DEFINE_VARARG_FUNC_NOP(wxLog##level, 2, (argclass, const wxCStrData&)) \
) \
inline void wxVLog##level(argclass WXUNUSED(arg), \ inline void wxVLog##level(argclass WXUNUSED(arg), \
const wxString& WXUNUSED(format), \ const wxString& WXUNUSED(format), \
va_list WXUNUSED(argptr)) {} va_list WXUNUSED(argptr)) {}
#undef WX_WATCOM_ONLY_CODE
// Empty Class to fake wxLogNull // Empty Class to fake wxLogNull
class WXDLLIMPEXP_BASE wxLogNull class WXDLLIMPEXP_BASE wxLogNull
@@ -521,28 +575,13 @@ public:
#endif // wxUSE_LOG/!wxUSE_LOG #endif // wxUSE_LOG/!wxUSE_LOG
#define DECLARE_LOG_FUNCTION(level) \
DECLARE_LOG_FUNCTION_PUBLIC(level) \
DECLARE_LOG_FUNCTION_IMPL(level)
#define DECLARE_LOG_FUNCTION2_EXP(level, argclass, arg, expdecl) \
DECLARE_LOG_FUNCTION_PUBLIC(level) \
DECLARE_LOG_FUNCTION2_EXP_IMPL(level, argclass, arg, expdecl)
#define DECLARE_LOG_FUNCTION2_EXP(level, argclass, arg, expdecl) \
DECLARE_LOG_FUNCTION_PUBLIC(level) \
DECLARE_LOG_FUNCTION2_EXP_IMPL(level, argclass, arg, expdecl)
#define DECLARE_LOG_FUNCTION2_IMPL(level, argclass, arg) \
DECLARE_LOG_FUNCTION2_EXP_IMPL(level, argclass, arg, WXDLLIMPEXP_BASE)
#define DECLARE_LOG_FUNCTION2(level, argclass, arg) \ #define DECLARE_LOG_FUNCTION2(level, argclass, arg) \
DECLARE_LOG_FUNCTION2_EXP(level, argclass, arg, WXDLLIMPEXP_BASE) DECLARE_LOG_FUNCTION2_EXP(level, argclass, arg, WXDLLIMPEXP_BASE)
// VC6 produces a warning if we a macro expanding to nothing to // VC6 produces a warning if we a macro expanding to nothing to
// DECLARE_LOG_FUNCTION2_IMPL: // DECLARE_LOG_FUNCTION2:
#if defined(__VISUALC__) && __VISUALC__ < 1300 #if defined(__VISUALC__) && __VISUALC__ < 1300
// "not enough actual parameters for macro 'DECLARE_LOG_FUNCTION2_EXP_IMPL'" // "not enough actual parameters for macro 'DECLARE_LOG_FUNCTION2_EXP'"
#pragma warning(disable:4003) #pragma warning(disable:4003)
#endif #endif
@@ -559,26 +598,26 @@ DECLARE_LOG_FUNCTION(Verbose);
// this function sends the log message to the status line of the top level // this function sends the log message to the status line of the top level
// application frame, if any // application frame, if any
DECLARE_LOG_FUNCTION_IMPL(Status); DECLARE_LOG_FUNCTION(Status);
#if wxUSE_GUI #if wxUSE_GUI
// this one is the same as previous except that it allows to explicitly // this one is the same as previous except that it allows to explicitly
class WXDLLEXPORT wxFrame; class WXDLLEXPORT wxFrame;
// specify the frame to which the output should go // specify the frame to which the output should go
DECLARE_LOG_FUNCTION2_EXP_IMPL(Status, wxFrame *, pFrame, WXDLLIMPEXP_CORE); DECLARE_LOG_FUNCTION2_EXP(Status, wxFrame *, pFrame, WXDLLIMPEXP_CORE);
#endif // wxUSE_GUI #endif // wxUSE_GUI
DECLARE_LOG_FUNCTION_PUBLIC(Status)
// additional one: as wxLogError, but also logs last system call error code // additional one: as wxLogError, but also logs last system call error code
// and the corresponding error message if available // and the corresponding error message if available
DECLARE_LOG_FUNCTION_IMPL(SysError); DECLARE_LOG_FUNCTION(SysError);
// and another one which also takes the error code (for those broken APIs // and another one which also takes the error code (for those broken APIs
// that don't set the errno (like registry APIs in Win32)) // that don't set the errno (like registry APIs in Win32))
DECLARE_LOG_FUNCTION2_IMPL(SysError, long, lErrCode); DECLARE_LOG_FUNCTION2(SysError, long, lErrCode);
#ifdef __WATCOMC__
DECLARE_LOG_FUNCTION_PUBLIC(SysError) // workaround for http://bugzilla.openwatcom.org/show_bug.cgi?id=351
DECLARE_LOG_FUNCTION2(SysError, unsigned long, lErrCode);
#endif
// debug functions do nothing in release mode // debug functions do nothing in release mode
#if wxUSE_LOG && wxUSE_LOG_DEBUG #if wxUSE_LOG && wxUSE_LOG_DEBUG
@@ -590,12 +629,21 @@ DECLARE_LOG_FUNCTION_PUBLIC(SysError)
// this version only logs the message if the mask had been added to the // this version only logs the message if the mask had been added to the
// list of masks with AddTraceMask() // list of masks with AddTraceMask()
DECLARE_LOG_FUNCTION2_IMPL(Trace, const wxString&, mask); DECLARE_LOG_FUNCTION2(Trace, const wxString&, mask);
#ifdef __WATCOMC__
// workaround for http://bugzilla.openwatcom.org/show_bug.cgi?id=351
DECLARE_LOG_FUNCTION2(Trace, const char*, mask);
DECLARE_LOG_FUNCTION2(Trace, const wchar_t*, mask);
#endif
// and this one does nothing if all of level bits are not set in // and this one does nothing if all of level bits are not set in
// wxLog::GetActive()->GetTraceMask() -- it's deprecated in favour of // wxLog::GetActive()->GetTraceMask() -- it's deprecated in favour of
// string identifiers // string identifiers
DECLARE_LOG_FUNCTION2_IMPL(Trace, wxTraceMask, mask); DECLARE_LOG_FUNCTION2(Trace, wxTraceMask, mask);
DECLARE_LOG_FUNCTION_PUBLIC(Trace) #ifdef __WATCOMC__
// workaround for http://bugzilla.openwatcom.org/show_bug.cgi?id=351
DECLARE_LOG_FUNCTION2(Trace, int, mask);
#endif
#else //!debug || !wxUSE_LOG #else //!debug || !wxUSE_LOG
// these functions do nothing in release builds, but don't define them as // these functions do nothing in release builds, but don't define them as
// nothing as it could result in different code structure in debug and // nothing as it could result in different code structure in debug and

View File

@@ -116,16 +116,44 @@ private:
class WXDLLIMPEXP_BASE wxFileTypeInfo class WXDLLIMPEXP_BASE wxFileTypeInfo
{ {
private:
void VarArgInit(const wxString& mimeType,
const wxString& openCmd,
const wxString& printCmd,
const wxString& desc,
// the other parameters form a NULL terminated list of
// extensions
...);
public: public:
// ctors // ctors
// a normal item // a normal item
wxFileTypeInfo(const wxChar *mimeType,
const wxChar *openCmd, // wxFileTypeInfo(const wxString& mimeType,
const wxChar *printCmd, // const wxString& openCmd,
const wxChar *desc, // const wxString& printCmd,
// the other parameters form a NULL terminated list of // const wxString& desc,
// extensions // // the other parameters form a NULL terminated list of
...); // // extensions
// ...);
WX_DEFINE_VARARG_FUNC_CTOR(wxFileTypeInfo,
4, (const wxString&, const wxString&,
const wxString&, const wxString&),
VarArgInit)
#ifdef __WATCOMC__
// workaround for http://bugzilla.openwatcom.org/show_bug.cgi?id=351
WX_DEFINE_VARARG_FUNC_CTOR(wxFileTypeInfo,
4, (const char*, const char*,
const char*, const char*),
VarArgInit)
WX_DEFINE_VARARG_FUNC_CTOR(wxFileTypeInfo,
4, (const wchar_t*, const wchar_t*,
const wchar_t*, const wchar_t*),
VarArgInit)
WX_DEFINE_VARARG_FUNC_CTOR(wxFileTypeInfo,
4, (const wxCStrData&, const wxCStrData&,
const wxCStrData&, const wxCStrData&),
VarArgInit)
#endif
// the array elements correspond to the parameters of the ctor above in // the array elements correspond to the parameters of the ctor above in
// the same order // the same order

View File

@@ -36,13 +36,19 @@ public:
virtual ~wxMessageOutputBase() { } virtual ~wxMessageOutputBase() { }
// show a message to the user // show a message to the user
// void Printf(const wxChar* format, ...) ATTRIBUTE_PRINTF_2 = 0; // void Printf(const wxString& format, ...) = 0;
WX_DEFINE_VARARG_FUNC_VOID(Printf, DoPrintf) WX_DEFINE_VARARG_FUNC_VOID(Printf, 1, (const wxString&), DoPrintf)
#ifdef __WATCOMC__
// workaround for http://bugzilla.openwatcom.org/show_bug.cgi?id=351
WX_DEFINE_VARARG_FUNC_VOID(Printf, 1, (const char*), DoPrintf)
WX_DEFINE_VARARG_FUNC_VOID(Printf, 1, (const wchar_t*), DoPrintf)
WX_DEFINE_VARARG_FUNC_VOID(Printf, 1, (const wxCStrData&), DoPrintf)
#endif
protected: protected:
// NB: this is pure virtual so that it can be implemented in dllexported // NB: this is pure virtual so that it can be implemented in dllexported
// wxMessagOutput class // wxMessagOutput class
virtual void DoPrintf(const wxChar* format, ...) ATTRIBUTE_PRINTF_2 = 0; virtual void DoPrintf(const wxString& format, ...) = 0;
// called by DoPrintf() to output formatted string // called by DoPrintf() to output formatted string
virtual void Output(const wxString& str) = 0; virtual void Output(const wxString& str) = 0;
@@ -67,7 +73,7 @@ public:
static wxMessageOutput* Set(wxMessageOutput* msgout); static wxMessageOutput* Set(wxMessageOutput* msgout);
protected: protected:
virtual void DoPrintf(const wxChar* format, ...) ATTRIBUTE_PRINTF_2; virtual void DoPrintf(const wxString& format, ...);
virtual void Output(const wxString& str) = 0; virtual void Output(const wxString& str) = 0;
private: private:

View File

@@ -51,7 +51,7 @@
#include <StringMgr.h> #include <StringMgr.h>
#endif #endif
#include "wx/wxchar.h" // for wxChar, wxStrlen() etc. #include "wx/wxcrt.h" // for wxChar, wxStrlen() etc.
#include "wx/strvararg.h" #include "wx/strvararg.h"
#include "wx/buffer.h" // for wxCharBuffer #include "wx/buffer.h" // for wxCharBuffer
#include "wx/strconv.h" // for wxConvertXXX() macros and wxMBConv classes #include "wx/strconv.h" // for wxConvertXXX() macros and wxMBConv classes
@@ -216,6 +216,10 @@ public:
inline wxString AsString() const; inline wxString AsString() const;
// returns the value as C string in internal representation (equivalent
// to AsString().wx_str(), but more efficient)
const wxStringCharType *AsInternal() const;
// allow expressions like "c_str()[0]": // allow expressions like "c_str()[0]":
inline wxUniChar operator[](size_t n) const; inline wxUniChar operator[](size_t n) const;
wxUniChar operator[](int n) const { return operator[](size_t(n)); } wxUniChar operator[](int n) const { return operator[](size_t(n)); }
@@ -292,8 +296,8 @@ class WXDLLIMPEXP_BASE wxStringPrintfMixinBase
protected: protected:
wxStringPrintfMixinBase() {} wxStringPrintfMixinBase() {}
int DoPrintf(const wxChar *format, ...) ATTRIBUTE_PRINTF_2; int DoPrintf(const wxString& format, ...);
static wxString DoFormat(const wxChar *format, ...) ATTRIBUTE_PRINTF_1; static wxString DoFormat(const wxString& format, ...);
}; };
// this class contains template wrappers for wxString's vararg methods, it's // this class contains template wrappers for wxString's vararg methods, it's
@@ -316,13 +320,27 @@ public:
// these are duplicated wxString methods, they're also declared below // these are duplicated wxString methods, they're also declared below
// if !wxNEEDS_WXSTRING_PRINTF_MIXIN: // if !wxNEEDS_WXSTRING_PRINTF_MIXIN:
// int Printf(const wxChar *pszFormat, ...); // static wxString Format(const wString& format, ...) ATTRIBUTE_PRINTF_1;
WX_DEFINE_VARARG_FUNC(int, Printf, DoPrintf) WX_DEFINE_VARARG_FUNC2_SANS_N0(static typename StringReturnType<T1>::type,
// static wxString Format(const wxChar *pszFormat, ...) ATTRIBUTE_PRINTF_1; Format, 1, (const wxString&),
WX_DEFINE_VARARG_FUNC(static typename StringReturnType<T1>::type, DoFormat, DoFormat)
Format, DoFormat) // We have to implement the version without template arguments manually
// int sprintf(const wxChar *pszFormat, ...) ATTRIBUTE_PRINTF_2; // because of the StringReturnType<> hack, although WX_DEFINE_VARARG_FUNC
WX_DEFINE_VARARG_FUNC(int, sprintf, DoPrintf) // normally does it itself. It has to be a template so that we can use
// the hack, even though there's no real template parameter:
struct FormatDummyArg {} ;
template<typename T>
inline static typename StringReturnType<T>::type
Format(const wxString& fmt, FormatDummyArg dummy = FormatDummyArg())
{
return DoFormat(fmt);
}
// int Printf(const wxString& format, ...);
WX_DEFINE_VARARG_FUNC(int, Printf, 1, (const wxString&), DoPrintf)
// int sprintf(const wxString& format, ...) ATTRIBUTE_PRINTF_2;
WX_DEFINE_VARARG_FUNC(int, sprintf, 1, (const wxString&), DoPrintf)
protected: protected:
wxStringPrintfMixin() : wxStringPrintfMixinBase() {} wxStringPrintfMixin() : wxStringPrintfMixinBase() {}
@@ -879,7 +897,6 @@ public:
// libstdc++ on some Linux versions which is bad, so instead we ask the // libstdc++ on some Linux versions which is bad, so instead we ask the
// client code to define this wxUSE_STD_STRING symbol if they need it // client code to define this wxUSE_STD_STRING symbol if they need it
#if wxUSE_STD_STRING #if wxUSE_STD_STRING
#if wxUSE_UNICODE_WCHAR #if wxUSE_UNICODE_WCHAR
wxString(const wxStdWideString& str) : m_impl(str) {} wxString(const wxStdWideString& str) : m_impl(str) {}
#else // UTF-8 or ANSI #else // UTF-8 or ANSI
@@ -1484,16 +1501,27 @@ public:
// formatted input/output // formatted input/output
// 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 wxChar *pszFormat, ...); // int Printf(const wxString& format, ...);
WX_DEFINE_VARARG_FUNC(int, Printf, DoPrintf) WX_DEFINE_VARARG_FUNC(int, Printf, 1, (const wxString&), DoPrintf)
#ifdef __WATCOMC__
WX_DEFINE_VARARG_FUNC(int, Printf, 1, (const char*), DoPrintf)
WX_DEFINE_VARARG_FUNC(int, Printf, 1, (const wchar_t*), DoPrintf)
WX_DEFINE_VARARG_FUNC(int, Printf, 1, (const wxCStrData&), DoPrintf)
#endif
#endif // !wxNEEDS_WXSTRING_PRINTF_MIXIN #endif // !wxNEEDS_WXSTRING_PRINTF_MIXIN
// as vprintf(), returns the number of characters written or < 0 on error // as vprintf(), returns the number of characters written or < 0 on error
int PrintfV(const wxString& format, va_list argptr); int PrintfV(const wxString& format, va_list argptr);
#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 wxChar *pszFormat, ...) ATTRIBUTE_PRINTF_1; // static wxString Format(const wxString& format, ...) ATTRIBUTE_PRINTF_1;
WX_DEFINE_VARARG_FUNC(static wxString, Format, DoFormat) WX_DEFINE_VARARG_FUNC(static wxString, Format, 1, (const wxString&), DoFormat)
#ifdef __WATCOMC__
// workaround for http://bugzilla.openwatcom.org/show_bug.cgi?id=351
WX_DEFINE_VARARG_FUNC(static wxString, Format, 1, (const char*), DoFormat)
WX_DEFINE_VARARG_FUNC(static wxString, Format, 1, (const wchar_t*), DoFormat)
WX_DEFINE_VARARG_FUNC(static wxString, Format, 1, (const wxCStrData&), DoFormat)
#endif
#endif #endif
// the same as above, but takes a va_list // the same as above, but takes a va_list
static wxString FormatV(const wxString& format, va_list argptr); static wxString FormatV(const wxString& format, va_list argptr);
@@ -1529,8 +1557,14 @@ public:
#ifndef wxNEEDS_WXSTRING_PRINTF_MIXIN #ifndef wxNEEDS_WXSTRING_PRINTF_MIXIN
// use Printf() // use Printf()
// (take 'this' into account in attribute parameter count) // (take 'this' into account in attribute parameter count)
// int sprintf(const wxChar *pszFormat, ...) ATTRIBUTE_PRINTF_2; // int sprintf(const wxString& format, ...) ATTRIBUTE_PRINTF_2;
WX_DEFINE_VARARG_FUNC(int, sprintf, DoPrintf) WX_DEFINE_VARARG_FUNC(int, sprintf, 1, (const wxString&), DoPrintf)
#ifdef __WATCOMC__
// workaround for http://bugzilla.openwatcom.org/show_bug.cgi?id=351
WX_DEFINE_VARARG_FUNC(int, sprintf, 1, (const char*), DoPrintf)
WX_DEFINE_VARARG_FUNC(int, sprintf, 1, (const wchar_t*), DoPrintf)
WX_DEFINE_VARARG_FUNC(int, sprintf, 1, (const wxCStrData&), DoPrintf)
#endif
#endif // wxNEEDS_WXSTRING_PRINTF_MIXIN #endif // wxNEEDS_WXSTRING_PRINTF_MIXIN
// use Cmp() // use Cmp()
@@ -2200,7 +2234,7 @@ public:
wxString& operator+=(wchar_t ch) { return *this += wxUniChar(ch); } wxString& operator+=(wchar_t ch) { return *this += wxUniChar(ch); }
private: private:
#if !wxUSE_STL_BASED_WXSTRING && !wxUSE_UNICODE_UTF8 #if !wxUSE_STL_BASED_WXSTRING
// helpers for wxStringBuffer and wxStringBufferLength // helpers for wxStringBuffer and wxStringBufferLength
wxStringCharType *DoGetWriteBuf(size_t nLen) wxStringCharType *DoGetWriteBuf(size_t nLen)
{ return m_impl.DoGetWriteBuf(nLen); } { return m_impl.DoGetWriteBuf(nLen); }
@@ -2208,14 +2242,11 @@ private:
{ m_impl.DoUngetWriteBuf(); } { m_impl.DoUngetWriteBuf(); }
void DoUngetWriteBuf(size_t nLen) void DoUngetWriteBuf(size_t nLen)
{ m_impl.DoUngetWriteBuf(nLen); } { m_impl.DoUngetWriteBuf(nLen); }
#endif // !wxUSE_STL_BASED_WXSTRING
friend class WXDLLIMPEXP_BASE wxStringBuffer;
friend class WXDLLIMPEXP_BASE wxStringBufferLength;
#endif // !wxUSE_STL_BASED_WXSTRING && !wxUSE_UNICODE_UTF8
#ifndef wxNEEDS_WXSTRING_PRINTF_MIXIN #ifndef wxNEEDS_WXSTRING_PRINTF_MIXIN
int DoPrintf(const wxChar *format, ...) ATTRIBUTE_PRINTF_2; int DoPrintf(const wxString& format, ...);
static wxString DoFormat(const wxChar *format, ...) ATTRIBUTE_PRINTF_1; static wxString DoFormat(const wxString& format, ...);
#endif #endif
#if !wxUSE_STL_BASED_WXSTRING #if !wxUSE_STL_BASED_WXSTRING
@@ -2253,7 +2284,10 @@ private:
#if !wxUSE_UNICODE_WCHAR #if !wxUSE_UNICODE_WCHAR
ConvertedBuffer<wchar_t> m_convertedToWChar; ConvertedBuffer<wchar_t> m_convertedToWChar;
#endif #endif
friend class WXDLLIMPEXP_BASE wxCStrData; friend class WXDLLIMPEXP_BASE wxCStrData;
friend class wxImplStringBuffer;
friend class wxImplStringBufferLength;
}; };
#ifdef wxNEEDS_WXSTRING_PRINTF_MIXIN #ifdef wxNEEDS_WXSTRING_PRINTF_MIXIN
@@ -2321,107 +2355,170 @@ inline wxString operator+(wchar_t ch, const wxString& string)
// wxStringBuffer: a tiny class allowing to get a writable pointer into string // wxStringBuffer: a tiny class allowing to get a writable pointer into string
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
#if wxUSE_STL_BASED_WXSTRING || wxUSE_UNICODE_UTF8 #if !wxUSE_STL_BASED_WXSTRING
// string buffer for direct access to string data in their native
class WXDLLIMPEXP_BASE wxStringBuffer // representation:
class wxImplStringBuffer
{ {
public: public:
wxStringBuffer(wxString& str, size_t lenWanted = 1024) typedef wxStringCharType CharType;
: m_str(str), m_buf(lenWanted)
{ }
~wxStringBuffer() { m_str.assign(m_buf.data(), wxStrlen(m_buf.data())); } wxImplStringBuffer(wxString& str, size_t lenWanted = 1024)
operator wxChar*() { return m_buf.data(); }
private:
wxString& m_str;
#if wxUSE_UNICODE
wxWCharBuffer m_buf;
#else
wxCharBuffer m_buf;
#endif
DECLARE_NO_COPY_CLASS(wxStringBuffer)
};
class WXDLLIMPEXP_BASE wxStringBufferLength
{
public:
wxStringBufferLength(wxString& str, size_t lenWanted = 1024)
: m_str(str), m_buf(lenWanted), m_len(0), m_lenSet(false)
{ }
~wxStringBufferLength()
{
wxASSERT(m_lenSet);
m_str.assign(m_buf.data(), m_len);
}
operator wxChar*() { return m_buf.data(); }
void SetLength(size_t length) { m_len = length; m_lenSet = true; }
private:
wxString& m_str;
#if wxUSE_UNICODE
wxWCharBuffer m_buf;
#else
wxCharBuffer m_buf;
#endif
size_t m_len;
bool m_lenSet;
DECLARE_NO_COPY_CLASS(wxStringBufferLength)
};
#else // if !wxUSE_STL_BASED_WXSTRING && !wxUSE_UNICODE_UTF8
class WXDLLIMPEXP_BASE wxStringBuffer
{
public:
wxStringBuffer(wxString& str, size_t lenWanted = 1024)
: m_str(str), m_buf(NULL) : m_str(str), m_buf(NULL)
{ m_buf = m_str.DoGetWriteBuf(lenWanted); } { m_buf = m_str.DoGetWriteBuf(lenWanted); }
~wxStringBuffer() { m_str.DoUngetWriteBuf(); } ~wxImplStringBuffer() { m_str.DoUngetWriteBuf(); }
operator wxChar*() const { return m_buf; } operator wxStringCharType*() const { return m_buf; }
private: private:
wxString& m_str; wxString& m_str;
wxChar *m_buf; wxStringCharType *m_buf;
DECLARE_NO_COPY_CLASS(wxStringBuffer) DECLARE_NO_COPY_CLASS(wxImplStringBuffer)
}; };
class WXDLLIMPEXP_BASE wxStringBufferLength class wxImplStringBufferLength
{ {
public: public:
wxStringBufferLength(wxString& str, size_t lenWanted = 1024) typedef wxStringCharType CharType;
wxImplStringBufferLength(wxString& str, size_t lenWanted = 1024)
: m_str(str), m_buf(NULL), m_len(0), m_lenSet(false) : m_str(str), m_buf(NULL), m_len(0), m_lenSet(false)
{ {
m_buf = m_str.DoGetWriteBuf(lenWanted); m_buf = m_str.DoGetWriteBuf(lenWanted);
wxASSERT(m_buf != NULL); wxASSERT(m_buf != NULL);
} }
~wxStringBufferLength() ~wxImplStringBufferLength()
{ {
wxASSERT(m_lenSet); wxASSERT(m_lenSet);
m_str.DoUngetWriteBuf(m_len); m_str.DoUngetWriteBuf(m_len);
} }
operator wxChar*() const { return m_buf; } operator wxStringCharType*() const { return m_buf; }
void SetLength(size_t length) { m_len = length; m_lenSet = true; } void SetLength(size_t length) { m_len = length; m_lenSet = true; }
private: private:
wxString& m_str; wxString& m_str;
wxChar *m_buf; wxStringCharType *m_buf;
size_t m_len; size_t m_len;
bool m_lenSet; bool m_lenSet;
DECLARE_NO_COPY_CLASS(wxStringBufferLength) DECLARE_NO_COPY_CLASS(wxImplStringBufferLength)
}; };
#endif // !wxUSE_STL_BASED_WXSTRING
template<typename T>
class wxStringTypeBufferBase
{
public:
typedef T CharType;
wxStringTypeBufferBase(wxString& str, size_t lenWanted = 1024)
: m_str(str), m_buf(lenWanted)
{ }
operator CharType*() { return m_buf.data(); }
protected:
wxString& m_str;
wxCharTypeBuffer<CharType> m_buf;
};
template<typename T>
class wxStringTypeBufferLengthBase
{
public:
typedef T CharType;
wxStringTypeBufferLengthBase(wxString& str, size_t lenWanted = 1024)
: m_str(str), m_buf(lenWanted), m_len(0), m_lenSet(false)
{ }
~wxStringTypeBufferLengthBase()
{
wxASSERT(m_lenSet);
m_str.assign(m_buf.data(), m_len);
}
operator CharType*() { return m_buf.data(); }
void SetLength(size_t length) { m_len = length; m_lenSet = true; }
protected:
wxString& m_str;
wxCharTypeBuffer<CharType> m_buf;
size_t m_len;
bool m_lenSet;
};
template<typename T>
class wxStringTypeBuffer : public wxStringTypeBufferBase<T>
{
public:
wxStringTypeBuffer(wxString& str, size_t lenWanted = 1024)
: wxStringTypeBufferBase<T>(str, lenWanted) {}
~wxStringTypeBuffer()
{
this->m_str.assign(this->m_buf.data());
}
DECLARE_NO_COPY_CLASS(wxStringTypeBuffer)
};
template<typename T>
class wxStringTypeBufferLength : public wxStringTypeBufferLengthBase<T>
{
public:
wxStringTypeBufferLength(wxString& str, size_t lenWanted = 1024)
: wxStringTypeBufferLengthBase<T>(str, lenWanted) {}
~wxStringTypeBufferLength()
{
wxASSERT(this->m_lenSet);
this->m_str.assign(this->m_buf.data(), this->m_len);
}
DECLARE_NO_COPY_CLASS(wxStringTypeBufferLength)
};
#if wxUSE_STL_BASED_WXSTRING
class wxImplStringBuffer : public wxStringTypeBufferBase<wxStringCharType>
{
public:
wxImplStringBuffer(wxString& str, size_t lenWanted = 1024)
: wxStringTypeBufferBase<wxStringCharType>(str, lenWanted) {}
~wxImplStringBuffer()
{ m_str.m_impl.assign(m_buf.data()); }
DECLARE_NO_COPY_CLASS(wxImplStringBuffer)
};
class wxImplStringBufferLength : public wxStringTypeBufferLengthBase<wxStringCharType>
{
public:
wxImplStringBufferLength(wxString& str, size_t lenWanted = 1024)
: wxStringTypeBufferLengthBase<wxStringCharType>(str, lenWanted) {}
~wxImplStringBufferLength()
{
wxASSERT(m_lenSet);
m_str.m_impl.assign(m_buf.data(), m_len);
}
DECLARE_NO_COPY_CLASS(wxImplStringBufferLength)
};
#endif // wxUSE_STL_BASED_WXSTRING
#if wxUSE_STL_BASED_WXSTRING || wxUSE_UNICODE_UTF8
typedef wxStringTypeBuffer<wxChar> wxStringBuffer;
typedef wxStringTypeBufferLength<wxChar> wxStringBufferLength;
#else // if !wxUSE_STL_BASED_WXSTRING && !wxUSE_UNICODE_UTF8
typedef wxImplStringBuffer wxStringBuffer;
typedef wxImplStringBufferLength wxStringBufferLength;
#endif // !wxUSE_STL_BASED_WXSTRING && !wxUSE_UNICODE_UTF8 #endif // !wxUSE_STL_BASED_WXSTRING && !wxUSE_UNICODE_UTF8
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
@@ -2600,6 +2697,11 @@ inline wxString wxCStrData::AsString() const
return m_str->Mid(m_offset); return m_str->Mid(m_offset);
} }
inline const wxStringCharType *wxCStrData::AsInternal() const
{
return wxStringOperations::AddToIter(m_str->wx_str(), m_offset);
}
inline wxUniChar wxCStrData::operator*() const inline wxUniChar wxCStrData::operator*() const
{ {
if ( m_str->empty() ) if ( m_str->empty() )

View File

@@ -23,7 +23,8 @@
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
#include "wx/defs.h" // everybody should include this #include "wx/defs.h" // everybody should include this
#include "wx/wxchar.h" // for wxChar, wxStrlen() etc. #include "wx/chartype.h" // for wxChar
#include "wx/wxcrt.h" // for wxStrlen() etc.
#include <stdlib.h> #include <stdlib.h>
@@ -540,12 +541,10 @@ public:
// string += char // string += char
wxStringImpl& operator+=(wxStringCharType ch) { return append(1, ch); } wxStringImpl& operator+=(wxStringCharType ch) { return append(1, ch); }
#if !wxUSE_UNICODE_UTF8
// helpers for wxStringBuffer and wxStringBufferLength // helpers for wxStringBuffer and wxStringBufferLength
wxStringCharType *DoGetWriteBuf(size_t nLen); wxStringCharType *DoGetWriteBuf(size_t nLen);
void DoUngetWriteBuf(); void DoUngetWriteBuf();
void DoUngetWriteBuf(size_t nLen); void DoUngetWriteBuf(size_t nLen);
#endif
private: private:
#if wxUSE_UNICODE_UTF8 #if wxUSE_UNICODE_UTF8

View File

@@ -39,6 +39,8 @@ struct WXDLLIMPEXP_BASE wxStringOperationsWchar
{ return i + n; } { return i + n; }
static wxStringImpl::const_iterator AddToIter(const wxStringImpl::const_iterator& i, int n) static wxStringImpl::const_iterator AddToIter(const wxStringImpl::const_iterator& i, int n)
{ return i + n; } { return i + n; }
static const wxChar* AddToIter(const wxChar *i, int n)
{ return i + n; }
// returns distance of the two iterators in Unicode characters // returns distance of the two iterators in Unicode characters
static int DiffIters(const wxStringImpl::iterator& i1, static int DiffIters(const wxStringImpl::iterator& i1,

View File

@@ -16,13 +16,14 @@
#error "OpenWatcom version >= 1.4 is required to compile this code" #error "OpenWatcom version >= 1.4 is required to compile this code"
#endif #endif
#include "wx/cpp.h"
#include "wx/chartype.h" #include "wx/chartype.h"
#include "wx/wxcrt.h"
#include "wx/strconv.h"
#include "wx/buffer.h"
class WXDLLIMPEXP_BASE wxCStrData; class WXDLLIMPEXP_BASE wxCStrData;
class WXDLLIMPEXP_BASE wxString; class WXDLLIMPEXP_BASE wxString;
class WXDLLIMPEXP_BASE wxCharBuffer;
class WXDLLIMPEXP_BASE wxWCharBuffer;
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// WX_DEFINE_VARARG_FUNC* macros // WX_DEFINE_VARARG_FUNC* macros
@@ -35,40 +36,86 @@ class WXDLLIMPEXP_BASE wxWCharBuffer;
// //
// This is done by defining a set of N template function taking 1..N arguments // This is done by defining a set of N template function taking 1..N arguments
// (currently, N is set to 30 in this header). These functions are just thin // (currently, N is set to 30 in this header). These functions are just thin
// wrappers around another variadic function (@a impl) and the only thing // wrappers around another variadic function ('impl' or 'implUtf8' arguments,
// the wrapper does is that it normalizes the arguments passed in so that // see below) and the only thing the wrapper does is that it normalizes the
// they are of the type expected by variadic functions taking string // arguments passed in so that they are of the type expected by variadic
// arguments, i.e., char* or wchar_t*, depending on the build: // functions taking string arguments, i.e., char* or wchar_t*, depending on the
// build:
// * char* in the current locale's charset in ANSI build // * char* in the current locale's charset in ANSI build
// * whchar_t* in the Unicode build // * char* with UTF-8 encoding if wxUSE_UNICODE_UTF8 and the app is running
// under an UTF-8 locale
// * wchar_t* if wxUSE_UNICODE_WCHAR or if wxUSE_UNICODE_UTF8 and the current
// locale is not UTF-8
// //
// Parameters: // Parameters:
// rettype Functions' return type. // [ there are examples in square brackets showing values of the parameters
// name Name of the function. // for the wxFprintf() wrapper for fprintf() function with the following
// impl Name of the variadic function that implements 'name'. // prototype:
#define WX_DEFINE_VARARG_FUNC(rettype, name, impl) \ // int wxFprintf(FILE *stream, const wxString& format, ...); ]
_WX_VARARG_ITER(_WX_VARARG_MAX_ARGS, \ //
_WX_VARARG_DEFINE_FUNC, \ // rettype Functions' return type [int]
rettype, name, impl) // name Name of the function [fprintf]
// numfixed The number of leading "fixed" (i.e., not variadic)
// arguments of the function (e.g. "stream" and "format"
// arguments of fprintf()); their type is _not_ converted
// using wxArgNormalizer<T>, unlike the rest of
// the function's arguments [2]
// fixed List of types of the leading "fixed" arguments, in
// parenthesis [(FILE*,const wxString&)]
// impl Name of the variadic function that implements 'name' for
// the native strings representation (wchar_t* if
// wxUSE_UNICODE_WCHAR or wxUSE_UNICODE_UTF8 when running under
// non-UTF8 locale, char* in ANSI build) [wxCrt_Fprintf]
// implUtf8 Like 'impl', but for the UTF-8 char* version to be used
// if wxUSE_UNICODE_UTF8 and running under UTF-8 locale
// (ignored otherwise) [fprintf]
//
#define WX_DEFINE_VARARG_FUNC2(rettype, name, numfixed, fixed, impl, implUtf8)\
_WX_VARARG_DEFINE_FUNC_N0(rettype, name, impl, implUtf8, numfixed, fixed) \
WX_DEFINE_VARARG_FUNC2_SANS_N0(rettype, name, numfixed, fixed, impl, implUtf8)
// Like WX_DEFINE_VARARG_FUNC, but for variadic functions that don't return // ditto, but without the version with 0 template/vararg arguments
#define WX_DEFINE_VARARG_FUNC2_SANS_N0(rettype, name, \
numfixed, fixed, impl, implUtf8) \
_WX_VARARG_ITER(_WX_VARARG_MAX_ARGS, \
_WX_VARARG_DEFINE_FUNC, \
rettype, name, impl, implUtf8, numfixed, fixed)
// like WX_DEFINE_VARARG_FUNC2, but for impl=implUtf8:
#define WX_DEFINE_VARARG_FUNC(rettype, name, numfixed, fixed, impl) \
WX_DEFINE_VARARG_FUNC2(rettype, name, numfixed, fixed, impl, impl)
// Like WX_DEFINE_VARARG_FUNC2, but for variadic functions that don't return
// a value. // a value.
#define WX_DEFINE_VARARG_FUNC_VOID(name, impl) \ #define WX_DEFINE_VARARG_FUNC_VOID2(name, numfixed, fixed, impl, implUtf8) \
_WX_VARARG_ITER(_WX_VARARG_MAX_ARGS, \ _WX_VARARG_DEFINE_FUNC_VOID_N0(name, impl, implUtf8, numfixed, fixed) \
_WX_VARARG_DEFINE_FUNC_VOID, \ _WX_VARARG_ITER(_WX_VARARG_MAX_ARGS, \
void, name, impl) _WX_VARARG_DEFINE_FUNC_VOID, \
void, name, impl, implUtf8, numfixed, fixed)
// like WX_DEFINE_VARARG_FUNC_VOID2, but for impl=implUtf8:
#define WX_DEFINE_VARARG_FUNC_VOID(name, numfixed, fixed, impl) \
WX_DEFINE_VARARG_FUNC_VOID2(name, numfixed, fixed, impl, impl)
// Like WX_DEFINE_VARARG_FUNC_VOID, but instead of wrapping an implementation // Like WX_DEFINE_VARARG_FUNC_VOID, but instead of wrapping an implementation
// function, does nothing in defined functions' bodies. // function, does nothing in defined functions' bodies.
// //
// Used to implement wxLogXXX functions if wxUSE_LOG=0. // Used to implement wxLogXXX functions if wxUSE_LOG=0.
#define WX_DEFINE_VARARG_FUNC_NOP(name) \ #define WX_DEFINE_VARARG_FUNC_NOP(name, numfixed, fixed) \
_WX_VARARG_ITER(_WX_VARARG_MAX_ARGS, \ _WX_VARARG_DEFINE_FUNC_NOP_N0(name, numfixed, fixed) \
_WX_VARARG_DEFINE_FUNC_NOP, \ _WX_VARARG_ITER(_WX_VARARG_MAX_ARGS, \
void, name, dummy) _WX_VARARG_DEFINE_FUNC_NOP, \
void, name, dummy, numfixed, fixed)
// Like WX_DEFINE_VARARG_FUNC_CTOR, but for defining template constructors
#define WX_DEFINE_VARARG_FUNC_CTOR(name, numfixed, fixed, impl) \
_WX_VARARG_DEFINE_FUNC_CTOR_N0(name, impl, impl, numfixed, fixed) \
_WX_VARARG_ITER(_WX_VARARG_MAX_ARGS, \
_WX_VARARG_DEFINE_FUNC_CTOR, \
void, name, impl, impl, numfixed, fixed)
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// implementation // wxArgNormalizer*<T> converters
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// Converts an argument passed to wxPrint etc. into standard form expected, // Converts an argument passed to wxPrint etc. into standard form expected,
@@ -87,122 +134,236 @@ struct wxArgNormalizer
const T& m_value; const T& m_value;
}; };
// normalizer for passing arguments to functions working with wchar_t* (and
// until ANSI build is removed, char* in ANSI build as well - FIXME-UTF8)
// string representation
#if !wxUSE_UTF8_LOCALE_ONLY
template<typename T>
struct wxArgNormalizerWchar : public wxArgNormalizer<T>
{
wxArgNormalizerWchar(const T& value) : wxArgNormalizer<T>(value) {}
};
#endif // !wxUSE_UTF8_LOCALE_ONLY
// normalizer for passing arguments to functions working with UTF-8 encoded
// char* strings
#if wxUSE_UNICODE_UTF8
template<typename T>
struct wxArgNormalizerUtf8 : public wxArgNormalizer<T>
{
wxArgNormalizerUtf8(const T& value) : wxArgNormalizer<T>(value) {}
};
#define wxArgNormalizerNative wxArgNormalizerUtf8
#else // wxUSE_UNICODE_WCHAR
#define wxArgNormalizerNative wxArgNormalizerWchar
#endif // wxUSE_UNICODE_UTF8 // wxUSE_UNICODE_UTF8
// special cases for converting strings: // special cases for converting strings:
template<>
struct WXDLLIMPEXP_BASE wxArgNormalizer<const wxCStrData&>
{
wxArgNormalizer(const wxCStrData& value) : m_value(value) {}
const wxChar *get() const; // FIXME-UTF8: should be wxStringCharType
const wxCStrData& m_value; // base class for wxArgNormalizer<T> specializations that need to do conversion;
// CharType is either wxStringCharType or wchar_t in UTF-8 build when wrapping
// widechar CRT function
template<typename CharType>
struct wxArgNormalizerWithBuffer
{
typedef wxCharTypeBuffer<CharType> CharBuffer;
wxArgNormalizerWithBuffer() {}
wxArgNormalizerWithBuffer(const CharBuffer& buf) : m_value(buf) {}
const CharType *get() const { return m_value; }
CharBuffer m_value;
}; };
// string objects:
template<> template<>
struct wxArgNormalizer<wxCStrData> : public wxArgNormalizer<const wxCStrData&> struct WXDLLIMPEXP_BASE wxArgNormalizerNative<const wxString&>
{ {
wxArgNormalizer(const wxCStrData& value) wxArgNormalizerNative(const wxString& s) : m_value(s) {}
: wxArgNormalizer<const wxCStrData&>(value) {} const wxStringCharType *get() const;
};
template<>
struct WXDLLIMPEXP_BASE wxArgNormalizer<const wxString&>
{
wxArgNormalizer(const wxString& value) : m_value(value) {}
const wxChar *get() const; // FIXME-UTF8: should be wxStringCharType
const wxString& m_value; const wxString& m_value;
}; };
// c_str() values:
template<> template<>
struct wxArgNormalizer<wxString> : public wxArgNormalizer<const wxString&> struct WXDLLIMPEXP_BASE wxArgNormalizerNative<const wxCStrData&>
{ {
wxArgNormalizer(const wxString& value) wxArgNormalizerNative(const wxCStrData& value) : m_value(value) {}
: wxArgNormalizer<const wxString&>(value) {} const wxStringCharType *get() const;
const wxCStrData& m_value;
}; };
#if wxUSE_UNICODE // FIXME-UTF8: should be wxUSE_UNICODE_WCHAR // wxString/wxCStrData conversion to wchar_t* value
#if wxUSE_UNICODE_UTF8 && !wxUSE_UTF8_LOCALE_ONLY
template<> template<>
struct WXDLLIMPEXP_BASE wxArgNormalizer<const char*> struct WXDLLIMPEXP_BASE wxArgNormalizerWchar<const wxString&>
: public wxArgNormalizerWithBuffer<wchar_t>
{ {
wxArgNormalizer(const char *value); wxArgNormalizerWchar(const wxString& s);
~wxArgNormalizer();
const wchar_t *get() const;
wxWCharBuffer *m_value;
}; };
template<> template<>
struct wxArgNormalizer<char*> : public wxArgNormalizer<const char*> struct WXDLLIMPEXP_BASE wxArgNormalizerWchar<const wxCStrData&>
: public wxArgNormalizerWithBuffer<wchar_t>
{ {
wxArgNormalizer(char *value) wxArgNormalizerWchar(const wxCStrData& s);
: wxArgNormalizer<const char*>(value) {}
}; };
#endif // wxUSE_UNICODE_WCHAR #endif // wxUSE_UNICODE_UTF8 && !wxUSE_UTF8_LOCALE_ONLY
// C string pointers of the wrong type (wchar_t* for ANSI or UTF8 build,
// char* for wchar_t Unicode build or UTF8):
#if wxUSE_UNICODE_WCHAR
// FIXME-UTF8
#if 0 // wxUSE_UNICODE_UTF8
// for conversion from local charset to UTF-8
template<> template<>
struct WXDLLIMPEXP_BASE wxArgNormalizer<const char*> struct wxArgNormalizerWchar<const char*>
: public wxArgNormalizerWithBuffer<wchar_t>
{ {
wxArgNormalizer(const char *value); wxArgNormalizerWchar(const char* s)
~wxArgNormalizer(); : wxArgNormalizerWithBuffer<wchar_t>(wxConvLibc.cMB2WC(s)) {}
const char *get() const; };
wxCharBuffer *m_value; #elif wxUSE_UNICODE_UTF8
template<>
struct wxArgNormalizerUtf8<const wchar_t*>
: public wxArgNormalizerWithBuffer<char>
{
wxArgNormalizerUtf8(const wchar_t* s)
: wxArgNormalizerWithBuffer<char>(wxConvUTF8.cWC2MB(s)) {}
}; };
template<> template<>
struct wxArgNormalizer<char*> : public wxArgNormalizer<const char*> struct wxArgNormalizerUtf8<const char*>
: public wxArgNormalizerWithBuffer<char>
{ {
wxArgNormalizer(char *value) wxArgNormalizerUtf8(const char* s)
: wxArgNormalizer<const char*>(value) {} {
}; // FIXME-UTF8: optimize this if current locale is UTF-8 one
#endif // wxUSE_UNICODE_UTF8
#if /*wxUSE_UNICODE_UTF8 || */ !wxUSE_UNICODE // FIXME-UTF8 // convert to widechar string first:
wxWCharBuffer buf(wxConvLibc.cMB2WC(s));
// then to UTF-8:
if ( buf )
m_value = wxConvUTF8.cWC2MB(buf);
}
};
// UTF-8 build needs conversion to wchar_t* too:
#if !wxUSE_UTF8_LOCALE_ONLY
template<> template<>
struct WXDLLIMPEXP_BASE wxArgNormalizer<const wchar_t*> struct wxArgNormalizerWchar<const char*>
: public wxArgNormalizerWithBuffer<wchar_t>
{ {
wxArgNormalizer(const wchar_t *value); wxArgNormalizerWchar(const char* s)
~wxArgNormalizer(); : wxArgNormalizerWithBuffer<wchar_t>(wxConvLibc.cMB2WC(s)) {}
const char *get() const;
wxCharBuffer *m_value;
}; };
#endif // !wxUSE_UTF8_LOCALE_ONLY
#else // ANSI - FIXME-UTF8
template<> template<>
struct wxArgNormalizer<wchar_t*> : public wxArgNormalizer<const wchar_t*> struct wxArgNormalizerWchar<const wchar_t*>
: public wxArgNormalizerWithBuffer<char>
{ {
wxArgNormalizer(wchar_t *value) wxArgNormalizerWchar(const wchar_t* s)
: wxArgNormalizer<const wchar_t*>(value) {} : wxArgNormalizerWithBuffer<char>(wxConvLibc.cWC2MB(s)) {}
}; };
#endif // wxUSE_UNICODE_UTF8 || !wxUSE_UNICODE
#endif // wxUSE_UNICODE_WCHAR/wxUSE_UNICODE_UTF8/ANSI
// this macro is used to implement specialization that are exactly same as
// some other specialization, i.e. to "forward" the implementation (e.g. for
// T=wxString and T=const wxString&). Note that the ctor takes BaseT argument,
// not T!
#if wxUSE_UNICODE_UTF8
#if wxUSE_UTF8_LOCALE_ONLY
#define WX_ARG_NORMALIZER_FORWARD(T, BaseT) \
_WX_ARG_NORMALIZER_FORWARD_IMPL(wxArgNormalizerUtf8, T, BaseT)
#else // possibly non-UTF8 locales
#define WX_ARG_NORMALIZER_FORWARD(T, BaseT) \
_WX_ARG_NORMALIZER_FORWARD_IMPL(wxArgNormalizerWchar, T, BaseT); \
_WX_ARG_NORMALIZER_FORWARD_IMPL(wxArgNormalizerUtf8, T, BaseT)
#endif
#else // wxUSE_UNICODE_WCHAR
#define WX_ARG_NORMALIZER_FORWARD(T, BaseT) \
_WX_ARG_NORMALIZER_FORWARD_IMPL(wxArgNormalizerWchar, T, BaseT)
#endif // wxUSE_UNICODE_UTF8/wxUSE_UNICODE_WCHAR
#define _WX_ARG_NORMALIZER_FORWARD_IMPL(Normalizer, T, BaseT) \
template<> \
struct Normalizer<T> : public Normalizer<BaseT> \
{ \
Normalizer(BaseT value) : Normalizer<BaseT>(value) {} \
}
// non-reference versions of specializations for string objects
WX_ARG_NORMALIZER_FORWARD(wxString, const wxString&);
WX_ARG_NORMALIZER_FORWARD(wxCStrData, const wxCStrData&);
// versions for passing non-const pointers:
WX_ARG_NORMALIZER_FORWARD(char*, const char*);
WX_ARG_NORMALIZER_FORWARD(wchar_t*, const wchar_t*);
// versions for passing wx[W]CharBuffer: // versions for passing wx[W]CharBuffer:
template<> WX_ARG_NORMALIZER_FORWARD(wxCharBuffer, const char*);
struct WXDLLIMPEXP_BASE wxArgNormalizer<wxCharBuffer> WX_ARG_NORMALIZER_FORWARD(const wxCharBuffer&, const char*);
: public wxArgNormalizer<const char*> WX_ARG_NORMALIZER_FORWARD(wxWCharBuffer, const wchar_t*);
WX_ARG_NORMALIZER_FORWARD(const wxWCharBuffer&, const wchar_t*);
#undef WX_ARG_NORMALIZER_FORWARD
#undef _WX_ARG_NORMALIZER_FORWARD_IMPL
// ----------------------------------------------------------------------------
// WX_VA_ARG_STRING
// ----------------------------------------------------------------------------
// Replacement for va_arg() for use with strings in functions that accept
// strings normalized by wxArgNormalizer<T>:
struct WXDLLIMPEXP_BASE wxArgNormalizedString
{ {
wxArgNormalizer(const wxCharBuffer& buf); wxArgNormalizedString(const void* ptr) : m_ptr(ptr) {}
// returns true if non-NULL string was passed in
bool IsValid() const { return m_ptr != NULL; }
operator bool() const { return IsValid(); }
// extracts the string, returns empty string if NULL was passed in
wxString GetString() const;
operator wxString() const;
private:
const void *m_ptr;
}; };
template<> #define WX_VA_ARG_STRING(ap) wxArgNormalizedString(va_arg(ap, const void*))
struct WXDLLIMPEXP_BASE wxArgNormalizer<wxWCharBuffer>
: public wxArgNormalizer<const wchar_t*>
{
wxArgNormalizer(const wxWCharBuffer& buf);
};
// ----------------------------------------------------------------------------
// implementation of the WX_DEFINE_VARARG_* macros
// ----------------------------------------------------------------------------
// NB: The vararg emulation code is limited to 30 variadic and 4 fixed
// NB: The vararg emulation code is limited to 30 arguments at the moment. // arguments at the moment.
// If you need more, you need to // If you need more variadic arguments, you need to
// 1) increase the value of _WX_VARARG_MAX_ARGS // 1) increase the value of _WX_VARARG_MAX_ARGS
// 2) add _WX_VARARG_JOIN_* and _WX_VARARG_ITER_* up to the new // 2) add _WX_VARARG_JOIN_* and _WX_VARARG_ITER_* up to the new
// _WX_VARARG_MAX_ARGS value to the lists below // _WX_VARARG_MAX_ARGS value to the lists below
// If you need more fixed arguments, you need to
// 1) increase the value of _WX_VARARG_MAX_FIXED_ARGS
// 2) add _WX_VARARG_FIXED_EXPAND_* and _WX_VARARG_FIXED_UNUSED_EXPAND_*
// macros below
#define _WX_VARARG_MAX_ARGS 30 #define _WX_VARARG_MAX_ARGS 30
#define _WX_VARARG_MAX_FIXED_ARGS 4
#define _WX_VARARG_JOIN_1(m) m(1) #define _WX_VARARG_JOIN_1(m) m(1)
#define _WX_VARARG_JOIN_2(m) _WX_VARARG_JOIN_1(m), m(2) #define _WX_VARARG_JOIN_2(m) _WX_VARARG_JOIN_1(m), m(2)
@@ -235,36 +396,72 @@ struct WXDLLIMPEXP_BASE wxArgNormalizer<wxWCharBuffer>
#define _WX_VARARG_JOIN_29(m) _WX_VARARG_JOIN_28(m), m(29) #define _WX_VARARG_JOIN_29(m) _WX_VARARG_JOIN_28(m), m(29)
#define _WX_VARARG_JOIN_30(m) _WX_VARARG_JOIN_29(m), m(30) #define _WX_VARARG_JOIN_30(m) _WX_VARARG_JOIN_29(m), m(30)
#define _WX_VARARG_ITER_1(m,a,b,c) m(1,a,b,c) #define _WX_VARARG_ITER_1(m,a,b,c,d,e,f) m(1,a,b,c,d,e,f)
#define _WX_VARARG_ITER_2(m,a,b,c) _WX_VARARG_ITER_1(m,a,b,c) m(2,a,b,c) #define _WX_VARARG_ITER_2(m,a,b,c,d,e,f) _WX_VARARG_ITER_1(m,a,b,c,d,e,f) m(2,a,b,c,d,e,f)
#define _WX_VARARG_ITER_3(m,a,b,c) _WX_VARARG_ITER_2(m,a,b,c) m(3,a,b,c) #define _WX_VARARG_ITER_3(m,a,b,c,d,e,f) _WX_VARARG_ITER_2(m,a,b,c,d,e,f) m(3,a,b,c,d,e,f)
#define _WX_VARARG_ITER_4(m,a,b,c) _WX_VARARG_ITER_3(m,a,b,c) m(4,a,b,c) #define _WX_VARARG_ITER_4(m,a,b,c,d,e,f) _WX_VARARG_ITER_3(m,a,b,c,d,e,f) m(4,a,b,c,d,e,f)
#define _WX_VARARG_ITER_5(m,a,b,c) _WX_VARARG_ITER_4(m,a,b,c) m(5,a,b,c) #define _WX_VARARG_ITER_5(m,a,b,c,d,e,f) _WX_VARARG_ITER_4(m,a,b,c,d,e,f) m(5,a,b,c,d,e,f)
#define _WX_VARARG_ITER_6(m,a,b,c) _WX_VARARG_ITER_5(m,a,b,c) m(6,a,b,c) #define _WX_VARARG_ITER_6(m,a,b,c,d,e,f) _WX_VARARG_ITER_5(m,a,b,c,d,e,f) m(6,a,b,c,d,e,f)
#define _WX_VARARG_ITER_7(m,a,b,c) _WX_VARARG_ITER_6(m,a,b,c) m(7,a,b,c) #define _WX_VARARG_ITER_7(m,a,b,c,d,e,f) _WX_VARARG_ITER_6(m,a,b,c,d,e,f) m(7,a,b,c,d,e,f)
#define _WX_VARARG_ITER_8(m,a,b,c) _WX_VARARG_ITER_7(m,a,b,c) m(8,a,b,c) #define _WX_VARARG_ITER_8(m,a,b,c,d,e,f) _WX_VARARG_ITER_7(m,a,b,c,d,e,f) m(8,a,b,c,d,e,f)
#define _WX_VARARG_ITER_9(m,a,b,c) _WX_VARARG_ITER_8(m,a,b,c) m(9,a,b,c) #define _WX_VARARG_ITER_9(m,a,b,c,d,e,f) _WX_VARARG_ITER_8(m,a,b,c,d,e,f) m(9,a,b,c,d,e,f)
#define _WX_VARARG_ITER_10(m,a,b,c) _WX_VARARG_ITER_9(m,a,b,c) m(10,a,b,c) #define _WX_VARARG_ITER_10(m,a,b,c,d,e,f) _WX_VARARG_ITER_9(m,a,b,c,d,e,f) m(10,a,b,c,d,e,f)
#define _WX_VARARG_ITER_11(m,a,b,c) _WX_VARARG_ITER_10(m,a,b,c) m(11,a,b,c) #define _WX_VARARG_ITER_11(m,a,b,c,d,e,f) _WX_VARARG_ITER_10(m,a,b,c,d,e,f) m(11,a,b,c,d,e,f)
#define _WX_VARARG_ITER_12(m,a,b,c) _WX_VARARG_ITER_11(m,a,b,c) m(12,a,b,c) #define _WX_VARARG_ITER_12(m,a,b,c,d,e,f) _WX_VARARG_ITER_11(m,a,b,c,d,e,f) m(12,a,b,c,d,e,f)
#define _WX_VARARG_ITER_13(m,a,b,c) _WX_VARARG_ITER_12(m,a,b,c) m(13,a,b,c) #define _WX_VARARG_ITER_13(m,a,b,c,d,e,f) _WX_VARARG_ITER_12(m,a,b,c,d,e,f) m(13,a,b,c,d,e,f)
#define _WX_VARARG_ITER_14(m,a,b,c) _WX_VARARG_ITER_13(m,a,b,c) m(14,a,b,c) #define _WX_VARARG_ITER_14(m,a,b,c,d,e,f) _WX_VARARG_ITER_13(m,a,b,c,d,e,f) m(14,a,b,c,d,e,f)
#define _WX_VARARG_ITER_15(m,a,b,c) _WX_VARARG_ITER_14(m,a,b,c) m(15,a,b,c) #define _WX_VARARG_ITER_15(m,a,b,c,d,e,f) _WX_VARARG_ITER_14(m,a,b,c,d,e,f) m(15,a,b,c,d,e,f)
#define _WX_VARARG_ITER_16(m,a,b,c) _WX_VARARG_ITER_15(m,a,b,c) m(16,a,b,c) #define _WX_VARARG_ITER_16(m,a,b,c,d,e,f) _WX_VARARG_ITER_15(m,a,b,c,d,e,f) m(16,a,b,c,d,e,f)
#define _WX_VARARG_ITER_17(m,a,b,c) _WX_VARARG_ITER_16(m,a,b,c) m(17,a,b,c) #define _WX_VARARG_ITER_17(m,a,b,c,d,e,f) _WX_VARARG_ITER_16(m,a,b,c,d,e,f) m(17,a,b,c,d,e,f)
#define _WX_VARARG_ITER_18(m,a,b,c) _WX_VARARG_ITER_17(m,a,b,c) m(18,a,b,c) #define _WX_VARARG_ITER_18(m,a,b,c,d,e,f) _WX_VARARG_ITER_17(m,a,b,c,d,e,f) m(18,a,b,c,d,e,f)
#define _WX_VARARG_ITER_19(m,a,b,c) _WX_VARARG_ITER_18(m,a,b,c) m(19,a,b,c) #define _WX_VARARG_ITER_19(m,a,b,c,d,e,f) _WX_VARARG_ITER_18(m,a,b,c,d,e,f) m(19,a,b,c,d,e,f)
#define _WX_VARARG_ITER_20(m,a,b,c) _WX_VARARG_ITER_19(m,a,b,c) m(20,a,b,c) #define _WX_VARARG_ITER_20(m,a,b,c,d,e,f) _WX_VARARG_ITER_19(m,a,b,c,d,e,f) m(20,a,b,c,d,e,f)
#define _WX_VARARG_ITER_21(m,a,b,c) _WX_VARARG_ITER_20(m,a,b,c) m(21,a,b,c) #define _WX_VARARG_ITER_21(m,a,b,c,d,e,f) _WX_VARARG_ITER_20(m,a,b,c,d,e,f) m(21,a,b,c,d,e,f)
#define _WX_VARARG_ITER_22(m,a,b,c) _WX_VARARG_ITER_21(m,a,b,c) m(22,a,b,c) #define _WX_VARARG_ITER_22(m,a,b,c,d,e,f) _WX_VARARG_ITER_21(m,a,b,c,d,e,f) m(22,a,b,c,d,e,f)
#define _WX_VARARG_ITER_23(m,a,b,c) _WX_VARARG_ITER_22(m,a,b,c) m(23,a,b,c) #define _WX_VARARG_ITER_23(m,a,b,c,d,e,f) _WX_VARARG_ITER_22(m,a,b,c,d,e,f) m(23,a,b,c,d,e,f)
#define _WX_VARARG_ITER_24(m,a,b,c) _WX_VARARG_ITER_23(m,a,b,c) m(24,a,b,c) #define _WX_VARARG_ITER_24(m,a,b,c,d,e,f) _WX_VARARG_ITER_23(m,a,b,c,d,e,f) m(24,a,b,c,d,e,f)
#define _WX_VARARG_ITER_25(m,a,b,c) _WX_VARARG_ITER_24(m,a,b,c) m(25,a,b,c) #define _WX_VARARG_ITER_25(m,a,b,c,d,e,f) _WX_VARARG_ITER_24(m,a,b,c,d,e,f) m(25,a,b,c,d,e,f)
#define _WX_VARARG_ITER_26(m,a,b,c) _WX_VARARG_ITER_25(m,a,b,c) m(26,a,b,c) #define _WX_VARARG_ITER_26(m,a,b,c,d,e,f) _WX_VARARG_ITER_25(m,a,b,c,d,e,f) m(26,a,b,c,d,e,f)
#define _WX_VARARG_ITER_27(m,a,b,c) _WX_VARARG_ITER_26(m,a,b,c) m(27,a,b,c) #define _WX_VARARG_ITER_27(m,a,b,c,d,e,f) _WX_VARARG_ITER_26(m,a,b,c,d,e,f) m(27,a,b,c,d,e,f)
#define _WX_VARARG_ITER_28(m,a,b,c) _WX_VARARG_ITER_27(m,a,b,c) m(28,a,b,c) #define _WX_VARARG_ITER_28(m,a,b,c,d,e,f) _WX_VARARG_ITER_27(m,a,b,c,d,e,f) m(28,a,b,c,d,e,f)
#define _WX_VARARG_ITER_29(m,a,b,c) _WX_VARARG_ITER_28(m,a,b,c) m(29,a,b,c) #define _WX_VARARG_ITER_29(m,a,b,c,d,e,f) _WX_VARARG_ITER_28(m,a,b,c,d,e,f) m(29,a,b,c,d,e,f)
#define _WX_VARARG_ITER_30(m,a,b,c) _WX_VARARG_ITER_29(m,a,b,c) m(30,a,b,c) #define _WX_VARARG_ITER_30(m,a,b,c,d,e,f) _WX_VARARG_ITER_29(m,a,b,c,d,e,f) m(30,a,b,c,d,e,f)
#define _WX_VARARG_FIXED_EXPAND_1(t1) \
t1 f1
#define _WX_VARARG_FIXED_EXPAND_2(t1,t2) \
t1 f1, t2 f2
#define _WX_VARARG_FIXED_EXPAND_3(t1,t2,t3) \
t1 f1, t2 f2, t3 f3
#define _WX_VARARG_FIXED_EXPAND_4(t1,t2,t3,t4) \
t1 f1, t2 f2, t3 f3, t4 f4
#define _WX_VARARG_FIXED_UNUSED_EXPAND_1(t1) \
t1 WXUNUSED(f1)
#define _WX_VARARG_FIXED_UNUSED_EXPAND_2(t1,t2) \
t1 WXUNUSED(f1), t2 WXUNUSED(f2)
#define _WX_VARARG_FIXED_UNUSED_EXPAND_3(t1,t2,t3) \
t1 WXUNUSED(f1), t2 WXUNUSED(f2), t3 WXUNUSED(f3)
#define _WX_VARARG_FIXED_UNUSED_EXPAND_4(t1,t2,t3,t4) \
t1 WXUNUSED(f1), t2 WXUNUSED(f2), t3 WXUNUSED(f3), t4 WXUNUSED(f4)
// This macro expands N-items tuple of fixed arguments types into part of
// function's declaration. For example,
// "_WX_VARARG_FIXED_EXPAND(3, (int, char*, int))" expands into
// "int f1, char* f2, int f3".
#define _WX_VARARG_FIXED_EXPAND(N, args) \
_WX_VARARG_FIXED_EXPAND_IMPL(N, args)
#define _WX_VARARG_FIXED_EXPAND_IMPL(N, args) \
_WX_VARARG_FIXED_EXPAND_##N args
// Ditto for unused arguments
#define _WX_VARARG_FIXED_UNUSED_EXPAND(N, args) \
_WX_VARARG_FIXED_UNUSED_EXPAND_IMPL(N, args)
#define _WX_VARARG_FIXED_UNUSED_EXPAND_IMPL(N, args) \
_WX_VARARG_FIXED_UNUSED_EXPAND_##N args
// This macro calls another macro 'm' passed as second argument 'N' times, // This macro calls another macro 'm' passed as second argument 'N' times,
// with its only argument set to 1..N, and concatenates the results using // with its only argument set to 1..N, and concatenates the results using
@@ -280,61 +477,160 @@ struct WXDLLIMPEXP_BASE wxArgNormalizer<wxWCharBuffer>
#define _WX_VARARG_JOIN(N, m) _WX_VARARG_JOIN_IMPL(N, m) #define _WX_VARARG_JOIN(N, m) _WX_VARARG_JOIN_IMPL(N, m)
#define _WX_VARARG_JOIN_IMPL(N, m) _WX_VARARG_JOIN_##N(m) #define _WX_VARARG_JOIN_IMPL(N, m) _WX_VARARG_JOIN_##N(m)
// This macro calls another macro 'm' passed as second argument 'N' times, with // This macro calls another macro 'm' passed as second argument 'N' times, with
// its first argument set to 1..N and the remaining arguments set to 'a', 'b' // its first argument set to 1..N and the remaining arguments set to 'a', 'b',
// and 'c'. The results are separated with whitespace in the expansion. // 'c', 'd', 'e' and 'f'. The results are separated with whitespace in the
// expansion.
// //
// An example: // An example:
// // this macro expands to: // // this macro expands to:
// // foo(1,a,b,c) // // foo(1,a,b,c,d,e,f)
// // foo(2,a,b,c) // // foo(2,a,b,c,d,e,f)
// // foo(3,a,b,c) // // foo(3,a,b,c,d,e,f)
// _WX_VARARG_ITER(3, foo, a, b, c) // _WX_VARARG_ITER(3, foo, a, b, c, d, e, f)
// //
// N must not be greater than _WX_VARARG_MAX_ARGS (=30). // N must not be greater than _WX_VARARG_MAX_ARGS (=30).
#define _WX_VARARG_ITER(N, m,a,b,c) _WX_VARARG_ITER_IMPL(N, m, a, b, c) #define _WX_VARARG_ITER(N,m,a,b,c,d,e,f) \
#define _WX_VARARG_ITER_IMPL(N, m,a,b,c) _WX_VARARG_ITER_##N(m, a, b, c) _WX_VARARG_ITER_IMPL(N,m,a,b,c,d,e,f)
#define _WX_VARARG_ITER_IMPL(N,m,a,b,c,d,e,f) \
_WX_VARARG_ITER_##N(m,a,b,c,d,e,f)
// Generates code snippet for i-th argument in vararg function's prototype. // Generates code snippet for i-th "variadic" argument in vararg function's
#define _WX_VARARG_ARG(i) T##i a##i // prototype:
#define _WX_VARARG_ARG(i) T##i a##i
// Like _WX_VARARG_ARG_UNUSED, but outputs argument's type with WXUNUSED. // Like _WX_VARARG_ARG_UNUSED, but outputs argument's type with WXUNUSED:
#define _WX_VARARG_ARG_UNUSED(i) T##i WXUNUSED(a##i) #define _WX_VARARG_ARG_UNUSED(i) T##i WXUNUSED(a##i)
// Generates code snippet for i-th type in vararg function's template<...>. // Generates code snippet for i-th type in vararg function's template<...>:
#define _WX_VARARG_TEMPL(i) typename T##i #define _WX_VARARG_TEMPL(i) typename T##i
// Generates code snippet for passing i-th argument of vararg function // Generates code snippet for passing i-th argument of vararg function
// wrapper to its implementation, normalizing it in the process // wrapper to its implementation, normalizing it in the process:
#define _WX_VARARG_PASS(i) wxArgNormalizer<T##i>(a##i).get() #define _WX_VARARG_PASS_WCHAR(i) wxArgNormalizerWchar<T##i>(a##i).get()
#define _WX_VARARG_PASS_UTF8(i) wxArgNormalizerUtf8<T##i>(a##i).get()
// And the same for fixed arguments, _not_ normalizing it:
// FIXME-UTF8: this works, but uses wxString's implicit conversion to wxChar*
// for the 'format' argument (which is const wxString&) _if_ the
// implementation function has C sting argument; we need to
// have wxFixedArgNormalizer<T> here that will pass everything
// as-is except for wxString (for which wx_str() would be used),
// but OTOH, we don't want to do that if the implementation takes
// wxString argument
#define _WX_VARARG_PASS_FIXED(i) f##i
#if wxUSE_UNICODE_UTF8
#define _WX_VARARG_DO_CALL_UTF8(return_kw, impl, implUtf8, N, numfixed) \
return_kw implUtf8(_WX_VARARG_JOIN(numfixed, _WX_VARARG_PASS_FIXED), \
_WX_VARARG_JOIN(N, _WX_VARARG_PASS_UTF8))
#define _WX_VARARG_DO_CALL0_UTF8(return_kw, impl, implUtf8, numfixed) \
return_kw implUtf8(_WX_VARARG_JOIN(numfixed, _WX_VARARG_PASS_FIXED))
#endif // wxUSE_UNICODE_UTF8
#define _WX_VARARG_DO_CALL_WCHAR(return_kw, impl, implUtf8, N, numfixed) \
return_kw impl(_WX_VARARG_JOIN(numfixed, _WX_VARARG_PASS_FIXED), \
_WX_VARARG_JOIN(N, _WX_VARARG_PASS_WCHAR))
#define _WX_VARARG_DO_CALL0_WCHAR(return_kw, impl, implUtf8, numfixed) \
return_kw impl(_WX_VARARG_JOIN(numfixed, _WX_VARARG_PASS_FIXED))
#if wxUSE_UNICODE_UTF8
#if wxUSE_UTF8_LOCALE_ONLY
#define _WX_VARARG_DO_CALL _WX_VARARG_DO_CALL_UTF8
#define _WX_VARARG_DO_CALL0 _WX_VARARG_DO_CALL0_UTF8
#else // possibly non-UTF8 locales
#define _WX_VARARG_DO_CALL(return_kw, impl, implUtf8, N, numfixed) \
if ( wxLocaleIsUtf8 ) \
_WX_VARARG_DO_CALL_UTF8(return_kw, impl, implUtf8, N, numfixed);\
else \
_WX_VARARG_DO_CALL_WCHAR(return_kw, impl, implUtf8, N, numfixed)
#define _WX_VARARG_DO_CALL0(return_kw, impl, implUtf8, numfixed) \
if ( wxLocaleIsUtf8 ) \
_WX_VARARG_DO_CALL0_UTF8(return_kw, impl, implUtf8, numfixed); \
else \
_WX_VARARG_DO_CALL0_WCHAR(return_kw, impl, implUtf8, numfixed)
#endif // wxUSE_UTF8_LOCALE_ONLY or not
#else // wxUSE_UNICODE_WCHAR or ANSI
#define _WX_VARARG_DO_CALL _WX_VARARG_DO_CALL_WCHAR
#define _WX_VARARG_DO_CALL0 _WX_VARARG_DO_CALL0_WCHAR
#endif // wxUSE_UNICODE_UTF8 / wxUSE_UNICODE_WCHAR
// Macro to be used with _WX_VARARG_ITER in the implementation of // Macro to be used with _WX_VARARG_ITER in the implementation of
// WX_DEFINE_VARARG_FUNC (see its documentation for the meaning of arguments) // WX_DEFINE_VARARG_FUNC (see its documentation for the meaning of arguments)
#define _WX_VARARG_DEFINE_FUNC(N, rettype, name, impl) \ #define _WX_VARARG_DEFINE_FUNC(N, rettype, name, \
template<_WX_VARARG_JOIN(N, _WX_VARARG_TEMPL)> \ impl, implUtf8, numfixed, fixed) \
rettype name(_WX_VARARG_JOIN(N, _WX_VARARG_ARG)) \ template<_WX_VARARG_JOIN(N, _WX_VARARG_TEMPL)> \
{ \ rettype name(_WX_VARARG_FIXED_EXPAND(numfixed, fixed), \
return impl(_WX_VARARG_JOIN(N, _WX_VARARG_PASS)); \ _WX_VARARG_JOIN(N, _WX_VARARG_ARG)) \
{ \
_WX_VARARG_DO_CALL(return, impl, implUtf8, N, numfixed); \
}
#define _WX_VARARG_DEFINE_FUNC_N0(rettype, name, \
impl, implUtf8, numfixed, fixed) \
inline rettype name(_WX_VARARG_FIXED_EXPAND(numfixed, fixed)) \
{ \
_WX_VARARG_DO_CALL0(return, impl, implUtf8, numfixed); \
} }
// Macro to be used with _WX_VARARG_ITER in the implementation of // Macro to be used with _WX_VARARG_ITER in the implementation of
// WX_DEFINE_VARARG_FUNC_VOID (see its documentation for the meaning of // WX_DEFINE_VARARG_FUNC_VOID (see its documentation for the meaning of
// arguments; rettype is ignored and is used only to satisfy _WX_VARARG_ITER's // arguments; rettype is ignored and is used only to satisfy _WX_VARARG_ITER's
// requirements). // requirements).
#define _WX_VARARG_DEFINE_FUNC_VOID(N, rettype, name, impl) \ #define _WX_VARARG_DEFINE_FUNC_VOID(N, rettype, name, \
template<_WX_VARARG_JOIN(N, _WX_VARARG_TEMPL)> \ impl, implUtf8, numfixed, fixed) \
void name(_WX_VARARG_JOIN(N, _WX_VARARG_ARG)) \ template<_WX_VARARG_JOIN(N, _WX_VARARG_TEMPL)> \
{ \ void name(_WX_VARARG_FIXED_EXPAND(numfixed, fixed), \
impl(_WX_VARARG_JOIN(N, _WX_VARARG_PASS)); \ _WX_VARARG_JOIN(N, _WX_VARARG_ARG)) \
{ \
_WX_VARARG_DO_CALL(wxEMPTY_PARAMETER_VALUE, \
impl, implUtf8, N, numfixed); \
}
#define _WX_VARARG_DEFINE_FUNC_VOID_N0(name, impl, implUtf8, numfixed, fixed) \
inline void name(_WX_VARARG_FIXED_EXPAND(numfixed, fixed)) \
{ \
_WX_VARARG_DO_CALL0(wxEMPTY_PARAMETER_VALUE, \
impl, implUtf8, numfixed); \
}
// Macro to be used with _WX_VARARG_ITER in the implementation of
// WX_DEFINE_VARARG_FUNC_CTOR (see its documentation for the meaning of
// arguments; rettype is ignored and is used only to satisfy _WX_VARARG_ITER's
// requirements).
#define _WX_VARARG_DEFINE_FUNC_CTOR(N, rettype, name, \
impl, implUtf8, numfixed, fixed) \
template<_WX_VARARG_JOIN(N, _WX_VARARG_TEMPL)> \
name(_WX_VARARG_FIXED_EXPAND(numfixed, fixed), \
_WX_VARARG_JOIN(N, _WX_VARARG_ARG)) \
{ \
_WX_VARARG_DO_CALL(wxEMPTY_PARAMETER_VALUE, \
impl, implUtf8, N, numfixed); \
}
#define _WX_VARARG_DEFINE_FUNC_CTOR_N0(name, impl, implUtf8, numfixed, fixed) \
inline name(_WX_VARARG_FIXED_EXPAND(numfixed, fixed)) \
{ \
_WX_VARARG_DO_CALL0(wxEMPTY_PARAMETER_VALUE, \
impl, implUtf8, numfixed); \
} }
// Macro to be used with _WX_VARARG_ITER in the implementation of // Macro to be used with _WX_VARARG_ITER in the implementation of
// WX_DEFINE_VARARG_FUNC_NOP, i.e. empty stub for a disabled vararg function. // WX_DEFINE_VARARG_FUNC_NOP, i.e. empty stub for a disabled vararg function.
// The rettype and impl arguments are ignored. // The rettype and impl arguments are ignored.
#define _WX_VARARG_DEFINE_FUNC_NOP(N, rettype, name, impl) \ #define _WX_VARARG_DEFINE_FUNC_NOP(N, rettype, name, \
template<_WX_VARARG_JOIN(N, _WX_VARARG_TEMPL)> \ impl, implUtf8, numfixed, fixed) \
void name(_WX_VARARG_JOIN(N, _WX_VARARG_ARG_UNUSED)) {} template<_WX_VARARG_JOIN(N, _WX_VARARG_TEMPL)> \
void name(_WX_VARARG_FIXED_UNUSED_EXPAND(numfixed, fixed), \
_WX_VARARG_JOIN(N, _WX_VARARG_ARG_UNUSED)) \
{}
#define _WX_VARARG_DEFINE_FUNC_NOP_N0(name, numfixed, fixed) \
inline void name(_WX_VARARG_FIXED_UNUSED_EXPAND(numfixed, fixed)) \
{}
#endif // _WX_STRVARARG_H_ #endif // _WX_STRVARARG_H_

View File

@@ -31,6 +31,7 @@
#include "wx/stopwatch.h" #include "wx/stopwatch.h"
#include "wx/module.h" #include "wx/module.h"
#include "wx/wxcrt.h" #include "wx/wxcrt.h"
#include "wx/wxcrtvararg.h"
#if wxUSE_GUI #if wxUSE_GUI

View File

@@ -16,51 +16,38 @@
#include "wx/wxcrt.h" #include "wx/wxcrt.h"
#include "wx/strvararg.h" #include "wx/strvararg.h"
#include "wx/string.h"
// ----------------------------------------------------------------------------
// CRT functions aliases
// ----------------------------------------------------------------------------
/* Required for wxPrintf() etc */ /* Required for wxPrintf() etc */
#include <stdarg.h> #include <stdarg.h>
#ifdef wxHAVE_TCHAR_SUPPORT #ifdef wxHAVE_TCHAR_SUPPORT
WX_DEFINE_VARARG_FUNC(int, wxFprintf, _ftprintf) #define wxCRT_Fprintf _ftprintf
WX_DEFINE_VARARG_FUNC(int, wxPrintf, _tprintf) #define wxCRT_Printf _tprintf
#define wxPutc(c,f) _puttc(WXWCHAR_T_CAST(c),f) #define wxCRT_Scanf _tscanf
#define wxPutchar _puttchar
#define wxPuts _putts
#define wxScanf _tscanf /* FIXME-UTF8: not wrapped */
#if defined(__DMC__)
#if wxUSE_UNICODE
/* Digital Mars adds count to _stprintf (C99) so prototype conversion see wxchar.cpp */
int wxDoSprintf (wchar_t * __RESTRICT s, const wchar_t * __RESTRICT format, ... ) ;
WX_DEFINE_VARARG_FUNC(int, wxSprintf, wxDoSprintf)
#else
/* and there is a bug in D Mars tchar.h prior to 8.39.4n, so define
as sprintf */
WX_DEFINE_VARARG_FUNC(int, wxSprintf, sprintf)
#endif
#else
WX_DEFINE_VARARG_FUNC(int, wxSprintf, _stprintf)
#endif
/* FIXME-UTF8: not wrapped */ #define wxCRT_Sscanf _stscanf
#define wxSscanf _stscanf #define wxCRT_Vfprintf _vftprintf
#define wxVfprintf _vftprintf #define wxCRT_Vprintf _vtprintf
#define wxVprintf _vtprintf #define wxCRT_Vsscanf _vstscanf
#define wxVsscanf _vstscanf #define wxCRT_Vsprintf _vstprintf
#define wxVsprintf _vstprintf
#else /* !TCHAR-aware compilers */ #else /* !TCHAR-aware compilers */
#if !wxUSE_UNICODE /* ASCII */ #if !wxUSE_UNICODE /* ASCII */
WX_DEFINE_VARARG_FUNC(int, wxFprintf, fprintf) #define wxCRT_Fprintf fprintf
#define wxFscanf fscanf #define wxCRT_Fscanf fscanf
WX_DEFINE_VARARG_FUNC(int, wxPrintf, printf) #define wxCRT_Printf printf
#define wxScanf scanf #define wxCRT_Scanf scanf
WX_DEFINE_VARARG_FUNC(int, wxSprintf, sprintf) #define wxCRT_Sscanf sscanf
#define wxSscanf sscanf #define wxCRT_Vfprintf vfprintf
#define wxVfprintf vfprintf #define wxCRT_Vprintf vprintf
#define wxVprintf vprintf #define wxCRT_Vsscanf vsscanf
#define wxVsscanf vsscanf #define wxCRT_Vsprintf vsprintf
#define wxVsprintf vsprintf
#endif /* ASCII */ #endif /* ASCII */
#endif /* TCHAR-aware compilers/the others */ #endif /* TCHAR-aware compilers/the others */
@@ -156,9 +143,7 @@
#ifndef wxVsnprintf_ #ifndef wxVsnprintf_
#if defined(__VISUALC__) || \ #if defined(__VISUALC__) || \
(defined(__BORLANDC__) && __BORLANDC__ >= 0x540) (defined(__BORLANDC__) && __BORLANDC__ >= 0x540)
#define wxSnprintf_ _sntprintf
#define wxVsnprintf_ _vsntprintf #define wxVsnprintf_ _vsntprintf
WX_DEFINE_VARARG_FUNC(int, wxSnprintf_, _sntprintf)
#endif #endif
#endif #endif
@@ -171,19 +156,12 @@
#define wxVsnprintf_ vswprintf #define wxVsnprintf_ vswprintf
#elif defined(__WATCOMC__) #elif defined(__WATCOMC__)
#define wxVsnprintf_ _vsnwprintf #define wxVsnprintf_ _vsnwprintf
WX_DEFINE_VARARG_FUNC(int, wxSnprintf_, _snwprintf)
#endif #endif
#else /* ASCII */ #else /* ASCII */
/* /*
All versions of CodeWarrior supported by wxWidgets apparently All versions of CodeWarrior supported by wxWidgets apparently
have both snprintf() and vsnprintf() have both snprintf() and vsnprintf()
*/ */
#if defined(HAVE_SNPRINTF) \
|| defined(__MWERKS__) || defined(__WATCOMC__)
#ifndef HAVE_BROKEN_SNPRINTF_DECL
WX_DEFINE_VARARG_FUNC(int, wxSnprintf_, snprintf)
#endif
#endif
#if defined(HAVE_VSNPRINTF) \ #if defined(HAVE_VSNPRINTF) \
|| defined(__MWERKS__) || defined(__WATCOMC__) || defined(__MWERKS__) || defined(__WATCOMC__)
#ifdef HAVE_BROKEN_VSNPRINTF_DECL #ifdef HAVE_BROKEN_VSNPRINTF_DECL
@@ -196,18 +174,10 @@
#endif /* wxVsnprintf_ */ #endif /* wxVsnprintf_ */
#endif /* wxUSE_PRINTF_POS_PARAMS/!wxUSE_PRINTF_POS_PARAMS */ #endif /* wxUSE_PRINTF_POS_PARAMS/!wxUSE_PRINTF_POS_PARAMS */
#ifndef wxSnprintf_
/* no snprintf(), cook our own */
WXDLLIMPEXP_BASE int
wxDoSnprintf_(wxChar *buf, size_t len,
const wxChar *format, ...) ATTRIBUTE_PRINTF_3;
WX_DEFINE_VARARG_FUNC(int, wxSnprintf_, wxDoSnprintf_)
#endif
#ifndef wxVsnprintf_ #ifndef wxVsnprintf_
/* no (suitable) vsnprintf(), cook our own */ /* no (suitable) vsnprintf(), cook our own */
WXDLLIMPEXP_BASE int WXDLLIMPEXP_BASE int
wxVsnprintf_(wxChar *buf, size_t len, wxVsnprintf_(wxChar *buf, size_t len, const wxChar *format, va_list argptr);
const wxChar *format, va_list argptr);
#define wxUSE_WXVSNPRINTF 1 #define wxUSE_WXVSNPRINTF 1
#else #else
@@ -242,28 +212,15 @@
either because we don't have them at all or because they don't have the either because we don't have them at all or because they don't have the
semantics we need semantics we need
*/ */
WX_DEFINE_VARARG_FUNC(int, wxScanf, wxDoScanf) int wxCRT_Scanf( const wxChar *format, ... ) ATTRIBUTE_PRINTF_1;
int wxDoScanf( const wxChar *format, ... ) ATTRIBUTE_PRINTF_1; int wxCRT_Sscanf( const wxChar *str, const wxChar *format, ... ) ATTRIBUTE_PRINTF_2;
int wxCRT_Fscanf( FILE *stream, const wxChar *format, ... ) ATTRIBUTE_PRINTF_2;
WX_DEFINE_VARARG_FUNC(int, wxSscanf, wxDoSscanf) int wxCRT_Vsscanf( const wxChar *str, const wxChar *format, va_list ap );
int wxDoSscanf( const wxChar *str, const wxChar *format, ... ) ATTRIBUTE_PRINTF_2; int wxCRT_Printf( const wxChar *format, ... ) ATTRIBUTE_PRINTF_1;
int wxCRT_Fprintf( FILE *stream, const wxChar *format, ... ) ATTRIBUTE_PRINTF_2;
WX_DEFINE_VARARG_FUNC(int, wxFscanf, wxDoFscanf) int wxCRT_Vfprintf( FILE *stream, const wxChar *format, va_list ap );
int wxDoFscanf( FILE *stream, const wxChar *format, ... ) ATTRIBUTE_PRINTF_2; int wxCRT_Vprintf( const wxChar *format, va_list ap );
int wxCRT_Vsprintf( wxChar *str, const wxChar *format, va_list ap );
WX_DEFINE_VARARG_FUNC(int, wxPrintf, wxDoPrintf)
int wxDoPrintf( const wxChar *format, ... ) ATTRIBUTE_PRINTF_1;
WX_DEFINE_VARARG_FUNC(int, wxSprintf, wxDoSprintf)
int wxDoSprintf( wxChar *str, const wxChar *format, ... ) ATTRIBUTE_PRINTF_2;
WX_DEFINE_VARARG_FUNC(int, wxFprintf, wxDoFprintf)
int wxDoFprintf( FILE *stream, const wxChar *format, ... ) ATTRIBUTE_PRINTF_2;
int wxVsscanf( const wxChar *str, const wxChar *format, va_list ap );
int wxVfprintf( FILE *stream, const wxChar *format, va_list ap );
int wxVprintf( const wxChar *format, va_list ap );
int wxVsprintf( wxChar *str, const wxChar *format, va_list ap );
#endif /* wxNEED_PRINTF_CONVERSION */ #endif /* wxNEED_PRINTF_CONVERSION */
/* these 2 can be simply mapped to the versions with underscore at the end */ /* these 2 can be simply mapped to the versions with underscore at the end */
@@ -273,12 +230,136 @@
anything as our own wxVsnprintf_() already behaves as needed. anything as our own wxVsnprintf_() already behaves as needed.
*/ */
#if defined(wxNEED_PRINTF_CONVERSION) && defined(wxVsnprintf_) #if defined(wxNEED_PRINTF_CONVERSION) && defined(wxVsnprintf_)
WX_DEFINE_VARARG_FUNC(int, wxSnprintf, wxDoSnprintf) int wxCRT_Vsnprintf( wxChar *str, size_t size, const wxChar *format, va_list ap );
int wxDoSnprintf( wxChar *str, size_t size, const wxChar *format, ... ) ATTRIBUTE_PRINTF_3;
int wxVsnprintf( wxChar *str, size_t size, const wxChar *format, va_list ap );
#else #else
#define wxSnprintf wxSnprintf_ #define wxCRT_Vsnprintf wxVsnprintf_
#define wxVsnprintf wxVsnprintf_
#endif #endif
// ----------------------------------------------------------------------------
// user-friendly wrappers to CRT functions
// ----------------------------------------------------------------------------
#ifdef __WATCOMC__
// workaround for http://bugzilla.openwatcom.org/show_bug.cgi?id=351
#define wxPrintf wxPrintf_Impl
#define wxFprintf wxFprintf_Impl
#define wxSprintf wxSprintf_Impl
#define wxSnprintf wxSnprintf_Impl
#endif
// FIXME-UTF8: explicit wide-string and short-string format specifiers
// (%hs, %ls and variants) are currently broken, only %s works
// as expected (regardless of the build)
// FIXME-UTF8: %c (and %hc, %lc) don't work as expected either: in UTF-8 build,
// we should replace them with %s (as some Unicode chars may be
// encoded with >1 bytes) and in all builds, we should use wchar_t
// for all characters and convert char to it;
// we'll also need wxArgNormalizer<T> specializations for char,
// wchar_t, wxUniChar and wxUniCharRef to handle this correctly
WX_DEFINE_VARARG_FUNC2(int, wxPrintf, 1, (const wxString&),
wxCRT_Printf, printf)
WX_DEFINE_VARARG_FUNC2(int, wxFprintf, 2, (FILE*, const wxString&),
wxCRT_Fprintf, fprintf)
// va_list versions of printf functions simply forward to the respective
// CRT function; note that they assume that va_list was created using
// wxArgNormalizer<T>!
#if wxUSE_UNICODE_UTF8
#if wxUSE_UTF8_LOCALE_ONLY
#define WX_VARARG_VFOO_IMPL(args, implWchar, implUtf8) \
return implUtf8 args
#else
#define WX_VARARG_VFOO_IMPL(args, implWchar, implUtf8) \
if ( wxLocaleIsUtf8 ) return implUtf8 args; \
else return implWchar args
#endif
#else // wxUSE_UNICODE_WCHAR / ANSI
#define WX_VARARG_VFOO_IMPL(args, implWchar, implUtf8) \
return implWchar args
#endif
inline int
wxVprintf(const wxString& format, va_list ap)
{
WX_VARARG_VFOO_IMPL((format, ap), wxCRT_Vprintf, vprintf);
}
inline int
wxVfprintf(FILE *f, const wxString& format, va_list ap)
{
WX_VARARG_VFOO_IMPL((f, format, ap), wxCRT_Vfprintf, vfprintf);
}
#undef WX_VARARG_VFOO_IMPL
// wxSprintf() and friends have to be implemented in two forms, one for
// writing to char* buffer and one for writing to wchar_t*:
int WXDLLIMPEXP_BASE wxDoSprintf(char *str, const wxString& format, ...);
WX_DEFINE_VARARG_FUNC(int, wxSprintf, 2, (char*, const wxString&),
wxDoSprintf)
int WXDLLIMPEXP_BASE
wxVsprintf(char *str, const wxString& format, va_list argptr);
int WXDLLIMPEXP_BASE wxDoSnprintf(char *str, size_t size, const wxString& format, ...);
WX_DEFINE_VARARG_FUNC(int, wxSnprintf, 3, (char*, size_t, const wxString&),
wxDoSnprintf)
int WXDLLIMPEXP_BASE
wxVsnprintf(char *str, size_t size, const wxString& format, va_list argptr);
#if wxUSE_UNICODE
int WXDLLIMPEXP_BASE wxDoSprintf(wchar_t *str, const wxString& format, ...);
WX_DEFINE_VARARG_FUNC(int, wxSprintf, 2, (wchar_t*, const wxString&),
wxDoSprintf)
int WXDLLIMPEXP_BASE
wxVsprintf(wchar_t *str, const wxString& format, va_list argptr);
int WXDLLIMPEXP_BASE wxDoSnprintf(wchar_t *str, size_t size, const wxString& format, ...);
WX_DEFINE_VARARG_FUNC(int, wxSnprintf, 3, (wchar_t*, size_t, const wxString&),
wxDoSnprintf)
int WXDLLIMPEXP_BASE
wxVsnprintf(wchar_t *str, size_t size, const wxString& format, va_list argptr);
#endif // wxUSE_UNICODE
#ifdef __WATCOMC__
// workaround for http://bugzilla.openwatcom.org/show_bug.cgi?id=351
//
// fortunately, OpenWatcom implements __VA_ARGS__, so we can provide macros
// that cast the format argument to wxString:
#undef wxPrintf
#undef wxFprintf
#undef wxSprintf
#undef wxSnprintf
#define wxPrintf(fmt, ...) \
wxPrintf_Impl(wxString(fmt), __VA_ARGS__)
#define wxFprintf(f, fmt, ...) \
wxFprintf_Impl(f, wxString(fmt), __VA_ARGS__)
#define wxSprintf(s, fmt, ...) \
wxSprintf_Impl(s, wxString(fmt), __VA_ARGS__)
#define wxSnprintf(s, n, fmt, ...) \
wxSnprintf_Impl(s, n, wxString(fmt), __VA_ARGS__)
#endif // __WATCOMC__
// We can't use wxArgNormalizer<T> for variadic arguments to wxScanf() etc.
// because they are writable, so instead of providing friendly template
// vararg-like functions, we just provide both char* and wchar_t* variants
// of these functions. The type of output variadic arguments for %s must match
// the type of 'str' and 'format' arguments.
// FIXME-UTF8: actually do it, for now we only have wxChar* variants:
#define wxScanf wxCRT_Scanf
#define wxFscanf wxCRT_Fscanf
#define wxSscanf wxCRT_Sscanf
#define wxVsscanf wxCRT_Vsscanf
#endif /* _WX_WXCRTVARARG_H_ */ #endif /* _WX_WXCRTVARARG_H_ */

View File

@@ -69,27 +69,27 @@ wxString wxFileSystemHandler::GetMimeTypeFromExt(const wxString& location)
wxEmptyString, wxEmptyString,
wxEmptyString, wxEmptyString,
_T("JPEG image (from fallback)"), _T("JPEG image (from fallback)"),
_T("jpg"), _T("jpeg"), _T("JPG"), _T("JPEG"), NULL), _T("jpg"), _T("jpeg"), _T("JPG"), _T("JPEG"), 0),
wxFileTypeInfo(_T("image/gif"), wxFileTypeInfo(_T("image/gif"),
wxEmptyString, wxEmptyString,
wxEmptyString, wxEmptyString,
_T("GIF image (from fallback)"), _T("GIF image (from fallback)"),
_T("gif"), _T("GIF"), NULL), _T("gif"), _T("GIF"), 0),
wxFileTypeInfo(_T("image/png"), wxFileTypeInfo(_T("image/png"),
wxEmptyString, wxEmptyString,
wxEmptyString, wxEmptyString,
_T("PNG image (from fallback)"), _T("PNG image (from fallback)"),
_T("png"), _T("PNG"), NULL), _T("png"), _T("PNG"), 0),
wxFileTypeInfo(_T("image/bmp"), wxFileTypeInfo(_T("image/bmp"),
wxEmptyString, wxEmptyString,
wxEmptyString, wxEmptyString,
_T("windows bitmap image (from fallback)"), _T("windows bitmap image (from fallback)"),
_T("bmp"), _T("BMP"), NULL), _T("bmp"), _T("BMP"), 0),
wxFileTypeInfo(_T("text/html"), wxFileTypeInfo(_T("text/html"),
wxEmptyString, wxEmptyString,
wxEmptyString, wxEmptyString,
_T("HTML document (from fallback)"), _T("HTML document (from fallback)"),
_T("htm"), _T("html"), _T("HTM"), _T("HTML"), NULL), _T("htm"), _T("html"), _T("HTM"), _T("HTML"), 0),
// must terminate the table with this! // must terminate the table with this!
wxFileTypeInfo() wxFileTypeInfo()
}; };

View File

@@ -31,6 +31,7 @@
#include "wx/log.h" #include "wx/log.h"
#include "wx/intl.h" #include "wx/intl.h"
#include "wx/module.h" #include "wx/module.h"
#include "wx/wxcrtvararg.h"
#endif //WX_PRECOMP #endif //WX_PRECOMP
#if defined(__WXMSW__) #if defined(__WXMSW__)

View File

@@ -38,6 +38,7 @@
#include "wx/utils.h" #include "wx/utils.h"
#include "wx/log.h" #include "wx/log.h"
#include "wx/intl.h" #include "wx/intl.h"
#include "wx/wxcrtvararg.h"
#endif // WX_PRECOMP #endif // WX_PRECOMP
#include "wx/sckaddr.h" #include "wx/sckaddr.h"

View File

@@ -141,7 +141,7 @@ wxString wxHTTP::GenerateAuthString(const wxString& user, const wxString& pass)
} else { } else {
buf << wxString::Format(wxT("%c%c"), base64[((from[0] << 4) & 0x30) | ((from[1] >> 4) & 0xf)], base64[(from[1] << 2) & 0x3c]); buf << wxString::Format(wxT("%c%c"), base64[((from[0] << 4) & 0x30) | ((from[1] >> 4) & 0xf)], base64[(from[1] << 2) & 0x3c]);
} }
buf << wxString::Format(wxT("=")); buf << wxT("=");
} }
return buf; return buf;

View File

@@ -91,11 +91,11 @@ void wxVLogGeneric(wxLogLevel level, const wxString& format, va_list argptr)
} }
} }
void wxDoLogGeneric(wxLogLevel level, const wxChar *szFormat, ...) void wxDoLogGeneric(wxLogLevel level, const wxString& format, ...)
{ {
va_list argptr; va_list argptr;
va_start(argptr, szFormat); va_start(argptr, format);
wxVLogGeneric(level, szFormat, argptr); wxVLogGeneric(level, format, argptr);
va_end(argptr); va_end(argptr);
} }
@@ -108,11 +108,11 @@ void wxDoLogGeneric(wxLogLevel level, const wxChar *szFormat, ...)
} \ } \
} \ } \
\ \
void wxDoLog##level(const wxChar *szFormat, ...) \ void wxDoLog##level(const wxString& format, ...) \
{ \ { \
va_list argptr; \ va_list argptr; \
va_start(argptr, szFormat); \ va_start(argptr, format); \
wxVLog##level(szFormat, argptr); \ wxVLog##level(format, argptr); \
va_end(argptr); \ va_end(argptr); \
} }
@@ -145,11 +145,11 @@ void wxVLogFatalError(const wxString& format, va_list argptr)
#endif #endif
} }
void wxDoLogFatalError(const wxChar *szFormat, ...) void wxDoLogFatalError(const wxString& format, ...)
{ {
va_list argptr; va_list argptr;
va_start(argptr, szFormat); va_start(argptr, format);
wxVLogFatalError(szFormat, argptr); wxVLogFatalError(format, argptr);
// some compilers warn about unreachable code and it shouldn't matter // some compilers warn about unreachable code and it shouldn't matter
// for the others anyhow... // for the others anyhow...
@@ -167,30 +167,30 @@ void wxVLogVerbose(const wxString& format, va_list argptr)
} }
} }
void wxDoLogVerbose(const wxChar *szFormat, ...) void wxDoLogVerbose(const wxString& format, ...)
{ {
va_list argptr; va_list argptr;
va_start(argptr, szFormat); va_start(argptr, format);
wxVLogVerbose(szFormat, argptr); wxVLogVerbose(format, argptr);
va_end(argptr); va_end(argptr);
} }
// debug functions // debug functions
#ifdef __WXDEBUG__ #ifdef __WXDEBUG__
#define IMPLEMENT_LOG_DEBUG_FUNCTION(level) \ #define IMPLEMENT_LOG_DEBUG_FUNCTION(level) \
void wxVLog##level(const wxChar *szFormat, va_list argptr) \ void wxVLog##level(const wxString& format, va_list argptr) \
{ \ { \
if ( wxLog::IsEnabled() ) { \ if ( wxLog::IsEnabled() ) { \
wxLog::OnLog(wxLOG_##level, \ wxLog::OnLog(wxLOG_##level, \
wxString::FormatV(szFormat, argptr), time(NULL));\ wxString::FormatV(format, argptr), time(NULL)); \
} \ } \
} \ } \
\ \
void wxDoLog##level(const wxChar *szFormat, ...) \ void wxDoLog##level(const wxString& format, ...) \
{ \ { \
va_list argptr; \ va_list argptr; \
va_start(argptr, szFormat); \ va_start(argptr, format); \
wxVLog##level(szFormat, argptr); \ wxVLog##level(format, argptr); \
va_end(argptr); \ va_end(argptr); \
} }
@@ -204,11 +204,11 @@ void wxDoLogVerbose(const wxChar *szFormat, ...)
} }
} }
void wxDoLogTrace(const wxString& mask, const wxChar *szFormat, ...) void wxDoLogTrace(const wxString& mask, const wxString& format, ...)
{ {
va_list argptr; va_list argptr;
va_start(argptr, szFormat); va_start(argptr, format);
wxVLogTrace(mask, szFormat, argptr); wxVLogTrace(mask, format, argptr);
va_end(argptr); va_end(argptr);
} }
@@ -222,14 +222,48 @@ void wxDoLogVerbose(const wxChar *szFormat, ...)
} }
} }
void wxDoLogTrace(wxTraceMask mask, const wxChar *szFormat, ...) void wxDoLogTrace(wxTraceMask mask, const wxString& format, ...)
{ {
va_list argptr; va_list argptr;
va_start(argptr, szFormat); va_start(argptr, format);
wxVLogTrace(mask, szFormat, argptr); wxVLogTrace(mask, format, argptr);
va_end(argptr); va_end(argptr);
} }
#ifdef __WATCOMC__
// workaround for http://bugzilla.openwatcom.org/show_bug.cgi?id=351
void wxDoLogTrace(int mask, const wxString& format, ...)
{
va_list argptr;
va_start(argptr, format);
wxVLogTrace(mask, format, argptr);
va_end(argptr);
}
void wxDoLogTrace(const char *mask, const wxString& format, ...)
{
va_list argptr;
va_start(argptr, format);
wxVLogTrace(mask, format, argptr);
va_end(argptr);
}
void wxDoLogTrace(const wchar_t *mask, const wxString& format, ...)
{
va_list argptr;
va_start(argptr, format);
wxVLogTrace(mask, format, argptr);
va_end(argptr);
}
void wxVLogTrace(int mask, const wxString& format, va_list argptr)
{ wxVLogTrace((wxTraceMask)mask, format, argptr); }
void wxVLogTrace(const char *mask, const wxString& format, va_list argptr)
{ wxVLogTrace(wxString(mask), format, argptr); }
void wxVLogTrace(const wchar_t *mask, const wxString& format, va_list argptr)
{ wxVLogTrace(wxString(mask), format, argptr); }
#endif // __WATCOMC__
#else // release #else // release
#define IMPLEMENT_LOG_DEBUG_FUNCTION(level) #define IMPLEMENT_LOG_DEBUG_FUNCTION(level)
#endif #endif
@@ -251,11 +285,11 @@ void WXDLLEXPORT wxVLogSysError(const wxString& format, va_list argptr)
wxVLogSysError(wxSysErrorCode(), format, argptr); wxVLogSysError(wxSysErrorCode(), format, argptr);
} }
void WXDLLEXPORT wxDoLogSysError(const wxChar *szFormat, ...) void WXDLLEXPORT wxDoLogSysError(const wxString& format, ...)
{ {
va_list argptr; va_list argptr;
va_start(argptr, szFormat); va_start(argptr, format);
wxVLogSysError(szFormat, argptr); wxVLogSysError(format, argptr);
va_end(argptr); va_end(argptr);
} }
@@ -268,14 +302,28 @@ void WXDLLEXPORT wxVLogSysError(long err, const wxString& format, va_list argptr
} }
} }
void WXDLLEXPORT wxDoLogSysError(long lErrCode, const wxChar *szFormat, ...) void WXDLLEXPORT wxDoLogSysError(long lErrCode, const wxString& format, ...)
{ {
va_list argptr; va_list argptr;
va_start(argptr, szFormat); va_start(argptr, format);
wxVLogSysError(lErrCode, szFormat, argptr); wxVLogSysError(lErrCode, format, argptr);
va_end(argptr); va_end(argptr);
} }
#ifdef __WATCOMC__
// workaround for http://bugzilla.openwatcom.org/show_bug.cgi?id=351
void WXDLLEXPORT wxDoLogSysError(unsigned long lErrCode, const wxString& format, ...)
{
va_list argptr;
va_start(argptr, format);
wxVLogSysError(lErrCode, format, argptr);
va_end(argptr);
}
void WXDLLEXPORT wxVLogSysError(unsigned long err, const wxString& format, va_list argptr)
{ wxVLogSysError((long)err, format, argptr); }
#endif // __WATCOMC__
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// wxLog class implementation // wxLog class implementation
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------

View File

@@ -111,19 +111,20 @@ wxString wxMimeTypeCommands::GetVerbCmd(size_t n) const
// wxFileTypeInfo // wxFileTypeInfo
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
wxFileTypeInfo::wxFileTypeInfo(const wxChar *mimeType, void wxFileTypeInfo::VarArgInit(const wxString& mimeType,
const wxChar *openCmd, const wxString& openCmd,
const wxChar *printCmd, const wxString& printCmd,
const wxChar *desc, const wxString& desc,
...) ...)
: m_mimeType(mimeType),
m_openCmd(openCmd),
m_printCmd(printCmd),
m_desc(desc)
{ {
va_list argptr; va_list argptr;
va_start(argptr, desc); va_start(argptr, desc);
m_mimeType = mimeType;
m_openCmd = openCmd;
m_printCmd = printCmd;
m_desc = desc;
for ( ;; ) for ( ;; )
{ {
// icc gives this warning in its own va_arg() macro, argh // icc gives this warning in its own va_arg() macro, argh
@@ -132,7 +133,7 @@ wxFileTypeInfo::wxFileTypeInfo(const wxChar *mimeType,
#pragma warning(disable: 1684) #pragma warning(disable: 1684)
#endif #endif
const wxChar *ext = va_arg(argptr, const wxChar *); wxArgNormalizedString ext(WX_VA_ARG_STRING(argptr));
#ifdef __INTELC__ #ifdef __INTELC__
#pragma warning(pop) #pragma warning(pop)
@@ -143,7 +144,7 @@ wxFileTypeInfo::wxFileTypeInfo(const wxChar *mimeType,
break; break;
} }
m_exts.Add(ext); m_exts.Add(ext.GetString());
} }
va_end(argptr); va_end(argptr);

View File

@@ -76,7 +76,7 @@ wxMessageOutput* wxMessageOutput::Set(wxMessageOutput* msgout)
return old; return old;
} }
void wxMessageOutput::DoPrintf(const wxChar* format, ...) void wxMessageOutput::DoPrintf(const wxString& format, ...)
{ {
va_list args; va_list args;
va_start(args, format); va_start(args, format);

View File

@@ -23,6 +23,7 @@
#ifndef WX_PRECOMP #ifndef WX_PRECOMP
#include "wx/string.h" #include "wx/string.h"
#include "wx/wxcrtvararg.h"
#endif #endif
#include <ctype.h> #include <ctype.h>
@@ -1442,9 +1443,9 @@ bool wxString::ToDouble(double *val) const
/* static */ /* static */
#ifdef wxNEEDS_WXSTRING_PRINTF_MIXIN #ifdef wxNEEDS_WXSTRING_PRINTF_MIXIN
wxString wxStringPrintfMixinBase::DoFormat(const wxChar *format, ...) wxString wxStringPrintfMixinBase::DoFormat(const wxString& format, ...)
#else #else
wxString wxString::DoFormat(const wxChar *format, ...) wxString wxString::DoFormat(const wxString& format, ...)
#endif #endif
{ {
va_list argptr; va_list argptr;
@@ -1467,9 +1468,9 @@ wxString wxString::FormatV(const wxString& format, va_list argptr)
} }
#ifdef wxNEEDS_WXSTRING_PRINTF_MIXIN #ifdef wxNEEDS_WXSTRING_PRINTF_MIXIN
int wxStringPrintfMixinBase::DoPrintf(const wxChar *format, ...) int wxStringPrintfMixinBase::DoPrintf(const wxString& format, ...)
#else #else
int wxString::DoPrintf(const wxChar *format, ...) int wxString::DoPrintf(const wxString& format, ...)
#endif #endif
{ {
va_list argptr; va_list argptr;
@@ -1491,14 +1492,27 @@ int wxString::DoPrintf(const wxChar *format, ...)
return iLen; return iLen;
} }
int wxString::PrintfV(const wxString& format, va_list argptr) #if wxUSE_UNICODE_UTF8
template<typename BufferType>
#else
// we only need one version in non-UTF8 builds and at least two Windows
// compilers have problems with this function template, so use just one
// normal function here
#endif
static int DoStringPrintfV(wxString& str,
const wxString& format, va_list argptr)
{ {
int size = 1024; int size = 1024;
for ( ;; ) for ( ;; )
{ {
wxStringBuffer tmp(*this, size + 1); #if wxUSE_UNICODE_UTF8
BufferType tmp(str, size + 1);
typename BufferType::CharType *buf = tmp;
#else
wxStringBuffer tmp(str, size + 1);
wxChar *buf = tmp; wxChar *buf = tmp;
#endif
if ( !buf ) if ( !buf )
{ {
@@ -1510,7 +1524,7 @@ int wxString::PrintfV(const wxString& format, va_list argptr)
// only a copy // only a copy
va_list argptrcopy; va_list argptrcopy;
wxVaCopy(argptrcopy, argptr); wxVaCopy(argptrcopy, argptr);
int len = wxVsnprintf(buf, size, (const wxChar*)/*FIXME-UTF8*/format, argptrcopy); int len = wxVsnprintf(buf, size, format, argptrcopy);
va_end(argptrcopy); va_end(argptrcopy);
// some implementations of vsnprintf() don't NUL terminate // some implementations of vsnprintf() don't NUL terminate
@@ -1554,9 +1568,37 @@ int wxString::PrintfV(const wxString& format, va_list argptr)
} }
// we could have overshot // we could have overshot
Shrink(); str.Shrink();
return length(); return str.length();
}
int wxString::PrintfV(const wxString& format, va_list argptr)
{
va_list argcopy;
wxVaCopy(argcopy, argptr);
#if wxUSE_UNICODE_UTF8
#if wxUSE_STL_BASED_WXSTRING
typedef wxStringTypeBuffer<char> Utf8Buffer;
#else
typedef wxImplStringBuffer Utf8Buffer;
#endif
#endif
#if wxUSE_UTF8_LOCALE_ONLY
return DoStringPrintfV<Utf8Buffer>(*this, format, argcopy);
#else
#if wxUSE_UNICODE_UTF8
if ( wxLocaleIsUtf8 )
return DoStringPrintfV<Utf8Buffer>(*this, format, argcopy);
else
// wxChar* version
return DoStringPrintfV<wxStringBuffer>(*this, format, argcopy);
#else
return DoStringPrintfV(*this, format, argcopy);
#endif // UTF8/WCHAR
#endif
} }
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------

View File

@@ -752,7 +752,6 @@ bool wxStringImpl::ConcatSelf(size_t nSrcLen,
return true; return true;
} }
#if !wxUSE_UNICODE_UTF8
// get the pointer to writable buffer of (at least) nLen bytes // get the pointer to writable buffer of (at least) nLen bytes
wxStringCharType *wxStringImpl::DoGetWriteBuf(size_t nLen) wxStringCharType *wxStringImpl::DoGetWriteBuf(size_t nLen)
{ {
@@ -784,6 +783,5 @@ void wxStringImpl::DoUngetWriteBuf(size_t nLen)
pData->nDataLength = nLen; pData->nDataLength = nLen;
pData->Validate(true); pData->Validate(true);
} }
#endif // !wxUSE_UNICODE_UTF8
#endif // !wxUSE_STL_BASED_WXSTRING #endif // !wxUSE_STL_BASED_WXSTRING

View File

@@ -24,116 +24,53 @@
#endif #endif
#include "wx/strvararg.h" #include "wx/strvararg.h"
#include "wx/buffer.h"
#include "wx/strconv.h"
#include "wx/string.h" #include "wx/string.h"
// ============================================================================ // ============================================================================
// implementation // implementation
// ============================================================================ // ============================================================================
const wxChar *wxArgNormalizer<const wxCStrData&>::get() const
{
// FIXME-UTF8: use some way that doesn't involve implicit conversion,
// so that we deallocate any converted buffer immediately;
// can't use AsString() because it returns wxString and not
// const wxString&, unfortunately; use As[W]CharBuf() when
// available.
return m_value;
}
const wxChar *wxArgNormalizer<const wxString&>::get() const const wxStringCharType *wxArgNormalizerNative<const wxString&>::get() const
{ {
#if wxUSE_UNICODE_UTF8 // FIXME-UTF8
return (const wxChar*)m_value;
#else
return m_value.wx_str(); return m_value.wx_str();
#endif
} }
#if wxUSE_UNICODE // FIXME-UTF8: should be wxUSE_UNICODE_WCHAR const wxStringCharType *wxArgNormalizerNative<const wxCStrData&>::get() const
wxArgNormalizer<const char*>::wxArgNormalizer(const char *value)
{ {
// FIXME-UTF8: move this to the header so that m_value doesn't have return m_value.AsInternal();
// to be dynamically allocated
m_value = new wxWCharBuffer(wxConvLibc.cMB2WC(value));
} }
wxArgNormalizer<const char*>::~wxArgNormalizer() #if wxUSE_UNICODE_UTF8
wxArgNormalizerWchar<const wxString&>::wxArgNormalizerWchar(const wxString& s)
: wxArgNormalizerWithBuffer<wchar_t>(s.wc_str())
{ {
delete m_value;
} }
const wchar_t *wxArgNormalizer<const char*>::get() const wxArgNormalizerWchar<const wxCStrData&>::wxArgNormalizerWchar(const wxCStrData& s)
: wxArgNormalizerWithBuffer<wchar_t>(s.AsWCharBuf())
{ {
return m_value->data();
}
#endif // wxUSE_UNICODE_WCHAR
#if /*wxUSE_UNICODE_UTF8 ||*/ !wxUSE_UNICODE // FIXME-UTF8
wxArgNormalizer<const wchar_t*>::wxArgNormalizer(const wchar_t *value)
{
#if wxUSE_UNICODE_UTF8 // FIXME-UTF8: this will be the only case
m_value = new wxCharBuffer(wxConvUTF8.cWC2MB(value));
#else
m_value = new wxCharBuffer(wxConvLibc.cWC2MB(value));
#endif
}
wxArgNormalizer<const wchar_t*>::~wxArgNormalizer()
{
delete m_value;
}
const char *wxArgNormalizer<const wchar_t*>::get() const
{
return m_value->data();
}
#endif // wxUSE_UNICODE_UTF8 || !wxUSE_UNICODE
#if 0 // wxUSE_UNICODE_UTF8 - FIXME-UTF8
wxArgNormalizer<const char*>::wxArgNormalizer(const char *value)
{
// FIXME-UTF8: move this to the header so that m_value doesn't have
// to be dynamically allocated
// FIXME-UTF8: optimize this if current locale is UTF-8 one
// convert to widechar string first:
wxWCharBuffer buf(wxConvLibc.cMB2WC(value));
if ( buf )
{
// then to UTF-8:
m_value = new wxCharBuffer(wxConvUTF8.cWC2MB(value));
}
else
{
m_value = new wxCharBuffer();
}
}
wxArgNormalizer<const char*>::~wxArgNormalizer()
{
delete m_value;
}
const char *wxArgNormalizer<const char*>::get() const
{
return m_value->data();
} }
#endif // wxUSE_UNICODE_UTF8 #endif // wxUSE_UNICODE_UTF8
wxString wxArgNormalizedString::GetString() const
// FIXME-UTF8: move this to the header once it's possible to include buffer.h
// without including wxcrt.h
wxArgNormalizer<wxCharBuffer>::wxArgNormalizer(const wxCharBuffer& buf)
: wxArgNormalizer<const char*>(buf.data())
{ {
if ( !IsValid() )
return wxEmptyString;
#if wxUSE_UTF8_LOCALE_ONLY
return wxString(wx_reinterpret_cast(const char*, m_ptr));
#else
#if wxUSE_UNICODE_UTF8
if ( wxLocaleIsUtf8 )
return wxString(wx_reinterpret_cast(const char*, m_ptr));
else
#endif
return wxString(wx_reinterpret_cast(const wchar_t*, m_ptr));
#endif // !wxUSE_UTF8_LOCALE_ONLY
} }
wxArgNormalizer<wxWCharBuffer>::wxArgNormalizer(const wxWCharBuffer& buf) wxArgNormalizedString::operator wxString() const
: wxArgNormalizer<const wchar_t*>(buf.data())
{ {
return GetString();
} }

View File

@@ -163,31 +163,16 @@ bool WXDLLEXPORT wxOKlibc()
#undef wxVsprintf #undef wxVsprintf
#undef wxVprintf #undef wxVprintf
#undef wxVsnprintf_ #undef wxVsnprintf_
#undef wxSnprintf_
#define wxNEED_WPRINTF #define wxNEED_WPRINTF
int wxVfprintf( FILE *stream, const wxChar *format, va_list argptr ); int wxVfprintf( FILE *stream, const wxChar *format, va_list argptr );
#endif #endif
#if !defined(wxSnprintf_)
int WXDLLEXPORT wxDoSnprintf_(wxChar *buf, size_t len, const wxChar *format, ...)
{
va_list argptr;
va_start(argptr, format);
int iLen = wxVsnprintf_(buf, len, format, argptr);
va_end(argptr);
return iLen;
}
#endif // wxSnprintf_
#if defined(__DMC__) #if defined(__DMC__)
/* Digital Mars adds count to _stprintf (C99) so convert */ /* Digital Mars adds count to _stprintf (C99) so convert */
#if wxUSE_UNICODE #if wxUSE_UNICODE
int wxDoSprintf (wchar_t * __RESTRICT s, const wchar_t * __RESTRICT format, ... ) int wxSprintf (wchar_t * __RESTRICT s, const wchar_t * __RESTRICT format, ... )
{ {
va_list arglist; va_list arglist;
@@ -527,7 +512,7 @@ wxString wxConvertFormat(const wxChar *format)
#if defined(wxNEED_PRINTF_CONVERSION) || defined(wxNEED_WPRINTF) #if defined(wxNEED_PRINTF_CONVERSION) || defined(wxNEED_WPRINTF)
int wxDoScanf( const wxChar *format, ... ) int wxCRT_Scanf( const wxChar *format, ... )
{ {
va_list argptr; va_list argptr;
va_start(argptr, format); va_start(argptr, format);
@@ -539,7 +524,7 @@ int wxDoScanf( const wxChar *format, ... )
return ret; return ret;
} }
int wxDoSscanf( const wxChar *str, const wxChar *format, ... ) int wxCRT_Sscanf( const wxChar *str, const wxChar *format, ... )
{ {
va_list argptr; va_list argptr;
va_start(argptr, format); va_start(argptr, format);
@@ -551,7 +536,7 @@ int wxDoSscanf( const wxChar *str, const wxChar *format, ... )
return ret; return ret;
} }
int wxDoFscanf( FILE *stream, const wxChar *format, ... ) int wxCRT_Fscanf( FILE *stream, const wxChar *format, ... )
{ {
va_list argptr; va_list argptr;
va_start(argptr, format); va_start(argptr, format);
@@ -562,7 +547,7 @@ int wxDoFscanf( FILE *stream, const wxChar *format, ... )
return ret; return ret;
} }
int wxDoPrintf( const wxChar *format, ... ) int wxCRT_Printf( const wxChar *format, ... )
{ {
va_list argptr; va_list argptr;
va_start(argptr, format); va_start(argptr, format);
@@ -574,40 +559,7 @@ int wxDoPrintf( const wxChar *format, ... )
return ret; return ret;
} }
#ifndef wxSnprintf int wxCRT_Fprintf( FILE *stream, const wxChar *format, ... )
int wxDoSnprintf( wxChar *str, size_t size, const wxChar *format, ... )
{
va_list argptr;
va_start(argptr, format);
int ret = vswprintf( str, size, wxFormatConverter(format), argptr );
// VsnprintfTestCase reveals that glibc's implementation of vswprintf
// doesn't nul terminate on truncation.
str[size - 1] = 0;
va_end(argptr);
return ret;
}
#endif // wxSnprintf
int wxDoSprintf( wxChar *str, const wxChar *format, ... )
{
va_list argptr;
va_start(argptr, format);
// note that wxString::FormatV() uses wxVsnprintf(), not wxSprintf(), so
// it's safe to implement this one in terms of it
wxString s(wxString::FormatV(format, argptr));
wxStrcpy(str, s);
va_end(argptr);
return s.length();
}
int wxDoFprintf( FILE *stream, const wxChar *format, ... )
{ {
va_list argptr; va_list argptr;
va_start( argptr, format ); va_start( argptr, format );
@@ -619,29 +571,29 @@ int wxDoFprintf( FILE *stream, const wxChar *format, ... )
return ret; return ret;
} }
int wxVsscanf( const wxChar *str, const wxChar *format, va_list argptr ) int wxCRT_Vsscanf( const wxChar *str, const wxChar *format, va_list argptr )
{ {
return vswscanf( str, wxFormatConverter(format), argptr ); return vswscanf( str, wxFormatConverter(format), argptr );
} }
int wxVfprintf( FILE *stream, const wxChar *format, va_list argptr ) int wxCRT_Vfprintf( FILE *stream, const wxChar *format, va_list argptr )
{ {
return vfwprintf( stream, wxFormatConverter(format), argptr ); return vfwprintf( stream, wxFormatConverter(format), argptr );
} }
int wxVprintf( const wxChar *format, va_list argptr ) int wxCRT_Vprintf( const wxChar *format, va_list argptr )
{ {
return vwprintf( wxFormatConverter(format), argptr ); return vwprintf( wxFormatConverter(format), argptr );
} }
#ifndef wxVsnprintf #ifndef wxCRT_Vsnprintf
int wxVsnprintf( wxChar *str, size_t size, const wxChar *format, va_list argptr ) int wxCRT_Vsnprintf( wxChar *str, size_t size, const wxChar *format, va_list argptr )
{ {
return vswprintf( str, size, wxFormatConverter(format), argptr ); return vswprintf( str, size, wxFormatConverter(format), argptr );
} }
#endif // wxVsnprintf #endif // wxCRT_Vsnprintf
int wxVsprintf( wxChar *str, const wxChar *format, va_list argptr ) int wxCRT_Vsprintf( wxChar *str, const wxChar *format, va_list argptr )
{ {
// same as for wxSprintf() // same as for wxSprintf()
return vswprintf(str, INT_MAX / 4, wxFormatConverter(format), argptr); return vswprintf(str, INT_MAX / 4, wxFormatConverter(format), argptr);
@@ -649,6 +601,206 @@ int wxVsprintf( wxChar *str, const wxChar *format, va_list argptr )
#endif // wxNEED_PRINTF_CONVERSION #endif // wxNEED_PRINTF_CONVERSION
// ----------------------------------------------------------------------------
// wrappers to printf and scanf function families
// ----------------------------------------------------------------------------
int wxDoSprintf(char *str, const wxString& format, ...)
{
va_list argptr;
va_start(argptr, format);
int rv = wxVsprintf(str, format, argptr);
va_end(argptr);
return rv;
}
#if wxUSE_UNICODE
int wxDoSprintf(wchar_t *str, const wxString& format, ...)
{
va_list argptr;
va_start(argptr, format);
int rv = wxVsprintf(str, format, argptr);
va_end(argptr);
return rv;
}
#endif
int wxDoSnprintf(char *str, size_t size, const wxString& format, ...)
{
va_list argptr;
va_start(argptr, format);
int rv = wxVsnprintf(str, size, format, argptr);
va_end(argptr);
return rv;
}
#if wxUSE_UNICODE
int wxDoSnprintf(wchar_t *str, size_t size, const wxString& format, ...)
{
va_list argptr;
va_start(argptr, format);
int rv = wxVsnprintf(str, size, format, argptr);
va_end(argptr);
return rv;
}
#endif
#ifdef HAVE_BROKEN_VSNPRINTF_DECL
#define vsnprintf wx_fixed_vsnprintf
#endif
#if wxUSE_UNICODE
static int ConvertStringToBuf(const wxString& s, char *out, size_t outsize)
{
const wxWX2WCbuf buf = s.wc_str();
size_t len = wxConvLibc.FromWChar(out, outsize, buf);
if ( len != wxCONV_FAILED )
return len-1;
else
return wxConvLibc.FromWChar(NULL, 0, buf);
}
#if wxUSE_UNICODE_UTF8
static int ConvertStringToBuf(const wxString& s, wchar_t *out, size_t outsize)
{
const wxWX2WCbuf buf(s.wc_str());
size_t len = wxWcslen(buf);
if ( outsize > len )
memcpy(out, buf, (len+1) * sizeof(wchar_t));
// else: not enough space
return len;
}
#endif
template<typename T>
static size_t PrintfViaString(T *out, size_t outsize,
const wxString& format, va_list argptr)
{
va_list argcopy;
wxVaCopy(argcopy, argptr);
wxString s;
s.PrintfV(format, argcopy);
return ConvertStringToBuf(s, out, outsize);
}
#endif // wxUSE_UNICODE
int wxVsprintf(char *str, const wxString& format, va_list argptr)
{
va_list argcopy;
wxVaCopy(argcopy, argptr);
#if wxUSE_UTF8_LOCALE_ONLY
return vsprintf(str, format.wx_str(), argcopy);
#else
#if wxUSE_UNICODE_UTF8
if ( wxLocaleIsUtf8 )
return vsprintf(str, format.wx_str(), argcopy);
else
#endif
#if wxUSE_UNICODE
return PrintfViaString(str, wxNO_LEN, format, argcopy);
#else
return wxCRT_Vsprintf(str, format, argcopy);
#endif
#endif
}
#if wxUSE_UNICODE
int wxVsprintf(wchar_t *str, const wxString& format, va_list argptr)
{
va_list argcopy;
wxVaCopy(argcopy, argptr);
#if wxUSE_UNICODE_WCHAR
return wxCRT_Vsprintf(str, format, argcopy);
#else // wxUSE_UNICODE_UTF8
#if !wxUSE_UTF8_LOCALE_ONLY
if ( !wxLocaleIsUtf8 )
return wxCRT_Vsprintf(str, format, argcopy);
else
#endif
return PrintfViaString(str, wxNO_LEN, format, argcopy);
#endif // wxUSE_UNICODE_UTF8
}
#endif // wxUSE_UNICODE
int wxVsnprintf(char *str, size_t size, const wxString& format, va_list argptr)
{
int rv;
va_list argcopy;
wxVaCopy(argcopy, argptr);
#if wxUSE_UTF8_LOCALE_ONLY
rv = vsnprintf(str, size, format.wx_str(), argcopy);
#else
#if wxUSE_UNICODE_UTF8
if ( wxLocaleIsUtf8 )
rv = vsnprintf(str, size, format.wx_str(), argcopy);
else
#endif
#if wxUSE_UNICODE
{
// NB: if this code is called, then wxString::PrintV() would use the
// wchar_t* version of wxVsnprintf(), so it's safe to use PrintV()
// from here
rv = PrintfViaString(str, size, format, argcopy);
}
#else
rv = wxCRT_Vsnprintf(str, size, format, argcopy);
#endif
#endif
// VsnprintfTestCase reveals that glibc's implementation of vswprintf
// doesn't nul terminate on truncation.
str[size - 1] = 0;
return rv;
}
#if wxUSE_UNICODE
int wxVsnprintf(wchar_t *str, size_t size, const wxString& format, va_list argptr)
{
int rv;
va_list argcopy;
wxVaCopy(argcopy, argptr);
#if wxUSE_UNICODE_WCHAR
rv = wxCRT_Vsnprintf(str, size, format, argcopy);
#else // wxUSE_UNICODE_UTF8
#if !wxUSE_UTF8_LOCALE_ONLY
if ( !wxLocaleIsUtf8 )
rv = wxCRT_Vsnprintf(str, size, format, argcopy);
else
#endif
{
// NB: if this code is called, then wxString::PrintV() would use the
// char* version of wxVsnprintf(), so it's safe to use PrintV()
// from here
rv = PrintfViaString(str, size, format, argcopy);
}
#endif // wxUSE_UNICODE_UTF8
// VsnprintfTestCase reveals that glibc's implementation of vswprintf
// doesn't nul terminate on truncation.
str[size - 1] = 0;
return rv;
}
#endif // wxUSE_UNICODE
#if wxUSE_WCHAR_T #if wxUSE_WCHAR_T
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------

View File

@@ -143,8 +143,7 @@ typedef union {
char pad_char; // %hc (in ANSI mode: %c, too) char pad_char; // %hc (in ANSI mode: %c, too)
wchar_t pad_wchar; // %lc (in Unicode mode: %c, too) wchar_t pad_wchar; // %lc (in Unicode mode: %c, too)
char *pad_pchar; // %s (related to a char *) void *pad_str; // %s
wchar_t *pad_pwchar; // %s (related to a wchar_t *)
int *pad_nint; // %n int *pad_nint; // %n
short int *pad_nshortint; // %hn short int *pad_nshortint; // %hn
@@ -616,10 +615,8 @@ bool wxPrintfConvSpec::LoadArg(wxPrintfArg *p, va_list &argptr)
break; break;
case wxPAT_PCHAR: case wxPAT_PCHAR:
p->pad_pchar = va_arg(argptr, char *);
break;
case wxPAT_PWCHAR: case wxPAT_PWCHAR:
p->pad_pwchar = va_arg(argptr, wchar_t *); p->pad_str = va_arg(argptr, void *);
break; break;
case wxPAT_NINT: case wxPAT_NINT:
@@ -735,54 +732,15 @@ int wxPrintfConvSpec::Process(wxChar *buf, size_t lenMax, wxPrintfArg *p, size_t
case wxPAT_PCHAR: case wxPAT_PCHAR:
case wxPAT_PWCHAR: case wxPAT_PWCHAR:
{ {
wxString s; wxArgNormalizedString arg(p->pad_str);
const wxChar *val = wxString s = arg;
#if wxUSE_UNICODE
p->pad_pwchar;
if (m_type == wxPAT_PCHAR) if ( !arg.IsValid() && m_nMaxWidth >= 6 )
{ s = wxT("(null)");
// user passed a string explicitely indicated as ANSI...
val = s = wxString(p->pad_pchar, wxConvLibc);
//wprintf(L"converting ANSI=>Unicode"); // for debug // at this point we are sure that m_nMaxWidth is positive or
} // null (see top of wxPrintfConvSpec::LoadArg)
#else int len = wxMin((unsigned int)m_nMaxWidth, s.length());
p->pad_pchar;
#if wxUSE_WCHAR_T
if (m_type == wxPAT_PWCHAR)
{
// user passed a string explicitely indicated as Unicode...
val = s = wxString(p->pad_pwchar, wxConvLibc);
//printf("converting Unicode=>ANSI"); // for debug
}
#endif
#endif
int len;
if (val)
{
#if wxUSE_STRUTILS
// at this point we are sure that m_nMaxWidth is positive or null
// (see top of wxPrintfConvSpec::LoadArg)
len = wxMin((unsigned int)m_nMaxWidth, wxStrlen(val));
#else
for ( len = 0; val[len] && (len < m_nMaxWidth); len++ )
;
#endif
}
else if (m_nMaxWidth >= 6)
{
val = wxT("(null)");
len = 6;
}
else
{
val = wxEmptyString;
len = 0;
}
int i; int i;
@@ -794,11 +752,16 @@ int wxPrintfConvSpec::Process(wxChar *buf, size_t lenMax, wxPrintfArg *p, size_t
#if wxUSE_STRUTILS #if wxUSE_STRUTILS
len = wxMin((unsigned int)len, lenMax-lenCur); len = wxMin((unsigned int)len, lenMax-lenCur);
wxStrncpy(buf+lenCur, val, len); #if wxUSE_UNICODE // FIXME-UTF8
wxStrncpy(buf+lenCur, s.wc_str(), len);
#else
wxStrncpy(buf+lenCur, s.mb_str(), len);
#endif
lenCur += len; lenCur += len;
#else #else
for (i = 0; i < len; i++) wxString::const_iterator end = s.begin() + len;
APPEND_CH(val[i]); for (wxString::const_iterator j = s.begin(); j != end; ++j)
APPEND_CH(*j);
#endif #endif
if (m_bAlignLeft) if (m_bAlignLeft)

View File

@@ -205,13 +205,13 @@ static wxFrame *gs_pFrame = NULL; // FIXME MT-unsafe
// accepts an additional argument which tells to which frame the output should // accepts an additional argument which tells to which frame the output should
// be directed // be directed
void wxVLogStatus(wxFrame *pFrame, const wxChar *szFormat, va_list argptr) void wxVLogStatus(wxFrame *pFrame, const wxString& format, va_list argptr)
{ {
wxString msg; wxString msg;
wxLog *pLog = wxLog::GetActiveTarget(); wxLog *pLog = wxLog::GetActiveTarget();
if ( pLog != NULL ) { if ( pLog != NULL ) {
msg.PrintfV(szFormat, argptr); msg.PrintfV(format, argptr);
wxASSERT( gs_pFrame == NULL ); // should be reset! wxASSERT( gs_pFrame == NULL ); // should be reset!
gs_pFrame = pFrame; gs_pFrame = pFrame;
@@ -224,11 +224,11 @@ void wxVLogStatus(wxFrame *pFrame, const wxChar *szFormat, va_list argptr)
} }
} }
void wxDoLogStatus(wxFrame *pFrame, const wxChar *szFormat, ...) void wxDoLogStatus(wxFrame *pFrame, const wxString& format, ...)
{ {
va_list argptr; va_list argptr;
va_start(argptr, szFormat); va_start(argptr, format);
wxVLogStatus(pFrame, szFormat, argptr); wxVLogStatus(pFrame, format, argptr);
va_end(argptr); va_end(argptr);
} }
@@ -588,7 +588,7 @@ void wxLogFrame::OnSave(wxCommandEvent& WXUNUSED(event))
wxLogError(_("Can't save log contents to file.")); wxLogError(_("Can't save log contents to file."));
} }
else { else {
wxLogStatus(this, _("Log saved to the file '%s'."), filename.c_str()); wxLogStatus((wxFrame*)this, _("Log saved to the file '%s'."), filename.c_str());
} }
#endif #endif
} }