ยปCore Development>Code coverage>PC/os2emx/getpathp.c

Python code coverage for PC/os2emx/getpathp.c

#countcontent
1n/a
2n/a/* Return the initial module search path. */
3n/a/* This version used by OS/2+EMX */
4n/a
5n/a/* ----------------------------------------------------------------
6n/a PATH RULES FOR OS/2+EMX:
7n/a This describes how sys.path is formed on OS/2+EMX. It describes the
8n/a functionality, not the implementation (ie, the order in which these
9n/a are actually fetched is different)
10n/a
11n/a * Python always adds an empty entry at the start, which corresponds
12n/a to the current directory.
13n/a
14n/a * If the PYTHONPATH env. var. exists, its entries are added next.
15n/a
16n/a * We attempt to locate the "Python Home" - if the PYTHONHOME env var
17n/a is set, we believe it. Otherwise, we use the path of our host .EXE's
18n/a to try and locate our "landmark" (lib\\os.py) and deduce our home.
19n/a - If we DO have a Python Home: The relevant sub-directories (Lib,
20n/a plat-win, etc) are based on the Python Home
21n/a - If we DO NOT have a Python Home, the core Python Path is
22n/a loaded from the registry. This is the main PythonPath key,
23n/a and both HKLM and HKCU are combined to form the path)
24n/a
25n/a * Iff - we can not locate the Python Home, and have not had a PYTHONPATH
26n/a specified (ie, we have _nothing_ we can assume is a good path), a
27n/a default path with relative entries is used (eg. .\Lib;.\plat-win, etc)
28n/a
29n/a
30n/a The end result of all this is:
31n/a * When running python.exe, or any other .exe in the main Python directory
32n/a (either an installed version, or directly from the PCbuild directory),
33n/a the core path is deduced.
34n/a
35n/a * When Python is hosted in another exe (different directory, embedded via
36n/a COM, etc), the Python Home will not be deduced, so the core path from
37n/a the registry is used. Other "application paths "in the registry are
38n/a always read.
39n/a
40n/a * If Python can't find its home and there is no registry (eg, frozen
41n/a exe, some very strange installation setup) you get a path with
42n/a some default, but relative, paths.
43n/a
44n/a ---------------------------------------------------------------- */
45n/a
46n/a
47n/a#include "Python.h"
48n/a#include "osdefs.h"
49n/a
50n/a#ifndef PYOS_OS2
51n/a#error This file only compilable on OS/2
52n/a#endif
53n/a
54n/a#define INCL_DOS
55n/a#include <os2.h>
56n/a
57n/a#include <sys/types.h>
58n/a#include <sys/stat.h>
59n/a#include <string.h>
60n/a
61n/a#if HAVE_UNISTD_H
62n/a#include <unistd.h>
63n/a#endif /* HAVE_UNISTD_H */
64n/a
65n/a/* Search in some common locations for the associated Python libraries.
66n/a *
67n/a * Py_GetPath() tries to return a sensible Python module search path.
68n/a *
69n/a * The approach is an adaptation for Windows of the strategy used in
70n/a * ../Modules/getpath.c; it uses the Windows Registry as one of its
71n/a * information sources.
72n/a */
73n/a
74n/a#ifndef LANDMARK
75n/a#if defined(PYCC_GCC)
76n/a#define LANDMARK "lib/os.py"
77n/a#else
78n/a#define LANDMARK "lib\\os.py"
79n/a#endif
80n/a#endif
81n/a
82n/astatic char prefix[MAXPATHLEN+1];
83n/astatic char progpath[MAXPATHLEN+1];
84n/astatic char *module_search_path = NULL;
85n/a
86n/a
87n/astatic int
88n/ais_sep(char ch) /* determine if "ch" is a separator character */
89n/a{
90n/a#ifdef ALTSEP
91n/a return ch == SEP || ch == ALTSEP;
92n/a#else
93n/a return ch == SEP;
94n/a#endif
95n/a}
96n/a
97n/a/* assumes 'dir' null terminated in bounds.
98n/a * Never writes beyond existing terminator.
99n/a */
100n/astatic void
101n/areduce(char *dir)
102n/a{
103n/a size_t i = strlen(dir);
104n/a while (i > 0 && !is_sep(dir[i]))
105n/a --i;
106n/a dir[i] = '\0';
107n/a}
108n/a
109n/astatic int
110n/aexists(char *filename)
111n/a{
112n/a struct stat buf;
113n/a return stat(filename, &buf) == 0;
114n/a}
115n/a
116n/a/* Is module (check for .pyc/.pyo too)
117n/a * Assumes 'filename' MAXPATHLEN+1 bytes long -
118n/a * may extend 'filename' by one character.
119n/a */
120n/astatic int
121n/aismodule(char *filename)
122n/a{
123n/a if (exists(filename))
124n/a return 1;
125n/a
126n/a /* Check for the compiled version of prefix. */
127n/a if (strlen(filename) < MAXPATHLEN) {
128n/a strcat(filename, Py_OptimizeFlag ? "o" : "c");
129n/a if (exists(filename))
130n/a return 1;
131n/a }
132n/a return 0;
133n/a}
134n/a
135n/a/* Add a path component, by appending stuff to buffer.
136n/a buffer must have at least MAXPATHLEN + 1 bytes allocated, and contain a
137n/a NUL-terminated string with no more than MAXPATHLEN characters (not counting
138n/a the trailing NUL). It's a fatal error if it contains a string longer than
139n/a that (callers must be careful!). If these requirements are met, it's
140n/a guaranteed that buffer will still be a NUL-terminated string with no more
141n/a than MAXPATHLEN characters at exit. If stuff is too long, only as much of
142n/a stuff as fits will be appended.
143n/a*/
144n/a
145n/astatic void
146n/ajoin(char *buffer, char *stuff)
147n/a{
148n/a size_t n, k;
149n/a if (is_sep(stuff[0]))
150n/a n = 0;
151n/a else {
152n/a n = strlen(buffer);
153n/a if (n > 0 && !is_sep(buffer[n-1]) && n < MAXPATHLEN)
154n/a buffer[n++] = SEP;
155n/a }
156n/a if (n > MAXPATHLEN)
157n/a Py_FatalError("buffer overflow in getpathp.c's joinpath()");
158n/a k = strlen(stuff);
159n/a if (n + k > MAXPATHLEN)
160n/a k = MAXPATHLEN - n;
161n/a strncpy(buffer+n, stuff, k);
162n/a buffer[n+k] = '\0';
163n/a}
164n/a
165n/a/* gotlandmark only called by search_for_prefix, which ensures
166n/a * 'prefix' is null terminated in bounds. join() ensures
167n/a * 'landmark' can not overflow prefix if too long.
168n/a */
169n/astatic int
170n/agotlandmark(char *landmark)
171n/a{
172n/a int n, ok;
173n/a
174n/a n = strlen(prefix);
175n/a join(prefix, landmark);
176n/a ok = ismodule(prefix);
177n/a prefix[n] = '\0';
178n/a return ok;
179n/a}
180n/a
181n/a/* assumes argv0_path is MAXPATHLEN+1 bytes long, already \0 term'd.
182n/a * assumption provided by only caller, calculate_path()
183n/a */
184n/astatic int
185n/asearch_for_prefix(char *argv0_path, char *landmark)
186n/a{
187n/a /* Search from argv0_path, until landmark is found */
188n/a strcpy(prefix, argv0_path);
189n/a do {
190n/a if (gotlandmark(landmark))
191n/a return 1;
192n/a reduce(prefix);
193n/a } while (prefix[0]);
194n/a return 0;
195n/a}
196n/a
197n/a
198n/astatic void
199n/aget_progpath(void)
200n/a{
201n/a extern char *Py_GetProgramName(void);
202n/a char *path = getenv("PATH");
203n/a char *prog = Py_GetProgramName();
204n/a
205n/a PPIB pib;
206n/a if ((DosGetInfoBlocks(NULL, &pib) == 0) &&
207n/a (DosQueryModuleName(pib->pib_hmte, sizeof(progpath), progpath) == 0))
208n/a return;
209n/a
210n/a if (prog == NULL || *prog == '\0')
211n/a prog = "python";
212n/a
213n/a /* If there is no slash in the argv0 path, then we have to
214n/a * assume python is on the user's $PATH, since there's no
215n/a * other way to find a directory to start the search from. If
216n/a * $PATH isn't exported, you lose.
217n/a */
218n/a#ifdef ALTSEP
219n/a if (strchr(prog, SEP) || strchr(prog, ALTSEP))
220n/a#else
221n/a if (strchr(prog, SEP))
222n/a#endif
223n/a strncpy(progpath, prog, MAXPATHLEN);
224n/a else if (path) {
225n/a while (1) {
226n/a char *delim = strchr(path, DELIM);
227n/a
228n/a if (delim) {
229n/a size_t len = delim - path;
230n/a /* ensure we can't overwrite buffer */
231n/a#if !defined(PYCC_GCC)
232n/a len = min(MAXPATHLEN,len);
233n/a#else
234n/a len = MAXPATHLEN < len ? MAXPATHLEN : len;
235n/a#endif
236n/a strncpy(progpath, path, len);
237n/a *(progpath + len) = '\0';
238n/a }
239n/a else
240n/a strncpy(progpath, path, MAXPATHLEN);
241n/a
242n/a /* join() is safe for MAXPATHLEN+1 size buffer */
243n/a join(progpath, prog);
244n/a if (exists(progpath))
245n/a break;
246n/a
247n/a if (!delim) {
248n/a progpath[0] = '\0';
249n/a break;
250n/a }
251n/a path = delim + 1;
252n/a }
253n/a }
254n/a else
255n/a progpath[0] = '\0';
256n/a}
257n/a
258n/astatic void
259n/acalculate_path(void)
260n/a{
261n/a char argv0_path[MAXPATHLEN+1];
262n/a char *buf;
263n/a size_t bufsz;
264n/a char *pythonhome = Py_GetPythonHome();
265n/a char *envpath = getenv("PYTHONPATH");
266n/a char zip_path[MAXPATHLEN+1];
267n/a size_t len;
268n/a
269n/a get_progpath();
270n/a /* progpath guaranteed \0 terminated in MAXPATH+1 bytes. */
271n/a strcpy(argv0_path, progpath);
272n/a reduce(argv0_path);
273n/a if (pythonhome == NULL || *pythonhome == '\0') {
274n/a if (search_for_prefix(argv0_path, LANDMARK))
275n/a pythonhome = prefix;
276n/a else
277n/a pythonhome = NULL;
278n/a }
279n/a else
280n/a strncpy(prefix, pythonhome, MAXPATHLEN);
281n/a
282n/a if (envpath && *envpath == '\0')
283n/a envpath = NULL;
284n/a
285n/a /* Calculate zip archive path */
286n/a strncpy(zip_path, progpath, MAXPATHLEN);
287n/a zip_path[MAXPATHLEN] = '\0';
288n/a len = strlen(zip_path);
289n/a if (len > 4) {
290n/a zip_path[len-3] = 'z'; /* change ending to "zip" */
291n/a zip_path[len-2] = 'i';
292n/a zip_path[len-1] = 'p';
293n/a }
294n/a else {
295n/a zip_path[0] = 0;
296n/a }
297n/a
298n/a /* We need to construct a path from the following parts.
299n/a * (1) the PYTHONPATH environment variable, if set;
300n/a * (2) the zip archive file path;
301n/a * (3) the PYTHONPATH config macro, with the leading "."
302n/a * of each component replaced with pythonhome, if set;
303n/a * (4) the directory containing the executable (argv0_path).
304n/a * The length calculation calculates #3 first.
305n/a */
306n/a
307n/a /* Calculate size of return buffer */
308n/a if (pythonhome != NULL) {
309n/a char *p;
310n/a bufsz = 1;
311n/a for (p = PYTHONPATH; *p; p++) {
312n/a if (*p == DELIM)
313n/a bufsz++; /* number of DELIM plus one */
314n/a }
315n/a bufsz *= strlen(pythonhome);
316n/a }
317n/a else
318n/a bufsz = 0;
319n/a bufsz += strlen(PYTHONPATH) + 1;
320n/a bufsz += strlen(argv0_path) + 1;
321n/a bufsz += strlen(zip_path) + 1;
322n/a if (envpath != NULL)
323n/a bufsz += strlen(envpath) + 1;
324n/a
325n/a module_search_path = buf = malloc(bufsz);
326n/a if (buf == NULL) {
327n/a /* We can't exit, so print a warning and limp along */
328n/a fprintf(stderr, "Can't malloc dynamic PYTHONPATH.\n");
329n/a if (envpath) {
330n/a fprintf(stderr, "Using environment $PYTHONPATH.\n");
331n/a module_search_path = envpath;
332n/a }
333n/a else {
334n/a fprintf(stderr, "Using default static path.\n");
335n/a module_search_path = PYTHONPATH;
336n/a }
337n/a return;
338n/a }
339n/a
340n/a if (envpath) {
341n/a strcpy(buf, envpath);
342n/a buf = strchr(buf, '\0');
343n/a *buf++ = DELIM;
344n/a }
345n/a if (zip_path[0]) {
346n/a strcpy(buf, zip_path);
347n/a buf = strchr(buf, '\0');
348n/a *buf++ = DELIM;
349n/a }
350n/a
351n/a if (pythonhome == NULL) {
352n/a strcpy(buf, PYTHONPATH);
353n/a buf = strchr(buf, '\0');
354n/a }
355n/a else {
356n/a char *p = PYTHONPATH;
357n/a char *q;
358n/a size_t n;
359n/a for (;;) {
360n/a q = strchr(p, DELIM);
361n/a if (q == NULL)
362n/a n = strlen(p);
363n/a else
364n/a n = q-p;
365n/a if (p[0] == '.' && is_sep(p[1])) {
366n/a strcpy(buf, pythonhome);
367n/a buf = strchr(buf, '\0');
368n/a p++;
369n/a n--;
370n/a }
371n/a strncpy(buf, p, n);
372n/a buf += n;
373n/a if (q == NULL)
374n/a break;
375n/a *buf++ = DELIM;
376n/a p = q+1;
377n/a }
378n/a }
379n/a if (argv0_path) {
380n/a *buf++ = DELIM;
381n/a strcpy(buf, argv0_path);
382n/a buf = strchr(buf, '\0');
383n/a }
384n/a *buf = '\0';
385n/a}
386n/a
387n/a
388n/a/* External interface */
389n/a
390n/achar *
391n/aPy_GetPath(void)
392n/a{
393n/a if (!module_search_path)
394n/a calculate_path();
395n/a return module_search_path;
396n/a}
397n/a
398n/achar *
399n/aPy_GetPrefix(void)
400n/a{
401n/a if (!module_search_path)
402n/a calculate_path();
403n/a return prefix;
404n/a}
405n/a
406n/achar *
407n/aPy_GetExecPrefix(void)
408n/a{
409n/a return Py_GetPrefix();
410n/a}
411n/a
412n/achar *
413n/aPy_GetProgramFullPath(void)
414n/a{
415n/a if (!module_search_path)
416n/a calculate_path();
417n/a return progpath;
418n/a}