Original MSVC 6.0 msvcrt.dll library does not provide _scprintf()
function. Add fallback _scprintf() implementation like for _vscprintf().
---
mingw-w64-crt/Makefile.am | 1 +
mingw-w64-crt/lib-common/msvcrt.def.in | 4 ++
mingw-w64-crt/misc/_scprintf.c | 52 ++++++++++++++++++++++++++
3 files changed, 57 insertions(+)
create mode 100644 mingw-w64-crt/misc/_scprintf.c
diff --git a/mingw-w64-crt/Makefile.am b/mingw-w64-crt/Makefile.am
index 1be9250c1e53..8ced6bd97b00 100644
--- a/mingw-w64-crt/Makefile.am
+++ b/mingw-w64-crt/Makefile.am
@@ -282,6 +282,7 @@ src_msvcrt32=\
misc/_create_locale.c \
misc/_free_locale.c \
misc/_get_current_locale.c \
+ misc/_scprintf.c \
misc/_vscprintf.c \
misc/lc_locale_func.c \
misc/wassert.c
diff --git a/mingw-w64-crt/lib-common/msvcrt.def.in
b/mingw-w64-crt/lib-common/msvcrt.def.in
index 17bc7e9a076e..cb4cbac0c936 100644
--- a/mingw-w64-crt/lib-common/msvcrt.def.in
+++ b/mingw-w64-crt/lib-common/msvcrt.def.in
@@ -930,7 +930,11 @@ _scalb
F_X64(_scalbf)
_scanf_l
_scanf_s_l
+#ifdef DEF_I386
+; _scprintf provided by emu
+#else
_scprintf
+#endif
_scprintf_l
_scprintf_p_l
_scwprintf
diff --git a/mingw-w64-crt/misc/_scprintf.c b/mingw-w64-crt/misc/_scprintf.c
new file mode 100644
index 000000000000..00fbcaa8c283
--- /dev/null
+++ b/mingw-w64-crt/misc/_scprintf.c
@@ -0,0 +1,52 @@
+/**
+ * This file has no copyright assigned and is placed in the Public Domain.
+ * This file is part of the mingw-w64 runtime package.
+ * 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>
+
+/* mingw-w64 always provides _vscprintf() implementation, so use it */
+static int __cdecl emu_scprintf(const char * __restrict__ format, ...)
+{
+ va_list arglist;
+ int ret;
+
+ va_start(arglist, format);
+ ret = _vscprintf(format, arglist);
+ va_end(arglist);
+ return ret;
+}
+
+static int __cdecl init_scprintf(const char * __restrict__ format, ...);
+
+int (__cdecl *__MINGW_IMP_SYMBOL(_scprintf))(const char * __restrict__, ...) =
init_scprintf;
+
+static void resolve_scprintf(void)
+{
+ HMODULE msvcrt = __mingw_get_msvcrt_handle();
+ int (__cdecl *func)(const char * __restrict__, ...) = NULL;
+
+ if (msvcrt)
+ func = (int (__cdecl *)(const char * __restrict__,
...))GetProcAddress(msvcrt, "_scprintf");
+
+ if (!func)
+ func = emu_scprintf;
+
+ __MINGW_IMP_SYMBOL(_scprintf) = func;
+}
+
+/* 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 (
+".def " ASM_SYM(init_scprintf) "; .scl 3; .type 32;
.endef\n"
+ASM_SYM(init_scprintf) ":\n"
+" pushal\n"
+" call " ASM_SYM(resolve_scprintf) "\n"
+" popal\n"
+" jmp *" ASM_SYM(__MINGW_IMP_SYMBOL(_scprintf))
+);
--
2.20.1
_______________________________________________
Mingw-w64-public mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/mingw-w64-public