]> git.saurik.com Git - wxWidgets.git/commitdiff
use UTF8-encoded char* strings in UTF8 build instead of wchar_t* if the current local...
authorVáclav Slavík <vslavik@fastmail.fm>
Thu, 26 Apr 2007 11:40:04 +0000 (11:40 +0000)
committerVáclav Slavík <vslavik@fastmail.fm>
Thu, 26 Apr 2007 11:40:04 +0000 (11:40 +0000)
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

23 files changed:
include/wx/generic/dcpsg.h
include/wx/log.h
include/wx/mimetype.h
include/wx/msgout.h
include/wx/string.h
include/wx/stringimpl.h
include/wx/stringops.h
include/wx/strvararg.h
include/wx/wx.h
include/wx/wxcrtvararg.h
src/common/filesys.cpp
src/common/fmapbase.cpp
src/common/ftp.cpp
src/common/http.cpp
src/common/log.cpp
src/common/mimecmn.cpp
src/common/msgout.cpp
src/common/string.cpp
src/common/stringimpl.cpp
src/common/strvararg.cpp
src/common/wxcrt.cpp
src/common/wxprintf.cpp
src/generic/logg.cpp

index 1958c18278584ae03d77d2fe23ce4fcfbcaa4ad5..f1932134d85afd3f5bbebfa2e0bcf5ce54eae7ec 100644 (file)
@@ -86,12 +86,18 @@ public:
   static void SetResolution(int ppi);
   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( int ch );
 
 private:
-    void DoPsPrintfFormat(const wxChar *fmt, ... );
+    void DoPsPrintfFormat(const wxString& fmt, ... );
 
     static float ms_PSScaleFactor;
 
index b280d7d309ab7aaaad324eb49901f9bd204a3841..0ed1ddbc629d3d4cd537f79a71e85584971bb38f 100644 (file)
@@ -471,39 +471,93 @@ WXDLLIMPEXP_BASE const wxChar* wxSysErrorMsg(unsigned long nErrCode = 0);
 // define wxLog<level>
 // ----------------------------------------------------------------------------
 
-#define DECLARE_LOG_FUNCTION_PUBLIC(level)                                  \
-    /* void wxLog##level(const wxChar *szFormat, ...); */                   \
-    WX_DEFINE_VARARG_FUNC_VOID(wxLog##level, wxDoLog##level)
+#ifdef __WATCOMC__
+    // workaround for http://bugzilla.openwatcom.org/show_bug.cgi?id=351
+    #define WX_WATCOM_ONLY_CODE( x )  x
+#else
+    #define WX_WATCOM_ONLY_CODE( x )
+#endif
 
-#define DECLARE_LOG_FUNCTION_IMPL(level)                                    \
-    extern void WXDLLIMPEXP_BASE wxVLog##level(const wxString& format,      \
-                                               va_list argptr);             \
+#define DECLARE_LOG_FUNCTION(level)                                         \
     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)
+
+#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_IMPL(level, argclass, arg, expdecl)       \
+#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,                         \
                                       const wxString& format,               \
-                                      va_list argptr);                      \
-    extern void expdecl wxDoLog##level(argclass arg,                        \
-                                       const wxChar *szFormat,              \
-                                       ...) ATTRIBUTE_PRINTF_2
+                                      va_list argptr)
+
+#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_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
 
 // log functions do nothing at all
-#define DECLARE_LOG_FUNCTION_PUBLIC(level)                                  \
-    /* void wxLog##level(const wxChar *szFormat, ...) {} */                 \
-    WX_DEFINE_VARARG_FUNC_NOP(wxLog##level)
-
-#define DECLARE_LOG_FUNCTION_IMPL(level)                                    \
+#define DECLARE_LOG_FUNCTION(level)                                         \
+    WX_DEFINE_VARARG_FUNC_NOP(wxLog##level, 1, (const wxString&))           \
+    WX_WATCOM_ONLY_CODE(                                                    \
+        WX_DEFINE_VARARG_FUNC_NOP(wxLog##level, 1, (const char*))           \
+        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),             \
-                              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),                       \
-                              const wxString& WXUNUSED(format),             \
-                              va_list WXUNUSED(argptr)) {}
+                               const wxString& WXUNUSED(format),            \
+                               va_list WXUNUSED(argptr)) {}
+
+#undef WX_WATCOM_ONLY_CODE
 
 // Empty Class to fake wxLogNull
 class WXDLLIMPEXP_BASE wxLogNull
@@ -521,28 +575,13 @@ public:
 
 #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)                         \
     DECLARE_LOG_FUNCTION2_EXP(level, argclass, arg, WXDLLIMPEXP_BASE)
 
 // VC6 produces a warning if we a macro expanding to nothing to
-// DECLARE_LOG_FUNCTION2_IMPL:
+// DECLARE_LOG_FUNCTION2:
 #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)
 #endif
 
@@ -559,26 +598,26 @@ DECLARE_LOG_FUNCTION(Verbose);
 
 // this function sends the log message to the status line of the top level
 // application frame, if any
-DECLARE_LOG_FUNCTION_IMPL(Status);
+DECLARE_LOG_FUNCTION(Status);
 
 #if wxUSE_GUI
     // this one is the same as previous except that it allows to explicitly
     class WXDLLEXPORT wxFrame;
     // 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
 
-DECLARE_LOG_FUNCTION_PUBLIC(Status)
-
 // additional one: as wxLogError, but also logs last system call error code
 // 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
 // that don't set the errno (like registry APIs in Win32))
-DECLARE_LOG_FUNCTION2_IMPL(SysError, long, lErrCode);
-
-DECLARE_LOG_FUNCTION_PUBLIC(SysError)
+DECLARE_LOG_FUNCTION2(SysError, long, lErrCode);
+#ifdef __WATCOMC__
+// 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
 #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
     // 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
     // wxLog::GetActive()->GetTraceMask() -- it's deprecated in favour of
     // string identifiers
-    DECLARE_LOG_FUNCTION2_IMPL(Trace, wxTraceMask, mask);
-    DECLARE_LOG_FUNCTION_PUBLIC(Trace)
+    DECLARE_LOG_FUNCTION2(Trace, wxTraceMask, mask);
+#ifdef __WATCOMC__
+    // workaround for http://bugzilla.openwatcom.org/show_bug.cgi?id=351
+    DECLARE_LOG_FUNCTION2(Trace, int, mask);
+#endif
 #else   //!debug || !wxUSE_LOG
     // 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
index 3c99c2c621d4d770a0993f57ad298f04dbd487ca..2a38d413ca25f868dedff8fa841cbd76c5889049 100644 (file)
@@ -116,16 +116,44 @@ private:
 
 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:
     // ctors
         // a normal item
-    wxFileTypeInfo(const wxChar *mimeType,
-                   const wxChar *openCmd,
-                   const wxChar *printCmd,
-                   const wxChar *desc,
-                   // the other parameters form a NULL terminated list of
-                   // extensions
-                   ...);
+
+    // wxFileTypeInfo(const wxString& mimeType,
+    //               const wxString& openCmd,
+    //               const wxString& printCmd,
+    //               const wxString& desc,
+    //               // 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 same order
index ba377c079cb98fccf0c49f79221b9ae22d0b4878..f48232752a26c89a84594b49184e41d9e4faba4a 100755 (executable)
@@ -36,13 +36,19 @@ public:
     virtual ~wxMessageOutputBase() { }
 
     // show a message to the user
-    // void Printf(const wxChar* format, ...)  ATTRIBUTE_PRINTF_2 = 0;
-    WX_DEFINE_VARARG_FUNC_VOID(Printf, DoPrintf)
+    // void Printf(const wxString& format, ...) = 0;
+    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:
     // NB: this is pure virtual so that it can be implemented in dllexported
     //     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
     virtual void Output(const wxString& str) = 0;
@@ -67,7 +73,7 @@ public:
     static wxMessageOutput* Set(wxMessageOutput* msgout);
 
 protected:
-    virtual void DoPrintf(const wxChar* format, ...) ATTRIBUTE_PRINTF_2;
+    virtual void DoPrintf(const wxString& format, ...);
     virtual void Output(const wxString& str) = 0;
 
 private:
index 83ca3c62ee4e0a9c1289c503e769c647c2e3e2b7..476af6441913699440a924cc0c8060e55ab7d2b0 100644 (file)
@@ -51,7 +51,7 @@
     #include <StringMgr.h>
 #endif
 
-#include "wx/wxchar.h"      // for wxChar, wxStrlen() etc.
+#include "wx/wxcrt.h"       // for wxChar, wxStrlen() etc.
 #include "wx/strvararg.h"
 #include "wx/buffer.h"      // for wxCharBuffer
 #include "wx/strconv.h"     // for wxConvertXXX() macros and wxMBConv classes
