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

Reply via email to