+// ============================================================================
+// printf() functions business
+// ============================================================================
+
+// special test mode: define all functions below even if we don't really need
+// them to be able to test them
+#ifdef wxTEST_PRINTF
+ #undef wxFprintf
+ #undef wxPrintf
+ #undef wxSprintf
+ #undef wxVfprintf
+ #undef wxVsprintf
+ #undef wxVprintf
+ #undef wxVsnprintf_
+ #undef wxSnprintf_
+
+ #define wxNEED_WPRINTF
+
+ int wxVfprintf( FILE *stream, const wxChar *format, va_list argptr );
+#endif
+
+// ----------------------------------------------------------------------------
+// implement [v]snprintf() if the system doesn't provide a safe one
+// or if the system's one does not support positional parameters
+// (very useful for i18n purposes)
+// ----------------------------------------------------------------------------
+
+#if !defined(wxVsnprintf_)
+
+// wxUSE_STRUTILS says our wxVsnprintf_ implementation to use or not to
+// use wxStrlen and wxStrncpy functions over one-char processing loops.
+//
+// Some benchmarking revealed that wxUSE_STRUTILS == 1 has the following
+// effects:
+// -> on Windows:
+// when in ANSI mode, this setting does not change almost anything
+// when in Unicode mode, it gives ~ 50% of slowdown !
+// -> on Linux:
+// both in ANSI and Unicode mode it gives ~ 60% of speedup !
+//
+#if defined(WIN32) && wxUSE_UNICODE
+#define wxUSE_STRUTILS 0
+#else
+#define wxUSE_STRUTILS 1
+#endif
+
+// some limits of our implementation
+#define wxMAX_SVNPRINTF_ARGUMENTS 64
+#define wxMAX_SVNPRINTF_FLAGBUFFER_LEN 32
+
+// the conversion specifiers accepted by wxVsnprintf_
+enum wxPrintfArgType {
+ wxPAT_INVALID = -1,
+
+ wxPAT_INT, // %d, %i, %o, %u, %x, %X
+ wxPAT_LONGINT, // %ld, etc
+#if SIZEOF_LONG_LONG
+ wxPAT_LONGLONGINT, // %Ld, etc
+#endif
+ wxPAT_SIZET, // %Zd, etc
+
+ wxPAT_DOUBLE, // %e, %E, %f, %g, %G
+ wxPAT_LONGDOUBLE, // %le, etc
+
+ wxPAT_POINTER, // %p
+
+ wxPAT_CHAR, // %hc (in ANSI mode: %c, too)
+ wxPAT_WCHAR, // %lc (in Unicode mode: %c, too)
+
+ wxPAT_PCHAR, // %s (related to a char *)
+ wxPAT_PWCHAR, // %s (related to a wchar_t *)
+
+ wxPAT_NINT, // %n
+ wxPAT_NSHORTINT, // %hn
+ wxPAT_NLONGINT // %ln
+};
+
+// an argument passed to wxVsnprintf_
+typedef union {
+ int pad_int; // %d, %i, %o, %u, %x, %X
+ long int pad_longint; // %ld, etc
+#if SIZEOF_LONG_LONG
+ long long int pad_longlongint; // %Ld, etc
+#endif
+ size_t pad_sizet; // %Zd, etc
+
+ double pad_double; // %e, %E, %f, %g, %G
+ long double pad_longdouble; // %le, etc
+
+ void *pad_pointer; // %p
+
+ 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 *)
+
+ int *pad_nint; // %n
+ short int *pad_nshortint; // %hn
+ long int *pad_nlongint; // %ln
+} wxPrintfArg;
+
+
+// Contains parsed data relative to a conversion specifier given to
+// wxVsnprintf_ and parsed from the format string
+// NOTE: in C++ there is almost no difference between struct & classes thus
+// there is no performance gain by using a struct here...
+class wxPrintfConvSpec