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