summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChun-wei Fan <fanchunwei@src.gnome.org>2018-08-21 09:04:08 +0800
committerChun-wei Fan <fanchunwei@src.gnome.org>2018-08-21 09:53:05 +0800
commit2a6fc83276e9ced066ea08aed591f40bba0409eb (patch)
treeabc06fda02f549c6df01981abff3a20d9cd5bcbc
parent032eac543d7aa44dbc4af3f4fd94be1dc4a93caf (diff)
downloadgobject-introspection-2a6fc83276e9ced066ea08aed591f40bba0409eb.tar.gz
Revert "scanner: remove hacks to make mingw g-i work with msvc Python"
Unfortunately, this is still needed for Visual Studio versions that do not have an official CPython release that uses the CRT which the compiler targets to, such as Visual Studio 2012 and 2013 This reverts commit a6a479af1bbe7c0d17766f1408c9fcb720df78dc.
-rw-r--r--giscanner/giscannermodule.c84
1 files changed, 84 insertions, 0 deletions
diff --git a/giscanner/giscannermodule.c b/giscanner/giscannermodule.c
index 5fc2fd4d..c37357bd 100644
--- a/giscanner/giscannermodule.c
+++ b/giscanner/giscannermodule.c
@@ -447,6 +447,90 @@ pygi_source_scanner_parse_file (PyGISourceScanner *self,
if (!PyArg_ParseTuple (args, "i:SourceScanner.parse_file", &fd))
return NULL;
+#ifdef _WIN32
+ /* The file descriptor passed to us is from the C library Python
+ * uses. That is msvcr71.dll for Python 2.5 and msvcr90.dll for
+ * Python 2.6, 2.7, 3.2 etc; and msvcr100.dll for Python 3.3 and 3.4.
+ * Python 3.5 and later is built with Visual Studio 2015, which uses
+ * the universal CRT, so we need to deal with urtbase.dll here instead.
+ * This code, at least if compiled with mingw, uses
+ * msvcrt.dll, so we cannot use the file descriptor directly. So
+ * perform appropriate magic.
+ */
+
+ /* If we are using the following combinations,
+ * we can use the file descriptors directly
+ * (Not if a build using WDK is used):
+ * Python 2.6.x/2.7.x with Visual C++ 2008
+ * Python 3.1.x/3.2.x with Visual C++ 2008
+ * Python 3.3.x/3.4.x with Visual C++ 2010
+ */
+
+ /* XXX: Somehow we cannot use the FD directly on Python 3.5+ even when
+ * using Visual Studio 2015, so we currently need to use _get_osfhandle() when
+ * in all cases on Python 3.5+
+ */
+
+#if (defined(_MSC_VER) && !defined(USE_WIN_DDK))
+#if (PY_MAJOR_VERSION==2 && PY_MINOR_VERSION>=6 && (_MSC_VER >= 1500 && _MSC_VER < 1600))
+#define MSVC_USE_FD_DIRECTLY 1
+#elif (PY_MAJOR_VERSION==3 && PY_MINOR_VERSION<=2 && (_MSC_VER >= 1500 && _MSC_VER < 1600))
+#define MSVC_USE_FD_DIRECTLY 1
+#elif (PY_MAJOR_VERSION==3 && PY_MINOR_VERSION<=4 && (_MSC_VER >= 1600 && _MSC_VER < 1700))
+#define MSVC_USE_FD_DIRECTLY 1
+#endif
+#endif
+
+#if !defined(MSVC_USE_FD_DIRECTLY) && !defined(__MINGW64_VERSION_MAJOR)
+ {
+#if defined(PY_MAJOR_VERSION) && PY_MAJOR_VERSION==2 && PY_MINOR_VERSION==5
+#define PYTHON_MSVCRXX_DLL "msvcr71.dll"
+#elif defined(PY_MAJOR_VERSION) && PY_MAJOR_VERSION==2 && PY_MINOR_VERSION==7
+#define PYTHON_MSVCRXX_DLL "msvcr90.dll"
+#elif defined(PY_MAJOR_VERSION) && PY_MAJOR_VERSION==3 && PY_MINOR_VERSION<=2
+#define PYTHON_MSVCRXX_DLL "msvcr90.dll"
+#elif defined(PY_MAJOR_VERSION) && PY_MAJOR_VERSION==3 && PY_MINOR_VERSION<=4
+#define PYTHON_MSVCRXX_DLL "msvcr100.dll"
+#elif defined(PY_MAJOR_VERSION) && PY_MAJOR_VERSION==3 && PY_MINOR_VERSION>=5
+#define PYTHON_MSVCRXX_DLL "ucrtbase.dll"
+#else
+#error This Python version not handled
+#endif
+ HMODULE msvcrxx;
+ intptr_t (*p__get_osfhandle) (int);
+ HANDLE handle;
+
+ msvcrxx = GetModuleHandle (PYTHON_MSVCRXX_DLL);
+ if (!msvcrxx)
+ {
+ g_print ("No " PYTHON_MSVCRXX_DLL " loaded.\n");
+ return NULL;
+ }
+
+ p__get_osfhandle = (intptr_t (*) (int)) GetProcAddress (msvcrxx, "_get_osfhandle");
+ if (!p__get_osfhandle)
+ {
+ g_print ("No _get_osfhandle found in " PYTHON_MSVCRXX_DLL ".\n");
+ return NULL;
+ }
+
+ handle = (HANDLE) p__get_osfhandle (fd);
+ if (!p__get_osfhandle)
+ {
+ g_print ("Could not get OS handle from " PYTHON_MSVCRXX_DLL " fd.\n");
+ return NULL;
+ }
+
+ fd = _open_osfhandle ((intptr_t) handle, _O_RDONLY);
+ if (fd == -1)
+ {
+ g_print ("Could not open C fd from OS handle.\n");
+ return NULL;
+ }
+ }
+#endif
+#endif
+
fp = fdopen (fd, "r");
if (!fp)
{