@@ -216,6 +216,10 @@ public:
 
     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]":
     inline wxUniChar operator[](size_t n) const;
     wxUniChar operator[](int n) const { return operator[](size_t(n)); }
@@ -292,8 +296,8 @@ class WXDLLIMPEXP_BASE wxStringPrintfMixinBase
 protected:
     wxStringPrintfMixinBase() {}
 
-    int DoPrintf(const wxChar *format, ...) ATTRIBUTE_PRINTF_2;
-    static wxString DoFormat(const wxChar *format, ...) ATTRIBUTE_PRINTF_1;
+    int DoPrintf(const wxString& format, ...);
+    static wxString DoFormat(const wxString& format, ...);
 };
 
 // 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
     // if !wxNEEDS_WXSTRING_PRINTF_MIXIN:
 
-    // int Printf(const wxChar *pszFormat, ...);
-    WX_DEFINE_VARARG_FUNC(int, Printf, DoPrintf)
-    // static wxString Format(const wxChar *pszFormat, ...) ATTRIBUTE_PRINTF_1;
-    WX_DEFINE_VARARG_FUNC(static typename StringReturnType<T1>::type,
-                          Format, DoFormat)
-    // int sprintf(const wxChar *pszFormat, ...) ATTRIBUTE_PRINTF_2;
-    WX_DEFINE_VARARG_FUNC(int, sprintf, DoPrintf)
+    // static wxString Format(const wString& format, ...) ATTRIBUTE_PRINTF_1;
+    WX_DEFINE_VARARG_FUNC2_SANS_N0(static typename StringReturnType<T1>::type,
+                                   Format, 1, (const wxString&),
+                                   DoFormat, DoFormat)
+    // We have to implement the version without template arguments manually
+    // because of the StringReturnType<> hack, although WX_DEFINE_VARARG_FUNC
+    // 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:
     wxStringPrintfMixin() : wxStringPrintfMixinBase() {}
@@ -879,7 +897,6 @@ public:
   // 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
 #if wxUSE_STD_STRING
-
   #if wxUSE_UNICODE_WCHAR
     wxString(const wxStdWideString& str) : m_impl(str) {}
   #else // UTF-8 or ANSI
@@ -1484,16 +1501,27 @@ public:
   // formatted input/output
     // as sprintf(), returns the number of characters written or < 0 on error
     // (take 'this' into account in attribute parameter count)
-  // int Printf(const wxChar *pszFormat, ...);
-  WX_DEFINE_VARARG_FUNC(int, Printf, DoPrintf)
+  // int Printf(const wxString& format, ...);
+  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
     // as vprintf(), returns the number of characters written or < 0 on error
   int PrintfV(const wxString& format, va_list argptr);
 
 #ifndef wxNEEDS_WXSTRING_PRINTF_MIXIN
     // returns the string containing the result of Printf() to it
-  // static wxString Format(const wxChar *pszFormat, ...) ATTRIBUTE_PRINTF_1;
-  WX_DEFINE_VARARG_FUNC(static wxString, Format, DoFormat)
+  // static wxString Format(const wxString& format, ...) ATTRIBUTE_PRINTF_1;
+  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
     // the same as above, but takes a va_list
   static wxString FormatV(const wxString& format, va_list argptr);
@@ -1529,8 +1557,14 @@ public:
 #ifndef wxNEEDS_WXSTRING_PRINTF_MIXIN
   // use Printf()
   // (take 'this' into account in attribute parameter count)
-  // int sprintf(const wxChar *pszFormat, ...) ATTRIBUTE_PRINTF_2;
-  WX_DEFINE_VARARG_FUNC(int, sprintf, DoPrintf)
+  // int sprintf(const wxString& format, ...) ATTRIBUTE_PRINTF_2;
+  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
 
     // use Cmp()
@@ -2200,7 +2234,7 @@ public:
   wxString& operator+=(wchar_t ch) { return *this += wxUniChar(ch); }
 
 private:
-#if !wxUSE_STL_BASED_WXSTRING && !wxUSE_UNICODE_UTF8
+#if !wxUSE_STL_BASED_WXSTRING
   // helpers for wxStringBuffer and wxStringBufferLength
   wxStringCharType *DoGetWriteBuf(size_t nLen)
     { return m_impl.DoGetWriteBuf(nLen); }
@@ -2208,14 +2242,11 @@ private:
     { m_impl.DoUngetWriteBuf(); }
   void DoUngetWriteBuf(size_t nLen)
     { m_impl.DoUngetWriteBuf(nLen); }
-
-  friend class WXDLLIMPEXP_BASE wxStringBuffer;
-  friend class WXDLLIMPEXP_BASE wxStringBufferLength;
-#endif // !wxUSE_STL_BASED_WXSTRING && !wxUSE_UNICODE_UTF8
+#endif // !wxUSE_STL_BASED_WXSTRING
 
 #ifndef wxNEEDS_WXSTRING_PRINTF_MIXIN
-  int DoPrintf(const wxChar *format, ...) ATTRIBUTE_PRINTF_2;
-  static wxString DoFormat(const wxChar *format, ...) ATTRIBUTE_PRINTF_1;
+  int DoPrintf(const wxString& format, ...);
+  static wxString DoFormat(const wxString& format, ...);
 #endif
 
 #if !wxUSE_STL_BASED_WXSTRING
@@ -2253,7 +2284,10 @@ private:
 #if !wxUSE_UNICODE_WCHAR
   ConvertedBuffer<wchar_t> m_convertedToWChar;
 #endif
+
   friend class WXDLLIMPEXP_BASE wxCStrData;
+  friend class wxImplStringBuffer;
+  friend class wxImplStringBufferLength;
 };
 
 #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
 // ----------------------------------------------------------------------------
 
-#if wxUSE_STL_BASED_WXSTRING || wxUSE_UNICODE_UTF8
+#if !wxUSE_STL_BASED_WXSTRING
+// string buffer for direct access to string data in their native
+// representation:
+class wxImplStringBuffer
+{
+public:
+    typedef wxStringCharType CharType;
+
+    wxImplStringBuffer(wxString& str, size_t lenWanted = 1024)
+        : m_str(str), m_buf(NULL)
+        { m_buf = m_str.DoGetWriteBuf(lenWanted); }
+
+    ~wxImplStringBuffer() { m_str.DoUngetWriteBuf(); }
+
+    operator wxStringCharType*() const { return m_buf; }
 
-class WXDLLIMPEXP_BASE wxStringBuffer
+private:
+    wxString&         m_str;
+    wxStringCharType *m_buf;
+
+    DECLARE_NO_COPY_CLASS(wxImplStringBuffer)
+};
+
+class wxImplStringBufferLength
 {
 public:
-    wxStringBuffer(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_buf = m_str.DoGetWriteBuf(lenWanted);
+        wxASSERT(m_buf != NULL);
+    }
+
+    ~wxImplStringBufferLength()
+    {
+        wxASSERT(m_lenSet);
+        m_str.DoUngetWriteBuf(m_len);
+    }
+
+    operator wxStringCharType*() const { return m_buf; }
+    void SetLength(size_t length) { m_len = length; m_lenSet = true; }
+
+private:
+    wxString&         m_str;
+    wxStringCharType *m_buf;
+    size_t            m_len;
+    bool              m_lenSet;
+
+    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)
         { }
 
-    ~wxStringBuffer() { m_str.assign(m_buf.data(), wxStrlen(m_buf.data())); }
 
-    operator wxChar*() { return m_buf.data(); }
+    operator CharType*() { return m_buf.data(); }
 
-private:
+protected:
     wxString& m_str;
-#if wxUSE_UNICODE
-    wxWCharBuffer m_buf;
-#else
-    wxCharBuffer m_buf;
-#endif
-
-    DECLARE_NO_COPY_CLASS(wxStringBuffer)
+    wxCharTypeBuffer<CharType> m_buf;
 };
 
