]> git.proxmox.com Git - mirror_edk2.git/blame_incremental - AppPkg/Applications/Python/Efi/getpathp.c
Fix compilation errors detected with GCC 4.4
[mirror_edk2.git] / AppPkg / Applications / Python / Efi / getpathp.c
... / ...
CommitLineData
1\r
2/* Return the initial module search path. */\r
3/* Used by DOS, OS/2, Windows 3.1, Windows 95/98, Windows NT. */\r
4\r
5/* ----------------------------------------------------------------\r
6 PATH RULES FOR WINDOWS:\r
7 This describes how sys.path is formed on Windows. It describes the\r
8 functionality, not the implementation (ie, the order in which these\r
9 are actually fetched is different)\r
10\r
11 * Python always adds an empty entry at the start, which corresponds\r
12 to the current directory.\r
13\r
14 * If the PYTHONPATH env. var. exists, its entries are added next.\r
15\r
16 * We look in the registry for "application paths" - that is, sub-keys\r
17 under the main PythonPath registry key. These are added next (the\r
18 order of sub-key processing is undefined).\r
19 HKEY_CURRENT_USER is searched and added first.\r
20 HKEY_LOCAL_MACHINE is searched and added next.\r
21 (Note that all known installers only use HKLM, so HKCU is typically\r
22 empty)\r
23\r
24 * We attempt to locate the "Python Home" - if the PYTHONHOME env var\r
25 is set, we believe it. Otherwise, we use the path of our host .EXE's\r
26 to try and locate our "landmark" (lib\\os.py) and deduce our home.\r
27 - If we DO have a Python Home: The relevant sub-directories (Lib,\r
28 plat-win, lib-tk, etc) are based on the Python Home\r
29 - If we DO NOT have a Python Home, the core Python Path is\r
30 loaded from the registry. This is the main PythonPath key,\r
31 and both HKLM and HKCU are combined to form the path)\r
32\r
33 * Iff - we can not locate the Python Home, have not had a PYTHONPATH\r
34 specified, and can't locate any Registry entries (ie, we have _nothing_\r
35 we can assume is a good path), a default path with relative entries is\r
36 used (eg. .\Lib;.\plat-win, etc)\r
37\r
38\r
39 The end result of all this is:\r
40 * When running python.exe, or any other .exe in the main Python directory\r
41 (either an installed version, or directly from the PCbuild directory),\r
42 the core path is deduced, and the core paths in the registry are\r
43 ignored. Other "application paths" in the registry are always read.\r
44\r
45 * When Python is hosted in another exe (different directory, embedded via\r
46 COM, etc), the Python Home will not be deduced, so the core path from\r
47 the registry is used. Other "application paths" in the registry are\r
48 always read.\r
49\r
50 * If Python can't find its home and there is no registry (eg, frozen\r
51 exe, some very strange installation setup) you get a path with\r
52 some default, but relative, paths.\r
53\r
54 ---------------------------------------------------------------- */\r
55\r
56\r
57#include "Python.h"\r
58#include "osdefs.h"\r
59\r
60#ifdef MS_WINDOWS\r
61#include <windows.h>\r
62#include <tchar.h>\r
63#endif\r
64\r
65#ifdef HAVE_SYS_TYPES_H\r
66#include <sys/types.h>\r
67#endif /* HAVE_SYS_TYPES_H */\r
68\r
69#ifdef HAVE_SYS_STAT_H\r
70#include <sys/stat.h>\r
71#endif /* HAVE_SYS_STAT_H */\r
72\r
73#include <string.h>\r
74\r
75/* Search in some common locations for the associated Python libraries.\r
76 *\r
77 * Py_GetPath() tries to return a sensible Python module search path.\r
78 *\r
79 * The approach is an adaptation for Windows of the strategy used in\r
80 * ../Modules/getpath.c; it uses the Windows Registry as one of its\r
81 * information sources.\r
82 */\r
83\r
84#ifndef LANDMARK\r
85#define LANDMARK "lib\\os.py"\r
86#endif\r
87\r
88static char prefix[MAXPATHLEN+1];\r
89static char progpath[MAXPATHLEN+1];\r
90static char dllpath[MAXPATHLEN+1];\r
91static char *module_search_path = NULL;\r
92\r
93\r
94static int\r
95is_sep(char ch) /* determine if "ch" is a separator character */\r
96{\r
97#ifdef ALTSEP\r
98 return ch == SEP || ch == ALTSEP;\r
99#else\r
100 return ch == SEP;\r
101#endif\r
102}\r
103\r
104/* assumes 'dir' null terminated in bounds. Never writes\r
105 beyond existing terminator.\r
106*/\r
107static void\r
108reduce(char *dir)\r
109{\r
110 size_t i = strlen(dir);\r
111 while (i > 0 && !is_sep(dir[i]))\r
112 --i;\r
113 dir[i] = '\0';\r
114}\r
115\r
116\r
117static int\r
118exists(char *filename)\r
119{\r
120 struct stat buf;\r
121 return stat(filename, &buf) == 0;\r
122}\r
123\r
124/* Assumes 'filename' MAXPATHLEN+1 bytes long -\r
125 may extend 'filename' by one character.\r
126*/\r
127static int\r
128ismodule(char *filename) /* Is module -- check for .pyc/.pyo too */\r
129{\r
130 if (exists(filename))\r
131 return 1;\r
132\r
133 /* Check for the compiled version of prefix. */\r
134 if (strlen(filename) < MAXPATHLEN) {\r
135 strcat(filename, Py_OptimizeFlag ? "o" : "c");\r
136 if (exists(filename))\r
137 return 1;\r
138 }\r
139 return 0;\r
140}\r
141\r
142/* Add a path component, by appending stuff to buffer.\r
143 buffer must have at least MAXPATHLEN + 1 bytes allocated, and contain a\r
144 NUL-terminated string with no more than MAXPATHLEN characters (not counting\r
145 the trailing NUL). It's a fatal error if it contains a string longer than\r
146 that (callers must be careful!). If these requirements are met, it's\r
147 guaranteed that buffer will still be a NUL-terminated string with no more\r
148 than MAXPATHLEN characters at exit. If stuff is too long, only as much of\r
149 stuff as fits will be appended.\r
150*/\r
151static void\r
152join(char *buffer, char *stuff)\r
153{\r
154 size_t n, k;\r
155 if (is_sep(stuff[0]))\r
156 n = 0;\r
157 else {\r
158 n = strlen(buffer);\r
159 if (n > 0 && !is_sep(buffer[n-1]) && n < MAXPATHLEN)\r
160 buffer[n++] = SEP;\r
161 }\r
162 if (n > MAXPATHLEN)\r
163 Py_FatalError("buffer overflow in getpathp.c's joinpath()");\r
164 k = strlen(stuff);\r
165 if (n + k > MAXPATHLEN)\r
166 k = MAXPATHLEN - n;\r
167 strncpy(buffer+n, stuff, k);\r
168 buffer[n+k] = '\0';\r
169}\r
170\r
171/* gotlandmark only called by search_for_prefix, which ensures\r
172 'prefix' is null terminated in bounds. join() ensures\r
173 'landmark' can not overflow prefix if too long.\r
174*/\r
175static int\r
176gotlandmark(char *landmark)\r
177{\r
178 int ok;\r
179 Py_ssize_t n;\r
180\r
181 n = strlen(prefix);\r
182 join(prefix, landmark);\r
183 ok = ismodule(prefix);\r
184 prefix[n] = '\0';\r
185 return ok;\r
186}\r
187\r
188/* assumes argv0_path is MAXPATHLEN+1 bytes long, already \0 term'd.\r
189 assumption provided by only caller, calculate_path() */\r
190static int\r
191search_for_prefix(char *argv0_path, char *landmark)\r
192{\r
193 /* Search from argv0_path, until landmark is found */\r
194 strcpy(prefix, argv0_path);\r
195 do {\r
196 if (gotlandmark(landmark))\r
197 return 1;\r
198 reduce(prefix);\r
199 } while (prefix[0]);\r
200 return 0;\r
201}\r
202\r
203#ifdef MS_WINDOWS\r
204#ifdef Py_ENABLE_SHARED\r
205\r
206/* a string loaded from the DLL at startup.*/\r
207extern const char *PyWin_DLLVersionString;\r
208\r
209\r
210/* Load a PYTHONPATH value from the registry.\r
211 Load from either HKEY_LOCAL_MACHINE or HKEY_CURRENT_USER.\r
212\r
213 Works in both Unicode and 8bit environments. Only uses the\r
214 Ex family of functions so it also works with Windows CE.\r
215\r
216 Returns NULL, or a pointer that should be freed.\r
217\r
218 XXX - this code is pretty strange, as it used to also\r
219 work on Win16, where the buffer sizes werent available\r
220 in advance. It could be simplied now Win16/Win32s is dead!\r
221*/\r
222\r
223static char *\r
224getpythonregpath(HKEY keyBase, int skipcore)\r
225{\r
226 HKEY newKey = 0;\r
227 DWORD dataSize = 0;\r
228 DWORD numKeys = 0;\r
229 LONG rc;\r
230 char *retval = NULL;\r
231 TCHAR *dataBuf = NULL;\r
232 static const TCHAR keyPrefix[] = _T("Software\\Python\\PythonCore\\");\r
233 static const TCHAR keySuffix[] = _T("\\PythonPath");\r
234 size_t versionLen;\r
235 DWORD index;\r
236 TCHAR *keyBuf = NULL;\r
237 TCHAR *keyBufPtr;\r
238 TCHAR **ppPaths = NULL;\r
239\r
240 /* Tried to use sysget("winver") but here is too early :-( */\r
241 versionLen = _tcslen(PyWin_DLLVersionString);\r
242 /* Space for all the chars, plus one \0 */\r
243 keyBuf = keyBufPtr = malloc(sizeof(keyPrefix) +\r
244 sizeof(TCHAR)*(versionLen-1) +\r
245 sizeof(keySuffix));\r
246 if (keyBuf==NULL) goto done;\r
247\r
248 memcpy(keyBufPtr, keyPrefix, sizeof(keyPrefix)-sizeof(TCHAR));\r
249 keyBufPtr += sizeof(keyPrefix)/sizeof(TCHAR) - 1;\r
250 memcpy(keyBufPtr, PyWin_DLLVersionString, versionLen * sizeof(TCHAR));\r
251 keyBufPtr += versionLen;\r
252 /* NULL comes with this one! */\r
253 memcpy(keyBufPtr, keySuffix, sizeof(keySuffix));\r
254 /* Open the root Python key */\r
255 rc=RegOpenKeyEx(keyBase,\r
256 keyBuf, /* subkey */\r
257 0, /* reserved */\r
258 KEY_READ,\r
259 &newKey);\r
260 if (rc!=ERROR_SUCCESS) goto done;\r
261 /* Find out how big our core buffer is, and how many subkeys we have */\r
262 rc = RegQueryInfoKey(newKey, NULL, NULL, NULL, &numKeys, NULL, NULL,\r
263 NULL, NULL, &dataSize, NULL, NULL);\r
264 if (rc!=ERROR_SUCCESS) goto done;\r
265 if (skipcore) dataSize = 0; /* Only count core ones if we want them! */\r
266 /* Allocate a temp array of char buffers, so we only need to loop\r
267 reading the registry once\r
268 */\r
269 ppPaths = malloc( sizeof(TCHAR *) * numKeys );\r
270 if (ppPaths==NULL) goto done;\r
271 memset(ppPaths, 0, sizeof(TCHAR *) * numKeys);\r
272 /* Loop over all subkeys, allocating a temp sub-buffer. */\r
273 for(index=0;index<numKeys;index++) {\r
274 TCHAR keyBuf[MAX_PATH+1];\r
275 HKEY subKey = 0;\r
276 DWORD reqdSize = MAX_PATH+1;\r
277 /* Get the sub-key name */\r
278 DWORD rc = RegEnumKeyEx(newKey, index, keyBuf, &reqdSize,\r
279 NULL, NULL, NULL, NULL );\r
280 if (rc!=ERROR_SUCCESS) goto done;\r
281 /* Open the sub-key */\r
282 rc=RegOpenKeyEx(newKey,\r
283 keyBuf, /* subkey */\r
284 0, /* reserved */\r
285 KEY_READ,\r
286 &subKey);\r
287 if (rc!=ERROR_SUCCESS) goto done;\r
288 /* Find the value of the buffer size, malloc, then read it */\r
289 RegQueryValueEx(subKey, NULL, 0, NULL, NULL, &reqdSize);\r
290 if (reqdSize) {\r
291 ppPaths[index] = malloc(reqdSize);\r
292 if (ppPaths[index]) {\r
293 RegQueryValueEx(subKey, NULL, 0, NULL,\r
294 (LPBYTE)ppPaths[index],\r
295 &reqdSize);\r
296 dataSize += reqdSize + 1; /* 1 for the ";" */\r
297 }\r
298 }\r
299 RegCloseKey(subKey);\r
300 }\r
301\r
302 /* return null if no path to return */\r
303 if (dataSize == 0) goto done;\r
304\r
305 /* original datasize from RegQueryInfo doesn't include the \0 */\r
306 dataBuf = malloc((dataSize+1) * sizeof(TCHAR));\r
307 if (dataBuf) {\r
308 TCHAR *szCur = dataBuf;\r
309 DWORD reqdSize = dataSize;\r
310 /* Copy our collected strings */\r
311 for (index=0;index<numKeys;index++) {\r
312 if (index > 0) {\r
313 *(szCur++) = _T(';');\r
314 dataSize--;\r
315 }\r
316 if (ppPaths[index]) {\r
317 Py_ssize_t len = _tcslen(ppPaths[index]);\r
318 _tcsncpy(szCur, ppPaths[index], len);\r
319 szCur += len;\r
320 assert(dataSize > (DWORD)len);\r
321 dataSize -= (DWORD)len;\r
322 }\r
323 }\r
324 if (skipcore)\r
325 *szCur = '\0';\r
326 else {\r
327 /* If we have no values, we dont need a ';' */\r
328 if (numKeys) {\r
329 *(szCur++) = _T(';');\r
330 dataSize--;\r
331 }\r
332 /* Now append the core path entries -\r
333 this will include the NULL\r
334 */\r
335 rc = RegQueryValueEx(newKey, NULL, 0, NULL,\r
336 (LPBYTE)szCur, &dataSize);\r
337 }\r
338 /* And set the result - caller must free\r
339 If MBCS, it is fine as is. If Unicode, allocate new\r
340 buffer and convert.\r
341 */\r
342#ifdef UNICODE\r
343 retval = (char *)malloc(reqdSize+1);\r
344 if (retval)\r
345 WideCharToMultiByte(CP_ACP, 0,\r
346 dataBuf, -1, /* source */\r
347 retval, reqdSize+1, /* dest */\r
348 NULL, NULL);\r
349 free(dataBuf);\r
350#else\r
351 retval = dataBuf;\r
352#endif\r
353 }\r
354done:\r
355 /* Loop freeing my temp buffers */\r
356 if (ppPaths) {\r
357 for(index=0;index<numKeys;index++)\r
358 if (ppPaths[index]) free(ppPaths[index]);\r
359 free(ppPaths);\r
360 }\r
361 if (newKey)\r
362 RegCloseKey(newKey);\r
363 if (keyBuf)\r
364 free(keyBuf);\r
365 return retval;\r
366}\r
367#endif /* Py_ENABLE_SHARED */\r
368#endif /* MS_WINDOWS */\r
369\r
370static void\r
371get_progpath(void)\r
372{\r
373 extern char *Py_GetProgramName(void);\r
374 char *path = getenv("PATH");\r
375 char *prog = Py_GetProgramName();\r
376\r
377#ifdef MS_WINDOWS\r
378 extern HANDLE PyWin_DLLhModule;\r
379#ifdef UNICODE\r
380 WCHAR wprogpath[MAXPATHLEN+1];\r
381 /* Windows documents that GetModuleFileName() will "truncate",\r
382 but makes no mention of the null terminator. Play it safe.\r
383 PLUS Windows itself defines MAX_PATH as the same, but anyway...\r
384 */\r
385#ifdef Py_ENABLE_SHARED\r
386 wprogpath[MAXPATHLEN]=_T('\0');\r
387 if (PyWin_DLLhModule &&\r
388 GetModuleFileName(PyWin_DLLhModule, wprogpath, MAXPATHLEN)) {\r
389 WideCharToMultiByte(CP_ACP, 0,\r
390 wprogpath, -1,\r
391 dllpath, MAXPATHLEN+1,\r
392 NULL, NULL);\r
393 }\r
394#else\r
395 dllpath[0] = 0;\r
396#endif\r
397 wprogpath[MAXPATHLEN]=_T('\0');\r
398 if (GetModuleFileName(NULL, wprogpath, MAXPATHLEN)) {\r
399 WideCharToMultiByte(CP_ACP, 0,\r
400 wprogpath, -1,\r
401 progpath, MAXPATHLEN+1,\r
402 NULL, NULL);\r
403 return;\r
404 }\r
405#else\r
406 /* static init of progpath ensures final char remains \0 */\r
407#ifdef Py_ENABLE_SHARED\r
408 if (PyWin_DLLhModule)\r
409 if (!GetModuleFileName(PyWin_DLLhModule, dllpath, MAXPATHLEN))\r
410 dllpath[0] = 0;\r
411#else\r
412 dllpath[0] = 0;\r
413#endif\r
414 if (GetModuleFileName(NULL, progpath, MAXPATHLEN))\r
415 return;\r
416#endif\r
417#endif\r
418 if (prog == NULL || *prog == '\0')\r
419 prog = "python";\r
420\r
421 /* If there is no slash in the argv0 path, then we have to\r
422 * assume python is on the user's $PATH, since there's no\r
423 * other way to find a directory to start the search from. If\r
424 * $PATH isn't exported, you lose.\r
425 */\r
426#ifdef ALTSEP\r
427 if (strchr(prog, SEP) || strchr(prog, ALTSEP))\r
428#else\r
429 if (strchr(prog, SEP))\r
430#endif\r
431 strncpy(progpath, prog, MAXPATHLEN);\r
432 else if (path) {\r
433 while (1) {\r
434 char *delim = strchr(path, DELIM);\r
435\r
436 if (delim) {\r
437 size_t len = delim - path;\r
438 /* ensure we can't overwrite buffer */\r
439 len = MIN(MAXPATHLEN,len);\r
440 strncpy(progpath, path, len);\r
441 *(progpath + len) = '\0';\r
442 }\r
443 else\r
444 strncpy(progpath, path, MAXPATHLEN);\r
445\r
446 /* join() is safe for MAXPATHLEN+1 size buffer */\r
447 join(progpath, prog);\r
448 if (exists(progpath))\r
449 break;\r
450\r
451 if (!delim) {\r
452 progpath[0] = '\0';\r
453 break;\r
454 }\r
455 path = delim + 1;\r
456 }\r
457 }\r
458 else\r
459 progpath[0] = '\0';\r
460}\r
461\r
462static void\r
463calculate_path(void)\r
464{\r
465 char argv0_path[MAXPATHLEN+1];\r
466 char *buf;\r
467 size_t bufsz;\r
468 char *pythonhome = Py_GetPythonHome();\r
469 char *envpath = Py_GETENV("PYTHONPATH");\r
470\r
471#ifdef MS_WINDOWS\r
472 int skiphome, skipdefault;\r
473 char *machinepath = NULL;\r
474 char *userpath = NULL;\r
475 char zip_path[MAXPATHLEN+1];\r
476 size_t len;\r
477#endif\r
478\r
479 get_progpath();\r
480 /* progpath guaranteed \0 terminated in MAXPATH+1 bytes. */\r
481 strcpy(argv0_path, progpath);\r
482 reduce(argv0_path);\r
483 if (pythonhome == NULL || *pythonhome == '\0') {\r
484 if (search_for_prefix(argv0_path, LANDMARK))\r
485 pythonhome = prefix;\r
486 else\r
487 pythonhome = NULL;\r
488 }\r
489 else\r
490 strncpy(prefix, pythonhome, MAXPATHLEN);\r
491\r
492 if (envpath && *envpath == '\0')\r
493 envpath = NULL;\r
494\r
495\r
496#ifdef MS_WINDOWS\r
497 /* Calculate zip archive path */\r
498 if (dllpath[0]) /* use name of python DLL */\r
499 strncpy(zip_path, dllpath, MAXPATHLEN);\r
500 else /* use name of executable program */\r
501 strncpy(zip_path, progpath, MAXPATHLEN);\r
502 zip_path[MAXPATHLEN] = '\0';\r
503 len = strlen(zip_path);\r
504 if (len > 4) {\r
505 zip_path[len-3] = 'z'; /* change ending to "zip" */\r
506 zip_path[len-2] = 'i';\r
507 zip_path[len-1] = 'p';\r
508 }\r
509 else {\r
510 zip_path[0] = 0;\r
511 }\r
512\r
513 skiphome = pythonhome==NULL ? 0 : 1;\r
514#ifdef Py_ENABLE_SHARED\r
515 machinepath = getpythonregpath(HKEY_LOCAL_MACHINE, skiphome);\r
516 userpath = getpythonregpath(HKEY_CURRENT_USER, skiphome);\r
517#endif\r
518 /* We only use the default relative PYTHONPATH if we havent\r
519 anything better to use! */\r
520 skipdefault = envpath!=NULL || pythonhome!=NULL || \\r
521 machinepath!=NULL || userpath!=NULL;\r
522#endif\r
523\r
524 /* We need to construct a path from the following parts.\r
525 (1) the PYTHONPATH environment variable, if set;\r
526 (2) for Win32, the zip archive file path;\r
527 (3) for Win32, the machinepath and userpath, if set;\r
528 (4) the PYTHONPATH config macro, with the leading "."\r
529 of each component replaced with pythonhome, if set;\r
530 (5) the directory containing the executable (argv0_path).\r
531 The length calculation calculates #4 first.\r
532 Extra rules:\r
533 - If PYTHONHOME is set (in any way) item (3) is ignored.\r
534 - If registry values are used, (4) and (5) are ignored.\r
535 */\r
536\r
537 /* Calculate size of return buffer */\r
538 if (pythonhome != NULL) {\r
539 char *p;\r
540 bufsz = 1;\r
541 for (p = PYTHONPATH; *p; p++) {\r
542 if (*p == DELIM)\r
543 bufsz++; /* number of DELIM plus one */\r
544 }\r
545 bufsz *= strlen(pythonhome);\r
546 }\r
547 else\r
548 bufsz = 0;\r
549 bufsz += strlen(PYTHONPATH) + 1;\r
550 bufsz += strlen(argv0_path) + 1;\r
551#ifdef MS_WINDOWS\r
552 if (userpath)\r
553 bufsz += strlen(userpath) + 1;\r
554 if (machinepath)\r
555 bufsz += strlen(machinepath) + 1;\r
556 bufsz += strlen(zip_path) + 1;\r
557#endif\r
558 if (envpath != NULL)\r
559 bufsz += strlen(envpath) + 1;\r
560\r
561 module_search_path = buf = malloc(bufsz);\r
562 if (buf == NULL) {\r
563 /* We can't exit, so print a warning and limp along */\r
564 fprintf(stderr, "Can't malloc dynamic PYTHONPATH.\n");\r
565 if (envpath) {\r
566 fprintf(stderr, "Using environment $PYTHONPATH.\n");\r
567 module_search_path = envpath;\r
568 }\r
569 else {\r
570 fprintf(stderr, "Using default static path.\n");\r
571 module_search_path = PYTHONPATH;\r
572 }\r
573#ifdef MS_WINDOWS\r
574 if (machinepath)\r
575 free(machinepath);\r
576 if (userpath)\r
577 free(userpath);\r
578#endif /* MS_WINDOWS */\r
579 return;\r
580 }\r
581\r
582 if (envpath) {\r
583 strcpy(buf, envpath);\r
584 buf = strchr(buf, '\0');\r
585 *buf++ = DELIM;\r
586 }\r
587#ifdef MS_WINDOWS\r
588 if (zip_path[0]) {\r
589 strcpy(buf, zip_path);\r
590 buf = strchr(buf, '\0');\r
591 *buf++ = DELIM;\r
592 }\r
593 if (userpath) {\r
594 strcpy(buf, userpath);\r
595 buf = strchr(buf, '\0');\r
596 *buf++ = DELIM;\r
597 free(userpath);\r
598 }\r
599 if (machinepath) {\r
600 strcpy(buf, machinepath);\r
601 buf = strchr(buf, '\0');\r
602 *buf++ = DELIM;\r
603 free(machinepath);\r
604 }\r
605 if (pythonhome == NULL) {\r
606 if (!skipdefault) {\r
607 strcpy(buf, PYTHONPATH);\r
608 buf = strchr(buf, '\0');\r
609 }\r
610 }\r
611#else\r
612 if (pythonhome == NULL) {\r
613 strcpy(buf, PYTHONPATH);\r
614 buf = strchr(buf, '\0');\r
615 }\r
616#endif /* MS_WINDOWS */\r
617 else {\r
618 char *p = PYTHONPATH;\r
619 char *q;\r
620 size_t n;\r
621 for (;;) {\r
622 q = strchr(p, DELIM);\r
623 if (q == NULL)\r
624 n = strlen(p);\r
625 else\r
626 n = q-p;\r
627 if (p[0] == '.' && is_sep(p[1])) {\r
628 strcpy(buf, pythonhome);\r
629 buf = strchr(buf, '\0');\r
630 p++;\r
631 n--;\r
632 }\r
633 strncpy(buf, p, n);\r
634 buf += n;\r
635 if (q == NULL)\r
636 break;\r
637 *buf++ = DELIM;\r
638 p = q+1;\r
639 }\r
640 }\r
641 if (argv0_path) {\r
642 *buf++ = DELIM;\r
643 strcpy(buf, argv0_path);\r
644 buf = strchr(buf, '\0');\r
645 }\r
646 *buf = '\0';\r
647 /* Now to pull one last hack/trick. If sys.prefix is\r
648 empty, then try and find it somewhere on the paths\r
649 we calculated. We scan backwards, as our general policy\r
650 is that Python core directories are at the *end* of\r
651 sys.path. We assume that our "lib" directory is\r
652 on the path, and that our 'prefix' directory is\r
653 the parent of that.\r
654 */\r
655 if (*prefix=='\0') {\r
656 char lookBuf[MAXPATHLEN+1];\r
657 char *look = buf - 1; /* 'buf' is at the end of the buffer */\r
658 while (1) {\r
659 Py_ssize_t nchars;\r
660 char *lookEnd = look;\r
661 /* 'look' will end up one character before the\r
662 start of the path in question - even if this\r
663 is one character before the start of the buffer\r
664 */\r
665 while (look >= module_search_path && *look != DELIM)\r
666 look--;\r
667 nchars = lookEnd-look;\r
668 strncpy(lookBuf, look+1, nchars);\r
669 lookBuf[nchars] = '\0';\r
670 /* Up one level to the parent */\r
671 reduce(lookBuf);\r
672 if (search_for_prefix(lookBuf, LANDMARK)) {\r
673 break;\r
674 }\r
675 /* If we are out of paths to search - give up */\r
676 if (look < module_search_path)\r
677 break;\r
678 look--;\r
679 }\r
680 }\r
681}\r
682\r
683\r
684/* External interface */\r
685\r
686char *\r
687Py_GetPath(void)\r
688{\r
689 if (!module_search_path)\r
690 calculate_path();\r
691 return module_search_path;\r
692}\r
693\r
694char *\r
695Py_GetPrefix(void)\r
696{\r
697 if (!module_search_path)\r
698 calculate_path();\r
699 return prefix;\r
700}\r
701\r
702char *\r
703Py_GetExecPrefix(void)\r
704{\r
705 return Py_GetPrefix();\r
706}\r
707\r
708char *\r
709Py_GetProgramFullPath(void)\r
710{\r
711 if (!module_search_path)\r
712 calculate_path();\r
713 return progpath;\r
714}\r