]> git.saurik.com Git - wxWidgets.git/blobdiff - include/wx/wxcrtvararg.h
Adapted to API changes with respect to GetTextExtent (patch #1709152).
[wxWidgets.git] / include / wx / wxcrtvararg.h
index c036b33ecf24d3083d187fd2972b3fee37bf4b0c..6ddb99ff1cb69cfec89241c4e038256ad93bad2d 100644 (file)
 #include "wx/wxcrt.h"
 #include "wx/strvararg.h"
 
+#include "wx/string.h"
+
+// ----------------------------------------------------------------------------
+// CRT functions aliases
+// ----------------------------------------------------------------------------
 
 /* Required for wxPrintf() etc */
 #include <stdarg.h>
 
 #ifdef wxHAVE_TCHAR_SUPPORT
-    WX_DEFINE_VARARG_FUNC(int, wxFprintf, _ftprintf)
-    WX_DEFINE_VARARG_FUNC(int, wxPrintf, _tprintf)
-    #define  wxPutc(c,f) _puttc(WXWCHAR_T_CAST(c),f)
-    #define  wxPutchar   _puttchar
-    #define  wxPuts      _putts
-    #define  wxScanf     _tscanf  /* FIXME-UTF8: not wrapped */
-    #if defined(__DMC__)
-        #if wxUSE_UNICODE
-            /* Digital Mars adds count to _stprintf (C99) so prototype conversion see wxchar.cpp */
-            int wxDoSprintf (wchar_t * __RESTRICT s, const wchar_t * __RESTRICT format, ... ) ;
-            WX_DEFINE_VARARG_FUNC(int, wxSprintf, wxDoSprintf)
-        #else
-            /* and there is a bug in D Mars tchar.h prior to 8.39.4n, so define
-               as sprintf */
-            WX_DEFINE_VARARG_FUNC(int, wxSprintf, sprintf)
-        #endif
-    #else
-        WX_DEFINE_VARARG_FUNC(int, wxSprintf, _stprintf)
-    #endif
+    #define  wxCRT_Fprintf   _ftprintf
+    #define  wxCRT_Printf    _tprintf
+    #define  wxCRT_Scanf     _tscanf
 
-    /* FIXME-UTF8: not wrapped */
-    #define  wxSscanf    _stscanf
-    #define  wxVfprintf  _vftprintf
-    #define  wxVprintf   _vtprintf
-    #define  wxVsscanf   _vstscanf
-    #define  wxVsprintf  _vstprintf
+    #define  wxCRT_Sscanf    _stscanf
+    #define  wxCRT_Vfprintf  _vftprintf
+    #define  wxCRT_Vprintf   _vtprintf
+    #define  wxCRT_Vsscanf   _vstscanf
+    #define  wxCRT_Vsprintf  _vstprintf
 
 #else /* !TCHAR-aware compilers */
 
     #if !wxUSE_UNICODE /* ASCII */
-        WX_DEFINE_VARARG_FUNC(int, wxFprintf, fprintf)
-        #define  wxFscanf    fscanf
-        WX_DEFINE_VARARG_FUNC(int, wxPrintf, printf)
-        #define  wxScanf     scanf
-        WX_DEFINE_VARARG_FUNC(int, wxSprintf, sprintf)
-        #define  wxSscanf    sscanf
-        #define  wxVfprintf  vfprintf
-        #define  wxVprintf   vprintf
-        #define  wxVsscanf   vsscanf
-        #define  wxVsprintf  vsprintf
+        #define  wxCRT_Fprintf   fprintf
+        #define  wxCRT_Fscanf    fscanf
+        #define  wxCRT_Printf    printf
+        #define  wxCRT_Scanf     scanf
+        #define  wxCRT_Sscanf    sscanf
+        #define  wxCRT_Vfprintf  vfprintf
+        #define  wxCRT_Vprintf   vprintf
+        #define  wxCRT_Vsscanf   vsscanf
+        #define  wxCRT_Vsprintf  vsprintf
     #endif /* ASCII */
 #endif /* TCHAR-aware compilers/the others */
 
     #ifndef wxVsnprintf_
         #if defined(__VISUALC__) || \
                 (defined(__BORLANDC__) && __BORLANDC__ >= 0x540)
-            #define wxSnprintf_     _sntprintf
             #define wxVsnprintf_    _vsntprintf
-            WX_DEFINE_VARARG_FUNC(int, wxSnprintf_, _sntprintf)
         #endif
     #endif
 
                 #define wxVsnprintf_     vswprintf
             #elif defined(__WATCOMC__)
                 #define wxVsnprintf_    _vsnwprintf
-                WX_DEFINE_VARARG_FUNC(int, wxSnprintf_, _snwprintf)
             #endif
         #else /* ASCII */
             /*
                All versions of CodeWarrior supported by wxWidgets apparently
                have both snprintf() and vsnprintf()
              */
-            #if defined(HAVE_SNPRINTF) \
-                || defined(__MWERKS__) || defined(__WATCOMC__)
-                #ifndef HAVE_BROKEN_SNPRINTF_DECL
-                    WX_DEFINE_VARARG_FUNC(int, wxSnprintf_, snprintf)
-                #endif
-            #endif
             #if defined(HAVE_VSNPRINTF) \
                 || defined(__MWERKS__) || defined(__WATCOMC__)
                 #ifdef HAVE_BROKEN_VSNPRINTF_DECL
     #endif /* wxVsnprintf_ */
 #endif /* wxUSE_PRINTF_POS_PARAMS/!wxUSE_PRINTF_POS_PARAMS */
 
-#ifndef wxSnprintf_
-    /* no snprintf(), cook our own */
-    WXDLLIMPEXP_BASE int
-    wxDoSnprintf_(wxChar *buf, size_t len,
-                  const wxChar *format, ...) ATTRIBUTE_PRINTF_3;
-    WX_DEFINE_VARARG_FUNC(int, wxSnprintf_, wxDoSnprintf_)
-#endif
 #ifndef wxVsnprintf_
     /* no (suitable) vsnprintf(), cook our own */
     WXDLLIMPEXP_BASE int
-    wxVsnprintf_(wxChar *buf, size_t len,
-                 const wxChar *format, va_list argptr);
+    wxVsnprintf_(wxChar *buf, size_t len, const wxChar *format, va_list argptr);
 
     #define wxUSE_WXVSNPRINTF 1
 #else
         either because we don't have them at all or because they don't have the
         semantics we need
      */
-    WX_DEFINE_VARARG_FUNC(int, wxScanf, wxDoScanf)
-    int wxDoScanf( const wxChar *format, ... ) ATTRIBUTE_PRINTF_1;
-
-    WX_DEFINE_VARARG_FUNC(int, wxSscanf, wxDoSscanf)
-    int wxDoSscanf( const wxChar *str, const wxChar *format, ... ) ATTRIBUTE_PRINTF_2;
-
-    WX_DEFINE_VARARG_FUNC(int, wxFscanf, wxDoFscanf)
-    int wxDoFscanf( FILE *stream, const wxChar *format, ... ) ATTRIBUTE_PRINTF_2;
-
-    WX_DEFINE_VARARG_FUNC(int, wxPrintf, wxDoPrintf)
-    int wxDoPrintf( const wxChar *format, ... ) ATTRIBUTE_PRINTF_1;
-
-    WX_DEFINE_VARARG_FUNC(int, wxSprintf, wxDoSprintf)
-    int wxDoSprintf( wxChar *str, const wxChar *format, ... ) ATTRIBUTE_PRINTF_2;
-
-    WX_DEFINE_VARARG_FUNC(int, wxFprintf, wxDoFprintf)
-    int wxDoFprintf( FILE *stream, const wxChar *format, ... ) ATTRIBUTE_PRINTF_2;
-
-    int wxVsscanf( const wxChar *str, const wxChar *format, va_list ap );
-    int wxVfprintf( FILE *stream, const wxChar *format, va_list ap );
-    int wxVprintf( const wxChar *format, va_list ap );
-    int wxVsprintf( wxChar *str, const wxChar *format, va_list ap );
+    int wxCRT_Scanf( const wxChar *format, ... ) ATTRIBUTE_PRINTF_1;
+    int wxCRT_Sscanf( const wxChar *str, const wxChar *format, ... ) ATTRIBUTE_PRINTF_2;
+    int wxCRT_Fscanf( FILE *stream, const wxChar *format, ... ) ATTRIBUTE_PRINTF_2;
+    int wxCRT_Vsscanf( const wxChar *str, const wxChar *format, va_list ap );
+    int wxCRT_Printf( const wxChar *format, ... ) ATTRIBUTE_PRINTF_1;
+    int wxCRT_Fprintf( FILE *stream, const wxChar *format, ... ) ATTRIBUTE_PRINTF_2;
+    int wxCRT_Vfprintf( FILE *stream, const wxChar *format, va_list ap );
+    int wxCRT_Vprintf( const wxChar *format, va_list ap );
+    int wxCRT_Vsprintf( wxChar *str, const wxChar *format, va_list ap );
 #endif /* wxNEED_PRINTF_CONVERSION */
 
 /* these 2 can be simply mapped to the versions with underscore at the end */
    anything as our own wxVsnprintf_() already behaves as needed.
 */
 #if defined(wxNEED_PRINTF_CONVERSION) && defined(wxVsnprintf_)
-    WX_DEFINE_VARARG_FUNC(int, wxSnprintf, wxDoSnprintf)
-    int wxDoSnprintf( wxChar *str, size_t size, const wxChar *format, ... ) ATTRIBUTE_PRINTF_3;
-    int wxVsnprintf( wxChar *str, size_t size, const wxChar *format, va_list ap );
+    int wxCRT_Vsnprintf( wxChar *str, size_t size, const wxChar *format, va_list ap );
 #else
-    #define wxSnprintf wxSnprintf_
-    #define wxVsnprintf wxVsnprintf_
+    #define wxCRT_Vsnprintf wxVsnprintf_
+#endif
+
+
+// ----------------------------------------------------------------------------
+// user-friendly wrappers to CRT functions
+// ----------------------------------------------------------------------------
+
+#ifdef __WATCOMC__
+    // workaround for http://bugzilla.openwatcom.org/show_bug.cgi?id=351
+    #define wxPrintf    wxPrintf_Impl
+    #define wxFprintf   wxFprintf_Impl
+    #define wxSprintf   wxSprintf_Impl
+    #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
+
+WX_DEFINE_VARARG_FUNC2(int, wxPrintf, 1, (const wxString&),
+                       wxCRT_Printf, printf)
+WX_DEFINE_VARARG_FUNC2(int, wxFprintf, 2, (FILE*, const wxString&),
+                       wxCRT_Fprintf, fprintf)
+
+// 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, implWchar, implUtf8)              \
+            return implUtf8 args
+    #else
+        #define WX_VARARG_VFOO_IMPL(args, implWchar, implUtf8)              \
+            if ( wxLocaleIsUtf8 ) return implUtf8 args;                     \
+            else return implWchar args
+    #endif
+#else // wxUSE_UNICODE_WCHAR / ANSI
+    #define WX_VARARG_VFOO_IMPL(args, implWchar, implUtf8)                  \
+        return implWchar args
 #endif
 
+inline int
+wxVprintf(const wxString& format, va_list ap)
+{
+    WX_VARARG_VFOO_IMPL((format, ap), wxCRT_Vprintf, vprintf);
+}
+
+inline int
+wxVfprintf(FILE *f, const wxString& format, va_list ap)
+{
+    WX_VARARG_VFOO_IMPL((f, format, ap), wxCRT_Vfprintf, vfprintf);
+}
+
+#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*:
+
+int WXDLLIMPEXP_BASE wxDoSprintf(char *str, const wxString& format, ...);
+WX_DEFINE_VARARG_FUNC(int, wxSprintf, 2, (char*, const wxString&),
+                      wxDoSprintf)
+
+int WXDLLIMPEXP_BASE
+wxVsprintf(char *str, const wxString& format, va_list argptr);
+
+int WXDLLIMPEXP_BASE wxDoSnprintf(char *str, size_t size, const wxString& format, ...);
+WX_DEFINE_VARARG_FUNC(int, wxSnprintf, 3, (char*, size_t, const wxString&),
+                      wxDoSnprintf)
+
+int WXDLLIMPEXP_BASE
+wxVsnprintf(char *str, size_t size, const wxString& format, va_list argptr);
+
+#if wxUSE_UNICODE
+int WXDLLIMPEXP_BASE wxDoSprintf(wchar_t *str, const wxString& format, ...);
+WX_DEFINE_VARARG_FUNC(int, wxSprintf, 2, (wchar_t*, const wxString&),
+                      wxDoSprintf)
+
+int WXDLLIMPEXP_BASE
+wxVsprintf(wchar_t *str, const wxString& format, va_list argptr);
+
+int WXDLLIMPEXP_BASE wxDoSnprintf(wchar_t *str, size_t size, const wxString& format, ...);
+WX_DEFINE_VARARG_FUNC(int, wxSnprintf, 3, (wchar_t*, size_t, const wxString&),
+                      wxDoSnprintf)
+
+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(wxString(fmt), __VA_ARGS__)
+    #define wxFprintf(f, fmt, ...) \
+            wxFprintf_Impl(f, wxString(fmt), __VA_ARGS__)
+    #define wxSprintf(s, fmt, ...) \
+            wxSprintf_Impl(s, wxString(fmt), __VA_ARGS__)
+    #define wxSnprintf(s, n, fmt, ...) \
+            wxSnprintf_Impl(s, n, wxString(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.
+
+// FIXME-UTF8: actually do it, for now we only have wxChar* variants:
+#define wxScanf   wxCRT_Scanf
+#define wxFscanf  wxCRT_Fscanf
+#define wxSscanf  wxCRT_Sscanf
+#define wxVsscanf wxCRT_Vsscanf
+
 #endif /* _WX_WXCRTVARARG_H_ */