diff options
-rw-r--r-- | src/if_python3.c | 73 | ||||
-rw-r--r-- | src/version.c | 2 |
2 files changed, 75 insertions, 0 deletions
diff --git a/src/if_python3.c b/src/if_python3.c index ea4fd7dd8..f9c8002da 100644 --- a/src/if_python3.c +++ b/src/if_python3.c @@ -671,6 +671,65 @@ py3_PyType_HasFeature(PyTypeObject *type, unsigned long feature) # define PyType_HasFeature(t,f) py3_PyType_HasFeature(t,f) # endif +# ifdef MSWIN +/* + * Look up the library "libname" using the InstallPath registry key. + * Return NULL when failed. Return an allocated string when successful. + */ + static char * +py3_get_system_libname(const char *libname) +{ + const char *cp = libname; + char subkey[128]; + HKEY hKey; + char installpath[MAXPATHL]; + LONG len = sizeof(installpath); + LSTATUS rc; + size_t sysliblen; + char *syslibname; + + while (*cp != '\0') + { + if (*cp == ':' || *cp == '\\' || *cp == '/') + { + // Bail out if "libname" contains path separator, assume it is + // an absolute path. + return NULL; + } + ++cp; + } + vim_snprintf(subkey, sizeof(subkey), +# ifdef _WIN64 + "Software\\Python\\PythonCore\\%d.%d\\InstallPath", +# else + "Software\\Python\\PythonCore\\%d.%d-32\\InstallPath", +# endif + PY_MAJOR_VERSION, PY_MINOR_VERSION); + if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, subkey, 0, KEY_QUERY_VALUE, &hKey) + != ERROR_SUCCESS) + return NULL; + rc = RegQueryValueA(hKey, NULL, installpath, &len); + RegCloseKey(hKey); + if (ERROR_SUCCESS != rc) + return NULL; + cp = installpath + len; + // Just in case registry value contains null terminators. + while (cp > installpath && *(cp-1) == '\0') + --cp; + // Remove trailing path separators. + while (cp > installpath && (*(cp-1) == '\\' || *(cp-1) == '/')) + --cp; + // Ignore if InstallPath is effectively empty. + if (cp <= installpath) + return NULL; + sysliblen = (cp - installpath) + 1 + STRLEN(libname) + 1; + syslibname = alloc(sysliblen); + vim_snprintf(syslibname, sysliblen, "%.*s\\%s", + (int)(cp - installpath), installpath, libname); + return syslibname; +} +# endif + /* * Load library and get all pointers. * Parameter 'libname' provides name of DLL. @@ -701,6 +760,20 @@ py3_runtime_link_init(char *libname, int verbose) return OK; hinstPy3 = load_dll(libname); +# ifdef MSWIN + if (!hinstPy3) + { + // Attempt to use the path from InstallPath as stored in the registry. + char *syslibname = py3_get_system_libname(libname); + + if (syslibname != NULL) + { + hinstPy3 = load_dll(syslibname); + vim_free(syslibname); + } + } +# endif + if (!hinstPy3) { if (verbose) diff --git a/src/version.c b/src/version.c index 018bfd52a..762e91263 100644 --- a/src/version.c +++ b/src/version.c @@ -751,6 +751,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 2211, +/**/ 2210, /**/ 2209, |