moved vararg CRT functions wrappers to a new wxcrtvararg.h header
[wxWidgets.git] / include / wx / wxcrtvararg.h
1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: wx/wxcrtvararg.h
3 // Purpose: Type-safe ANSI and Unicode builds compatible wrappers for
4 // printf(), scanf() and related CRT functions
5 // Author: Joel Farley, Ove Kåven
6 // Modified by: Vadim Zeitlin, Robert Roebling, Ron Lee
7 // Created: 2007-02-19
8 // RCS-ID: $Id$
9 // Copyright: (c) 2007 REA Elektronik GmbH
10 // Licence: wxWindows licence
11 ///////////////////////////////////////////////////////////////////////////////
12
13 #ifndef _WX_WXCRTVARARG_H_
14 #define _WX_WXCRTVARARG_H_
15
16 #include "wx/wxcrt.h"
17 #include "wx/strvararg.h"
18
19
20 /* Required for wxPrintf() etc */
21 #include <stdarg.h>
22
23 #ifdef wxHAVE_TCHAR_SUPPORT
24 WX_DEFINE_VARARG_FUNC(int, wxFprintf, _ftprintf)
25 WX_DEFINE_VARARG_FUNC(int, wxPrintf, _tprintf)
26 #define wxPutc(c,f) _puttc(WXWCHAR_T_CAST(c),f)
27 #define wxPutchar _puttchar
28 #define wxPuts _putts
29 #define wxScanf _tscanf /* FIXME-UTF8: not wrapped */
30 #if defined(__DMC__)
31 #if wxUSE_UNICODE
32 /* Digital Mars adds count to _stprintf (C99) so prototype conversion see wxchar.cpp */
33 int wxDoSprintf (wchar_t * __RESTRICT s, const wchar_t * __RESTRICT format, ... ) ;
34 WX_DEFINE_VARARG_FUNC(int, wxSprintf, wxDoSprintf)
35 #else
36 /* and there is a bug in D Mars tchar.h prior to 8.39.4n, so define
37 as sprintf */
38 WX_DEFINE_VARARG_FUNC(int, wxSprintf, sprintf)
39 #endif
40 #else
41 WX_DEFINE_VARARG_FUNC(int, wxSprintf, _stprintf)
42 #endif
43
44 /* FIXME-UTF8: not wrapped */
45 #define wxSscanf _stscanf
46 #define wxVfprintf _vftprintf
47 #define wxVprintf _vtprintf
48 #define wxVsscanf _vstscanf
49 #define wxVsprintf _vstprintf
50
51 #else /* !TCHAR-aware compilers */
52
53 #if !wxUSE_UNICODE /* ASCII */
54 WX_DEFINE_VARARG_FUNC(int, wxFprintf, fprintf)
55 #define wxFscanf fscanf
56 WX_DEFINE_VARARG_FUNC(int, wxPrintf, printf)
57 #define wxScanf scanf
58 WX_DEFINE_VARARG_FUNC(int, wxSprintf, sprintf)
59 #define wxSscanf sscanf
60 #define wxVfprintf vfprintf
61 #define wxVprintf vprintf
62 #define wxVsscanf vsscanf
63 #define wxVsprintf vsprintf
64 #endif /* ASCII */
65 #endif /* TCHAR-aware compilers/the others */
66
67 /* printf() family saga */
68
69 /*
70 For some systems [v]snprintf() exists in the system libraries but not in the
71 headers, so we need to declare it ourselves to be able to use it.
72 */
73 #if defined(HAVE_VSNPRINTF) && !defined(HAVE_VSNPRINTF_DECL)
74 #ifdef __cplusplus
75 extern "C"
76 #else
77 extern
78 #endif
79 int vsnprintf(char *str, size_t size, const char *format, va_list ap);
80 #endif /* !HAVE_VSNPRINTF_DECL */
81
82 #if defined(HAVE_SNPRINTF) && !defined(HAVE_SNPRINTF_DECL)
83 #ifdef __cplusplus
84 extern "C"
85 #else
86 extern
87 #endif
88 WXDLLIMPEXP_BASE int snprintf(char *str, size_t size, const char *format, ...);
89 #endif /* !HAVE_SNPRINTF_DECL */
90
91 /* Wrapper for vsnprintf if it's 3rd parameter is non-const. Note: the
92 * same isn't done for snprintf below, the builtin wxSnprintf_ is used
93 * instead since it's already a simple wrapper */
94 #if defined __cplusplus && defined HAVE_BROKEN_VSNPRINTF_DECL
95 inline int wx_fixed_vsnprintf(char *str, size_t size, const char *format, va_list ap)
96 {
97 return vsnprintf(str, size, (char*)format, ap);
98 }
99 #endif
100
101 /*
102 MinGW MSVCRT has non-standard vswprintf() (for MSVC compatibility
103 presumably) and normally _vsnwprintf() is used instead
104 */
105 #if defined(HAVE_VSWPRINTF) && defined(__MINGW32__)
106 #undef HAVE_VSWPRINTF
107 #endif
108
109 #if wxUSE_PRINTF_POS_PARAMS
110 /*
111 The systems where vsnprintf() supports positional parameters should
112 define the HAVE_UNIX98_PRINTF symbol.
113
114 On systems which don't (e.g. Windows) we are forced to use
115 our wxVsnprintf() implementation.
116 */
117 #if defined(HAVE_UNIX98_PRINTF)
118 #if wxUSE_UNICODE
119 #ifdef HAVE_VSWPRINTF
120 #define wxVsnprintf_ vswprintf
121 #endif
122 #else /* ASCII */
123 #ifdef HAVE_BROKEN_VSNPRINTF_DECL
124 #define wxVsnprintf_ wx_fixed_vsnprintf
125 #else
126 #define wxVsnprintf_ vsnprintf
127 #endif
128 #endif
129 #else /* !HAVE_UNIX98_PRINTF */
130 /*
131 The only compiler with positional parameters support under Windows
132 is VC++ 8.0 which provides a new xxprintf_p() functions family.
133 The 2003 PSDK includes a slightly earlier version of VC8 than the
134 main release and does not have the printf_p functions.
135 */
136 #if defined _MSC_FULL_VER && _MSC_FULL_VER >= 140050727 && !defined __WXWINCE__
137 #if wxUSE_UNICODE
138 #define wxVsnprintf_ _vswprintf_p
139 #else
140 #define wxVsnprintf_ _vsprintf_p
141 #endif
142 #endif
143 #endif /* HAVE_UNIX98_PRINTF/!HAVE_UNIX98_PRINTF */
144 #else /* !wxUSE_PRINTF_POS_PARAMS */
145 /*
146 We always want to define safe snprintf() function to be used instead of
147 sprintf(). Some compilers already have it (or rather vsnprintf() which
148 we really need...), otherwise we implement it using our own printf()
149 code.
150
151 We define function with a trailing underscore here because the real one
152 is a wrapper around it as explained below
153 */
154
155 /* first deal with TCHAR-aware compilers which have _vsntprintf */
156 #ifndef wxVsnprintf_
157 #if defined(__VISUALC__) || \
158 (defined(__BORLANDC__) && __BORLANDC__ >= 0x540)
159 #define wxSnprintf_ _sntprintf
160 #define wxVsnprintf_ _vsntprintf
161 WX_DEFINE_VARARG_FUNC(int, wxSnprintf_, _sntprintf)
162 #endif
163 #endif
164
165 /* if this didn't work, define it separately for Unicode and ANSI builds */
166 #ifndef wxVsnprintf_
167 #if wxUSE_UNICODE
168 #if defined(HAVE__VSNWPRINTF)
169 #define wxVsnprintf_ _vsnwprintf
170 #elif defined(HAVE_VSWPRINTF)
171 #define wxVsnprintf_ vswprintf
172 #elif defined(__WATCOMC__)
173 #define wxVsnprintf_ _vsnwprintf
174 WX_DEFINE_VARARG_FUNC(int, wxSnprintf_, _snwprintf)
175 #endif
176 #else /* ASCII */
177 /*
178 All versions of CodeWarrior supported by wxWidgets apparently
179 have both snprintf() and vsnprintf()
180 */
181 #if defined(HAVE_SNPRINTF) \
182 || defined(__MWERKS__) || defined(__WATCOMC__)
183 #ifndef HAVE_BROKEN_SNPRINTF_DECL
184 WX_DEFINE_VARARG_FUNC(int, wxSnprintf_, snprintf)
185 #endif
186 #endif
187 #if defined(HAVE_VSNPRINTF) \
188 || defined(__MWERKS__) || defined(__WATCOMC__)
189 #ifdef HAVE_BROKEN_VSNPRINTF_DECL
190 #define wxVsnprintf_ wx_fixed_vsnprintf
191 #else
192 #define wxVsnprintf_ vsnprintf
193 #endif
194 #endif
195 #endif /* Unicode/ASCII */
196 #endif /* wxVsnprintf_ */
197 #endif /* wxUSE_PRINTF_POS_PARAMS/!wxUSE_PRINTF_POS_PARAMS */
198
199 #ifndef wxSnprintf_
200 /* no snprintf(), cook our own */
201 WXDLLIMPEXP_BASE int
202 wxDoSnprintf_(wxChar *buf, size_t len,
203 const wxChar *format, ...) ATTRIBUTE_PRINTF_3;
204 WX_DEFINE_VARARG_FUNC(int, wxSnprintf_, wxDoSnprintf_)
205 #endif
206 #ifndef wxVsnprintf_
207 /* no (suitable) vsnprintf(), cook our own */
208 WXDLLIMPEXP_BASE int
209 wxVsnprintf_(wxChar *buf, size_t len,
210 const wxChar *format, va_list argptr);
211
212 #define wxUSE_WXVSNPRINTF 1
213 #else
214 #define wxUSE_WXVSNPRINTF 0
215 #endif
216
217 /*
218 In Unicode mode we need to have all standard functions such as wprintf() and
219 so on but not all systems have them so use our own implementations in this
220 case.
221 */
222 #if wxUSE_UNICODE && !defined(wxHAVE_TCHAR_SUPPORT) && !defined(HAVE_WPRINTF)
223 #define wxNEED_WPRINTF
224 #endif
225
226 /*
227 More Unicode complications: although both ANSI C and C++ define a number of
228 wide character functions such as wprintf(), not all environments have them.
229 Worse, those which do have different behaviours: under Windows, %s format
230 specifier changes its meaning in Unicode build and expects a Unicode string
231 while under Unix/POSIX it still means an ASCII string even for wprintf() and
232 %ls has to be used for wide strings.
233
234 We choose to always emulate Windows behaviour as more useful for us so even
235 if we have wprintf() we still must wrap it in a non trivial wxPrintf().
236
237 */
238
239 #if defined(wxNEED_PRINTF_CONVERSION) || defined(wxNEED_WPRINTF)
240 /*
241 we need to implement all wide character printf and scanf functions
242 either because we don't have them at all or because they don't have the
243 semantics we need
244 */
245 WX_DEFINE_VARARG_FUNC(int, wxScanf, wxDoScanf)
246 int wxDoScanf( const wxChar *format, ... ) ATTRIBUTE_PRINTF_1;
247
248 WX_DEFINE_VARARG_FUNC(int, wxSscanf, wxDoSscanf)
249 int wxDoSscanf( const wxChar *str, const wxChar *format, ... ) ATTRIBUTE_PRINTF_2;
250
251 WX_DEFINE_VARARG_FUNC(int, wxFscanf, wxDoFscanf)
252 int wxDoFscanf( FILE *stream, const wxChar *format, ... ) ATTRIBUTE_PRINTF_2;
253
254 WX_DEFINE_VARARG_FUNC(int, wxPrintf, wxDoPrintf)
255 int wxDoPrintf( const wxChar *format, ... ) ATTRIBUTE_PRINTF_1;
256
257 WX_DEFINE_VARARG_FUNC(int, wxSprintf, wxDoSprintf)
258 int wxDoSprintf( wxChar *str, const wxChar *format, ... ) ATTRIBUTE_PRINTF_2;
259
260 WX_DEFINE_VARARG_FUNC(int, wxFprintf, wxDoFprintf)
261 int wxDoFprintf( FILE *stream, const wxChar *format, ... ) ATTRIBUTE_PRINTF_2;
262
263 int wxVsscanf( const wxChar *str, const wxChar *format, va_list ap );
264 int wxVfprintf( FILE *stream, const wxChar *format, va_list ap );
265 int wxVprintf( const wxChar *format, va_list ap );
266 int wxVsprintf( wxChar *str, const wxChar *format, va_list ap );
267 #endif /* wxNEED_PRINTF_CONVERSION */
268
269 /* these 2 can be simply mapped to the versions with underscore at the end */
270 /* if we don't have to do the conversion */
271 /*
272 However, if we don't have any vswprintf() at all we don't need to redefine
273 anything as our own wxVsnprintf_() already behaves as needed.
274 */
275 #if defined(wxNEED_PRINTF_CONVERSION) && defined(wxVsnprintf_)
276 WX_DEFINE_VARARG_FUNC(int, wxSnprintf, wxDoSnprintf)
277 int wxDoSnprintf( wxChar *str, size_t size, const wxChar *format, ... ) ATTRIBUTE_PRINTF_3;
278 int wxVsnprintf( wxChar *str, size_t size, const wxChar *format, va_list ap );
279 #else
280 #define wxSnprintf wxSnprintf_
281 #define wxVsnprintf wxVsnprintf_
282 #endif
283
284 #endif /* _WX_WXCRTVARARG_H_ */