---
 mingw-w64-crt/include/msvcrt_or_emu_glue.h | 112 +++++++++++++++++++++
 mingw-w64-headers/crt/_mingw_mac.h         |  15 +--
 2 files changed, 121 insertions(+), 6 deletions(-)
 create mode 100644 mingw-w64-crt/include/msvcrt_or_emu_glue.h

diff --git a/mingw-w64-crt/include/msvcrt_or_emu_glue.h 
b/mingw-w64-crt/include/msvcrt_or_emu_glue.h
new file mode 100644
index 000000000000..ac5834b577b0
--- /dev/null
+++ b/mingw-w64-crt/include/msvcrt_or_emu_glue.h
@@ -0,0 +1,112 @@
+/**
+ * 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 <_mingw_mac.h>
+
+/*
+ * Example usage of this include file:
+ *
+ * #define RETT int
+ * #define FUNC func1
+ * #define ARGS int arg1, int arg2
+ * #define CALL arg1, arg2
+ * #include "msvcrt_or_emu_glue.h"
+ *
+ * This example defines function named "func1" with signature:
+ * int __cdecl func1(int arg1, int arg2) { ... }
+ *
+ * This function "func1" would either call emulation function named "emu_func1"
+ * which always has to be declarated (it should be defined as static in the
+ * same source file) or would call function named "func1" from "msvcrt.dll"
+ * library if exists.
+*/
+
+#if !defined(RETT) || !defined(FUNC) || !defined(ARGS) || !defined(CALL)
+#error "Missing definitions for msvcrt_or_emu_glue.h"
+#endif
+
+#if defined(FORCEEMU) || !defined(__LIBMSVCRT_OS__)
+
+/*
+ * If not compiling for os-system version of msvcrt.dll or FORCEEMU was
+ * specified then always use emulated version.
+ */
+
+#ifdef NORETURN
+__MINGW_ATTRIB_NORETURN
+#endif
+RETT __attribute__((alias(__MINGW64_STRINGIFY(__MINGW64_PASTE(emu_,FUNC))))) 
__cdecl FUNC(ARGS);
+#ifdef NORETURN
+__MINGW_ATTRIB_NORETURN
+#endif
+RETT (__cdecl *__MINGW_IMP_SYMBOL(FUNC))(ARGS) = FUNC;
+
+#else
+
+/*
+ * If compiling for os-system version of msvcrt.dll and FORCEEMU was not
+ * specified then try to use function from msvcrt.dll and fallback to
+ * emulated version only if function does not exist in msvcrt.dll.
+ */
+
+#include <windows.h>
+#include <msvcrt.h>
+
+#ifdef NORETURN
+__MINGW_ATTRIB_NORETURN
+#endif
+static RETT __cdecl __MINGW64_PASTE(init_,FUNC)(ARGS);
+
+#ifdef NORETURN
+__MINGW_ATTRIB_NORETURN
+#endif
+RETT (__cdecl *volatile __MINGW_IMP_SYMBOL(FUNC))(ARGS) = 
__MINGW64_PASTE(init_,FUNC);
+
+#ifdef NORETURN
+__MINGW_ATTRIB_NORETURN
+#endif
+static RETT __cdecl __MINGW64_PASTE(init_,FUNC)(ARGS)
+{
+    HMODULE msvcrt = __mingw_get_msvcrt_handle();
+#ifdef NORETURN
+    __MINGW_ATTRIB_NORETURN
+#endif
+    RETT (__cdecl *func)(ARGS) = NULL;
+
+    if (msvcrt)
+        func = (typeof(func))(void (__cdecl *)(void))GetProcAddress(msvcrt, 
__MINGW64_STRINGIFY(FUNC));
+
+    if (!func)
+        func = __MINGW64_PASTE(emu_,FUNC);
+
+    (void)InterlockedExchangePointer((PVOID volatile 
*)&__MINGW_IMP_SYMBOL(FUNC), func);
+
+#ifndef NORETURN
+    return
+#endif
+    func(CALL);
+}
+
+#ifdef NORETURN
+__MINGW_ATTRIB_NORETURN
+#endif
+RETT __cdecl FUNC(ARGS)
+{
+#ifndef NORETURN
+    return
+#endif
+    __MINGW_IMP_SYMBOL(FUNC)(CALL);
+}
+
+#endif
+
+/* Now undefine the definitions, so the file can be included more times. */
+#undef FORCEEMU
+#undef NORETURN
+#undef RETT
+#undef FUNC
+#undef ARGS
+#undef CALL
diff --git a/mingw-w64-headers/crt/_mingw_mac.h 
b/mingw-w64-headers/crt/_mingw_mac.h
index 3fe61328edfb..7ceabe7474f8 100644
--- a/mingw-w64-headers/crt/_mingw_mac.h
+++ b/mingw-w64-headers/crt/_mingw_mac.h
@@ -7,6 +7,9 @@
 #ifndef _INC_CRTDEFS_MACRO
 #define _INC_CRTDEFS_MACRO
 
+#define __PASTE(x, y) x ## y
+#define __MINGW64_PASTE(x, y) __PASTE(x, y)
+
 #define __STRINGIFY(x) #x
 #define __MINGW64_STRINGIFY(x) \
   __STRINGIFY(x)
@@ -123,14 +126,14 @@
 #endif /* ifndef _X86_ */
 
 #if __MINGW_USE_UNDERSCORE_PREFIX == 0
-#  define __MINGW_IMP_SYMBOL(sym) __imp_##sym
-#  define __MINGW_IMP_LSYMBOL(sym) __imp_##sym
+#  define __MINGW_IMP_SYMBOL(sym) __MINGW64_PASTE(__imp_,sym)
+#  define __MINGW_IMP_LSYMBOL(sym) __MINGW64_PASTE(__imp_,sym)
 #  define __MINGW_USYMBOL(sym) sym
-#  define __MINGW_LSYMBOL(sym) _##sym
+#  define __MINGW_LSYMBOL(sym) __MINGW64_PASTE(_,sym)
 #else /* ! if __MINGW_USE_UNDERSCORE_PREFIX == 0 */
-#  define __MINGW_IMP_SYMBOL(sym) _imp__##sym
-#  define __MINGW_IMP_LSYMBOL(sym) __imp__##sym
-#  define __MINGW_USYMBOL(sym) _##sym
+#  define __MINGW_IMP_SYMBOL(sym) __MINGW64_PASTE(_imp__,sym)
+#  define __MINGW_IMP_LSYMBOL(sym) __MINGW64_PASTE(__imp__,sym)
+#  define __MINGW_USYMBOL(sym) __MINGW64_PASTE(_,sym)
 #  define __MINGW_LSYMBOL(sym) sym
 #endif /* if __MINGW_USE_UNDERSCORE_PREFIX == 0 */
 
-- 
2.20.1



_______________________________________________
Mingw-w64-public mailing list
Mingw-w64-public@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/mingw-w64-public

Reply via email to