blob: 5cb8278c7c7e1079261c4bab806b8e2b19c667a0 [file] [log] [blame]
Andrew MacIntyre41d97d62002-02-17 05:23:30 +00001
2/* Return the initial module search path. */
3/* This version used by OS/2+EMX */
4
5/* ----------------------------------------------------------------
6 PATH RULES FOR OS/2+EMX:
7 This describes how sys.path is formed on OS/2+EMX. 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
14 * If the PYTHONPATH env. var. exists, it's entries are added next.
15
16 * We attempt to locate the "Python Home" - if the PYTHONHOME env var
17 is set, we believe it. Otherwise, we use the path of our host .EXE's
18 to try and locate our "landmark" (lib\\os.py) and deduce our home.
19 - If we DO have a Python Home: The relevant sub-directories (Lib,
20 plat-win, lib-tk, etc) are based on the Python Home
21 - If we DO NOT have a Python Home, the core Python Path is
22 loaded from the registry. This is the main PythonPath key,
23 and both HKLM and HKCU are combined to form the path)
24
25 * Iff - we can not locate the Python Home, and have not had a PYTHONPATH
26 specified (ie, we have _nothing_ we can assume is a good path), a
27 default path with relative entries is used (eg. .\Lib;.\plat-win, etc)
28
29
30 The end result of all this is:
31 * When running python.exe, or any other .exe in the main Python directory
32 (either an installed version, or directly from the PCbuild directory),
33 the core path is deduced.
34
35 * When Python is hosted in another exe (different directory, embedded via
36 COM, etc), the Python Home will not be deduced, so the core path from
37 the registry is used. Other "application paths "in the registry are
38 always read.
39
40 * If Python can't find its home and there is no registry (eg, frozen
41 exe, some very strange installation setup) you get a path with
42 some default, but relative, paths.
43
44 ---------------------------------------------------------------- */
45
46
47#include "Python.h"
48#include "osdefs.h"
49
50#ifndef PYOS_OS2
51#error This file only compilable on OS/2
52#endif
53
54#define INCL_DOS
55#include <os2.h>
56
57#include <sys/types.h>
58#include <sys/stat.h>
59#include <string.h>
60
61#if HAVE_UNISTD_H
62#include <unistd.h>
63#endif /* HAVE_UNISTD_H */
64
65/* Search in some common locations for the associated Python libraries.
66 *
67 * Py_GetPath() tries to return a sensible Python module search path.
68 *
69 * The approach is an adaptation for Windows of the strategy used in
70 * ../Modules/getpath.c; it uses the Windows Registry as one of its
71 * information sources.
72 */
73
74#ifndef LANDMARK
75#if defined(PYCC_GCC)
76#define LANDMARK "lib/os.py"
77#else
78#define LANDMARK "lib\\os.py"
79#endif
80#endif
81
82static char prefix[MAXPATHLEN+1];
83static char progpath[MAXPATHLEN+1];
84static char *module_search_path = NULL;
85
86
87static int
88is_sep(char ch) /* determine if "ch" is a separator character */
89{
90#ifdef ALTSEP
91 return ch == SEP || ch == ALTSEP;
92#else
93 return ch == SEP;
94#endif
95}
96
97/* assumes 'dir' null terminated in bounds. Never writes
98 beyond existing terminator.
99*/
100static void
101reduce(char *dir)
102{
103 size_t i = strlen(dir);
104 while (i > 0 && !is_sep(dir[i]))
105 --i;
106 dir[i] = '\0';
107}
108
109static int
110exists(char *filename)
111{
112 struct stat buf;
113 return stat(filename, &buf) == 0;
114}
115
116/* Assumes 'filename' MAXPATHLEN+1 bytes long -
117 may extend 'filename' by one character.
118*/
119static int
120ismodule(char *filename) /* Is module -- check for .pyc/.pyo too */
121{
122 if (exists(filename))
123 return 1;
124
125 /* Check for the compiled version of prefix. */
126 if (strlen(filename) < MAXPATHLEN) {
127 strcat(filename, Py_OptimizeFlag ? "o" : "c");
128 if (exists(filename))
129 return 1;
130 }
131 return 0;
132}
133
134/* guarantees buffer will never overflow MAXPATHLEN+1 bytes */
135static void
136join(char *buffer, char *stuff)
137{
138 size_t n, k;
139 if (is_sep(stuff[0]))
140 n = 0;
141 else {
142 n = strlen(buffer);
143 if (n > 0 && !is_sep(buffer[n-1]) && n < MAXPATHLEN)
144 buffer[n++] = SEP;
145 }
146 k = strlen(stuff);
147 if (n + k > MAXPATHLEN)
148 k = MAXPATHLEN - n;
149 strncpy(buffer+n, stuff, k);
150 buffer[n+k] = '\0';
151}
152
153/* gotlandmark only called by search_for_prefix, which ensures
154 'prefix' is null terminated in bounds. join() ensures
155 'landmark' can not overflow prefix if too long.
156*/
157static int
158gotlandmark(char *landmark)
159{
160 int n, ok;
161
162 n = strlen(prefix);
163 join(prefix, landmark);
164 ok = ismodule(prefix);
165 prefix[n] = '\0';
166 return ok;
167}
168
169/* assumes argv0_path is MAXPATHLEN+1 bytes long, already \0 term'd.
170 assumption provided by only caller, calculate_path() */
171static int
172search_for_prefix(char *argv0_path, char *landmark)
173{
174 /* Search from argv0_path, until landmark is found */
175 strcpy(prefix, argv0_path);
176 do {
177 if (gotlandmark(landmark))
178 return 1;
179 reduce(prefix);
180 } while (prefix[0]);
181 return 0;
182}
183
184
185static void
186get_progpath(void)
187{
188 extern char *Py_GetProgramName(void);
189 char *path = getenv("PATH");
190 char *prog = Py_GetProgramName();
191
192 PPIB pib;
193 if ((DosGetInfoBlocks(NULL, &pib) == 0) &&
194 (DosQueryModuleName(pib->pib_hmte, sizeof(progpath), progpath) == 0))
195 return;
196
197 if (prog == NULL || *prog == '\0')
198 prog = "python";
199
200 /* If there is no slash in the argv0 path, then we have to
201 * assume python is on the user's $PATH, since there's no
202 * other way to find a directory to start the search from. If
203 * $PATH isn't exported, you lose.
204 */
205#ifdef ALTSEP
206 if (strchr(prog, SEP) || strchr(prog, ALTSEP))
207#else
208 if (strchr(prog, SEP))
209#endif
210 strncpy(progpath, prog, MAXPATHLEN);
211 else if (path) {
212 while (1) {
213 char *delim = strchr(path, DELIM);
214
215 if (delim) {
216 size_t len = delim - path;
217 /* ensure we can't overwrite buffer */
218#if !defined(PYCC_GCC)
219 len = min(MAXPATHLEN,len);
220#else
221 len = MAXPATHLEN < len ? MAXPATHLEN : len;
222#endif
223 strncpy(progpath, path, len);
224 *(progpath + len) = '\0';
225 }
226 else
227 strncpy(progpath, path, MAXPATHLEN);
228
229 /* join() is safe for MAXPATHLEN+1 size buffer */
230 join(progpath, prog);
231 if (exists(progpath))
232 break;
233
234 if (!delim) {
235 progpath[0] = '\0';
236 break;
237 }
238 path = delim + 1;
239 }
240 }
241 else
242 progpath[0] = '\0';
243}
244
245static void
246calculate_path(void)
247{
248 char argv0_path[MAXPATHLEN+1];
249 char *buf;
250 size_t bufsz;
251 char *pythonhome = Py_GetPythonHome();
252 char *envpath = getenv("PYTHONPATH");
253
254 get_progpath();
255 /* progpath guaranteed \0 terminated in MAXPATH+1 bytes. */
256 strcpy(argv0_path, progpath);
257 reduce(argv0_path);
258 if (pythonhome == NULL || *pythonhome == '\0') {
259 if (search_for_prefix(argv0_path, LANDMARK))
260 pythonhome = prefix;
261 else
262 pythonhome = NULL;
263 }
264 else
265 strncpy(prefix, pythonhome, MAXPATHLEN);
266
267 if (envpath && *envpath == '\0')
268 envpath = NULL;
269
270 /* We need to construct a path from the following parts.
271 (1) the PYTHONPATH environment variable, if set;
272 (2) the PYTHONPATH config macro, with the leading "."
273 of each component replaced with pythonhome, if set;
274 (3) the directory containing the executable (argv0_path).
275 The length calculation calculates #2 first.
276 */
277
278 /* Calculate size of return buffer */
279 if (pythonhome != NULL) {
280 char *p;
281 bufsz = 1;
282 for (p = PYTHONPATH; *p; p++) {
283 if (*p == DELIM)
284 bufsz++; /* number of DELIM plus one */
285 }
286 bufsz *= strlen(pythonhome);
287 }
288 else
289 bufsz = 0;
290 bufsz += strlen(PYTHONPATH) + 1;
291 bufsz += strlen(argv0_path) + 1;
292 if (envpath != NULL)
293 bufsz += strlen(envpath) + 1;
294
295 module_search_path = buf = malloc(bufsz);
296 if (buf == NULL) {
297 /* We can't exit, so print a warning and limp along */
298 fprintf(stderr, "Can't malloc dynamic PYTHONPATH.\n");
299 if (envpath) {
300 fprintf(stderr, "Using environment $PYTHONPATH.\n");
301 module_search_path = envpath;
302 }
303 else {
304 fprintf(stderr, "Using default static path.\n");
305 module_search_path = PYTHONPATH;
306 }
307 return;
308 }
309
310 if (envpath) {
311 strcpy(buf, envpath);
312 buf = strchr(buf, '\0');
313 *buf++ = DELIM;
314 }
315
316 if (pythonhome == NULL) {
317 strcpy(buf, PYTHONPATH);
318 buf = strchr(buf, '\0');
319 }
320 else {
321 char *p = PYTHONPATH;
322 char *q;
323 size_t n;
324 for (;;) {
325 q = strchr(p, DELIM);
326 if (q == NULL)
327 n = strlen(p);
328 else
329 n = q-p;
330 if (p[0] == '.' && is_sep(p[1])) {
331 strcpy(buf, pythonhome);
332 buf = strchr(buf, '\0');
333 p++;
334 n--;
335 }
336 strncpy(buf, p, n);
337 buf += n;
338 if (q == NULL)
339 break;
340 *buf++ = DELIM;
341 p = q+1;
342 }
343 }
344 if (argv0_path) {
345 *buf++ = DELIM;
346 strcpy(buf, argv0_path);
347 buf = strchr(buf, '\0');
348 }
349 *buf = '\0';
350}
351
352
353/* External interface */
354
355char *
356Py_GetPath(void)
357{
358 if (!module_search_path)
359 calculate_path();
360 return module_search_path;
361}
362
363char *
364Py_GetPrefix(void)
365{
366 if (!module_search_path)
367 calculate_path();
368 return prefix;
369}
370
371char *
372Py_GetExecPrefix(void)
373{
374 return Py_GetPrefix();
375}
376
377char *
378Py_GetProgramFullPath(void)
379{
380 if (!module_search_path)
381 calculate_path();
382 return progpath;
383}