Class around PixMap objects that allows more python-like access. By Joe Strout.
[python/dscho.git] / PC / os2vacpp / getpathp.c
blobb7056ab1b401b2c899a7f7a4515748378b4d0cf7
1 /***********************************************************
2 Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam,
3 The Netherlands.
5 All Rights Reserved
7 Permission to use, copy, modify, and distribute this software and its
8 documentation for any purpose and without fee is hereby granted,
9 provided that the above copyright notice appear in all copies and that
10 both that copyright notice and this permission notice appear in
11 supporting documentation, and that the names of Stichting Mathematisch
12 Centrum or CWI or Corporation for National Research Initiatives or
13 CNRI not be used in advertising or publicity pertaining to
14 distribution of the software without specific, written prior
15 permission.
17 While CWI is the initial source for this software, a modified version
18 is made available by the Corporation for National Research Initiatives
19 (CNRI) at the Internet address ftp://ftp.python.org.
21 STICHTING MATHEMATISCH CENTRUM AND CNRI DISCLAIM ALL WARRANTIES WITH
22 REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
23 MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH
24 CENTRUM OR CNRI BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
25 DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
26 PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
27 TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
28 PERFORMANCE OF THIS SOFTWARE.
30 ******************************************************************/
32 /* Return the initial module search path. */
33 /* Used by DOS, OS/2, Windows 3.1. Works on NT too. */
35 #include "Python.h"
36 #include "osdefs.h"
38 #ifdef MS_WIN32
39 #include <windows.h>
40 extern BOOL PyWin_IsWin32s();
41 #endif
43 #include <sys/types.h>
44 #include <sys/stat.h>
45 #include <string.h>
47 #if HAVE_UNISTD_H
48 #include <unistd.h>
49 #endif /* HAVE_UNISTD_H */
51 /* Search in some common locations for the associated Python libraries.
53 * Two directories must be found, the platform independent directory
54 * (prefix), containing the common .py and .pyc files, and the platform
55 * dependent directory (exec_prefix), containing the shared library
56 * modules. Note that prefix and exec_prefix can be the same directory,
57 * but for some installations, they are different.
59 * Py_GetPath() tries to return a sensible Python module search path.
61 * First, we look to see if the executable is in a subdirectory of
62 * the Python build directory. We calculate the full path of the
63 * directory containing the executable as progpath. We work backwards
64 * along progpath and look for $dir/Modules/Setup.in, a distinctive
65 * landmark. If found, we use $dir/Lib as $root. The returned
66 * Python path is the compiled #define PYTHONPATH with all the initial
67 * "./lib" replaced by $root.
69 * Otherwise, if there is a PYTHONPATH environment variable, we return that.
71 * Otherwise we try to find $progpath/lib/string.py, and if found, then
72 * root is $progpath/lib, and we return Python path as compiled PYTHONPATH
73 * with all "./lib" replaced by $root (as above).
77 #ifndef LANDMARK
78 #define LANDMARK "lib\\string.py"
79 #endif
81 static char prefix[MAXPATHLEN+1];
82 static char exec_prefix[MAXPATHLEN+1];
83 static char progpath[MAXPATHLEN+1];
84 static char *module_search_path = NULL;
87 static int
88 is_sep(ch) /* determine if "ch" is a separator character */
89 char ch;
91 #ifdef ALTSEP
92 return ch == SEP || ch == ALTSEP;
93 #else
94 return ch == SEP;
95 #endif
99 static void
100 reduce(dir)
101 char *dir;
103 int i = strlen(dir);
104 while (i > 0 && !is_sep(dir[i]))
105 --i;
106 dir[i] = '\0';
110 static int
111 exists(filename)
112 char *filename;
114 struct stat buf;
115 return stat(filename, &buf) == 0;
119 static void
120 join(buffer, stuff)
121 char *buffer;
122 char *stuff;
124 int n, k;
125 if (is_sep(stuff[0]))
126 n = 0;
127 else {
128 n = strlen(buffer);
129 if (n > 0 && !is_sep(buffer[n-1]) && n < MAXPATHLEN)
130 buffer[n++] = SEP;
132 k = strlen(stuff);
133 if (n + k > MAXPATHLEN)
134 k = MAXPATHLEN - n;
135 strncpy(buffer+n, stuff, k);
136 buffer[n+k] = '\0';
140 static int
141 search_for_prefix(argv0_path, landmark)
142 char *argv0_path;
143 char *landmark;
145 int n;
147 /* Search from argv0_path, until root is found */
148 strcpy(prefix, argv0_path);
149 do {
150 n = strlen(prefix);
151 join(prefix, landmark);
152 if (exists(prefix)) {
153 prefix[n] = '\0';
154 return 1;
156 prefix[n] = '\0';
157 reduce(prefix);
158 } while (prefix[0]);
159 return 0;
162 #ifdef MS_WIN32
163 #include "malloc.h" // for alloca - see comments below!
164 extern const char *PyWin_DLLVersionString; // a string loaded from the DLL at startup.
167 /* Load a PYTHONPATH value from the registry.
168 Load from either HKEY_LOCAL_MACHINE or HKEY_CURRENT_USER.
170 Returns NULL, or a pointer that should be freed.
173 static char *
174 getpythonregpath(HKEY keyBase, BOOL bWin32s)
176 HKEY newKey = 0;
177 DWORD nameSize = 0;
178 DWORD dataSize = 0;
179 DWORD numEntries = 0;
180 LONG rc;
181 char *retval = NULL;
182 char *dataBuf;
183 const char keyPrefix[] = "Software\\Python\\PythonCore\\";
184 const char keySuffix[] = "\\PythonPath";
185 int versionLen;
186 char *keyBuf;
188 // Tried to use sysget("winver") but here is too early :-(
189 versionLen = strlen(PyWin_DLLVersionString);
190 // alloca == no free required, but memory only local to fn.
191 // also no heap fragmentation! Am I being silly?
192 keyBuf = alloca(sizeof(keyPrefix)-1 + versionLen + sizeof(keySuffix)); // chars only, plus 1 NULL.
193 // lots of constants here for the compiler to optimize away :-)
194 memcpy(keyBuf, keyPrefix, sizeof(keyPrefix)-1);
195 memcpy(keyBuf+sizeof(keyPrefix)-1, PyWin_DLLVersionString, versionLen);
196 memcpy(keyBuf+sizeof(keyPrefix)-1+versionLen, keySuffix, sizeof(keySuffix)); // NULL comes with this one!
198 rc=RegOpenKey(keyBase,
199 keyBuf,
200 &newKey);
201 if (rc==ERROR_SUCCESS) {
202 RegQueryInfoKey(newKey, NULL, NULL, NULL, NULL, NULL, NULL,
203 &numEntries, &nameSize, &dataSize, NULL, NULL);
205 if (bWin32s && numEntries==0 && dataSize==0) {
206 /* must hardcode for Win32s */
207 numEntries = 1;
208 dataSize = 511;
210 if (numEntries) {
211 /* Loop over all subkeys. */
212 /* Win32s doesnt know how many subkeys, so we do
213 it twice */
214 char keyBuf[MAX_PATH+1];
215 int index = 0;
216 int off = 0;
217 for(index=0;;index++) {
218 long reqdSize = 0;
219 DWORD rc = RegEnumKey(newKey,
220 index, keyBuf, MAX_PATH+1);
221 if (rc) break;
222 rc = RegQueryValue(newKey, keyBuf, NULL, &reqdSize);
223 if (rc) break;
224 if (bWin32s && reqdSize==0) reqdSize = 512;
225 dataSize += reqdSize + 1; /* 1 for the ";" */
227 dataBuf = malloc(dataSize+1);
228 if (dataBuf==NULL)
229 return NULL; /* pretty serious? Raise error? */
230 /* Now loop over, grabbing the paths.
231 Subkeys before main library */
232 for(index=0;;index++) {
233 int adjust;
234 long reqdSize = dataSize;
235 DWORD rc = RegEnumKey(newKey,
236 index, keyBuf,MAX_PATH+1);
237 if (rc) break;
238 rc = RegQueryValue(newKey,
239 keyBuf, dataBuf+off, &reqdSize);
240 if (rc) break;
241 if (reqdSize>1) {
242 /* If Nothing, or only '\0' copied. */
243 adjust = strlen(dataBuf+off);
244 dataSize -= adjust;
245 off += adjust;
246 dataBuf[off++] = ';';
247 dataBuf[off] = '\0';
248 dataSize--;
251 /* Additionally, win32s doesnt work as expected, so
252 the specific strlen() is required for 3.1. */
253 rc = RegQueryValue(newKey, "", dataBuf+off, &dataSize);
254 if (rc==ERROR_SUCCESS) {
255 if (strlen(dataBuf)==0)
256 free(dataBuf);
257 else
258 retval = dataBuf; /* caller will free */
260 else
261 free(dataBuf);
264 if (newKey)
265 RegCloseKey(newKey);
266 return retval;
268 #endif /* MS_WIN32 */
270 static void
271 get_progpath()
273 extern char *Py_GetProgramName();
274 char *path = getenv("PATH");
275 char *prog = Py_GetProgramName();
277 #ifdef MS_WIN32
278 if (GetModuleFileName(NULL, progpath, MAXPATHLEN))
279 return;
280 #endif
281 if (prog == NULL || *prog == '\0')
282 prog = "python";
284 /* If there is no slash in the argv0 path, then we have to
285 * assume python is on the user's $PATH, since there's no
286 * other way to find a directory to start the search from. If
287 * $PATH isn't exported, you lose.
289 #ifdef ALTSEP
290 if (strchr(prog, SEP) || strchr(prog, ALTSEP))
291 #else
292 if (strchr(prog, SEP))
293 #endif
294 strcpy(progpath, prog);
295 else if (path) {
296 while (1) {
297 char *delim = strchr(path, DELIM);
299 if (delim) {
300 int len = delim - path;
301 strncpy(progpath, path, len);
302 *(progpath + len) = '\0';
304 else
305 strcpy(progpath, path);
307 join(progpath, prog);
308 if (exists(progpath))
309 break;
311 if (!delim) {
312 progpath[0] = '\0';
313 break;
315 path = delim + 1;
318 else
319 progpath[0] = '\0';
322 static void
323 calculate_path()
325 char argv0_path[MAXPATHLEN+1];
326 char *buf;
327 int bufsz;
328 char *pythonhome = Py_GetPythonHome();
329 char *envpath = getenv("PYTHONPATH");
330 #ifdef MS_WIN32
331 char *machinepath, *userpath;
333 /* Are we running under Windows 3.1(1) Win32s? */
334 if (PyWin_IsWin32s()) {
335 /* Only CLASSES_ROOT is supported */
336 machinepath = getpythonregpath(HKEY_CLASSES_ROOT, TRUE);
337 userpath = NULL;
338 } else {
339 machinepath = getpythonregpath(HKEY_LOCAL_MACHINE, FALSE);
340 userpath = getpythonregpath(HKEY_CURRENT_USER, FALSE);
342 #endif
344 get_progpath();
345 strcpy(argv0_path, progpath);
346 reduce(argv0_path);
347 if (pythonhome == NULL || *pythonhome == '\0') {
348 if (search_for_prefix(argv0_path, LANDMARK))
349 pythonhome = prefix;
350 else
351 pythonhome = NULL;
353 else {
354 char *delim;
356 strcpy(prefix, pythonhome);
358 /* Extract Any Optional Trailing EXEC_PREFIX */
359 /* e.g. PYTHONHOME=<prefix>:<exec_prefix> */
360 delim = strchr(prefix, DELIM);
361 if (delim) {
362 *delim = '\0';
363 strcpy(exec_prefix, delim+1);
364 } else
365 strcpy(exec_prefix, EXEC_PREFIX);
368 if (envpath && *envpath == '\0')
369 envpath = NULL;
371 /* We need to construct a path from the following parts:
372 (1) the PYTHONPATH environment variable, if set;
373 (2) for Win32, the machinepath and userpath, if set;
374 (3) the PYTHONPATH config macro, with the leading "."
375 of each component replaced with pythonhome, if set;
376 (4) the directory containing the executable (argv0_path).
377 The length calculation calculates #3 first.
380 /* Calculate size of return buffer */
381 if (pythonhome != NULL) {
382 char *p;
383 bufsz = 1;
384 for (p = PYTHONPATH; *p; p++) {
385 if (*p == DELIM)
386 bufsz++; /* number of DELIM plus one */
388 bufsz *= strlen(pythonhome);
390 else
391 bufsz = 0;
392 bufsz += strlen(PYTHONPATH) + 1;
393 if (envpath != NULL)
394 bufsz += strlen(envpath) + 1;
395 bufsz += strlen(argv0_path) + 1;
396 #ifdef MS_WIN32
397 if (machinepath)
398 bufsz += strlen(machinepath) + 1;
399 if (userpath)
400 bufsz += strlen(userpath) + 1;
401 #endif
403 module_search_path = buf = malloc(bufsz);
404 if (buf == NULL) {
405 /* We can't exit, so print a warning and limp along */
406 fprintf(stderr, "Can't malloc dynamic PYTHONPATH.\n");
407 if (envpath) {
408 fprintf(stderr, "Using default static $PYTHONPATH.\n");
409 module_search_path = envpath;
411 else {
412 fprintf(stderr, "Using environment $PYTHONPATH.\n");
413 module_search_path = PYTHONPATH;
415 return;
418 if (envpath) {
419 strcpy(buf, envpath);
420 buf = strchr(buf, '\0');
421 *buf++ = DELIM;
423 #ifdef MS_WIN32
424 if (machinepath) {
425 strcpy(buf, machinepath);
426 buf = strchr(buf, '\0');
427 *buf++ = DELIM;
429 if (userpath) {
430 strcpy(buf, userpath);
431 buf = strchr(buf, '\0');
432 *buf++ = DELIM;
434 #endif
435 if (pythonhome == NULL) {
436 strcpy(buf, PYTHONPATH);
437 buf = strchr(buf, '\0');
439 else {
440 char *p = PYTHONPATH;
441 char *q;
442 int n;
443 for (;;) {
444 q = strchr(p, DELIM);
445 if (q == NULL)
446 n = strlen(p);
447 else
448 n = q-p;
449 if (p[0] == '.' && is_sep(p[1])) {
450 strcpy(buf, pythonhome);
451 buf = strchr(buf, '\0');
452 p++;
453 n--;
455 strncpy(buf, p, n);
456 buf += n;
457 if (q == NULL)
458 break;
459 *buf++ = DELIM;
460 p = q+1;
463 if (argv0_path) {
464 *buf++ = DELIM;
465 strcpy(buf, argv0_path);
466 buf = strchr(buf, '\0');
468 *buf = '\0';
472 /* External interface */
474 char *
475 Py_GetPath()
477 if (!module_search_path)
478 calculate_path();
480 return module_search_path;
483 char *
484 Py_GetPrefix()
486 if (!module_search_path)
487 calculate_path();
489 return prefix;
492 char *
493 Py_GetExecPrefix()
495 if (!module_search_path)
496 calculate_path();
498 return exec_prefix;
501 char *
502 Py_GetProgramFullPath()
504 if (!module_search_path)
505 calculate_path();
507 return progpath;