| Guido van Rossum | 1aa7e3a | 1997-05-19 14:16:21 +0000 | [diff] [blame] | 1 |  | 
 | 2 | /* Return the initial module search path. */ | 
| Guido van Rossum | c499572 | 1998-08-08 20:05:31 +0000 | [diff] [blame] | 3 | /* Used by DOS, OS/2, Windows 3.1, Windows 95/98, Windows NT. */ | 
| Guido van Rossum | 1aa7e3a | 1997-05-19 14:16:21 +0000 | [diff] [blame] | 4 |  | 
| Guido van Rossum | 88716bb | 2000-03-30 19:45:39 +0000 | [diff] [blame] | 5 | /* ---------------------------------------------------------------- | 
 | 6 |    PATH RULES FOR WINDOWS: | 
 | 7 |    This describes how sys.path is formed on Windows.  It describes the  | 
 | 8 |    functionality, not the implementation (ie, the order in which these  | 
 | 9 |    are actually fetched is different) | 
 | 10 |  | 
 | 11 |    * Python always adds an empty entry at the start, which corresponds | 
 | 12 |      to the current directory. | 
 | 13 |  | 
| Georg Brandl | 7eb4b7d | 2005-07-22 21:49:32 +0000 | [diff] [blame] | 14 |    * If the PYTHONPATH env. var. exists, its entries are added next. | 
| Guido van Rossum | 88716bb | 2000-03-30 19:45:39 +0000 | [diff] [blame] | 15 |  | 
 | 16 |    * We look in the registry for "application paths" - that is, sub-keys | 
 | 17 |      under the main PythonPath registry key.  These are added next (the | 
 | 18 |      order of sub-key processing is undefined). | 
 | 19 |      HKEY_CURRENT_USER is searched and added first. | 
 | 20 |      HKEY_LOCAL_MACHINE is searched and added next. | 
 | 21 |      (Note that all known installers only use HKLM, so HKCU is typically | 
 | 22 |      empty) | 
 | 23 |  | 
 | 24 |    * We attempt to locate the "Python Home" - if the PYTHONHOME env var | 
 | 25 |      is set, we believe it.  Otherwise, we use the path of our host .EXE's | 
| Jeremy Hylton | 847a996 | 2000-05-26 21:49:07 +0000 | [diff] [blame] | 26 |      to try and locate our "landmark" (lib\\os.py) and deduce our home. | 
| Guido van Rossum | 88716bb | 2000-03-30 19:45:39 +0000 | [diff] [blame] | 27 |      - If we DO have a Python Home: The relevant sub-directories (Lib,  | 
| Georg Brandl | 6e47a33 | 2008-05-17 19:15:58 +0000 | [diff] [blame] | 28 |        plat-win, etc) are based on the Python Home | 
| Guido van Rossum | 88716bb | 2000-03-30 19:45:39 +0000 | [diff] [blame] | 29 |      - If we DO NOT have a Python Home, the core Python Path is | 
 | 30 |        loaded from the registry.  This is the main PythonPath key,  | 
 | 31 |        and both HKLM and HKCU are combined to form the path) | 
 | 32 |  | 
 | 33 |    * Iff - we can not locate the Python Home, have not had a PYTHONPATH | 
 | 34 |      specified, and can't locate any Registry entries (ie, we have _nothing_ | 
 | 35 |      we can assume is a good path), a default path with relative entries is  | 
 | 36 |      used (eg. .\Lib;.\plat-win, etc) | 
 | 37 |  | 
 | 38 |  | 
 | 39 |   The end result of all this is: | 
 | 40 |   * When running python.exe, or any other .exe in the main Python directory | 
 | 41 |     (either an installed version, or directly from the PCbuild directory), | 
 | 42 |     the core path is deduced, and the core paths in the registry are | 
 | 43 |     ignored.  Other "application paths" in the registry are always read. | 
 | 44 |  | 
 | 45 |   * When Python is hosted in another exe (different directory, embedded via  | 
 | 46 |     COM, etc), the Python Home will not be deduced, so the core path from | 
| Mark Hammond | 19fdbfb | 2001-09-07 14:08:01 +0000 | [diff] [blame] | 47 |     the registry is used.  Other "application paths" in the registry are  | 
| Guido van Rossum | 88716bb | 2000-03-30 19:45:39 +0000 | [diff] [blame] | 48 |     always read. | 
 | 49 |  | 
 | 50 |   * If Python can't find its home and there is no registry (eg, frozen | 
 | 51 |     exe, some very strange installation setup) you get a path with | 
 | 52 |     some default, but relative, paths. | 
 | 53 |  | 
 | 54 |    ---------------------------------------------------------------- */ | 
 | 55 |  | 
 | 56 |  | 
| Guido van Rossum | 1aa7e3a | 1997-05-19 14:16:21 +0000 | [diff] [blame] | 57 | #include "Python.h" | 
 | 58 | #include "osdefs.h" | 
| Martin v. Löwis | 790465f | 2008-04-05 20:41:37 +0000 | [diff] [blame] | 59 | #include <wchar.h> | 
| Guido van Rossum | 1aa7e3a | 1997-05-19 14:16:21 +0000 | [diff] [blame] | 60 |  | 
| Martin v. Löwis | 6238d2b | 2002-06-30 15:26:10 +0000 | [diff] [blame] | 61 | #ifdef MS_WINDOWS | 
| Guido van Rossum | 8f1b651 | 1997-08-13 19:55:43 +0000 | [diff] [blame] | 62 | #include <windows.h> | 
 | 63 | #endif | 
 | 64 |  | 
| Thomas Wouters | 0e3f591 | 2006-08-11 14:57:12 +0000 | [diff] [blame] | 65 | #ifdef HAVE_SYS_TYPES_H | 
| Guido van Rossum | 1aa7e3a | 1997-05-19 14:16:21 +0000 | [diff] [blame] | 66 | #include <sys/types.h> | 
| Thomas Wouters | 0e3f591 | 2006-08-11 14:57:12 +0000 | [diff] [blame] | 67 | #endif /* HAVE_SYS_TYPES_H */ | 
 | 68 |  | 
 | 69 | #ifdef HAVE_SYS_STAT_H | 
| Guido van Rossum | 1aa7e3a | 1997-05-19 14:16:21 +0000 | [diff] [blame] | 70 | #include <sys/stat.h> | 
| Thomas Wouters | 0e3f591 | 2006-08-11 14:57:12 +0000 | [diff] [blame] | 71 | #endif /* HAVE_SYS_STAT_H */ | 
 | 72 |  | 
| Guido van Rossum | 1aa7e3a | 1997-05-19 14:16:21 +0000 | [diff] [blame] | 73 | #include <string.h> | 
 | 74 |  | 
| Guido van Rossum | 1aa7e3a | 1997-05-19 14:16:21 +0000 | [diff] [blame] | 75 | /* Search in some common locations for the associated Python libraries. | 
 | 76 |  * | 
| Guido van Rossum | 1aa7e3a | 1997-05-19 14:16:21 +0000 | [diff] [blame] | 77 |  * Py_GetPath() tries to return a sensible Python module search path. | 
 | 78 |  * | 
| Guido van Rossum | 42a9744 | 1998-02-19 21:00:45 +0000 | [diff] [blame] | 79 |  * The approach is an adaptation for Windows of the strategy used in | 
 | 80 |  * ../Modules/getpath.c; it uses the Windows Registry as one of its | 
 | 81 |  * information sources. | 
| Guido van Rossum | 1aa7e3a | 1997-05-19 14:16:21 +0000 | [diff] [blame] | 82 |  */ | 
 | 83 |  | 
 | 84 | #ifndef LANDMARK | 
| Martin v. Löwis | 790465f | 2008-04-05 20:41:37 +0000 | [diff] [blame] | 85 | #define LANDMARK L"lib\\os.py" | 
| Guido van Rossum | 1aa7e3a | 1997-05-19 14:16:21 +0000 | [diff] [blame] | 86 | #endif | 
 | 87 |  | 
| Martin v. Löwis | 790465f | 2008-04-05 20:41:37 +0000 | [diff] [blame] | 88 | static wchar_t prefix[MAXPATHLEN+1]; | 
 | 89 | static wchar_t progpath[MAXPATHLEN+1]; | 
 | 90 | static wchar_t dllpath[MAXPATHLEN+1]; | 
 | 91 | static wchar_t *module_search_path = NULL; | 
| Guido van Rossum | 1aa7e3a | 1997-05-19 14:16:21 +0000 | [diff] [blame] | 92 |  | 
| Guido van Rossum | eea1449 | 1997-08-13 21:30:44 +0000 | [diff] [blame] | 93 |  | 
| Guido van Rossum | 1aa7e3a | 1997-05-19 14:16:21 +0000 | [diff] [blame] | 94 | static int | 
| Martin v. Löwis | 790465f | 2008-04-05 20:41:37 +0000 | [diff] [blame] | 95 | is_sep(wchar_t ch)	/* determine if "ch" is a separator character */ | 
| Guido van Rossum | 1aa7e3a | 1997-05-19 14:16:21 +0000 | [diff] [blame] | 96 | { | 
 | 97 | #ifdef ALTSEP | 
 | 98 | 	return ch == SEP || ch == ALTSEP; | 
 | 99 | #else | 
 | 100 | 	return ch == SEP; | 
 | 101 | #endif | 
 | 102 | } | 
 | 103 |  | 
