mirror of https://github.com/python/cpython.git
175 lines
4.3 KiB
C
175 lines
4.3 KiB
C
|
#include "Python.h"
|
||
|
#include "osdefs.h"
|
||
|
#include <windows.h>
|
||
|
|
||
|
/* PREFIX and EXEC_PREFIX are meaningless on Windows */
|
||
|
|
||
|
#ifndef PREFIX
|
||
|
#define PREFIX ""
|
||
|
#endif
|
||
|
|
||
|
#ifndef EXEC_PREFIX
|
||
|
#define EXEC_PREFIX ""
|
||
|
#endif
|
||
|
|
||
|
/*
|
||
|
This is a special Win32 version of getpath.
|
||
|
|
||
|
* There is no default path. There is nothing even remotely resembling
|
||
|
a standard location. Maybe later "Program Files/Python", but not yet.
|
||
|
|
||
|
* The Registry is used as the primary store for the Python path.
|
||
|
|
||
|
* The environment variable PYTHONPATH _overrides_ the registry. This should
|
||
|
allow a "standard" Python environment, but allow you to manually setup
|
||
|
another (eg, a beta version).
|
||
|
|
||
|
*/
|
||
|
|
||
|
BOOL PyWin_IsWin32s()
|
||
|
{
|
||
|
static BOOL bIsWin32s = -1; // flag as "not yet looked"
|
||
|
|
||
|
if (bIsWin32s==-1) {
|
||
|
OSVERSIONINFO ver;
|
||
|
ver.dwOSVersionInfoSize = sizeof(ver);
|
||
|
GetVersionEx(&ver);
|
||
|
bIsWin32s = ver.dwPlatformId == VER_PLATFORM_WIN32s;
|
||
|
}
|
||
|
return bIsWin32s;
|
||
|
}
|
||
|
|
||
|
/* Load a PYTHONPATH value from the registry
|
||
|
Load from either HKEY_LOCAL_MACHINE or HKEY_CURRENT_USER
|
||
|
|
||
|
Returns NULL, or a pointer that should be free'd.
|
||
|
*/
|
||
|
static char *
|
||
|
getpythonregpath(HKEY keyBase, BOOL bWin32s)
|
||
|
{
|
||
|
HKEY newKey = 0;
|
||
|
DWORD nameSize = 0;
|
||
|
DWORD dataSize = 0;
|
||
|
DWORD numEntries = 0;
|
||
|
LONG rc;
|
||
|
char *retval = NULL;
|
||
|
char *dataBuf;
|
||
|
if ((rc=RegOpenKey(keyBase, "Software\\Python\\PythonCore\\" WIN32_PATCH_LEVEL "\\PythonPath",
|
||
|
&newKey))==ERROR_SUCCESS) {
|
||
|
RegQueryInfoKey(newKey, NULL, NULL, NULL, NULL, NULL, NULL,
|
||
|
&numEntries, &nameSize, &dataSize, NULL, NULL );
|
||
|
}
|
||
|
if (numEntries==0) {
|
||
|
if (newKey)
|
||
|
CloseHandle(newKey);
|
||
|
if ((rc=RegOpenKey(keyBase, "Software\\Python\\PythonPath",
|
||
|
&newKey))==ERROR_SUCCESS) {
|
||
|
RegQueryInfoKey(newKey, NULL, NULL, NULL, NULL, NULL, NULL,
|
||
|
&numEntries, &nameSize, &dataSize, NULL, NULL );
|
||
|
}
|
||
|
}
|
||
|
if (bWin32s && numEntries==0 && dataSize==0) { /* must hardcode for Win32s */
|
||
|
numEntries = 1;
|
||
|
dataSize = 511;
|
||
|
}
|
||
|
if (numEntries) {
|
||
|
dataBuf = malloc(dataSize);
|
||
|
// on NT, datasize is unicode - ie, 2xstrlen,
|
||
|
// even when ascii string returned.
|
||
|
// presumably will be 1xstrlen on 95/win3.1
|
||
|
// Additionally, win32s doesnt work as expected, so
|
||
|
// the specific strlen() is required for 3.1.
|
||
|
rc = RegQueryValue(newKey, "", dataBuf, &dataSize);
|
||
|
if (rc==ERROR_SUCCESS) {
|
||
|
if (strlen(dataBuf)==0)
|
||
|
free(dataBuf);
|
||
|
else
|
||
|
retval = dataBuf; // caller will free
|
||
|
}
|
||
|
else
|
||
|
free(dataBuf);
|
||
|
}
|
||
|
|
||
|
if (newKey)
|
||
|
CloseHandle(newKey);
|
||
|
return retval;
|
||
|
}
|
||
|
/* Return the initial python search path. This is called once from
|
||
|
initsys() to initialize sys.path. The environment variable
|
||
|
PYTHONPATH is fetched and the default path appended. The default
|
||
|
path may be passed to the preprocessor; if not, a system-dependent
|
||
|
default is used. */
|
||
|
|
||
|
char *
|
||
|
Py_GetPath()
|
||
|
{
|
||
|
char *path = getenv("PYTHONPATH");
|
||
|
char *defpath = PYTHONPATH;
|
||
|
static char *buf = NULL;
|
||
|
char *p;
|
||
|
int n;
|
||
|
|
||
|
if (buf != NULL) {
|
||
|
free(buf);
|
||
|
buf = NULL;
|
||
|
}
|
||
|
|
||
|
if (path == NULL) {
|
||
|
char *machinePath, *userPath;
|
||
|
int machineLen, userLen;
|
||
|
/* lookup the registry */
|
||
|
BOOL bWin32s = PyWin_IsWin32s();
|
||
|
|
||
|
if (bWin32s) { /* are we running under Windows 3.1 Win32s */
|
||
|
/* only CLASSES_ROOT is supported */
|
||
|
machinePath = getpythonregpath(HKEY_CLASSES_ROOT, TRUE);
|
||
|
userPath = NULL;
|
||
|
} else {
|
||
|
machinePath = getpythonregpath(HKEY_LOCAL_MACHINE, FALSE);
|
||
|
userPath = getpythonregpath(HKEY_CURRENT_USER, FALSE);
|
||
|
}
|
||
|
if (machinePath==NULL && userPath==NULL) return defpath;
|
||
|
machineLen = machinePath ? strlen(machinePath) : 0;
|
||
|
userLen = userPath ? strlen(userPath) : 0;
|
||
|
n = machineLen + userLen + 1;
|
||
|
// this is a memory leak, as Python never frees it. Only ever called once, so big deal!
|
||
|
buf = malloc(n);
|
||
|
if (buf == NULL)
|
||
|
Py_FatalError("not enough memory to copy module search path");
|
||
|
p = buf;
|
||
|
*p = '\0';
|
||
|
if (machineLen) {
|
||
|
strcpy(p, machinePath);
|
||
|
p += machineLen;
|
||
|
}
|
||
|
if (userLen) {
|
||
|
if (machineLen)
|
||
|
*p++ = DELIM;
|
||
|
strcpy(p, userPath);
|
||
|
}
|
||
|
if (userPath) free(userPath);
|
||
|
if (machinePath) free(machinePath);
|
||
|
} else {
|
||
|
|
||
|
buf = malloc(strlen(path)+1);
|
||
|
if (buf == NULL)
|
||
|
Py_FatalError("not enough memory to copy module search path");
|
||
|
strcpy(buf, path);
|
||
|
}
|
||
|
return buf;
|
||
|
}
|
||
|
|
||
|
/* Similar for Makefile variables $prefix and $exec_prefix */
|
||
|
|
||
|
char *
|
||
|
Py_GetPrefix()
|
||
|
{
|
||
|
return PREFIX;
|
||
|
}
|
||
|
|
||
|
char *
|
||
|
Py_GetExecPrefix()
|
||
|
{
|
||
|
return EXEC_PREFIX;
|
||
|
}
|