Move setting of ioready 'wait' earlier in call chain, to
[python/dscho.git] / PC / os2emx / getpathp.c
blobab31c654338baf5a6010b093f72b4b508d2b9ab5
2 /* Return the initial module search path. */
3 /* This version used by OS/2+EMX */
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)
11 * Python always adds an empty entry at the start, which corresponds
12 to the current directory.
14 * If the PYTHONPATH env. var. exists, it's entries are added next.
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)
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)
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.
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.
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.
44 ---------------------------------------------------------------- */
47 #include "Python.h"
48 #include "osdefs.h"
50 #ifndef PYOS_OS2
51 #error This file only compilable on OS/2
52 #endif
54 #define INCL_DOS
55 #include <os2.h>
57 #include <sys/types.h>
58 #include <sys/stat.h>
59 #include <string.h>
61 #if HAVE_UNISTD_H
62 #include <unistd.h>
63 #endif /* HAVE_UNISTD_H */
65 /* Search in some common locations for the associated Python libraries.
67 * Py_GetPath() tries to return a sensible Python module search path.
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.
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
82 static char prefix[MAXPATHLEN+1];
83 static char progpath[MAXPATHLEN+1];
84 static char *module_search_path = NULL;
87 static int
88 is_sep(char ch) /* determine if "ch" is a separator character */
90 #ifdef ALTSEP
91 return ch == SEP || ch == ALTSEP;
92 #else
93 return ch == SEP;
94 #endif
97 /* assumes 'dir' null terminated in bounds. Never writes
98 beyond existing terminator.
100 static void
101 reduce(char *dir)
103 size_t i = strlen(dir);
104 while (i > 0 && !is_sep(dir[i]))
105 --i;
106 dir[i] = '\0';
109 static int
110 exists(char *filename)
112 struct stat buf;
113 return stat(filename, &buf) == 0;
116 /* Assumes 'filename' MAXPATHLEN+1 bytes long -
117 may extend 'filename' by one character.
119 static int
120 ismodule(char *filename) /* Is module -- check for .pyc/.pyo too */
122 if (exists(filename))
123 return 1;
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;
131 return 0;
134 /* guarantees buffer will never overflow MAXPATHLEN+1 bytes */
135 static void
136 join(char *buffer, char *stuff)
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;
146 k = strlen(stuff);
147 if (n + k > MAXPATHLEN)
148 k = MAXPATHLEN - n;
149 strncpy(buffer+n, stuff, k);
150 buffer[n+k] = '\0';
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.
157 static int
158 gotlandmark(char *landmark)
160 int n, ok;
162 n = strlen(prefix);
163 join(prefix, landmark);
164 ok = ismodule(prefix);
165 prefix[n] = '\0';
166 return ok;
169 /* assumes argv0_path is MAXPATHLEN+1 bytes long, already \0 term'd.
170 assumption provided by only caller, calculate_path() */
171 static int
172 search_for_prefix(char *argv0_path, char *landmark)
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;
185 static void
186 get_progpath(void)
188 extern char *Py_GetProgramName(void);
189 char *path = getenv("PATH");
190 char *prog = Py_GetProgramName();
192 PPIB pib;
193 if ((DosGetInfoBlocks(NULL, &pib) == 0) &&
194 (DosQueryModuleName(pib->pib_hmte, sizeof(progpath), progpath) == 0))
195 return;
197 if (prog == NULL || *prog == '\0')
198 prog = "python";
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.
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);
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';
226 else
227 strncpy(progpath, path, MAXPATHLEN);
229 /* join() is safe for MAXPATHLEN+1 size buffer */
230 join(progpath, prog);
231 if (exists(progpath))
232 break;
234 if (!delim) {
235 progpath[0] = '\0';
236 break;
238 path = delim + 1;
241 else
242 progpath[0] = '\0';
245 static void
246 calculate_path(void)
248 char argv0_path[MAXPATHLEN+1];
249 char *buf;
250 size_t bufsz;
251 char *pythonhome = Py_GetPythonHome();
252 char *envpath = getenv("PYTHONPATH");
253 char zip_path[MAXPATHLEN+1];
254 size_t len;
256 get_progpath();
257 /* progpath guaranteed \0 terminated in MAXPATH+1 bytes. */
258 strcpy(argv0_path, progpath);
259 reduce(argv0_path);
260 if (pythonhome == NULL || *pythonhome == '\0') {
261 if (search_for_prefix(argv0_path, LANDMARK))
262 pythonhome = prefix;
263 else
264 pythonhome = NULL;
266 else
267 strncpy(prefix, pythonhome, MAXPATHLEN);
269 if (envpath && *envpath == '\0')
270 envpath = NULL;
272 /* Calculate zip archive path */
273 strncpy(zip_path, progpath, MAXPATHLEN);
274 zip_path[MAXPATHLEN] = '\0';
275 len = strlen(zip_path);
276 if (len > 4) {
277 zip_path[len-3] = 'z'; /* change ending to "zip" */
278 zip_path[len-2] = 'i';
279 zip_path[len-1] = 'p';
281 else {
282 zip_path[0] = 0;
285 /* We need to construct a path from the following parts.
286 (1) the PYTHONPATH environment variable, if set;
287 (2) the zip archive file path;
288 (3) the PYTHONPATH config macro, with the leading "."
289 of each component replaced with pythonhome, if set;
290 (4) the directory containing the executable (argv0_path).
291 The length calculation calculates #3 first.
294 /* Calculate size of return buffer */
295 if (pythonhome != NULL) {
296 char *p;
297 bufsz = 1;
298 for (p = PYTHONPATH; *p; p++) {
299 if (*p == DELIM)
300 bufsz++; /* number of DELIM plus one */
302 bufsz *= strlen(pythonhome);
304 else
305 bufsz = 0;
306 bufsz += strlen(PYTHONPATH) + 1;
307 bufsz += strlen(argv0_path) + 1;
308 bufsz += strlen(zip_path) + 1;
309 if (envpath != NULL)
310 bufsz += strlen(envpath) + 1;
312 module_search_path = buf = malloc(bufsz);
313 if (buf == NULL) {
314 /* We can't exit, so print a warning and limp along */
315 fprintf(stderr, "Can't malloc dynamic PYTHONPATH.\n");
316 if (envpath) {
317 fprintf(stderr, "Using environment $PYTHONPATH.\n");
318 module_search_path = envpath;
320 else {
321 fprintf(stderr, "Using default static path.\n");
322 module_search_path = PYTHONPATH;
324 return;
327 if (envpath) {
328 strcpy(buf, envpath);
329 buf = strchr(buf, '\0');
330 *buf++ = DELIM;
332 if (zip_path[0]) {
333 strcpy(buf, zip_path);
334 buf = strchr(buf, '\0');
335 *buf++ = DELIM;
338 if (pythonhome == NULL) {
339 strcpy(buf, PYTHONPATH);
340 buf = strchr(buf, '\0');
342 else {
343 char *p = PYTHONPATH;
344 char *q;
345 size_t n;
346 for (;;) {
347 q = strchr(p, DELIM);
348 if (q == NULL)
349 n = strlen(p);
350 else
351 n = q-p;
352 if (p[0] == '.' && is_sep(p[1])) {
353 strcpy(buf, pythonhome);
354 buf = strchr(buf, '\0');
355 p++;
356 n--;
358 strncpy(buf, p, n);
359 buf += n;
360 if (q == NULL)
361 break;
362 *buf++ = DELIM;
363 p = q+1;
366 if (argv0_path) {
367 *buf++ = DELIM;
368 strcpy(buf, argv0_path);
369 buf = strchr(buf, '\0');
371 *buf = '\0';
375 /* External interface */
377 char *
378 Py_GetPath(void)
380 if (!module_search_path)
381 calculate_path();
382 return module_search_path;
385 char *
386 Py_GetPrefix(void)
388 if (!module_search_path)
389 calculate_path();
390 return prefix;
393 char *
394 Py_GetExecPrefix(void)
396 return Py_GetPrefix();
399 char *
400 Py_GetProgramFullPath(void)
402 if (!module_search_path)
403 calculate_path();
404 return progpath;