AppPkg/Applications/Python: Deleted obsolete and incomplete PyMod-2.7.1. Changes to enable compilation using GCC 4.4 on both Windows and Linux hosts. Signed-off-by: daryl.mcdaniel@intel.com Reviewed-by: jaben.carsey@intel.com git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@13147 6f19259b-4bc3-4df7-8a09-765794883524
		
			
				
	
	
		
			726 lines
		
	
	
		
			22 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			726 lines
		
	
	
		
			22 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/** @file
 | 
						|
    Return the initial module search path.
 | 
						|
 | 
						|
    Search in specified locations for the associated Python libraries.
 | 
						|
 | 
						|
    Py_GetPath returns module_search_path.
 | 
						|
    Py_GetPrefix returns PREFIX
 | 
						|
    Py_GetExec_Prefix returns PREFIX
 | 
						|
    Py_GetProgramFullPath returns the full path to the python executable.
 | 
						|
 | 
						|
    These are built dynamically so that the proper volume name can be prefixed
 | 
						|
    to the paths.
 | 
						|
 | 
						|
    For the EDK II, UEFI, implementation of Python, PREFIX and EXEC_PREFIX
 | 
						|
    are set as follows:
 | 
						|
      PREFIX      = /Efi/StdLib
 | 
						|
      EXEC_PREFIX = PREFIX
 | 
						|
 | 
						|
    The following final paths are assumed:
 | 
						|
      /Efi/Tools/Python.efi                     The Python executable.
 | 
						|
      /Efi/StdLib/lib/python.VERSION            The platform independent Python modules.
 | 
						|
      /Efi/StdLib/lib/python.VERSION/dynalib    Dynamically loadable Python extension modules.
 | 
						|
 | 
						|
    Copyright (c) 2011 - 2012, Intel Corporation. All rights reserved.<BR>
 | 
						|
    This program and the accompanying materials are licensed and made available under
 | 
						|
    the terms and conditions of the BSD License that accompanies this distribution.
 | 
						|
    The full text of the license may be found at
 | 
						|
    http://opensource.org/licenses/bsd-license.
 | 
						|
 | 
						|
    THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
 | 
						|
    WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 | 
						|
**/
 | 
						|
#include <Python.h>
 | 
						|
#include <osdefs.h>
 | 
						|
#include  <ctype.h>
 | 
						|
 | 
						|
