blob: b7d903b33f0bcff172b21e1bb353cd871bf95874 [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
38#include <sys/types.h>
39#include <sys/stat.h>
40#include <string.h>
41
42#if HAVE_UNISTD_H
43#include <unistd.h>
44#endif /* HAVE_UNISTD_H */
45
46/* Search in some common locations for the associated Python libraries.
47 *
48 * This version always returns "" for both prefix and exec_prefix.
49 *
50 * Py_GetPath() tries to return a sensible Python module search path.
51 *
52 * First, we look to see if the executable is in a subdirectory of
53 * the Python build directory. We calculate the full path of the
54 * directory containing the executable as progpath. We work backwards
55 * along progpath and look for $dir/Modules/Setup.in, a distinctive
56 * landmark. If found, we use $dir/Lib as $root. The returned
57 * Python path is the compiled #define PYTHONPATH with all the initial
58 * "./lib" replaced by $root.
59 *
60 * Otherwise, if there is a PYTHONPATH environment variable, we return that.
61 *
62 * Otherwise we try to find $progpath/lib/string.py, and if found, then
63 * root is $progpath/lib, and we return Python path as compiled PYTHONPATH
64 * with all "./lib" replaced by $root (as above).
65 *
66 */
67
68#ifndef LANDMARK
69#define LANDMARK "Modules\\Setup.in"
70#endif
71
72static char prefix[MAXPATHLEN+1];
73static char progpath[MAXPATHLEN+1];
74static char *module_search_path = NULL;
75
76static int
77is_sep(ch) /* determine if "ch" is a separator character */
78 char ch;
79{
80#ifdef ALTSEP
81 return ch == SEP || ch == ALTSEP;
82#else
83 return ch == SEP;
84#endif
85}
86
87static void
88reduce(dir)
89 char *dir;
90{
91 int i = strlen(dir);
92 while (i > 0 && !is_sep(dir[i]))
93 --i;
94 dir[i] = '\0';
95}
96
97
98static int
99exists(filename)
100 char *filename;
101{
102 struct stat buf;
103 return stat(filename, &buf) == 0;
104}
105
106
107static void
108join(buffer, stuff)
109 char *buffer;
110 char *stuff;
111{
112 int n, k;
113 if (is_sep(stuff[0]))
114 n = 0;
115 else {
116 n = strlen(buffer);
117 if (n > 0 && !is_sep(buffer[n-1]) && n < MAXPATHLEN)
118 buffer[n++] = SEP;
119 }
120 k = strlen(stuff);
121 if (n + k > MAXPATHLEN)
122 k = MAXPATHLEN - n;
123 strncpy(buffer+n, stuff, k);
124 buffer[n+k] = '\0';
125}
126
127
128static int
129search_for_prefix(argv0_path, landmark)
130 char *argv0_path;
131 char *landmark;
132{
133 int n;
134
135 /* Search from argv0_path, until root is found */
136 strcpy(prefix, argv0_path);
137 do {
138 n = strlen(prefix);
139 join(prefix, landmark);
140 if (exists(prefix))
141 return 1;
142 prefix[n] = '\0';
143 reduce(prefix);
144 } while (prefix[0]);
145 return 0;
146}
147
148static void
149get_progpath()
150{
151#ifdef MS_WIN32
152#include <windows.h>
153 if (!GetModuleFileName(NULL, progpath, MAXPATHLEN))
154 progpath[0] = '\0'; /* failure */
155#else
156 extern char *Py_GetProgramName();
157 char *path = getenv("PATH");
158 char *prog = Py_GetProgramName();
159
160 /* If there is no slash in the argv0 path, then we have to
161 * assume python is on the user's $PATH, since there's no
162 * other way to find a directory to start the search from. If
163 * $PATH isn't exported, you lose.
164 */
165#ifdef ALTSEP
166 if (strchr(prog, SEP) || strchr(prog, ALTSEP))
167#else
168 if (strchr(prog, SEP))
169#endif
170 strcpy(progpath, prog);
171 else if (path) {
172 while (1) {
173 char *delim = strchr(path, DELIM);
174
175 if (delim) {
176 int len = delim - path;
177 strncpy(progpath, path, len);
178 *(progpath + len) = '\0';
179 }
180 else
181 strcpy(progpath, path);
182
183 join(progpath, prog);
184 if (exists(progpath))
185 break;
186
187 if (!delim) {
188 progpath[0] = '\0';
189 break;
190 }
191 path = delim + 1;
192 }
193 }
194 else
195 progpath[0] = '\0';
196#endif
197}
198
199static void
200calculate_path()
201{
202 char ch, *pt, *pt2;
203 char argv0_path[MAXPATHLEN+1];
204 char *buf;
205 int bufsz;
206
207 get_progpath();
208 strcpy(argv0_path, progpath);
209 reduce(argv0_path);
210
211 if (search_for_prefix(argv0_path, LANDMARK)) {
212 reduce(prefix);
213 reduce(prefix);
214 join(prefix, "lib");
215 }
216 else if ((module_search_path = getenv("PYTHONPATH")) != 0) {
217 return; /* if PYTHONPATH environment variable exists, we are done */
218 }
219 else { /* Try the executable_directory/lib */
220 strcpy(prefix, progpath);
221 reduce(prefix);
222 join(prefix, "lib");
223 join(prefix, "string.py"); /* Look for lib/string.py */
224 if (exists(prefix)) {
225 reduce(prefix);
226 }
227 else { /* No module search path!!! */
228 module_search_path = PYTHONPATH;
229 return;
230 }
231 }
232
233
234 /* If we get here, we need to return a path equal to the compiled
235 PYTHONPATH with ".\lib" replaced by our "prefix" directory */
236
237 bufsz = 1; /* Calculate size of return buffer. */
238 for (pt = PYTHONPATH; *pt; pt++)
239 if (*pt == DELIM)
240 bufsz++; /* number of DELIM plus one */
241 bufsz *= strlen(PYTHONPATH) + strlen(prefix); /* high estimate */
242
243 module_search_path = buf = malloc(bufsz);
244
245 if (buf == NULL) {
246 /* We can't exit, so print a warning and limp along */
247 fprintf(stderr, "Not enough memory for dynamic PYTHONPATH.\n");
248 fprintf(stderr, "Using default static PYTHONPATH.\n");
249 module_search_path = PYTHONPATH;
250 return;
251 }
252 for (pt = PYTHONPATH; *pt; pt++) {
253 if (!strncmp(pt, ".\\lib", 5) &&
254 ((ch = *(pt + 5)) == '\\' || ch == DELIM || !ch)){
255 pt += 4;
256 for (pt2 = prefix; *pt2; pt2++)
257 *buf++ = *pt2;
258 }
259 else
260 *buf++ = *pt;
261 }
262 *buf = '\0';
263}
264
265
266/* External interface */
267
268char *
269Py_GetPath()
270{
271 if (!module_search_path)
272 calculate_path();
273 return module_search_path;
274}
275
276char *
277Py_GetPrefix()
278{
279 return "";
280}
281
282char *
283Py_GetExecPrefix()
284{
285 return "";
286}
287
288char *
289Py_GetProgramFullPath() /* Full path to Python executable */
290{
291 if (!module_search_path)
292 calculate_path();
293 return progpath;
294}