From 26a1f54837da021aeeb72680acb2feb4ea1e02da Mon Sep 17 00:00:00 2001 From: Ron Yorston Date: Tue, 8 Jan 2019 15:20:21 +0000 Subject: win32: implement vsnprintf(2) The Microsoft C runtime may include a defective version of vsnprintf. Implement a standards-compliant replacement. --- include/mingw.h | 4 ++++ win32/winansi.c | 21 +++++++++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/include/mingw.h b/include/mingw.h index 2dc3ddfd7..f9c098917 100644 --- a/include/mingw.h +++ b/include/mingw.h @@ -134,6 +134,7 @@ int winansi_putchar(int c); int winansi_puts(const char *s); size_t winansi_fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream); int winansi_fputs(const char *str, FILE *stream); +int winansi_vsnprintf(char *buf, size_t size, const char *format, va_list list); int winansi_vfprintf(FILE *stream, const char *format, va_list list); int winansi_printf(const char *format, ...) __attribute__((format (printf, 1, 2))); int winansi_fprintf(FILE *stream, const char *format, ...) __attribute__((format (printf, 2, 3))); @@ -144,6 +145,9 @@ int winansi_getc(FILE *stream); #define puts winansi_puts #define fwrite winansi_fwrite #define fputs winansi_fputs +#if !defined(__USE_MINGW_ANSI_STDIO) || !__USE_MINGW_ANSI_STDIO +#define vsnprintf(buf, size, ...) winansi_vsnprintf(buf, size, __VA_ARGS__) +#endif #define vfprintf(stream, ...) winansi_vfprintf(stream, __VA_ARGS__) #define vprintf(...) winansi_vfprintf(stdout, __VA_ARGS__) #define printf(...) winansi_printf(__VA_ARGS__) diff --git a/win32/winansi.c b/win32/winansi.c index 167b4b0b1..9e7d10a56 100644 --- a/win32/winansi.c +++ b/win32/winansi.c @@ -552,6 +552,27 @@ int winansi_fputs(const char *str, FILE *stream) return ansi_emulate(str, stream) == EOF ? EOF : 0; } +#if !defined(__USE_MINGW_ANSI_STDIO) || !__USE_MINGW_ANSI_STDIO +/* + * Prior to Windows 10 vsnprintf was incompatible with the C99 standard. + * Implement a replacement using _vsnprintf. + */ +int winansi_vsnprintf(char *buf, size_t size, const char *format, va_list list) +{ + size_t len; + va_list list2; + + va_copy(list2, list); + len = _vsnprintf(NULL, 0, format, list2); + if (len < 0) + return -1; + + _vsnprintf(buf, size, format, list); + buf[size-1] = '\0'; + return len; +} +#endif + int winansi_vfprintf(FILE *stream, const char *format, va_list list) { int len, rv; -- cgit v1.2.3-55-g6feb