MinGW-w64 (v)snprintf() implementation uses windows functions _(v)snprintf() and _(v)scprintf(). Runtime library crtdll.dll provides only _(v)snprintf(), so include MinGW-w64 emulation of _(v)scprintf() functions into libcrtdll.a import library.
As <msvcrt.h> header file and __mingw_get_msvcrt_handle() function depend on msvcrtl.dll library do not use them in _scprintf.c and _vscprintf.c source files when building object files for libcrtdll.a import library. With this change it is possible to use snprintf() function in application which uses crtdll.dll runtime library. --- mingw-w64-crt/Makefile.am | 3 +++ mingw-w64-crt/stdio/_scprintf.c | 21 ++++++++++++++++++++- mingw-w64-crt/stdio/_vscprintf.c | 11 ++++++++++- 3 files changed, 33 insertions(+), 2 deletions(-) diff --git a/mingw-w64-crt/Makefile.am b/mingw-w64-crt/Makefile.am index c669f131c5f1..305d1b934e65 100644 --- a/mingw-w64-crt/Makefile.am +++ b/mingw-w64-crt/Makefile.am @@ -425,6 +425,9 @@ src_crtdll=\ misc/__set_app_type.c \ misc/invalid_parameter_handler.c \ misc/lc_locale_func.c \ + misc/seterrno.c \ + stdio/_scprintf.c \ + stdio/_vscprintf.c \ stdio/mingw_lock.c src_msvcr120_app=\ diff --git a/mingw-w64-crt/stdio/_scprintf.c b/mingw-w64-crt/stdio/_scprintf.c index eb3044a8c5df..bcee08a957b7 100644 --- a/mingw-w64-crt/stdio/_scprintf.c +++ b/mingw-w64-crt/stdio/_scprintf.c @@ -4,7 +4,6 @@ * No warranty is given; refer to the file DISCLAIMER.PD within this package. */ #include <windows.h> -#include <msvcrt.h> #include <stdarg.h> #include <stdio.h> #include <string.h> @@ -21,6 +20,24 @@ static int __cdecl emu_scprintf(const char * __restrict__ format, ...) return ret; } +#ifndef __LIBMSVCRT_OS__ + +int (__cdecl *__MINGW_IMP_SYMBOL(_scprintf))(const char * __restrict__, ...) = emu_scprintf; + +/* gcc does not provide an easy way to call another variadic function with reusing current arguments + * this source file is used only on i386, so do this function redirect via inline i386 assembly */ +#define ASM_SYM(sym) __MINGW64_STRINGIFY(__MINGW_USYMBOL(sym)) +asm ( +".globl\t" ASM_SYM(_scprintf) "\n\t" +".def\t" ASM_SYM(_scprintf) ";\t.scl\t2;\t.type\t32;\t.endef\n" +ASM_SYM(_scprintf) ":\n\t" + "jmp\t*" ASM_SYM(__MINGW_IMP_SYMBOL(_scprintf)) +); + +#else + +#include <msvcrt.h> + static int __cdecl init_scprintf(const char * __restrict__ format, ...); int (__cdecl *__MINGW_IMP_SYMBOL(_scprintf))(const char * __restrict__, ...) = init_scprintf; @@ -55,3 +72,5 @@ ASM_SYM(init_scprintf) ":\n\t" ASM_SYM(_scprintf) ":\n\t" "jmp\t*" ASM_SYM(__MINGW_IMP_SYMBOL(_scprintf)) ); + +#endif diff --git a/mingw-w64-crt/stdio/_vscprintf.c b/mingw-w64-crt/stdio/_vscprintf.c index 6bbbb274a5ff..b859b9a2a028 100644 --- a/mingw-w64-crt/stdio/_vscprintf.c +++ b/mingw-w64-crt/stdio/_vscprintf.c @@ -4,7 +4,6 @@ * No warranty is given; refer to the file DISCLAIMER.PD within this package. */ #include <windows.h> -#include <msvcrt.h> #include <stdarg.h> #include <stdio.h> #include <stdlib.h> @@ -53,6 +52,14 @@ static int __cdecl emu_vscprintf(const char * __restrict__ format, va_list argli return ret; } +#ifndef __LIBMSVCRT_OS__ + +int (__cdecl *__MINGW_IMP_SYMBOL(_vscprintf))(const char * __restrict__, va_list) = emu_vscprintf; + +#else + +#include <msvcrt.h> + static int __cdecl init_vscprintf(const char * __restrict__ format, va_list arglist); int (__cdecl *__MINGW_IMP_SYMBOL(_vscprintf))(const char * __restrict__, va_list) = init_vscprintf; @@ -71,6 +78,8 @@ static int __cdecl init_vscprintf(const char * __restrict__ format, va_list argl return (__MINGW_IMP_SYMBOL(_vscprintf) = func)(format, arglist); } +#endif + int __cdecl _vscprintf(const char * __restrict__ format, va_list arglist) { return __MINGW_IMP_SYMBOL(_vscprintf)(format, arglist); -- 2.20.1 _______________________________________________ Mingw-w64-public mailing list Mingw-w64-public@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/mingw-w64-public