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

Python code coverage for PC/os2vacpp/getpathp.c

#countcontent
1n/a
2n/a/* Return the initial module search path. */
3n/a/* Used by DOS, OS/2, Windows 3.1. Works on NT too. */
4n/a
5n/a#include "Python.h"
6n/a#include "osdefs.h"
7n/a
8n/a#ifdef MS_WIN32
9n/a#include <windows.h>
10n/aextern BOOL PyWin_IsWin32s(void);
11n/a#endif
12n/a
13n/a#include <sys/types.h>
14n/a#include <sys/stat.h>
15n/a#include <string.h>
16n/a
17n/a#if HAVE_UNISTD_H
18n/a#include <unistd.h>
19n/a#endif /* HAVE_UNISTD_H */
20n/a
21n/a/* Search in some common locations for the associated Python libraries.
22n/a *
23n/a * Two directories must be found, the platform independent directory
24n/a * (prefix), containing the common .py and .pyc files, and the platform
25n/a * dependent directory (exec_prefix), containing the shared library
26n/a * modules. Note that prefix and exec_prefix can be the same directory,
27n/a * but for some installations, they are different.
28n/a *
29n/a * Py_GetPath() tries to return a sensible Python module search path.
30n/a *
31n/a * First, we look to see if the executable is in a subdirectory of
32n/a * the Python build directory. We calculate the full path of the
33n/a * directory containing the executable as progpath. We work backwards
34n/a * along progpath and look for $dir/Modules/Setup.in, a distinctive
35n/a * landmark. If found, we use $dir/Lib as $root. The returned
36n/a * Python path is the compiled #define PYTHONPATH with all the initial
37n/a * "./lib" replaced by $root.
38n/a *
39n/a * Otherwise, if there is a PYTHONPATH environment variable, we return that.
40n/a *
41n/a * Otherwise we try to find $progpath/lib/os.py, and if found, then
42n/a * root is $progpath/lib, and we return Python path as compiled PYTHONPATH
43n/a * with all "./lib" replaced by $root (as above).
44n/a *
45n/a */
46n/a
47n/a#ifndef LANDMARK
48n/a#define LANDMARK "lib\\os.py"
49n/a#endif
50n/a
51n/astatic char prefix[MAXPATHLEN+1];
52n/astatic char exec_prefix[MAXPATHLEN+1];
53n/astatic char progpath[MAXPATHLEN+1];
54n/astatic char *module_search_path = NULL;
55n/a
56n/a
57n/astatic int
58n/ais_sep(char ch) /* determine if "ch" is a separator character */
59n/a{
60n/a#ifdef ALTSEP
61n/a return ch == SEP || ch == ALTSEP;
62n/a#else
63n/a return ch == SEP;
64n/a#endif
65n/a}
66n/a
67n/a
68n/astatic void
69n/areduce(char *dir)
70n/a{
71n/a int i = strlen(dir);
72n/a while (i > 0 && !is_sep(dir[i]))
73n/a --i;
74n/a dir[i] = '\0';
75n/a}
76n/a
77n/a
78n/astatic int
79n/aexists(char *filename)
80n/a{
81n/a struct stat buf;
82n/a return stat(filename, &buf) == 0;
83n/a}
84n/a
85n/a
86n/a/* Add a path component, by appending stuff to buffer.
87n/a buffer must have at least MAXPATHLEN + 1 bytes allocated, and contain a
88n/a NUL-terminated string with no more than MAXPATHLEN characters (not counting
89n/a the trailing NUL). It's a fatal error if it contains a string longer than
90n/a that (callers must be careful!). If these requirements are met, it's
91n/a guaranteed that buffer will still be a NUL-terminated string with no more
92n/a than MAXPATHLEN characters at exit. If stuff is too long, only as much of
93n/a stuff as fits will be appended.
94n/a*/
95n/astatic void
96n/ajoin(char *buffer, char *stuff)
97n/a{
98n/a int n, k;
99n/a if (is_sep(stuff[0]))
100n/a n = 0;
101n/a else {
102n/a n = strlen(buffer);
103n/a if (n > 0 && !is_sep(buffer[n-1]) && n < MAXPATHLEN)
104n/a buffer[n++] = SEP;
105n/a }
106n/a if (n > MAXPATHLEN)
107n/a Py_FatalError("buffer overflow in getpathp.c's joinpath()");
108n/a k = strlen(stuff);
109n/a if (n + k > MAXPATHLEN)
110n/a k = MAXPATHLEN - n;
111n/a strncpy(buffer+n, stuff, k);
112n/a buffer[n+k] = '\0';
113n/a}
114n/a
115n/a
116n/astatic int
117n/asearch_for_prefix(char *argv0_path, char *landmark)
118n/a{
119n/a int n;
120n/a
121n/a /* Search from argv0_path, until root is found */
122n/a strcpy(prefix, argv0_path);
123n/a do {
124n/a n = strlen(prefix);
125n/a join(prefix, landmark);
126n/a if (exists(prefix)) {
127n/a prefix[n] = '\0';
128n/a return 1;
129n/a }
130n/a prefix[n] = '\0';
131n/a reduce(prefix);
132n/a } while (prefix[0]);
133n/a return 0;
134n/a}
135n/a
136n/a#ifdef MS_WIN32
137n/a#include "malloc.h" // for alloca - see comments below!
138n/aextern const char *PyWin_DLLVersionString; // a string loaded from the DLL at startup.
139n/a
140n/a
141n/a/* Load a PYTHONPATH value from the registry.
142n/a Load from either HKEY_LOCAL_MACHINE or HKEY_CURRENT_USER.
143n/a
144n/a Returns NULL, or a pointer that should be freed.
145n/a*/
146n/a
147n/astatic char *
148n/agetpythonregpath(HKEY keyBase, BOOL bWin32s)
149n/a{
150n/a HKEY newKey = 0;
151n/a DWORD nameSize = 0;
152n/a DWORD dataSize = 0;
153n/a DWORD numEntries = 0;
154n/a LONG rc;
155n/a char *retval = NULL;
156n/a char *dataBuf;
157n/a const char keyPrefix[] = "Software\\Python\\PythonCore\\";
158n/a const char keySuffix[] = "\\PythonPath";
159n/a int versionLen;
160n/a char *keyBuf;
161n/a
162n/a // Tried to use sysget("winver") but here is too early :-(
163n/a versionLen = strlen(PyWin_DLLVersionString);
164n/a // alloca == no free required, but memory only local to fn.
165n/a // also no heap fragmentation! Am I being silly?
166n/a keyBuf = alloca(sizeof(keyPrefix)-1 + versionLen + sizeof(keySuffix)); // chars only, plus 1 NULL.
167n/a // lots of constants here for the compiler to optimize away :-)
168n/a memcpy(keyBuf, keyPrefix, sizeof(keyPrefix)-1);
169n/a memcpy(keyBuf+sizeof(keyPrefix)-1, PyWin_DLLVersionString, versionLen);
170n/a memcpy(keyBuf+sizeof(keyPrefix)-1+versionLen, keySuffix, sizeof(keySuffix)); // NULL comes with this one!
171n/a
172n/a rc=RegOpenKey(keyBase,
173n/a keyBuf,
174n/a &newKey);
175n/a if (rc==ERROR_SUCCESS) {
176n/a RegQueryInfoKey(newKey, NULL, NULL, NULL, NULL, NULL, NULL,
177n/a &numEntries, &nameSize, &dataSize, NULL, NULL);
178n/a }
179n/a if (bWin32s && numEntries==0 && dataSize==0) {
180n/a /* must hardcode for Win32s */
181n/a numEntries = 1;
182n/a dataSize = 511;
183n/a }
184n/a if (numEntries) {
185n/a /* Loop over all subkeys. */
186n/a /* Win32s doesnt know how many subkeys, so we do
187n/a it twice */
188n/a char keyBuf[MAX_PATH+1];
189n/a int index = 0;
190n/a int off = 0;
191n/a for(index=0;;index++) {
192n/a long reqdSize = 0;
193n/a DWORD rc = RegEnumKey(newKey,
194n/a index, keyBuf, MAX_PATH+1);
195n/a if (rc) break;
196n/a rc = RegQueryValue(newKey, keyBuf, NULL, &reqdSize);
197n/a if (rc) break;
198n/a if (bWin32s && reqdSize==0) reqdSize = 512;
199n/a dataSize += reqdSize + 1; /* 1 for the ";" */
200n/a }
201n/a dataBuf = malloc(dataSize+1);
202n/a if (dataBuf==NULL)
203n/a return NULL; /* pretty serious? Raise error? */
204n/a /* Now loop over, grabbing the paths.
205n/a Subkeys before main library */
206n/a for(index=0;;index++) {
207n/a int adjust;
208n/a long reqdSize = dataSize;
209n/a DWORD rc = RegEnumKey(newKey,
210n/a index, keyBuf,MAX_PATH+1);
211n/a if (rc) break;
212n/a rc = RegQueryValue(newKey,
213n/a keyBuf, dataBuf+off, &reqdSize);
214n/a if (rc) break;
215n/a if (reqdSize>1) {
216n/a /* If Nothing, or only '\0' copied. */
217n/a adjust = strlen(dataBuf+off);
218n/a dataSize -= adjust;
219n/a off += adjust;
220n/a dataBuf[off++] = ';';
221n/a dataBuf[off] = '\0';
222n/a dataSize--;
223n/a }
224n/a }
225n/a /* Additionally, win32s doesnt work as expected, so
226n/a the specific strlen() is required for 3.1. */
227n/a rc = RegQueryValue(newKey, "", dataBuf+off, &dataSize);
228n/a if (rc==ERROR_SUCCESS) {
229n/a if (strlen(dataBuf)==0)
230n/a free(dataBuf);
231n/a else
232n/a retval = dataBuf; /* caller will free */
233n/a }
234n/a else
235n/a free(dataBuf);
236n/a }
237n/a
238n/a if (newKey)
239n/a RegCloseKey(newKey);
240n/a return retval;
241n/a}
242n/a#endif /* MS_WIN32 */
243n/a
244n/astatic void
245n/aget_progpath(void)
246n/a{
247n/a extern char *Py_GetProgramName(void);
248n/a char *path = getenv("PATH");
249n/a char *prog = Py_GetProgramName();
250n/a
251n/a#ifdef MS_WIN32
252n/a if (GetModuleFileName(NULL, progpath, MAXPATHLEN))
253n/a return;
254n/a#endif
255n/a if (prog == NULL || *prog == '\0')
256n/a prog = "python";
257n/a
258n/a /* If there is no slash in the argv0 path, then we have to
259n/a * assume python is on the user's $PATH, since there's no
260n/a * other way to find a directory to start the search from. If
261n/a * $PATH isn't exported, you lose.
262n/a */
263n/a#ifdef ALTSEP
264n/a if (strchr(prog, SEP) || strchr(prog, ALTSEP))
265n/a#else
266n/a if (strchr(prog, SEP))
267n/a#endif
268n/a strcpy(progpath, prog);
269n/a else if (path) {
270n/a while (1) {
271n/a char *delim = strchr(path, DELIM);
272n/a
273n/a if (delim) {
274n/a int len = delim - path;
275n/a strncpy(progpath, path, len);
276n/a *(progpath + len) = '\0';
277n/a }
278n/a else
279n/a strcpy(progpath, path);
280n/a
281n/a join(progpath, prog);
282n/a if (exists(progpath))
283n/a break;
284n/a
285n/a if (!delim) {
286n/a progpath[0] = '\0';
287n/a break;
288n/a }
289n/a path = delim + 1;
290n/a }
291n/a }
292n/a else
293n/a progpath[0] = '\0';
294n/a}
295n/a
296n/astatic void
297n/acalculate_path(void)
298n/a{
299n/a char argv0_path[MAXPATHLEN+1];
300n/a char *buf;
301n/a int bufsz;
302n/a char *pythonhome = Py_GetPythonHome();
303n/a char *envpath = Py_GETENV("PYTHONPATH");
304n/a#ifdef MS_WIN32
305n/a char *machinepath, *userpath;
306n/a
307n/a /* Are we running under Windows 3.1(1) Win32s? */
308n/a if (PyWin_IsWin32s()) {
309n/a /* Only CLASSES_ROOT is supported */
310n/a machinepath = getpythonregpath(HKEY_CLASSES_ROOT, TRUE);
311n/a userpath = NULL;
312n/a } else {
313n/a machinepath = getpythonregpath(HKEY_LOCAL_MACHINE, FALSE);
314n/a userpath = getpythonregpath(HKEY_CURRENT_USER, FALSE);
315n/a }
316n/a#endif
317n/a
318n/a get_progpath();
319n/a strcpy(argv0_path, progpath);
320n/a reduce(argv0_path);
321n/a if (pythonhome == NULL || *pythonhome == '\0') {
322n/a if (search_for_prefix(argv0_path, LANDMARK))
323n/a pythonhome = prefix;
324n/a else
325n/a pythonhome = NULL;
326n/a }
327n/a else {
328n/a char *delim;
329n/a
330n/a strcpy(prefix, pythonhome);
331n/a
332n/a /* Extract Any Optional Trailing EXEC_PREFIX */
333n/a /* e.g. PYTHONHOME=<prefix>:<exec_prefix> */
334n/a delim = strchr(prefix, DELIM);
335n/a if (delim) {
336n/a *delim = '\0';
337n/a strcpy(exec_prefix, delim+1);
338n/a } else
339n/a strcpy(exec_prefix, EXEC_PREFIX);
340n/a }
341n/a
342n/a if (envpath && *envpath == '\0')
343n/a envpath = NULL;
344n/a
345n/a /* We need to construct a path from the following parts:
346n/a (1) the PYTHONPATH environment variable, if set;
347n/a (2) for Win32, the machinepath and userpath, if set;
348n/a (3) the PYTHONPATH config macro, with the leading "."
349n/a of each component replaced with pythonhome, if set;
350n/a (4) the directory containing the executable (argv0_path).
351n/a The length calculation calculates #3 first.
352n/a */
353n/a
354n/a /* Calculate size of return buffer */
355n/a if (pythonhome != NULL) {
356n/a char *p;
357n/a bufsz = 1;
358n/a for (p = PYTHONPATH; *p; p++) {
359n/a if (*p == DELIM)
360n/a bufsz++; /* number of DELIM plus one */
361n/a }
362n/a bufsz *= strlen(pythonhome);
363n/a }
364n/a else
365n/a bufsz = 0;
366n/a bufsz += strlen(PYTHONPATH) + 1;
367n/a if (envpath != NULL)
368n/a bufsz += strlen(envpath) + 1;
369n/a bufsz += strlen(argv0_path) + 1;
370n/a#ifdef MS_WIN32
371n/a if (machinepath)
372n/a bufsz += strlen(machinepath) + 1;
373n/a if (userpath)
374n/a bufsz += strlen(userpath) + 1;
375n/a#endif
376n/a
377n/a module_search_path = buf = malloc(bufsz);
378n/a if (buf == NULL) {
379n/a /* We can't exit, so print a warning and limp along */
380n/a fprintf(stderr, "Can't malloc dynamic PYTHONPATH.\n");
381n/a if (envpath) {
382n/a fprintf(stderr, "Using default static $PYTHONPATH.\n");
383n/a module_search_path = envpath;
384n/a }
385n/a else {
386n/a fprintf(stderr, "Using environment $PYTHONPATH.\n");
387n/a module_search_path = PYTHONPATH;
388n/a }
389n/a return;
390n/a }
391n/a
392n/a if (envpath) {
393n/a strcpy(buf, envpath);
394n/a buf = strchr(buf, '\0');
395n/a *buf++ = DELIM;
396n/a }
397n/a#ifdef MS_WIN32
398n/a if (machinepath) {
399n/a strcpy(buf, machinepath);
400n/a buf = strchr(buf, '\0');
401n/a *buf++ = DELIM;
402n/a }
403n/a if (userpath) {
404n/a strcpy(buf, userpath);
405n/a buf = strchr(buf, '\0');
406n/a *buf++ = DELIM;
407n/a }
408n/a#endif
409n/a if (pythonhome == NULL) {
410n/a strcpy(buf, PYTHONPATH);
411n/a buf = strchr(buf, '\0');
412n/a }
413n/a else {
414n/a char *p = PYTHONPATH;
415n/a char *q;
416n/a int n;
417n/a for (;;) {
418n/a q = strchr(p, DELIM);
419n/a if (q == NULL)
420n/a n = strlen(p);
421n/a else
422n/a n = q-p;
423n/a if (p[0] == '.' && is_sep(p[1])) {
424n/a strcpy(buf, pythonhome);
425n/a buf = strchr(buf, '\0');
426n/a p++;
427n/a n--;
428n/a }
429n/a strncpy(buf, p, n);
430n/a buf += n;
431n/a if (q == NULL)
432n/a break;
433n/a *buf++ = DELIM;
434n/a p = q+1;
435n/a }
436n/a }
437n/a if (argv0_path) {
438n/a *buf++ = DELIM;
439n/a strcpy(buf, argv0_path);
440n/a buf = strchr(buf, '\0');
441n/a }
442n/a *buf = '\0';
443n/a}
444n/a
445n/a
446n/a/* External interface */
447n/a
448n/achar *
449n/aPy_GetPath(void)
450n/a{
451n/a if (!module_search_path)
452n/a calculate_path();
453n/a
454n/a return module_search_path;
455n/a}
456n/a
457n/achar *
458n/aPy_GetPrefix(void)
459n/a{
460n/a if (!module_search_path)
461n/a calculate_path();
462n/a
463n/a return prefix;
464n/a}
465n/a
466n/achar *
467n/aPy_GetExecPrefix(void)
468n/a{
469n/a if (!module_search_path)
470n/a calculate_path();
471n/a
472n/a return exec_prefix;
473n/a}
474n/a
475n/achar *
476n/aPy_GetProgramFullPath(void)
477n/a{
478n/a if (!module_search_path)
479n/a calculate_path();
480n/a
481n/a return progpath;
482n/a}