+WX_DEFINE_VARARG_FUNC(int, wxPrintf, 1, (const wxFormatString&),
+ wxCRT_PrintfNative, wxCRT_PrintfA)
+WX_DEFINE_VARARG_FUNC(int, wxFprintf, 2, (FILE*, const wxFormatString&),
+ wxCRT_FprintfNative, wxCRT_FprintfA)
+
+// 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, implW, implA) \
+ return implA args
+ #else
+ #define WX_VARARG_VFOO_IMPL(args, implW, implA) \
+ if ( wxLocaleIsUtf8 ) return implA args; \
+ else return implW args
+ #endif
+#elif wxUSE_UNICODE_WCHAR
+ #define WX_VARARG_VFOO_IMPL(args, implW, implA) \
+ return implW args
+#else // ANSI
+ #define WX_VARARG_VFOO_IMPL(args, implW, implA) \
+ return implA args
+#endif
+
+inline int
+wxVprintf(const wxString& format, va_list ap)
+{
+ WX_VARARG_VFOO_IMPL((wxFormatString(format), ap),
+ wxCRT_VprintfW, wxCRT_VprintfA);
+}
+
+inline int
+wxVfprintf(FILE *f, const wxString& format, va_list ap)
+{
+ WX_VARARG_VFOO_IMPL((f, wxFormatString(format), ap),
+ wxCRT_VfprintfW, wxCRT_VfprintfA);
+}
+
+#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*:
+
+#if !wxUSE_UTF8_LOCALE_ONLY
+int WXDLLIMPEXP_BASE wxDoSprintfWchar(char *str, const wxChar *format, ...);
+#endif
+#if wxUSE_UNICODE_UTF8
+int WXDLLIMPEXP_BASE wxDoSprintfUtf8(char *str, const char *format, ...);
+#endif
+WX_DEFINE_VARARG_FUNC(int, wxSprintf, 2, (char*, const wxFormatString&),
+ wxDoSprintfWchar, wxDoSprintfUtf8)
+
+int WXDLLIMPEXP_BASE
+wxVsprintf(char *str, const wxString& format, va_list argptr);
+
+#if !wxUSE_UTF8_LOCALE_ONLY
+int WXDLLIMPEXP_BASE wxDoSnprintfWchar(char *str, size_t size, const wxChar *format, ...);
+#endif
+#if wxUSE_UNICODE_UTF8
+int WXDLLIMPEXP_BASE wxDoSnprintfUtf8(char *str, size_t size, const char *format, ...);
+#endif
+WX_DEFINE_VARARG_FUNC(int, wxSnprintf, 3, (char*, size_t, const wxFormatString&),
+ wxDoSnprintfWchar, wxDoSnprintfUtf8)
+
+int WXDLLIMPEXP_BASE
+wxVsnprintf(char *str, size_t size, const wxString& format, va_list argptr);
+
+#if wxUSE_UNICODE
+
+#if !wxUSE_UTF8_LOCALE_ONLY
+int WXDLLIMPEXP_BASE wxDoSprintfWchar(wchar_t *str, const wxChar *format, ...);
+#endif
+#if wxUSE_UNICODE_UTF8
+int WXDLLIMPEXP_BASE wxDoSprintfUtf8(wchar_t *str, const char *format, ...);
+#endif
+WX_DEFINE_VARARG_FUNC(int, wxSprintf, 2, (wchar_t*, const wxFormatString&),
+ wxDoSprintfWchar, wxDoSprintfUtf8)
+
+int WXDLLIMPEXP_BASE
+wxVsprintf(wchar_t *str, const wxString& format, va_list argptr);
+
+#if !wxUSE_UTF8_LOCALE_ONLY
+int WXDLLIMPEXP_BASE wxDoSnprintfWchar(wchar_t *str, size_t size, const wxChar *format, ...);
+#endif
+#if wxUSE_UNICODE_UTF8
+int WXDLLIMPEXP_BASE wxDoSnprintfUtf8(wchar_t *str, size_t size, const char *format, ...);
+#endif
+WX_DEFINE_VARARG_FUNC(int, wxSnprintf, 3, (wchar_t*, size_t, const wxFormatString&),
+ wxDoSnprintfWchar, wxDoSnprintfUtf8)
+
+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(wxFormatString(fmt), __VA_ARGS__)
+ #define wxFprintf(f, fmt, ...) \
+ wxFprintf_Impl(f, wxFormatString(fmt), __VA_ARGS__)
+ #define wxSprintf(s, fmt, ...) \
+ wxSprintf_Impl(s, wxFormatString(fmt), __VA_ARGS__)
+ #define wxSnprintf(s, n, fmt, ...) \
+ wxSnprintf_Impl(s, n, wxFormatString(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.
+//
+// For compatibility with earlier wx versions, we also provide wxSscanf()
+// version with the first argument (input string) wxString; for this version,
+// the type of output string values is determined by the type of format string
+// only.
+
+#define _WX_SCANFUNC_EXTRACT_ARGS_1(x) x
+#define _WX_SCANFUNC_EXTRACT_ARGS_2(x,y) x, y
+#define _WX_SCANFUNC_EXTRACT_ARGS(N, args) _WX_SCANFUNC_EXTRACT_ARGS_##N args
+
+#define _WX_VARARG_PASS_WRITABLE(i) a##i
+
+#define _WX_DEFINE_SCANFUNC(N, dummy1, name, impl, passfixed, numfixed, fixed)\
+ template<_WX_VARARG_JOIN(N, _WX_VARARG_TEMPL)> \
+ int name(_WX_SCANFUNC_EXTRACT_ARGS(numfixed, fixed), \
+ _WX_VARARG_JOIN(N, _WX_VARARG_ARG)) \
+ { \
+ return impl(_WX_SCANFUNC_EXTRACT_ARGS(numfixed, passfixed), \
+ _WX_VARARG_JOIN(N, _WX_VARARG_PASS_WRITABLE)); \
+ }
+
+#define WX_DEFINE_SCANFUNC(name, numfixed, fixed, impl, passfixed) \
+ inline int name(_WX_SCANFUNC_EXTRACT_ARGS(numfixed, fixed)) \
+ { \
+ return impl(_WX_SCANFUNC_EXTRACT_ARGS(numfixed, passfixed)); \
+ } \
+ _WX_VARARG_ITER(_WX_VARARG_MAX_ARGS, \
+ _WX_DEFINE_SCANFUNC, \
+ dummy1, name, impl, passfixed, numfixed, fixed)
+
+// this is needed to normalize the format string, see src/common/strvararg.cpp
+// for more details
+#ifdef __WINDOWS__
+ #define wxScanfConvertFormatW(fmt) fmt