]>
Commit | Line | Data |
---|---|---|
e713a90b VS |
1 | /////////////////////////////////////////////////////////////////////////////// |
2 | // Name: wx/wxcrtvararg.h | |
3 | // Purpose: Type-safe ANSI and Unicode builds compatible wrappers for | |
4 | // printf(), scanf() and related CRT functions | |
e9670814 | 5 | // Author: Joel Farley, Ove Kåven |
e713a90b VS |
6 | // Modified by: Vadim Zeitlin, Robert Roebling, Ron Lee |
7 | // Created: 2007-02-19 | |
e713a90b VS |
8 | // Copyright: (c) 2007 REA Elektronik GmbH |
9 | // Licence: wxWindows licence | |
10 | /////////////////////////////////////////////////////////////////////////////// | |
11 | ||
12 | #ifndef _WX_WXCRTVARARG_H_ | |
13 | #define _WX_WXCRTVARARG_H_ | |
14 | ||
3a3dde0d VS |
15 | // NB: User code should include wx/crt.h instead of including this |
16 | // header directly. | |
17 | ||
e713a90b VS |
18 | #include "wx/wxcrt.h" |
19 | #include "wx/strvararg.h" | |
20 | ||
2523e9b7 VS |
21 | #include "wx/string.h" |
22 | ||
23 | // ---------------------------------------------------------------------------- | |
24 | // CRT functions aliases | |
25 | // ---------------------------------------------------------------------------- | |
e713a90b VS |
26 | |
27 | /* Required for wxPrintf() etc */ | |
28 | #include <stdarg.h> | |
29 | ||
e713a90b VS |
30 | /* printf() family saga */ |
31 | ||
32 | /* | |
6bc7b913 VZ |
33 | For many old Unix systems [v]snprintf()/vsscanf() exists in the system |
34 | libraries but not in the headers, so we need to declare it ourselves to be | |
35 | able to use it. | |
e713a90b | 36 | */ |
6bc7b913 VZ |
37 | #ifdef __UNIX__ |
38 | ||
e713a90b VS |
39 | #if defined(HAVE_VSNPRINTF) && !defined(HAVE_VSNPRINTF_DECL) |
40 | #ifdef __cplusplus | |
41 | extern "C" | |
42 | #else | |
43 | extern | |
44 | #endif | |
45 | int vsnprintf(char *str, size_t size, const char *format, va_list ap); | |
46 | #endif /* !HAVE_VSNPRINTF_DECL */ | |
47 | ||
48 | #if defined(HAVE_SNPRINTF) && !defined(HAVE_SNPRINTF_DECL) | |
49 | #ifdef __cplusplus | |
50 | extern "C" | |
51 | #else | |
52 | extern | |
53 | #endif | |
52de37c7 | 54 | int snprintf(char *str, size_t size, const char *format, ...); |
e713a90b VS |
55 | #endif /* !HAVE_SNPRINTF_DECL */ |
56 | ||
a93cf225 SN |
57 | #if defined(HAVE_VSSCANF) && !defined(HAVE_VSSCANF_DECL) |
58 | #ifdef __cplusplus | |
59 | extern "C" | |
60 | #else | |
61 | extern | |
62 | #endif | |
63 | int vsscanf(const char *str, const char *format, va_list ap); | |
6bc7b913 | 64 | #endif /* !HAVE_VSSCANF_DECL */ |
a93cf225 | 65 | |
e713a90b VS |
66 | /* Wrapper for vsnprintf if it's 3rd parameter is non-const. Note: the |
67 | * same isn't done for snprintf below, the builtin wxSnprintf_ is used | |
68 | * instead since it's already a simple wrapper */ | |
69 | #if defined __cplusplus && defined HAVE_BROKEN_VSNPRINTF_DECL | |
70 | inline int wx_fixed_vsnprintf(char *str, size_t size, const char *format, va_list ap) | |
71 | { | |
72 | return vsnprintf(str, size, (char*)format, ap); | |
73 | } | |
74 | #endif | |
75 | ||
6bc7b913 VZ |
76 | #endif /* __UNIX__ */ |
77 | ||
e713a90b | 78 | /* |
e461247b VZ |
79 | mingw32 normally uses MSVCRT which has non-standard vswprintf() and so |
80 | normally _vsnwprintf() is used instead, the only exception is when mingw32 | |
81 | is used with STLPort which does have a standard vswprintf() starting from | |
82 | version 5.1 which we can use. | |
e713a90b | 83 | */ |
e461247b VZ |
84 | #ifdef __MINGW32__ |
85 | #if defined(_STLPORT_VERSION) && _STLPORT_VERSION >= 0x510 | |
86 | #ifndef HAVE_VSWPRINTF | |
87 | #define HAVE_VSWPRINTF | |
88 | #endif | |
89 | #elif defined(HAVE_VSWPRINTF) | |
90 | /* can't use non-standard vswprintf() */ | |
91 | #undef HAVE_VSWPRINTF | |
92 | #endif | |
93 | #endif /* __MINGW32__ */ | |
e713a90b | 94 | |
ed12c5a2 VS |
95 | #if defined(__WATCOMC__) |
96 | #define HAVE_VSWPRINTF 1 | |
97 | #endif | |
98 | ||
e713a90b VS |
99 | #if wxUSE_PRINTF_POS_PARAMS |
100 | /* | |
101 | The systems where vsnprintf() supports positional parameters should | |
102 | define the HAVE_UNIX98_PRINTF symbol. | |
103 | ||
104 | On systems which don't (e.g. Windows) we are forced to use | |
105 | our wxVsnprintf() implementation. | |
106 | */ | |
107 | #if defined(HAVE_UNIX98_PRINTF) | |
52de37c7 | 108 | #ifdef HAVE_VSWPRINTF |
57c42b62 | 109 | #define wxCRT_VsnprintfW vswprintf |
52de37c7 VS |
110 | #endif |
111 | #ifdef HAVE_BROKEN_VSNPRINTF_DECL | |
112 | #define wxCRT_VsnprintfA wx_fixed_vsnprintf | |
113 | #else | |
114 | #define wxCRT_VsnprintfA vsnprintf | |
e713a90b VS |
115 | #endif |
116 | #else /* !HAVE_UNIX98_PRINTF */ | |
117 | /* | |
118 | The only compiler with positional parameters support under Windows | |
119 | is VC++ 8.0 which provides a new xxprintf_p() functions family. | |
120 | The 2003 PSDK includes a slightly earlier version of VC8 than the | |
121 | main release and does not have the printf_p functions. | |
122 | */ | |
123 | #if defined _MSC_FULL_VER && _MSC_FULL_VER >= 140050727 && !defined __WXWINCE__ | |
52de37c7 | 124 | #define wxCRT_VsnprintfA _vsprintf_p |
57c42b62 | 125 | #define wxCRT_VsnprintfW _vswprintf_p |
e713a90b VS |
126 | #endif |
127 | #endif /* HAVE_UNIX98_PRINTF/!HAVE_UNIX98_PRINTF */ | |
128 | #else /* !wxUSE_PRINTF_POS_PARAMS */ | |
129 | /* | |
130 | We always want to define safe snprintf() function to be used instead of | |
131 | sprintf(). Some compilers already have it (or rather vsnprintf() which | |
132 | we really need...), otherwise we implement it using our own printf() | |
133 | code. | |
134 | ||
135 | We define function with a trailing underscore here because the real one | |
136 | is a wrapper around it as explained below | |
137 | */ | |
138 | ||
52de37c7 VS |
139 | #if defined(__VISUALC__) || \ |
140 | (defined(__BORLANDC__) && __BORLANDC__ >= 0x540) | |
141 | #define wxCRT_VsnprintfA _vsnprintf | |
57c42b62 | 142 | #define wxCRT_VsnprintfW _vsnwprintf |
52de37c7 VS |
143 | #else |
144 | #if defined(HAVE__VSNWPRINTF) | |
57c42b62 | 145 | #define wxCRT_VsnprintfW _vsnwprintf |
52de37c7 | 146 | #elif defined(HAVE_VSWPRINTF) |
57c42b62 | 147 | #define wxCRT_VsnprintfW vswprintf |
52de37c7 | 148 | #elif defined(__WATCOMC__) |
57c42b62 | 149 | #define wxCRT_VsnprintfW _vsnwprintf |
e713a90b | 150 | #endif |
e713a90b | 151 | |
52de37c7 | 152 | #if defined(HAVE_VSNPRINTF) \ |
2415cf67 | 153 | || defined(__WATCOMC__) |
52de37c7 VS |
154 | #ifdef HAVE_BROKEN_VSNPRINTF_DECL |
155 | #define wxCRT_VsnprintfA wx_fixed_vsnprintf | |
156 | #else | |
157 | #define wxCRT_VsnprintfA vsnprintf | |
e713a90b | 158 | #endif |
52de37c7 VS |
159 | #endif |
160 | #endif | |
e713a90b VS |
161 | #endif /* wxUSE_PRINTF_POS_PARAMS/!wxUSE_PRINTF_POS_PARAMS */ |
162 | ||
57c42b62 | 163 | #ifndef wxCRT_VsnprintfW |
e713a90b VS |
164 | /* no (suitable) vsnprintf(), cook our own */ |
165 | WXDLLIMPEXP_BASE int | |
57c42b62 | 166 | wxCRT_VsnprintfW(wchar_t *buf, size_t len, const wchar_t *format, va_list argptr); |
52de37c7 VS |
167 | #define wxUSE_WXVSNPRINTFW 1 |
168 | #else | |
169 | #define wxUSE_WXVSNPRINTFW 0 | |
170 | #endif | |
e713a90b | 171 | |
52de37c7 VS |
172 | #ifndef wxCRT_VsnprintfA |
173 | /* no (suitable) vsnprintf(), cook our own */ | |
174 | WXDLLIMPEXP_BASE int | |
175 | wxCRT_VsnprintfA(char *buf, size_t len, const char *format, va_list argptr); | |
176 | #define wxUSE_WXVSNPRINTFA 1 | |
e713a90b | 177 | #else |
52de37c7 | 178 | #define wxUSE_WXVSNPRINTFA 0 |
e713a90b VS |
179 | #endif |
180 | ||
52de37c7 VS |
181 | // for wxString code, define wxUSE_WXVSNPRINTF to indicate that wx |
182 | // implementation is used no matter what (in UTF-8 build, either *A or *W | |
183 | // version may be called): | |
184 | #if !wxUSE_UNICODE | |
185 | #define wxUSE_WXVSNPRINTF wxUSE_WXVSNPRINTFA | |
186 | #elif wxUSE_UNICODE_WCHAR | |
187 | #define wxUSE_WXVSNPRINTF wxUSE_WXVSNPRINTFW | |
188 | #elif wxUSE_UTF8_LOCALE_ONLY | |
189 | #define wxUSE_WXVSNPRINTF wxUSE_WXVSNPRINTFA | |
190 | #else // UTF-8 under any locale | |
191 | #define wxUSE_WXVSNPRINTF (wxUSE_WXVSNPRINTFA && wxUSE_WXVSNPRINTFW) | |
e713a90b VS |
192 | #endif |
193 | ||
52de37c7 VS |
194 | #define wxCRT_FprintfA fprintf |
195 | #define wxCRT_PrintfA printf | |
196 | #define wxCRT_VfprintfA vfprintf | |
197 | #define wxCRT_VprintfA vprintf | |
198 | #define wxCRT_VsprintfA vsprintf | |
199 | ||
52de37c7 VS |
200 | /* |
201 | In Unicode mode we need to have all standard functions such as wprintf() and | |
202 | so on but not all systems have them so use our own implementations in this | |
203 | case. | |
204 | */ | |
205 | #if wxUSE_UNICODE && !defined(wxHAVE_TCHAR_SUPPORT) && !defined(HAVE_WPRINTF) | |
206 | #define wxNEED_WPRINTF | |
207 | #endif | |
ccd96bfe PC |
208 | #if wxUSE_UNICODE && !defined(wxHAVE_TCHAR_SUPPORT) && !defined(HAVE_VSWSCANF) |
209 | #define wxNEED_VSWSCANF | |
210 | #endif | |
52de37c7 | 211 | |
e713a90b | 212 | |
57c42b62 | 213 | #if defined(wxNEED_WPRINTF) |
e713a90b | 214 | /* |
c49f8879 VS |
215 | we need to implement all wide character printf functions either because |
216 | we don't have them at all or because they don't have the semantics we | |
217 | need | |
e713a90b | 218 | */ |
872ef943 VS |
219 | int wxCRT_PrintfW( const wchar_t *format, ... ); |
220 | int wxCRT_FprintfW( FILE *stream, const wchar_t *format, ... ); | |
52de37c7 VS |
221 | int wxCRT_VfprintfW( FILE *stream, const wchar_t *format, va_list ap ); |
222 | int wxCRT_VprintfW( const wchar_t *format, va_list ap ); | |
223 | int wxCRT_VsprintfW( wchar_t *str, const wchar_t *format, va_list ap ); | |
fc1f568e VZ |
224 | #else /* !wxNEED_WPRINTF */ |
225 | #define wxCRT_FprintfW fwprintf | |
226 | #define wxCRT_PrintfW wprintf | |
227 | #define wxCRT_VfprintfW vfwprintf | |
228 | #define wxCRT_VprintfW vwprintf | |
e461247b | 229 | |
fc1f568e VZ |
230 | #if defined(__WINDOWS__) && !defined(HAVE_VSWPRINTF) |
231 | // only non-standard vswprintf() without buffer size argument can be used here | |
232 | #define wxCRT_VsprintfW vswprintf | |
233 | #endif | |
57c42b62 | 234 | #endif /* wxNEED_WPRINTF */ |
2523e9b7 VS |
235 | |
236 | ||
eb6cb207 VS |
237 | /* Required for wxScanf() etc. */ |
238 | #define wxCRT_ScanfA scanf | |
239 | #define wxCRT_SscanfA sscanf | |
240 | #define wxCRT_FscanfA fscanf | |
241 | #define wxCRT_VsscanfA vsscanf | |
242 | ||
57c42b62 | 243 | #if defined(wxNEED_WPRINTF) |
872ef943 VS |
244 | int wxCRT_ScanfW(const wchar_t *format, ...); |
245 | int wxCRT_SscanfW(const wchar_t *str, const wchar_t *format, ...); | |
246 | int wxCRT_FscanfW(FILE *stream, const wchar_t *format, ...); | |
934960d1 | 247 | #else |
b6937696 JJ |
248 | #define wxCRT_ScanfW wxVMS_USE_STD wscanf |
249 | #define wxCRT_SscanfW wxVMS_USE_STD swscanf | |
250 | #define wxCRT_FscanfW wxVMS_USE_STD fwscanf | |
ccd96bfe PC |
251 | #endif |
252 | #ifdef wxNEED_VSWSCANF | |
253 | int wxCRT_VsscanfW(const wchar_t *str, const wchar_t *format, va_list ap); | |
254 | #else | |
b6937696 | 255 | #define wxCRT_VsscanfW wxVMS_USE_STD vswscanf |
934960d1 | 256 | #endif |
eb6cb207 | 257 | |
2523e9b7 VS |
258 | // ---------------------------------------------------------------------------- |
259 | // user-friendly wrappers to CRT functions | |
260 | // ---------------------------------------------------------------------------- | |
261 | ||
262 | #ifdef __WATCOMC__ | |
263 | // workaround for http://bugzilla.openwatcom.org/show_bug.cgi?id=351 | |
264 | #define wxPrintf wxPrintf_Impl | |
265 | #define wxFprintf wxFprintf_Impl | |
266 | #define wxSprintf wxSprintf_Impl | |
267 | #define wxSnprintf wxSnprintf_Impl | |
268 | #endif | |
269 | ||
52de37c7 VS |
270 | // FIXME-UTF8: remove this |
271 | #if wxUSE_UNICODE | |
272 | #define wxCRT_PrintfNative wxCRT_PrintfW | |
273 | #define wxCRT_FprintfNative wxCRT_FprintfW | |
274 | #else | |
275 | #define wxCRT_PrintfNative wxCRT_PrintfA | |
276 | #define wxCRT_FprintfNative wxCRT_FprintfA | |
277 | #endif | |
278 | ||
e68a8744 VS |
279 | |
280 | WX_DEFINE_VARARG_FUNC_SANS_N0(int, wxPrintf, 1, (const wxFormatString&), | |
281 | wxCRT_PrintfNative, wxCRT_PrintfA) | |
282 | inline int wxPrintf(const wxFormatString& s) | |
283 | { | |
284 | return wxPrintf("%s", s.InputAsString()); | |
285 | } | |
286 | ||
287 | WX_DEFINE_VARARG_FUNC_SANS_N0(int, wxFprintf, 2, (FILE*, const wxFormatString&), | |
288 | wxCRT_FprintfNative, wxCRT_FprintfA) | |
289 | inline int wxFprintf(FILE *f, const wxFormatString& s) | |
290 | { | |
291 | return wxFprintf(f, "%s", s.InputAsString()); | |
292 | } | |
2523e9b7 VS |
293 | |
294 | // va_list versions of printf functions simply forward to the respective | |
295 | // CRT function; note that they assume that va_list was created using | |
296 | // wxArgNormalizer<T>! | |
297 | #if wxUSE_UNICODE_UTF8 | |
298 | #if wxUSE_UTF8_LOCALE_ONLY | |
52de37c7 VS |
299 | #define WX_VARARG_VFOO_IMPL(args, implW, implA) \ |
300 | return implA args | |
2523e9b7 | 301 | #else |
52de37c7 VS |
302 | #define WX_VARARG_VFOO_IMPL(args, implW, implA) \ |
303 | if ( wxLocaleIsUtf8 ) return implA args; \ | |
304 | else return implW args | |
2523e9b7 | 305 | #endif |
52de37c7 VS |
306 | #elif wxUSE_UNICODE_WCHAR |
307 | #define WX_VARARG_VFOO_IMPL(args, implW, implA) \ | |
308 | return implW args | |
309 | #else // ANSI | |
310 | #define WX_VARARG_VFOO_IMPL(args, implW, implA) \ | |
311 | return implA args | |
e713a90b VS |
312 | #endif |
313 | ||
2523e9b7 VS |
314 | inline int |
315 | wxVprintf(const wxString& format, va_list ap) | |
316 | { | |
0d23e825 | 317 | WX_VARARG_VFOO_IMPL((wxFormatString(format), ap), |
52de37c7 | 318 | wxCRT_VprintfW, wxCRT_VprintfA); |
2523e9b7 VS |
319 | } |
320 | ||
321 | inline int | |
322 | wxVfprintf(FILE *f, const wxString& format, va_list ap) | |
323 | { | |
0d23e825 | 324 | WX_VARARG_VFOO_IMPL((f, wxFormatString(format), ap), |
52de37c7 | 325 | wxCRT_VfprintfW, wxCRT_VfprintfA); |
2523e9b7 VS |
326 | } |
327 | ||
328 | #undef WX_VARARG_VFOO_IMPL | |
329 | ||
330 | ||
331 | // wxSprintf() and friends have to be implemented in two forms, one for | |
332 | // writing to char* buffer and one for writing to wchar_t*: | |
333 | ||
d1f6e2cf VS |
334 | #if !wxUSE_UTF8_LOCALE_ONLY |
335 | int WXDLLIMPEXP_BASE wxDoSprintfWchar(char *str, const wxChar *format, ...); | |
336 | #endif | |
337 | #if wxUSE_UNICODE_UTF8 | |
338 | int WXDLLIMPEXP_BASE wxDoSprintfUtf8(char *str, const char *format, ...); | |
339 | #endif | |
1528e0b8 | 340 | WX_DEFINE_VARARG_FUNC(int, wxSprintf, 2, (char*, const wxFormatString&), |
d1f6e2cf | 341 | wxDoSprintfWchar, wxDoSprintfUtf8) |
2523e9b7 VS |
342 | |
343 | int WXDLLIMPEXP_BASE | |
344 | wxVsprintf(char *str, const wxString& format, va_list argptr); | |
345 | ||
d1f6e2cf VS |
346 | #if !wxUSE_UTF8_LOCALE_ONLY |
347 | int WXDLLIMPEXP_BASE wxDoSnprintfWchar(char *str, size_t size, const wxChar *format, ...); | |
348 | #endif | |
349 | #if wxUSE_UNICODE_UTF8 | |
350 | int WXDLLIMPEXP_BASE wxDoSnprintfUtf8(char *str, size_t size, const char *format, ...); | |
351 | #endif | |
1528e0b8 | 352 | WX_DEFINE_VARARG_FUNC(int, wxSnprintf, 3, (char*, size_t, const wxFormatString&), |
d1f6e2cf | 353 | wxDoSnprintfWchar, wxDoSnprintfUtf8) |
2523e9b7 VS |
354 | |
355 | int WXDLLIMPEXP_BASE | |
356 | wxVsnprintf(char *str, size_t size, const wxString& format, va_list argptr); | |
357 | ||
358 | #if wxUSE_UNICODE | |
d1f6e2cf VS |
359 | |
360 | #if !wxUSE_UTF8_LOCALE_ONLY | |
361 | int WXDLLIMPEXP_BASE wxDoSprintfWchar(wchar_t *str, const wxChar *format, ...); | |
362 | #endif | |
363 | #if wxUSE_UNICODE_UTF8 | |
364 | int WXDLLIMPEXP_BASE wxDoSprintfUtf8(wchar_t *str, const char *format, ...); | |
365 | #endif | |
1528e0b8 | 366 | WX_DEFINE_VARARG_FUNC(int, wxSprintf, 2, (wchar_t*, const wxFormatString&), |
d1f6e2cf | 367 | wxDoSprintfWchar, wxDoSprintfUtf8) |
2523e9b7 VS |
368 | |
369 | int WXDLLIMPEXP_BASE | |
370 | wxVsprintf(wchar_t *str, const wxString& format, va_list argptr); | |
371 | ||
d1f6e2cf VS |
372 | #if !wxUSE_UTF8_LOCALE_ONLY |
373 | int WXDLLIMPEXP_BASE wxDoSnprintfWchar(wchar_t *str, size_t size, const wxChar *format, ...); | |
374 | #endif | |
375 | #if wxUSE_UNICODE_UTF8 | |
376 | int WXDLLIMPEXP_BASE wxDoSnprintfUtf8(wchar_t *str, size_t size, const char *format, ...); | |
377 | #endif | |
1528e0b8 | 378 | WX_DEFINE_VARARG_FUNC(int, wxSnprintf, 3, (wchar_t*, size_t, const wxFormatString&), |
d1f6e2cf | 379 | wxDoSnprintfWchar, wxDoSnprintfUtf8) |
2523e9b7 VS |
380 | |
381 | int WXDLLIMPEXP_BASE | |
382 | wxVsnprintf(wchar_t *str, size_t size, const wxString& format, va_list argptr); | |
d1f6e2cf | 383 | |
2523e9b7 VS |
384 | #endif // wxUSE_UNICODE |
385 | ||
386 | #ifdef __WATCOMC__ | |
387 | // workaround for http://bugzilla.openwatcom.org/show_bug.cgi?id=351 | |
388 | // | |
389 | // fortunately, OpenWatcom implements __VA_ARGS__, so we can provide macros | |
390 | // that cast the format argument to wxString: | |
391 | #undef wxPrintf | |
392 | #undef wxFprintf | |
393 | #undef wxSprintf | |
394 | #undef wxSnprintf | |
395 | ||
396 | #define wxPrintf(fmt, ...) \ | |
59a14f69 | 397 | wxPrintf_Impl(wxFormatString(fmt), __VA_ARGS__) |
2523e9b7 | 398 | #define wxFprintf(f, fmt, ...) \ |
59a14f69 | 399 | wxFprintf_Impl(f, wxFormatString(fmt), __VA_ARGS__) |
2523e9b7 | 400 | #define wxSprintf(s, fmt, ...) \ |
59a14f69 | 401 | wxSprintf_Impl(s, wxFormatString(fmt), __VA_ARGS__) |
2523e9b7 | 402 | #define wxSnprintf(s, n, fmt, ...) \ |
59a14f69 | 403 | wxSnprintf_Impl(s, n, wxFormatString(fmt), __VA_ARGS__) |
2523e9b7 VS |
404 | #endif // __WATCOMC__ |
405 | ||
406 | ||
407 | // We can't use wxArgNormalizer<T> for variadic arguments to wxScanf() etc. | |
408 | // because they are writable, so instead of providing friendly template | |
409 | // vararg-like functions, we just provide both char* and wchar_t* variants | |
410 | // of these functions. The type of output variadic arguments for %s must match | |
411 | // the type of 'str' and 'format' arguments. | |
c49f8879 VS |
412 | // |
413 | // For compatibility with earlier wx versions, we also provide wxSscanf() | |
414 | // version with the first argument (input string) wxString; for this version, | |
415 | // the type of output string values is determined by the type of format string | |
416 | // only. | |
417 | ||
eb6cb207 VS |
418 | #define _WX_SCANFUNC_EXTRACT_ARGS_1(x) x |
419 | #define _WX_SCANFUNC_EXTRACT_ARGS_2(x,y) x, y | |
420 | #define _WX_SCANFUNC_EXTRACT_ARGS(N, args) _WX_SCANFUNC_EXTRACT_ARGS_##N args | |
c49f8879 | 421 | |
eb6cb207 | 422 | #define _WX_VARARG_PASS_WRITABLE(i) a##i |
c49f8879 | 423 | |
eb6cb207 VS |
424 | #define _WX_DEFINE_SCANFUNC(N, dummy1, name, impl, passfixed, numfixed, fixed)\ |
425 | template<_WX_VARARG_JOIN(N, _WX_VARARG_TEMPL)> \ | |
426 | int name(_WX_SCANFUNC_EXTRACT_ARGS(numfixed, fixed), \ | |
427 | _WX_VARARG_JOIN(N, _WX_VARARG_ARG)) \ | |
428 | { \ | |
429 | return impl(_WX_SCANFUNC_EXTRACT_ARGS(numfixed, passfixed), \ | |
430 | _WX_VARARG_JOIN(N, _WX_VARARG_PASS_WRITABLE)); \ | |
431 | } | |
c49f8879 | 432 | |
eb6cb207 | 433 | #define WX_DEFINE_SCANFUNC(name, numfixed, fixed, impl, passfixed) \ |
eb6cb207 VS |
434 | _WX_VARARG_ITER(_WX_VARARG_MAX_ARGS, \ |
435 | _WX_DEFINE_SCANFUNC, \ | |
436 | dummy1, name, impl, passfixed, numfixed, fixed) | |
437 | ||
57c42b62 VS |
438 | // this is needed to normalize the format string, see src/common/strvararg.cpp |
439 | // for more details | |
440 | #ifdef __WINDOWS__ | |
441 | #define wxScanfConvertFormatW(fmt) fmt | |
442 | #else | |
de4983f3 | 443 | const wxScopedWCharBuffer |
57c42b62 VS |
444 | WXDLLIMPEXP_BASE wxScanfConvertFormatW(const wchar_t *format); |
445 | #endif | |
446 | ||
eb6cb207 VS |
447 | WX_DEFINE_SCANFUNC(wxScanf, 1, (const char *format), |
448 | wxCRT_ScanfA, (format)) | |
449 | WX_DEFINE_SCANFUNC(wxScanf, 1, (const wchar_t *format), | |
57c42b62 | 450 | wxCRT_ScanfW, (wxScanfConvertFormatW(format))) |
eb6cb207 VS |
451 | |
452 | WX_DEFINE_SCANFUNC(wxFscanf, 2, (FILE *stream, const char *format), | |
453 | wxCRT_FscanfA, (stream, format)) | |
454 | WX_DEFINE_SCANFUNC(wxFscanf, 2, (FILE *stream, const wchar_t *format), | |
57c42b62 | 455 | wxCRT_FscanfW, (stream, wxScanfConvertFormatW(format))) |
eb6cb207 VS |
456 | |
457 | WX_DEFINE_SCANFUNC(wxSscanf, 2, (const char *str, const char *format), | |
458 | wxCRT_SscanfA, (str, format)) | |
459 | WX_DEFINE_SCANFUNC(wxSscanf, 2, (const wchar_t *str, const wchar_t *format), | |
57c42b62 | 460 | wxCRT_SscanfW, (str, wxScanfConvertFormatW(format))) |
de4983f3 | 461 | WX_DEFINE_SCANFUNC(wxSscanf, 2, (const wxScopedCharBuffer& str, const char *format), |
eb6cb207 | 462 | wxCRT_SscanfA, (str.data(), format)) |
de4983f3 | 463 | WX_DEFINE_SCANFUNC(wxSscanf, 2, (const wxScopedWCharBuffer& str, const wchar_t *format), |
57c42b62 | 464 | wxCRT_SscanfW, (str.data(), wxScanfConvertFormatW(format))) |
eb6cb207 VS |
465 | WX_DEFINE_SCANFUNC(wxSscanf, 2, (const wxString& str, const char *format), |
466 | wxCRT_SscanfA, (str.mb_str(), format)) | |
467 | WX_DEFINE_SCANFUNC(wxSscanf, 2, (const wxString& str, const wchar_t *format), | |
57c42b62 | 468 | wxCRT_SscanfW, (str.wc_str(), wxScanfConvertFormatW(format))) |
eb6cb207 VS |
469 | WX_DEFINE_SCANFUNC(wxSscanf, 2, (const wxCStrData& str, const char *format), |
470 | wxCRT_SscanfA, (str.AsCharBuf(), format)) | |
471 | WX_DEFINE_SCANFUNC(wxSscanf, 2, (const wxCStrData& str, const wchar_t *format), | |
57c42b62 | 472 | wxCRT_SscanfW, (str.AsWCharBuf(), wxScanfConvertFormatW(format))) |
eb6cb207 VS |
473 | |
474 | // Visual C++ doesn't provide vsscanf() | |
475 | #ifndef __VISUALC___ | |
c49f8879 VS |
476 | int WXDLLIMPEXP_BASE wxVsscanf(const char *str, const char *format, va_list ap); |
477 | int WXDLLIMPEXP_BASE wxVsscanf(const wchar_t *str, const wchar_t *format, va_list ap); | |
de4983f3 VS |
478 | int WXDLLIMPEXP_BASE wxVsscanf(const wxScopedCharBuffer& str, const char *format, va_list ap); |
479 | int WXDLLIMPEXP_BASE wxVsscanf(const wxScopedWCharBuffer& str, const wchar_t *format, va_list ap); | |
c49f8879 VS |
480 | int WXDLLIMPEXP_BASE wxVsscanf(const wxString& str, const char *format, va_list ap); |
481 | int WXDLLIMPEXP_BASE wxVsscanf(const wxString& str, const wchar_t *format, va_list ap); | |
482 | int WXDLLIMPEXP_BASE wxVsscanf(const wxCStrData& str, const char *format, va_list ap); | |
483 | int WXDLLIMPEXP_BASE wxVsscanf(const wxCStrData& str, const wchar_t *format, va_list ap); | |
eb6cb207 | 484 | #endif // !__VISUALC__ |
2523e9b7 | 485 | |
e713a90b | 486 | #endif /* _WX_WXCRTVARARG_H_ */ |