symbian-qemu-0.9.1-12/python-2.6.1/PC/getpathp.c
changeset 1 2fb8b9db1c86
equal deleted inserted replaced
0:ffa851df0825 1:2fb8b9db1c86
       
     1 
       
     2 /* Return the initial module search path. */
       
     3 /* Used by DOS, OS/2, Windows 3.1, Windows 95/98, Windows NT. */
       
     4 
       
     5 /* ----------------------------------------------------------------
       
     6    PATH RULES FOR WINDOWS:
       
     7    This describes how sys.path is formed on Windows.  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 look in the registry for "application paths" - that is, sub-keys
       
    17      under the main PythonPath registry key.  These are added next (the
       
    18      order of sub-key processing is undefined).
       
    19      HKEY_CURRENT_USER is searched and added first.
       
    20      HKEY_LOCAL_MACHINE is searched and added next.
       
    21      (Note that all known installers only use HKLM, so HKCU is typically
       
    22      empty)
       
    23 
       
    24    * We attempt to locate the "Python Home" - if the PYTHONHOME env var
       
    25      is set, we believe it.  Otherwise, we use the path of our host .EXE's
       
    26      to try and locate our "landmark" (lib\\os.py) and deduce our home.
       
    27      - If we DO have a Python Home: The relevant sub-directories (Lib, 
       
    28        plat-win, lib-tk, etc) are based on the Python Home
       
    29      - If we DO NOT have a Python Home, the core Python Path is
       
    30        loaded from the registry.  This is the main PythonPath key, 
       
    31        and both HKLM and HKCU are combined to form the path)
       
    32 
       
    33    * Iff - we can not locate the Python Home, have not had a PYTHONPATH
       
    34      specified, and can't locate any Registry entries (ie, we have _nothing_
       
    35      we can assume is a good path), a default path with relative entries is 
       
    36      used (eg. .\Lib;.\plat-win, etc)
       
    37 
       
    38 
       
    39   The end result of all this is:
       
    40   * When running python.exe, or any other .exe in the main Python directory
       
    41     (either an installed version, or directly from the PCbuild directory),
       
    42     the core path is deduced, and the core paths in the registry are
       
    43     ignored.  Other "application paths" in the registry are always read.
       
    44 
       
    45   * When Python is hosted in another exe (different directory, embedded via 
       
    46     COM, etc), the Python Home will not be deduced, so the core path from
       
    47     the registry is used.  Other "application paths" in the registry are 
       
    48     always read.
       
    49 
       
    50   * If Python can't find its home and there is no registry (eg, frozen
       
    51     exe, some very strange installation setup) you get a path with
       
    52     some default, but relative, paths.
       
    53 
       
    54    ---------------------------------------------------------------- */
       
    55 
       
    56 
       
    57 #include "Python.h"
       
    58 #include "osdefs.h"
       
    59 
       
    60 #ifdef MS_WINDOWS
       
    61 #include <windows.h>
       
    62 #include <tchar.h>
       
    63 #endif
       
    64 
       
    65 #ifdef HAVE_SYS_TYPES_H
       
    66 #include <sys/types.h>
       
    67 #endif /* HAVE_SYS_TYPES_H */
       
    68 
       
    69 #ifdef HAVE_SYS_STAT_H
       
    70 #include <sys/stat.h>
       
    71 #endif /* HAVE_SYS_STAT_H */
       
    72 
       
    73 #include <string.h>
       
    74 
       
    75 /* Search in some common locations for the associated Python libraries.
       
    76  *
       
    77  * Py_GetPath() tries to return a sensible Python module search path.
       
    78  *
       
    79  * The approach is an adaptation for Windows of the strategy used in
       
    80  * ../Modules/getpath.c; it uses the Windows Registry as one of its
       
    81  * information sources.
       
    82  */
       
    83 
       
    84 #ifndef LANDMARK
       
    85 #define LANDMARK "lib\\os.py"
       
    86 #endif
       
    87 
       
    88 static char prefix[MAXPATHLEN+1];
       
    89 static char progpath[MAXPATHLEN+1];
       
    90 static char dllpath[MAXPATHLEN+1];
       
    91 static char *module_search_path = NULL;
       
    92 
       
    93 
       
    94 static int
       
    95 is_sep(char ch)	/* determine if "ch" is a separator character */
       
    96 {
       
    97 #ifdef ALTSEP
       
    98 	return ch == SEP || ch == ALTSEP;
       
    99 #else
       
   100 	return ch == SEP;
       
   101 #endif
       
   102 }
       
   103 
       
   104 /* assumes 'dir' null terminated in bounds.  Never writes
       
   105    beyond existing terminator.
       
   106 */
       
   107 static void
       
   108 reduce(char *dir)
       
   109 {
       
   110 	size_t i = strlen(dir);
       
   111 	while (i > 0 && !is_sep(dir[i]))
       
   112 		--i;
       
   113 	dir[i] = '\0';
       
   114 }
       
   115 	
       
   116 
       
   117 static int
       
   118 exists(char *filename)
       
   119 {
       
   120 	struct stat buf;
       
   121 	return stat(filename, &buf) == 0;
       
   122 }
       
   123 
       
   124 /* Assumes 'filename' MAXPATHLEN+1 bytes long - 
       
   125    may extend 'filename' by one character.
       
   126 */
       
   127 static int
       
   128 ismodule(char *filename)	/* Is module -- check for .pyc/.pyo too */
       
   129 {
       
   130 	if (exists(filename))
       
   131 		return 1;
       
   132 
       
   133 	/* Check for the compiled version of prefix. */
       
   134 	if (strlen(filename) < MAXPATHLEN) {
       
   135 		strcat(filename, Py_OptimizeFlag ? "o" : "c");
       
   136 		if (exists(filename))
       
   137 			return 1;
       
   138 	}
       
   139 	return 0;
       
   140 }
       
   141 
       
   142 /* Add a path component, by appending stuff to buffer.
       
   143    buffer must have at least MAXPATHLEN + 1 bytes allocated, and contain a
       
   144    NUL-terminated string with no more than MAXPATHLEN characters (not counting
       
   145    the trailing NUL).  It's a fatal error if it contains a string longer than
       
   146    that (callers must be careful!).  If these requirements are met, it's
       
   147    guaranteed that buffer will still be a NUL-terminated string with no more
       
   148    than MAXPATHLEN characters at exit.  If stuff is too long, only as much of
       
   149    stuff as fits will be appended.
       
   150 */
       
   151 static void
       
   152 join(char *buffer, char *stuff)
       
   153 {
       
   154 	size_t n, k;
       
   155 	if (is_sep(stuff[0]))
       
   156 		n = 0;
       
   157 	else {
       
   158 		n = strlen(buffer);
       
   159 		if (n > 0 && !is_sep(buffer[n-1]) && n < MAXPATHLEN)
       
   160 			buffer[n++] = SEP;
       
   161 	}
       
   162 	if (n > MAXPATHLEN)
       
   163 		Py_FatalError("buffer overflow in getpathp.c's joinpath()");
       
   164 	k = strlen(stuff);
       
   165 	if (n + k > MAXPATHLEN)
       
   166 		k = MAXPATHLEN - n;
       
   167 	strncpy(buffer+n, stuff, k);
       
   168 	buffer[n+k] = '\0';
       
   169 }
       
   170 
       
   171 /* gotlandmark only called by search_for_prefix, which ensures
       
   172    'prefix' is null terminated in bounds.  join() ensures
       
   173    'landmark' can not overflow prefix if too long.
       
   174 */
       
   175 static int
       
   176 gotlandmark(char *landmark)
       
   177 {
       
   178 	int ok;
       
   179 	Py_ssize_t n;
       
   180 
       
   181 	n = strlen(prefix);
       
   182 	join(prefix, landmark);
       
   183 	ok = ismodule(prefix);
       
   184 	prefix[n] = '\0';
       
   185 	return ok;
       
   186 }
       
   187 
       
   188 /* assumes argv0_path is MAXPATHLEN+1 bytes long, already \0 term'd. 
       
   189    assumption provided by only caller, calculate_path() */
       
   190 static int
       
   191 search_for_prefix(char *argv0_path, char *landmark)
       
   192 {
       
   193 	/* Search from argv0_path, until landmark is found */
       
   194 	strcpy(prefix, argv0_path);
       
   195 	do {
       
   196 		if (gotlandmark(landmark))
       
   197 			return 1;
       
   198 		reduce(prefix);
       
   199 	} while (prefix[0]);
       
   200 	return 0;
       
   201 }
       
   202 
       
   203 #ifdef MS_WINDOWS
       
   204 
       
   205 /* a string loaded from the DLL at startup.*/
       
   206 extern const char *PyWin_DLLVersionString;
       
   207 
       
   208 
       
   209 /* Load a PYTHONPATH value from the registry.
       
   210    Load from either HKEY_LOCAL_MACHINE or HKEY_CURRENT_USER.
       
   211 
       
   212    Works in both Unicode and 8bit environments.  Only uses the
       
   213    Ex family of functions so it also works with Windows CE.
       
   214 
       
   215    Returns NULL, or a pointer that should be freed.
       
   216 
       
   217    XXX - this code is pretty strange, as it used to also
       
   218    work on Win16, where the buffer sizes werent available
       
   219    in advance.  It could be simplied now Win16/Win32s is dead!
       
   220 */
       
   221 
       
   222 static char *
       
   223 getpythonregpath(HKEY keyBase, int skipcore)
       
   224 {
       
   225 	HKEY newKey = 0;
       
   226 	DWORD dataSize = 0;
       
   227 	DWORD numKeys = 0;
       
   228 	LONG rc;
       
   229 	char *retval = NULL;
       
   230 	TCHAR *dataBuf = NULL;
       
   231 	static const TCHAR keyPrefix[] = _T("Software\\Python\\PythonCore\\");
       
   232 	static const TCHAR keySuffix[] = _T("\\PythonPath");
       
   233 	size_t versionLen;
       
   234 	DWORD index;
       
   235 	TCHAR *keyBuf = NULL;
       
   236 	TCHAR *keyBufPtr;
       
   237 	TCHAR **ppPaths = NULL;
       
   238 
       
   239 	/* Tried to use sysget("winver") but here is too early :-( */
       
   240 	versionLen = _tcslen(PyWin_DLLVersionString);
       
   241 	/* Space for all the chars, plus one \0 */
       
   242 	keyBuf = keyBufPtr = malloc(sizeof(keyPrefix) + 
       
   243 		                    sizeof(TCHAR)*(versionLen-1) + 
       
   244 				    sizeof(keySuffix));
       
   245 	if (keyBuf==NULL) goto done;
       
   246 
       
   247 	memcpy(keyBufPtr, keyPrefix, sizeof(keyPrefix)-sizeof(TCHAR));
       
   248 	keyBufPtr += sizeof(keyPrefix)/sizeof(TCHAR) - 1;
       
   249 	memcpy(keyBufPtr, PyWin_DLLVersionString, versionLen * sizeof(TCHAR));
       
   250 	keyBufPtr += versionLen;
       
   251 	/* NULL comes with this one! */
       
   252 	memcpy(keyBufPtr, keySuffix, sizeof(keySuffix));
       
   253 	/* Open the root Python key */
       
   254 	rc=RegOpenKeyEx(keyBase,
       
   255 	                keyBuf, /* subkey */
       
   256 	                0, /* reserved */
       
   257 	                KEY_READ,
       
   258 	                &newKey);
       
   259 	if (rc!=ERROR_SUCCESS) goto done;
       
   260 	/* Find out how big our core buffer is, and how many subkeys we have */
       
   261 	rc = RegQueryInfoKey(newKey, NULL, NULL, NULL, &numKeys, NULL, NULL, 
       
   262 	                NULL, NULL, &dataSize, NULL, NULL);
       
   263 	if (rc!=ERROR_SUCCESS) goto done;
       
   264 	if (skipcore) dataSize = 0; /* Only count core ones if we want them! */
       
   265 	/* Allocate a temp array of char buffers, so we only need to loop 
       
   266 	   reading the registry once
       
   267 	*/
       
   268 	ppPaths = malloc( sizeof(TCHAR *) * numKeys );
       
   269 	if (ppPaths==NULL) goto done;
       
   270 	memset(ppPaths, 0, sizeof(TCHAR *) * numKeys);
       
   271 	/* Loop over all subkeys, allocating a temp sub-buffer. */
       
   272 	for(index=0;index<numKeys;index++) {
       
   273 		TCHAR keyBuf[MAX_PATH+1];
       
   274 		HKEY subKey = 0;
       
   275 		DWORD reqdSize = MAX_PATH+1;
       
   276 		/* Get the sub-key name */
       
   277 		DWORD rc = RegEnumKeyEx(newKey, index, keyBuf, &reqdSize,
       
   278 		                        NULL, NULL, NULL, NULL );
       
   279 		if (rc!=ERROR_SUCCESS) goto done;
       
   280 		/* Open the sub-key */
       
   281 		rc=RegOpenKeyEx(newKey,
       
   282 						keyBuf, /* subkey */
       
   283 						0, /* reserved */
       
   284 						KEY_READ,
       
   285 						&subKey);
       
   286 		if (rc!=ERROR_SUCCESS) goto done;
       
   287 		/* Find the value of the buffer size, malloc, then read it */
       
   288 		RegQueryValueEx(subKey, NULL, 0, NULL, NULL, &reqdSize);
       
   289 		if (reqdSize) {
       
   290 			ppPaths[index] = malloc(reqdSize);
       
   291 			if (ppPaths[index]) {
       
   292 				RegQueryValueEx(subKey, NULL, 0, NULL, 
       
   293 				                (LPBYTE)ppPaths[index], 
       
   294 				                &reqdSize);
       
   295 				dataSize += reqdSize + 1; /* 1 for the ";" */
       
   296 			}
       
   297 		}
       
   298 		RegCloseKey(subKey);
       
   299 	}
       
   300 
       
   301 	/* return null if no path to return */
       
   302 	if (dataSize == 0) goto done;
       
   303 
       
   304 	/* original datasize from RegQueryInfo doesn't include the \0 */
       
   305 	dataBuf = malloc((dataSize+1) * sizeof(TCHAR));
       
   306 	if (dataBuf) {
       
   307 		TCHAR *szCur = dataBuf;
       
   308 		DWORD reqdSize = dataSize;
       
   309 		/* Copy our collected strings */
       
   310 		for (index=0;index<numKeys;index++) {
       
   311 			if (index > 0) {
       
   312 				*(szCur++) = _T(';');
       
   313 				dataSize--;
       
   314 			}
       
   315 			if (ppPaths[index]) {
       
   316 				Py_ssize_t len = _tcslen(ppPaths[index]);
       
   317 				_tcsncpy(szCur, ppPaths[index], len);
       
   318 				szCur += len;
       
   319 				assert(dataSize > (DWORD)len);
       
   320 				dataSize -= (DWORD)len;
       
   321 			}
       
   322 		}
       
   323 		if (skipcore)
       
   324 			*szCur = '\0';
       
   325 		else {
       
   326 			/* If we have no values, we dont need a ';' */
       
   327 			if (numKeys) {
       
   328 				*(szCur++) = _T(';');
       
   329 				dataSize--;
       
   330 			}
       
   331 			/* Now append the core path entries - 
       
   332 			   this will include the NULL 
       
   333 			*/
       
   334 			rc = RegQueryValueEx(newKey, NULL, 0, NULL, 
       
   335 			                     (LPBYTE)szCur, &dataSize);
       
   336 		}
       
   337 		/* And set the result - caller must free 
       
   338 		   If MBCS, it is fine as is.  If Unicode, allocate new
       
   339 		   buffer and convert.
       
   340 		*/
       
   341 #ifdef UNICODE
       
   342 		retval = (char *)malloc(reqdSize+1);
       
   343 		if (retval)
       
   344 			WideCharToMultiByte(CP_ACP, 0, 
       
   345 					dataBuf, -1, /* source */ 
       
   346 					retval, reqdSize+1, /* dest */
       
   347 					NULL, NULL);
       
   348 		free(dataBuf);
       
   349 #else
       
   350 		retval = dataBuf;
       
   351 #endif
       
   352 	}
       
   353 done:
       
   354 	/* Loop freeing my temp buffers */
       
   355 	if (ppPaths) {
       
   356 		for(index=0;index<numKeys;index++)
       
   357 			if (ppPaths[index]) free(ppPaths[index]);
       
   358 		free(ppPaths);
       
   359 	}
       
   360 	if (newKey)
       
   361 		RegCloseKey(newKey);
       
   362 	if (keyBuf)
       
   363 		free(keyBuf);
       
   364 	return retval;
       
   365 }
       
   366 #endif /* MS_WINDOWS */
       
   367 
       
   368 static void
       
   369 get_progpath(void)
       
   370 {
       
   371 	extern char *Py_GetProgramName(void);
       
   372 	char *path = getenv("PATH");
       
   373 	char *prog = Py_GetProgramName();
       
   374 
       
   375 #ifdef MS_WINDOWS
       
   376 	extern HANDLE PyWin_DLLhModule;
       
   377 #ifdef UNICODE
       
   378 	WCHAR wprogpath[MAXPATHLEN+1];
       
   379 	/* Windows documents that GetModuleFileName() will "truncate",
       
   380 	   but makes no mention of the null terminator.  Play it safe.
       
   381 	   PLUS Windows itself defines MAX_PATH as the same, but anyway...
       
   382 	*/
       
   383 	wprogpath[MAXPATHLEN]=_T('\0');
       
   384 	if (PyWin_DLLhModule &&
       
   385 	    GetModuleFileName(PyWin_DLLhModule, wprogpath, MAXPATHLEN)) {
       
   386 		WideCharToMultiByte(CP_ACP, 0, 
       
   387 		                    wprogpath, -1, 
       
   388 		                    dllpath, MAXPATHLEN+1, 
       
   389 		                    NULL, NULL);
       
   390 	}
       
   391 	wprogpath[MAXPATHLEN]=_T('\0');
       
   392 	if (GetModuleFileName(NULL, wprogpath, MAXPATHLEN)) {
       
   393 		WideCharToMultiByte(CP_ACP, 0, 
       
   394 		                    wprogpath, -1, 
       
   395 		                    progpath, MAXPATHLEN+1, 
       
   396 		                    NULL, NULL);
       
   397 		return;
       
   398 	}
       
   399 #else
       
   400 	/* static init of progpath ensures final char remains \0 */
       
   401 	if (PyWin_DLLhModule)
       
   402 		if (!GetModuleFileName(PyWin_DLLhModule, dllpath, MAXPATHLEN))
       
   403 			dllpath[0] = 0;
       
   404 	if (GetModuleFileName(NULL, progpath, MAXPATHLEN))
       
   405 		return;
       
   406 #endif
       
   407 #endif
       
   408 	if (prog == NULL || *prog == '\0')
       
   409 		prog = "python";
       
   410 
       
   411 	/* If there is no slash in the argv0 path, then we have to
       
   412 	 * assume python is on the user's $PATH, since there's no
       
   413 	 * other way to find a directory to start the search from.  If
       
   414 	 * $PATH isn't exported, you lose.
       
   415 	 */
       
   416 #ifdef ALTSEP
       
   417 	if (strchr(prog, SEP) || strchr(prog, ALTSEP))
       
   418 #else
       
   419 	if (strchr(prog, SEP))
       
   420 #endif
       
   421 		strncpy(progpath, prog, MAXPATHLEN);
       
   422 	else if (path) {
       
   423 		while (1) {
       
   424 			char *delim = strchr(path, DELIM);
       
   425 
       
   426 			if (delim) {
       
   427 				size_t len = delim - path;
       
   428 				/* ensure we can't overwrite buffer */
       
   429 				len = min(MAXPATHLEN,len);
       
   430 				strncpy(progpath, path, len);
       
   431 				*(progpath + len) = '\0';
       
   432 			}
       
   433 			else
       
   434 				strncpy(progpath, path, MAXPATHLEN);
       
   435 
       
   436 			/* join() is safe for MAXPATHLEN+1 size buffer */
       
   437 			join(progpath, prog);
       
   438 			if (exists(progpath))
       
   439 				break;
       
   440 
       
   441 			if (!delim) {
       
   442 				progpath[0] = '\0';
       
   443 				break;
       
   444 			}
       
   445 			path = delim + 1;
       
   446 		}
       
   447 	}
       
   448 	else
       
   449 		progpath[0] = '\0';
       
   450 }
       
   451 
       
   452 static void
       
   453 calculate_path(void)
       
   454 {
       
   455 	char argv0_path[MAXPATHLEN+1];
       
   456 	char *buf;
       
   457 	size_t bufsz;
       
   458 	char *pythonhome = Py_GetPythonHome();
       
   459 	char *envpath = Py_GETENV("PYTHONPATH");
       
   460 
       
   461 #ifdef MS_WINDOWS
       
   462 	int skiphome, skipdefault;
       
   463 	char *machinepath = NULL;
       
   464 	char *userpath = NULL;
       
   465 	char zip_path[MAXPATHLEN+1];
       
   466 	size_t len;
       
   467 #endif
       
   468 
       
   469 	get_progpath();
       
   470 	/* progpath guaranteed \0 terminated in MAXPATH+1 bytes. */
       
   471 	strcpy(argv0_path, progpath);
       
   472 	reduce(argv0_path);
       
   473 	if (pythonhome == NULL || *pythonhome == '\0') {
       
   474 		if (search_for_prefix(argv0_path, LANDMARK))
       
   475 			pythonhome = prefix;
       
   476 		else
       
   477 			pythonhome = NULL;
       
   478 	}
       
   479 	else
       
   480 		strncpy(prefix, pythonhome, MAXPATHLEN);
       
   481 
       
   482 	if (envpath && *envpath == '\0')
       
   483 		envpath = NULL;
       
   484 
       
   485 
       
   486 #ifdef MS_WINDOWS
       
   487 	/* Calculate zip archive path */
       
   488 	if (dllpath[0])		/* use name of python DLL */
       
   489 		strncpy(zip_path, dllpath, MAXPATHLEN);
       
   490 	else			/* use name of executable program */
       
   491 		strncpy(zip_path, progpath, MAXPATHLEN);
       
   492 	zip_path[MAXPATHLEN] = '\0';
       
   493 	len = strlen(zip_path);
       
   494 	if (len > 4) {
       
   495 		zip_path[len-3] = 'z';	/* change ending to "zip" */
       
   496 		zip_path[len-2] = 'i';
       
   497 		zip_path[len-1] = 'p';
       
   498 	}
       
   499 	else {
       
   500 		zip_path[0] = 0;
       
   501 	}
       
   502  
       
   503 	skiphome = pythonhome==NULL ? 0 : 1;
       
   504 	machinepath = getpythonregpath(HKEY_LOCAL_MACHINE, skiphome);
       
   505 	userpath = getpythonregpath(HKEY_CURRENT_USER, skiphome);
       
   506 	/* We only use the default relative PYTHONPATH if we havent
       
   507 	   anything better to use! */
       
   508 	skipdefault = envpath!=NULL || pythonhome!=NULL || \
       
   509 		      machinepath!=NULL || userpath!=NULL;
       
   510 #endif
       
   511 
       
   512 	/* We need to construct a path from the following parts.
       
   513 	   (1) the PYTHONPATH environment variable, if set;
       
   514 	   (2) for Win32, the zip archive file path;
       
   515 	   (3) for Win32, the machinepath and userpath, if set;
       
   516 	   (4) the PYTHONPATH config macro, with the leading "."
       
   517 	       of each component replaced with pythonhome, if set;
       
   518 	   (5) the directory containing the executable (argv0_path).
       
   519 	   The length calculation calculates #4 first.
       
   520 	   Extra rules:
       
   521 	   - If PYTHONHOME is set (in any way) item (3) is ignored.
       
   522 	   - If registry values are used, (4) and (5) are ignored.
       
   523 	*/
       
   524 
       
   525 	/* Calculate size of return buffer */
       
   526 	if (pythonhome != NULL) {
       
   527 		char *p;
       
   528 		bufsz = 1;	
       
   529 		for (p = PYTHONPATH; *p; p++) {
       
   530 			if (*p == DELIM)
       
   531 				bufsz++; /* number of DELIM plus one */
       
   532 		}
       
   533 		bufsz *= strlen(pythonhome);
       
   534 	}
       
   535 	else
       
   536 		bufsz = 0;
       
   537 	bufsz += strlen(PYTHONPATH) + 1;
       
   538 	bufsz += strlen(argv0_path) + 1;
       
   539 #ifdef MS_WINDOWS
       
   540 	if (userpath)
       
   541 		bufsz += strlen(userpath) + 1;
       
   542 	if (machinepath)
       
   543 		bufsz += strlen(machinepath) + 1;
       
   544 	bufsz += strlen(zip_path) + 1;
       
   545 #endif
       
   546 	if (envpath != NULL)
       
   547 		bufsz += strlen(envpath) + 1;
       
   548 
       
   549 	module_search_path = buf = malloc(bufsz);
       
   550 	if (buf == NULL) {
       
   551 		/* We can't exit, so print a warning and limp along */
       
   552 		fprintf(stderr, "Can't malloc dynamic PYTHONPATH.\n");
       
   553 		if (envpath) {
       
   554 			fprintf(stderr, "Using environment $PYTHONPATH.\n");
       
   555 			module_search_path = envpath;
       
   556 		}
       
   557 		else {
       
   558 			fprintf(stderr, "Using default static path.\n");
       
   559 			module_search_path = PYTHONPATH;
       
   560 		}
       
   561 #ifdef MS_WINDOWS
       
   562 		if (machinepath)
       
   563 			free(machinepath);
       
   564 		if (userpath)
       
   565 			free(userpath);
       
   566 #endif /* MS_WINDOWS */
       
   567 		return;
       
   568 	}
       
   569 
       
   570 	if (envpath) {
       
   571 		strcpy(buf, envpath);
       
   572 		buf = strchr(buf, '\0');
       
   573 		*buf++ = DELIM;
       
   574 	}
       
   575 #ifdef MS_WINDOWS
       
   576 	if (zip_path[0]) {
       
   577 		strcpy(buf, zip_path);
       
   578 		buf = strchr(buf, '\0');
       
   579 		*buf++ = DELIM;
       
   580 	}
       
   581 	if (userpath) {
       
   582 		strcpy(buf, userpath);
       
   583 		buf = strchr(buf, '\0');
       
   584 		*buf++ = DELIM;
       
   585 		free(userpath);
       
   586 	}
       
   587 	if (machinepath) {
       
   588 		strcpy(buf, machinepath);
       
   589 		buf = strchr(buf, '\0');
       
   590 		*buf++ = DELIM;
       
   591 		free(machinepath);
       
   592 	}
       
   593 	if (pythonhome == NULL) {
       
   594 		if (!skipdefault) {
       
   595 			strcpy(buf, PYTHONPATH);
       
   596 			buf = strchr(buf, '\0');
       
   597 		}
       
   598 	}
       
   599 #else
       
   600 	if (pythonhome == NULL) {
       
   601 		strcpy(buf, PYTHONPATH);
       
   602 		buf = strchr(buf, '\0');
       
   603 	}
       
   604 #endif /* MS_WINDOWS */
       
   605 	else {
       
   606 		char *p = PYTHONPATH;
       
   607 		char *q;
       
   608 		size_t n;
       
   609 		for (;;) {
       
   610 			q = strchr(p, DELIM);
       
   611 			if (q == NULL)
       
   612 				n = strlen(p);
       
   613 			else
       
   614 				n = q-p;
       
   615 			if (p[0] == '.' && is_sep(p[1])) {
       
   616 				strcpy(buf, pythonhome);
       
   617 				buf = strchr(buf, '\0');
       
   618 				p++;
       
   619 				n--;
       
   620 			}
       
   621 			strncpy(buf, p, n);
       
   622 			buf += n;
       
   623 			if (q == NULL)
       
   624 				break;
       
   625 			*buf++ = DELIM;
       
   626 			p = q+1;
       
   627 		}
       
   628 	}
       
   629 	if (argv0_path) {
       
   630 		*buf++ = DELIM;
       
   631 		strcpy(buf, argv0_path);
       
   632 		buf = strchr(buf, '\0');
       
   633 	}
       
   634 	*buf = '\0';
       
   635 	/* Now to pull one last hack/trick.  If sys.prefix is
       
   636 	   empty, then try and find it somewhere on the paths
       
   637 	   we calculated.  We scan backwards, as our general policy
       
   638 	   is that Python core directories are at the *end* of
       
   639 	   sys.path.  We assume that our "lib" directory is
       
   640 	   on the path, and that our 'prefix' directory is
       
   641 	   the parent of that.
       
   642 	*/
       
   643 	if (*prefix=='\0') {
       
   644 		char lookBuf[MAXPATHLEN+1];
       
   645 		char *look = buf - 1; /* 'buf' is at the end of the buffer */
       
   646 		while (1) {
       
   647 			Py_ssize_t nchars;
       
   648 			char *lookEnd = look;
       
   649 			/* 'look' will end up one character before the
       
   650 			   start of the path in question - even if this
       
   651 			   is one character before the start of the buffer
       
   652 			*/
       
   653 			while (look >= module_search_path && *look != DELIM)
       
   654 				look--;
       
   655 			nchars = lookEnd-look;
       
   656 			strncpy(lookBuf, look+1, nchars);
       
   657 			lookBuf[nchars] = '\0';
       
   658 			/* Up one level to the parent */
       
   659 			reduce(lookBuf);
       
   660 			if (search_for_prefix(lookBuf, LANDMARK)) {
       
   661 				break;
       
   662 			}
       
   663 			/* If we are out of paths to search - give up */
       
   664 			if (look < module_search_path)
       
   665 				break;
       
   666 			look--;
       
   667 		}
       
   668 	}
       
   669 }
       
   670 
       
   671 
       
   672 /* External interface */
       
   673 
       
   674 char *
       
   675 Py_GetPath(void)
       
   676 {
       
   677 	if (!module_search_path)
       
   678 		calculate_path();
       
   679 	return module_search_path;
       
   680 }
       
   681 
       
   682 char *
       
   683 Py_GetPrefix(void)
       
   684 {
       
   685 	if (!module_search_path)
       
   686 		calculate_path();
       
   687 	return prefix;
       
   688 }
       
   689 
       
   690 char *
       
   691 Py_GetExecPrefix(void)
       
   692 {
       
   693 	return Py_GetPrefix();
       
   694 }
       
   695 
       
   696 char *
       
   697 Py_GetProgramFullPath(void)
       
   698 {
       
   699 	if (!module_search_path)
       
   700 		calculate_path();
       
   701 	return progpath;
       
   702 }