normalize printf/scanf format strings correctly on all platforms, while accounting for wxArgNormalizer<T> conversions
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@46618 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -80,7 +80,7 @@
|
||||
*/
|
||||
#if defined(HAVE_UNIX98_PRINTF)
|
||||
#ifdef HAVE_VSWPRINTF
|
||||
#define wxCRT_VsnprintfW_ vswprintf
|
||||
#define wxCRT_VsnprintfW vswprintf
|
||||
#endif
|
||||
#ifdef HAVE_BROKEN_VSNPRINTF_DECL
|
||||
#define wxCRT_VsnprintfA wx_fixed_vsnprintf
|
||||
@@ -96,7 +96,7 @@
|
||||
*/
|
||||
#if defined _MSC_FULL_VER && _MSC_FULL_VER >= 140050727 && !defined __WXWINCE__
|
||||
#define wxCRT_VsnprintfA _vsprintf_p
|
||||
#define wxCRT_VsnprintfW_ _vswprintf_p
|
||||
#define wxCRT_VsnprintfW _vswprintf_p
|
||||
#endif
|
||||
#endif /* HAVE_UNIX98_PRINTF/!HAVE_UNIX98_PRINTF */
|
||||
#else /* !wxUSE_PRINTF_POS_PARAMS */
|
||||
@@ -113,14 +113,14 @@
|
||||
#if defined(__VISUALC__) || \
|
||||
(defined(__BORLANDC__) && __BORLANDC__ >= 0x540)
|
||||
#define wxCRT_VsnprintfA _vsnprintf
|
||||
#define wxCRT_VsnprintfW_ _vsnwprintf
|
||||
#define wxCRT_VsnprintfW _vsnwprintf
|
||||
#else
|
||||
#if defined(HAVE__VSNWPRINTF)
|
||||
#define wxCRT_VsnprintfW_ _vsnwprintf
|
||||
#define wxCRT_VsnprintfW _vsnwprintf
|
||||
#elif defined(HAVE_VSWPRINTF)
|
||||
#define wxCRT_VsnprintfW_ vswprintf
|
||||
#define wxCRT_VsnprintfW vswprintf
|
||||
#elif defined(__WATCOMC__)
|
||||
#define wxCRT_VsnprintfW_ _vsnwprintf
|
||||
#define wxCRT_VsnprintfW _vsnwprintf
|
||||
#endif
|
||||
|
||||
/*
|
||||
@@ -138,10 +138,10 @@
|
||||
#endif
|
||||
#endif /* wxUSE_PRINTF_POS_PARAMS/!wxUSE_PRINTF_POS_PARAMS */
|
||||
|
||||
#ifndef wxCRT_VsnprintfW_
|
||||
#ifndef wxCRT_VsnprintfW
|
||||
/* no (suitable) vsnprintf(), cook our own */
|
||||
WXDLLIMPEXP_BASE int
|
||||
wxCRT_VsnprintfW_(wchar_t *buf, size_t len, const wchar_t *format, va_list argptr);
|
||||
wxCRT_VsnprintfW(wchar_t *buf, size_t len, const wchar_t *format, va_list argptr);
|
||||
#define wxUSE_WXVSNPRINTFW 1
|
||||
#else
|
||||
#define wxUSE_WXVSNPRINTFW 0
|
||||
@@ -175,35 +175,16 @@
|
||||
#define wxCRT_VprintfA vprintf
|
||||
#define wxCRT_VsprintfA vsprintf
|
||||
|
||||
/*
|
||||
More Unicode complications: although both ANSI C and C++ define a number of
|
||||
wide character functions such as wprintf(), not all environments have them.
|
||||
Worse, those which do have different behaviours: under Windows, %s format
|
||||
specifier changes its meaning in Unicode build and expects a Unicode string
|
||||
while under Unix/POSIX it still means an ASCII string even for wprintf() and
|
||||
%ls has to be used for wide strings.
|
||||
#define wxCRT_FprintfW fwprintf
|
||||
#define wxCRT_PrintfW wprintf
|
||||
#define wxCRT_VfprintfW vfwprintf
|
||||
#define wxCRT_VprintfW vwprintf
|
||||
|
||||
We choose to always emulate Windows behaviour as more useful for us so even
|
||||
if we have wprintf() we still must wrap it in a non trivial wxPrintf().
|
||||
|
||||
*/
|
||||
#ifndef __WINDOWS__
|
||||
#define wxNEED_PRINTF_CONVERSION
|
||||
#if defined(__WINDOWS__) && !HAVE_VSWPRINTF
|
||||
// only non-standard vswprintf() without buffer size argument can be used here
|
||||
#define wxCRT_VsprintfW vswprintf
|
||||
#endif
|
||||
|
||||
// FIXME-UTF8: format conversion should be moved outside of wxCRT_* and to the
|
||||
// vararg templates; after then, wxNEED_PRINTF_CONVERSION should
|
||||
// be removed and this code simplified
|
||||
#ifndef wxNEED_PRINTF_CONVERSION
|
||||
#ifdef wxHAVE_TCHAR_SUPPORT
|
||||
#define wxCRT_FprintfW fwprintf
|
||||
#define wxCRT_PrintfW wprintf
|
||||
#define wxCRT_VfprintfW vfwprintf
|
||||
#define wxCRT_VprintfW vwprintf
|
||||
#define wxCRT_VsprintfW vswprintf
|
||||
#endif
|
||||
#endif // !defined(wxNEED_PRINTF_CONVERSION)
|
||||
|
||||
/*
|
||||
In Unicode mode we need to have all standard functions such as wprintf() and
|
||||
so on but not all systems have them so use our own implementations in this
|
||||
@@ -214,7 +195,7 @@
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(wxNEED_PRINTF_CONVERSION) || defined(wxNEED_WPRINTF)
|
||||
#if defined(wxNEED_WPRINTF)
|
||||
/*
|
||||
we need to implement all wide character printf functions either because
|
||||
we don't have them at all or because they don't have the semantics we
|
||||
@@ -225,19 +206,7 @@
|
||||
int wxCRT_VfprintfW( FILE *stream, const wchar_t *format, va_list ap );
|
||||
int wxCRT_VprintfW( const wchar_t *format, va_list ap );
|
||||
int wxCRT_VsprintfW( wchar_t *str, const wchar_t *format, va_list ap );
|
||||
#endif /* wxNEED_PRINTF_CONVERSION */
|
||||
|
||||
/* these 2 can be simply mapped to the versions with underscore at the end */
|
||||
/* if we don't have to do the conversion */
|
||||
/*
|
||||
However, if we don't have any vswprintf() at all we don't need to redefine
|
||||
anything as our own wxCRT_VsnprintfW_() already behaves as needed.
|
||||
*/
|
||||
#if defined(wxNEED_PRINTF_CONVERSION) && defined(wxCRT_VsnprintfW_)
|
||||
int wxCRT_VsnprintfW( wchar_t *str, size_t size, const wchar_t *format, va_list ap );
|
||||
#else
|
||||
#define wxCRT_VsnprintfW wxCRT_VsnprintfW_
|
||||
#endif
|
||||
#endif /* wxNEED_WPRINTF */
|
||||
|
||||
|
||||
/* Required for wxScanf() etc. */
|
||||
@@ -246,7 +215,7 @@
|
||||
#define wxCRT_FscanfA fscanf
|
||||
#define wxCRT_VsscanfA vsscanf
|
||||
|
||||
#if defined(wxNEED_PRINTF_CONVERSION) || defined(wxNEED_WPRINTF)
|
||||
#if defined(wxNEED_WPRINTF)
|
||||
int wxCRT_ScanfW(const wchar_t *format, ...);
|
||||
int wxCRT_SscanfW(const wchar_t *str, const wchar_t *format, ...);
|
||||
int wxCRT_FscanfW(FILE *stream, const wchar_t *format, ...);
|
||||
@@ -270,17 +239,6 @@
|
||||
#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
|
||||
|
||||
// FIXME-UTF8: remove this
|
||||
#if wxUSE_UNICODE
|
||||
#define wxCRT_PrintfNative wxCRT_PrintfW
|
||||
@@ -443,32 +401,41 @@ wxVsnprintf(wchar_t *str, size_t size, const wxString& format, va_list argptr);
|
||||
_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
|
||||
#else
|
||||
const wxWCharBuffer
|
||||
WXDLLIMPEXP_BASE wxScanfConvertFormatW(const wchar_t *format);
|
||||
#endif
|
||||
|
||||
WX_DEFINE_SCANFUNC(wxScanf, 1, (const char *format),
|
||||
wxCRT_ScanfA, (format))
|
||||
WX_DEFINE_SCANFUNC(wxScanf, 1, (const wchar_t *format),
|
||||
wxCRT_ScanfW, (format))
|
||||
wxCRT_ScanfW, (wxScanfConvertFormatW(format)))
|
||||
|
||||
WX_DEFINE_SCANFUNC(wxFscanf, 2, (FILE *stream, const char *format),
|
||||
wxCRT_FscanfA, (stream, format))
|
||||
WX_DEFINE_SCANFUNC(wxFscanf, 2, (FILE *stream, const wchar_t *format),
|
||||
wxCRT_FscanfW, (stream, format))
|
||||
wxCRT_FscanfW, (stream, wxScanfConvertFormatW(format)))
|
||||
|
||||
WX_DEFINE_SCANFUNC(wxSscanf, 2, (const char *str, const char *format),
|
||||
wxCRT_SscanfA, (str, format))
|
||||
WX_DEFINE_SCANFUNC(wxSscanf, 2, (const wchar_t *str, const wchar_t *format),
|
||||
wxCRT_SscanfW, (str, format))
|
||||
wxCRT_SscanfW, (str, wxScanfConvertFormatW(format)))
|
||||
WX_DEFINE_SCANFUNC(wxSscanf, 2, (const wxCharBuffer& str, const char *format),
|
||||
wxCRT_SscanfA, (str.data(), format))
|
||||
WX_DEFINE_SCANFUNC(wxSscanf, 2, (const wxWCharBuffer& str, const wchar_t *format),
|
||||
wxCRT_SscanfW, (str.data(), format))
|
||||
wxCRT_SscanfW, (str.data(), wxScanfConvertFormatW(format)))
|
||||
WX_DEFINE_SCANFUNC(wxSscanf, 2, (const wxString& str, const char *format),
|
||||
wxCRT_SscanfA, (str.mb_str(), format))
|
||||
WX_DEFINE_SCANFUNC(wxSscanf, 2, (const wxString& str, const wchar_t *format),
|
||||
wxCRT_SscanfW, (str.wc_str(), format))
|
||||
wxCRT_SscanfW, (str.wc_str(), wxScanfConvertFormatW(format)))
|
||||
WX_DEFINE_SCANFUNC(wxSscanf, 2, (const wxCStrData& str, const char *format),
|
||||
wxCRT_SscanfA, (str.AsCharBuf(), format))
|
||||
WX_DEFINE_SCANFUNC(wxSscanf, 2, (const wxCStrData& str, const wchar_t *format),
|
||||
wxCRT_SscanfW, (str.AsWCharBuf(), format))
|
||||
wxCRT_SscanfW, (str.AsWCharBuf(), wxScanfConvertFormatW(format)))
|
||||
|
||||
// Visual C++ doesn't provide vsscanf()
|
||||
#ifndef __VISUALC___
|
||||
|
Reference in New Issue
Block a user