blob: d73cd7385e022bf813325ca0cb01cc4824fcaff8 [file] [log] [blame]
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +00001/***********************************************************
2Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam,
3The Netherlands.
4
5 All Rights Reserved
6
7Permission to use, copy, modify, and distribute this software and its
8documentation for any purpose and without fee is hereby granted,
9provided that the above copyright notice appear in all copies and that
10both that copyright notice and this permission notice appear in
11supporting documentation, and that the names of Stichting Mathematisch
12Centrum or CWI or Corporation for National Research Initiatives or
13CNRI not be used in advertising or publicity pertaining to
14distribution of the software without specific, written prior
15permission.
16
17While CWI is the initial source for this software, a modified version
18is made available by the Corporation for National Research Initiatives
19(CNRI) at the Internet address ftp://ftp.python.org.
20
21STICHTING MATHEMATISCH CENTRUM AND CNRI DISCLAIM ALL WARRANTIES WITH
22REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
23MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH
24CENTRUM OR CNRI BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
25DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
26PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
27TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
28PERFORMANCE OF THIS SOFTWARE.
29
30******************************************************************/
31
32/* Return the initial module search path. */
33/* Used by DOS, OS/2, Windows 3.1. Works on NT too. */
34
35#include "Python.h"
36#include "osdefs.h"
37
Guido van Rossum8f1b6511997-08-13 19:55:43 +000038#ifdef MS_WIN32
39#include <windows.h>
Guido van Rossumeea14491997-08-13 21:30:44 +000040extern BOOL PyWin_IsWin32s();
Guido van Rossum8f1b6511997-08-13 19:55:43 +000041#endif
42
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +000043#include <sys/types.h>
44#include <sys/stat.h>
45#include <string.h>
46
47#if HAVE_UNISTD_H
48#include <unistd.h>
49#endif /* HAVE_UNISTD_H */
50
51/* Search in some common locations for the associated Python libraries.
52 *
53 * This version always returns "" for both prefix and exec_prefix.
54 *
55 * Py_GetPath() tries to return a sensible Python module search path.
56 *
57 * First, we look to see if the executable is in a subdirectory of
58 * the Python build directory. We calculate the full path of the
59 * directory containing the executable as progpath. We work backwards
60 * along progpath and look for $dir/Modules/Setup.in, a distinctive
61 * landmark. If found, we use $dir/Lib as $root. The returned
62 * Python path is the compiled #define PYTHONPATH with all the initial
63 * "./lib" replaced by $root.
64 *
65 * Otherwise, if there is a PYTHONPATH environment variable, we return that.
66 *
67 * Otherwise we try to find $progpath/lib/string.py, and if found, then
68 * root is $progpath/lib, and we return Python path as compiled PYTHONPATH
69 * with all "./lib" replaced by $root (as above).
70 *
71 */
72
73#ifndef LANDMARK
Guido van Rossumeea14491997-08-13 21:30:44 +000074#define LANDMARK "lib\\string.py"
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +000075#endif
76
77static char prefix[MAXPATHLEN+1];
78static char progpath[MAXPATHLEN+1];
79static char *module_search_path = NULL;
80
Guido van Rossumeea14491997-08-13 21:30:44 +000081
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +000082static int
83is_sep(ch) /* determine if "ch" is a separator character */
84 char ch;
85{
86#ifdef ALTSEP
87 return ch == SEP || ch == ALTSEP;
88#else
89 return ch == SEP;
90#endif
91}
92
Guido van Rossumeea14491997-08-13 21:30:44 +000093
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +000094static void
95reduce(dir)
96 char *dir;
97{
98 int i = strlen(dir);
99 while (i > 0 && !is_sep(dir[i]))
100 --i;
101 dir[i] = '\0';
102}
103
104
105static int
106exists(filename)
107 char *filename;
108{
109 struct stat buf;
110 return stat(filename, &buf) == 0;
111}
112
113
114static void
115join(buffer, stuff)
116 char *buffer;
117 char *stuff;
118{
119 int n, k;
120 if (is_sep(stuff[0]))
121 n = 0;
122 else {
123 n = strlen(buffer);
124 if (n > 0 && !is_sep(buffer[n-1]) && n < MAXPATHLEN)
125 buffer[n++] = SEP;
126 }
127 k = strlen(stuff);
128 if (n + k > MAXPATHLEN)
129 k = MAXPATHLEN - n;
130 strncpy(buffer+n, stuff, k);
131 buffer[n+k] = '\0';
132}
133
134
135static int
136search_for_prefix(argv0_path, landmark)
137 char *argv0_path;
138 char *landmark;
139{
140 int n;
141
142 /* Search from argv0_path, until root is found */
143 strcpy(prefix, argv0_path);
144 do {
145 n = strlen(prefix);
146 join(prefix, landmark);
Guido van Rossumeea14491997-08-13 21:30:44 +0000147 if (exists(prefix)) {
148 prefix[n] = '\0';
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +0000149 return 1;
Guido van Rossumeea14491997-08-13 21:30:44 +0000150 }
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +0000151 prefix[n] = '\0';
152 reduce(prefix);
153 } while (prefix[0]);
154 return 0;
155}
156
Guido van Rossumeea14491997-08-13 21:30:44 +0000157#ifdef MS_WIN32
Guido van Rossum271f9771997-09-29 23:39:31 +0000158#include "malloc.h" // for alloca - see comments below!
159extern const char *PyWin_DLLVersionString; // a string loaded from the DLL at startup.
160
Guido van Rossumeea14491997-08-13 21:30:44 +0000161
162/* Load a PYTHONPATH value from the registry.
163 Load from either HKEY_LOCAL_MACHINE or HKEY_CURRENT_USER.
164
165 Returns NULL, or a pointer that should be freed.
166*/
167
168static char *
169getpythonregpath(HKEY keyBase, BOOL bWin32s)
170{
171 HKEY newKey = 0;
172 DWORD nameSize = 0;
173 DWORD dataSize = 0;
174 DWORD numEntries = 0;
175 LONG rc;
176 char *retval = NULL;
177 char *dataBuf;
Guido van Rossum271f9771997-09-29 23:39:31 +0000178 const char keyPrefix[] = "Software\\Python\\PythonCore\\";
179 const char keySuffix[] = "\\PythonPath";
180 int versionLen;
181 char *keyBuf;
182
183 // Tried to use sysget("winver") but here is too early :-(
184 versionLen = strlen(PyWin_DLLVersionString);
185 // alloca == no free required, but memory only local to fn.
186 // also no heap fragmentation! Am I being silly?
187 keyBuf = alloca(sizeof(keyPrefix)-1 + versionLen + sizeof(keySuffix)); // chars only, plus 1 NULL.
188 // lots of constants here for the compiler to optimize away :-)
189 memcpy(keyBuf, keyPrefix, sizeof(keyPrefix)-1);
190 memcpy(keyBuf+sizeof(keyPrefix)-1, PyWin_DLLVersionString, versionLen);
191 memcpy(keyBuf+sizeof(keyPrefix)-1+versionLen, keySuffix, sizeof(keySuffix)); // NULL comes with this one!
192
Guido van Rossumeea14491997-08-13 21:30:44 +0000193 rc=RegOpenKey(keyBase,
Guido van Rossum271f9771997-09-29 23:39:31 +0000194 keyBuf,
Guido van Rossumeea14491997-08-13 21:30:44 +0000195 &newKey);
196 if (rc==ERROR_SUCCESS) {
197 RegQueryInfoKey(newKey, NULL, NULL, NULL, NULL, NULL, NULL,
198 &numEntries, &nameSize, &dataSize, NULL, NULL);
199 }
200 if (bWin32s && numEntries==0 && dataSize==0) {
201 /* must hardcode for Win32s */
202 numEntries = 1;
203 dataSize = 511;
204 }
205 if (numEntries) {
206 /* Loop over all subkeys. */
207 /* Win32s doesnt know how many subkeys, so we do
208 it twice */
209 char keyBuf[MAX_PATH+1];
210 int index = 0;
211 int off = 0;
212 for(index=0;;index++) {
213 long reqdSize = 0;
214 DWORD rc = RegEnumKey(newKey,
215 index, keyBuf, MAX_PATH+1);
216 if (rc) break;
217 rc = RegQueryValue(newKey, keyBuf, NULL, &reqdSize);
218 if (rc) break;
219 if (bWin32s && reqdSize==0) reqdSize = 512;
220 dataSize += reqdSize + 1; /* 1 for the ";" */
221 }
222 dataBuf = malloc(dataSize+1);
223 if (dataBuf==NULL)
224 return NULL; /* pretty serious? Raise error? */
225 /* Now loop over, grabbing the paths.
226 Subkeys before main library */
227 for(index=0;;index++) {
228 int adjust;
229 long reqdSize = dataSize;
230 DWORD rc = RegEnumKey(newKey,
231 index, keyBuf,MAX_PATH+1);
232 if (rc) break;
233 rc = RegQueryValue(newKey,
234 keyBuf, dataBuf+off, &reqdSize);
235 if (rc) break;
236 if (reqdSize>1) {
237 /* If Nothing, or only '\0' copied. */
238 adjust = strlen(dataBuf+off);
239 dataSize -= adjust;
240 off += adjust;
241 dataBuf[off++] = ';';
242 dataBuf[off] = '\0';
243 dataSize--;
244 }
245 }
246 /* Additionally, win32s doesnt work as expected, so
247 the specific strlen() is required for 3.1. */
248 rc = RegQueryValue(newKey, "", dataBuf+off, &dataSize);
249 if (rc==ERROR_SUCCESS) {
250 if (strlen(dataBuf)==0)
251 free(dataBuf);
252 else
253 retval = dataBuf; /* caller will free */
254 }
255 else
256 free(dataBuf);
257 }
258
259 if (newKey)
260 RegCloseKey(newKey);
261 return retval;
262}
263#endif /* MS_WIN32 */
264
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +0000265static void
266get_progpath()
267{
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +0000268 extern char *Py_GetProgramName();
269 char *path = getenv("PATH");
270 char *prog = Py_GetProgramName();
271
Guido van Rossumeea14491997-08-13 21:30:44 +0000272#ifdef MS_WIN32
273 if (GetModuleFileName(NULL, progpath, MAXPATHLEN))
274 return;
275#endif
276 if (prog == NULL || *prog == '\0')
277 prog = "python";
278
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +0000279 /* If there is no slash in the argv0 path, then we have to
280 * assume python is on the user's $PATH, since there's no
281 * other way to find a directory to start the search from. If
282 * $PATH isn't exported, you lose.
283 */
284#ifdef ALTSEP
285 if (strchr(prog, SEP) || strchr(prog, ALTSEP))
286#else
287 if (strchr(prog, SEP))
288#endif
289 strcpy(progpath, prog);
290 else if (path) {
291 while (1) {
292 char *delim = strchr(path, DELIM);
293
294 if (delim) {
295 int len = delim - path;
296 strncpy(progpath, path, len);
297 *(progpath + len) = '\0';
298 }
299 else
300 strcpy(progpath, path);
301
302 join(progpath, prog);
303 if (exists(progpath))
304 break;
305
306 if (!delim) {
307 progpath[0] = '\0';
308 break;
309 }
310 path = delim + 1;
311 }
312 }
313 else
314 progpath[0] = '\0';
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +0000315}
316
317static void
318calculate_path()
319{
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +0000320 char argv0_path[MAXPATHLEN+1];
321 char *buf;
322 int bufsz;
Guido van Rossumeea14491997-08-13 21:30:44 +0000323 char *pythonhome = getenv("PYTHONHOME");
324 char *envpath = getenv("PYTHONPATH");
325#ifdef MS_WIN32
326 char *machinepath, *userpath;
327
328 /* Are we running under Windows 3.1(1) Win32s? */
329 if (PyWin_IsWin32s()) {
330 /* Only CLASSES_ROOT is supported */
331 machinepath = getpythonregpath(HKEY_CLASSES_ROOT, TRUE);
332 userpath = NULL;
333 } else {
334 machinepath = getpythonregpath(HKEY_LOCAL_MACHINE, FALSE);
335 userpath = getpythonregpath(HKEY_CURRENT_USER, FALSE);
336 }
337#endif
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +0000338
339 get_progpath();
340 strcpy(argv0_path, progpath);
341 reduce(argv0_path);
Guido van Rossumeea14491997-08-13 21:30:44 +0000342 if (pythonhome == NULL || *pythonhome == '\0') {
343 if (search_for_prefix(argv0_path, LANDMARK))
344 pythonhome = prefix;
345 else
346 pythonhome = NULL;
347 }
348 else
349 strcpy(prefix, pythonhome);
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +0000350
Guido van Rossumeea14491997-08-13 21:30:44 +0000351 if (envpath && *envpath == '\0')
352 envpath = NULL;
353
354 /* We need to construct a path from the following parts:
355 (1) the PYTHONPATH environment variable, if set;
356 (2) for Win32, the machinepath and userpath, if set;
357 (3) the PYTHONPATH config macro, with the leading "."
358 of each component replaced with pythonhome, if set;
359 (4) the directory containing the executable (argv0_path).
360 The length calculation calculates #3 first.
361 */
362
363 /* Calculate size of return buffer */
364 if (pythonhome != NULL) {
365 char *p;
366 bufsz = 1;
367 for (p = PYTHONPATH; *p; p++) {
368 if (*p == DELIM)
369 bufsz++; /* number of DELIM plus one */
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +0000370 }
Guido van Rossumeea14491997-08-13 21:30:44 +0000371 bufsz *= strlen(pythonhome);
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +0000372 }
Guido van Rossumeea14491997-08-13 21:30:44 +0000373 else
374 bufsz = 0;
375 bufsz += strlen(PYTHONPATH);
376 if (envpath != NULL)
377 bufsz += strlen(envpath) + 1;
Guido van Rossum8f1b6511997-08-13 19:55:43 +0000378 bufsz += strlen(argv0_path) + 1;
Guido van Rossumeea14491997-08-13 21:30:44 +0000379#ifdef MS_WIN32
380 if (machinepath)
381 bufsz += strlen(machinepath) + 1;
382 if (userpath)
383 bufsz += strlen(userpath) + 1;
384#endif
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +0000385
386 module_search_path = buf = malloc(bufsz);
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +0000387 if (buf == NULL) {
388 /* We can't exit, so print a warning and limp along */
Guido van Rossumeea14491997-08-13 21:30:44 +0000389 fprintf(stderr, "Can't malloc dynamic PYTHONPATH.\n");
390 if (envpath) {
391 fprintf(stderr, "Using default static $PYTHONPATH.\n");
392 module_search_path = envpath;
393 }
394 else {
395 fprintf(stderr, "Using environment $PYTHONPATH.\n");
396 module_search_path = PYTHONPATH;
397 }
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +0000398 return;
399 }
Guido van Rossumeea14491997-08-13 21:30:44 +0000400
401 if (envpath) {
402 strcpy(buf, envpath);
403 buf = strchr(buf, '\0');
404 *buf++ = DELIM;
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +0000405 }
Guido van Rossumeea14491997-08-13 21:30:44 +0000406#ifdef MS_WIN32
407 if (machinepath) {
408 strcpy(buf, machinepath);
409 buf = strchr(buf, '\0');
410 *buf++ = DELIM;
411 }
412 if (userpath) {
413 strcpy(buf, userpath);
414 buf = strchr(buf, '\0');
415 *buf++ = DELIM;
416 }
417#endif
418 if (pythonhome == NULL) {
419 strcpy(buf, PYTHONPATH);
420 buf = strchr(buf, '\0');
421 }
422 else {
423 char *p = PYTHONPATH;
424 char *q;
425 int n;
426 for (;;) {
427 q = strchr(p, DELIM);
428 if (q == NULL)
429 n = strlen(p);
430 else
431 n = q-p;
432 if (p[0] == '.' && is_sep(p[1])) {
433 strcpy(buf, pythonhome);
434 buf = strchr(buf, '\0');
435 p++;
436 n--;
437 }
438 strncpy(buf, p, n);
439 buf += n;
440 if (q == NULL)
441 break;
442 *buf++ = DELIM;
443 p = q+1;
444 }
445 }
446 if (argv0_path) {
447 *buf++ = DELIM;
448 strcpy(buf, argv0_path);
449 buf = strchr(buf, '\0');
450 }
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +0000451 *buf = '\0';
452}
453
454
455/* External interface */
456
457char *
458Py_GetPath()
459{
460 if (!module_search_path)
461 calculate_path();
462 return module_search_path;
463}
464
465char *
466Py_GetPrefix()
467{
Guido van Rossumeea14491997-08-13 21:30:44 +0000468 if (!module_search_path)
469 calculate_path();
470 return prefix;
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +0000471}
472
473char *
474Py_GetExecPrefix()
475{
Guido van Rossumeea14491997-08-13 21:30:44 +0000476 return Py_GetPrefix();
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +0000477}
478
479char *
Guido van Rossumeea14491997-08-13 21:30:44 +0000480Py_GetProgramFullPath()
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +0000481{
482 if (!module_search_path)
483 calculate_path();
484 return progpath;
485}