-class WXDLLIMPEXP_BASE wxStringBufferLength
+template<typename T>
+class wxStringTypeBufferLengthBase
 {
 public:
-    wxStringBufferLength(wxString& str, size_t lenWanted = 1024)
+    typedef T CharType;
+
+    wxStringTypeBufferLengthBase(wxString& str, size_t lenWanted = 1024)
         : m_str(str), m_buf(lenWanted), m_len(0), m_lenSet(false)
         { }
 
-    ~wxStringBufferLength()
+    ~wxStringTypeBufferLengthBase()
     {
         wxASSERT(m_lenSet);
         m_str.assign(m_buf.data(), m_len);
     }
 
-    operator wxChar*() { return m_buf.data(); }
+    operator CharType*() { return m_buf.data(); }
     void SetLength(size_t length) { m_len = length; m_lenSet = true; }
 
-private:
+protected:
     wxString& m_str;
-#if wxUSE_UNICODE
-    wxWCharBuffer m_buf;
-#else
-    wxCharBuffer  m_buf;
-#endif
+    wxCharTypeBuffer<CharType> m_buf;
     size_t        m_len;
     bool          m_lenSet;
-
-    DECLARE_NO_COPY_CLASS(wxStringBufferLength)
 };
 
-#else // if !wxUSE_STL_BASED_WXSTRING && !wxUSE_UNICODE_UTF8
+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());
+    }
 
-class WXDLLIMPEXP_BASE wxStringBuffer
+    DECLARE_NO_COPY_CLASS(wxStringTypeBuffer)
+};
+
+template<typename T>
+class wxStringTypeBufferLength : public wxStringTypeBufferLengthBase<T>
 {
 public:
-    wxStringBuffer(wxString& str, size_t lenWanted = 1024)
-        : m_str(str), m_buf(NULL)
-        { m_buf = m_str.DoGetWriteBuf(lenWanted); }
+    wxStringTypeBufferLength(wxString& str, size_t lenWanted = 1024)
+        : wxStringTypeBufferLengthBase<T>(str, lenWanted) {}
 
-    ~wxStringBuffer() { m_str.DoUngetWriteBuf(); }
+    ~wxStringTypeBufferLength()
+    {
+        wxASSERT(this->m_lenSet);
+        this->m_str.assign(this->m_buf.data(), this->m_len);
+    }
 
-    operator wxChar*() const { return m_buf; }
+    DECLARE_NO_COPY_CLASS(wxStringTypeBufferLength)
+};
 
-private:
-    wxString& m_str;
-    wxChar   *m_buf;
+#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(wxStringBuffer)
+    DECLARE_NO_COPY_CLASS(wxImplStringBuffer)
 };
 
