]>
Commit | Line | Data |
---|---|---|
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 | |
86 | static char prefix[MAXPATHLEN+1];\r | |
87 | static char exec_prefix[MAXPATHLEN+1];\r | |
88 | static char progpath[MAXPATHLEN+1];\r | |
89 | static char *module_search_path = NULL;\r | |
90 | static char lib_python[] = LIBPYTHON;\r | |
91 | static 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 | |
100 | static int\r | |
101 | is_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 | |
113 | static void\r | |
114 | reduce(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 | |
140 | static int\r | |
141 | is_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 | |
177 | static void\r | |
178 | joinpath(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 | |
230 | static int\r | |
231 | isxfile(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 | |
270 | static void\r | |
271 | copy_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 | |
297 | static void\r | |
298 | absolutize(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 | |
313 | static void\r | |
314 | set_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 | |
390 | static void\r | |
391 | calculate_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 | |
620 | char *\r | |
621 | Py_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 | |
628 | char *\r | |
629 | Py_GetPrefix(void)\r | |
630 | {\r | |
631 | if (!module_search_path)\r | |
632 | calculate_path();\r | |
633 | return prefix;\r | |
634 | }\r | |
635 | \r | |
636 | char *\r | |
637 | Py_GetExecPrefix(void)\r | |
638 | {\r | |
639 | if (!module_search_path)\r | |
640 | calculate_path();\r | |
641 | return exec_prefix;\r | |
642 | }\r | |
643 | \r | |
644 | char *\r | |
645 | Py_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 |