Ignore:
Timestamp:
Mar 19, 2014, 11:31:01 PM (11 years ago)
Author:
dmik
Message:

python: Merge vendor 2.7.6 to trunk.

Location:
python/trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • python/trunk

  • python/trunk/PC/getpathp.c

    r2 r391  
    55/* ----------------------------------------------------------------
    66   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 
     7   This describes how sys.path is formed on Windows.  It describes the
     8   functionality, not the implementation (ie, the order in which these
    99   are actually fetched is different)
    1010
     
    2525     is set, we believe it.  Otherwise, we use the path of our host .EXE's
    2626     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, 
     27     - If we DO have a Python Home: The relevant sub-directories (Lib,
    2828       plat-win, lib-tk, etc) are based on the Python Home
    2929     - If we DO NOT have a Python Home, the core Python Path is
    30        loaded from the registry.  This is the main PythonPath key, 
     30       loaded from the registry.  This is the main PythonPath key,
    3131       and both HKLM and HKCU are combined to form the path)
    3232
    3333   * Iff - we can not locate the Python Home, have not had a PYTHONPATH
    3434     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 
     35     we can assume is a good path), a default path with relative entries is
    3636     used (eg. .\Lib;.\plat-win, etc)
    3737
     
    4343    ignored.  Other "application paths" in the registry are always read.
    4444
    45   * When Python is hosted in another exe (different directory, embedded via 
     45  * When Python is hosted in another exe (different directory, embedded via
    4646    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 
     47    the registry is used.  Other "application paths" in the registry are
    4848    always read.
    4949
     
    9393
    9494static int
    95 is_sep(char ch) /* determine if "ch" is a separator character */
     95is_sep(char ch) /* determine if "ch" is a separator character */
    9696{
    9797#ifdef ALTSEP
    98         return ch == SEP || ch == ALTSEP;
     98    return ch == SEP || ch == ALTSEP;
    9999#else
    100         return ch == SEP;
     100    return ch == SEP;
    101101#endif
    102102}
     
    108108reduce(char *dir)
    109109{
    110         size_t i = strlen(dir);
    111         while (i > 0 && !is_sep(dir[i]))
    112                 --i;
    113         dir[i] = '\0';
    114 }
    115        
     110    size_t i = strlen(dir);
     111    while (i > 0 && !is_sep(dir[i]))
     112        --i;
     113    dir[i] = '\0';
     114}
     115
    116116
    117117static int
    118118exists(char *filename)
    119119{
    120         struct stat buf;
    121         return stat(filename, &buf) == 0;
    122 }
    123 
    124 /* Assumes 'filename' MAXPATHLEN+1 bytes long - 
     120    struct stat buf;
     121    return stat(filename, &buf) == 0;
     122}
     123
     124/* Assumes 'filename' MAXPATHLEN+1 bytes long -
    125125   may extend 'filename' by one character.
    126126*/
    127127static 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;
     128ismodule(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;
    140140}
    141141
     
    152152join(char *buffer, char *stuff)
    153153{
    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';
     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';
    169169}
    170170
     
    176176gotlandmark(char *landmark)
    177177{
    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. 
     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.
    189189   assumption provided by only caller, calculate_path() */
    190190static int
    191191search_for_prefix(char *argv0_path, char *landmark)
    192192{
    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;
     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;
    201201}
    202202
     
    224224getpythonregpath(HKEY keyBase, int skipcore)
    225225{
    226         HKEY newKey = 0;
    227         DWORD dataSize = 0;
    228         DWORD numKeys = 0;
    229         LONG rc;
    230         char *retval = NULL;
    231         TCHAR *dataBuf = NULL;
    232         static const TCHAR keyPrefix[] = _T("Software\\Python\\PythonCore\\");
    233         static const TCHAR keySuffix[] = _T("\\PythonPath");
    234         size_t versionLen;
    235         DWORD index;
    236         TCHAR *keyBuf = NULL;
    237         TCHAR *keyBufPtr;
    238         TCHAR **ppPaths = NULL;
    239 
    240         /* Tried to use sysget("winver") but here is too early :-( */
    241         versionLen = _tcslen(PyWin_DLLVersionString);
    242         /* Space for all the chars, plus one \0 */
    243         keyBuf = keyBufPtr = malloc(sizeof(keyPrefix) +
    244                                     sizeof(TCHAR)*(versionLen-1) +
    245                                     sizeof(keySuffix));
    246         if (keyBuf==NULL) goto done;
    247 
    248         memcpy(keyBufPtr, keyPrefix, sizeof(keyPrefix)-sizeof(TCHAR));
    249         keyBufPtr += sizeof(keyPrefix)/sizeof(TCHAR) - 1;
    250         memcpy(keyBufPtr, PyWin_DLLVersionString, versionLen * sizeof(TCHAR));
    251         keyBufPtr += versionLen;
    252         /* NULL comes with this one! */
    253         memcpy(keyBufPtr, keySuffix, sizeof(keySuffix));
    254         /* Open the root Python key */
    255         rc=RegOpenKeyEx(keyBase,
    256                         keyBuf, /* subkey */
    257                         0, /* reserved */
    258                         KEY_READ,
    259                         &newKey);
    260         if (rc!=ERROR_SUCCESS) goto done;
    261         /* Find out how big our core buffer is, and how many subkeys we have */
    262         rc = RegQueryInfoKey(newKey, NULL, NULL, NULL, &numKeys, NULL, NULL,
    263                         NULL, NULL, &dataSize, NULL, NULL);
    264         if (rc!=ERROR_SUCCESS) goto done;
    265         if (skipcore) dataSize = 0; /* Only count core ones if we want them! */
    266         /* Allocate a temp array of char buffers, so we only need to loop
    267            reading the registry once
    268         */
    269         ppPaths = malloc( sizeof(TCHAR *) * numKeys );
    270         if (ppPaths==NULL) goto done;
    271         memset(ppPaths, 0, sizeof(TCHAR *) * numKeys);
    272         /* Loop over all subkeys, allocating a temp sub-buffer. */
    273         for(index=0;index<numKeys;index++) {
    274                 TCHAR keyBuf[MAX_PATH+1];
    275                 HKEY subKey = 0;
    276                 DWORD reqdSize = MAX_PATH+1;
    277                 /* Get the sub-key name */
    278                 DWORD rc = RegEnumKeyEx(newKey, index, keyBuf, &reqdSize,
    279                                         NULL, NULL, NULL, NULL );
    280                 if (rc!=ERROR_SUCCESS) goto done;
    281                 /* Open the sub-key */
    282                 rc=RegOpenKeyEx(newKey,
    283                                                 keyBuf, /* subkey */
    284                                                 0, /* reserved */
    285                                                 KEY_READ,
    286                                                 &subKey);
    287                 if (rc!=ERROR_SUCCESS) goto done;
    288                 /* Find the value of the buffer size, malloc, then read it */
    289                 RegQueryValueEx(subKey, NULL, 0, NULL, NULL, &reqdSize);
    290                 if (reqdSize) {
    291                         ppPaths[index] = malloc(reqdSize);
    292                         if (ppPaths[index]) {
    293                                 RegQueryValueEx(subKey, NULL, 0, NULL,
    294                                                 (LPBYTE)ppPaths[index],
    295                                                 &reqdSize);
    296                                 dataSize += reqdSize + 1; /* 1 for the ";" */
    297                         }
    298                 }
    299                 RegCloseKey(subKey);
    300         }
    301 
    302         /* return null if no path to return */
    303         if (dataSize == 0) goto done;
    304 
    305         /* original datasize from RegQueryInfo doesn't include the \0 */
    306         dataBuf = malloc((dataSize+1) * sizeof(TCHAR));
    307         if (dataBuf) {
    308                 TCHAR *szCur = dataBuf;
    309                 DWORD reqdSize = dataSize;
    310                 /* Copy our collected strings */
    311                 for (index=0;index<numKeys;index++) {
    312                         if (index > 0) {
    313                                 *(szCur++) = _T(';');
    314                                 dataSize--;
    315                         }
    316                         if (ppPaths[index]) {
    317                                 Py_ssize_t len = _tcslen(ppPaths[index]);
    318                                 _tcsncpy(szCur, ppPaths[index], len);
    319                                 szCur += len;
    320                                 assert(dataSize > (DWORD)len);
    321                                 dataSize -= (DWORD)len;
    322                         }
    323                 }
    324                 if (skipcore)
    325                         *szCur = '\0';
    326                 else {
    327                         /* If we have no values, we dont need a ';' */
    328                         if (numKeys) {
    329                                 *(szCur++) = _T(';');
    330                                 dataSize--;
    331                         }
    332                         /* Now append the core path entries -
    333                            this will include the NULL
    334                         */
    335                         rc = RegQueryValueEx(newKey, NULL, 0, NULL,
    336                                              (LPBYTE)szCur, &dataSize);
    337                 }
    338                 /* And set the result - caller must free
    339                    If MBCS, it is fine as is.  If Unicode, allocate new
    340                    buffer and convert.
    341                 */
     226    HKEY newKey = 0;
     227    DWORD dataSize = 0;
     228    DWORD numKeys = 0;
     229    LONG rc;
     230    char *retval = NULL;
     231    TCHAR *dataBuf = NULL;
     232    static const TCHAR keyPrefix[] = _T("Software\\Python\\PythonCore\\");
     233    static const TCHAR keySuffix[] = _T("\\PythonPath");
     234    size_t versionLen;
     235    DWORD index;
     236    TCHAR *keyBuf = NULL;
     237    TCHAR *keyBufPtr;
     238    TCHAR **ppPaths = NULL;
     239
     240    /* Tried to use sysget("winver") but here is too early :-( */
     241    versionLen = _tcslen(PyWin_DLLVersionString);
     242    /* Space for all the chars, plus one \0 */
     243    keyBuf = keyBufPtr = malloc(sizeof(keyPrefix) +
     244                                sizeof(TCHAR)*(versionLen-1) +
     245                                sizeof(keySuffix));
     246    if (keyBuf==NULL) goto done;
     247
     248    memcpy(keyBufPtr, keyPrefix, sizeof(keyPrefix)-sizeof(TCHAR));
     249    keyBufPtr += sizeof(keyPrefix)/sizeof(TCHAR) - 1;
     250    memcpy(keyBufPtr, PyWin_DLLVersionString, versionLen * sizeof(TCHAR));
     251    keyBufPtr += versionLen;
     252    /* NULL comes with this one! */
     253    memcpy(keyBufPtr, keySuffix, sizeof(keySuffix));
     254    /* Open the root Python key */
     255    rc=RegOpenKeyEx(keyBase,
     256                    keyBuf, /* subkey */
     257            0, /* reserved */
     258            KEY_READ,
     259            &newKey);
     260    if (rc!=ERROR_SUCCESS) goto done;
     261    /* Find out how big our core buffer is, and how many subkeys we have */
     262    rc = RegQueryInfoKey(newKey, NULL, NULL, NULL, &numKeys, NULL, NULL,
     263                    NULL, NULL, &dataSize, NULL, NULL);
     264    if (rc!=ERROR_SUCCESS) goto done;
     265    if (skipcore) dataSize = 0; /* Only count core ones if we want them! */
     266    /* Allocate a temp array of char buffers, so we only need to loop
     267       reading the registry once
     268    */
     269    ppPaths = malloc( sizeof(TCHAR *) * numKeys );
     270    if (ppPaths==NULL) goto done;
     271    memset(ppPaths, 0, sizeof(TCHAR *) * numKeys);
     272    /* Loop over all subkeys, allocating a temp sub-buffer. */
     273    for(index=0;index<numKeys;index++) {
     274        TCHAR keyBuf[MAX_PATH+1];
     275        HKEY subKey = 0;
     276        DWORD reqdSize = MAX_PATH+1;
     277        /* Get the sub-key name */
     278        DWORD rc = RegEnumKeyEx(newKey, index, keyBuf, &reqdSize,
     279                                NULL, NULL, NULL, NULL );
     280        if (rc!=ERROR_SUCCESS) goto done;
     281        /* Open the sub-key */
     282        rc=RegOpenKeyEx(newKey,
     283                                        keyBuf, /* subkey */
     284                        0, /* reserved */
     285                        KEY_READ,
     286                        &subKey);
     287        if (rc!=ERROR_SUCCESS) goto done;
     288        /* Find the value of the buffer size, malloc, then read it */
     289        RegQueryValueEx(subKey, NULL, 0, NULL, NULL, &reqdSize);
     290        if (reqdSize) {
     291            ppPaths[index] = malloc(reqdSize);
     292            if (ppPaths[index]) {
     293                RegQueryValueEx(subKey, NULL, 0, NULL,
     294                                (LPBYTE)ppPaths[index],
     295                                &reqdSize);
     296                dataSize += reqdSize + 1; /* 1 for the ";" */
     297            }
     298        }
     299        RegCloseKey(subKey);
     300    }
     301
     302    /* return null if no path to return */
     303    if (dataSize == 0) goto done;
     304
     305    /* original datasize from RegQueryInfo doesn't include the \0 */
     306    dataBuf = malloc((dataSize+1) * sizeof(TCHAR));
     307    if (dataBuf) {
     308        TCHAR *szCur = dataBuf;
     309        DWORD reqdSize = dataSize;
     310        /* Copy our collected strings */
     311        for (index=0;index<numKeys;index++) {
     312            if (index > 0) {
     313                *(szCur++) = _T(';');
     314                dataSize--;
     315            }
     316            if (ppPaths[index]) {
     317                Py_ssize_t len = _tcslen(ppPaths[index]);
     318                _tcsncpy(szCur, ppPaths[index], len);
     319                szCur += len;
     320                assert(dataSize > (DWORD)len);
     321                dataSize -= (DWORD)len;
     322            }
     323        }
     324        if (skipcore)
     325            *szCur = '\0';
     326        else {
     327            /* If we have no values, we dont need a ';' */
     328            if (numKeys) {
     329                *(szCur++) = _T(';');
     330                dataSize--;
     331            }
     332            /* Now append the core path entries -
     333               this will include the NULL
     334            */
     335            rc = RegQueryValueEx(newKey, NULL, 0, NULL,
     336                                 (LPBYTE)szCur, &dataSize);
     337        }
     338        /* And set the result - caller must free
     339           If MBCS, it is fine as is.  If Unicode, allocate new
     340           buffer and convert.
     341        */
    342342#ifdef UNICODE
    343                 retval = (char *)malloc(reqdSize+1);
    344                 if (retval)
    345                         WideCharToMultiByte(CP_ACP, 0,
    346                                         dataBuf, -1, /* source */
    347                                         retval, reqdSize+1, /* dest */
    348                                         NULL, NULL);
    349                 free(dataBuf);
     343        retval = (char *)malloc(reqdSize+1);
     344        if (retval)
     345            WideCharToMultiByte(CP_ACP, 0,
     346                            dataBuf, -1, /* source */
     347                    retval, reqdSize+1, /* dest */
     348                    NULL, NULL);
     349        free(dataBuf);
    350350#else
    351                 retval = dataBuf;
    352 #endif
    353         }
     351        retval = dataBuf;
     352#endif
     353    }
    354354done:
    355         /* Loop freeing my temp buffers */
    356         if (ppPaths) {
    357                 for(index=0;index<numKeys;index++)
    358                         if (ppPaths[index]) free(ppPaths[index]);
    359                 free(ppPaths);
    360         }
    361         if (newKey)
    362                 RegCloseKey(newKey);
    363         if (keyBuf)
    364                 free(keyBuf);
    365         return retval;
     355    /* Loop freeing my temp buffers */
     356    if (ppPaths) {
     357        for(index=0;index<numKeys;index++)
     358            if (ppPaths[index]) free(ppPaths[index]);
     359        free(ppPaths);
     360    }
     361    if (newKey)
     362        RegCloseKey(newKey);
     363    if (keyBuf)
     364        free(keyBuf);
     365    return retval;
    366366}
    367367#endif /* Py_ENABLE_SHARED */
     
    371371get_progpath(void)
    372372{
    373         extern char *Py_GetProgramName(void);
    374         char *path = getenv("PATH");
    375         char *prog = Py_GetProgramName();
     373    extern char *Py_GetProgramName(void);
     374    char *path = getenv("PATH");
     375    char *prog = Py_GetProgramName();
    376376
    377377#ifdef MS_WINDOWS
    378         extern HANDLE PyWin_DLLhModule;
     378    extern HANDLE PyWin_DLLhModule;
    379379#ifdef UNICODE
    380         WCHAR wprogpath[MAXPATHLEN+1];
    381         /* Windows documents that GetModuleFileName() will "truncate",
    382            but makes no mention of the null terminator.  Play it safe.
    383            PLUS Windows itself defines MAX_PATH as the same, but anyway...
    384         */
     380    WCHAR wprogpath[MAXPATHLEN+1];
     381    /* Windows documents that GetModuleFileName() will "truncate",
     382       but makes no mention of the null terminator.  Play it safe.
     383       PLUS Windows itself defines MAX_PATH as the same, but anyway...
     384    */
    385385#ifdef Py_ENABLE_SHARED
    386         wprogpath[MAXPATHLEN]=_T('\0');
    387         if (PyWin_DLLhModule &&
    388             GetModuleFileName(PyWin_DLLhModule, wprogpath, MAXPATHLEN)) {
    389                 WideCharToMultiByte(CP_ACP, 0,
    390                                     wprogpath, -1,
    391                                     dllpath, MAXPATHLEN+1,
    392                                     NULL, NULL);
    393         }
     386    wprogpath[MAXPATHLEN]=_T('\0');
     387    if (PyWin_DLLhModule &&
     388        GetModuleFileName(PyWin_DLLhModule, wprogpath, MAXPATHLEN)) {
     389        WideCharToMultiByte(CP_ACP, 0,
     390                            wprogpath, -1,
     391                            dllpath, MAXPATHLEN+1,
     392                            NULL, NULL);
     393    }
    394394#else
    395         dllpath[0] = 0;
    396 #endif
    397         wprogpath[MAXPATHLEN]=_T('\0');
    398         if (GetModuleFileName(NULL, wprogpath, MAXPATHLEN)) {
    399                 WideCharToMultiByte(CP_ACP, 0,
    400                                     wprogpath, -1,
    401                                     progpath, MAXPATHLEN+1,
    402                                     NULL, NULL);
    403                 return;
    404         }
     395    dllpath[0] = 0;
     396#endif
     397    wprogpath[MAXPATHLEN]=_T('\0');
     398    if (GetModuleFileName(NULL, wprogpath, MAXPATHLEN)) {
     399        WideCharToMultiByte(CP_ACP, 0,
     400                            wprogpath, -1,
     401                            progpath, MAXPATHLEN+1,
     402                            NULL, NULL);
     403        return;
     404    }
    405405#else
    406         /* static init of progpath ensures final char remains \0 */
     406    /* static init of progpath ensures final char remains \0 */
    407407#ifdef Py_ENABLE_SHARED
    408         if (PyWin_DLLhModule)
    409                 if (!GetModuleFileName(PyWin_DLLhModule, dllpath, MAXPATHLEN))
    410                         dllpath[0] = 0;
     408    if (PyWin_DLLhModule)
     409        if (!GetModuleFileName(PyWin_DLLhModule, dllpath, MAXPATHLEN))
     410            dllpath[0] = 0;
    411411#else
    412         dllpath[0] = 0;
    413 #endif
    414         if (GetModuleFileName(NULL, progpath, MAXPATHLEN))
    415                 return;
    416 #endif
    417 #endif
    418         if (prog == NULL || *prog == '\0')
    419                 prog = "python";
    420 
    421         /* If there is no slash in the argv0 path, then we have to
    422         * assume python is on the user's $PATH, since there's no
    423         * other way to find a directory to start the search from.  If
    424         * $PATH isn't exported, you lose.
    425         */
     412    dllpath[0] = 0;
     413#endif
     414    if (GetModuleFileName(NULL, progpath, MAXPATHLEN))
     415        return;
     416#endif
     417#endif
     418    if (prog == NULL || *prog == '\0')
     419        prog = "python";
     420
     421    /* If there is no slash in the argv0 path, then we have to
     422    * assume python is on the user's $PATH, since there's no
     423    * other way to find a directory to start the search from.  If
     424    * $PATH isn't exported, you lose.
     425    */
    426426#ifdef ALTSEP
    427         if (strchr(prog, SEP) || strchr(prog, ALTSEP))
     427    if (strchr(prog, SEP) || strchr(prog, ALTSEP))
    428428#else
    429         if (strchr(prog, SEP))
    430 #endif
    431                 strncpy(progpath, prog, MAXPATHLEN);
    432         else if (path) {
    433                 while (1) {
    434                         char *delim = strchr(path, DELIM);
    435 
    436                         if (delim) {
    437                                 size_t len = delim - path;
    438                                 /* ensure we can't overwrite buffer */
    439                                 len = min(MAXPATHLEN,len);
    440                                 strncpy(progpath, path, len);
    441                                 *(progpath + len) = '\0';
    442                         }
    443                         else
    444                                 strncpy(progpath, path, MAXPATHLEN);
    445 
    446                         /* join() is safe for MAXPATHLEN+1 size buffer */
    447                         join(progpath, prog);
    448                         if (exists(progpath))
    449                                 break;
    450 
    451                         if (!delim) {
    452                                 progpath[0] = '\0';
    453                                 break;
    454                         }
    455                         path = delim + 1;
    456                 }
    457         }
    458         else
    459                 progpath[0] = '\0';
     429    if (strchr(prog, SEP))
     430#endif
     431        strncpy(progpath, prog, MAXPATHLEN);
     432    else if (path) {
     433        while (1) {
     434            char *delim = strchr(path, DELIM);
     435
     436            if (delim) {
     437                size_t len = delim - path;
     438                /* ensure we can't overwrite buffer */
     439                len = min(MAXPATHLEN,len);
     440                strncpy(progpath, path, len);
     441                *(progpath + len) = '\0';
     442            }
     443            else
     444                strncpy(progpath, path, MAXPATHLEN);
     445
     446            /* join() is safe for MAXPATHLEN+1 size buffer */
     447            join(progpath, prog);
     448            if (exists(progpath))
     449                break;
     450
     451            if (!delim) {
     452                progpath[0] = '\0';
     453                break;
     454            }
     455            path = delim + 1;
     456        }
     457    }
     458    else
     459        progpath[0] = '\0';
    460460}
    461461
     
    463463calculate_path(void)
    464464{
    465         char argv0_path[MAXPATHLEN+1];
    466         char *buf;
    467         size_t bufsz;
    468         char *pythonhome = Py_GetPythonHome();
    469         char *envpath = Py_GETENV("PYTHONPATH");
     465    char argv0_path[MAXPATHLEN+1];
     466    char *buf;
     467    size_t bufsz;
     468    char *pythonhome = Py_GetPythonHome();
     469    char *envpath = Py_GETENV("PYTHONPATH");
    470470
    471471#ifdef MS_WINDOWS
    472         int skiphome, skipdefault;
    473         char *machinepath = NULL;
    474         char *userpath = NULL;
    475         char zip_path[MAXPATHLEN+1];
    476         size_t len;
    477 #endif
    478 
    479         get_progpath();
    480         /* progpath guaranteed \0 terminated in MAXPATH+1 bytes. */
    481         strcpy(argv0_path, progpath);
    482         reduce(argv0_path);
    483         if (pythonhome == NULL || *pythonhome == '\0') {
    484                 if (search_for_prefix(argv0_path, LANDMARK))
    485                         pythonhome = prefix;
    486                 else
    487                         pythonhome = NULL;
    488         }
    489         else
    490                 strncpy(prefix, pythonhome, MAXPATHLEN);
    491 
    492         if (envpath && *envpath == '\0')
    493                 envpath = NULL;
     472    int skiphome, skipdefault;
     473    char *machinepath = NULL;
     474    char *userpath = NULL;
     475    char zip_path[MAXPATHLEN+1];
     476    size_t len;
     477#endif
     478
     479    get_progpath();
     480    /* progpath guaranteed \0 terminated in MAXPATH+1 bytes. */
     481    strcpy(argv0_path, progpath);
     482    reduce(argv0_path);
     483    if (pythonhome == NULL || *pythonhome == '\0') {
     484        if (search_for_prefix(argv0_path, LANDMARK))
     485            pythonhome = prefix;
     486        else
     487            pythonhome = NULL;
     488    }
     489    else
     490        strncpy(prefix, pythonhome, MAXPATHLEN);
     491
     492    if (envpath && *envpath == '\0')
     493        envpath = NULL;
    494494
    495495
    496496#ifdef MS_WINDOWS
    497         /* Calculate zip archive path */
    498         if (dllpath[0])         /* use name of python DLL */
    499                 strncpy(zip_path, dllpath, MAXPATHLEN);
    500         else                    /* use name of executable program */
    501                 strncpy(zip_path, progpath, MAXPATHLEN);
    502         zip_path[MAXPATHLEN] = '\0';
    503         len = strlen(zip_path);
    504         if (len > 4) {
    505                 zip_path[len-3] = 'z';  /* change ending to "zip" */
    506                 zip_path[len-2] = 'i';
    507                 zip_path[len-1] = 'p';
    508         }
    509         else {
    510                 zip_path[0] = 0;
    511         }
    512  
    513         skiphome = pythonhome==NULL ? 0 : 1;
     497    /* Calculate zip archive path */
     498    if (dllpath[0])             /* use name of python DLL */
     499        strncpy(zip_path, dllpath, MAXPATHLEN);
     500    else                        /* use name of executable program */
     501        strncpy(zip_path, progpath, MAXPATHLEN);
     502    zip_path[MAXPATHLEN] = '\0';
     503    len = strlen(zip_path);
     504    if (len > 4) {
     505        zip_path[len-3] = 'z';          /* change ending to "zip" */
     506        zip_path[len-2] = 'i';
     507        zip_path[len-1] = 'p';
     508    }
     509    else {
     510        zip_path[0] = 0;
     511    }
     512
     513    skiphome = pythonhome==NULL ? 0 : 1;
    514514#ifdef Py_ENABLE_SHARED
    515         machinepath = getpythonregpath(HKEY_LOCAL_MACHINE, skiphome);
    516         userpath = getpythonregpath(HKEY_CURRENT_USER, skiphome);
    517 #endif
    518         /* We only use the default relative PYTHONPATH if we havent
    519            anything better to use! */
    520         skipdefault = envpath!=NULL || pythonhome!=NULL || \
    521                       machinepath!=NULL || userpath!=NULL;
    522 #endif
    523 
    524         /* We need to construct a path from the following parts.
    525            (1) the PYTHONPATH environment variable, if set;
    526            (2) for Win32, the zip archive file path;
    527            (3) for Win32, the machinepath and userpath, if set;
    528            (4) the PYTHONPATH config macro, with the leading "."
    529                of each component replaced with pythonhome, if set;
    530            (5) the directory containing the executable (argv0_path).
    531            The length calculation calculates #4 first.
    532            Extra rules:
    533            - If PYTHONHOME is set (in any way) item (3) is ignored.
    534            - If registry values are used, (4) and (5) are ignored.
    535         */
    536 
    537         /* Calculate size of return buffer */
    538         if (pythonhome != NULL) {
    539                 char *p;
    540                 bufsz = 1;     
    541                 for (p = PYTHONPATH; *p; p++) {
    542                         if (*p == DELIM)
    543                                 bufsz++; /* number of DELIM plus one */
    544                 }
    545                 bufsz *= strlen(pythonhome);
    546         }
    547         else
    548                 bufsz = 0;
    549         bufsz += strlen(PYTHONPATH) + 1;
    550         bufsz += strlen(argv0_path) + 1;
     515    machinepath = getpythonregpath(HKEY_LOCAL_MACHINE, skiphome);
     516    userpath = getpythonregpath(HKEY_CURRENT_USER, skiphome);
     517#endif
     518    /* We only use the default relative PYTHONPATH if we havent
     519       anything better to use! */
     520    skipdefault = envpath!=NULL || pythonhome!=NULL || \
     521                  machinepath!=NULL || userpath!=NULL;
     522#endif
     523
     524    /* We need to construct a path from the following parts.
     525       (1) the PYTHONPATH environment variable, if set;
     526       (2) for Win32, the zip archive file path;
     527       (3) for Win32, the machinepath and userpath, if set;
     528       (4) the PYTHONPATH config macro, with the leading "."
     529           of each component replaced with pythonhome, if set;
     530       (5) the directory containing the executable (argv0_path).
     531       The length calculation calculates #4 first.
     532       Extra rules:
     533       - If PYTHONHOME is set (in any way) item (3) is ignored.
     534       - If registry values are used, (4) and (5) are ignored.
     535    */
     536
     537    /* Calculate size of return buffer */
     538    if (pythonhome != NULL) {
     539        char *p;
     540        bufsz = 1;
     541        for (p = PYTHONPATH; *p; p++) {
     542            if (*p == DELIM)
     543                bufsz++; /* number of DELIM plus one */
     544        }
     545        bufsz *= strlen(pythonhome);
     546    }
     547    else
     548        bufsz = 0;
     549    bufsz += strlen(PYTHONPATH) + 1;
     550    bufsz += strlen(argv0_path) + 1;
    551551#ifdef MS_WINDOWS
    552         if (userpath)
    553                 bufsz += strlen(userpath) + 1;
    554         if (machinepath)
    555                 bufsz += strlen(machinepath) + 1;
    556         bufsz += strlen(zip_path) + 1;
    557 #endif
    558         if (envpath != NULL)
    559                 bufsz += strlen(envpath) + 1;
    560 
    561         module_search_path = buf = malloc(bufsz);
    562         if (buf == NULL) {
    563                 /* We can't exit, so print a warning and limp along */
    564                 fprintf(stderr, "Can't malloc dynamic PYTHONPATH.\n");
    565                 if (envpath) {
    566                         fprintf(stderr, "Using environment $PYTHONPATH.\n");
    567                         module_search_path = envpath;
    568                 }
    569                 else {
    570                         fprintf(stderr, "Using default static path.\n");
    571                         module_search_path = PYTHONPATH;
    572                 }
     552    if (userpath)
     553        bufsz += strlen(userpath) + 1;
     554    if (machinepath)
     555        bufsz += strlen(machinepath) + 1;
     556    bufsz += strlen(zip_path) + 1;
     557#endif
     558    if (envpath != NULL)
     559        bufsz += strlen(envpath) + 1;
     560
     561    module_search_path = buf = malloc(bufsz);
     562    if (buf == NULL) {
     563        /* We can't exit, so print a warning and limp along */
     564        fprintf(stderr, "Can't malloc dynamic PYTHONPATH.\n");
     565        if (envpath) {
     566            fprintf(stderr, "Using environment $PYTHONPATH.\n");
     567            module_search_path = envpath;
     568        }
     569        else {
     570            fprintf(stderr, "Using default static path.\n");
     571            module_search_path = PYTHONPATH;
     572        }
    573573#ifdef MS_WINDOWS
    574                 if (machinepath)
    575                         free(machinepath);
    576                 if (userpath)
    577                         free(userpath);
     574        if (machinepath)
     575            free(machinepath);
     576        if (userpath)
     577            free(userpath);
    578578#endif /* MS_WINDOWS */
    579                 return;
    580         }
    581 
    582         if (envpath) {
    583                 strcpy(buf, envpath);
    584                 buf = strchr(buf, '\0');
    585                 *buf++ = DELIM;
    586         }
     579        return;
     580    }
     581
     582    if (envpath) {
     583        strcpy(buf, envpath);
     584        buf = strchr(buf, '\0');
     585        *buf++ = DELIM;
     586    }
    587587#ifdef MS_WINDOWS
    588         if (zip_path[0]) {
    589                 strcpy(buf, zip_path);
    590                 buf = strchr(buf, '\0');
    591                 *buf++ = DELIM;
    592         }
    593         if (userpath) {
    594                 strcpy(buf, userpath);
    595                 buf = strchr(buf, '\0');
    596                 *buf++ = DELIM;
    597                 free(userpath);
    598         }
    599         if (machinepath) {
    600                 strcpy(buf, machinepath);
    601                 buf = strchr(buf, '\0');
    602                 *buf++ = DELIM;
    603                 free(machinepath);
    604         }
    605         if (pythonhome == NULL) {
    606                 if (!skipdefault) {
    607                         strcpy(buf, PYTHONPATH);
    608                         buf = strchr(buf, '\0');
    609                 }
    610         }
     588    if (zip_path[0]) {
     589        strcpy(buf, zip_path);
     590        buf = strchr(buf, '\0');
     591        *buf++ = DELIM;
     592    }
     593    if (userpath) {
     594        strcpy(buf, userpath);
     595        buf = strchr(buf, '\0');
     596        *buf++ = DELIM;
     597        free(userpath);
     598    }
     599    if (machinepath) {
     600        strcpy(buf, machinepath);
     601        buf = strchr(buf, '\0');
     602        *buf++ = DELIM;
     603        free(machinepath);
     604    }
     605    if (pythonhome == NULL) {
     606        if (!skipdefault) {
     607            strcpy(buf, PYTHONPATH);
     608            buf = strchr(buf, '\0');
     609        }
     610    }
    611611#else
    612         if (pythonhome == NULL) {
    613                 strcpy(buf, PYTHONPATH);
    614                 buf = strchr(buf, '\0');
    615         }
     612    if (pythonhome == NULL) {
     613        strcpy(buf, PYTHONPATH);
     614        buf = strchr(buf, '\0');
     615    }
    616616#endif /* MS_WINDOWS */
    617         else {
    618                 char *p = PYTHONPATH;
    619                 char *q;
    620                 size_t n;
    621                 for (;;) {
    622                         q = strchr(p, DELIM);
    623                         if (q == NULL)
    624                                 n = strlen(p);
    625                         else
    626                                 n = q-p;
    627                         if (p[0] == '.' && is_sep(p[1])) {
    628                                 strcpy(buf, pythonhome);
    629                                 buf = strchr(buf, '\0');
    630                                 p++;
    631                                 n--;
    632                         }
    633                         strncpy(buf, p, n);
    634                         buf += n;
    635                         if (q == NULL)
    636                                 break;
    637                         *buf++ = DELIM;
    638                         p = q+1;
    639                 }
    640         }
    641         if (argv0_path) {
    642                 *buf++ = DELIM;
    643                 strcpy(buf, argv0_path);
    644                 buf = strchr(buf, '\0');
    645         }
    646         *buf = '\0';
    647         /* Now to pull one last hack/trick.  If sys.prefix is
    648            empty, then try and find it somewhere on the paths
    649            we calculated.  We scan backwards, as our general policy
    650            is that Python core directories are at the *end* of
    651            sys.path.  We assume that our "lib" directory is
    652            on the path, and that our 'prefix' directory is
    653            the parent of that.
    654         */
    655         if (*prefix=='\0') {
    656                 char lookBuf[MAXPATHLEN+1];
    657                 char *look = buf - 1; /* 'buf' is at the end of the buffer */
    658                 while (1) {
    659                         Py_ssize_t nchars;
    660                         char *lookEnd = look;
    661                         /* 'look' will end up one character before the
    662                            start of the path in question - even if this
    663                            is one character before the start of the buffer
    664                         */
    665                         while (look >= module_search_path && *look != DELIM)
    666                                 look--;
    667                         nchars = lookEnd-look;
    668                         strncpy(lookBuf, look+1, nchars);
    669                         lookBuf[nchars] = '\0';
    670                         /* Up one level to the parent */
    671                         reduce(lookBuf);
    672                         if (search_for_prefix(lookBuf, LANDMARK)) {
    673                                 break;
    674                         }
    675                         /* If we are out of paths to search - give up */
    676                         if (look < module_search_path)
    677                                 break;
    678                         look--;
    679                 }
    680         }
     617    else {
     618        char *p = PYTHONPATH;
     619        char *q;
     620        size_t n;
     621        for (;;) {
     622            q = strchr(p, DELIM);
     623            if (q == NULL)
     624                n = strlen(p);
     625            else
     626                n = q-p;
     627            if (p[0] == '.' && is_sep(p[1])) {
     628                strcpy(buf, pythonhome);
     629                buf = strchr(buf, '\0');
     630                p++;
     631                n--;
     632            }
     633            strncpy(buf, p, n);
     634            buf += n;
     635            if (q == NULL)
     636                break;
     637            *buf++ = DELIM;
     638            p = q+1;
     639        }
     640    }
     641    if (argv0_path) {
     642        *buf++ = DELIM;
     643        strcpy(buf, argv0_path);
     644        buf = strchr(buf, '\0');
     645    }
     646    *buf = '\0';
     647    /* Now to pull one last hack/trick.  If sys.prefix is
     648       empty, then try and find it somewhere on the paths
     649       we calculated.  We scan backwards, as our general policy
     650       is that Python core directories are at the *end* of
     651       sys.path.  We assume that our "lib" directory is
     652       on the path, and that our 'prefix' directory is
     653       the parent of that.
     654    */
     655    if (*prefix=='\0') {
     656        char lookBuf[MAXPATHLEN+1];
     657        char *look = buf - 1; /* 'buf' is at the end of the buffer */
     658        while (1) {
     659            Py_ssize_t nchars;
     660            char *lookEnd = look;
     661            /* 'look' will end up one character before the
     662               start of the path in question - even if this
     663               is one character before the start of the buffer
     664            */
     665            while (look >= module_search_path && *look != DELIM)
     666                look--;
     667            nchars = lookEnd-look;
     668            strncpy(lookBuf, look+1, nchars);
     669            lookBuf[nchars] = '\0';
     670            /* Up one level to the parent */
     671            reduce(lookBuf);
     672            if (search_for_prefix(lookBuf, LANDMARK)) {
     673                break;
     674            }
     675            /* If we are out of paths to search - give up */
     676            if (look < module_search_path)
     677                break;
     678            look--;
     679        }
     680    }
    681681}
    682682
     
    687687Py_GetPath(void)
    688688{
    689         if (!module_search_path)
    690                 calculate_path();
    691         return module_search_path;
     689    if (!module_search_path)
     690        calculate_path();
     691    return module_search_path;
    692692}
    693693
     
    695695Py_GetPrefix(void)
    696696{
    697         if (!module_search_path)
    698                 calculate_path();
    699         return prefix;
     697    if (!module_search_path)
     698        calculate_path();
     699    return prefix;
    700700}
    701701
     
    703703Py_GetExecPrefix(void)
    704704{
    705         return Py_GetPrefix();
     705    return Py_GetPrefix();
    706706}
    707707
     
    709709Py_GetProgramFullPath(void)
    710710{
    711         if (!module_search_path)
    712                 calculate_path();
    713         return progpath;
    714 }
     711    if (!module_search_path)
     712        calculate_path();
     713    return progpath;
     714}
Note: See TracChangeset for help on using the changeset viewer.