-class WXDLLIMPEXP_BASE wxStringBufferLength
+class wxImplStringBufferLength : public wxStringTypeBufferLengthBase<wxStringCharType>
 {
 public:
-    wxStringBufferLength(wxString& str, size_t lenWanted = 1024)
-        : m_str(str), m_buf(NULL), m_len(0), m_lenSet(false)
-    {
-        m_buf = m_str.DoGetWriteBuf(lenWanted);
-        wxASSERT(m_buf != NULL);
-    }
+    wxImplStringBufferLength(wxString& str, size_t lenWanted = 1024)
+        : wxStringTypeBufferLengthBase<wxStringCharType>(str, lenWanted) {}
 
-    ~wxStringBufferLength()
+    ~wxImplStringBufferLength()
     {
         wxASSERT(m_lenSet);
-        m_str.DoUngetWriteBuf(m_len);
+        m_str.m_impl.assign(m_buf.data(), m_len);
     }
 
-    operator wxChar*() const { return m_buf; }
-    void SetLength(size_t length) { m_len = length; m_lenSet = true; }
-
-private:
-    wxString& m_str;
-    wxChar   *m_buf;
-    size_t    m_len;
-    bool      m_lenSet;
-
-    DECLARE_NO_COPY_CLASS(wxStringBufferLength)
+    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
 
 // ---------------------------------------------------------------------------
@@ -2600,6 +2697,11 @@ inline wxString wxCStrData::AsString() const
         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
 {
     if ( m_str->empty() )
index 1b3f172c948bda220fa3bd0398a3f1196818a661..a3f82ca74f912f0c08a10c0168c5f9adbe555b26 100644 (file)
@@ -23,7 +23,8 @@
 // ----------------------------------------------------------------------------
 
 #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>
 
@@ -540,12 +541,10 @@ public:
       // string += char
   wxStringImpl& operator+=(wxStringCharType ch) { return append(1, ch); }
 
-#if !wxUSE_UNICODE_UTF8
   // helpers for wxStringBuffer and wxStringBufferLength
   wxStringCharType *DoGetWriteBuf(size_t nLen);
   void DoUngetWriteBuf();
   void DoUngetWriteBuf(size_t nLen);
-#endif
 
 private:
 #if wxUSE_UNICODE_UTF8
index 6451275bb1d1a7460d36e8d61e490970a586d34c..972b8327171a6b60afc08cb0738645bc689bcbf5 100644 (file)
@@ -39,6 +39,8 @@ struct WXDLLIMPEXP_BASE wxStringOperationsWchar
         { return i + n; }
     static wxStringImpl::const_iterator AddToIter(const wxStringImpl::const_iterator& i, int 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
     static int DiffIters(const wxStringImpl::iterator& i1,
index 55eb9c01f23e9a18215b6be268df30124c98093e..459c0ffeeca87a39774a96eabe673c8afb84a842 100644 (file)
     #error "OpenWatcom version >= 1.4 is required to compile this code"
 #endif
 
+#include "wx/cpp.h"
 #include "wx/chartype.h"
+#include "wx/wxcrt.h"
+#include "wx/strconv.h"
+#include "wx/buffer.h"
 
 class WXDLLIMPEXP_BASE wxCStrData;
 class WXDLLIMPEXP_BASE wxString;
-class WXDLLIMPEXP_BASE wxCharBuffer;
-class WXDLLIMPEXP_BASE wxWCharBuffer;
-
 
 // ----------------------------------------------------------------------------
 // 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
 // (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
-// the wrapper does is that it normalizes the arguments passed in so that
-// they are of the type expected by variadic functions taking string
-// arguments, i.e., char* or wchar_t*, depending on the build:
+// wrappers around another variadic function ('impl' or 'implUtf8' arguments,
+// see below) and the only thing the wrapper does is that it normalizes the
+// arguments passed in so that they are of the type expected by variadic
+// functions taking string arguments, i.e., char* or wchar_t*, depending on the
+// 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:
-//        rettype   Functions' return type.
-//        name      Name of the function.
-//        impl      Name of the variadic function that implements 'name'.
-#define WX_DEFINE_VARARG_FUNC(rettype, name, impl)                        \
-        _WX_VARARG_ITER(_WX_VARARG_MAX_ARGS,                              \
-                        _WX_VARARG_DEFINE_FUNC,                           \
-                        rettype, name, impl)
-
-// Like WX_DEFINE_VARARG_FUNC, but for variadic functions that don't return
+// [ there are examples in square brackets showing values of the parameters
+//   for the wxFprintf() wrapper for fprintf() function with the following
+//   prototype:
+//   int wxFprintf(FILE *stream, const wxString& format, ...); ]
+//
+//        rettype   Functions' return type  [int]
+//        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)
+
+// 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.
-#define WX_DEFINE_VARARG_FUNC_VOID(name, impl)                            \
-        _WX_VARARG_ITER(_WX_VARARG_MAX_ARGS,                              \
-                        _WX_VARARG_DEFINE_FUNC_VOID,                      \
-                        void, name, impl)
+#define WX_DEFINE_VARARG_FUNC_VOID2(name, numfixed, fixed, impl, implUtf8)    \
+    _WX_VARARG_DEFINE_FUNC_VOID_N0(name, impl, implUtf8, numfixed, fixed)     \
+    _WX_VARARG_ITER(_WX_VARARG_MAX_ARGS,                                      \
+                    _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
 // function, does nothing in defined functions' bodies.
 //
 // Used to implement wxLogXXX functions if wxUSE_LOG=0.
-#define WX_DEFINE_VARARG_FUNC_NOP(name)                                   \
-        _WX_VARARG_ITER(_WX_VARARG_MAX_ARGS,                              \
-                        _WX_VARARG_DEFINE_FUNC_NOP,                       \
-                        void, name, dummy)
+#define WX_DEFINE_VARARG_FUNC_NOP(name, numfixed, fixed)                      \
+        _WX_VARARG_DEFINE_FUNC_NOP_N0(name, numfixed, fixed)                  \
+        _WX_VARARG_ITER(_WX_VARARG_MAX_ARGS,                                  \
+                        _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,
@@ -87,122 +134,236 @@ struct wxArgNormalizer
     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:
 
-template<>
-struct WXDLLIMPEXP_BASE wxArgNormalizer<const wxCStrData&>
+
+// 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
 {
-    wxArgNormalizer(const wxCStrData& value) : m_value(value) {}
-    const wxChar *get() const; // FIXME-UTF8: should be wxStringCharType
+    typedef wxCharTypeBuffer<CharType> CharBuffer;
 
-    const wxCStrData& m_value;
-};
+    wxArgNormalizerWithBuffer() {}
+    wxArgNormalizerWithBuffer(const CharBuffer& buf) : m_value(buf) {}
 
-template<>
-struct wxArgNormalizer<wxCStrData> : public wxArgNormalizer<const wxCStrData&>
-{
-    wxArgNormalizer(const wxCStrData& value)
-        : wxArgNormalizer<const wxCStrData&>(value) {}
+    const CharType *get() const { return m_value; }
+
+    CharBuffer m_value;
 };
 
+// string objects:
 template<>
-struct WXDLLIMPEXP_BASE wxArgNormalizer<const wxString&>
+struct WXDLLIMPEXP_BASE wxArgNormalizerNative<const wxString&>
 {
-    wxArgNormalizer(const wxString& value) : m_value(value) {}
-    const wxChar *get() const; // FIXME-UTF8: should be wxStringCharType
+    wxArgNormalizerNative(const wxString& s) : m_value(s) {}
+    const wxStringCharType *get() const;
 
     const wxString& m_value;
 };
 
+// c_str() values:
 template<>
-struct wxArgNormalizer<wxString> : public wxArgNormalizer<const wxString&>
+struct WXDLLIMPEXP_BASE wxArgNormalizerNative<const wxCStrData&>
 {
-    wxArgNormalizer(const wxString& value)
-        : wxArgNormalizer<const wxString&>(value) {}
+    wxArgNormalizerNative(const wxCStrData& value) : m_value(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<>
-struct WXDLLIMPEXP_BASE wxArgNormalizer<const char*>
+struct WXDLLIMPEXP_BASE wxArgNormalizerWchar<const wxString&>
+    : public wxArgNormalizerWithBuffer<wchar_t>
 {
-    wxArgNormalizer(const char *value);
-    ~wxArgNormalizer();
-    const wchar_t *get() const;
-
-    wxWCharBuffer *m_value;
+    wxArgNormalizerWchar(const wxString& s);
 };
 
 template<>
-struct wxArgNormalizer<char*> : public wxArgNormalizer<const char*>
+struct WXDLLIMPEXP_BASE wxArgNormalizerWchar<const wxCStrData&>
+    : public wxArgNormalizerWithBuffer<wchar_t>
 {
-    wxArgNormalizer(char *value)
-        : wxArgNormalizer<const char*>(value) {}
+    wxArgNormalizerWchar(const wxCStrData& s);
 };
-#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<>
-struct WXDLLIMPEXP_BASE wxArgNormalizer<const char*>
+struct wxArgNormalizerWchar<const char*>
+    : public wxArgNormalizerWithBuffer<wchar_t>
 {
-    wxArgNormalizer(const char *value);
-    ~wxArgNormalizer();
-    const char *get() const;
-
-    wxCharBuffer *m_value;
+    wxArgNormalizerWchar(const char* s)
+        : wxArgNormalizerWithBuffer<wchar_t>(wxConvLibc.cMB2WC(s)) {}
 };
 
+#elif wxUSE_UNICODE_UTF8
+
 template<>
-struct wxArgNormalizer<char*> : public wxArgNormalizer<const char*>
+struct wxArgNormalizerUtf8<const wchar_t*>
+    : public wxArgNormalizerWithBuffer<char>
 {
-    wxArgNormalizer(char *value)
-        : wxArgNormalizer<const char*>(value) {}
+    wxArgNormalizerUtf8(const wchar_t* s)
+        : wxArgNormalizerWithBuffer<char>(wxConvUTF8.cWC2MB(s)) {}
 };
-#endif // wxUSE_UNICODE_UTF8
 
-#if /*wxUSE_UNICODE_UTF8 || */ !wxUSE_UNICODE // FIXME-UTF8
 template<>
-struct WXDLLIMPEXP_BASE wxArgNormalizer<const wchar_t*>
+struct wxArgNormalizerUtf8<const char*>
+    : public wxArgNormalizerWithBuffer<char>
 {
-    wxArgNormalizer(const wchar_t *value);
-    ~wxArgNormalizer();
-    const char *get() const;
+    wxArgNormalizerUtf8(const char* s)
+    {
+        // FIXME-UTF8: optimize this if current locale is UTF-8 one
+
+        // convert to widechar string first:
+        wxWCharBuffer buf(wxConvLibc.cMB2WC(s));
 
-    wxCharBuffer *m_value;
+        // 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<>
-struct wxArgNormalizer<wchar_t*> : public wxArgNormalizer<const wchar_t*>
+struct wxArgNormalizerWchar<const char*>
+    : public wxArgNormalizerWithBuffer<wchar_t>
 {
-    wxArgNormalizer(wchar_t *value)
-        : wxArgNormalizer<const wchar_t*>(value) {}
+    wxArgNormalizerWchar(const char* s)
+        : wxArgNormalizerWithBuffer<wchar_t>(wxConvLibc.cMB2WC(s)) {}
 };
-#endif // wxUSE_UNICODE_UTF8 || !wxUSE_UNICODE
+#endif // !wxUSE_UTF8_LOCALE_ONLY
+
+#else // ANSI - FIXME-UTF8
 
-// versions for passing wx[W]CharBuffer:
 template<>
-struct WXDLLIMPEXP_BASE wxArgNormalizer<wxCharBuffer>
-            : public wxArgNormalizer<const char*>
+struct wxArgNormalizerWchar<const wchar_t*>
+    : public wxArgNormalizerWithBuffer<char>
 {
-    wxArgNormalizer(const wxCharBuffer& buf);
+    wxArgNormalizerWchar(const wchar_t* s)
+        : wxArgNormalizerWithBuffer<char>(wxConvLibc.cWC2MB(s)) {}
 };
 
-template<>
-struct WXDLLIMPEXP_BASE wxArgNormalizer<wxWCharBuffer>
-            : public wxArgNormalizer<const wchar_t*>
+#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:
+WX_ARG_NORMALIZER_FORWARD(wxCharBuffer, const char*);
+WX_ARG_NORMALIZER_FORWARD(const wxCharBuffer&, 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 wxWCharBuffer& 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;
 };
 
+#define WX_VA_ARG_STRING(ap) wxArgNormalizedString(va_arg(ap, const void*))
 
+// ----------------------------------------------------------------------------
+// implementation of the WX_DEFINE_VARARG_* macros
+// ----------------------------------------------------------------------------
 
-// NB: The vararg emulation code is limited to 30 arguments at the moment.
-//     If you need more, you need to
+// NB: The vararg emulation code is limited to 30 variadic and 4 fixed
+//     arguments at the moment.
+//     If you need more variadic arguments, you need to
 //        1) increase the value of _WX_VARARG_MAX_ARGS
 //        2) add _WX_VARARG_JOIN_* and _WX_VARARG_ITER_* up to the new
 //           _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_FIXED_ARGS   4
 
 #define _WX_VARARG_JOIN_1(m)                                 m(1)
 #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_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_2(m,a,b,c)   _WX_VARARG_ITER_1(m,a,b,c)  m(2,a,b,c)
-#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_4(m,a,b,c)   _WX_VARARG_ITER_3(m,a,b,c)  m(4,a,b,c)
-#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_6(m,a,b,c)   _WX_VARARG_ITER_5(m,a,b,c)  m(6,a,b,c)
-#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_8(m,a,b,c)   _WX_VARARG_ITER_7(m,a,b,c)  m(8,a,b,c)
-#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_10(m,a,b,c)  _WX_VARARG_ITER_9(m,a,b,c)  m(10,a,b,c)
-#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_12(m,a,b,c)  _WX_VARARG_ITER_11(m,a,b,c) m(12,a,b,c)
-#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_14(m,a,b,c)  _WX_VARARG_ITER_13(m,a,b,c) m(14,a,b,c)
-#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_16(m,a,b,c)  _WX_VARARG_ITER_15(m,a,b,c) m(16,a,b,c)
-#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_18(m,a,b,c)  _WX_VARARG_ITER_17(m,a,b,c) m(18,a,b,c)
-#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_20(m,a,b,c)  _WX_VARARG_ITER_19(m,a,b,c) m(20,a,b,c)
-#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_22(m,a,b,c)  _WX_VARARG_ITER_21(m,a,b,c) m(22,a,b,c)
-#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_24(m,a,b,c)  _WX_VARARG_ITER_23(m,a,b,c) m(24,a,b,c)
-#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_26(m,a,b,c)  _WX_VARARG_ITER_25(m,a,b,c) m(26,a,b,c)
-#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_28(m,a,b,c)  _WX_VARARG_ITER_27(m,a,b,c) m(28,a,b,c)
-#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_30(m,a,b,c)  _WX_VARARG_ITER_29(m,a,b,c) m(30,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,
 // 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_IMPL(N, m)        _WX_VARARG_JOIN_##N(m)
 
+
 // 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'
-// and 'c'. The results are separated with whitespace in the expansion.
+// its first argument set to 1..N and the remaining arguments set to 'a', 'b',
+// 'c', 'd', 'e' and 'f'. The results are separated with whitespace in the
+// expansion.
 //
 // An example:
 //     // this macro expands to:
-//     //     foo(1,a,b,c)
-//     //     foo(2,a,b,c)
-//     //     foo(3,a,b,c)
-//     _WX_VARARG_ITER(3, foo, a, b, c)
+//     //     foo(1,a,b,c,d,e,f)
+//     //     foo(2,a,b,c,d,e,f)
+//     //     foo(3,a,b,c,d,e,f)
+//     _WX_VARARG_ITER(3, foo, a, b, c, d, e, f)
 //
 // 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_IMPL(N, m,a,b,c)  _WX_VARARG_ITER_##N(m, a, b, c)
+#define _WX_VARARG_ITER(N,m,a,b,c,d,e,f) \
+        _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.
-#define _WX_VARARG_ARG(i)          T##i a##i
+// Generates code snippet for i-th "variadic" argument in vararg function's
+// prototype:
+#define _WX_VARARG_ARG(i)               T##i a##i
 
-// Like _WX_VARARG_ARG_UNUSED, but outputs argument's type with WXUNUSED.
-#define _WX_VARARG_ARG_UNUSED(i)   T##i WXUNUSED(a##i)
+// Like _WX_VARARG_ARG_UNUSED, but outputs argument's type with WXUNUSED:
+#define _WX_VARARG_ARG_UNUSED(i)             T##i WXUNUSED(a##i)
 
-// Generates code snippet for i-th type in vararg function's template<...>.
-#define _WX_VARARG_TEMPL(i)        typename T##i
+// Generates code snippet for i-th type in vararg function's template<...>:
+#define _WX_VARARG_TEMPL(i)             typename T##i
 
 // Generates code snippet for passing i-th argument of vararg function
-// wrapper to its implementation, normalizing it in the process
-#define _WX_VARARG_PASS(i)         wxArgNormalizer<T##i>(a##i).get()
+// wrapper to its implementation, normalizing it in the process:
+#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
 // WX_DEFINE_VARARG_FUNC (see its documentation for the meaning of arguments)
-#define _WX_VARARG_DEFINE_FUNC(N, rettype, name, impl)                      \
-    template<_WX_VARARG_JOIN(N, _WX_VARARG_TEMPL)>                          \
-    rettype name(_WX_VARARG_JOIN(N, _WX_VARARG_ARG))                        \
-    {                                                                       \
-        return impl(_WX_VARARG_JOIN(N, _WX_VARARG_PASS));                   \
+#define _WX_VARARG_DEFINE_FUNC(N, rettype, name,                              \
+                               impl, implUtf8, numfixed, fixed)               \
+    template<_WX_VARARG_JOIN(N, _WX_VARARG_TEMPL)>                            \
+    rettype name(_WX_VARARG_FIXED_EXPAND(numfixed, fixed),                    \
+                 _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
 // 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
 // requirements).
-#define _WX_VARARG_DEFINE_FUNC_VOID(N, rettype, name, impl)                 \
-    template<_WX_VARARG_JOIN(N, _WX_VARARG_TEMPL)>                          \
-    void name(_WX_VARARG_JOIN(N, _WX_VARARG_ARG))                           \
-    {                                                                       \
-        impl(_WX_VARARG_JOIN(N, _WX_VARARG_PASS));                          \
+#define _WX_VARARG_DEFINE_FUNC_VOID(N, rettype, name,                         \
+                                    impl, implUtf8, numfixed, fixed)          \
+    template<_WX_VARARG_JOIN(N, _WX_VARARG_TEMPL)>                            \
+    void 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_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
 // WX_DEFINE_VARARG_FUNC_NOP, i.e. empty stub for a disabled vararg function.
 // The rettype and impl arguments are ignored.
-#define _WX_VARARG_DEFINE_FUNC_NOP(N, rettype, name, impl)                  \
-    template<_WX_VARARG_JOIN(N, _WX_VARARG_TEMPL)>                          \
-    void name(_WX_VARARG_JOIN(N, _WX_VARARG_ARG_UNUSED)) {}
-
+#define _WX_VARARG_DEFINE_FUNC_NOP(N, rettype, name,                          \
+                                   impl, implUtf8, numfixed, fixed)           \
+    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_
index df72b056b255e35ee1d2b1d6fa00981cbf299a6d..62ba23fa15aa536c28d674fef0031528d98ff3c8 100644 (file)
@@ -31,6 +31,7 @@
 #include "wx/stopwatch.h"
 #include "wx/module.h"
 #include "wx/wxcrt.h"
+#include "wx/wxcrtvararg.h"
 
 #if wxUSE_GUI
 
index c036b33ecf24d3083d187fd2972b3fee37bf4b0c..6ddb99ff1cb69cfec89241c4e038256ad93bad2d 100644 (file)
 #include "wx/wxcrt.h"
 #include "wx/strvararg.h"
 
+#include "wx/string.h"
+
+// ----------------------------------------------------------------------------
+// CRT functions aliases
+// ----------------------------------------------------------------------------
 
 /* Required for wxPrintf() etc */
 #include <stdarg.h>
 
 #ifdef wxHAVE_TCHAR_SUPPORT
-    WX_DEFINE_VARARG_FUNC(int, wxFprintf, _ftprintf)
-    WX_DEFINE_VARARG_FUNC(int, wxPrintf, _tprintf)
-    #define  wxPutc(c,f) _puttc(WXWCHAR_T_CAST(c),f)
-    #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
+    #define  wxCRT_Fprintf   _ftprintf
+    #define  wxCRT_Printf    _tprintf
+    #define  wxCRT_Scanf     _tscanf
 
-    /* FIXME-UTF8: not wrapped */
-    #define  wxSscanf    _stscanf
-    #define  wxVfprintf  _vftprintf
-    #define  wxVprintf   _vtprintf
-    #define  wxVsscanf   _vstscanf
-    #define  wxVsprintf  _vstprintf
+    #define  wxCRT_Sscanf    _stscanf
+    #define  wxCRT_Vfprintf  _vftprintf
+    #define  wxCRT_Vprintf   _vtprintf
+    #define  wxCRT_Vsscanf   _vstscanf
+    #define  wxCRT_Vsprintf  _vstprintf
 
 #else /* !TCHAR-aware compilers */
 
     #if !wxUSE_UNICODE /* ASCII */
-        WX_DEFINE_VARARG_FUNC(int, wxFprintf, fprintf)
-        #define  wxFscanf    fscanf
-        WX_DEFINE_VARARG_FUNC(int, wxPrintf, printf)
-        #define  wxScanf     scanf
-        WX_DEFINE_VARARG_FUNC(int, wxSprintf, sprintf)
-        #define  wxSscanf    sscanf
-        #define  wxVfprintf  vfprintf
-        #define  wxVprintf   vprintf
-        #define  wxVsscanf   vsscanf
-        #define  wxVsprintf  vsprintf
+        #define  wxCRT_Fprintf   fprintf
+        #define  wxCRT_Fscanf    fscanf
+        #define  wxCRT_Printf    printf
+        #define  wxCRT_Scanf     scanf
+        #define  wxCRT_Sscanf    sscanf
+        #define  wxCRT_Vfprintf  vfprintf
+        #define  wxCRT_Vprintf   vprintf
+        #define  wxCRT_Vsscanf   vsscanf
+        #define  wxCRT_Vsprintf  vsprintf
     #endif /* ASCII */
 #endif /* TCHAR-aware compilers/the others */
 
     #ifndef wxVsnprintf_
         #if defined(__VISUALC__) || \
                 (defined(__BORLANDC__) && __BORLANDC__ >= 0x540)
-            #define wxSnprintf_     _sntprintf
             #define wxVsnprintf_    _vsntprintf
-            WX_DEFINE_VARARG_FUNC(int, wxSnprintf_, _sntprintf)
         #endif
     #endif
 
                 #define wxVsnprintf_     vswprintf
             #elif defined(__WATCOMC__)
                 #define wxVsnprintf_    _vsnwprintf
-                WX_DEFINE_VARARG_FUNC(int, wxSnprintf_, _snwprintf)
             #endif
         #else /* ASCII */
             /*
                All versions of CodeWarrior supported by wxWidgets apparently
                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) \
                 || defined(__MWERKS__) || defined(__WATCOMC__)
                 #ifdef HAVE_BROKEN_VSNPRINTF_DECL
     #endif /* wxVsnprintf_ */
 #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_
     /* no (suitable) vsnprintf(), cook our own */
     WXDLLIMPEXP_BASE int
-    wxVsnprintf_(wxChar *buf, size_t len,
-                 const wxChar *format, va_list argptr);
+    wxVsnprintf_(wxChar *buf, size_t len, const wxChar *format, va_list argptr);
 
     #define wxUSE_WXVSNPRINTF 1
 #else
         either because we don't have them at all or because they don't have the
         semantics we need
      */
-    WX_DEFINE_VARARG_FUNC(int, wxScanf, wxDoScanf)
-    int wxDoScanf( const wxChar *format, ... ) ATTRIBUTE_PRINTF_1;
-
-    WX_DEFINE_VARARG_FUNC(int, wxSscanf, wxDoSscanf)
-    int wxDoSscanf( const wxChar *str, const wxChar *format, ... ) ATTRIBUTE_PRINTF_2;
-
-    WX_DEFINE_VARARG_FUNC(int, wxFscanf, wxDoFscanf)
-    int wxDoFscanf( FILE *stream, const wxChar *format, ... ) ATTRIBUTE_PRINTF_2;
-
-    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 );
+    int wxCRT_Scanf( 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;
+    int wxCRT_Vsscanf( const wxChar *str, const wxChar *format, va_list ap );
+    int wxCRT_Printf( const wxChar *format, ... ) ATTRIBUTE_PRINTF_1;
+    int wxCRT_Fprintf( FILE *stream, const wxChar *format, ... ) ATTRIBUTE_PRINTF_2;
+    int wxCRT_Vfprintf( FILE *stream, const wxChar *format, va_list ap );
+    int wxCRT_Vprintf( const wxChar *format, va_list ap );
+    int wxCRT_Vsprintf( wxChar *str, const wxChar *format, va_list ap );
 #endif /* wxNEED_PRINTF_CONVERSION */
 
 /* these 2 can be simply mapped to the versions with underscore at the end */
    anything as our own wxVsnprintf_() already behaves as needed.
 */
 #if defined(wxNEED_PRINTF_CONVERSION) && defined(wxVsnprintf_)
-    WX_DEFINE_VARARG_FUNC(int, wxSnprintf, wxDoSnprintf)
-    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 );
+    int wxCRT_Vsnprintf( wxChar *str, size_t size, const wxChar *format, va_list ap );
 #else
-    #define wxSnprintf wxSnprintf_
-    #define wxVsnprintf wxVsnprintf_
+    #define wxCRT_Vsnprintf wxVsnprintf_
+#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_ */
index 19675f7996b584fdfb133ae13e245b7b8124901e..94a229f49c5d280494719a6459c3b710e94d5534 100644 (file)
@@ -69,27 +69,27 @@ wxString wxFileSystemHandler::GetMimeTypeFromExt(const wxString& location)
                            wxEmptyString,
                            wxEmptyString,
                            _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"),
                            wxEmptyString,
                            wxEmptyString,
                            _T("GIF image (from fallback)"),
-                           _T("gif"), _T("GIF"), NULL),
+                           _T("gif"), _T("GIF"), 0),
             wxFileTypeInfo(_T("image/png"),
                            wxEmptyString,
                            wxEmptyString,
                            _T("PNG image (from fallback)"),
-                           _T("png"), _T("PNG"), NULL),
+                           _T("png"), _T("PNG"), 0),
             wxFileTypeInfo(_T("image/bmp"),
                            wxEmptyString,
                            wxEmptyString,
                            _T("windows bitmap image (from fallback)"),
-                           _T("bmp"), _T("BMP"), NULL),
+                           _T("bmp"), _T("BMP"), 0),
             wxFileTypeInfo(_T("text/html"),
                            wxEmptyString,
                            wxEmptyString,
                            _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!
             wxFileTypeInfo()
         };
index 48e1b2e148bc9a5a4953d00371b4a505a6faa668..e989e839f8b6724af42d23c9248e5080146ea688 100644 (file)
@@ -31,6 +31,7 @@
     #include "wx/log.h"
     #include "wx/intl.h"
     #include "wx/module.h"
+    #include "wx/wxcrtvararg.h"
 #endif //WX_PRECOMP
 
 #if defined(__WXMSW__)
index 3672b76b4bc5072f33324cfbc98353bc6fef4700..da7c72171ec2356abd69a6ce88af7185a153d864 100644 (file)
@@ -38,6 +38,7 @@
     #include "wx/utils.h"
     #include "wx/log.h"
     #include "wx/intl.h"
+    #include "wx/wxcrtvararg.h"
 #endif // WX_PRECOMP
 
 #include "wx/sckaddr.h"
index f190f800e4e093d9768b5236d937e0b3797e8b62..f8977ecedffbf4188ad68b02ff431eba1e476605 100644 (file)
@@ -141,7 +141,7 @@ wxString wxHTTP::GenerateAuthString(const wxString& user, const wxString& pass)
         } 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("="));
+        buf << wxT("=");
     }
 
     return buf;
index e6690b652a6be8f489b95e50266c80982c36bdb2..1e03c06a06f7a1020c3411df62ff7f9e2cd60263 100644 (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_start(argptr, szFormat);
-    wxVLogGeneric(level, szFormat, argptr);
+    va_start(argptr, format);
+    wxVLogGeneric(level, format, 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_start(argptr, szFormat);                                     \
-    wxVLog##level(szFormat, argptr);                                \
+    va_start(argptr, format);                                       \
+    wxVLog##level(format, argptr);                                  \
     va_end(argptr);                                                 \
   }
 
@@ -145,11 +145,11 @@ void wxVLogFatalError(const wxString& format, va_list argptr)
 #endif
 }
 
-void wxDoLogFatalError(const wxChar *szFormat, ...)
+void wxDoLogFatalError(const wxString& format, ...)
 {
     va_list argptr;
-    va_start(argptr, szFormat);
-    wxVLogFatalError(szFormat, argptr);
+    va_start(argptr, format);
+    wxVLogFatalError(format, argptr);
 
     // some compilers warn about unreachable code and it shouldn't matter
     // 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_start(argptr, szFormat);
-    wxVLogVerbose(szFormat, argptr);
+    va_start(argptr, format);
+    wxVLogVerbose(format, argptr);
     va_end(argptr);
 }
 
 // debug functions
 #ifdef __WXDEBUG__
 #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() ) {                                     \
       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_start(argptr, szFormat);                                     \
-    wxVLog##level(szFormat, argptr);                                \
+    va_start(argptr, format);                                       \
+    wxVLog##level(format, 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_start(argptr, szFormat);
-    wxVLogTrace(mask, szFormat, argptr);
+    va_start(argptr, format);
+    wxVLogTrace(mask, format, 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_start(argptr, format);
+    wxVLogTrace(mask, format, 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, szFormat);
-    wxVLogTrace(mask, szFormat, 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
   #define IMPLEMENT_LOG_DEBUG_FUNCTION(level)
 #endif
@@ -251,11 +285,11 @@ void WXDLLEXPORT wxVLogSysError(const wxString& format, va_list argptr)
     wxVLogSysError(wxSysErrorCode(), format, argptr);
 }
 
-void WXDLLEXPORT wxDoLogSysError(const wxChar *szFormat, ...)
+void WXDLLEXPORT wxDoLogSysError(const wxString& format, ...)
 {
     va_list argptr;
-    va_start(argptr, szFormat);
-    wxVLogSysError(szFormat, argptr);
+    va_start(argptr, format);
+    wxVLogSysError(format, 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_start(argptr, szFormat);
-    wxVLogSysError(lErrCode, szFormat, argptr);
+    va_start(argptr, format);
+    wxVLogSysError(lErrCode, format, 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
 // ----------------------------------------------------------------------------
index 9325fb81c3afbf622192f83ff6efacc334070b39..1db9b7176cdba07982261324fbeb6f68057bc082 100644 (file)
@@ -111,19 +111,20 @@ wxString wxMimeTypeCommands::GetVerbCmd(size_t n) const
 // wxFileTypeInfo
 // ----------------------------------------------------------------------------
 
-wxFileTypeInfo::wxFileTypeInfo(const wxChar *mimeType,
-                               const wxChar *openCmd,
-                               const wxChar *printCmd,
-                               const wxChar *desc,
-                               ...)
-              : m_mimeType(mimeType),
-                m_openCmd(openCmd),
-                m_printCmd(printCmd),
-                m_desc(desc)
+void wxFileTypeInfo::VarArgInit(const wxString& mimeType,
+                                const wxString& openCmd,
+                                const wxString& printCmd,
+                                const wxString& desc,
+                                ...)
 {
     va_list argptr;
     va_start(argptr, desc);
 
+    m_mimeType = mimeType;
+    m_openCmd = openCmd;
+    m_printCmd = printCmd;
+    m_desc = desc;
+
     for ( ;; )
     {
         // icc gives this warning in its own va_arg() macro, argh
@@ -132,7 +133,7 @@ wxFileTypeInfo::wxFileTypeInfo(const wxChar *mimeType,
     #pragma warning(disable: 1684)
 #endif
 
-        const wxChar *ext = va_arg(argptr, const wxChar *);
+        wxArgNormalizedString ext(WX_VA_ARG_STRING(argptr));
 
 #ifdef __INTELC__
     #pragma warning(pop)
@@ -143,7 +144,7 @@ wxFileTypeInfo::wxFileTypeInfo(const wxChar *mimeType,
             break;
         }
 
-        m_exts.Add(ext);
+        m_exts.Add(ext.GetString());
     }
 
     va_end(argptr);
index 44ec5e15971b37c613cf6396450c1c35a25fe637..ca7f4e1c70182db70b94d8c19bfccc4b5f853b33 100755 (executable)
@@ -76,7 +76,7 @@ wxMessageOutput* wxMessageOutput::Set(wxMessageOutput* msgout)
     return old;
 }
 
-void wxMessageOutput::DoPrintf(const wxChar* format, ...)
+void wxMessageOutput::DoPrintf(const wxString& format, ...)
 {
     va_list args;
     va_start(args, format);
index 25f604519ca24d0ae0aeb8e63cee53635ad854c9..b2969ff04f4b3b168cfb2e23c2ca68505283423b 100644 (file)
@@ -23,6 +23,7 @@
 
 #ifndef WX_PRECOMP
     #include "wx/string.h"
+    #include "wx/wxcrtvararg.h"
 #endif
 
 #include <ctype.h>
@@ -1442,9 +1443,9 @@ bool wxString::ToDouble(double *val) const
 
 /* static */
 #ifdef wxNEEDS_WXSTRING_PRINTF_MIXIN
-wxString wxStringPrintfMixinBase::DoFormat(const wxChar *format, ...)
+wxString wxStringPrintfMixinBase::DoFormat(const wxString& format, ...)
 #else
-wxString wxString::DoFormat(const wxChar *format, ...)
+wxString wxString::DoFormat(const wxString& format, ...)
 #endif
 {
     va_list argptr;
@@ -1467,9 +1468,9 @@ wxString wxString::FormatV(const wxString& format, va_list argptr)
 }
 
 #ifdef wxNEEDS_WXSTRING_PRINTF_MIXIN
-int wxStringPrintfMixinBase::DoPrintf(const wxChar *format, ...)
+int wxStringPrintfMixinBase::DoPrintf(const wxString& format, ...)
 #else
-int wxString::DoPrintf(const wxChar *format, ...)
+int wxString::DoPrintf(const wxString& format, ...)
 #endif
 {
     va_list argptr;
@@ -1491,14 +1492,27 @@ int wxString::DoPrintf(const wxChar *format, ...)
     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;
 
     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;
+#endif
 
         if ( !buf )
         {
@@ -1510,7 +1524,7 @@ int wxString::PrintfV(const wxString& format, va_list argptr)
         // only a copy
         va_list argptrcopy;
         wxVaCopy(argptrcopy, argptr);
-        int len = wxVsnprintf(buf, size, (const wxChar*)/*FIXME-UTF8*/format, argptrcopy);
+        int len = wxVsnprintf(buf, size, format, argptrcopy);
         va_end(argptrcopy);
 
         // 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
-    Shrink();
+    str.Shrink();
+
+    return str.length();
+}
 
-    return 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
 }
 
 // ----------------------------------------------------------------------------
index ecf9ea5b1b30a8a28fc29b1f7e954c839d66fd12..3cafa8bf8066c15f62965ea8685d49b24604c1f1 100644 (file)
@@ -752,7 +752,6 @@ bool wxStringImpl::ConcatSelf(size_t nSrcLen,
   return true;
 }
 
-#if !wxUSE_UNICODE_UTF8
 // get the pointer to writable buffer of (at least) nLen bytes
 wxStringCharType *wxStringImpl::DoGetWriteBuf(size_t nLen)
 {
@@ -784,6 +783,5 @@ void wxStringImpl::DoUngetWriteBuf(size_t nLen)
   pData->nDataLength = nLen;
   pData->Validate(true);
 }
-#endif // !wxUSE_UNICODE_UTF8
 
 #endif // !wxUSE_STL_BASED_WXSTRING
index 81288c6f8943f918ebfd4ff2362691bf39909535..f18e2f0bc1551a792d961b13dc4870086bc324df 100644 (file)
 #endif
 
 #include "wx/strvararg.h"
-#include "wx/buffer.h"
-#include "wx/strconv.h"
 #include "wx/string.h"
 
 // ============================================================================
 // 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();
-#endif
-}
-
-#if wxUSE_UNICODE // FIXME-UTF8: should be wxUSE_UNICODE_WCHAR
-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
-    m_value = new wxWCharBuffer(wxConvLibc.cMB2WC(value));
-}
-
-wxArgNormalizer<const char*>::~wxArgNormalizer()
-{
-    delete m_value;
-}
-
-const wchar_t *wxArgNormalizer<const char*>::get() const
-{
-    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)
+const wxStringCharType *wxArgNormalizerNative<const wxCStrData&>::get() const
 {
-#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
+    return m_value.AsInternal();
 }
 
-wxArgNormalizer<const wchar_t*>::~wxArgNormalizer()
+#if wxUSE_UNICODE_UTF8
+wxArgNormalizerWchar<const wxString&>::wxArgNormalizerWchar(const wxString& s)
+    : wxArgNormalizerWithBuffer<wchar_t>(s.wc_str())
 {
-    delete m_value;
 }
 
-const char *wxArgNormalizer<const wchar_t*>::get() const
+wxArgNormalizerWchar<const wxCStrData&>::wxArgNormalizerWchar(const wxCStrData& s)
+    : wxArgNormalizerWithBuffer<wchar_t>(s.AsWCharBuf())
 {
-    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
 
-
-
-// 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())
+wxString wxArgNormalizedString::GetString() const
 {
+    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)
-    : wxArgNormalizer<const wchar_t*>(buf.data())
+wxArgNormalizedString::operator wxString() const
 {
+    return GetString();
 }
index 15bc111642605c060e814eca21e9a343aab55395..7a1c9363bbe90afccfe17813e5171f0e517fd4b2 100644 (file)
@@ -163,31 +163,16 @@ bool WXDLLEXPORT wxOKlibc()
     #undef wxVsprintf
     #undef wxVprintf
     #undef wxVsnprintf_
-    #undef wxSnprintf_
 
     #define wxNEED_WPRINTF
 
     int wxVfprintf( FILE *stream, const wxChar *format, va_list argptr );
 #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__)
     /* Digital Mars adds count to _stprintf (C99) so convert */
     #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;
 
@@ -527,7 +512,7 @@ wxString wxConvertFormat(const wxChar *format)
 
 #if defined(wxNEED_PRINTF_CONVERSION) || defined(wxNEED_WPRINTF)
 
-int wxDoScanf( const wxChar *format, ... )
+int wxCRT_Scanf( const wxChar *format, ... )
 {
     va_list argptr;
     va_start(argptr, format);
@@ -539,7 +524,7 @@ int wxDoScanf( const wxChar *format, ... )
     return ret;
 }
 
-int wxDoSscanf( const wxChar *str, const wxChar *format, ... )
+int wxCRT_Sscanf( const wxChar *str, const wxChar *format, ... )
 {
     va_list argptr;
     va_start(argptr, format);
@@ -551,7 +536,7 @@ int wxDoSscanf( const wxChar *str, const wxChar *format, ... )
     return ret;
 }
 
-int wxDoFscanf( FILE *stream, const wxChar *format, ... )
+int wxCRT_Fscanf( FILE *stream, const wxChar *format, ... )
 {
     va_list argptr;
     va_start(argptr, format);
@@ -562,7 +547,7 @@ int wxDoFscanf( FILE *stream, const wxChar *format, ... )
     return ret;
 }
 
-int wxDoPrintf( const wxChar *format, ... )
+int wxCRT_Printf( const wxChar *format, ... )
 {
     va_list argptr;
     va_start(argptr, format);
@@ -574,80 +559,247 @@ int wxDoPrintf( const wxChar *format, ... )
     return ret;
 }
 
-#ifndef wxSnprintf
-int wxDoSnprintf( wxChar *str, size_t size, const wxChar *format, ... )
+int wxCRT_Fprintf( FILE *stream, const wxChar *format, ... )
 {
     va_list argptr;
-    va_start(argptr, format);
-
-    int ret = vswprintf( str, size, wxFormatConverter(format), argptr );
+    va_start( argptr, format );
 
-    // VsnprintfTestCase reveals that glibc's implementation of vswprintf
-    // doesn't nul terminate on truncation.
-    str[size - 1] = 0;
+    int ret = vfwprintf( stream, wxFormatConverter(format), argptr );
 
     va_end(argptr);
 
     return ret;
 }
-#endif // wxSnprintf
 
-int wxDoSprintf( wxChar *str, const wxChar *format, ... )
+int wxCRT_Vsscanf( const wxChar *str, const wxChar *format, va_list argptr )
+{
+    return vswscanf( str, wxFormatConverter(format), argptr );
+}
+
+int wxCRT_Vfprintf( FILE *stream, const wxChar *format, va_list argptr )
+{
+    return vfwprintf( stream, wxFormatConverter(format), argptr );
+}
+
+int wxCRT_Vprintf( const wxChar *format, va_list argptr )
+{
+    return vwprintf( wxFormatConverter(format), argptr );
+}
+
+#ifndef wxCRT_Vsnprintf
+int wxCRT_Vsnprintf( wxChar *str, size_t size, const wxChar *format, va_list argptr )
+{
+    return vswprintf( str, size, wxFormatConverter(format), argptr );
+}
+#endif // wxCRT_Vsnprintf
+
+int wxCRT_Vsprintf( wxChar *str, const wxChar *format, va_list argptr )
+{
+    // same as for wxSprintf()
+    return vswprintf(str, INT_MAX / 4, wxFormatConverter(format), argptr);
+}
+
+#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);
 
-    // 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);
+    int rv = wxVsprintf(str, format, argptr);
 
     va_end(argptr);
+    return rv;
+}
+#endif
 
-    return s.length();
+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;
 }
 
-int wxDoFprintf( FILE *stream, const wxChar *format, ... )
+#if wxUSE_UNICODE
+int wxDoSnprintf(wchar_t *str, size_t size, const wxString& format, ...)
 {
     va_list argptr;
-    va_start( argptr, format );
+    va_start(argptr, format);
 
-    int ret = vfwprintf( stream, wxFormatConverter(format), argptr );
+    int rv = wxVsnprintf(str, size, format, argptr);
 
     va_end(argptr);
+    return rv;
+}
+#endif
 
-    return ret;
+
+#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);
 }
 
-int wxVsscanf( const wxChar *str, const wxChar *format, va_list argptr )
+#if wxUSE_UNICODE_UTF8
+static int ConvertStringToBuf(const wxString& s, wchar_t *out, size_t outsize)
 {
-    return vswscanf( str, wxFormatConverter(format), argptr );
+    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
 
-int wxVfprintf( FILE *stream, const wxChar *format, va_list argptr )
+template<typename T>
+static size_t PrintfViaString(T *out, size_t outsize,
+                              const wxString& format, va_list argptr)
 {
-    return vfwprintf( stream, wxFormatConverter(format), argptr );
+    va_list argcopy;
+    wxVaCopy(argcopy, argptr);
+
+    wxString s;
+    s.PrintfV(format, argcopy);
+
+    return ConvertStringToBuf(s, out, outsize);
 }
+#endif // wxUSE_UNICODE
 
-int wxVprintf( const wxChar *format, va_list argptr )
+int wxVsprintf(char *str, const wxString& format, va_list argptr)
 {
-    return vwprintf( wxFormatConverter(format), 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
 }
 
-#ifndef wxVsnprintf
-int wxVsnprintf( wxChar *str, size_t size, const wxChar *format, va_list argptr )
+#if wxUSE_UNICODE
+int wxVsprintf(wchar_t *str, const wxString& format, va_list argptr)
 {
-    return vswprintf( str, size, wxFormatConverter(format), 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 // wxVsnprintf
+#endif // wxUSE_UNICODE
 
-int wxVsprintf( wxChar *str, const wxChar *format, va_list argptr )
+int wxVsnprintf(char *str, size_t size, const wxString& format, va_list argptr)
 {
-    // same as for wxSprintf()
-    return vswprintf(str, INT_MAX / 4, wxFormatConverter(format), 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;
 }
 
-#endif // wxNEED_PRINTF_CONVERSION
+#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
 
index 5f8cef2b8ceebbabeb9477c84a210689cdb39a13..4aed1cad1f5a229cc8d78c586c1c32638caa152c 100644 (file)
@@ -143,8 +143,7 @@ typedef union {
     char pad_char;                      // %hc  (in ANSI mode: %c, too)
     wchar_t pad_wchar;                  // %lc  (in Unicode mode: %c, too)
 
-    char *pad_pchar;                    // %s   (related to a char *)
-    wchar_t *pad_pwchar;                // %s   (related to a wchar_t *)
+    void *pad_str;                      // %s
 
     int *pad_nint;                      // %n
     short int *pad_nshortint;           // %hn
@@ -616,10 +615,8 @@ bool wxPrintfConvSpec::LoadArg(wxPrintfArg *p, va_list &argptr)
             break;
 
         case wxPAT_PCHAR:
-            p->pad_pchar = va_arg(argptr, char *);
-            break;
         case wxPAT_PWCHAR:
-            p->pad_pwchar = va_arg(argptr, wchar_t *);
+            p->pad_str = va_arg(argptr, void *);
             break;
 
         case wxPAT_NINT:
@@ -735,54 +732,15 @@ int wxPrintfConvSpec::Process(wxChar *buf, size_t lenMax, wxPrintfArg *p, size_t
         case wxPAT_PCHAR:
         case wxPAT_PWCHAR:
             {
-                wxString s;
-                const wxChar *val =
-#if wxUSE_UNICODE
-                    p->pad_pwchar;
-
-                if (m_type == wxPAT_PCHAR)
-                {
-                    // user passed a string explicitely indicated as ANSI...
-                    val = s = wxString(p->pad_pchar, wxConvLibc);
+                wxArgNormalizedString arg(p->pad_str);
+                wxString s = arg;
 
-                    //wprintf(L"converting ANSI=>Unicode");   // for debug
-                }
-#else
-                    p->pad_pchar;
+                if ( !arg.IsValid() && m_nMaxWidth >= 6 )
+                    s = wxT("(null)");
 
-#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;
-                }
+                // at this point we are sure that m_nMaxWidth is positive or
+                // null (see top of wxPrintfConvSpec::LoadArg)
+                int len = wxMin((unsigned int)m_nMaxWidth, s.length());
 
                 int i;
 
@@ -794,11 +752,16 @@ int wxPrintfConvSpec::Process(wxChar *buf, size_t lenMax, wxPrintfArg *p, size_t
 
 #if wxUSE_STRUTILS
                 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;
 #else
-                for (i = 0; i < len; i++)
-                    APPEND_CH(val[i]);
+                wxString::const_iterator end = s.begin() + len;
+                for (wxString::const_iterator j = s.begin(); j != end; ++j)
+                    APPEND_CH(*j);
 #endif
 
                 if (m_bAlignLeft)
index 8547e03461b967c3a697e1f16969db3aade90707..dc74164100a22b436addc025819431c997528b86 100644 (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
 // be directed
-void wxVLogStatus(wxFrame *pFrame, const wxChar *szFormat, va_list argptr)
+void wxVLogStatus(wxFrame *pFrame, const wxString& format, va_list argptr)
 {
   wxString msg;
 
   wxLog *pLog = wxLog::GetActiveTarget();
   if ( pLog != NULL ) {
-    msg.PrintfV(szFormat, argptr);
+    msg.PrintfV(format, argptr);
 
     wxASSERT( gs_pFrame == NULL ); // should be reset!
     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_start(argptr, szFormat);
-    wxVLogStatus(pFrame, szFormat, argptr);
+    va_start(argptr, format);
+    wxVLogStatus(pFrame, format, argptr);
     va_end(argptr);
 }
 
@@ -588,7 +588,7 @@ void wxLogFrame::OnSave(wxCommandEvent& WXUNUSED(event))
         wxLogError(_("Can't save log contents to file."));
     }
     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
 }