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