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