To: vim_dev@googlegroups.com Subject: Patch 8.2.2211 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 8.2.2211 Problem: MS-Windows: can't load Python dll if not in the path. Solution: Use the InstallPath registry entry. (Kelvin Lee, closes #7540) Files: src/if_python3.c *** ../vim-8.2.2210/src/if_python3.c 2020-12-21 16:02:58.486392542 +0100 --- src/if_python3.c 2020-12-25 13:52:08.089394234 +0100 *************** *** 671,676 **** --- 671,735 ---- # 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,706 **** --- 760,779 ---- 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) *** ../vim-8.2.2210/src/version.c 2020-12-25 13:20:36.799341018 +0100 --- src/version.c 2020-12-25 13:52:20.381355066 +0100 *************** *** 752,753 **** --- 752,755 ---- { /* Add new patch number below this line */ + /**/ + 2211, /**/ -- How To Keep A Healthy Level Of Insanity: 3. Every time someone asks you to do something, ask if they want fries with that. /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\ \\\ an exciting new programming language -- http://www.Zimbu.org /// \\\ help me help AIDS victims -- http://ICCF-Holland.org ///