#ifdef __cplusplus
 | 
						|
 extern "C" {
 | 
						|
#endif
 | 
						|
 | 
						|
/* VERSION must be at least two characters long. */
 | 
						|
#ifndef VERSION
 | 
						|
  #define VERSION     "27"
 | 
						|
#endif
 | 
						|
 | 
						|
#ifndef VPATH
 | 
						|
  #define VPATH       "."
 | 
						|
#endif
 | 
						|
 | 
						|
/* Search path entry delimiter */
 | 
						|
#ifdef DELIM
 | 
						|
  #define sDELIM        ";"
 | 
						|
#endif
 | 
						|
 | 
						|
#ifndef PREFIX
 | 
						|
  #define PREFIX      "/Efi/StdLib"
 | 
						|
#endif
 | 
						|
 | 
						|
#ifndef EXEC_PREFIX
 | 
						|
  #define EXEC_PREFIX PREFIX
 | 
						|
#endif
 | 
						|
 | 
						|
#ifndef   LIBPYTHON
 | 
						|
  #define   LIBPYTHON     "lib/python." VERSION
 | 
						|
#endif
 | 
						|
 | 
						|
#ifndef PYTHONPATH
 | 
						|
  #ifdef HAVE_ENVIRONMENT_OPS
 | 
						|
    #define PYTHONPATH  PREFIX LIBPYTHON sDELIM \
 | 
						|
                        EXEC_PREFIX LIBPYTHON "/lib-dynload"
 | 
						|
  #else
 | 
						|
    #define PYTHONPATH  LIBPYTHON
 | 
						|
  #endif
 | 
						|
#endif
 | 
						|
 | 
						|
#ifndef LANDMARK
 | 
						|
#define LANDMARK    "os.py"
 | 
						|
#endif
 | 
						|
 | 
						|
static char   prefix[MAXPATHLEN+1];
 | 
						|
static char   exec_prefix[MAXPATHLEN+1];
 | 
						|
static char   progpath[MAXPATHLEN+1];
 | 
						|
static char  *module_search_path          = NULL;
 | 
						|
static char   lib_python[]                = LIBPYTHON;
 | 
						|
static char   volume_name[32]             = { 0 };
 | 
						|
 | 
						|
/** Determine if "ch" is a separator character.
 | 
						|
 | 
						|
    @param[in]  ch      The character to test.
 | 
						|
 | 
						|
    @retval     TRUE    ch is a separator character.
 | 
						|
    @retval     FALSE   ch is NOT a separator character.
 | 
						|
**/
 | 
						|
static int
 | 
						|
is_sep(char ch)
 | 
						|
{
 | 
						|
#ifdef ALTSEP
 | 
						|
  return ch == SEP || ch == ALTSEP;
 | 
						|
#else
 | 
						|
  return ch == SEP;
 | 
						|
#endif
 | 
						|
}
 | 
						|
 | 
						|
/** Reduce a path by its last element.
 | 
						|
 | 
						|
    The last element (everything to the right of the last separator character)
 | 
						|
    in the path, dir, is removed from the path.  Parameter dir is modified in place.
 | 
						|
 | 
						|
    @param[in,out]    dir   Pointer to the path to modify.
 | 
						|
**/
 | 
						|
static void
 | 
						|
reduce(char *dir)
 | 
						|
{
 | 
						|
    size_t i = strlen(dir);
 | 
						|
    while (i > 0 && !is_sep(dir[i]))
 | 
						|
        --i;
 | 
						|
    dir[i] = '\0';
 | 
						|
}
 | 
						|
 | 
						|
#ifndef UEFI_C_SOURCE
 | 
						|
/** Does filename point to a file and not directory?
 | 
						|
 | 
						|
    @param[in]    filename    The fully qualified path to the object to test.
 | 
						|
 | 
						|
    @retval       0     Filename was not found, or is a directory.
 | 
						|
    @retval       1     Filename refers to a regular file.
 | 
						|
**/
 | 
						|
static int
 | 
						|
isfile(char *filename)
 | 
						|
{
 | 
						|
    struct stat buf;
 | 
						|
    if (stat(filename, &buf) != 0) {
 | 
						|
      return 0;
 | 
						|
    }
 | 
						|
    //if (!S_ISREG(buf.st_mode))
 | 
						|
    if (S_ISDIR(buf.st_mode)) {
 | 
						|
      return 0;
 | 
						|
    }
 | 
						|
    return 1;
 | 
						|
}
 | 
						|
 | 
						|
/** Determine if filename refers to a Python module.
 | 
						|
 | 
						|
    A Python module is indicated if the file exists, or if the file with
 | 
						|
    'o' or 'c' appended exists.
 | 
						|
 | 
						|
    @param[in]    filename    The fully qualified path to the object to test.
 | 
						|
 | 
						|
    @retval       0
 | 
						|
**/
 | 
						|
static int
 | 
						|
ismodule(char *filename)
 | 
						|
{
 | 
						|
  if (isfile(filename)) {
 | 
						|
    //if (Py_VerboseFlag) PySys_WriteStderr("%s[%d]: file = \"%s\"\n", __func__, __LINE__, filename);
 | 
						|
    return 1;
 | 
						|
  }
 | 
						|
 | 
						|
    /* Check for the compiled version of prefix. */
 | 
						|
    if (strlen(filename) < MAXPATHLEN) {
 | 
						|
        strcat(filename, Py_OptimizeFlag ? "o" : "c");
 | 
						|
        if (isfile(filename)) {
 | 
						|
          return 1;
 | 
						|
        }
 | 
						|
    }
 | 
						|
    return 0;
 | 
						|
}
 | 
						|
 | 
						|
/** Does filename point to a directory?
 | 
						|
 | 
						|
    @param[in]    filename    The fully qualified path to the object to test.
 | 
						|
 | 
						|
    @retval       0     Filename was not found, or is not a regular file.
 | 
						|
    @retval       1     Filename refers to a directory.
 | 
						|
**/
 | 
						|
static int
 | 
						|
isdir(char *filename)
 | 
						|
{
 | 
						|
    struct stat buf;
 | 
						|
 | 
						|
    if (stat(filename, &buf) != 0)
 | 
						|
        return 0;
 | 
						|
 | 
						|
    if (!S_ISDIR(buf.st_mode))
 | 
						|
        return 0;
 | 
						|
 | 
						|
    return 1;
 | 
						|
}
 | 
						|
#endif  /* UEFI_C_SOURCE */
 | 
						|
 | 
						|
/** Determine if a path is absolute, or not.
 | 
						|
    An absolute path consists of a volume name, "VOL:", followed by a rooted path,
 | 
						|
    "/path/elements".  If both of these components are present, the path is absolute.
 | 
						|
 | 
						|
    Let P be a pointer to the path to test.
 | 
						|
    Let A be a pointer to the first ':' in P.
 | 
						|
    Let B be a pointer to the first '/' or '\\' in P.
 | 
						|
 | 
						|
    If A and B are not NULL
 | 
						|
      If (A-P+1) == (B-P) then the path is absolute.
 | 
						|
    Otherwise, the path is NOT absolute.
 | 
						|
 | 
						|
    @param[in]  path    The path to test.
 | 
						|
 | 
						|
    @retval     -1      Path is absolute but lacking volume name.
 | 
						|
    @retval      0      Path is NOT absolute.
 | 
						|
    @retval      1      Path is absolute.
 | 
						|
*/
 | 
						|
static int
 | 
						|
is_absolute(char *path)
 | 
						|
{
 | 
						|
  char  *A;
 | 
						|
  char  *B;
 | 
						|
 | 
						|
  A = strchr(path, ':');
 | 
						|
  B = strpbrk(path, "/\\");
 | 
						|
 | 
						|
  if(B != NULL) {
 | 
						|
    if(A == NULL) {
 | 
						|
      if(B == path) {
 | 
						|
        return -1;
 | 
						|
      }
 | 
						|
    }
 | 
						|
    else {
 | 
						|
      if(((A - path) + 1) == (B - path)) {
 | 
						|
        return 1;
 | 
						|
      }
 | 
						|
    }
 | 
						|
  }
 | 
						|
  return 0;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/** Add a path component, by appending stuff to buffer.
 | 
						|
    buffer must have at least MAXPATHLEN + 1 bytes allocated, and contain a
 | 
						|
    NUL-terminated string with no more than MAXPATHLEN characters (not counting
 | 
						|
    the trailing NUL).  It's a fatal error if it contains a string longer than
 | 
						|
    that (callers must be careful!).  If these requirements are met, it's
 | 
						|
    guaranteed that buffer will still be a NUL-terminated string with no more
 | 
						|
    than MAXPATHLEN characters at exit.  If stuff is too long, only as much of
 | 
						|
    stuff as fits will be appended.
 | 
						|
 | 
						|
    @param[in,out]    buffer    The path to be extended.
 | 
						|
    @param[in]        stuff     The stuff to join onto the path.
 | 
						|
*/
 | 
						|
static void
 | 
						|
joinpath(char *buffer, char *stuff)
 | 
						|
{
 | 
						|
  size_t n, k;
 | 
						|
 | 
						|
  k = 0;
 | 
						|
  if (is_absolute(stuff) == 1) {
 | 
						|
    n = 0;
 | 
						|
  }
 | 
						|
  else {
 | 
						|
    n = strlen(buffer);
 | 
						|
    if(n == 0) {
 | 
						|
      strncpy(buffer, volume_name, MAXPATHLEN);
 | 
						|
      n = strlen(buffer);
 | 
						|
    }
 | 
						|
    /* We must not use an else clause here because we want to test n again.
 | 
						|
        volume_name may have been empty.
 | 
						|
    */
 | 
						|
    if (n > 0 && n < MAXPATHLEN) {
 | 
						|
      if(!is_sep(buffer[n-1])) {
 | 
						|
        buffer[n++] = SEP;
 | 
						|
      }
 | 
						|
      if(is_sep(stuff[0]))   ++stuff;
 | 
						|
    }
 | 
						|
  }
 | 
						|
  if (n > MAXPATHLEN)
 | 
						|
    Py_FatalError("buffer overflow in getpath.c's joinpath()");
 | 
						|
  k = strlen(stuff);
 | 
						|
  if (n + k > MAXPATHLEN)
 | 
						|
    k = MAXPATHLEN - n;
 | 
						|
  strncpy(buffer+n, stuff, k);
 | 
						|
  buffer[n+k] = '\0';
 | 
						|
}
 | 
						|
 | 
						|
/** Is filename an executable file?
 | 
						|
 | 
						|
    An executable file:
 | 
						|
      1) exists
 | 
						|
      2) is a file, not a directory
 | 
						|
      3) has a name ending with ".efi"
 | 
						|
      4) Only has a single '.' in the name.
 | 
						|
 | 
						|
    If basename(filename) does not contain a '.', append ".efi" to filename
 | 
						|
    If filename ends in ".efi", it is executable, else it isn't.
 | 
						|
 | 
						|
    This routine is used to when searching for the file named by argv[0].
 | 
						|
    As such, there is no need to search for extensions other than ".efi".
 | 
						|
 | 
						|
    @param[in]    filename      The name of the file to test.  It may, or may not, have an extension.
 | 
						|
 | 
						|
    @retval       0     filename already has a path other than ".efi", or it doesn't exist, or is a directory.
 | 
						|
    @retval       1     filename refers to an executable file.
 | 
						|
**/
 | 
						|
static int
 | 
						|
isxfile(char *filename)
 | 
						|
{
 | 
						|
    struct stat  buf;
 | 
						|
    char        *bn;
 | 
						|
    char        *newbn;
 | 
						|
    int          bnlen;
 | 
						|
 | 
						|
    bn = basename(filename);            // Separate off the file name component
 | 
						|
    reduce(filename);                   // and isolate the path component
 | 
						|
    bnlen = strlen(bn);
 | 
						|
    newbn = strrchr(bn, '.');           // Does basename contain a period?
 | 
						|
    if(newbn == NULL) {                   // Does NOT contain a period.
 | 
						|
      newbn = &bn[bnlen];
 | 
						|
      strncpyX(newbn, ".efi", MAXPATHLEN - bnlen);    // append ".efi" to basename
 | 
						|
      bnlen += 4;
 | 
						|
    }
 | 
						|
    else if(strcmp(newbn, ".efi") != 0) {
 | 
						|
      return 0;                         // File can not be executable.
 | 
						|
    }
 | 
						|
    joinpath(filename, bn);             // Stitch path and file name back together
 | 
						|
 | 
						|
    if (stat(filename, &buf) != 0) {    // Now, verify that file exists
 | 
						|
      return 0;
 | 
						|
    }
 | 
						|
    if(S_ISDIR(buf.st_mode)) {          // And it is not a directory.
 | 
						|
      return 0;
 | 
						|
    }
 | 
						|
 | 
						|
    return 1;
 | 
						|
}
 | 
						|
 | 
						|
/** Copy p into path, ensuring that the result is an absolute path.
 | 
						|
 | 
						|
    copy_absolute requires that path be allocated at least
 | 
						|
    MAXPATHLEN + 1 bytes and that p be no more than MAXPATHLEN bytes.
 | 
						|
 | 
						|
    @param[out]     path    Destination to receive the absolute path.
 | 
						|
    @param[in]      p       Path to be tested and possibly converted.
 | 
						|
**/
 | 
						|
static void
 | 
						|
copy_absolute(char *path, char *p)
 | 
						|
{
 | 
						|
  if (is_absolute(p) == 1)
 | 
						|
        strcpy(path, p);
 | 
						|
  else {
 | 
						|
    if (!getcwd(path, MAXPATHLEN)) {
 | 
						|
      /* unable to get the current directory */
 | 
						|
      if(volume_name[0] != 0) {
 | 
						|
        strcpy(path, volume_name);
 | 
						|
        joinpath(path, p);
 | 
						|
      }
 | 
						|
      else
 | 
						|
        strcpy(path, p);
 | 
						|
      return;
 | 
						|
    }
 | 
						|
    if (p[0] == '.' && is_sep(p[1]))
 | 
						|
        p += 2;
 | 
						|
    joinpath(path, p);
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
/** Modify path so that the result is an absolute path.
 | 
						|
    absolutize() requires that path be allocated at least MAXPATHLEN+1 bytes.
 | 
						|
 | 
						|
    @param[in,out]    path    The path to be made absolute.
 | 
						|
*/
 | 
						|
static void
 | 
						|
absolutize(char *path)
 | 
						|
{
 | 
						|
    char buffer[MAXPATHLEN + 1];
 | 
						|
 | 
						|
    if (is_absolute(path) == 1)
 | 
						|
        return;
 | 
						|
    copy_absolute(buffer, path);
 | 
						|
    strcpy(path, buffer);
 | 
						|
}
 | 
						|
 | 
						|
/** Extract the volume name from a path.
 | 
						|
 | 
						|
    @param[out]   Dest    Pointer to location in which to store the extracted volume name.
 | 
						|
    @param[in]    path    Pointer to the path to extract the volume name from.
 | 
						|
**/
 | 
						|
static void
 | 
						|
set_volume(char *Dest, char *path)
 | 
						|
{
 | 
						|
  size_t    VolLen;
 | 
						|
 | 
						|
  if(is_absolute(path)) {
 | 
						|
    VolLen = strcspn(path, "/\\:");
 | 
						|
    if((VolLen != 0) && (path[VolLen] == ':')) {
 | 
						|
      (void) strncpyX(Dest, path, VolLen + 1);
 | 
						|
    }
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/** Determine paths.
 | 
						|
 | 
						|
    Two directories must be found, the platform independent directory
 | 
						|
    (prefix), containing the common .py and .pyc files, and the platform
 | 
						|
    dependent directory (exec_prefix), containing the shared library
 | 
						|
    modules.  Note that prefix and exec_prefix are the same directory
 | 
						|
    for UEFI installations.
 | 
						|
 | 
						|
    Separate searches are carried out for prefix and exec_prefix.
 | 
						|
    Each search tries a number of different locations until a ``landmark''
 | 
						|
    file or directory is found.  If no prefix or exec_prefix is found, a
 | 
						|
    warning message is issued and the preprocessor defined PREFIX and
 | 
						|
    EXEC_PREFIX are used (even though they may not work); python carries on
 | 
						|
    as best as is possible, but some imports may fail.
 | 
						|
 | 
						|
    Before any searches are done, the location of the executable is
 | 
						|
    determined.  If argv[0] has one or more slashes in it, it is used
 | 
						|
    unchanged.  Otherwise, it must have been invoked from the shell's path,
 | 
						|
    so we search %PATH% for the named executable and use that.  If the
 | 
						|
    executable was not found on %PATH% (or there was no %PATH% environment
 | 
						|
    variable), the original argv[0] string is used.
 | 
						|
 | 
						|
    Finally, argv0_path is set to the directory containing the executable
 | 
						|
    (i.e. the last component is stripped).
 | 
						|
 | 
						|
    With argv0_path in hand, we perform a number of steps.  The same steps
 | 
						|
    are performed for prefix and for exec_prefix, but with a different
 | 
						|
    landmark.
 | 
						|
 | 
						|
    The prefix landmark will always be lib/python.VERSION/os.py and the
 | 
						|
    exec_prefix will always be lib/python.VERSION/dynaload, where VERSION
 | 
						|
    is Python's version number as defined at the beginning of this file.
 | 
						|
 | 
						|
    First. See if the %PYTHONHOME% environment variable points to the
 | 
						|
    installed location of the Python libraries.  If %PYTHONHOME% is set, then
 | 
						|
    it points to prefix and exec_prefix.  %PYTHONHOME% can be a single
 | 
						|
    directory, which is used for both, or the prefix and exec_prefix
 | 
						|
    directories separated by the DELIM character.
 | 
						|
 | 
						|
    Next. Search the directories pointed to by the preprocessor variables
 | 
						|
    PREFIX and EXEC_PREFIX.  These paths are prefixed with the volume name
 | 
						|
    extracted from argv0_path.  The volume names correspond to the UEFI
 | 
						|
    shell "map" names.
 | 
						|
 | 
						|
    That's it!
 | 
						|
 | 
						|
    Well, almost.  Once we have determined prefix and exec_prefix, the
 | 
						|
    preprocessor variable PYTHONPATH is used to construct a path.  Each
 | 
						|
    relative path on PYTHONPATH is prefixed with prefix.  Then the directory
 | 
						|
    containing the shared library modules is appended.  The environment
 | 
						|
    variable $PYTHONPATH is inserted in front of it all.  Finally, the
 | 
						|
    prefix and exec_prefix globals are tweaked so they reflect the values
 | 
						|
    expected by other code, by stripping the "lib/python$VERSION/..." stuff
 | 
						|
    off.  This seems to make more sense given that currently the only
 | 
						|
    known use of sys.prefix and sys.exec_prefix is for the ILU installation
 | 
						|
    process to find the installed Python tree.
 | 
						|
 | 
						|
    The final, fully resolved, paths should look something like:
 | 
						|
      fs0:/Efi/Tools/python.efi
 | 
						|
      fs0:/Efi/StdLib/lib/python27
 | 
						|
      fs0:/Efi/StdLib/lib/python27/dynaload
 | 
						|
 | 
						|
**/
 | 
						|
static void
 | 
						|
calculate_path(void)
 | 
						|
{
 | 
						|
    extern char *Py_GetProgramName(void);
 | 
						|
 | 
						|
    static char delimiter[2] = {DELIM, '\0'};
 | 
						|
    static char separator[2] = {SEP, '\0'};
 | 
						|
    char *pythonpath = PYTHONPATH;
 | 
						|
    char *rtpypath = Py_GETENV("PYTHONPATH");
 | 
						|
    //char *home = Py_GetPythonHome();
 | 
						|
    char *path = getenv("PATH");
 | 
						|
    char *prog = Py_GetProgramName();
 | 
						|
    char argv0_path[MAXPATHLEN+1];
 | 
						|
    char zip_path[MAXPATHLEN+1];
 | 
						|
    char *buf;
 | 
						|
    size_t bufsz;
 | 
						|
    size_t prefixsz;
 | 
						|
    char *defpath;
 | 
						|
 | 
						|
 | 
						|
/* ###########################################################################
 | 
						|
      Determine path to the Python.efi binary.
 | 
						|
      Produces progpath, argv0_path, and volume_name.
 | 
						|
########################################################################### */
 | 
						|
 | 
						|
    /* If there is no slash in the argv0 path, then we have to
 | 
						|
     * assume python is on the user's $PATH, since there's no
 | 
						|
     * other way to find a directory to start the search from.  If
 | 
						|
     * $PATH isn't exported, you lose.
 | 
						|
     */
 | 
						|
    if (strchr(prog, SEP))
 | 
						|
            strncpy(progpath, prog, MAXPATHLEN);
 | 
						|
    else if (path) {
 | 
						|
      while (1) {
 | 
						|
        char *delim = strchr(path, DELIM);
 | 
						|
 | 
						|
        if (delim) {
 | 
						|
                size_t len = delim - path;
 | 
						|
                if (len > MAXPATHLEN)
 | 
						|
                        len = MAXPATHLEN;
 | 
						|
                strncpy(progpath, path, len);
 | 
						|
                *(progpath + len) = '\0';
 | 
						|
        }
 | 
						|
        else
 | 
						|
                strncpy(progpath, path, MAXPATHLEN);
 | 
						|
 | 
						|
        joinpath(progpath, prog);
 | 
						|
        if (isxfile(progpath))
 | 
						|
                break;
 | 
						|
 | 
						|
        if (!delim) {
 | 
						|
                progpath[0] = '\0';
 | 
						|
                break;
 | 
						|
        }
 | 
						|
        path = delim + 1;
 | 
						|
      }
 | 
						|
    }
 | 
						|
    else
 | 
						|
            progpath[0] = '\0';
 | 
						|
    if ( (!is_absolute(progpath)) && (progpath[0] != '\0') )
 | 
						|
            absolutize(progpath);
 | 
						|
    strncpy(argv0_path, progpath, MAXPATHLEN);
 | 
						|
    argv0_path[MAXPATHLEN] = '\0';
 | 
						|
    set_volume(volume_name, argv0_path);
 | 
						|
 | 
						|
    reduce(argv0_path);
 | 
						|
    /* At this point, argv0_path is guaranteed to be less than
 | 
						|
       MAXPATHLEN bytes long.
 | 
						|
    */
 | 
						|
 | 
						|
/* ###########################################################################
 | 
						|
      Build the FULL prefix string, including volume name.
 | 
						|
      This is the full path to the platform independent libraries.
 | 
						|
########################################################################### */
 | 
						|
 | 
						|
        strncpy(prefix, volume_name, MAXPATHLEN);
 | 
						|
        joinpath(prefix, PREFIX);
 | 
						|
        joinpath(prefix, lib_python);
 | 
						|
 | 
						|
/* ###########################################################################
 | 
						|
      Build the FULL path to the zipped-up Python library.
 | 
						|
########################################################################### */
 | 
						|
 | 
						|
    strncpy(zip_path, prefix, MAXPATHLEN);
 | 
						|
    zip_path[MAXPATHLEN] = '\0';
 | 
						|
    reduce(zip_path);
 | 
						|
    joinpath(zip_path, "python00.zip");
 | 
						|
    bufsz = strlen(zip_path);   /* Replace "00" with version */
 | 
						|
    zip_path[bufsz - 6] = VERSION[0];
 | 
						|
    zip_path[bufsz - 5] = VERSION[1];
 | 
						|
 | 
						|
/* ###########################################################################
 | 
						|
      Build the FULL path to dynamically loadable libraries.
 | 
						|
########################################################################### */
 | 
						|
 | 
						|
        strncpy(exec_prefix, volume_name, MAXPATHLEN);
 | 
						|
        joinpath(exec_prefix, EXEC_PREFIX);
 | 
						|
        joinpath(exec_prefix, lib_python);
 | 
						|
        joinpath(exec_prefix, "lib-dynload");
 | 
						|
 | 
						|
/* ###########################################################################
 | 
						|
      Build the module search path.
 | 
						|
########################################################################### */
 | 
						|
 | 
						|
    /* Reduce prefix and exec_prefix to their essence,
 | 
						|
     * e.g. /usr/local/lib/python1.5 is reduced to /usr/local.
 | 
						|
     * If we're loading relative to the build directory,
 | 
						|
     * return the compiled-in defaults instead.
 | 
						|
     */
 | 
						|
    reduce(prefix);
 | 
						|
    reduce(prefix);
 | 
						|
    /* The prefix is the root directory, but reduce() chopped
 | 
						|
     * off the "/". */
 | 
						|
    if (!prefix[0]) {
 | 
						|
      strcpy(prefix, volume_name);
 | 
						|
    }
 | 
						|
    bufsz = strlen(prefix);
 | 
						|
    if(prefix[bufsz-1] == ':') {
 | 
						|
      prefix[bufsz] = SEP;
 | 
						|
      prefix[bufsz+1] = 0;
 | 
						|
    }
 | 
						|
 | 
						|
    /* Calculate size of return buffer.
 | 
						|
     */
 | 
						|
    defpath = pythonpath;
 | 
						|
    bufsz = 0;
 | 
						|
 | 
						|
    if (rtpypath)
 | 
						|
        bufsz += strlen(rtpypath) + 1;
 | 
						|
 | 
						|
    prefixsz = strlen(prefix) + 1;
 | 
						|
 | 
						|
    while (1) {
 | 
						|
        char *delim = strchr(defpath, DELIM);
 | 
						|
 | 
						|
        if (is_absolute(defpath) == 0)
 | 
						|
            /* Paths are relative to prefix */
 | 
						|
            bufsz += prefixsz;
 | 
						|
 | 
						|
        if (delim)
 | 
						|
            bufsz += delim - defpath + 1;
 | 
						|
        else {
 | 
						|
            bufsz += strlen(defpath) + 1;
 | 
						|
            break;
 | 
						|
        }
 | 
						|
        defpath = delim + 1;
 | 
						|
    }
 | 
						|
 | 
						|
    bufsz += strlen(zip_path) + 1;
 | 
						|
    bufsz += strlen(exec_prefix) + 1;
 | 
						|
 | 
						|
    /* This is the only malloc call in this file */
 | 
						|
    buf = (char *)PyMem_Malloc(bufsz);
 | 
						|
 | 
						|
    if (buf == NULL) {
 | 
						|
        /* We can't exit, so print a warning and limp along */
 | 
						|
        fprintf(stderr, "Not enough memory for dynamic PYTHONPATH.\n");
 | 
						|
        fprintf(stderr, "Using default static PYTHONPATH.\n");
 | 
						|
        module_search_path = PYTHONPATH;
 | 
						|
    }
 | 
						|
    else {
 | 
						|
        /* Run-time value of $PYTHONPATH goes first */
 | 
						|
        if (rtpypath) {
 | 
						|
            strcpy(buf, rtpypath);
 | 
						|
            strcat(buf, delimiter);
 | 
						|
        }
 | 
						|
        else
 | 
						|
            buf[0] = '\0';
 | 
						|
 | 
						|
        /* Next is the default zip path */
 | 
						|
        strcat(buf, zip_path);
 | 
						|
        strcat(buf, delimiter);
 | 
						|
 | 
						|
        /* Next goes merge of compile-time $PYTHONPATH with
 | 
						|
         * dynamically located prefix.
 | 
						|
         */
 | 
						|
        defpath = pythonpath;
 | 
						|
        while (1) {
 | 
						|
            char *delim = strchr(defpath, DELIM);
 | 
						|
 | 
						|
            if (is_absolute(defpath) != 1) {
 | 
						|
                strcat(buf, prefix);
 | 
						|
                strcat(buf, separator);
 | 
						|
            }
 | 
						|
 | 
						|
            if (delim) {
 | 
						|
                size_t len = delim - defpath + 1;
 | 
						|
                size_t end = strlen(buf) + len;
 | 
						|
                strncat(buf, defpath, len);
 | 
						|
                *(buf + end) = '\0';
 | 
						|
            }
 | 
						|
            else {
 | 
						|
                strcat(buf, defpath);
 | 
						|
                break;
 | 
						|
            }
 | 
						|
            defpath = delim + 1;
 | 
						|
        }
 | 
						|
        strcat(buf, delimiter);
 | 
						|
 | 
						|
        /* Finally, on goes the directory for dynamic-load modules */
 | 
						|
        strcat(buf, exec_prefix);
 | 
						|
 | 
						|
        /* And publish the results */
 | 
						|
        module_search_path = buf;
 | 
						|
    }
 | 
						|
        /*  At this point, exec_prefix is set to VOL:/Efi/StdLib/lib/python.27/dynalib.
 | 
						|
            We want to get back to the root value, so we have to remove the final three
 | 
						|
            segments to get VOL:/Efi/StdLib.  Because we don't know what VOL is, and
 | 
						|
            EXEC_PREFIX is also indeterminate, we just remove the three final segments.
 | 
						|
        */
 | 
						|
        reduce(exec_prefix);
 | 
						|
        reduce(exec_prefix);
 | 
						|
        reduce(exec_prefix);
 | 
						|
        if (!exec_prefix[0]) {
 | 
						|
          strcpy(exec_prefix, volume_name);
 | 
						|
        }
 | 
						|
        bufsz = strlen(exec_prefix);
 | 
						|
        if(exec_prefix[bufsz-1] == ':') {
 | 
						|
          exec_prefix[bufsz] = SEP;
 | 
						|
          exec_prefix[bufsz+1] = 0;
 | 
						|
        }
 | 
						|
    if (Py_VerboseFlag) PySys_WriteStderr("%s[%d]: module_search_path = \"%s\"\n", __func__, __LINE__, module_search_path);
 | 
						|
    if (Py_VerboseFlag) PySys_WriteStderr("%s[%d]: prefix             = \"%s\"\n", __func__, __LINE__, prefix);
 | 
						|
    if (Py_VerboseFlag) PySys_WriteStderr("%s[%d]: exec_prefix        = \"%s\"\n", __func__, __LINE__, exec_prefix);
 | 
						|
    if (Py_VerboseFlag) PySys_WriteStderr("%s[%d]: progpath           = \"%s\"\n", __func__, __LINE__, progpath);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/* External interface */
 | 
						|
 | 
						|
char *
 | 
						|
Py_GetPath(void)
 | 
						|
{
 | 
						|
    if (!module_search_path)
 | 
						|
        calculate_path();
 | 
						|
    return module_search_path;
 | 
						|
}
 | 
						|
 | 
						|
char *
 | 
						|
Py_GetPrefix(void)
 | 
						|
{
 | 
						|
    if (!module_search_path)
 | 
						|
        calculate_path();
 | 
						|
    return prefix;
 | 
						|
}
 | 
						|
 | 
						|
char *
 | 
						|
Py_GetExecPrefix(void)
 | 
						|
{
 | 
						|
    if (!module_search_path)
 | 
						|
        calculate_path();
 | 
						|
    return exec_prefix;
 | 
						|
}
 | 
						|
 | 
						|
char *
 | 
						|
Py_GetProgramFullPath(void)
 | 
						|
{
 | 
						|
    if (!module_search_path)
 | 
						|
        calculate_path();
 | 
						|
    return progpath;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
#ifdef __cplusplus
 | 
						|
}
 | 
						|
#endif
 | 
						|
 |