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