]> git.proxmox.com Git - mirror_edk2.git/blame - AppPkg/Applications/Python/Efi/getpath.c
EmbeddedPkg: Extend NvVarStoreFormattedLib LIBRARY_CLASS
[mirror_edk2.git] / AppPkg / Applications / Python / Efi / getpath.c
CommitLineData
41b152c5 1/** @file\r
2 Return the initial module search path.\r
3\r
4 Search in specified locations for the associated Python libraries.\r
5\r
6 Py_GetPath returns module_search_path.\r
7 Py_GetPrefix returns PREFIX\r
8 Py_GetExec_Prefix returns PREFIX\r
9 Py_GetProgramFullPath returns the full path to the python executable.\r
10\r
11 These are built dynamically so that the proper volume name can be prefixed\r
12 to the paths.\r
13\r
14 For the EDK II, UEFI, implementation of Python, PREFIX and EXEC_PREFIX\r
15 are set as follows:\r
16 PREFIX = /Efi/StdLib\r
17 EXEC_PREFIX = PREFIX\r
18\r
19 The following final paths are assumed:\r
20 /Efi/Tools/Python.efi The Python executable.\r
21 /Efi/StdLib/lib/python.VERSION The platform independent Python modules.\r
22 /Efi/StdLib/lib/python.VERSION/dynalib Dynamically loadable Python extension modules.\r
23\r
521527e0 24 Copyright (c) 2011 - 2012, Intel Corporation. All rights reserved.<BR>\r
bcb96695 25 SPDX-License-Identifier: BSD-2-Clause-Patent\r
41b152c5 26**/\r
27#include <Python.h>\r
28#include <osdefs.h>\r
b410d6e4 29#include <ctype.h>\r
41b152c5 30\r
31#ifdef __cplusplus\r
32 extern "C" {\r
33#endif\r
34\r
35/* VERSION must be at least two characters long. */\r
36#ifndef VERSION\r
37 #define VERSION "27"\r
38#endif\r
39\r
40#ifndef VPATH\r
41 #define VPATH "."\r
42#endif\r
43\r
44/* Search path entry delimiter */\r
45#ifdef DELIM\r
46 #define sDELIM ";"\r
47#endif\r
48\r
49#ifndef PREFIX\r
50 #define PREFIX "/Efi/StdLib"\r
51#endif\r
52\r
53#ifndef EXEC_PREFIX\r
54 #define EXEC_PREFIX PREFIX\r
55#endif\r
56\r
57#ifndef LIBPYTHON\r
58 #define LIBPYTHON "lib/python." VERSION\r
59#endif\r
60\r
61#ifndef PYTHONPATH\r
521527e0 62 #ifdef HAVE_ENVIRONMENT_OPS\r
63 #define PYTHONPATH PREFIX LIBPYTHON sDELIM \\r
64 EXEC_PREFIX LIBPYTHON "/lib-dynload"\r
65 #else\r
66 #define PYTHONPATH LIBPYTHON\r
67 #endif\r
41b152c5 68#endif\r
69\r
70#ifndef LANDMARK\r
71#define LANDMARK "os.py"\r
72#endif\r
73\r
74static char prefix[MAXPATHLEN+1];\r
75static char exec_prefix[MAXPATHLEN+1];\r
76static char progpath[MAXPATHLEN+1];\r
77static char *module_search_path = NULL;\r
78static char lib_python[] = LIBPYTHON;\r
79static char volume_name[32] = { 0 };\r
80\r
81/** Determine if "ch" is a separator character.\r
82\r
83 @param[in] ch The character to test.\r
84\r
85 @retval TRUE ch is a separator character.\r
86 @retval FALSE ch is NOT a separator character.\r
87**/\r
88static int\r
89is_sep(char ch)\r
90{\r
91#ifdef ALTSEP\r
92 return ch == SEP || ch == ALTSEP;\r
93#else\r
94 return ch == SEP;\r
95#endif\r
96}\r
97\r
98/** Reduce a path by its last element.\r
99\r
100 The last element (everything to the right of the last separator character)\r
101 in the path, dir, is removed from the path. Parameter dir is modified in place.\r
102\r
103 @param[in,out] dir Pointer to the path to modify.\r
104**/\r
105static void\r
106reduce(char *dir)\r
107{\r
108 size_t i = strlen(dir);\r
109 while (i > 0 && !is_sep(dir[i]))\r
110 --i;\r
111 dir[i] = '\0';\r
112}\r
113\r
521527e0 114#ifndef UEFI_C_SOURCE\r
41b152c5 115/** Does filename point to a file and not directory?\r
116\r
117 @param[in] filename The fully qualified path to the object to test.\r
118\r
119 @retval 0 Filename was not found, or is a directory.\r
120 @retval 1 Filename refers to a regular file.\r
121**/\r
122static int\r
123isfile(char *filename)\r
124{\r
125 struct stat buf;\r
126 if (stat(filename, &buf) != 0) {\r
41b152c5 127 return 0;\r
128 }\r
129 //if (!S_ISREG(buf.st_mode))\r
130 if (S_ISDIR(buf.st_mode)) {\r
41b152c5 131 return 0;\r
132 }\r
41b152c5 133 return 1;\r
134}\r
135\r
136/** Determine if filename refers to a Python module.\r
137\r
138 A Python module is indicated if the file exists, or if the file with\r
139 'o' or 'c' appended exists.\r
140\r
141 @param[in] filename The fully qualified path to the object to test.\r
142\r
143 @retval 0\r
144**/\r
145static int\r
146ismodule(char *filename)\r
147{\r
148 if (isfile(filename)) {\r
149 //if (Py_VerboseFlag) PySys_WriteStderr("%s[%d]: file = \"%s\"\n", __func__, __LINE__, filename);\r
150 return 1;\r
151 }\r
152\r
153 /* Check for the compiled version of prefix. */\r
154 if (strlen(filename) < MAXPATHLEN) {\r
155 strcat(filename, Py_OptimizeFlag ? "o" : "c");\r
156 if (isfile(filename)) {\r
41b152c5 157 return 1;\r
158 }\r
159 }\r
41b152c5 160 return 0;\r
161}\r
162\r
163/** Does filename point to a directory?\r
164\r
165 @param[in] filename The fully qualified path to the object to test.\r
166\r
167 @retval 0 Filename was not found, or is not a regular file.\r
168 @retval 1 Filename refers to a directory.\r
169**/\r
170static int\r
171isdir(char *filename)\r
172{\r
173 struct stat buf;\r
174\r
175 if (stat(filename, &buf) != 0)\r
176 return 0;\r
177\r
178 if (!S_ISDIR(buf.st_mode))\r
179 return 0;\r
180\r
181 return 1;\r
182}\r
521527e0 183#endif /* UEFI_C_SOURCE */\r
41b152c5 184\r
185/** Determine if a path is absolute, or not.\r
186 An absolute path consists of a volume name, "VOL:", followed by a rooted path,\r
187 "/path/elements". If both of these components are present, the path is absolute.\r
188\r
189 Let P be a pointer to the path to test.\r
190 Let A be a pointer to the first ':' in P.\r
191 Let B be a pointer to the first '/' or '\\' in P.\r
192\r
193 If A and B are not NULL\r
194 If (A-P+1) == (B-P) then the path is absolute.\r
195 Otherwise, the path is NOT absolute.\r
196\r
197 @param[in] path The path to test.\r
198\r
199 @retval -1 Path is absolute but lacking volume name.\r
200 @retval 0 Path is NOT absolute.\r
201 @retval 1 Path is absolute.\r
202*/\r
203static int\r
204is_absolute(char *path)\r
205{\r
206 char *A;\r
207 char *B;\r
208\r
209 A = strchr(path, ':');\r
210 B = strpbrk(path, "/\\");\r
211\r
212 if(B != NULL) {\r
213 if(A == NULL) {\r
214 if(B == path) {\r
215 return -1;\r
216 }\r
217 }\r
218 else {\r
219 if(((A - path) + 1) == (B - path)) {\r
220 return 1;\r
221 }\r
222 }\r
223 }\r
224 return 0;\r
225}\r
226\r
227\r
228/** Add a path component, by appending stuff to buffer.\r
229 buffer must have at least MAXPATHLEN + 1 bytes allocated, and contain a\r
230 NUL-terminated string with no more than MAXPATHLEN characters (not counting\r
231 the trailing NUL). It's a fatal error if it contains a string longer than\r
232 that (callers must be careful!). If these requirements are met, it's\r
233 guaranteed that buffer will still be a NUL-terminated string with no more\r
234 than MAXPATHLEN characters at exit. If stuff is too long, only as much of\r
235 stuff as fits will be appended.\r
236\r
237 @param[in,out] buffer The path to be extended.\r
238 @param[in] stuff The stuff to join onto the path.\r
239*/\r
240static void\r
241joinpath(char *buffer, char *stuff)\r
242{\r
243 size_t n, k;\r
244\r
245 k = 0;\r
246 if (is_absolute(stuff) == 1) {\r
247 n = 0;\r
248 }\r
249 else {\r
250 n = strlen(buffer);\r
251 if(n == 0) {\r
252 strncpy(buffer, volume_name, MAXPATHLEN);\r
253 n = strlen(buffer);\r
254 }\r
255 /* We must not use an else clause here because we want to test n again.\r
256 volume_name may have been empty.\r
257 */\r
258 if (n > 0 && n < MAXPATHLEN) {\r
259 if(!is_sep(buffer[n-1])) {\r
260 buffer[n++] = SEP;\r
261 }\r
262 if(is_sep(stuff[0])) ++stuff;\r
263 }\r
264 }\r
265 if (n > MAXPATHLEN)\r
266 Py_FatalError("buffer overflow in getpath.c's joinpath()");\r
267 k = strlen(stuff);\r
268 if (n + k > MAXPATHLEN)\r
269 k = MAXPATHLEN - n;\r
270 strncpy(buffer+n, stuff, k);\r
271 buffer[n+k] = '\0';\r
272}\r
273\r
274/** Is filename an executable file?\r
275\r
276 An executable file:\r
277 1) exists\r
278 2) is a file, not a directory\r
279 3) has a name ending with ".efi"\r
280 4) Only has a single '.' in the name.\r
281\r
282 If basename(filename) does not contain a '.', append ".efi" to filename\r
283 If filename ends in ".efi", it is executable, else it isn't.\r
284\r
285 This routine is used to when searching for the file named by argv[0].\r
286 As such, there is no need to search for extensions other than ".efi".\r
287\r
288 @param[in] filename The name of the file to test. It may, or may not, have an extension.\r
289\r
290 @retval 0 filename already has a path other than ".efi", or it doesn't exist, or is a directory.\r
291 @retval 1 filename refers to an executable file.\r
292**/\r
293static int\r
294isxfile(char *filename)\r
295{\r
296 struct stat buf;\r
297 char *bn;\r
298 char *newbn;\r
299 int bnlen;\r
300\r
41b152c5 301 bn = basename(filename); // Separate off the file name component\r
302 reduce(filename); // and isolate the path component\r
303 bnlen = strlen(bn);\r
304 newbn = strrchr(bn, '.'); // Does basename contain a period?\r
305 if(newbn == NULL) { // Does NOT contain a period.\r
306 newbn = &bn[bnlen];\r
307 strncpyX(newbn, ".efi", MAXPATHLEN - bnlen); // append ".efi" to basename\r
308 bnlen += 4;\r
309 }\r
310 else if(strcmp(newbn, ".efi") != 0) {\r
41b152c5 311 return 0; // File can not be executable.\r
312 }\r
313 joinpath(filename, bn); // Stitch path and file name back together\r
41b152c5 314\r
315 if (stat(filename, &buf) != 0) { // Now, verify that file exists\r
41b152c5 316 return 0;\r
317 }\r
318 if(S_ISDIR(buf.st_mode)) { // And it is not a directory.\r
41b152c5 319 return 0;\r
320 }\r
321\r
41b152c5 322 return 1;\r
323}\r
324\r
325/** Copy p into path, ensuring that the result is an absolute path.\r
326\r
327 copy_absolute requires that path be allocated at least\r
328 MAXPATHLEN + 1 bytes and that p be no more than MAXPATHLEN bytes.\r
329\r
330 @param[out] path Destination to receive the absolute path.\r
331 @param[in] p Path to be tested and possibly converted.\r
332**/\r
333static void\r
334copy_absolute(char *path, char *p)\r
335{\r
336 if (is_absolute(p) == 1)\r
337 strcpy(path, p);\r
338 else {\r
339 if (!getcwd(path, MAXPATHLEN)) {\r
340 /* unable to get the current directory */\r
341 if(volume_name[0] != 0) {\r
342 strcpy(path, volume_name);\r
343 joinpath(path, p);\r
344 }\r
345 else\r
346 strcpy(path, p);\r
347 return;\r
348 }\r
349 if (p[0] == '.' && is_sep(p[1]))\r
350 p += 2;\r
351 joinpath(path, p);\r
352 }\r
353}\r
354\r
355/** Modify path so that the result is an absolute path.\r
356 absolutize() requires that path be allocated at least MAXPATHLEN+1 bytes.\r
357\r
358 @param[in,out] path The path to be made absolute.\r
359*/\r
360static void\r
361absolutize(char *path)\r
362{\r
363 char buffer[MAXPATHLEN + 1];\r
364\r
365 if (is_absolute(path) == 1)\r
366 return;\r
367 copy_absolute(buffer, path);\r
368 strcpy(path, buffer);\r
369}\r
370\r
371/** Extract the volume name from a path.\r
372\r
373 @param[out] Dest Pointer to location in which to store the extracted volume name.\r
374 @param[in] path Pointer to the path to extract the volume name from.\r
375**/\r
376static void\r
377set_volume(char *Dest, char *path)\r
378{\r
379 size_t VolLen;\r
380\r
41b152c5 381 if(is_absolute(path)) {\r
382 VolLen = strcspn(path, "/\\:");\r
41b152c5 383 if((VolLen != 0) && (path[VolLen] == ':')) {\r
384 (void) strncpyX(Dest, path, VolLen + 1);\r
41b152c5 385 }\r
386 }\r
41b152c5 387}\r
388\r
389\r
390/** Determine paths.\r
391\r
392 Two directories must be found, the platform independent directory\r
393 (prefix), containing the common .py and .pyc files, and the platform\r
394 dependent directory (exec_prefix), containing the shared library\r
395 modules. Note that prefix and exec_prefix are the same directory\r
396 for UEFI installations.\r
397\r
398 Separate searches are carried out for prefix and exec_prefix.\r
399 Each search tries a number of different locations until a ``landmark''\r
400 file or directory is found. If no prefix or exec_prefix is found, a\r
401 warning message is issued and the preprocessor defined PREFIX and\r
402 EXEC_PREFIX are used (even though they may not work); python carries on\r
403 as best as is possible, but some imports may fail.\r
404\r
405 Before any searches are done, the location of the executable is\r
406 determined. If argv[0] has one or more slashes in it, it is used\r
407 unchanged. Otherwise, it must have been invoked from the shell's path,\r
408 so we search %PATH% for the named executable and use that. If the\r
409 executable was not found on %PATH% (or there was no %PATH% environment\r
410 variable), the original argv[0] string is used.\r
411\r
412 Finally, argv0_path is set to the directory containing the executable\r
413 (i.e. the last component is stripped).\r
414\r
415 With argv0_path in hand, we perform a number of steps. The same steps\r
416 are performed for prefix and for exec_prefix, but with a different\r
417 landmark.\r
418\r
419 The prefix landmark will always be lib/python.VERSION/os.py and the\r
420 exec_prefix will always be lib/python.VERSION/dynaload, where VERSION\r
421 is Python's version number as defined at the beginning of this file.\r
422\r
423 First. See if the %PYTHONHOME% environment variable points to the\r
424 installed location of the Python libraries. If %PYTHONHOME% is set, then\r
425 it points to prefix and exec_prefix. %PYTHONHOME% can be a single\r
426 directory, which is used for both, or the prefix and exec_prefix\r
427 directories separated by the DELIM character.\r
428\r
429 Next. Search the directories pointed to by the preprocessor variables\r
430 PREFIX and EXEC_PREFIX. These paths are prefixed with the volume name\r
431 extracted from argv0_path. The volume names correspond to the UEFI\r
432 shell "map" names.\r
433\r
434 That's it!\r
435\r
436 Well, almost. Once we have determined prefix and exec_prefix, the\r
437 preprocessor variable PYTHONPATH is used to construct a path. Each\r
438 relative path on PYTHONPATH is prefixed with prefix. Then the directory\r
439 containing the shared library modules is appended. The environment\r
440 variable $PYTHONPATH is inserted in front of it all. Finally, the\r
441 prefix and exec_prefix globals are tweaked so they reflect the values\r
442 expected by other code, by stripping the "lib/python$VERSION/..." stuff\r
443 off. This seems to make more sense given that currently the only\r
444 known use of sys.prefix and sys.exec_prefix is for the ILU installation\r
445 process to find the installed Python tree.\r
446\r
447 The final, fully resolved, paths should look something like:\r
448 fs0:/Efi/Tools/python.efi\r
449 fs0:/Efi/StdLib/lib/python27\r
450 fs0:/Efi/StdLib/lib/python27/dynaload\r
451\r
452**/\r
453static void\r
454calculate_path(void)\r
455{\r
456 extern char *Py_GetProgramName(void);\r
457\r
458 static char delimiter[2] = {DELIM, '\0'};\r
459 static char separator[2] = {SEP, '\0'};\r
460 char *pythonpath = PYTHONPATH;\r
461 char *rtpypath = Py_GETENV("PYTHONPATH");\r
462 //char *home = Py_GetPythonHome();\r
463 char *path = getenv("PATH");\r
464 char *prog = Py_GetProgramName();\r
465 char argv0_path[MAXPATHLEN+1];\r
466 char zip_path[MAXPATHLEN+1];\r
41b152c5 467 char *buf;\r
468 size_t bufsz;\r
469 size_t prefixsz;\r
470 char *defpath;\r
41b152c5 471\r
472\r
473/* ###########################################################################\r
474 Determine path to the Python.efi binary.\r
475 Produces progpath, argv0_path, and volume_name.\r
476########################################################################### */\r
477\r
478 /* If there is no slash in the argv0 path, then we have to\r
479 * assume python is on the user's $PATH, since there's no\r
480 * other way to find a directory to start the search from. If\r
481 * $PATH isn't exported, you lose.\r
482 */\r
483 if (strchr(prog, SEP))\r
484 strncpy(progpath, prog, MAXPATHLEN);\r
485 else if (path) {\r
486 while (1) {\r
487 char *delim = strchr(path, DELIM);\r
488\r
489 if (delim) {\r
490 size_t len = delim - path;\r
491 if (len > MAXPATHLEN)\r
492 len = MAXPATHLEN;\r
493 strncpy(progpath, path, len);\r
494 *(progpath + len) = '\0';\r
495 }\r
496 else\r
497 strncpy(progpath, path, MAXPATHLEN);\r
498\r
499 joinpath(progpath, prog);\r
41b152c5 500 if (isxfile(progpath))\r
501 break;\r
502\r
503 if (!delim) {\r
504 progpath[0] = '\0';\r
505 break;\r
506 }\r
507 path = delim + 1;\r
508 }\r
509 }\r
510 else\r
511 progpath[0] = '\0';\r
512 if ( (!is_absolute(progpath)) && (progpath[0] != '\0') )\r
513 absolutize(progpath);\r
514 strncpy(argv0_path, progpath, MAXPATHLEN);\r
515 argv0_path[MAXPATHLEN] = '\0';\r
516 set_volume(volume_name, argv0_path);\r
517\r
41b152c5 518 reduce(argv0_path);\r
41b152c5 519 /* At this point, argv0_path is guaranteed to be less than\r
520 MAXPATHLEN bytes long.\r
521 */\r
522\r
523/* ###########################################################################\r
524 Build the FULL prefix string, including volume name.\r
525 This is the full path to the platform independent libraries.\r
526########################################################################### */\r
527\r
41b152c5 528 strncpy(prefix, volume_name, MAXPATHLEN);\r
529 joinpath(prefix, PREFIX);\r
530 joinpath(prefix, lib_python);\r
41b152c5 531\r
532/* ###########################################################################\r
533 Build the FULL path to the zipped-up Python library.\r
534########################################################################### */\r
535\r
536 strncpy(zip_path, prefix, MAXPATHLEN);\r
537 zip_path[MAXPATHLEN] = '\0';\r
b410d6e4 538 reduce(zip_path);\r
41b152c5 539 joinpath(zip_path, "python00.zip");\r
540 bufsz = strlen(zip_path); /* Replace "00" with version */\r
541 zip_path[bufsz - 6] = VERSION[0];\r
542 zip_path[bufsz - 5] = VERSION[1];\r
41b152c5 543\r
544/* ###########################################################################\r
545 Build the FULL path to dynamically loadable libraries.\r
546########################################################################### */\r
547\r
41b152c5 548 strncpy(exec_prefix, volume_name, MAXPATHLEN);\r
549 joinpath(exec_prefix, EXEC_PREFIX);\r
550 joinpath(exec_prefix, lib_python);\r
b410d6e4 551 joinpath(exec_prefix, "lib-dynload");\r
41b152c5 552\r
553/* ###########################################################################\r
554 Build the module search path.\r
555########################################################################### */\r
556\r
557 /* Reduce prefix and exec_prefix to their essence,\r
558 * e.g. /usr/local/lib/python1.5 is reduced to /usr/local.\r
559 * If we're loading relative to the build directory,\r
560 * return the compiled-in defaults instead.\r
561 */\r
41b152c5 562 reduce(prefix);\r
563 reduce(prefix);\r
564 /* The prefix is the root directory, but reduce() chopped\r
565 * off the "/". */\r
566 if (!prefix[0]) {\r
567 strcpy(prefix, volume_name);\r
568 }\r
569 bufsz = strlen(prefix);\r
570 if(prefix[bufsz-1] == ':') {\r
571 prefix[bufsz] = SEP;\r
572 prefix[bufsz+1] = 0;\r
573 }\r
41b152c5 574\r
575 /* Calculate size of return buffer.\r
576 */\r
577 defpath = pythonpath;\r
578 bufsz = 0;\r
579\r
580 if (rtpypath)\r
581 bufsz += strlen(rtpypath) + 1;\r
582\r
583 prefixsz = strlen(prefix) + 1;\r
584\r
585 while (1) {\r
586 char *delim = strchr(defpath, DELIM);\r
587\r
588 if (is_absolute(defpath) == 0)\r
589 /* Paths are relative to prefix */\r
590 bufsz += prefixsz;\r
591\r
592 if (delim)\r
593 bufsz += delim - defpath + 1;\r
594 else {\r
595 bufsz += strlen(defpath) + 1;\r
596 break;\r
597 }\r
598 defpath = delim + 1;\r
599 }\r
41b152c5 600\r
601 bufsz += strlen(zip_path) + 1;\r
602 bufsz += strlen(exec_prefix) + 1;\r
603\r
604 /* This is the only malloc call in this file */\r
605 buf = (char *)PyMem_Malloc(bufsz);\r
606\r
607 if (buf == NULL) {\r
608 /* We can't exit, so print a warning and limp along */\r
609 fprintf(stderr, "Not enough memory for dynamic PYTHONPATH.\n");\r
610 fprintf(stderr, "Using default static PYTHONPATH.\n");\r
611 module_search_path = PYTHONPATH;\r
612 }\r
613 else {\r
41b152c5 614 /* Run-time value of $PYTHONPATH goes first */\r
615 if (rtpypath) {\r
616 strcpy(buf, rtpypath);\r
617 strcat(buf, delimiter);\r
618 }\r
619 else\r
620 buf[0] = '\0';\r
41b152c5 621\r
622 /* Next is the default zip path */\r
623 strcat(buf, zip_path);\r
624 strcat(buf, delimiter);\r
41b152c5 625\r
626 /* Next goes merge of compile-time $PYTHONPATH with\r
627 * dynamically located prefix.\r
628 */\r
629 defpath = pythonpath;\r
630 while (1) {\r
631 char *delim = strchr(defpath, DELIM);\r
632\r
633 if (is_absolute(defpath) != 1) {\r
634 strcat(buf, prefix);\r
635 strcat(buf, separator);\r
636 }\r
637\r
638 if (delim) {\r
639 size_t len = delim - defpath + 1;\r
640 size_t end = strlen(buf) + len;\r
641 strncat(buf, defpath, len);\r
642 *(buf + end) = '\0';\r
643 }\r
644 else {\r
645 strcat(buf, defpath);\r
646 break;\r
647 }\r
648 defpath = delim + 1;\r
649 }\r
650 strcat(buf, delimiter);\r
41b152c5 651\r
652 /* Finally, on goes the directory for dynamic-load modules */\r
653 strcat(buf, exec_prefix);\r
654\r
655 /* And publish the results */\r
656 module_search_path = buf;\r
41b152c5 657 }\r
41b152c5 658 /* At this point, exec_prefix is set to VOL:/Efi/StdLib/lib/python.27/dynalib.\r
659 We want to get back to the root value, so we have to remove the final three\r
660 segments to get VOL:/Efi/StdLib. Because we don't know what VOL is, and\r
661 EXEC_PREFIX is also indeterminate, we just remove the three final segments.\r
662 */\r
663 reduce(exec_prefix);\r
664 reduce(exec_prefix);\r
665 reduce(exec_prefix);\r
666 if (!exec_prefix[0]) {\r
667 strcpy(exec_prefix, volume_name);\r
668 }\r
669 bufsz = strlen(exec_prefix);\r
670 if(exec_prefix[bufsz-1] == ':') {\r
671 exec_prefix[bufsz] = SEP;\r
672 exec_prefix[bufsz+1] = 0;\r
673 }\r
41b152c5 674 if (Py_VerboseFlag) PySys_WriteStderr("%s[%d]: module_search_path = \"%s\"\n", __func__, __LINE__, module_search_path);\r
675 if (Py_VerboseFlag) PySys_WriteStderr("%s[%d]: prefix = \"%s\"\n", __func__, __LINE__, prefix);\r
676 if (Py_VerboseFlag) PySys_WriteStderr("%s[%d]: exec_prefix = \"%s\"\n", __func__, __LINE__, exec_prefix);\r
677 if (Py_VerboseFlag) PySys_WriteStderr("%s[%d]: progpath = \"%s\"\n", __func__, __LINE__, progpath);\r
678}\r
679\r
680\r
681/* External interface */\r
682\r
683char *\r
684Py_GetPath(void)\r
685{\r
686 if (!module_search_path)\r
687 calculate_path();\r
688 return module_search_path;\r
689}\r
690\r
691char *\r
692Py_GetPrefix(void)\r
693{\r
694 if (!module_search_path)\r
695 calculate_path();\r
696 return prefix;\r
697}\r
698\r
699char *\r
700Py_GetExecPrefix(void)\r
701{\r
702 if (!module_search_path)\r
703 calculate_path();\r
704 return exec_prefix;\r
705}\r
706\r
707char *\r
708Py_GetProgramFullPath(void)\r
709{\r
710 if (!module_search_path)\r
711 calculate_path();\r
712 return progpath;\r
713}\r
714\r
715\r
716#ifdef __cplusplus\r
717}\r
718#endif\r
719\r