| Mark Hammond | 8bf9e3b | 2000-10-07 11:10:50 +0000 | [diff] [blame] | 104 | /* assumes 'dir' null terminated in bounds.  Never writes | 
 | 105 |    beyond existing terminator. | 
 | 106 | */ | 
| Guido van Rossum | 1aa7e3a | 1997-05-19 14:16:21 +0000 | [diff] [blame] | 107 | static void | 
| Martin v. Löwis | 790465f | 2008-04-05 20:41:37 +0000 | [diff] [blame] | 108 | reduce(wchar_t *dir) | 
| Guido van Rossum | 1aa7e3a | 1997-05-19 14:16:21 +0000 | [diff] [blame] | 109 | { | 
| Martin v. Löwis | 790465f | 2008-04-05 20:41:37 +0000 | [diff] [blame] | 110 | 	size_t i = wcslen(dir); | 
| Guido van Rossum | 1aa7e3a | 1997-05-19 14:16:21 +0000 | [diff] [blame] | 111 | 	while (i > 0 && !is_sep(dir[i])) | 
 | 112 | 		--i; | 
 | 113 | 	dir[i] = '\0'; | 
 | 114 | } | 
 | 115 | 	 | 
 | 116 |  | 
 | 117 | static int | 
| Martin v. Löwis | 790465f | 2008-04-05 20:41:37 +0000 | [diff] [blame] | 118 | exists(wchar_t *filename) | 
| Guido van Rossum | 1aa7e3a | 1997-05-19 14:16:21 +0000 | [diff] [blame] | 119 | { | 
| Amaury Forgeot d'Arc | 3d17a5c | 2008-06-13 01:09:34 +0000 | [diff] [blame] | 120 | 	return GetFileAttributesW(filename) != 0xFFFFFFFF; | 
| Guido van Rossum | 1aa7e3a | 1997-05-19 14:16:21 +0000 | [diff] [blame] | 121 | } | 
 | 122 |  | 
| Mark Hammond | 8bf9e3b | 2000-10-07 11:10:50 +0000 | [diff] [blame] | 123 | /* Assumes 'filename' MAXPATHLEN+1 bytes long -  | 
 | 124 |    may extend 'filename' by one character. | 
 | 125 | */ | 
| Guido van Rossum | 43ff114 | 1998-08-08 23:40:40 +0000 | [diff] [blame] | 126 | static int | 
| Martin v. Löwis | 790465f | 2008-04-05 20:41:37 +0000 | [diff] [blame] | 127 | ismodule(wchar_t *filename)	/* Is module -- check for .pyc/.pyo too */ | 
| Guido van Rossum | 43ff114 | 1998-08-08 23:40:40 +0000 | [diff] [blame] | 128 | { | 
 | 129 | 	if (exists(filename)) | 
 | 130 | 		return 1; | 
 | 131 |  | 
 | 132 | 	/* Check for the compiled version of prefix. */ | 
| Martin v. Löwis | 790465f | 2008-04-05 20:41:37 +0000 | [diff] [blame] | 133 | 	if (wcslen(filename) < MAXPATHLEN) { | 
 | 134 | 		wcscat(filename, Py_OptimizeFlag ? L"o" : L"c"); | 
| Guido van Rossum | 43ff114 | 1998-08-08 23:40:40 +0000 | [diff] [blame] | 135 | 		if (exists(filename)) | 
 | 136 | 			return 1; | 
 | 137 | 	} | 
 | 138 | 	return 0; | 
 | 139 | } | 
 | 140 |  | 
| Tim Peters | 8484fbf | 2004-08-07 19:12:27 +0000 | [diff] [blame] | 141 | /* Add a path component, by appending stuff to buffer. | 
 | 142 |    buffer must have at least MAXPATHLEN + 1 bytes allocated, and contain a | 
 | 143 |    NUL-terminated string with no more than MAXPATHLEN characters (not counting | 
 | 144 |    the trailing NUL).  It's a fatal error if it contains a string longer than | 
 | 145 |    that (callers must be careful!).  If these requirements are met, it's | 
 | 146 |    guaranteed that buffer will still be a NUL-terminated string with no more | 
 | 147 |    than MAXPATHLEN characters at exit.  If stuff is too long, only as much of | 
 | 148 |    stuff as fits will be appended. | 
 | 149 | */ | 
| Guido van Rossum | 1aa7e3a | 1997-05-19 14:16:21 +0000 | [diff] [blame] | 150 | static void | 
| Martin v. Löwis | 790465f | 2008-04-05 20:41:37 +0000 | [diff] [blame] | 151 | join(wchar_t *buffer, wchar_t *stuff) | 
| Guido van Rossum | 1aa7e3a | 1997-05-19 14:16:21 +0000 | [diff] [blame] | 152 | { | 
| Guido van Rossum | 1c44e28 | 2000-06-28 22:20:06 +0000 | [diff] [blame] | 153 | 	size_t n, k; | 
| Guido van Rossum | 1aa7e3a | 1997-05-19 14:16:21 +0000 | [diff] [blame] | 154 | 	if (is_sep(stuff[0])) | 
 | 155 | 		n = 0; | 
 | 156 | 	else { | 
| Martin v. Löwis | 790465f | 2008-04-05 20:41:37 +0000 | [diff] [blame] | 157 | 		n = wcslen(buffer); | 
| Guido van Rossum | 1aa7e3a | 1997-05-19 14:16:21 +0000 | [diff] [blame] | 158 | 		if (n > 0 && !is_sep(buffer[n-1]) && n < MAXPATHLEN) | 
 | 159 | 			buffer[n++] = SEP; | 
 | 160 | 	} | 
| Tim Peters | 8484fbf | 2004-08-07 19:12:27 +0000 | [diff] [blame] | 161 | 	if (n > MAXPATHLEN) | 
 | 162 | 		Py_FatalError("buffer overflow in getpathp.c's joinpath()"); | 
| Martin v. Löwis | 790465f | 2008-04-05 20:41:37 +0000 | [diff] [blame] | 163 | 	k = wcslen(stuff); | 
| Guido van Rossum | 1aa7e3a | 1997-05-19 14:16:21 +0000 | [diff] [blame] | 164 | 	if (n + k > MAXPATHLEN) | 
 | 165 | 		k = MAXPATHLEN - n; | 
| Martin v. Löwis | 790465f | 2008-04-05 20:41:37 +0000 | [diff] [blame] | 166 | 	wcsncpy(buffer+n, stuff, k); | 
| Guido van Rossum | 1aa7e3a | 1997-05-19 14:16:21 +0000 | [diff] [blame] | 167 | 	buffer[n+k] = '\0'; | 
 | 168 | } | 
 | 169 |  | 
| Mark Hammond | 8bf9e3b | 2000-10-07 11:10:50 +0000 | [diff] [blame] | 170 | /* gotlandmark only called by search_for_prefix, which ensures | 
 | 171 |    'prefix' is null terminated in bounds.  join() ensures | 
 | 172 |    'landmark' can not overflow prefix if too long. | 
 | 173 | */ | 
| Guido van Rossum | 1aa7e3a | 1997-05-19 14:16:21 +0000 | [diff] [blame] | 174 | static int | 
| Martin v. Löwis | 790465f | 2008-04-05 20:41:37 +0000 | [diff] [blame] | 175 | gotlandmark(wchar_t *landmark) | 
| Guido van Rossum | e02e48b | 2000-03-29 01:49:47 +0000 | [diff] [blame] | 176 | { | 
| Martin v. Löwis | 18e1655 | 2006-02-15 17:27:45 +0000 | [diff] [blame] | 177 | 	int ok; | 
 | 178 | 	Py_ssize_t n; | 
| Guido van Rossum | e02e48b | 2000-03-29 01:49:47 +0000 | [diff] [blame] | 179 |  | 
| Martin v. Löwis | 790465f | 2008-04-05 20:41:37 +0000 | [diff] [blame] | 180 | 	n = wcslen(prefix); | 
| Guido van Rossum | e02e48b | 2000-03-29 01:49:47 +0000 | [diff] [blame] | 181 | 	join(prefix, landmark); | 
 | 182 | 	ok = ismodule(prefix); | 
 | 183 | 	prefix[n] = '\0'; | 
 | 184 | 	return ok; | 
 | 185 | } | 
 | 186 |  | 
| Mark Hammond | 8bf9e3b | 2000-10-07 11:10:50 +0000 | [diff] [blame] | 187 | /* assumes argv0_path is MAXPATHLEN+1 bytes long, already \0 term'd.  | 
 | 188 |    assumption provided by only caller, calculate_path() */ | 
