#include <string.h>
#ifdef __APPLE__
-#include <mach-o/dyld.h>
+# include <mach-o/dyld.h>
#endif
/* Search in some common locations for the associated Python libraries.
*/
#ifdef __cplusplus
- extern "C" {
+extern "C" {
#endif
#define LANDMARK L"os.py"
#endif
-static wchar_t prefix[MAXPATHLEN+1];
-static wchar_t exec_prefix[MAXPATHLEN+1];
-static wchar_t progpath[MAXPATHLEN+1];
-static wchar_t *module_search_path = NULL;
+typedef struct {
+ wchar_t prefix[MAXPATHLEN+1];
+ wchar_t exec_prefix[MAXPATHLEN+1];
+ wchar_t progpath[MAXPATHLEN+1];
+ wchar_t *module_search_path;
+} PyPathConfig;
+
+typedef struct {
+ wchar_t *path_env; /* PATH environment variable */
+ wchar_t *home; /* PYTHONHOME environment variable */
+ wchar_t *module_search_path_env; /* PYTHONPATH environment variable */
+ wchar_t *module_search_path_buffer;
+
+ wchar_t *prog; /* Program name */
+ wchar_t *pythonpath; /* PYTHONPATH define */
+ wchar_t *prefix; /* PREFIX define */
+ wchar_t *exec_prefix; /* EXEC_PREFIX define */
+
+ wchar_t *lib_python; /* "lib/pythonX.Y" */
+ wchar_t argv0_path[MAXPATHLEN+1];
+ wchar_t zip_path[MAXPATHLEN+1]; /* ".../lib/pythonXY.zip" */
+
+ int prefix_found; /* found platform independent libraries? */
+ int exec_prefix_found; /* found the platform dependent libraries? */
+} PyCalculatePath;
+
+static const wchar_t delimiter[2] = {DELIM, '\0'};
+static const wchar_t separator[2] = {SEP, '\0'};
+static PyPathConfig path_config = {.module_search_path = NULL};
-/* Get file status. Encode the path to the locale encoding. */
+/* Get file status. Encode the path to the locale encoding. */
static int
_Py_wstat(const wchar_t* path, struct stat *buf)
{
return err;
}
+
static void
reduce(wchar_t *dir)
{
dir[i] = '\0';
}
+
static int
isfile(wchar_t *filename) /* Is file, not directory */
{
struct stat buf;
- if (_Py_wstat(filename, &buf) != 0)
+ if (_Py_wstat(filename, &buf) != 0) {
return 0;
- if (!S_ISREG(buf.st_mode))
+ }
+ if (!S_ISREG(buf.st_mode)) {
return 0;
+ }
return 1;
}
static int
ismodule(wchar_t *filename) /* Is module -- check for .pyc too */
{
- if (isfile(filename))
+ if (isfile(filename)) {
return 1;
+ }
/* Check for the compiled version of prefix. */
if (wcslen(filename) < MAXPATHLEN) {
wcscat(filename, L"c");
- if (isfile(filename))
+ if (isfile(filename)) {
return 1;
+ }
}
return 0;
}
+/* Is executable file */
static int
-isxfile(wchar_t *filename) /* Is executable file */
+isxfile(wchar_t *filename)
{
struct stat buf;
- if (_Py_wstat(filename, &buf) != 0)
+ if (_Py_wstat(filename, &buf) != 0) {
return 0;
- if (!S_ISREG(buf.st_mode))
+ }
+ if (!S_ISREG(buf.st_mode)) {
return 0;
- if ((buf.st_mode & 0111) == 0)
+ }
+ if ((buf.st_mode & 0111) == 0) {
return 0;
+ }
return 1;
}
+/* Is directory */
static int
-isdir(wchar_t *filename) /* Is directory */
+isdir(wchar_t *filename)
{
struct stat buf;
- if (_Py_wstat(filename, &buf) != 0)
+ if (_Py_wstat(filename, &buf) != 0) {
return 0;
- if (!S_ISDIR(buf.st_mode))
+ }
+ if (!S_ISDIR(buf.st_mode)) {
return 0;
+ }
return 1;
}
joinpath(wchar_t *buffer, wchar_t *stuff)
{
size_t n, k;
- if (stuff[0] == SEP)
+ if (stuff[0] == SEP) {
n = 0;
+ }
else {
n = wcslen(buffer);
- if (n > 0 && buffer[n-1] != SEP && n < MAXPATHLEN)
+ if (n > 0 && buffer[n-1] != SEP && n < MAXPATHLEN) {
buffer[n++] = SEP;
+ }
}
- if (n > MAXPATHLEN)
+ if (n > MAXPATHLEN) {
Py_FatalError("buffer overflow in getpath.c's joinpath()");
+ }
k = wcslen(stuff);
- if (n + k > MAXPATHLEN)
+ if (n + k > MAXPATHLEN) {
k = MAXPATHLEN - n;
+ }
wcsncpy(buffer+n, stuff, k);
buffer[n+k] = '\0';
}
+
/* copy_absolute requires that path be allocated at least
MAXPATHLEN + 1 bytes and that p be no more than MAXPATHLEN bytes. */
static void
copy_absolute(wchar_t *path, wchar_t *p, size_t pathlen)
{
- if (p[0] == SEP)
+ if (p[0] == SEP) {
wcscpy(path, p);
+ }
else {
if (!_Py_wgetcwd(path, pathlen)) {
/* unable to get the current directory */
wcscpy(path, p);
return;
}
- if (p[0] == '.' && p[1] == SEP)
+ if (p[0] == '.' && p[1] == SEP) {
p += 2;
+ }
joinpath(path, p);
}
}
+
/* absolutize() requires that path be allocated at least MAXPATHLEN+1 bytes. */
static void
absolutize(wchar_t *path)
{
wchar_t buffer[MAXPATHLEN+1];
- if (path[0] == SEP)
+ if (path[0] == SEP) {
return;
+ }
copy_absolute(buffer, path, MAXPATHLEN+1);
wcscpy(path, buffer);
}
+
/* search for a prefix value in an environment file. If found, copy it
to the provided buffer, which is expected to be no more than MAXPATHLEN
bytes long.
*/
-
static int
find_env_config_value(FILE * env_file, const wchar_t * key, wchar_t * value)
{
PyObject * decoded;
int n;
- if (p == NULL)
+ if (p == NULL) {
break;
+ }
n = strlen(p);
if (p[n - 1] != '\n') {
/* line has overflowed - bail */
break;
}
- if (p[0] == '#') /* Comment - skip */
+ if (p[0] == '#') {
+ /* Comment - skip */
continue;
+ }
decoded = PyUnicode_DecodeUTF8(buffer, n, "surrogateescape");
if (decoded != NULL) {
Py_ssize_t k;
return result;
}
+
/* search_for_prefix requires that argv0_path be no more than MAXPATHLEN
bytes long.
*/
static int
-search_for_prefix(wchar_t *argv0_path, wchar_t *home, wchar_t *_prefix,
- wchar_t *lib_python)
+search_for_prefix(PyCalculatePath *calculate, PyPathConfig *config)
{
size_t n;
wchar_t *vpath;
/* If PYTHONHOME is set, we believe it unconditionally */
- if (home) {
- wchar_t *delim;
- wcsncpy(prefix, home, MAXPATHLEN);
- prefix[MAXPATHLEN] = L'\0';
- delim = wcschr(prefix, DELIM);
- if (delim)
+ if (calculate->home) {
+ wcsncpy(config->prefix, calculate->home, MAXPATHLEN);
+ config->prefix[MAXPATHLEN] = L'\0';
+ wchar_t *delim = wcschr(config->prefix, DELIM);
+ if (delim) {
*delim = L'\0';
- joinpath(prefix, lib_python);
- joinpath(prefix, LANDMARK);
+ }
+ joinpath(config->prefix, calculate->lib_python);
+ joinpath(config->prefix, LANDMARK);
return 1;
}
/* Check to see if argv[0] is in the build directory */
- wcsncpy(prefix, argv0_path, MAXPATHLEN);
- prefix[MAXPATHLEN] = L'\0';
- joinpath(prefix, L"Modules/Setup");
- if (isfile(prefix)) {
+ wcsncpy(config->prefix, calculate->argv0_path, MAXPATHLEN);
+ config->prefix[MAXPATHLEN] = L'\0';
+ joinpath(config->prefix, L"Modules/Setup");
+ if (isfile(config->prefix)) {
/* Check VPATH to see if argv0_path is in the build directory. */
vpath = Py_DecodeLocale(VPATH, NULL);
if (vpath != NULL) {
- wcsncpy(prefix, argv0_path, MAXPATHLEN);
- prefix[MAXPATHLEN] = L'\0';
- joinpath(prefix, vpath);
+ wcsncpy(config->prefix, calculate->argv0_path, MAXPATHLEN);
+ config->prefix[MAXPATHLEN] = L'\0';
+ joinpath(config->prefix, vpath);
PyMem_RawFree(vpath);
- joinpath(prefix, L"Lib");
- joinpath(prefix, LANDMARK);
- if (ismodule(prefix))
+ joinpath(config->prefix, L"Lib");
+ joinpath(config->prefix, LANDMARK);
+ if (ismodule(config->prefix)) {
return -1;
+ }
}
}
/* Search from argv0_path, until root is found */
- copy_absolute(prefix, argv0_path, MAXPATHLEN+1);
+ copy_absolute(config->prefix, calculate->argv0_path, MAXPATHLEN+1);
do {
- n = wcslen(prefix);
- joinpath(prefix, lib_python);
- joinpath(prefix, LANDMARK);
- if (ismodule(prefix))
+ n = wcslen(config->prefix);
+ joinpath(config->prefix, calculate->lib_python);
+ joinpath(config->prefix, LANDMARK);
+ if (ismodule(config->prefix)) {
return 1;
- prefix[n] = L'\0';
- reduce(prefix);
- } while (prefix[0]);
+ }
+ config->prefix[n] = L'\0';
+ reduce(config->prefix);
+ } while (config->prefix[0]);
/* Look at configure's PREFIX */
- wcsncpy(prefix, _prefix, MAXPATHLEN);
- prefix[MAXPATHLEN] = L'\0';
- joinpath(prefix, lib_python);
- joinpath(prefix, LANDMARK);
- if (ismodule(prefix))
+ wcsncpy(config->prefix, calculate->prefix, MAXPATHLEN);
+ config->prefix[MAXPATHLEN] = L'\0';
+ joinpath(config->prefix, calculate->lib_python);
+ joinpath(config->prefix, LANDMARK);
+ if (ismodule(config->prefix)) {
return 1;
+ }
/* Fail */
return 0;
}
+static void
+calculate_prefix(PyCalculatePath *calculate, PyPathConfig *config)
+{
+ calculate->prefix_found = search_for_prefix(calculate, config);
+ if (!calculate->prefix_found) {
+ if (!Py_FrozenFlag) {
+ fprintf(stderr,
+ "Could not find platform independent libraries <prefix>\n");
+ }
+ wcsncpy(config->prefix, calculate->prefix, MAXPATHLEN);
+ joinpath(config->prefix, calculate->lib_python);
+ }
+ else {
+ reduce(config->prefix);
+ }
+}
+
+
+static void
+calculate_reduce_prefix(PyCalculatePath *calculate, PyPathConfig *config)
+{
+ /* Reduce prefix and exec_prefix to their essence,
+ * e.g. /usr/local/lib/python1.5 is reduced to /usr/local.
+ * If we're loading relative to the build directory,
+ * return the compiled-in defaults instead.
+ */
+ if (calculate->prefix_found > 0) {
+ reduce(config->prefix);
+ reduce(config->prefix);
+ /* The prefix is the root directory, but reduce() chopped
+ * off the "/". */
+ if (!config->prefix[0]) {
+ wcscpy(config->prefix, separator);
+ }
+ }
+ else {
+ wcsncpy(config->prefix, calculate->prefix, MAXPATHLEN);
+ }
+}
+
+
/* search_for_exec_prefix requires that argv0_path be no more than
MAXPATHLEN bytes long.
*/
static int
-search_for_exec_prefix(wchar_t *argv0_path, wchar_t *home,
- wchar_t *_exec_prefix, wchar_t *lib_python)
+search_for_exec_prefix(PyCalculatePath *calculate, PyPathConfig *config)
{
size_t n;
/* If PYTHONHOME is set, we believe it unconditionally */
- if (home) {
- wchar_t *delim;
- delim = wcschr(home, DELIM);
- if (delim)
- wcsncpy(exec_prefix, delim+1, MAXPATHLEN);
- else
- wcsncpy(exec_prefix, home, MAXPATHLEN);
- exec_prefix[MAXPATHLEN] = L'\0';
- joinpath(exec_prefix, lib_python);
- joinpath(exec_prefix, L"lib-dynload");
+ if (calculate->home) {
+ wchar_t *delim = wcschr(calculate->home, DELIM);
+ if (delim) {
+ wcsncpy(config->exec_prefix, delim+1, MAXPATHLEN);
+ }
+ else {
+ wcsncpy(config->exec_prefix, calculate->home, MAXPATHLEN);
+ }
+ config->exec_prefix[MAXPATHLEN] = L'\0';
+ joinpath(config->exec_prefix, calculate->lib_python);
+ joinpath(config->exec_prefix, L"lib-dynload");
return 1;
}
/* Check to see if argv[0] is in the build directory. "pybuilddir.txt"
is written by setup.py and contains the relative path to the location
of shared library modules. */
- wcsncpy(exec_prefix, argv0_path, MAXPATHLEN);
- exec_prefix[MAXPATHLEN] = L'\0';
- joinpath(exec_prefix, L"pybuilddir.txt");
- if (isfile(exec_prefix)) {
- FILE *f = _Py_wfopen(exec_prefix, L"rb");
- if (f == NULL)
+ wcsncpy(config->exec_prefix, calculate->argv0_path, MAXPATHLEN);
+ config->exec_prefix[MAXPATHLEN] = L'\0';
+ joinpath(config->exec_prefix, L"pybuilddir.txt");
+ if (isfile(config->exec_prefix)) {
+ FILE *f = _Py_wfopen(config->exec_prefix, L"rb");
+ if (f == NULL) {
errno = 0;
+ }
else {
char buf[MAXPATHLEN+1];
PyObject *decoded;
Py_DECREF(decoded);
if (k >= 0) {
rel_builddir_path[k] = L'\0';
- wcsncpy(exec_prefix, argv0_path, MAXPATHLEN);
- exec_prefix[MAXPATHLEN] = L'\0';
- joinpath(exec_prefix, rel_builddir_path);
+ wcsncpy(config->exec_prefix, calculate->argv0_path, MAXPATHLEN);
+ config->exec_prefix[MAXPATHLEN] = L'\0';
+ joinpath(config->exec_prefix, rel_builddir_path);
return -1;
}
}
}
/* Search from argv0_path, until root is found */
- copy_absolute(exec_prefix, argv0_path, MAXPATHLEN+1);
+ copy_absolute(config->exec_prefix, calculate->argv0_path, MAXPATHLEN+1);
do {
- n = wcslen(exec_prefix);
- joinpath(exec_prefix, lib_python);
- joinpath(exec_prefix, L"lib-dynload");
- if (isdir(exec_prefix))
+ n = wcslen(config->exec_prefix);
+ joinpath(config->exec_prefix, calculate->lib_python);
+ joinpath(config->exec_prefix, L"lib-dynload");
+ if (isdir(config->exec_prefix)) {
return 1;
- exec_prefix[n] = L'\0';
- reduce(exec_prefix);
- } while (exec_prefix[0]);
+ }
+ config->exec_prefix[n] = L'\0';
+ reduce(config->exec_prefix);
+ } while (config->exec_prefix[0]);
/* Look at configure's EXEC_PREFIX */
- wcsncpy(exec_prefix, _exec_prefix, MAXPATHLEN);
- exec_prefix[MAXPATHLEN] = L'\0';
- joinpath(exec_prefix, lib_python);
- joinpath(exec_prefix, L"lib-dynload");
- if (isdir(exec_prefix))
+ wcsncpy(config->exec_prefix, calculate->exec_prefix, MAXPATHLEN);
+ config->exec_prefix[MAXPATHLEN] = L'\0';
+ joinpath(config->exec_prefix, calculate->lib_python);
+ joinpath(config->exec_prefix, L"lib-dynload");
+ if (isdir(config->exec_prefix)) {
return 1;
+ }
/* Fail */
return 0;
}
+
static void
-calculate_path(const _PyMainInterpreterConfig *config)
+calculate_exec_prefix(PyCalculatePath *calculate, PyPathConfig *config)
{
- extern wchar_t *Py_GetProgramName(void);
-
- static const wchar_t delimiter[2] = {DELIM, '\0'};
- static const wchar_t separator[2] = {SEP, '\0'};
- wchar_t *home = _Py_GetPythonHomeWithConfig(config);
- char *_path = getenv("PATH");
- wchar_t *path_buffer = NULL;
- wchar_t *path = NULL;
- wchar_t *prog = Py_GetProgramName();
- wchar_t argv0_path[MAXPATHLEN+1];
- wchar_t zip_path[MAXPATHLEN+1];
- int pfound, efound; /* 1 if found; -1 if found build directory */
- wchar_t *buf;
- size_t bufsz;
- size_t prefixsz;
- wchar_t *defpath;
-#ifdef WITH_NEXT_FRAMEWORK
- NSModule pythonModule;
- const char* modPath;
-#endif
-#ifdef __APPLE__
-#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4
- uint32_t nsexeclength = MAXPATHLEN;
-#else
- unsigned long nsexeclength = MAXPATHLEN;
-#endif
- char execpath[MAXPATHLEN+1];
-#endif
- wchar_t *_pythonpath, *_prefix, *_exec_prefix;
- wchar_t *lib_python;
+ calculate->exec_prefix_found = search_for_exec_prefix(calculate, config);
+ if (!calculate->exec_prefix_found) {
+ if (!Py_FrozenFlag) {
+ fprintf(stderr,
+ "Could not find platform dependent libraries <exec_prefix>\n");
+ }
+ wcsncpy(config->exec_prefix, calculate->exec_prefix, MAXPATHLEN);
+ joinpath(config->exec_prefix, L"lib/lib-dynload");
+ }
+ /* If we found EXEC_PREFIX do *not* reduce it! (Yet.) */
+}
- _pythonpath = Py_DecodeLocale(PYTHONPATH, NULL);
- _prefix = Py_DecodeLocale(PREFIX, NULL);
- _exec_prefix = Py_DecodeLocale(EXEC_PREFIX, NULL);
- lib_python = Py_DecodeLocale("lib/python" VERSION, NULL);
- if (!_pythonpath || !_prefix || !_exec_prefix || !lib_python) {
- Py_FatalError(
- "Unable to decode path variables in getpath.c: "
- "memory error");
+static void
+calculate_reduce_exec_prefix(PyCalculatePath *calculate, PyPathConfig *config)
+{
+ if (calculate->exec_prefix_found > 0) {
+ reduce(config->exec_prefix);
+ reduce(config->exec_prefix);
+ reduce(config->exec_prefix);
+ if (!config->exec_prefix[0]) {
+ wcscpy(config->exec_prefix, separator);
+ }
}
-
- if (_path) {
- path_buffer = Py_DecodeLocale(_path, NULL);
- path = path_buffer;
+ else {
+ wcsncpy(config->exec_prefix, calculate->exec_prefix, MAXPATHLEN);
}
+}
+
+static void
+calculate_progpath(PyCalculatePath *calculate, PyPathConfig *config)
+{
/* If there is no slash in the argv0 path, then we have to
* assume python is on the user's $PATH, since there's no
* other way to find a directory to start the search from. If
* $PATH isn't exported, you lose.
*/
- if (wcschr(prog, SEP))
- wcsncpy(progpath, prog, MAXPATHLEN);
+ if (wcschr(calculate->prog, SEP)) {
+ wcsncpy(config->progpath, calculate->prog, MAXPATHLEN);
+ }
+
#ifdef __APPLE__
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4
+ uint32_t nsexeclength = MAXPATHLEN;
+#else
+ unsigned long nsexeclength = MAXPATHLEN;
+#endif
+ char execpath[MAXPATHLEN+1];
+
/* On Mac OS X, if a script uses an interpreter of the form
* "#!/opt/python2.3/bin/python", the kernel only passes "python"
* as argv[0], which falls through to the $PATH search below.
* absolutize() should help us out below
*/
else if(0 == _NSGetExecutablePath(execpath, &nsexeclength) && execpath[0] == SEP) {
- size_t r = mbstowcs(progpath, execpath, MAXPATHLEN+1);
+ size_t r = mbstowcs(config->progpath, execpath, MAXPATHLEN+1);
if (r == (size_t)-1 || r > MAXPATHLEN) {
/* Could not convert execpath, or it's too long. */
- progpath[0] = '\0';
+ config->progpath[0] = '\0';
}
}
#endif /* __APPLE__ */
- else if (path) {
+ else if (calculate->path_env) {
+ wchar_t *path = calculate->path_env;
while (1) {
wchar_t *delim = wcschr(path, DELIM);
if (delim) {
size_t len = delim - path;
- if (len > MAXPATHLEN)
+ if (len > MAXPATHLEN) {
len = MAXPATHLEN;
- wcsncpy(progpath, path, len);
- *(progpath + len) = '\0';
+ }
+ wcsncpy(config->progpath, path, len);
+ *(config->progpath + len) = '\0';
+ }
+ else {
+ wcsncpy(config->progpath, path, MAXPATHLEN);
}
- else
- wcsncpy(progpath, path, MAXPATHLEN);
- joinpath(progpath, prog);
- if (isxfile(progpath))
+ joinpath(config->progpath, calculate->prog);
+ if (isxfile(config->progpath)) {
break;
+ }
if (!delim) {
- progpath[0] = L'\0';
+ config->progpath[0] = L'\0';
break;
}
path = delim + 1;
}
}
- else
- progpath[0] = '\0';
- PyMem_RawFree(path_buffer);
- if (progpath[0] != SEP && progpath[0] != '\0')
- absolutize(progpath);
- wcsncpy(argv0_path, progpath, MAXPATHLEN);
- argv0_path[MAXPATHLEN] = '\0';
+ else {
+ config->progpath[0] = '\0';
+ }
+ if (config->progpath[0] != SEP && config->progpath[0] != '\0') {
+ absolutize(config->progpath);
+ }
+}
+
+
+static void
+calculate_argv0_path(PyCalculatePath *calculate, PyPathConfig *config)
+{
+ wcsncpy(calculate->argv0_path, config->progpath, MAXPATHLEN);
+ calculate->argv0_path[MAXPATHLEN] = '\0';
#ifdef WITH_NEXT_FRAMEWORK
+ NSModule pythonModule;
+
/* On Mac OS X we have a special case if we're running from a framework.
** This is because the python home should be set relative to the library,
** which is in the framework, not relative to the executable, which may
*/
pythonModule = NSModuleForSymbol(NSLookupAndBindSymbol("_Py_Initialize"));
/* Use dylib functions to find out where the framework was loaded from */
- modPath = NSLibraryNameForModule(pythonModule);
+ const char* modPath = NSLibraryNameForModule(pythonModule);
if (modPath != NULL) {
/* We're in a framework. */
/* See if we might be in the build directory. The framework in the
Py_FatalError("Cannot decode framework location");
}
- wcsncpy(argv0_path, wbuf, MAXPATHLEN);
- reduce(argv0_path);
- joinpath(argv0_path, lib_python);
- joinpath(argv0_path, LANDMARK);
- if (!ismodule(argv0_path)) {
+ wcsncpy(calculate->argv0_path, wbuf, MAXPATHLEN);
+ reduce(calculate->argv0_path);
+ joinpath(calculate->argv0_path, calculate->lib_python);
+ joinpath(calculate->argv0_path, LANDMARK);
+ if (!ismodule(calculate->argv0_path)) {
/* We are in the build directory so use the name of the
executable - we know that the absolute path is passed */
- wcsncpy(argv0_path, progpath, MAXPATHLEN);
+ wcsncpy(calculate->argv0_path, config->progpath, MAXPATHLEN);
}
else {
/* Use the location of the library as the progpath */
- wcsncpy(argv0_path, wbuf, MAXPATHLEN);
+ wcsncpy(calculate->argv0_path, wbuf, MAXPATHLEN);
}
PyMem_RawFree(wbuf);
}
#endif
#if HAVE_READLINK
- {
- wchar_t tmpbuffer[MAXPATHLEN+1];
- int linklen = _Py_wreadlink(progpath, tmpbuffer, MAXPATHLEN);
- while (linklen != -1) {
- if (tmpbuffer[0] == SEP)
- /* tmpbuffer should never be longer than MAXPATHLEN,
- but extra check does not hurt */
- wcsncpy(argv0_path, tmpbuffer, MAXPATHLEN);
- else {
- /* Interpret relative to progpath */
- reduce(argv0_path);
- joinpath(argv0_path, tmpbuffer);
- }
- linklen = _Py_wreadlink(argv0_path, tmpbuffer, MAXPATHLEN);
+ wchar_t tmpbuffer[MAXPATHLEN+1];
+ int linklen = _Py_wreadlink(config->progpath, tmpbuffer, MAXPATHLEN);
+ while (linklen != -1) {
+ if (tmpbuffer[0] == SEP) {
+ /* tmpbuffer should never be longer than MAXPATHLEN,
+ but extra check does not hurt */
+ wcsncpy(calculate->argv0_path, tmpbuffer, MAXPATHLEN);
+ }
+ else {
+ /* Interpret relative to progpath */
+ reduce(calculate->argv0_path);
+ joinpath(calculate->argv0_path, tmpbuffer);
}
+ linklen = _Py_wreadlink(calculate->argv0_path, tmpbuffer, MAXPATHLEN);
}
#endif /* HAVE_READLINK */
- reduce(argv0_path);
+ reduce(calculate->argv0_path);
/* At this point, argv0_path is guaranteed to be less than
- MAXPATHLEN bytes long.
- */
+ MAXPATHLEN bytes long. */
+}
- /* Search for an environment configuration file, first in the
- executable's directory and then in the parent directory.
- If found, open it for use when searching for prefixes.
- */
- {
- wchar_t tmpbuffer[MAXPATHLEN+1];
- wchar_t *env_cfg = L"pyvenv.cfg";
- FILE * env_file = NULL;
+/* Search for an "pyvenv.cfg" environment configuration file, first in the
+ executable's directory and then in the parent directory.
+ If found, open it for use when searching for prefixes.
+*/
+static void
+calculate_read_pyenv(PyCalculatePath *calculate)
+{
+ wchar_t tmpbuffer[MAXPATHLEN+1];
+ wchar_t *env_cfg = L"pyvenv.cfg";
+ FILE *env_file;
+
+ wcscpy(tmpbuffer, calculate->argv0_path);
- wcscpy(tmpbuffer, argv0_path);
+ joinpath(tmpbuffer, env_cfg);
+ env_file = _Py_wfopen(tmpbuffer, L"r");
+ if (env_file == NULL) {
+ errno = 0;
+ reduce(tmpbuffer);
+ reduce(tmpbuffer);
joinpath(tmpbuffer, env_cfg);
+
env_file = _Py_wfopen(tmpbuffer, L"r");
if (env_file == NULL) {
errno = 0;
- reduce(tmpbuffer);
- reduce(tmpbuffer);
- joinpath(tmpbuffer, env_cfg);
- env_file = _Py_wfopen(tmpbuffer, L"r");
- if (env_file == NULL) {
- errno = 0;
- }
- }
- if (env_file != NULL) {
- /* Look for a 'home' variable and set argv0_path to it, if found */
- if (find_env_config_value(env_file, L"home", tmpbuffer)) {
- wcscpy(argv0_path, tmpbuffer);
- }
- fclose(env_file);
- env_file = NULL;
}
}
- pfound = search_for_prefix(argv0_path, home, _prefix, lib_python);
- if (!pfound) {
- if (!Py_FrozenFlag)
- fprintf(stderr,
- "Could not find platform independent libraries <prefix>\n");
- wcsncpy(prefix, _prefix, MAXPATHLEN);
- joinpath(prefix, lib_python);
- }
- else
- reduce(prefix);
-
- wcsncpy(zip_path, prefix, MAXPATHLEN);
- zip_path[MAXPATHLEN] = L'\0';
- if (pfound > 0) { /* Use the reduced prefix returned by Py_GetPrefix() */
- reduce(zip_path);
- reduce(zip_path);
- }
- else
- wcsncpy(zip_path, _prefix, MAXPATHLEN);
- joinpath(zip_path, L"lib/python00.zip");
- bufsz = wcslen(zip_path); /* Replace "00" with version */
- zip_path[bufsz - 6] = VERSION[0];
- zip_path[bufsz - 5] = VERSION[2];
-
- efound = search_for_exec_prefix(argv0_path, home,
- _exec_prefix, lib_python);
- if (!efound) {
- if (!Py_FrozenFlag)
- fprintf(stderr,
- "Could not find platform dependent libraries <exec_prefix>\n");
- wcsncpy(exec_prefix, _exec_prefix, MAXPATHLEN);
- joinpath(exec_prefix, L"lib/lib-dynload");
+ if (env_file == NULL) {
+ return;
}
- /* If we found EXEC_PREFIX do *not* reduce it! (Yet.) */
- if ((!pfound || !efound) && !Py_FrozenFlag)
- fprintf(stderr,
- "Consider setting $PYTHONHOME to <prefix>[:<exec_prefix>]\n");
+ /* Look for a 'home' variable and set argv0_path to it, if found */
+ if (find_env_config_value(env_file, L"home", tmpbuffer)) {
+ wcscpy(calculate->argv0_path, tmpbuffer);
+ }
+ fclose(env_file);
+}
- /* Calculate size of return buffer.
- */
- bufsz = 0;
- wchar_t *env_path = NULL;
- if (config) {
- if (config->module_search_path_env) {
- bufsz += wcslen(config->module_search_path_env) + 1;
- }
+static void
+calculate_zip_path(PyCalculatePath *calculate, PyPathConfig *config)
+{
+ wcsncpy(calculate->zip_path, config->prefix, MAXPATHLEN);
+ calculate->zip_path[MAXPATHLEN] = L'\0';
+
+ if (calculate->prefix_found > 0) {
+ /* Use the reduced prefix returned by Py_GetPrefix() */
+ reduce(calculate->zip_path);
+ reduce(calculate->zip_path);
}
else {
- char *env_pathb = Py_GETENV("PYTHONPATH");
- if (env_pathb && env_pathb[0] != '\0') {
- size_t env_path_len;
- env_path = Py_DecodeLocale(env_pathb, &env_path_len);
- /* FIXME: handle decoding and memory error */
- if (env_path != NULL) {
- bufsz += env_path_len + 1;
- }
- }
+ wcsncpy(calculate->zip_path, calculate->prefix, MAXPATHLEN);
}
+ joinpath(calculate->zip_path, L"lib/python00.zip");
+
+ /* Replace "00" with version */
+ size_t bufsz = wcslen(calculate->zip_path);
+ calculate->zip_path[bufsz - 6] = VERSION[0];
+ calculate->zip_path[bufsz - 5] = VERSION[2];
+}
- defpath = _pythonpath;
- prefixsz = wcslen(prefix) + 1;
+
+static wchar_t *
+calculate_module_search_path(PyCalculatePath *calculate, PyPathConfig *config)
+{
+ /* Calculate size of return buffer */
+ size_t bufsz = 0;
+ if (calculate->module_search_path_env != NULL) {
+ bufsz += wcslen(calculate->module_search_path_env) + 1;
+ }
+
+ wchar_t *defpath = calculate->pythonpath;
+ size_t prefixsz = wcslen(config->prefix) + 1;
while (1) {
wchar_t *delim = wcschr(defpath, DELIM);
- if (defpath[0] != SEP)
+ if (defpath[0] != SEP) {
/* Paths are relative to prefix */
bufsz += prefixsz;
+ }
- if (delim)
+ if (delim) {
bufsz += delim - defpath + 1;
+ }
else {
bufsz += wcslen(defpath) + 1;
break;
defpath = delim + 1;
}
- bufsz += wcslen(zip_path) + 1;
- bufsz += wcslen(exec_prefix) + 1;
+ bufsz += wcslen(calculate->zip_path) + 1;
+ bufsz += wcslen(config->exec_prefix) + 1;
- buf = PyMem_RawMalloc(bufsz * sizeof(wchar_t));
+ /* Allocate the buffer */
+ wchar_t *buf = PyMem_RawMalloc(bufsz * sizeof(wchar_t));
if (buf == NULL) {
Py_FatalError(
"Not enough memory for dynamic PYTHONPATH");
}
+ buf[0] = '\0';
/* Run-time value of $PYTHONPATH goes first */
- buf[0] = '\0';
- if (config) {
- if (config->module_search_path_env) {
- wcscpy(buf, config->module_search_path_env);
- wcscat(buf, delimiter);
- }
- }
- else {
- if (env_path) {
- wcscpy(buf, env_path);
- wcscat(buf, delimiter);
- }
+ if (calculate->module_search_path_env) {
+ wcscpy(buf, calculate->module_search_path_env);
+ wcscat(buf, delimiter);
}
- PyMem_RawFree(env_path);
/* Next is the default zip path */
- wcscat(buf, zip_path);
+ wcscat(buf, calculate->zip_path);
wcscat(buf, delimiter);
/* Next goes merge of compile-time $PYTHONPATH with
* dynamically located prefix.
*/
- defpath = _pythonpath;
+ defpath = calculate->pythonpath;
while (1) {
wchar_t *delim = wcschr(defpath, DELIM);
if (defpath[0] != SEP) {
- wcscat(buf, prefix);
- if (prefixsz >= 2 && prefix[prefixsz - 2] != SEP &&
- defpath[0] != (delim ? DELIM : L'\0')) { /* not empty */
+ wcscat(buf, config->prefix);
+ if (prefixsz >= 2 && config->prefix[prefixsz - 2] != SEP &&
+ defpath[0] != (delim ? DELIM : L'\0'))
+ {
+ /* not empty */
wcscat(buf, separator);
}
}
wcscat(buf, delimiter);
/* Finally, on goes the directory for dynamic-load modules */
- wcscat(buf, exec_prefix);
+ wcscat(buf, config->exec_prefix);
- /* And publish the results */
- module_search_path = buf;
+ return buf;
+}
- /* Reduce prefix and exec_prefix to their essence,
- * e.g. /usr/local/lib/python1.5 is reduced to /usr/local.
- * If we're loading relative to the build directory,
- * return the compiled-in defaults instead.
- */
- if (pfound > 0) {
- reduce(prefix);
- reduce(prefix);
- /* The prefix is the root directory, but reduce() chopped
- * off the "/". */
- if (!prefix[0])
- wcscpy(prefix, separator);
+
+#define DECODE_FAILED(NAME, LEN) \
+ ((LEN) == (size_t)-2) \
+ ? _Py_INIT_ERR("failed to decode " #NAME) \
+ : _Py_INIT_NO_MEMORY()
+
+
+static _PyInitError
+calculate_init(PyCalculatePath *calculate,
+ const _PyMainInterpreterConfig *main_config)
+{
+ _PyInitError err;
+
+ err = _Py_GetPythonHomeWithConfig(main_config, &calculate->home);
+ if (_Py_INIT_FAILED(err)) {
+ return err;
+ }
+
+ size_t len;
+ char *path = getenv("PATH");
+ if (path) {
+ calculate->path_env = Py_DecodeLocale(path, &len);
+ if (!calculate->path_env) {
+ return DECODE_FAILED("PATH environment variable", len);
+ }
+ }
+
+ calculate->prog = Py_GetProgramName();
+
+ calculate->pythonpath = Py_DecodeLocale(PYTHONPATH, &len);
+ if (!calculate->pythonpath) {
+ return DECODE_FAILED("PYTHONPATH define", len);
+ }
+ calculate->prefix = Py_DecodeLocale(PREFIX, &len);
+ if (!calculate->prefix) {
+ return DECODE_FAILED("PREFIX define", len);
+ }
+ calculate->exec_prefix = Py_DecodeLocale(EXEC_PREFIX, &len);
+ if (!calculate->prefix) {
+ return DECODE_FAILED("EXEC_PREFIX define", len);
+ }
+ calculate->lib_python = Py_DecodeLocale("lib/python" VERSION, &len);
+ if (!calculate->lib_python) {
+ return DECODE_FAILED("EXEC_PREFIX define", len);
}
- else
- wcsncpy(prefix, _prefix, MAXPATHLEN);
- if (efound > 0) {
- reduce(exec_prefix);
- reduce(exec_prefix);
- reduce(exec_prefix);
- if (!exec_prefix[0])
- wcscpy(exec_prefix, separator);
+ calculate->module_search_path_env = NULL;
+ if (main_config) {
+ if (main_config->module_search_path_env) {
+ calculate->module_search_path_env = main_config->module_search_path_env;
+ }
+
+ }
+ else {
+ char *pythonpath = Py_GETENV("PYTHONPATH");
+ if (pythonpath && pythonpath[0] != '\0') {
+ calculate->module_search_path_buffer = Py_DecodeLocale(pythonpath, &len);
+ if (!calculate->module_search_path_buffer) {
+ return DECODE_FAILED("PYTHONPATH environment variable", len);
+ }
+ calculate->module_search_path_env = calculate->module_search_path_buffer;
+ }
}
- else
- wcsncpy(exec_prefix, _exec_prefix, MAXPATHLEN);
+ return _Py_INIT_OK();
+}
+
- PyMem_RawFree(_pythonpath);
- PyMem_RawFree(_prefix);
- PyMem_RawFree(_exec_prefix);
- PyMem_RawFree(lib_python);
+static void
+calculate_free(PyCalculatePath *calculate)
+{
+ PyMem_RawFree(calculate->pythonpath);
+ PyMem_RawFree(calculate->prefix);
+ PyMem_RawFree(calculate->exec_prefix);
+ PyMem_RawFree(calculate->lib_python);
+ PyMem_RawFree(calculate->path_env);
+ PyMem_RawFree(calculate->module_search_path_buffer);
+}
+
+
+static void
+calculate_path_impl(PyCalculatePath *calculate, PyPathConfig *config)
+{
+ calculate_progpath(calculate, config);
+ calculate_argv0_path(calculate, config);
+ calculate_read_pyenv(calculate);
+ calculate_prefix(calculate, config);
+ calculate_zip_path(calculate, config);
+ calculate_exec_prefix(calculate, config);
+
+ if ((!calculate->prefix_found || !calculate->exec_prefix_found) && !Py_FrozenFlag) {
+ fprintf(stderr,
+ "Consider setting $PYTHONHOME to <prefix>[:<exec_prefix>]\n");
+ }
+
+ config->module_search_path = calculate_module_search_path(calculate, config);
+ calculate_reduce_prefix(calculate, config);
+ calculate_reduce_exec_prefix(calculate, config);
+}
+
+
+static void
+calculate_path(const _PyMainInterpreterConfig *main_config)
+{
+ PyCalculatePath calculate;
+ memset(&calculate, 0, sizeof(calculate));
+
+ _PyInitError err = calculate_init(&calculate, main_config);
+ if (_Py_INIT_FAILED(err)) {
+ calculate_free(&calculate);
+ _Py_FatalInitError(err);
+ }
+
+ PyPathConfig new_path_config;
+ memset(&new_path_config, 0, sizeof(new_path_config));
+
+ calculate_path_impl(&calculate, &new_path_config);
+ path_config = new_path_config;
+
+ calculate_free(&calculate);
}
void
Py_SetPath(const wchar_t *path)
{
- if (module_search_path != NULL) {
- PyMem_RawFree(module_search_path);
- module_search_path = NULL;
+ if (path_config.module_search_path != NULL) {
+ PyMem_RawFree(path_config.module_search_path);
+ path_config.module_search_path = NULL;
}
- if (path != NULL) {
- extern wchar_t *Py_GetProgramName(void);
- wchar_t *prog = Py_GetProgramName();
- wcsncpy(progpath, prog, MAXPATHLEN);
- exec_prefix[0] = prefix[0] = L'\0';
- module_search_path = PyMem_RawMalloc((wcslen(path) + 1) * sizeof(wchar_t));
- if (module_search_path != NULL)
- wcscpy(module_search_path, path);
+
+ if (path == NULL) {
+ return;
+ }
+
+ wchar_t *prog = Py_GetProgramName();
+ wcsncpy(path_config.progpath, prog, MAXPATHLEN);
+ path_config.exec_prefix[0] = path_config.prefix[0] = L'\0';
+ path_config.module_search_path = PyMem_RawMalloc((wcslen(path) + 1) * sizeof(wchar_t));
+ if (path_config.module_search_path != NULL) {
+ wcscpy(path_config.module_search_path, path);
}
}
+
wchar_t *
-_Py_GetPathWithConfig(const _PyMainInterpreterConfig *config)
+_Py_GetPathWithConfig(const _PyMainInterpreterConfig *main_config)
{
- if (!module_search_path) {
- calculate_path(config);
+ if (!path_config.module_search_path) {
+ calculate_path(main_config);
}
- return module_search_path;
+ return path_config.module_search_path;
}
+
wchar_t *
Py_GetPath(void)
{
- if (!module_search_path)
+ if (!path_config.module_search_path) {
calculate_path(NULL);
- return module_search_path;
+ }
+ return path_config.module_search_path;
}
+
wchar_t *
Py_GetPrefix(void)
{
- if (!module_search_path)
+ if (!path_config.module_search_path) {
calculate_path(NULL);
- return prefix;
+ }
+ return path_config.prefix;
}
+
wchar_t *
Py_GetExecPrefix(void)
{
- if (!module_search_path)
+ if (!path_config.module_search_path) {
calculate_path(NULL);
- return exec_prefix;
+ }
+ return path_config.exec_prefix;
}
+
wchar_t *
Py_GetProgramFullPath(void)
{
- if (!module_search_path)
+ if (!path_config.module_search_path) {
calculate_path(NULL);
- return progpath;
+ }
+ return path_config.progpath;
}
-
#ifdef __cplusplus
}
#endif
#define LANDMARK L"lib\\os.py"
#endif
-static wchar_t prefix[MAXPATHLEN+1];
-static wchar_t progpath[MAXPATHLEN+1];
-static wchar_t dllpath[MAXPATHLEN+1];
-static wchar_t *module_search_path = NULL;
+typedef struct {
+ wchar_t prefix[MAXPATHLEN+1];
+ wchar_t progpath[MAXPATHLEN+1];
+ wchar_t dllpath[MAXPATHLEN+1];
+ wchar_t *module_search_path;
+} PyPathConfig;
+
+typedef struct {
+ wchar_t *module_search_path_env; /* PYTHONPATH environment variable */
+ wchar_t *path_env; /* PATH environment variable */
+ wchar_t *home; /* PYTHONHOME environment variable */
+
+ /* Registry key "Software\Python\PythonCore\PythonPath" */
+ wchar_t *machine_path; /* from HKEY_LOCAL_MACHINE */
+ wchar_t *user_path; /* from HKEY_CURRENT_USER */
+
+ wchar_t *prog; /* Program name */
+ wchar_t argv0_path[MAXPATHLEN+1];
+ wchar_t zip_path[MAXPATHLEN+1];
+} PyCalculatePath;
+
+static PyPathConfig path_config = {.module_search_path = NULL};
+
+/* determine if "ch" is a separator character */
static int
-is_sep(wchar_t ch) /* determine if "ch" is a separator character */
+is_sep(wchar_t ch)
{
#ifdef ALTSEP
return ch == SEP || ch == ALTSEP;
#endif
}
+
/* assumes 'dir' null terminated in bounds. Never writes
- beyond existing terminator.
-*/
+ beyond existing terminator. */
static void
reduce(wchar_t *dir)
{
size_t i = wcsnlen_s(dir, MAXPATHLEN+1);
- if (i >= MAXPATHLEN+1)
+ if (i >= MAXPATHLEN+1) {
Py_FatalError("buffer overflow in getpathp.c's reduce()");
+ }
while (i > 0 && !is_sep(dir[i]))
--i;
dir[i] = '\0';
}
+
static int
change_ext(wchar_t *dest, const wchar_t *src, const wchar_t *ext)
{
size_t src_len = wcsnlen_s(src, MAXPATHLEN+1);
size_t i = src_len;
- if (i >= MAXPATHLEN+1)
+ if (i >= MAXPATHLEN+1) {
Py_FatalError("buffer overflow in getpathp.c's reduce()");
+ }
while (i > 0 && src[i] != '.' && !is_sep(src[i]))
--i;
return -1;
}
- if (is_sep(src[i]))
+ if (is_sep(src[i])) {
i = src_len;
+ }
if (wcsncpy_s(dest, MAXPATHLEN+1, src, i) ||
- wcscat_s(dest, MAXPATHLEN+1, ext)) {
+ wcscat_s(dest, MAXPATHLEN+1, ext))
+ {
dest[0] = '\0';
return -1;
}
return 0;
}
+
static int
exists(wchar_t *filename)
{
return GetFileAttributesW(filename) != 0xFFFFFFFF;
}
-/* Assumes 'filename' MAXPATHLEN+1 bytes long -
- may extend 'filename' by one character.
-*/
+
+/* Is module -- check for .pyc too.
+ Assumes 'filename' MAXPATHLEN+1 bytes long -
+ may extend 'filename' by one character. */
static int
-ismodule(wchar_t *filename, int update_filename) /* Is module -- check for .pyc too */
+ismodule(wchar_t *filename, int update_filename)
{
size_t n;
- if (exists(filename))
+ if (exists(filename)) {
return 1;
+ }
/* Check for the compiled version of prefix. */
n = wcsnlen_s(filename, MAXPATHLEN+1);
filename[n] = L'c';
filename[n + 1] = L'\0';
exist = exists(filename);
- if (!update_filename)
+ if (!update_filename) {
filename[n] = L'\0';
+ }
return exist;
}
return 0;
}
+
/* Add a path component, by appending stuff to buffer.
buffer must have at least MAXPATHLEN + 1 bytes allocated, and contain a
NUL-terminated string with no more than MAXPATHLEN characters (not counting
*/
static int _PathCchCombineEx_Initialized = 0;
-typedef HRESULT(__stdcall *PPathCchCombineEx)(PWSTR pszPathOut, size_t cchPathOut, PCWSTR pszPathIn, PCWSTR pszMore, unsigned long dwFlags);
+typedef HRESULT(__stdcall *PPathCchCombineEx) (PWSTR pszPathOut, size_t cchPathOut,
+ PCWSTR pszPathIn, PCWSTR pszMore,
+ unsigned long dwFlags);
static PPathCchCombineEx _PathCchCombineEx;
static void
{
if (_PathCchCombineEx_Initialized == 0) {
HMODULE pathapi = LoadLibraryW(L"api-ms-win-core-path-l1-1-0.dll");
- if (pathapi)
+ if (pathapi) {
_PathCchCombineEx = (PPathCchCombineEx)GetProcAddress(pathapi, "PathCchCombineEx");
- else
+ }
+ else {
_PathCchCombineEx = NULL;
+ }
_PathCchCombineEx_Initialized = 1;
}
if (_PathCchCombineEx) {
- if (FAILED(_PathCchCombineEx(buffer, MAXPATHLEN+1, buffer, stuff, 0)))
+ if (FAILED(_PathCchCombineEx(buffer, MAXPATHLEN+1, buffer, stuff, 0))) {
Py_FatalError("buffer overflow in getpathp.c's join()");
+ }
} else {
- if (!PathCombineW(buffer, buffer, stuff))
+ if (!PathCombineW(buffer, buffer, stuff)) {
Py_FatalError("buffer overflow in getpathp.c's join()");
+ }
}
}
+
/* gotlandmark only called by search_for_prefix, which ensures
'prefix' is null terminated in bounds. join() ensures
- 'landmark' can not overflow prefix if too long.
-*/
+ 'landmark' can not overflow prefix if too long. */
static int
-gotlandmark(const wchar_t *landmark)
+gotlandmark(wchar_t *prefix, const wchar_t *landmark)
{
int ok;
Py_ssize_t n = wcsnlen_s(prefix, MAXPATHLEN);
return ok;
}
+
/* assumes argv0_path is MAXPATHLEN+1 bytes long, already \0 term'd.
assumption provided by only caller, calculate_path() */
static int
-search_for_prefix(wchar_t *argv0_path, const wchar_t *landmark)
+search_for_prefix(wchar_t *prefix, wchar_t *argv0_path, const wchar_t *landmark)
{
/* Search from argv0_path, until landmark is found */
wcscpy_s(prefix, MAXPATHLEN + 1, argv0_path);
do {
- if (gotlandmark(landmark))
+ if (gotlandmark(prefix, landmark)) {
return 1;
+ }
reduce(prefix);
} while (prefix[0]);
return 0;
}
+
#ifdef Py_ENABLE_SHARED
/* a string loaded from the DLL at startup.*/
extern const char *PyWin_DLLVersionString;
-
/* Load a PYTHONPATH value from the registry.
Load from either HKEY_LOCAL_MACHINE or HKEY_CURRENT_USER.
work on Win16, where the buffer sizes werent available
in advance. It could be simplied now Win16/Win32s is dead!
*/
-
static wchar_t *
getpythonregpath(HKEY keyBase, int skipcore)
{
sizeof(WCHAR)*(versionLen-1) +
sizeof(keySuffix);
keyBuf = keyBufPtr = PyMem_RawMalloc(keyBufLen);
- if (keyBuf==NULL) goto done;
+ if (keyBuf==NULL) {
+ goto done;
+ }
memcpy_s(keyBufPtr, keyBufLen, keyPrefix, sizeof(keyPrefix)-sizeof(WCHAR));
keyBufPtr += Py_ARRAY_LENGTH(keyPrefix) - 1;
0, /* reserved */
KEY_READ,
&newKey);
- if (rc!=ERROR_SUCCESS) goto done;
+ if (rc!=ERROR_SUCCESS) {
+ goto done;
+ }
/* Find out how big our core buffer is, and how many subkeys we have */
rc = RegQueryInfoKey(newKey, NULL, NULL, NULL, &numKeys, NULL, NULL,
NULL, NULL, &dataSize, NULL, NULL);
- if (rc!=ERROR_SUCCESS) goto done;
- if (skipcore) dataSize = 0; /* Only count core ones if we want them! */
+ if (rc!=ERROR_SUCCESS) {
+ goto done;
+ }
+ if (skipcore) {
+ dataSize = 0; /* Only count core ones if we want them! */
+ }
/* Allocate a temp array of char buffers, so we only need to loop
reading the registry once
*/
ppPaths = PyMem_RawMalloc( sizeof(WCHAR *) * numKeys );
- if (ppPaths==NULL) goto done;
+ if (ppPaths==NULL) {
+ goto done;
+ }
memset(ppPaths, 0, sizeof(WCHAR *) * numKeys);
/* Loop over all subkeys, allocating a temp sub-buffer. */
for(index=0;index<numKeys;index++) {
/* Get the sub-key name */
DWORD rc = RegEnumKeyExW(newKey, index, keyBuf, &reqdSize,
NULL, NULL, NULL, NULL );
- if (rc!=ERROR_SUCCESS) goto done;
+ if (rc!=ERROR_SUCCESS) {
+ goto done;
+ }
/* Open the sub-key */
rc=RegOpenKeyExW(newKey,
keyBuf, /* subkey */
0, /* reserved */
KEY_READ,
&subKey);
- if (rc!=ERROR_SUCCESS) goto done;
+ if (rc!=ERROR_SUCCESS) {
+ goto done;
+ }
/* Find the value of the buffer size, malloc, then read it */
RegQueryValueExW(subKey, NULL, 0, NULL, NULL, &reqdSize);
if (reqdSize) {
}
/* return null if no path to return */
- if (dataSize == 0) goto done;
+ if (dataSize == 0) {
+ goto done;
+ }
/* original datasize from RegQueryInfo doesn't include the \0 */
dataBuf = PyMem_RawMalloc((dataSize+1) * sizeof(WCHAR));
dataSize -= (DWORD)len;
}
}
- if (skipcore)
+ if (skipcore) {
*szCur = '\0';
+ }
else {
/* If we have no values, we don't need a ';' */
if (numKeys) {
PyMem_RawFree(ppPaths[index]);
PyMem_RawFree(ppPaths);
}
- if (newKey)
+ if (newKey) {
RegCloseKey(newKey);
+ }
PyMem_RawFree(keyBuf);
return retval;
}
#endif /* Py_ENABLE_SHARED */
+
static void
-get_progpath(void)
+get_progpath(PyCalculatePath *calculate, wchar_t *progpath, wchar_t *dllpath)
{
- extern wchar_t *Py_GetProgramName(void);
- wchar_t *path = _wgetenv(L"PATH");
- wchar_t *prog = Py_GetProgramName();
+ wchar_t *path = calculate->path_env;
#ifdef Py_ENABLE_SHARED
extern HANDLE PyWin_DLLhModule;
/* static init of progpath ensures final char remains \0 */
- if (PyWin_DLLhModule)
- if (!GetModuleFileNameW(PyWin_DLLhModule, dllpath, MAXPATHLEN))
+ if (PyWin_DLLhModule) {
+ if (!GetModuleFileNameW(PyWin_DLLhModule, dllpath, MAXPATHLEN)) {
dllpath[0] = 0;
+ }
+ }
#else
dllpath[0] = 0;
#endif
- if (GetModuleFileNameW(NULL, progpath, MAXPATHLEN))
+ if (GetModuleFileNameW(NULL, progpath, MAXPATHLEN)) {
return;
- if (prog == NULL || *prog == '\0')
- prog = L"python";
+ }
/* If there is no slash in the argv0 path, then we have to
* assume python is on the user's $PATH, since there's no
* $PATH isn't exported, you lose.
*/
#ifdef ALTSEP
- if (wcschr(prog, SEP) || wcschr(prog, ALTSEP))
+ if (wcschr(calculate->prog, SEP) || wcschr(calculate->prog, ALTSEP))
#else
- if (wcschr(prog, SEP))
+ if (wcschr(calculate->prog, SEP))
#endif
- wcsncpy(progpath, prog, MAXPATHLEN);
+ {
+ wcsncpy(progpath, calculate->prog, MAXPATHLEN);
+ }
else if (path) {
while (1) {
wchar_t *delim = wcschr(path, DELIM);
wcsncpy(progpath, path, len);
*(progpath + len) = '\0';
}
- else
+ else {
wcsncpy(progpath, path, MAXPATHLEN);
+ }
/* join() is safe for MAXPATHLEN+1 size buffer */
- join(progpath, prog);
- if (exists(progpath))
+ join(progpath, calculate->prog);
+ if (exists(progpath)) {
break;
+ }
if (!delim) {
progpath[0] = '\0';
path = delim + 1;
}
}
- else
+ else {
progpath[0] = '\0';
+ }
}
+
static int
find_env_config_value(FILE * env_file, const wchar_t * key, wchar_t * value)
{
PyObject * decoded;
size_t n;
- if (p == NULL)
+ if (p == NULL) {
break;
+ }
n = strlen(p);
if (p[n - 1] != '\n') {
/* line has overflowed - bail */
break;
}
- if (p[0] == '#') /* Comment - skip */
+ if (p[0] == '#') {
+ /* Comment - skip */
continue;
+ }
decoded = PyUnicode_DecodeUTF8(buffer, n, "surrogateescape");
if (decoded != NULL) {
Py_ssize_t k;
return result;
}
-static int
+
+static wchar_t*
read_pth_file(const wchar_t *path, wchar_t *prefix, int *isolated, int *nosite)
{
FILE *sp_file = _Py_wfopen(path, L"r");
- if (sp_file == NULL)
- return -1;
+ if (sp_file == NULL) {
+ return NULL;
+ }
wcscpy_s(prefix, MAXPATHLEN+1, path);
reduce(prefix);
while (!feof(sp_file)) {
char line[MAXPATHLEN + 1];
char *p = fgets(line, MAXPATHLEN + 1, sp_file);
- if (!p)
+ if (!p) {
break;
- if (*p == '\0' || *p == '\r' || *p == '\n' || *p == '#')
+ }
+ if (*p == '\0' || *p == '\r' || *p == '\n' || *p == '#') {
continue;
+ }
while (*++p) {
if (*p == '\r' || *p == '\n') {
*p = '\0';
PyMem_RawFree(wline);
}
- module_search_path = buf;
-
fclose(sp_file);
- return 0;
+ return buf;
error:
PyMem_RawFree(buf);
fclose(sp_file);
- return -1;
+ return NULL;
}
-static void
-calculate_path(const _PyMainInterpreterConfig *config)
+static _PyInitError
+calculate_init(PyCalculatePath *calculate,
+ const _PyMainInterpreterConfig *main_config)
{
- wchar_t argv0_path[MAXPATHLEN+1];
- wchar_t *buf;
- size_t bufsz;
- wchar_t *pythonhome = _Py_GetPythonHomeWithConfig(config);
- wchar_t *envpath = NULL;
-
- int skiphome, skipdefault;
- wchar_t *machinepath = NULL;
- wchar_t *userpath = NULL;
- wchar_t zip_path[MAXPATHLEN+1];
+ _PyInitError err;
- if (config) {
- envpath = config->module_search_path_env;
+ err = _Py_GetPythonHomeWithConfig(main_config, &calculate->home);
+ if (_Py_INIT_FAILED(err)) {
+ return err;
+ }
+
+ if (main_config) {
+ calculate->module_search_path_env = main_config->module_search_path_env;
}
else if (!Py_IgnoreEnvironmentFlag) {
- envpath = _wgetenv(L"PYTHONPATH");
- if (envpath && *envpath == '\0')
- envpath = NULL;
+ wchar_t *path = _wgetenv(L"PYTHONPATH");
+ if (path && *path != '\0') {
+ calculate->module_search_path_env = path;
+ }
}
- get_progpath();
- /* progpath guaranteed \0 terminated in MAXPATH+1 bytes. */
- wcscpy_s(argv0_path, MAXPATHLEN+1, progpath);
- reduce(argv0_path);
+ calculate->path_env = _wgetenv(L"PATH");
- /* Search for a sys.path file */
- {
- wchar_t spbuffer[MAXPATHLEN+1];
+ wchar_t *prog = Py_GetProgramName();
+ if (prog == NULL || *prog == '\0') {
+ prog = L"python";
+ }
+ calculate->prog = prog;
- if ((dllpath[0] && !change_ext(spbuffer, dllpath, L"._pth") && exists(spbuffer)) ||
- (progpath[0] && !change_ext(spbuffer, progpath, L"._pth") && exists(spbuffer))) {
+ return _Py_INIT_OK();
+}
- if (!read_pth_file(spbuffer, prefix, &Py_IsolatedFlag, &Py_NoSiteFlag)) {
- return;
- }
+
+static int
+get_pth_filename(wchar_t *spbuffer, PyPathConfig *config)
+{
+ if (config->dllpath[0]) {
+ if (!change_ext(spbuffer, config->dllpath, L"._pth") && exists(spbuffer)) {
+ return 1;
+ }
+ }
+ if (config->progpath[0]) {
+ if (!change_ext(spbuffer, config->progpath, L"._pth") && exists(spbuffer)) {
+ return 1;
}
}
+ return 0;
+}
- /* Search for an environment configuration file, first in the
- executable's directory and then in the parent directory.
- If found, open it for use when searching for prefixes.
- */
- {
- wchar_t envbuffer[MAXPATHLEN+1];
- wchar_t tmpbuffer[MAXPATHLEN+1];
- const wchar_t *env_cfg = L"pyvenv.cfg";
- FILE * env_file = NULL;
+static int
+calculate_pth_file(PyPathConfig *config)
+{
+ wchar_t spbuffer[MAXPATHLEN+1];
+
+ if (!get_pth_filename(spbuffer, config)) {
+ return 0;
+ }
+
+ config->module_search_path = read_pth_file(spbuffer, config->prefix,
+ &Py_IsolatedFlag,
+ &Py_NoSiteFlag);
+ if (!config->module_search_path) {
+ return 0;
+ }
+ return 1;
+}
+
+
+/* Search for an environment configuration file, first in the
+ executable's directory and then in the parent directory.
+ If found, open it for use when searching for prefixes.
+*/
+static void
+calculate_pyvenv_file(PyCalculatePath *calculate)
+{
+ wchar_t envbuffer[MAXPATHLEN+1];
+ const wchar_t *env_cfg = L"pyvenv.cfg";
+
+ wcscpy_s(envbuffer, MAXPATHLEN+1, calculate->argv0_path);
+ join(envbuffer, env_cfg);
- wcscpy_s(envbuffer, MAXPATHLEN+1, argv0_path);
+ FILE *env_file = _Py_wfopen(envbuffer, L"r");
+ if (env_file == NULL) {
+ errno = 0;
+ reduce(envbuffer);
+ reduce(envbuffer);
join(envbuffer, env_cfg);
env_file = _Py_wfopen(envbuffer, L"r");
if (env_file == NULL) {
errno = 0;
- reduce(envbuffer);
- reduce(envbuffer);
- join(envbuffer, env_cfg);
- env_file = _Py_wfopen(envbuffer, L"r");
- if (env_file == NULL) {
- errno = 0;
- }
- }
- if (env_file != NULL) {
- /* Look for a 'home' variable and set argv0_path to it, if found */
- if (find_env_config_value(env_file, L"home", tmpbuffer)) {
- wcscpy_s(argv0_path, MAXPATHLEN+1, tmpbuffer);
- }
- fclose(env_file);
- env_file = NULL;
}
}
- /* Calculate zip archive path from DLL or exe path */
- change_ext(zip_path, dllpath[0] ? dllpath : progpath, L".zip");
+ if (env_file == NULL) {
+ return;
+ }
- if (pythonhome == NULL || *pythonhome == '\0') {
- if (zip_path[0] && exists(zip_path)) {
- wcscpy_s(prefix, MAXPATHLEN+1, zip_path);
- reduce(prefix);
- pythonhome = prefix;
- } else if (search_for_prefix(argv0_path, LANDMARK))
- pythonhome = prefix;
- else
- pythonhome = NULL;
+ /* Look for a 'home' variable and set argv0_path to it, if found */
+ wchar_t tmpbuffer[MAXPATHLEN+1];
+ if (find_env_config_value(env_file, L"home", tmpbuffer)) {
+ wcscpy_s(calculate->argv0_path, MAXPATHLEN+1, tmpbuffer);
}
- else
- wcscpy_s(prefix, MAXPATHLEN+1, pythonhome);
+ fclose(env_file);
+}
- skiphome = pythonhome==NULL ? 0 : 1;
+static void
+calculate_path_impl(PyCalculatePath *calculate, PyPathConfig *config,
+ const _PyMainInterpreterConfig *main_config)
+{
+ get_progpath(calculate, config->progpath, config->dllpath);
+ /* progpath guaranteed \0 terminated in MAXPATH+1 bytes. */
+ wcscpy_s(calculate->argv0_path, MAXPATHLEN+1, config->progpath);
+ reduce(calculate->argv0_path);
+
+ /* Search for a sys.path file */
+ if (calculate_pth_file(config)) {
+ return;
+ }
+
+ calculate_pyvenv_file(calculate);
+
+ /* Calculate zip archive path from DLL or exe path */
+ change_ext(calculate->zip_path,
+ config->dllpath[0] ? config->dllpath : config->progpath,
+ L".zip");
+
+ if (calculate->home == NULL || *calculate->home == '\0') {
+ if (calculate->zip_path[0] && exists(calculate->zip_path)) {
+ wcscpy_s(config->prefix, MAXPATHLEN+1, calculate->zip_path);
+ reduce(config->prefix);
+ calculate->home = config->prefix;
+ } else if (search_for_prefix(config->prefix, calculate->argv0_path, LANDMARK)) {
+ calculate->home = config->prefix;
+ }
+ else {
+ calculate->home = NULL;
+ }
+ }
+ else {
+ wcscpy_s(config->prefix, MAXPATHLEN+1, calculate->home);
+ }
+
+ int skiphome = calculate->home==NULL ? 0 : 1;
#ifdef Py_ENABLE_SHARED
- machinepath = getpythonregpath(HKEY_LOCAL_MACHINE, skiphome);
- userpath = getpythonregpath(HKEY_CURRENT_USER, skiphome);
+ calculate->machine_path = getpythonregpath(HKEY_LOCAL_MACHINE, skiphome);
+ calculate->user_path = getpythonregpath(HKEY_CURRENT_USER, skiphome);
#endif
/* We only use the default relative PYTHONPATH if we haven't
anything better to use! */
- skipdefault = envpath!=NULL || pythonhome!=NULL || \
- machinepath!=NULL || userpath!=NULL;
+ int skipdefault = (calculate->module_search_path_env!=NULL || calculate->home!=NULL || \
+ calculate->machine_path!=NULL || calculate->user_path!=NULL);
/* We need to construct a path from the following parts.
(1) the PYTHONPATH environment variable, if set;
(2) for Win32, the zip archive file path;
- (3) for Win32, the machinepath and userpath, if set;
+ (3) for Win32, the machine_path and user_path, if set;
(4) the PYTHONPATH config macro, with the leading "."
- of each component replaced with pythonhome, if set;
+ of each component replaced with home, if set;
(5) the directory containing the executable (argv0_path).
The length calculation calculates #4 first.
Extra rules:
*/
/* Calculate size of return buffer */
- if (pythonhome != NULL) {
+ size_t bufsz = 0;
+ if (calculate->home != NULL) {
wchar_t *p;
bufsz = 1;
for (p = PYTHONPATH; *p; p++) {
- if (*p == DELIM)
+ if (*p == DELIM) {
bufsz++; /* number of DELIM plus one */
+ }
}
- bufsz *= wcslen(pythonhome);
+ bufsz *= wcslen(calculate->home);
}
- else
- bufsz = 0;
bufsz += wcslen(PYTHONPATH) + 1;
- bufsz += wcslen(argv0_path) + 1;
- if (userpath)
- bufsz += wcslen(userpath) + 1;
- if (machinepath)
- bufsz += wcslen(machinepath) + 1;
- bufsz += wcslen(zip_path) + 1;
- if (envpath != NULL)
- bufsz += wcslen(envpath) + 1;
-
- module_search_path = buf = PyMem_RawMalloc(bufsz*sizeof(wchar_t));
+ bufsz += wcslen(calculate->argv0_path) + 1;
+ if (calculate->user_path) {
+ bufsz += wcslen(calculate->user_path) + 1;
+ }
+ if (calculate->machine_path) {
+ bufsz += wcslen(calculate->machine_path) + 1;
+ }
+ bufsz += wcslen(calculate->zip_path) + 1;
+ if (calculate->module_search_path_env != NULL) {
+ bufsz += wcslen(calculate->module_search_path_env) + 1;
+ }
+
+ wchar_t *buf, *start_buf;
+ buf = PyMem_RawMalloc(bufsz * sizeof(wchar_t));
if (buf == NULL) {
/* We can't exit, so print a warning and limp along */
fprintf(stderr, "Can't malloc dynamic PYTHONPATH.\n");
- if (envpath) {
+ if (calculate->module_search_path_env) {
fprintf(stderr, "Using environment $PYTHONPATH.\n");
- module_search_path = envpath;
+ config->module_search_path = calculate->module_search_path_env;
}
else {
fprintf(stderr, "Using default static path.\n");
- module_search_path = PYTHONPATH;
+ config->module_search_path = PYTHONPATH;
}
- PyMem_RawFree(machinepath);
- PyMem_RawFree(userpath);
return;
}
+ start_buf = buf;
- if (envpath) {
- if (wcscpy_s(buf, bufsz - (buf - module_search_path), envpath))
+ if (calculate->module_search_path_env) {
+ if (wcscpy_s(buf, bufsz - (buf - start_buf), calculate->module_search_path_env)) {
Py_FatalError("buffer overflow in getpathp.c's calculate_path()");
+ }
buf = wcschr(buf, L'\0');
*buf++ = DELIM;
}
- if (zip_path[0]) {
- if (wcscpy_s(buf, bufsz - (buf - module_search_path), zip_path))
+ if (calculate->zip_path[0]) {
+ if (wcscpy_s(buf, bufsz - (buf - start_buf), calculate->zip_path)) {
Py_FatalError("buffer overflow in getpathp.c's calculate_path()");
+ }
buf = wcschr(buf, L'\0');
*buf++ = DELIM;
}
- if (userpath) {
- if (wcscpy_s(buf, bufsz - (buf - module_search_path), userpath))
+ if (calculate->user_path) {
+ if (wcscpy_s(buf, bufsz - (buf - start_buf), calculate->user_path)) {
Py_FatalError("buffer overflow in getpathp.c's calculate_path()");
+ }
buf = wcschr(buf, L'\0');
*buf++ = DELIM;
- PyMem_RawFree(userpath);
}
- if (machinepath) {
- if (wcscpy_s(buf, bufsz - (buf - module_search_path), machinepath))
+ if (calculate->machine_path) {
+ if (wcscpy_s(buf, bufsz - (buf - start_buf), calculate->machine_path)) {
Py_FatalError("buffer overflow in getpathp.c's calculate_path()");
+ }
buf = wcschr(buf, L'\0');
*buf++ = DELIM;
- PyMem_RawFree(machinepath);
}
- if (pythonhome == NULL) {
+ if (calculate->home == NULL) {
if (!skipdefault) {
- if (wcscpy_s(buf, bufsz - (buf - module_search_path), PYTHONPATH))
+ if (wcscpy_s(buf, bufsz - (buf - start_buf), PYTHONPATH)) {
Py_FatalError("buffer overflow in getpathp.c's calculate_path()");
+ }
buf = wcschr(buf, L'\0');
*buf++ = DELIM;
}
size_t n;
for (;;) {
q = wcschr(p, DELIM);
- if (q == NULL)
+ if (q == NULL) {
n = wcslen(p);
- else
+ }
+ else {
n = q-p;
+ }
if (p[0] == '.' && is_sep(p[1])) {
- if (wcscpy_s(buf, bufsz - (buf - module_search_path), pythonhome))
+ if (wcscpy_s(buf, bufsz - (buf - start_buf), calculate->home)) {
Py_FatalError("buffer overflow in getpathp.c's calculate_path()");
+ }
buf = wcschr(buf, L'\0');
p++;
n--;
wcsncpy(buf, p, n);
buf += n;
*buf++ = DELIM;
- if (q == NULL)
+ if (q == NULL) {
break;
+ }
p = q+1;
}
}
- if (argv0_path) {
- wcscpy(buf, argv0_path);
+ if (calculate->argv0_path) {
+ wcscpy(buf, calculate->argv0_path);
buf = wcschr(buf, L'\0');
*buf++ = DELIM;
}
*(buf - 1) = L'\0';
+
/* Now to pull one last hack/trick. If sys.prefix is
empty, then try and find it somewhere on the paths
we calculated. We scan backwards, as our general policy
on the path, and that our 'prefix' directory is
the parent of that.
*/
- if (*prefix==L'\0') {
+ if (config->prefix[0] == L'\0') {
wchar_t lookBuf[MAXPATHLEN+1];
wchar_t *look = buf - 1; /* 'buf' is at the end of the buffer */
while (1) {
start of the path in question - even if this
is one character before the start of the buffer
*/
- while (look >= module_search_path && *look != DELIM)
+ while (look >= start_buf && *look != DELIM)
look--;
nchars = lookEnd-look;
wcsncpy(lookBuf, look+1, nchars);
lookBuf[nchars] = L'\0';
/* Up one level to the parent */
reduce(lookBuf);
- if (search_for_prefix(lookBuf, LANDMARK)) {
+ if (search_for_prefix(config->prefix, lookBuf, LANDMARK)) {
break;
}
/* If we are out of paths to search - give up */
- if (look < module_search_path)
+ if (look < start_buf) {
break;
+ }
look--;
}
}
+
+ config->module_search_path = start_buf;
+}
+
+
+static void
+calculate_free(PyCalculatePath *calculate)
+{
+ PyMem_RawFree(calculate->machine_path);
+ PyMem_RawFree(calculate->user_path);
}
+static void
+calculate_path(const _PyMainInterpreterConfig *main_config)
+{
+ PyCalculatePath calculate;
+ memset(&calculate, 0, sizeof(calculate));
+
+ _PyInitError err = calculate_init(&calculate, main_config);
+ if (_Py_INIT_FAILED(err)) {
+ calculate_free(&calculate);
+ _Py_FatalInitError(err);
+ }
+
+ PyPathConfig new_path_config;
+ memset(&new_path_config, 0, sizeof(new_path_config));
+
+ calculate_path_impl(&calculate, &new_path_config, main_config);
+ path_config = new_path_config;
+
+ calculate_free(&calculate);
+}
+
+
/* External interface */
void
Py_SetPath(const wchar_t *path)
{
- if (module_search_path != NULL) {
- PyMem_RawFree(module_search_path);
- module_search_path = NULL;
- }
- if (path != NULL) {
- extern wchar_t *Py_GetProgramName(void);
- wchar_t *prog = Py_GetProgramName();
- wcsncpy(progpath, prog, MAXPATHLEN);
- prefix[0] = L'\0';
- module_search_path = PyMem_RawMalloc((wcslen(path) + 1) * sizeof(wchar_t));
- if (module_search_path != NULL)
- wcscpy(module_search_path, path);
+ if (path_config.module_search_path != NULL) {
+ PyMem_RawFree(path_config.module_search_path);
+ path_config.module_search_path = NULL;
+ }
+
+ if (path == NULL) {
+ return;
+ }
+
+ wchar_t *prog = Py_GetProgramName();
+ wcsncpy(path_config.progpath, prog, MAXPATHLEN);
+ path_config.prefix[0] = L'\0';
+ path_config.module_search_path = PyMem_RawMalloc((wcslen(path) + 1) * sizeof(wchar_t));
+ if (path_config.module_search_path != NULL) {
+ wcscpy(path_config.module_search_path, path);
}
}
+
wchar_t *
-_Py_GetPathWithConfig(const _PyMainInterpreterConfig *config)
+_Py_GetPathWithConfig(const _PyMainInterpreterConfig *main_config)
{
- if (!module_search_path) {
- calculate_path(config);
+ if (!path_config.module_search_path) {
+ calculate_path(main_config);
}
- return module_search_path;
+ return path_config.module_search_path;
}
+
wchar_t *
Py_GetPath(void)
{
- if (!module_search_path)
+ if (!path_config.module_search_path) {
calculate_path(NULL);
- return module_search_path;
+ }
+ return path_config.module_search_path;
}
+
wchar_t *
Py_GetPrefix(void)
{
- if (!module_search_path)
+ if (!path_config.module_search_path) {
calculate_path(NULL);
- return prefix;
+ }
+ return path_config.prefix;
}
+
wchar_t *
Py_GetExecPrefix(void)
{
return Py_GetPrefix();
}
+
wchar_t *
Py_GetProgramFullPath(void)
{
- if (!module_search_path)
+ if (!path_config.module_search_path) {
calculate_path(NULL);
- return progpath;
+ }
+ return path_config.progpath;
}
+
/* Load python3.dll before loading any extension module that might refer
to it. That way, we can be sure that always the python3.dll corresponding
to this python DLL is loaded, not a python3.dll that might be on the path
{
wchar_t py3path[MAXPATHLEN+1];
wchar_t *s;
- if (python3_checked)
+ if (python3_checked) {
return hPython3 != NULL;
+ }
python3_checked = 1;
/* If there is a python3.dll next to the python3y.dll,
assume this is a build tree; use that DLL */
- wcscpy(py3path, dllpath);
+ wcscpy(py3path, path_config.dllpath);
s = wcsrchr(py3path, L'\\');
- if (!s)
+ if (!s) {
s = py3path;
+ }
wcscpy(s, L"\\python3.dll");
hPython3 = LoadLibraryExW(py3path, NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
- if (hPython3 != NULL)
+ if (hPython3 != NULL) {
return 1;
+ }
/* Check sys.prefix\DLLs\python3.dll */
wcscpy(py3path, Py_GetPrefix());