]> git.saurik.com Git - wxWidgets.git/commitdiff
fixed wxScanf() etc. to compile with Visual C++ again
authorVáclav Slavík <vslavik@fastmail.fm>
Wed, 6 Jun 2007 13:48:24 +0000 (13:48 +0000)
committerVáclav Slavík <vslavik@fastmail.fm>
Wed, 6 Jun 2007 13:48:24 +0000 (13:48 +0000)
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@46341 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

include/wx/wxcrtvararg.h
src/common/wxcrt.cpp
tests/strings/vararg.cpp

index ab0ca2b12d55f6ca18787756f740fbf57b1ac568..a137d53a58b6e58e90bd2574c9d28aa8260fe9f0 100644 (file)
     #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 */
 
 #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_ */
index f461aa340c7be31056e9be5e3235496b2c289778..bf0a5b2f1138a025fd6f21ab4492e0e28496720d 100644 (file)
@@ -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__
index 95d24dca02f0da1c846c8ed25bce3d60e6aa1aee..de259e3534696169944f2250649287af1484a82a 100644 (file)
@@ -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 );
+}