| Guido van Rossum | e02e48b | 2000-03-29 01:49:47 +0000 | [diff] [blame] | 189 | static int | 
| Martin v. Löwis | 790465f | 2008-04-05 20:41:37 +0000 | [diff] [blame] | 190 | search_for_prefix(wchar_t *argv0_path, wchar_t *landmark) | 
| Guido van Rossum | 1aa7e3a | 1997-05-19 14:16:21 +0000 | [diff] [blame] | 191 | { | 
| Guido van Rossum | e02e48b | 2000-03-29 01:49:47 +0000 | [diff] [blame] | 192 | 	/* Search from argv0_path, until landmark is found */ | 
| Martin v. Löwis | 790465f | 2008-04-05 20:41:37 +0000 | [diff] [blame] | 193 | 	wcscpy(prefix, argv0_path); | 
| Guido van Rossum | 1aa7e3a | 1997-05-19 14:16:21 +0000 | [diff] [blame] | 194 | 	do { | 
| Guido van Rossum | e02e48b | 2000-03-29 01:49:47 +0000 | [diff] [blame] | 195 | 		if (gotlandmark(landmark)) | 
| Guido van Rossum | 1aa7e3a | 1997-05-19 14:16:21 +0000 | [diff] [blame] | 196 | 			return 1; | 
| Guido van Rossum | 1aa7e3a | 1997-05-19 14:16:21 +0000 | [diff] [blame] | 197 | 		reduce(prefix); | 
 | 198 | 	} while (prefix[0]); | 
 | 199 | 	return 0; | 
 | 200 | } | 
 | 201 |  | 
| Martin v. Löwis | 6238d2b | 2002-06-30 15:26:10 +0000 | [diff] [blame] | 202 | #ifdef MS_WINDOWS | 
| Guido van Rossum | 43ff114 | 1998-08-08 23:40:40 +0000 | [diff] [blame] | 203 |  | 
| Guido van Rossum | 88716bb | 2000-03-30 19:45:39 +0000 | [diff] [blame] | 204 | /* a string loaded from the DLL at startup.*/ | 
 | 205 | extern const char *PyWin_DLLVersionString; | 
| Guido van Rossum | 271f977 | 1997-09-29 23:39:31 +0000 | [diff] [blame] | 206 |  | 
| Guido van Rossum | eea1449 | 1997-08-13 21:30:44 +0000 | [diff] [blame] | 207 |  | 
 | 208 | /* Load a PYTHONPATH value from the registry. | 
 | 209 |    Load from either HKEY_LOCAL_MACHINE or HKEY_CURRENT_USER. | 
 | 210 |  | 
| Guido van Rossum | 88716bb | 2000-03-30 19:45:39 +0000 | [diff] [blame] | 211 |    Works in both Unicode and 8bit environments.  Only uses the | 
 | 212 |    Ex family of functions so it also works with Windows CE. | 
 | 213 |  | 
| Guido van Rossum | eea1449 | 1997-08-13 21:30:44 +0000 | [diff] [blame] | 214 |    Returns NULL, or a pointer that should be freed. | 
| Mark Hammond | 5edc627 | 2001-02-23 11:38:38 +0000 | [diff] [blame] | 215 |  | 
 | 216 |    XXX - this code is pretty strange, as it used to also | 
 | 217 |    work on Win16, where the buffer sizes werent available | 
 | 218 |    in advance.  It could be simplied now Win16/Win32s is dead! | 
| Guido van Rossum | eea1449 | 1997-08-13 21:30:44 +0000 | [diff] [blame] | 219 | */ | 
 | 220 |  | 
