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