blob: 4a4c89394530be4fc5ec37b1eadfa557ef728ca8 [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
Andrew MacIntyre0c833482003-04-22 03:21:42 +000097/* assumes 'dir' null terminated in bounds.
98 * Never writes beyond existing terminator.
99 */
Andrew MacIntyre41d97d62002-02-17 05:23:30 +0000100static 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
Andrew MacIntyre0c833482003-04-22 03:21:42 +0000116/* Is module (check for .pyc/.pyo too)
117 * Assumes 'filename' MAXPATHLEN+1 bytes long -
118 * may extend 'filename' by one character.
119 */
Andrew MacIntyre41d97d62002-02-17 05:23:30 +0000120static int
Andrew MacIntyre0c833482003-04-22 03:21:42 +0000121ismodule(char *filename)
Andrew MacIntyre41d97d62002-02-17 05:23:30 +0000122{
123 if (exists(filename))
124 return 1;
125
126 /* Check for the compiled version of prefix. */
127 if (strlen(filename) < MAXPATHLEN) {
128 strcat(filename, Py_OptimizeFlag ? "o" : "c");
129 if (exists(filename))
130 return 1;
131 }
132 return 0;
133}
134
135/* guarantees buffer will never overflow MAXPATHLEN+1 bytes */
136static void
137join(char *buffer, char *stuff)
138{
139 size_t n, k;
140 if (is_sep(stuff[0]))
141 n = 0;
142 else {
143 n = strlen(buffer);
144 if (n > 0 && !is_sep(buffer[n-1]) && n < MAXPATHLEN)
145 buffer[n++] = SEP;
146 }
147 k = strlen(stuff);
148 if (n + k > MAXPATHLEN)
149 k = MAXPATHLEN - n;
150 strncpy(buffer+n, stuff, k);
151 buffer[n+k] = '\0';
152}
153
154/* gotlandmark only called by search_for_prefix, which ensures
Andrew MacIntyre0c833482003-04-22 03:21:42 +0000155 * 'prefix' is null terminated in bounds. join() ensures
156 * 'landmark' can not overflow prefix if too long.
157 */
Andrew MacIntyre41d97d62002-02-17 05:23:30 +0000158static int
159gotlandmark(char *landmark)
160{
161 int n, ok;
162
163 n = strlen(prefix);
164 join(prefix, landmark);
165 ok = ismodule(prefix);
166 prefix[n] = '\0';
167 return ok;
168}
169
170/* assumes argv0_path is MAXPATHLEN+1 bytes long, already \0 term'd.
Andrew MacIntyre0c833482003-04-22 03:21:42 +0000171 * assumption provided by only caller, calculate_path()
172 */
Andrew MacIntyre41d97d62002-02-17 05:23:30 +0000173static int
174search_for_prefix(char *argv0_path, char *landmark)
175{
176 /* Search from argv0_path, until landmark is found */
177 strcpy(prefix, argv0_path);
178 do {
179 if (gotlandmark(landmark))
180 return 1;
181 reduce(prefix);
182 } while (prefix[0]);
183 return 0;
184}
185
186
187static void
188get_progpath(void)
189{
190 extern char *Py_GetProgramName(void);
191 char *path = getenv("PATH");
192 char *prog = Py_GetProgramName();
193
194 PPIB pib;
195 if ((DosGetInfoBlocks(NULL, &pib) == 0) &&
196 (DosQueryModuleName(pib->pib_hmte, sizeof(progpath), progpath) == 0))
197 return;
198
199 if (prog == NULL || *prog == '\0')
200 prog = "python";
201
202 /* If there is no slash in the argv0 path, then we have to
203 * assume python is on the user's $PATH, since there's no
204 * other way to find a directory to start the search from. If
205 * $PATH isn't exported, you lose.
206 */
207#ifdef ALTSEP
208 if (strchr(prog, SEP) || strchr(prog, ALTSEP))
209#else
210 if (strchr(prog, SEP))
211#endif
212 strncpy(progpath, prog, MAXPATHLEN);
213 else if (path) {
214 while (1) {
215 char *delim = strchr(path, DELIM);
216
217 if (delim) {
218 size_t len = delim - path;
219 /* ensure we can't overwrite buffer */
220#if !defined(PYCC_GCC)
221 len = min(MAXPATHLEN,len);
222#else
223 len = MAXPATHLEN < len ? MAXPATHLEN : len;
224#endif
225 strncpy(progpath, path, len);
226 *(progpath + len) = '\0';
227 }
228 else
229 strncpy(progpath, path, MAXPATHLEN);
230
231 /* join() is safe for MAXPATHLEN+1 size buffer */
232 join(progpath, prog);
233 if (exists(progpath))
234 break;
235
236 if (!delim) {
237 progpath[0] = '\0';
238 break;
239 }
240 path = delim + 1;
241 }
242 }
243 else
244 progpath[0] = '\0';
245}
246
247static void
248calculate_path(void)
249{
250 char argv0_path[MAXPATHLEN+1];
251 char *buf;
252 size_t bufsz;
253 char *pythonhome = Py_GetPythonHome();
254 char *envpath = getenv("PYTHONPATH");
Andrew MacIntyre214d39a2003-01-02 12:41:58 +0000255 char zip_path[MAXPATHLEN+1];
256 size_t len;
Andrew MacIntyre41d97d62002-02-17 05:23:30 +0000257
258 get_progpath();
259 /* progpath guaranteed \0 terminated in MAXPATH+1 bytes. */
260 strcpy(argv0_path, progpath);
261 reduce(argv0_path);
262 if (pythonhome == NULL || *pythonhome == '\0') {
263 if (search_for_prefix(argv0_path, LANDMARK))
264 pythonhome = prefix;
265 else
266 pythonhome = NULL;
267 }
268 else
269 strncpy(prefix, pythonhome, MAXPATHLEN);
270
271 if (envpath && *envpath == '\0')
272 envpath = NULL;
273
Andrew MacIntyre214d39a2003-01-02 12:41:58 +0000274 /* Calculate zip archive path */
275 strncpy(zip_path, progpath, MAXPATHLEN);
276 zip_path[MAXPATHLEN] = '\0';
277 len = strlen(zip_path);
278 if (len > 4) {
279 zip_path[len-3] = 'z'; /* change ending to "zip" */
280 zip_path[len-2] = 'i';
281 zip_path[len-1] = 'p';
282 }
283 else {
284 zip_path[0] = 0;
285 }
286
Andrew MacIntyre41d97d62002-02-17 05:23:30 +0000287 /* We need to construct a path from the following parts.
Andrew MacIntyre0c833482003-04-22 03:21:42 +0000288 * (1) the PYTHONPATH environment variable, if set;
289 * (2) the zip archive file path;
290 * (3) the PYTHONPATH config macro, with the leading "."
291 * of each component replaced with pythonhome, if set;
292 * (4) the directory containing the executable (argv0_path).
293 * The length calculation calculates #3 first.
294 */
Andrew MacIntyre41d97d62002-02-17 05:23:30 +0000295
296 /* Calculate size of return buffer */
297 if (pythonhome != NULL) {
298 char *p;
299 bufsz = 1;
300 for (p = PYTHONPATH; *p; p++) {
301 if (*p == DELIM)
302 bufsz++; /* number of DELIM plus one */
303 }
304 bufsz *= strlen(pythonhome);
305 }
306 else
307 bufsz = 0;
308 bufsz += strlen(PYTHONPATH) + 1;
309 bufsz += strlen(argv0_path) + 1;
Andrew MacIntyre214d39a2003-01-02 12:41:58 +0000310 bufsz += strlen(zip_path) + 1;
Andrew MacIntyre41d97d62002-02-17 05:23:30 +0000311 if (envpath != NULL)
312 bufsz += strlen(envpath) + 1;
313
314 module_search_path = buf = malloc(bufsz);
315 if (buf == NULL) {
316 /* We can't exit, so print a warning and limp along */
317 fprintf(stderr, "Can't malloc dynamic PYTHONPATH.\n");
318 if (envpath) {
319 fprintf(stderr, "Using environment $PYTHONPATH.\n");
320 module_search_path = envpath;
321 }
322 else {
323 fprintf(stderr, "Using default static path.\n");
324 module_search_path = PYTHONPATH;
325 }
326 return;
327 }
328
329 if (envpath) {
330 strcpy(buf, envpath);
331 buf = strchr(buf, '\0');
332 *buf++ = DELIM;
333 }
Andrew MacIntyre214d39a2003-01-02 12:41:58 +0000334 if (zip_path[0]) {
335 strcpy(buf, zip_path);
336 buf = strchr(buf, '\0');
337 *buf++ = DELIM;
338 }
Andrew MacIntyre41d97d62002-02-17 05:23:30 +0000339
340 if (pythonhome == NULL) {
341 strcpy(buf, PYTHONPATH);
342 buf = strchr(buf, '\0');
343 }
344 else {
345 char *p = PYTHONPATH;
346 char *q;
347 size_t n;
348 for (;;) {
349 q = strchr(p, DELIM);
350 if (q == NULL)
351 n = strlen(p);
352 else
353 n = q-p;
354 if (p[0] == '.' && is_sep(p[1])) {
355 strcpy(buf, pythonhome);
356 buf = strchr(buf, '\0');
357 p++;
358 n--;
359 }
360 strncpy(buf, p, n);
361 buf += n;
362 if (q == NULL)
363 break;
364 *buf++ = DELIM;
365 p = q+1;
366 }
367 }
368 if (argv0_path) {
369 *buf++ = DELIM;
370 strcpy(buf, argv0_path);
371 buf = strchr(buf, '\0');
372 }
373 *buf = '\0';
374}
375
376
377/* External interface */
378
379char *
380Py_GetPath(void)
381{
382 if (!module_search_path)
383 calculate_path();
384 return module_search_path;
385}
386
387char *
388Py_GetPrefix(void)
389{
390 if (!module_search_path)
391 calculate_path();
392 return prefix;
393}
394
395char *
396Py_GetExecPrefix(void)
397{
398 return Py_GetPrefix();
399}
400
401char *
402Py_GetProgramFullPath(void)
403{
404 if (!module_search_path)
405 calculate_path();
406 return progpath;
407}