| Martin v. Löwis | 790465f | 2008-04-05 20:41:37 +0000 | [diff] [blame] | 221 | static wchar_t * | 
| Guido van Rossum | 88716bb | 2000-03-30 19:45:39 +0000 | [diff] [blame] | 222 | getpythonregpath(HKEY keyBase, int skipcore) | 
| Guido van Rossum | eea1449 | 1997-08-13 21:30:44 +0000 | [diff] [blame] | 223 | { | 
 | 224 | 	HKEY newKey = 0; | 
| Guido van Rossum | eea1449 | 1997-08-13 21:30:44 +0000 | [diff] [blame] | 225 | 	DWORD dataSize = 0; | 
| Guido van Rossum | 88716bb | 2000-03-30 19:45:39 +0000 | [diff] [blame] | 226 | 	DWORD numKeys = 0; | 
| Guido van Rossum | eea1449 | 1997-08-13 21:30:44 +0000 | [diff] [blame] | 227 | 	LONG rc; | 
| Martin v. Löwis | 790465f | 2008-04-05 20:41:37 +0000 | [diff] [blame] | 228 | 	wchar_t *retval = NULL; | 
 | 229 | 	WCHAR *dataBuf = NULL; | 
 | 230 | 	static const WCHAR keyPrefix[] = L"Software\\Python\\PythonCore\\"; | 
 | 231 | 	static const WCHAR keySuffix[] = L"\\PythonPath"; | 
| Guido van Rossum | 1c44e28 | 2000-06-28 22:20:06 +0000 | [diff] [blame] | 232 | 	size_t versionLen; | 
| Guido van Rossum | 88716bb | 2000-03-30 19:45:39 +0000 | [diff] [blame] | 233 | 	DWORD index; | 
| Martin v. Löwis | 790465f | 2008-04-05 20:41:37 +0000 | [diff] [blame] | 234 | 	WCHAR *keyBuf = NULL; | 
 | 235 | 	WCHAR *keyBufPtr; | 
 | 236 | 	WCHAR **ppPaths = NULL; | 
 | 237 | 	 | 
| Guido van Rossum | 88716bb | 2000-03-30 19:45:39 +0000 | [diff] [blame] | 238 | 	/* Tried to use sysget("winver") but here is too early :-( */ | 
| Martin v. Löwis | 790465f | 2008-04-05 20:41:37 +0000 | [diff] [blame] | 239 | 	versionLen = strlen(PyWin_DLLVersionString); | 
| Guido van Rossum | 88716bb | 2000-03-30 19:45:39 +0000 | [diff] [blame] | 240 | 	/* Space for all the chars, plus one \0 */ | 
 | 241 | 	keyBuf = keyBufPtr = malloc(sizeof(keyPrefix) +  | 
| Martin v. Löwis | 790465f | 2008-04-05 20:41:37 +0000 | [diff] [blame] | 242 | 		                    sizeof(WCHAR)*(versionLen-1) +  | 
| Guido van Rossum | 88716bb | 2000-03-30 19:45:39 +0000 | [diff] [blame] | 243 | 				    sizeof(keySuffix)); | 
 | 244 | 	if (keyBuf==NULL) goto done; | 
| Guido van Rossum | 271f977 | 1997-09-29 23:39:31 +0000 | [diff] [blame] | 245 |  | 
| Martin v. Löwis | 790465f | 2008-04-05 20:41:37 +0000 | [diff] [blame] | 246 | 	memcpy(keyBufPtr, keyPrefix, sizeof(keyPrefix)-sizeof(WCHAR)); | 
 | 247 | 	keyBufPtr += sizeof(keyPrefix)/sizeof(WCHAR) - 1; | 
 | 248 | 	mbstowcs(keyBufPtr, PyWin_DLLVersionString, versionLen); | 
| Guido van Rossum | 88716bb | 2000-03-30 19:45:39 +0000 | [diff] [blame] | 249 | 	keyBufPtr += versionLen; | 
 | 250 | 	/* NULL comes with this one! */ | 
 | 251 | 	memcpy(keyBufPtr, keySuffix, sizeof(keySuffix)); | 
 | 252 | 	/* Open the root Python key */ | 
| Martin v. Löwis | 790465f | 2008-04-05 20:41:37 +0000 | [diff] [blame] | 253 | 	rc=RegOpenKeyExW(keyBase, | 
| Guido van Rossum | 88716bb | 2000-03-30 19:45:39 +0000 | [diff] [blame] | 254 | 	                keyBuf, /* subkey */ | 
 | 255 | 	                0, /* reserved */ | 
 | 256 | 	                KEY_READ, | 
 | 257 | 	                &newKey); | 
 | 258 | 	if (rc!=ERROR_SUCCESS) goto done; | 
 | 259 | 	/* Find out how big our core buffer is, and how many subkeys we have */ | 
 | 260 | 	rc = RegQueryInfoKey(newKey, NULL, NULL, NULL, &numKeys, NULL, NULL,  | 
 | 261 | 	                NULL, NULL, &dataSize, NULL, NULL); | 
 | 262 | 	if (rc!=ERROR_SUCCESS) goto done; | 
 | 263 | 	if (skipcore) dataSize = 0; /* Only count core ones if we want them! */ | 
 | 264 | 	/* Allocate a temp array of char buffers, so we only need to loop  | 
 | 265 | 	   reading the registry once | 
 | 266 | 	*/ | 
| Martin v. Löwis | 790465f | 2008-04-05 20:41:37 +0000 | [diff] [blame] | 267 | 	ppPaths = malloc( sizeof(WCHAR *) * numKeys ); | 
| Guido van Rossum | 88716bb | 2000-03-30 19:45:39 +0000 | [diff] [blame] | 268 | 	if (ppPaths==NULL) goto done; | 
| Martin v. Löwis | 790465f | 2008-04-05 20:41:37 +0000 | [diff] [blame] | 269 | 	memset(ppPaths, 0, sizeof(WCHAR *) * numKeys); | 
| Guido van Rossum | 88716bb | 2000-03-30 19:45:39 +0000 | [diff] [blame] | 270 | 	/* Loop over all subkeys, allocating a temp sub-buffer. */ | 
 | 271 | 	for(index=0;index<numKeys;index++) { | 
| Martin v. Löwis | 790465f | 2008-04-05 20:41:37 +0000 | [diff] [blame] | 272 | 		WCHAR keyBuf[MAX_PATH+1]; | 
| Guido van Rossum | 88716bb | 2000-03-30 19:45:39 +0000 | [diff] [blame] | 273 | 		HKEY subKey = 0; | 
 | 274 | 		DWORD reqdSize = MAX_PATH+1; | 
 | 275 | 		/* Get the sub-key name */ | 
| Martin v. Löwis | 790465f | 2008-04-05 20:41:37 +0000 | [diff] [blame] | 276 | 		DWORD rc = RegEnumKeyExW(newKey, index, keyBuf, &reqdSize, | 
 | 277 | 					 NULL, NULL, NULL, NULL ); | 
| Guido van Rossum | 88716bb | 2000-03-30 19:45:39 +0000 | [diff] [blame] | 278 | 		if (rc!=ERROR_SUCCESS) goto done; | 
 | 279 | 		/* Open the sub-key */ | 
| Martin v. Löwis | 790465f | 2008-04-05 20:41:37 +0000 | [diff] [blame] | 280 | 		rc=RegOpenKeyExW(newKey, | 
| Guido van Rossum | 88716bb | 2000-03-30 19:45:39 +0000 | [diff] [blame] | 281 | 						keyBuf, /* subkey */ | 
 | 282 | 						0, /* reserved */ | 
 | 283 | 						KEY_READ, | 
 | 284 | 						&subKey); | 
 | 285 | 		if (rc!=ERROR_SUCCESS) goto done; | 
 | 286 | 		/* Find the value of the buffer size, malloc, then read it */ | 
| Martin v. Löwis | 790465f | 2008-04-05 20:41:37 +0000 | [diff] [blame] | 287 | 		RegQueryValueExW(subKey, NULL, 0, NULL, NULL, &reqdSize); | 
| Guido van Rossum | 88716bb | 2000-03-30 19:45:39 +0000 | [diff] [blame] | 288 | 		if (reqdSize) { | 
 | 289 | 			ppPaths[index] = malloc(reqdSize); | 
 | 290 | 			if (ppPaths[index]) { | 
| Martin v. Löwis | 790465f | 2008-04-05 20:41:37 +0000 | [diff] [blame] | 291 | 				RegQueryValueExW(subKey, NULL, 0, NULL,  | 
| Mark Hammond | e61aca7 | 2000-09-10 09:14:53 +0000 | [diff] [blame] | 292 | 				                (LPBYTE)ppPaths[index],  | 
 | 293 | 				                &reqdSize); | 
| Guido van Rossum | 88716bb | 2000-03-30 19:45:39 +0000 | [diff] [blame] | 294 | 				dataSize += reqdSize + 1; /* 1 for the ";" */ | 
| Guido van Rossum | eea1449 | 1997-08-13 21:30:44 +0000 | [diff] [blame] | 295 | 			} | 
 | 296 | 		} | 
| Guido van Rossum | 88716bb | 2000-03-30 19:45:39 +0000 | [diff] [blame] | 297 | 		RegCloseKey(subKey); | 
| Guido van Rossum | eea1449 | 1997-08-13 21:30:44 +0000 | [diff] [blame] | 298 | 	} | 
| Thomas Wouters | 0e3f591 | 2006-08-11 14:57:12 +0000 | [diff] [blame] | 299 |  | 
 | 300 | 	/* return null if no path to return */ | 
 | 301 | 	if (dataSize == 0) goto done; | 
 | 302 |  | 
| Mark Hammond | 5edc627 | 2001-02-23 11:38:38 +0000 | [diff] [blame] | 303 | 	/* original datasize from RegQueryInfo doesn't include the \0 */ | 
| Martin v. Löwis | 790465f | 2008-04-05 20:41:37 +0000 | [diff] [blame] | 304 | 	dataBuf = malloc((dataSize+1) * sizeof(WCHAR)); | 
| Guido van Rossum | 88716bb | 2000-03-30 19:45:39 +0000 | [diff] [blame] | 305 | 	if (dataBuf) { | 
| Martin v. Löwis | 790465f | 2008-04-05 20:41:37 +0000 | [diff] [blame] | 306 | 		WCHAR *szCur = dataBuf; | 
| Guido van Rossum | 88716bb | 2000-03-30 19:45:39 +0000 | [diff] [blame] | 307 | 		DWORD reqdSize = dataSize; | 
 | 308 | 		/* Copy our collected strings */ | 
 | 309 | 		for (index=0;index<numKeys;index++) { | 
| Guido van Rossum | 88716bb | 2000-03-30 19:45:39 +0000 | [diff] [blame] | 310 | 			if (index > 0) { | 
| Martin v. Löwis | 790465f | 2008-04-05 20:41:37 +0000 | [diff] [blame] | 311 | 				*(szCur++) = L';'; | 
| Guido van Rossum | 88716bb | 2000-03-30 19:45:39 +0000 | [diff] [blame] | 312 | 				dataSize--; | 
 | 313 | 			} | 
| Mark Hammond | e61aca7 | 2000-09-10 09:14:53 +0000 | [diff] [blame] | 314 | 			if (ppPaths[index]) { | 
| Martin v. Löwis | 790465f | 2008-04-05 20:41:37 +0000 | [diff] [blame] | 315 | 				Py_ssize_t len = wcslen(ppPaths[index]); | 
 | 316 | 				wcsncpy(szCur, ppPaths[index], len); | 
| Mark Hammond | e61aca7 | 2000-09-10 09:14:53 +0000 | [diff] [blame] | 317 | 				szCur += len; | 
| Tim Peters | c7f6cf6 | 2006-02-16 00:35:06 +0000 | [diff] [blame] | 318 | 				assert(dataSize > (DWORD)len); | 
 | 319 | 				dataSize -= (DWORD)len; | 
| Mark Hammond | e61aca7 | 2000-09-10 09:14:53 +0000 | [diff] [blame] | 320 | 			} | 
| Guido van Rossum | 88716bb | 2000-03-30 19:45:39 +0000 | [diff] [blame] | 321 | 		} | 
 | 322 | 		if (skipcore) | 
 | 323 | 			*szCur = '\0'; | 
 | 324 | 		else { | 
| Mark Hammond | 5edc627 | 2001-02-23 11:38:38 +0000 | [diff] [blame] | 325 | 			/* If we have no values, we dont need a ';' */ | 
 | 326 | 			if (numKeys) { | 
| Martin v. Löwis | 790465f | 2008-04-05 20:41:37 +0000 | [diff] [blame] | 327 | 				*(szCur++) = L';'; | 
| Mark Hammond | 5edc627 | 2001-02-23 11:38:38 +0000 | [diff] [blame] | 328 | 				dataSize--; | 
 | 329 | 			} | 
| Mark Hammond | e61aca7 | 2000-09-10 09:14:53 +0000 | [diff] [blame] | 330 | 			/* Now append the core path entries -  | 
 | 331 | 			   this will include the NULL  | 
 | 332 | 			*/ | 
| Martin v. Löwis | 790465f | 2008-04-05 20:41:37 +0000 | [diff] [blame] | 333 | 			rc = RegQueryValueExW(newKey, NULL, 0, NULL,  | 
 | 334 | 					      (LPBYTE)szCur, &dataSize); | 
| Guido van Rossum | 88716bb | 2000-03-30 19:45:39 +0000 | [diff] [blame] | 335 | 		} | 
| Martin v. Löwis | 790465f | 2008-04-05 20:41:37 +0000 | [diff] [blame] | 336 | 		/* And set the result - caller must free */ | 
| Guido van Rossum | 88716bb | 2000-03-30 19:45:39 +0000 | [diff] [blame] | 337 | 		retval = dataBuf; | 
| Guido van Rossum | 88716bb | 2000-03-30 19:45:39 +0000 | [diff] [blame] | 338 | 	} | 
 | 339 | done: | 
 | 340 | 	/* Loop freeing my temp buffers */ | 
 | 341 | 	if (ppPaths) { | 
 | 342 | 		for(index=0;index<numKeys;index++) | 
 | 343 | 			if (ppPaths[index]) free(ppPaths[index]); | 
 | 344 | 		free(ppPaths); | 
 | 345 | 	} | 
| Guido van Rossum | eea1449 | 1997-08-13 21:30:44 +0000 | [diff] [blame] | 346 | 	if (newKey) | 
 | 347 | 		RegCloseKey(newKey); | 
| Guido van Rossum | 88716bb | 2000-03-30 19:45:39 +0000 | [diff] [blame] | 348 | 	if (keyBuf) | 
 | 349 | 		free(keyBuf); | 
| Guido van Rossum | eea1449 | 1997-08-13 21:30:44 +0000 | [diff] [blame] | 350 | 	return retval; | 
 | 351 | } | 
