From eb6cb2079398cd74e98627c9065454e338cb1e6c Mon Sep 17 00:00:00 2001 From: =?utf8?q?V=C3=A1clav=20Slav=C3=ADk?= Date: Wed, 6 Jun 2007 13:48:24 +0000 Subject: [PATCH] fixed wxScanf() etc. to compile with Visual C++ again git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@46341 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- include/wx/wxcrtvararg.h | 95 ++++++++++++++++++++++++++---------- src/common/wxcrt.cpp | 101 ++++++++++++++++++++++----------------- tests/strings/vararg.cpp | 20 ++++++++ 3 files changed, 145 insertions(+), 71 deletions(-) diff --git a/include/wx/wxcrtvararg.h b/include/wx/wxcrtvararg.h index ab0ca2b12d..a137d53a58 100644 --- a/include/wx/wxcrtvararg.h +++ b/include/wx/wxcrtvararg.h @@ -31,31 +31,17 @@ #define wxCRT_Vfprintf _vftprintf #define wxCRT_Vprintf _vtprintf #define wxCRT_Vsprintf _vstprintf - #define wxCRT_Vscanf _vtscanf - #define wxCRT_Vfscanf _vftscanf - #define wxCRT_Vsscanf _vstscanf #else /* !TCHAR-aware compilers */ #if !wxUSE_UNICODE /* ASCII */ #define wxCRT_Fprintf fprintf - #define wxCRT_Fscanf fscanf #define wxCRT_Printf printf #define wxCRT_Vfprintf vfprintf #define wxCRT_Vprintf vprintf #define wxCRT_Vsprintf vsprintf - #define wxCRT_Scanf scanf - #define wxCRT_Sscanf sscanf - #define wxCRT_Vsscanf vsscanf #endif /* ASCII */ #endif /* TCHAR-aware compilers/the others */ -/* Required for wxScanf() etc. */ -#define wxCRT_VscanfA vscanf -#define wxCRT_VsscanfA vsscanf -#define wxCRT_VfscanfA vfscanf -#define wxCRT_VscanfW vwscanf -#define wxCRT_VsscanfW vswscanf -#define wxCRT_VfscanfW vfwscanf /* printf() family saga */ @@ -238,6 +224,24 @@ #endif +/* Required for wxScanf() etc. */ +#define wxCRT_ScanfA scanf +#define wxCRT_SscanfA sscanf +#define wxCRT_FscanfA fscanf +#define wxCRT_VsscanfA vsscanf + +#if defined(wxNEED_PRINTF_CONVERSION) || defined(wxNEED_WPRINTF) + int wxCRT_ScanfW(const wchar_t *format, ...) ATTRIBUTE_PRINTF_1; + int wxCRT_SscanfW(const wchar_t *str, const wchar_t *format, ...) ATTRIBUTE_PRINTF_2; + int wxCRT_FscanfW(FILE *stream, const wchar_t *format, ...) ATTRIBUTE_PRINTF_2; + int wxCRT_VsscanfW(const wchar_t *str, const wchar_t *format, va_list ap); +#else + #define wxCRT_ScanfW wscanf + #define wxCRT_SscanfW swscanf + #define wxCRT_FscanfW fwscanf + #define wxCRT_VsscanfW vswscanf +#endif + // ---------------------------------------------------------------------------- // user-friendly wrappers to CRT functions // ---------------------------------------------------------------------------- @@ -387,21 +391,59 @@ wxVsnprintf(wchar_t *str, size_t size, const wxString& format, va_list argptr); // the type of output string values is determined by the type of format string // only. -int WXDLLIMPEXP_BASE wxScanf(const char *format, ...); -int WXDLLIMPEXP_BASE wxScanf(const wchar_t *format, ...); +#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 -int WXDLLIMPEXP_BASE wxFscanf(FILE *stream, const char *format, ...); -int WXDLLIMPEXP_BASE wxFscanf(FILE *stream, const wchar_t *format, ...); +#define _WX_VARARG_PASS_WRITABLE(i) a##i -int WXDLLIMPEXP_BASE wxSscanf(const char *str, const char *format, ...); -int WXDLLIMPEXP_BASE wxSscanf(const wchar_t *str, const wchar_t *format, ...); -int WXDLLIMPEXP_BASE wxSscanf(const wxCharBuffer& str, const char *format, ...); -int WXDLLIMPEXP_BASE wxSscanf(const wxWCharBuffer& str, const wchar_t *format, ...); -int WXDLLIMPEXP_BASE wxSscanf(const wxString& str, const char *format, ...); -int WXDLLIMPEXP_BASE wxSscanf(const wxString& str, const wchar_t *format, ...); -int WXDLLIMPEXP_BASE wxSscanf(const wxCStrData& str, const char *format, ...); -int WXDLLIMPEXP_BASE wxSscanf(const wxCStrData& str, const wchar_t *format, ...); +#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) + +WX_DEFINE_SCANFUNC(wxScanf, 1, (const char *format), + wxCRT_ScanfA, (format)) +WX_DEFINE_SCANFUNC(wxScanf, 1, (const wchar_t *format), + wxCRT_ScanfW, (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)) + +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)) +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)) +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)) +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)) + +// Visual C++ doesn't provide vsscanf() +#ifndef __VISUALC___ int WXDLLIMPEXP_BASE wxVsscanf(const char *str, const char *format, va_list ap); int WXDLLIMPEXP_BASE wxVsscanf(const wchar_t *str, const wchar_t *format, va_list ap); int WXDLLIMPEXP_BASE wxVsscanf(const wxCharBuffer& str, const char *format, va_list ap); @@ -410,5 +452,6 @@ int WXDLLIMPEXP_BASE wxVsscanf(const wxString& str, const char *format, va_list int WXDLLIMPEXP_BASE wxVsscanf(const wxString& str, const wchar_t *format, va_list ap); int WXDLLIMPEXP_BASE wxVsscanf(const wxCStrData& str, const char *format, va_list ap); int WXDLLIMPEXP_BASE wxVsscanf(const wxCStrData& str, const wchar_t *format, va_list ap); +#endif // !__VISUALC__ #endif /* _WX_WXCRTVARARG_H_ */ diff --git a/src/common/wxcrt.cpp b/src/common/wxcrt.cpp index f461aa340c..bf0a5b2f11 100644 --- a/src/common/wxcrt.cpp +++ b/src/common/wxcrt.cpp @@ -234,14 +234,14 @@ int /* not wint_t */ wxPutc(wchar_t wc, FILE *stream) #ifdef wxNEED_WPRINTF // TODO: implement the scanf() functions -int vwscanf(const wxChar *format, va_list argptr) +static int vwscanf(const wxChar *format, va_list argptr) { wxFAIL_MSG( _T("TODO") ); return -1; } -int vswscanf(const wxChar *ws, const wxChar *format, va_list argptr) +static int vswscanf(const wxChar *ws, const wxChar *format, va_list argptr) { // The best we can do without proper Unicode support in glibc is to // convert the strings into MB representation and run ANSI version @@ -256,7 +256,7 @@ int vswscanf(const wxChar *ws, const wxChar *format, va_list argptr) return vsscanf(wxConvLibc.cWX2MB(ws), wxConvLibc.cWX2MB(format), argptr); } -int vfwscanf(FILE *stream, const wxChar *format, va_list argptr) +static int vfwscanf(FILE *stream, const wxChar *format, va_list argptr) { wxFAIL_MSG( _T("TODO") ); @@ -265,7 +265,7 @@ int vfwscanf(FILE *stream, const wxChar *format, va_list argptr) #define vswprintf wxVsnprintf_ -int vfwprintf(FILE *stream, const wxChar *format, va_list argptr) +static int vfwprintf(FILE *stream, const wxChar *format, va_list argptr) { wxString s; int rc = s.PrintfV(format, argptr); @@ -280,7 +280,7 @@ int vfwprintf(FILE *stream, const wxChar *format, va_list argptr) return rc; } -int vwprintf(const wxChar *format, va_list argptr) +static int vwprintf(const wxChar *format, va_list argptr) { return wxVfprintf(stdout, format, argptr); } @@ -510,6 +510,11 @@ wxString wxConvertFormat(const wxChar *format) #if defined(wxNEED_PRINTF_CONVERSION) || defined(wxNEED_WPRINTF) +// FIXME-UTF8: do format conversion using (modified) wxFormatConverter in +// template wrappers, not here; note that it will needed to +// translate all forms of string specifiers to %(l)s for wxPrintf(), +// but it only should do what it did in 2.8 for wxScanf()! + int wxCRT_Printf( const wxChar *format, ... ) { va_list argptr; @@ -557,6 +562,46 @@ int wxCRT_Vsprintf( wxChar *str, const wxChar *format, va_list argptr ) return vswprintf(str, INT_MAX / 4, wxFormatConverter(format), argptr); } +int wxCRT_ScanfW(const wchar_t *format, ...) +{ + va_list argptr; + va_start(argptr, format); + + int ret = vwscanf(wxFormatConverter(format), argptr); + + va_end(argptr); + + return ret; +} + +int wxCRT_SscanfW(const wchar_t *str, const wchar_t *format, ...) +{ + va_list argptr; + va_start(argptr, format); + + int ret = vswscanf(str, wxFormatConverter(format), argptr); + + va_end(argptr); + + return ret; +} + +int wxCRT_FscanfW(FILE *stream, const wchar_t *format, ...) +{ + va_list argptr; + va_start(argptr, format); + int ret = vfwscanf(stream, wxFormatConverter(format), argptr); + + va_end(argptr); + + return ret; +} + +int wxCRT_VsscanfW(const wchar_t *str, const wchar_t *format, va_list argptr) +{ + return vswscanf(str, wxFormatConverter(format), argptr); +} + #endif // wxNEED_PRINTF_CONVERSION @@ -1603,55 +1648,21 @@ void wxUpdateLocaleIsUtf8() // wxScanf() and friends // ---------------------------------------------------------------------------- -// implement vararg function by calling a vfoo function that takes va_list -// argument; use "ap" for the va_list argument in "call" expression -#define IMPL_SCANFUNC(call) \ - va_list ap; \ - va_start(ap, format); \ - int retval = call; \ - va_end(ap); \ - return retval - -int wxScanf(const char *format, ...) - { IMPL_SCANFUNC( wxCRT_VscanfA(format, ap) ); } -int wxScanf(const wchar_t *format, ...) - { IMPL_SCANFUNC( wxCRT_VscanfW(wxFormatConverter(format), ap) ); } - -int wxFscanf(FILE *stream, const char *format, ...) - { IMPL_SCANFUNC( wxCRT_VfscanfA(stream, format, ap) ); } -int wxFscanf(FILE *stream, const wchar_t *format, ...) - { IMPL_SCANFUNC( wxCRT_VfscanfW(stream, wxFormatConverter(format), ap) ); } - -int wxSscanf(const char *str, const char *format, ...) - { IMPL_SCANFUNC( wxCRT_VsscanfA(str, format, ap) ); } -int wxSscanf(const wchar_t *str, const wchar_t *format, ...) - { IMPL_SCANFUNC( wxCRT_VsscanfW(str, wxFormatConverter(format), ap) ); } -int wxSscanf(const wxCharBuffer& str, const char *format, ...) - { IMPL_SCANFUNC( wxCRT_VsscanfA(str, format, ap) ); } -int wxSscanf(const wxWCharBuffer& str, const wchar_t *format, ...) - { IMPL_SCANFUNC( wxCRT_VsscanfW(str, wxFormatConverter(format), ap) ); } -int wxSscanf(const wxString& str, const char *format, ...) - { IMPL_SCANFUNC( wxCRT_VsscanfA(str.mb_str(), format, ap) ); } -int wxSscanf(const wxString& str, const wchar_t *format, ...) - { IMPL_SCANFUNC( wxCRT_VsscanfW(str.wc_str(), wxFormatConverter(format), ap) ); } -int wxSscanf(const wxCStrData& str, const char *format, ...) - { IMPL_SCANFUNC( wxCRT_VsscanfA(str.AsCharBuf(), format, ap) ); } -int wxSscanf(const wxCStrData& str, const wchar_t *format, ...) - { IMPL_SCANFUNC( wxCRT_VsscanfW(str.AsWCharBuf(), wxFormatConverter(format), ap) ); } - +#ifndef __VISUALC__ int wxVsscanf(const char *str, const char *format, va_list ap) { return wxCRT_VsscanfA(str, format, ap); } int wxVsscanf(const wchar_t *str, const wchar_t *format, va_list ap) - { return wxCRT_VsscanfW(str, wxFormatConverter(format), ap); } + { return wxCRT_VsscanfW(str, format, ap); } int wxVsscanf(const wxCharBuffer& str, const char *format, va_list ap) { return wxCRT_VsscanfA(str, format, ap); } int wxVsscanf(const wxWCharBuffer& str, const wchar_t *format, va_list ap) - { return wxCRT_VsscanfW(str, wxFormatConverter(format), ap); } + { return wxCRT_VsscanfW(str, format, ap); } int wxVsscanf(const wxString& str, const char *format, va_list ap) { return wxCRT_VsscanfA(str.mb_str(), format, ap); } int wxVsscanf(const wxString& str, const wchar_t *format, va_list ap) - { return wxCRT_VsscanfW(str.wc_str(), wxFormatConverter(format), ap); } + { return wxCRT_VsscanfW(str.wc_str(), format, ap); } int wxVsscanf(const wxCStrData& str, const char *format, va_list ap) { return wxCRT_VsscanfA(str.AsCharBuf(), format, ap); } int wxVsscanf(const wxCStrData& str, const wchar_t *format, va_list ap) - { return wxCRT_VsscanfW(str.AsWCharBuf(), wxFormatConverter(format), ap); } + { return wxCRT_VsscanfW(str.AsWCharBuf(), format, ap); } +#endif // !__VISUALC__ diff --git a/tests/strings/vararg.cpp b/tests/strings/vararg.cpp index 95d24dca02..de259e3534 100644 --- a/tests/strings/vararg.cpp +++ b/tests/strings/vararg.cpp @@ -39,12 +39,14 @@ private: #if wxUSE_STD_STRING CPPUNIT_TEST( StdString ); #endif + CPPUNIT_TEST( Sscanf ); CPPUNIT_TEST_SUITE_END(); void StringPrintf(); #if wxUSE_STD_STRING void StdString(); #endif + void Sscanf(); DECLARE_NO_COPY_CLASS(VarArgTestCase) }; @@ -108,3 +110,21 @@ void VarArgTestCase::StdString() CPPUNIT_ASSERT( s == "string widechar(2)." ); } #endif // wxUSE_STD_STRING + +void VarArgTestCase::Sscanf() +{ + int i = 0; + char str[20]; + wchar_t wstr[20]; + + wxString input("42 test"); + + wxSscanf(input, "%d %s", &i, &str); + CPPUNIT_ASSERT( i == 42 ); + CPPUNIT_ASSERT( wxStrcmp(str, "test") == 0 ); + + i = 0; + wxSscanf(input, L"%d %s", &i, &wstr); + CPPUNIT_ASSERT( i == 42 ); + CPPUNIT_ASSERT( wxStrcmp(wstr, "test") == 0 ); +} -- 2.49.0