Monero
win32_snprintf.h
Go to the documentation of this file.
1 /* vim: tabstop=4 shiftwidth=4 noexpandtab
2  * MiniUPnP project
3  * http://miniupnp.free.fr/ or https://miniupnp.tuxfamily.org/
4  * (c) 2020 Pali Rohár
5  * This software is subject to the conditions detailed
6  * in the LICENCE file provided within the distribution */
7 
8 #ifndef WIN32_SNPRINTF_H
9 #define WIN32_SNPRINTF_H
10 
11 #ifdef _WIN32
12 
13 #include <stdio.h>
14 
15 /* snprintf is supported by:
16  * - Visual Studio 2015 or new
17  * - mingw32 with iso c ext
18  * - mingw-w64 with ansi stdio
19  * - mingw-w64 6.0.0 or new with ucrt
20  * - mingw-w64 8.0.0 or new with iso c ext
21  */
22 #if ( \
23  (defined(_MSC_VER) && _MSC_VER < 1900) /* Visual Studio older than 2015 */ || \
24  (defined(__MINGW32__) && !defined(__MINGW64_VERSION_MAJOR) && defined(__NO_ISOCEXT)) /* mingw32 without iso c ext */ || \
25  (defined(__MINGW64_VERSION_MAJOR) && /* mingw-w64 not ... */ !( \
26  (defined (__USE_MINGW_ANSI_STDIO) && __USE_MINGW_ANSI_STDIO != 0)) /* ... with ansi stdio */ || \
27  (__MINGW64_VERSION_MAJOR >= 6 && defined(_UCRT)) /* ... at least 6.0.0 with ucrt */ || \
28  (__MINGW64_VERSION_MAJOR >= 8 && !defined(__NO_ISOCEXT)) /* ... at least 8.0.0 with iso c ext */ || \
29  0) || \
30 0)
31 
32 /* _scprintf is supported by:
33  * - Visual Studio 2002 or new
34  * - msvcr70.dll or new
35  * - msvcrt.dll on Windows XP or new
36  */
37 #if ( \
38  (defined(_MSC_VER) && _MSC_VER < 1300) /* Visual Studio older than 2002 */ || \
39  (defined(__MSVCRT_VERSION__) && __MSVCRT_VERSION__ < 0x700) /* msvcrt older than 7.0 */ || \
40 0)
41 #define CHECK_SCPRINTF 0
42 #define IF_SCPRINTF(expr) 0
43 #define ELSE_SCPRINTF(expr) expr
44 #else
45 #define CHECK_SCPRINTF 1
46 #define IF_SCPRINTF(expr) expr
47 #define ELSE_SCPRINTF(expr) 0
48 #endif
49 
50 /* Emulation of snprintf for win32 */
51 #define snprintf(buf, size, fmt, ...) ( \
52  (((size) != 0 && (buf) != NULL) ? ( /* _snprintf does not work with NULL buffer */ \
53  _snprintf((buf), (size), (fmt), __VA_ARGS__), /* _snprintf returns -1 on overflow, so ignore its value */ \
54  (((char *)buf)[(size_t)(size)-1] = 0), /* _snprintf does not fill nul byte on overflow */ \
55  0) : 0), \
56  (CHECK_SCPRINTF ? IF_SCPRINTF( \
57  _scprintf((fmt), __VA_ARGS__) /* calculate return value for snprintf via _scprintf */ \
58  ) : ELSE_SCPRINTF( \
59  ((size) != 0 && (buf) != NULL) ? \
60  strlen((buf)) /* return just length of buffer */ \
61  : \
62  1 /* no buffer, impossible to calculate, return just non-zero number */ \
63  ) \
64  ) \
65 )
66 
67 #endif
68 
69 #endif /* _WIN32 */
70 
71 #endif /* WIN32_SNPRINTF_H */