| Martin v. Löwis | 6238d2b | 2002-06-30 15:26:10 +0000 | [diff] [blame] | 352 | #endif /* MS_WINDOWS */ | 
| Guido van Rossum | eea1449 | 1997-08-13 21:30:44 +0000 | [diff] [blame] | 353 |  | 
| Guido van Rossum | 1aa7e3a | 1997-05-19 14:16:21 +0000 | [diff] [blame] | 354 | static void | 
| Thomas Wouters | 7889010 | 2000-07-22 19:25:51 +0000 | [diff] [blame] | 355 | get_progpath(void) | 
| Guido van Rossum | 1aa7e3a | 1997-05-19 14:16:21 +0000 | [diff] [blame] | 356 | { | 
| Martin v. Löwis | 790465f | 2008-04-05 20:41:37 +0000 | [diff] [blame] | 357 | 	extern wchar_t *Py_GetProgramName(void); | 
 | 358 | 	wchar_t *path = _wgetenv(L"PATH"); | 
 | 359 | 	wchar_t *prog = Py_GetProgramName(); | 
| Guido van Rossum | 1aa7e3a | 1997-05-19 14:16:21 +0000 | [diff] [blame] | 360 |  | 
| Martin v. Löwis | 6238d2b | 2002-06-30 15:26:10 +0000 | [diff] [blame] | 361 | #ifdef MS_WINDOWS | 
| Just van Rossum | 52e14d6 | 2002-12-30 22:08:05 +0000 | [diff] [blame] | 362 | 	extern HANDLE PyWin_DLLhModule; | 
| Mark Hammond | 8bf9e3b | 2000-10-07 11:10:50 +0000 | [diff] [blame] | 363 | 	/* static init of progpath ensures final char remains \0 */ | 
| Just van Rossum | 52e14d6 | 2002-12-30 22:08:05 +0000 | [diff] [blame] | 364 | 	if (PyWin_DLLhModule) | 
| Martin v. Löwis | 790465f | 2008-04-05 20:41:37 +0000 | [diff] [blame] | 365 | 		if (!GetModuleFileNameW(PyWin_DLLhModule, dllpath, MAXPATHLEN)) | 
| Just van Rossum | 52e14d6 | 2002-12-30 22:08:05 +0000 | [diff] [blame] | 366 | 			dllpath[0] = 0; | 
| Martin v. Löwis | 790465f | 2008-04-05 20:41:37 +0000 | [diff] [blame] | 367 | 	if (GetModuleFileNameW(NULL, progpath, MAXPATHLEN)) | 
| Guido van Rossum | eea1449 | 1997-08-13 21:30:44 +0000 | [diff] [blame] | 368 | 		return; | 
 | 369 | #endif | 
 | 370 | 	if (prog == NULL || *prog == '\0') | 
| Martin v. Löwis | 790465f | 2008-04-05 20:41:37 +0000 | [diff] [blame] | 371 | 		prog = L"python"; | 
| Guido van Rossum | eea1449 | 1997-08-13 21:30:44 +0000 | [diff] [blame] | 372 |  | 
| Guido van Rossum | 1aa7e3a | 1997-05-19 14:16:21 +0000 | [diff] [blame] | 373 | 	/* If there is no slash in the argv0 path, then we have to | 
 | 374 | 	 * assume python is on the user's $PATH, since there's no | 
 | 375 | 	 * other way to find a directory to start the search from.  If | 
 | 376 | 	 * $PATH isn't exported, you lose. | 
 | 377 | 	 */ | 
 | 378 | #ifdef ALTSEP | 
| Martin v. Löwis | 790465f | 2008-04-05 20:41:37 +0000 | [diff] [blame] | 379 | 	if (wcschr(prog, SEP) || wcschr(prog, ALTSEP)) | 
| Guido van Rossum | 1aa7e3a | 1997-05-19 14:16:21 +0000 | [diff] [blame] | 380 | #else | 
| Martin v. Löwis | 790465f | 2008-04-05 20:41:37 +0000 | [diff] [blame] | 381 | 	if (wcschr(prog, SEP)) | 
| Guido van Rossum | 1aa7e3a | 1997-05-19 14:16:21 +0000 | [diff] [blame] | 382 | #endif | 
| Martin v. Löwis | 790465f | 2008-04-05 20:41:37 +0000 | [diff] [blame] | 383 | 		wcsncpy(progpath, prog, MAXPATHLEN); | 
| Guido van Rossum | 1aa7e3a | 1997-05-19 14:16:21 +0000 | [diff] [blame] | 384 | 	else if (path) { | 
 | 385 | 		while (1) { | 
| Martin v. Löwis | 790465f | 2008-04-05 20:41:37 +0000 | [diff] [blame] | 386 | 			wchar_t *delim = wcschr(path, DELIM); | 
| Guido van Rossum | 1aa7e3a | 1997-05-19 14:16:21 +0000 | [diff] [blame] | 387 |  | 
 | 388 | 			if (delim) { | 
| Guido van Rossum | 1c44e28 | 2000-06-28 22:20:06 +0000 | [diff] [blame] | 389 | 				size_t len = delim - path; | 
| Mark Hammond | 8bf9e3b | 2000-10-07 11:10:50 +0000 | [diff] [blame] | 390 | 				/* ensure we can't overwrite buffer */ | 
 | 391 | 				len = min(MAXPATHLEN,len); | 
| Martin v. Löwis | 790465f | 2008-04-05 20:41:37 +0000 | [diff] [blame] | 392 | 				wcsncpy(progpath, path, len); | 
| Guido van Rossum | 1aa7e3a | 1997-05-19 14:16:21 +0000 | [diff] [blame] | 393 | 				*(progpath + len) = '\0'; | 
 | 394 | 			} | 
 | 395 | 			else | 
| Martin v. Löwis | 790465f | 2008-04-05 20:41:37 +0000 | [diff] [blame] | 396 | 				wcsncpy(progpath, path, MAXPATHLEN); | 
| Guido van Rossum | 1aa7e3a | 1997-05-19 14:16:21 +0000 | [diff] [blame] | 397 |  | 
| Mark Hammond | 8bf9e3b | 2000-10-07 11:10:50 +0000 | [diff] [blame] | 398 | 			/* join() is safe for MAXPATHLEN+1 size buffer */ | 
| Guido van Rossum | 1aa7e3a | 1997-05-19 14:16:21 +0000 | [diff] [blame] | 399 | 			join(progpath, prog); | 
 | 400 | 			if (exists(progpath)) | 
 | 401 | 				break; | 
 | 402 |  | 
 | 403 | 			if (!delim) { | 
 | 404 | 				progpath[0] = '\0'; | 
 | 405 | 				break; | 
 | 406 | 			} | 
 | 407 | 			path = delim + 1; | 
 | 408 | 		} | 
 | 409 | 	} | 
 | 410 | 	else | 
 | 411 | 		progpath[0] = '\0'; | 
| Guido van Rossum | 1aa7e3a | 1997-05-19 14:16:21 +0000 | [diff] [blame] | 412 | } | 
 | 413 |  | 
 | 414 | static void | 
| Thomas Wouters | 7889010 | 2000-07-22 19:25:51 +0000 | [diff] [blame] | 415 | calculate_path(void) | 
| Guido van Rossum | 1aa7e3a | 1997-05-19 14:16:21 +0000 | [diff] [blame] | 416 | { | 
| Martin v. Löwis | 790465f | 2008-04-05 20:41:37 +0000 | [diff] [blame] | 417 | 	wchar_t argv0_path[MAXPATHLEN+1]; | 
 | 418 | 	wchar_t *buf; | 
| Guido van Rossum | 1c44e28 | 2000-06-28 22:20:06 +0000 | [diff] [blame] | 419 | 	size_t bufsz; | 
| Martin v. Löwis | 790465f | 2008-04-05 20:41:37 +0000 | [diff] [blame] | 420 | 	wchar_t *pythonhome = Py_GetPythonHome(); | 
 | 421 | 	char *_envpath = Py_GETENV("PYTHONPATH"); | 
 | 422 | 	wchar_t wenvpath[MAXPATHLEN+1]; | 
 | 423 | 	wchar_t *envpath = NULL; | 
| Guido van Rossum | eea1449 | 1997-08-13 21:30:44 +0000 | [diff] [blame] | 424 |  | 
| Martin v. Löwis | 6238d2b | 2002-06-30 15:26:10 +0000 | [diff] [blame] | 425 | #ifdef MS_WINDOWS | 
| Guido van Rossum | 88716bb | 2000-03-30 19:45:39 +0000 | [diff] [blame] | 426 | 	int skiphome, skipdefault; | 
| Martin v. Löwis | 790465f | 2008-04-05 20:41:37 +0000 | [diff] [blame] | 427 | 	wchar_t *machinepath = NULL; | 
 | 428 | 	wchar_t *userpath = NULL; | 
 | 429 | 	wchar_t zip_path[MAXPATHLEN+1]; | 
| Just van Rossum | 52e14d6 | 2002-12-30 22:08:05 +0000 | [diff] [blame] | 430 | 	size_t len; | 
| Guido van Rossum | eea1449 | 1997-08-13 21:30:44 +0000 | [diff] [blame] | 431 | #endif | 
| Martin v. Löwis | 790465f | 2008-04-05 20:41:37 +0000 | [diff] [blame] | 432 | 	if (_envpath) { | 
 | 433 | 		size_t r = mbstowcs(wenvpath, _envpath, MAXPATHLEN+1); | 
 | 434 | 		envpath = wenvpath; | 
 | 435 | 		if (r == (size_t)-1 || r >= MAXPATHLEN) | 
 | 436 | 			envpath = NULL; | 
 | 437 | 	} | 
| Guido van Rossum | 1aa7e3a | 1997-05-19 14:16:21 +0000 | [diff] [blame] | 438 |  | 
 | 439 | 	get_progpath(); | 
| Mark Hammond | 8bf9e3b | 2000-10-07 11:10:50 +0000 | [diff] [blame] | 440 | 	/* progpath guaranteed \0 terminated in MAXPATH+1 bytes. */ | 
| Martin v. Löwis | 790465f | 2008-04-05 20:41:37 +0000 | [diff] [blame] | 441 | 	wcscpy(argv0_path, progpath); | 
| Guido van Rossum | 1aa7e3a | 1997-05-19 14:16:21 +0000 | [diff] [blame] | 442 | 	reduce(argv0_path); | 
| Guido van Rossum | eea1449 | 1997-08-13 21:30:44 +0000 | [diff] [blame] | 443 | 	if (pythonhome == NULL || *pythonhome == '\0') { | 
 | 444 | 		if (search_for_prefix(argv0_path, LANDMARK)) | 
 | 445 | 			pythonhome = prefix; | 
| Guido van Rossum | 43ff114 | 1998-08-08 23:40:40 +0000 | [diff] [blame] | 446 | 		else | 
 | 447 | 			pythonhome = NULL; | 
| Guido van Rossum | eea1449 | 1997-08-13 21:30:44 +0000 | [diff] [blame] | 448 | 	} | 
 | 449 | 	else | 
| Martin v. Löwis | 790465f | 2008-04-05 20:41:37 +0000 | [diff] [blame] | 450 | 		wcsncpy(prefix, pythonhome, MAXPATHLEN); | 
| Guido van Rossum | 1aa7e3a | 1997-05-19 14:16:21 +0000 | [diff] [blame] | 451 |  | 
| Guido van Rossum | eea1449 | 1997-08-13 21:30:44 +0000 | [diff] [blame] | 452 | 	if (envpath && *envpath == '\0') | 
 | 453 | 		envpath = NULL; | 
 | 454 |  | 
| Guido van Rossum | e02e48b | 2000-03-29 01:49:47 +0000 | [diff] [blame] | 455 |  | 
| Martin v. Löwis | 6238d2b | 2002-06-30 15:26:10 +0000 | [diff] [blame] | 456 | #ifdef MS_WINDOWS | 
| Just van Rossum | 52e14d6 | 2002-12-30 22:08:05 +0000 | [diff] [blame] | 457 | 	/* Calculate zip archive path */ | 
 | 458 | 	if (dllpath[0])		/* use name of python DLL */ | 
| Martin v. Löwis | 790465f | 2008-04-05 20:41:37 +0000 | [diff] [blame] | 459 | 		wcsncpy(zip_path, dllpath, MAXPATHLEN); | 
| Just van Rossum | 52e14d6 | 2002-12-30 22:08:05 +0000 | [diff] [blame] | 460 | 	else			/* use name of executable program */ | 
| Martin v. Löwis | 790465f | 2008-04-05 20:41:37 +0000 | [diff] [blame] | 461 | 		wcsncpy(zip_path, progpath, MAXPATHLEN); | 
| Neal Norwitz | a8aed02 | 2002-12-31 12:35:41 +0000 | [diff] [blame] | 462 | 	zip_path[MAXPATHLEN] = '\0'; | 
| Martin v. Löwis | 790465f | 2008-04-05 20:41:37 +0000 | [diff] [blame] | 463 | 	len = wcslen(zip_path); | 
| Just van Rossum | 52e14d6 | 2002-12-30 22:08:05 +0000 | [diff] [blame] | 464 | 	if (len > 4) { | 
 | 465 | 		zip_path[len-3] = 'z';	/* change ending to "zip" */ | 
 | 466 | 		zip_path[len-2] = 'i'; | 
 | 467 | 		zip_path[len-1] = 'p'; | 
 | 468 | 	} | 
 | 469 | 	else { | 
 | 470 | 		zip_path[0] = 0; | 
 | 471 | 	} | 
 | 472 |   | 
| Guido van Rossum | 88716bb | 2000-03-30 19:45:39 +0000 | [diff] [blame] | 473 | 	skiphome = pythonhome==NULL ? 0 : 1; | 
 | 474 | 	machinepath = getpythonregpath(HKEY_LOCAL_MACHINE, skiphome); | 
 | 475 | 	userpath = getpythonregpath(HKEY_CURRENT_USER, skiphome); | 
 | 476 | 	/* We only use the default relative PYTHONPATH if we havent | 
 | 477 | 	   anything better to use! */ | 
 | 478 | 	skipdefault = envpath!=NULL || pythonhome!=NULL || \ | 
 | 479 | 		      machinepath!=NULL || userpath!=NULL; | 
| Guido van Rossum | 43ff114 | 1998-08-08 23:40:40 +0000 | [diff] [blame] | 480 | #endif | 
 | 481 |  | 
 | 482 | 	/* We need to construct a path from the following parts. | 
| Guido van Rossum | eea1449 | 1997-08-13 21:30:44 +0000 | [diff] [blame] | 483 | 	   (1) the PYTHONPATH environment variable, if set; | 
| Just van Rossum | 52e14d6 | 2002-12-30 22:08:05 +0000 | [diff] [blame] | 484 | 	   (2) for Win32, the zip archive file path; | 
 | 485 | 	   (3) for Win32, the machinepath and userpath, if set; | 
 | 486 | 	   (4) the PYTHONPATH config macro, with the leading "." | 
| Guido van Rossum | eea1449 | 1997-08-13 21:30:44 +0000 | [diff] [blame] | 487 | 	       of each component replaced with pythonhome, if set; | 
| Just van Rossum | 52e14d6 | 2002-12-30 22:08:05 +0000 | [diff] [blame] | 488 | 	   (5) the directory containing the executable (argv0_path). | 
 | 489 | 	   The length calculation calculates #4 first. | 
| Guido van Rossum | 43ff114 | 1998-08-08 23:40:40 +0000 | [diff] [blame] | 490 | 	   Extra rules: | 
| Just van Rossum | 52e14d6 | 2002-12-30 22:08:05 +0000 | [diff] [blame] | 491 | 	   - If PYTHONHOME is set (in any way) item (3) is ignored. | 
 | 492 | 	   - If registry values are used, (4) and (5) are ignored. | 
| Guido van Rossum | eea1449 | 1997-08-13 21:30:44 +0000 | [diff] [blame] | 493 | 	*/ | 
 | 494 |  | 
 | 495 | 	/* Calculate size of return buffer */ | 
 | 496 | 	if (pythonhome != NULL) { | 
| Martin v. Löwis | 790465f | 2008-04-05 20:41:37 +0000 | [diff] [blame] | 497 | 		wchar_t *p; | 
| Guido van Rossum | eea1449 | 1997-08-13 21:30:44 +0000 | [diff] [blame] | 498 | 		bufsz = 1;	 | 
 | 499 | 		for (p = PYTHONPATH; *p; p++) { | 
 | 500 | 			if (*p == DELIM) | 
 | 501 | 				bufsz++; /* number of DELIM plus one */ | 
| Guido van Rossum | 1aa7e3a | 1997-05-19 14:16:21 +0000 | [diff] [blame] | 502 | 		} | 
| Martin v. Löwis | 790465f | 2008-04-05 20:41:37 +0000 | [diff] [blame] | 503 | 		bufsz *= wcslen(pythonhome); | 
| Guido van Rossum | 1aa7e3a | 1997-05-19 14:16:21 +0000 | [diff] [blame] | 504 | 	} | 
| Guido van Rossum | eea1449 | 1997-08-13 21:30:44 +0000 | [diff] [blame] | 505 | 	else | 
 | 506 | 		bufsz = 0; | 
| Martin v. Löwis | 790465f | 2008-04-05 20:41:37 +0000 | [diff] [blame] | 507 | 	bufsz += wcslen(PYTHONPATH) + 1; | 
 | 508 | 	bufsz += wcslen(argv0_path) + 1; | 
| Martin v. Löwis | 6238d2b | 2002-06-30 15:26:10 +0000 | [diff] [blame] | 509 | #ifdef MS_WINDOWS | 
| Guido van Rossum | eea1449 | 1997-08-13 21:30:44 +0000 | [diff] [blame] | 510 | 	if (userpath) | 
| Martin v. Löwis | 790465f | 2008-04-05 20:41:37 +0000 | [diff] [blame] | 511 | 		bufsz += wcslen(userpath) + 1; | 
| Guido van Rossum | 67ab672 | 1998-08-08 19:58:59 +0000 | [diff] [blame] | 512 | 	if (machinepath) | 
| Martin v. Löwis | 790465f | 2008-04-05 20:41:37 +0000 | [diff] [blame] | 513 | 		bufsz += wcslen(machinepath) + 1; | 
 | 514 | 	bufsz += wcslen(zip_path) + 1; | 
| Guido van Rossum | eea1449 | 1997-08-13 21:30:44 +0000 | [diff] [blame] | 515 | #endif | 
| Guido van Rossum | 67ab672 | 1998-08-08 19:58:59 +0000 | [diff] [blame] | 516 | 	if (envpath != NULL) | 
| Martin v. Löwis | 790465f | 2008-04-05 20:41:37 +0000 | [diff] [blame] | 517 | 		bufsz += wcslen(envpath) + 1; | 
| Guido van Rossum | 1aa7e3a | 1997-05-19 14:16:21 +0000 | [diff] [blame] | 518 |  | 
| Martin v. Löwis | 790465f | 2008-04-05 20:41:37 +0000 | [diff] [blame] | 519 | 	module_search_path = buf = malloc(bufsz*sizeof(wchar_t)); | 
| Guido van Rossum | 1aa7e3a | 1997-05-19 14:16:21 +0000 | [diff] [blame] | 520 | 	if (buf == NULL) { | 
 | 521 | 		/* We can't exit, so print a warning and limp along */ | 
| Guido van Rossum | eea1449 | 1997-08-13 21:30:44 +0000 | [diff] [blame] | 522 | 		fprintf(stderr, "Can't malloc dynamic PYTHONPATH.\n"); | 
 | 523 | 		if (envpath) { | 
| Guido van Rossum | e02e48b | 2000-03-29 01:49:47 +0000 | [diff] [blame] | 524 | 			fprintf(stderr, "Using environment $PYTHONPATH.\n"); | 
| Guido van Rossum | eea1449 | 1997-08-13 21:30:44 +0000 | [diff] [blame] | 525 | 			module_search_path = envpath; | 
 | 526 | 		} | 
 | 527 | 		else { | 
| Guido van Rossum | e02e48b | 2000-03-29 01:49:47 +0000 | [diff] [blame] | 528 | 			fprintf(stderr, "Using default static path.\n"); | 
| Guido van Rossum | eea1449 | 1997-08-13 21:30:44 +0000 | [diff] [blame] | 529 | 			module_search_path = PYTHONPATH; | 
 | 530 | 		} | 
| Martin v. Löwis | 6238d2b | 2002-06-30 15:26:10 +0000 | [diff] [blame] | 531 | #ifdef MS_WINDOWS | 
| Guido van Rossum | 42a9744 | 1998-02-19 21:00:45 +0000 | [diff] [blame] | 532 | 		if (machinepath) | 
 | 533 | 			free(machinepath); | 
 | 534 | 		if (userpath) | 
 | 535 | 			free(userpath); | 
| Martin v. Löwis | 6238d2b | 2002-06-30 15:26:10 +0000 | [diff] [blame] | 536 | #endif /* MS_WINDOWS */ | 
| Guido van Rossum | 1aa7e3a | 1997-05-19 14:16:21 +0000 | [diff] [blame] | 537 | 		return; | 
 | 538 | 	} | 
| Guido van Rossum | eea1449 | 1997-08-13 21:30:44 +0000 | [diff] [blame] | 539 |  | 
 | 540 | 	if (envpath) { | 
| Martin v. Löwis | 790465f | 2008-04-05 20:41:37 +0000 | [diff] [blame] | 541 | 		wcscpy(buf, envpath); | 
 | 542 | 		buf = wcschr(buf, L'\0'); | 
| Guido van Rossum | eea1449 | 1997-08-13 21:30:44 +0000 | [diff] [blame] | 543 | 		*buf++ = DELIM; | 
| Guido van Rossum | 1aa7e3a | 1997-05-19 14:16:21 +0000 | [diff] [blame] | 544 | 	} | 
| Martin v. Löwis | 6238d2b | 2002-06-30 15:26:10 +0000 | [diff] [blame] | 545 | #ifdef MS_WINDOWS | 
| Just van Rossum | 52e14d6 | 2002-12-30 22:08:05 +0000 | [diff] [blame] | 546 | 	if (zip_path[0]) { | 
| Martin v. Löwis | 790465f | 2008-04-05 20:41:37 +0000 | [diff] [blame] | 547 | 		wcscpy(buf, zip_path); | 
 | 548 | 		buf = wcschr(buf, L'\0'); | 
| Just van Rossum | 52e14d6 | 2002-12-30 22:08:05 +0000 | [diff] [blame] | 549 | 		*buf++ = DELIM; | 
 | 550 | 	} | 
| Guido van Rossum | 67ab672 | 1998-08-08 19:58:59 +0000 | [diff] [blame] | 551 | 	if (userpath) { | 
| Martin v. Löwis | 790465f | 2008-04-05 20:41:37 +0000 | [diff] [blame] | 552 | 		wcscpy(buf, userpath); | 
 | 553 | 		buf = wcschr(buf, L'\0'); | 
| Guido van Rossum | 67ab672 | 1998-08-08 19:58:59 +0000 | [diff] [blame] | 554 | 		*buf++ = DELIM; | 
 | 555 | 		free(userpath); | 
 | 556 | 	} | 
| Guido van Rossum | eea1449 | 1997-08-13 21:30:44 +0000 | [diff] [blame] | 557 | 	if (machinepath) { | 
| Martin v. Löwis | 790465f | 2008-04-05 20:41:37 +0000 | [diff] [blame] | 558 | 		wcscpy(buf, machinepath); | 
 | 559 | 		buf = wcschr(buf, L'\0'); | 
| Guido van Rossum | eea1449 | 1997-08-13 21:30:44 +0000 | [diff] [blame] | 560 | 		*buf++ = DELIM; | 
| Guido van Rossum | 42a9744 | 1998-02-19 21:00:45 +0000 | [diff] [blame] | 561 | 		free(machinepath); | 
| Guido van Rossum | e02e48b | 2000-03-29 01:49:47 +0000 | [diff] [blame] | 562 | 	} | 
| Guido van Rossum | 88716bb | 2000-03-30 19:45:39 +0000 | [diff] [blame] | 563 | 	if (pythonhome == NULL) { | 
 | 564 | 		if (!skipdefault) { | 
| Martin v. Löwis | 790465f | 2008-04-05 20:41:37 +0000 | [diff] [blame] | 565 | 			wcscpy(buf, PYTHONPATH); | 
 | 566 | 			buf = wcschr(buf, L'\0'); | 
| Guido van Rossum | 88716bb | 2000-03-30 19:45:39 +0000 | [diff] [blame] | 567 | 		} | 
| Guido van Rossum | eea1449 | 1997-08-13 21:30:44 +0000 | [diff] [blame] | 568 | 	} | 
| Guido van Rossum | 88716bb | 2000-03-30 19:45:39 +0000 | [diff] [blame] | 569 | #else | 
| Guido van Rossum | eea1449 | 1997-08-13 21:30:44 +0000 | [diff] [blame] | 570 | 	if (pythonhome == NULL) { | 
| Martin v. Löwis | 790465f | 2008-04-05 20:41:37 +0000 | [diff] [blame] | 571 | 		wcscpy(buf, PYTHONPATH); | 
 | 572 | 		buf = wcschr(buf, L'\0'); | 
| Guido van Rossum | eea1449 | 1997-08-13 21:30:44 +0000 | [diff] [blame] | 573 | 	} | 
| Martin v. Löwis | 6238d2b | 2002-06-30 15:26:10 +0000 | [diff] [blame] | 574 | #endif /* MS_WINDOWS */ | 
| Guido van Rossum | eea1449 | 1997-08-13 21:30:44 +0000 | [diff] [blame] | 575 | 	else { | 
| Martin v. Löwis | 790465f | 2008-04-05 20:41:37 +0000 | [diff] [blame] | 576 | 		wchar_t *p = PYTHONPATH; | 
 | 577 | 		wchar_t *q; | 
| Guido van Rossum | 1c44e28 | 2000-06-28 22:20:06 +0000 | [diff] [blame] | 578 | 		size_t n; | 
| Guido van Rossum | eea1449 | 1997-08-13 21:30:44 +0000 | [diff] [blame] | 579 | 		for (;;) { | 
| Martin v. Löwis | 790465f | 2008-04-05 20:41:37 +0000 | [diff] [blame] | 580 | 			q = wcschr(p, DELIM); | 
| Guido van Rossum | eea1449 | 1997-08-13 21:30:44 +0000 | [diff] [blame] | 581 | 			if (q == NULL) | 
| Martin v. Löwis | 790465f | 2008-04-05 20:41:37 +0000 | [diff] [blame] | 582 | 				n = wcslen(p); | 
| Guido van Rossum | eea1449 | 1997-08-13 21:30:44 +0000 | [diff] [blame] | 583 | 			else | 
 | 584 | 				n = q-p; | 
 | 585 | 			if (p[0] == '.' && is_sep(p[1])) { | 
| Martin v. Löwis | 790465f | 2008-04-05 20:41:37 +0000 | [diff] [blame] | 586 | 				wcscpy(buf, pythonhome); | 
 | 587 | 				buf = wcschr(buf, L'\0'); | 
| Guido van Rossum | eea1449 | 1997-08-13 21:30:44 +0000 | [diff] [blame] | 588 | 				p++; | 
 | 589 | 				n--; | 
 | 590 | 			} | 
| Martin v. Löwis | 790465f | 2008-04-05 20:41:37 +0000 | [diff] [blame] | 591 | 			wcsncpy(buf, p, n); | 
| Guido van Rossum | eea1449 | 1997-08-13 21:30:44 +0000 | [diff] [blame] | 592 | 			buf += n; | 
 | 593 | 			if (q == NULL) | 
 | 594 | 				break; | 
 | 595 | 			*buf++ = DELIM; | 
 | 596 | 			p = q+1; | 
 | 597 | 		} | 
 | 598 | 	} | 
 | 599 | 	if (argv0_path) { | 
 | 600 | 		*buf++ = DELIM; | 
| Martin v. Löwis | 790465f | 2008-04-05 20:41:37 +0000 | [diff] [blame] | 601 | 		wcscpy(buf, argv0_path); | 
 | 602 | 		buf = wcschr(buf, L'\0'); | 
| Guido van Rossum | eea1449 | 1997-08-13 21:30:44 +0000 | [diff] [blame] | 603 | 	} | 
| Martin v. Löwis | 790465f | 2008-04-05 20:41:37 +0000 | [diff] [blame] | 604 | 	*buf = L'\0'; | 
| Mark Hammond | 19fdbfb | 2001-09-07 14:08:01 +0000 | [diff] [blame] | 605 | 	/* Now to pull one last hack/trick.  If sys.prefix is | 
 | 606 | 	   empty, then try and find it somewhere on the paths | 
 | 607 | 	   we calculated.  We scan backwards, as our general policy | 
 | 608 | 	   is that Python core directories are at the *end* of | 
 | 609 | 	   sys.path.  We assume that our "lib" directory is | 
 | 610 | 	   on the path, and that our 'prefix' directory is | 
 | 611 | 	   the parent of that. | 
 | 612 | 	*/ | 
| Martin v. Löwis | 790465f | 2008-04-05 20:41:37 +0000 | [diff] [blame] | 613 | 	if (*prefix==L'\0') { | 
 | 614 | 		wchar_t lookBuf[MAXPATHLEN+1]; | 
 | 615 | 		wchar_t *look = buf - 1; /* 'buf' is at the end of the buffer */ | 
| Mark Hammond | 19fdbfb | 2001-09-07 14:08:01 +0000 | [diff] [blame] | 616 | 		while (1) { | 
| Martin v. Löwis | 18e1655 | 2006-02-15 17:27:45 +0000 | [diff] [blame] | 617 | 			Py_ssize_t nchars; | 
| Martin v. Löwis | 790465f | 2008-04-05 20:41:37 +0000 | [diff] [blame] | 618 | 			wchar_t *lookEnd = look; | 
| Mark Hammond | 19fdbfb | 2001-09-07 14:08:01 +0000 | [diff] [blame] | 619 | 			/* 'look' will end up one character before the | 
 | 620 | 			   start of the path in question - even if this | 
 | 621 | 			   is one character before the start of the buffer | 
 | 622 | 			*/ | 
| Guido van Rossum | d8faa36 | 2007-04-27 19:54:29 +0000 | [diff] [blame] | 623 | 			while (look >= module_search_path && *look != DELIM) | 
| Mark Hammond | 19fdbfb | 2001-09-07 14:08:01 +0000 | [diff] [blame] | 624 | 				look--; | 
 | 625 | 			nchars = lookEnd-look; | 
| Martin v. Löwis | 790465f | 2008-04-05 20:41:37 +0000 | [diff] [blame] | 626 | 			wcsncpy(lookBuf, look+1, nchars); | 
 | 627 | 			lookBuf[nchars] = L'\0'; | 
| Mark Hammond | 19fdbfb | 2001-09-07 14:08:01 +0000 | [diff] [blame] | 628 | 			/* Up one level to the parent */ | 
 | 629 | 			reduce(lookBuf); | 
 | 630 | 			if (search_for_prefix(lookBuf, LANDMARK)) { | 
 | 631 | 				break; | 
 | 632 | 			} | 
 | 633 | 			/* If we are out of paths to search - give up */ | 
 | 634 | 			if (look < module_search_path) | 
 | 635 | 				break; | 
 | 636 | 			look--; | 
 | 637 | 		} | 
 | 638 | 	} | 
| Guido van Rossum | 1aa7e3a | 1997-05-19 14:16:21 +0000 | [diff] [blame] | 639 | } | 
 | 640 |  | 
 | 641 |  | 
 | 642 | /* External interface */ | 
 | 643 |  | 
| Martin v. Löwis | 790465f | 2008-04-05 20:41:37 +0000 | [diff] [blame] | 644 | wchar_t * | 
| Thomas Wouters | 7889010 | 2000-07-22 19:25:51 +0000 | [diff] [blame] | 645 | Py_GetPath(void) | 
| Guido van Rossum | 1aa7e3a | 1997-05-19 14:16:21 +0000 | [diff] [blame] | 646 | { | 
 | 647 | 	if (!module_search_path) | 
 | 648 | 		calculate_path(); | 
 | 649 | 	return module_search_path; | 
 | 650 | } | 
 | 651 |  | 
| Martin v. Löwis | 790465f | 2008-04-05 20:41:37 +0000 | [diff] [blame] | 652 | wchar_t * | 
| Thomas Wouters | 7889010 | 2000-07-22 19:25:51 +0000 | [diff] [blame] | 653 | Py_GetPrefix(void) | 
| Guido van Rossum | 1aa7e3a | 1997-05-19 14:16:21 +0000 | [diff] [blame] | 654 | { | 
| Guido van Rossum | eea1449 | 1997-08-13 21:30:44 +0000 | [diff] [blame] | 655 | 	if (!module_search_path) | 
 | 656 | 		calculate_path(); | 
 | 657 | 	return prefix; | 
| Guido van Rossum | 1aa7e3a | 1997-05-19 14:16:21 +0000 | [diff] [blame] | 658 | } | 
 | 659 |  | 
| Martin v. Löwis | 790465f | 2008-04-05 20:41:37 +0000 | [diff] [blame] | 660 | wchar_t * | 
| Thomas Wouters | 7889010 | 2000-07-22 19:25:51 +0000 | [diff] [blame] | 661 | Py_GetExecPrefix(void) | 
| Guido van Rossum | 1aa7e3a | 1997-05-19 14:16:21 +0000 | [diff] [blame] | 662 | { | 
| Guido van Rossum | eea1449 | 1997-08-13 21:30:44 +0000 | [diff] [blame] | 663 | 	return Py_GetPrefix(); | 
| Guido van Rossum | 1aa7e3a | 1997-05-19 14:16:21 +0000 | [diff] [blame] | 664 | } | 
 | 665 |  | 
| Martin v. Löwis | 790465f | 2008-04-05 20:41:37 +0000 | [diff] [blame] | 666 | wchar_t * | 
| Thomas Wouters | 7889010 | 2000-07-22 19:25:51 +0000 | [diff] [blame] | 667 | Py_GetProgramFullPath(void) | 
| Guido van Rossum | 1aa7e3a | 1997-05-19 14:16:21 +0000 | [diff] [blame] | 668 | { | 
 | 669 | 	if (!module_search_path) | 
 | 670 | 		calculate_path(); | 
 | 671 | 	return progpath; | 
 | 672 | } |