LCOV - code coverage report
Current view: top level - Modules - getpath.c (source / functions) Hit Total Coverage
Test: CPython 3.12 LCOV report [commit acb105a7c1f] Lines: 261 372 70.2 %
Date: 2022-07-20 13:12:14 Functions: 19 22 86.4 %
Branches: 142 260 54.6 %

           Branch data     Line data    Source code
       1                 :            : /* Return the initial module search path. */
       2                 :            : 
       3                 :            : #include "Python.h"
       4                 :            : #include "marshal.h"              // PyMarshal_ReadObjectFromString
       5                 :            : #include "osdefs.h"               // DELIM
       6                 :            : #include "pycore_initconfig.h"
       7                 :            : #include "pycore_fileutils.h"
       8                 :            : #include "pycore_pathconfig.h"
       9                 :            : #include "pycore_pymem.h"         // _PyMem_SetDefaultAllocator()
      10                 :            : #include <wchar.h>
      11                 :            : 
      12                 :            : #ifdef MS_WINDOWS
      13                 :            : #  include <windows.h>            // GetFullPathNameW(), MAX_PATH
      14                 :            : #  include <pathcch.h>
      15                 :            : #endif
      16                 :            : 
      17                 :            : #ifdef __APPLE__
      18                 :            : #  include <mach-o/dyld.h>
      19                 :            : #endif
      20                 :            : 
      21                 :            : /* Reference the precompiled getpath.py */
      22                 :            : #include "../Python/frozen_modules/getpath.h"
      23                 :            : 
      24                 :            : #if (!defined(PREFIX) || !defined(EXEC_PREFIX) \
      25                 :            :         || !defined(VERSION) || !defined(VPATH) \
      26                 :            :         || !defined(PLATLIBDIR))
      27                 :            : #error "PREFIX, EXEC_PREFIX, VERSION, VPATH and PLATLIBDIR macros must be defined"
      28                 :            : #endif
      29                 :            : 
      30                 :            : #if !defined(PYTHONPATH)
      31                 :            : #define PYTHONPATH NULL
      32                 :            : #endif
      33                 :            : 
      34                 :            : #if !defined(PYDEBUGEXT)
      35                 :            : #define PYDEBUGEXT NULL
      36                 :            : #endif
      37                 :            : 
      38                 :            : #if !defined(PYWINVER)
      39                 :            : #ifdef MS_DLL_ID
      40                 :            : #define PYWINVER MS_DLL_ID
      41                 :            : #else
      42                 :            : #define PYWINVER NULL
      43                 :            : #endif
      44                 :            : #endif
      45                 :            : 
      46                 :            : #if !defined(EXE_SUFFIX)
      47                 :            : #if defined(MS_WINDOWS) || defined(__CYGWIN__) || defined(__MINGW32__)
      48                 :            : #define EXE_SUFFIX L".exe"
      49                 :            : #else
      50                 :            : #define EXE_SUFFIX NULL
      51                 :            : #endif
      52                 :            : #endif
      53                 :            : 
      54                 :            : 
      55                 :            : /* HELPER FUNCTIONS for getpath.py */
      56                 :            : 
      57                 :            : static PyObject *
      58                 :       2990 : getpath_abspath(PyObject *Py_UNUSED(self), PyObject *args)
      59                 :            : {
      60                 :       2990 :     PyObject *r = NULL;
      61                 :            :     PyObject *pathobj;
      62                 :            :     wchar_t *path;
      63         [ -  + ]:       2990 :     if (!PyArg_ParseTuple(args, "U", &pathobj)) {
      64                 :          0 :         return NULL;
      65                 :            :     }
      66                 :            :     Py_ssize_t len;
      67                 :       2990 :     path = PyUnicode_AsWideCharString(pathobj, &len);
      68         [ +  - ]:       2990 :     if (path) {
      69                 :            :         wchar_t *abs;
      70   [ +  -  +  - ]:       2990 :         if (_Py_abspath((const wchar_t *)_Py_normpath(path, -1), &abs) == 0 && abs) {
      71                 :       2990 :             r = PyUnicode_FromWideChar(abs, -1);
      72                 :       2990 :             PyMem_RawFree((void *)abs);
      73                 :            :         } else {
      74                 :          0 :             PyErr_SetString(PyExc_OSError, "failed to make path absolute");
      75                 :            :         }
      76                 :       2990 :         PyMem_Free((void *)path);
      77                 :            :     }
      78                 :       2990 :     return r;
      79                 :            : }
      80                 :            : 
      81                 :            : 
      82                 :            : static PyObject *
      83                 :         25 : getpath_basename(PyObject *Py_UNUSED(self), PyObject *args)
      84                 :            : {
      85                 :            :     const char *path;
      86         [ -  + ]:         25 :     if (!PyArg_ParseTuple(args, "s", &path)) {
      87                 :          0 :         return NULL;
      88                 :            :     }
      89                 :         25 :     const char *name = strrchr(path, SEP);
      90         [ +  - ]:         25 :     return PyUnicode_FromString(name ? name + 1 : path);
      91                 :            : }
      92                 :            : 
      93                 :            : 
      94                 :            : static PyObject *
      95                 :       9480 : getpath_dirname(PyObject *Py_UNUSED(self), PyObject *args)
      96                 :            : {
      97                 :            :     const char *path;
      98         [ -  + ]:       9480 :     if (!PyArg_ParseTuple(args, "s", &path)) {
      99                 :          0 :         return NULL;
     100                 :            :     }
     101                 :       9480 :     const char *name = strrchr(path, SEP);
     102         [ +  + ]:       9480 :     if (!name) {
     103                 :         10 :         return PyUnicode_FromStringAndSize(NULL, 0);
     104                 :            :     }
     105                 :       9470 :     return PyUnicode_FromStringAndSize(path, (name - path));
     106                 :            : }
     107                 :            : 
     108                 :            : 
     109                 :            : static PyObject *
     110                 :          0 : getpath_isabs(PyObject *Py_UNUSED(self), PyObject *args)
     111                 :            : {
     112                 :          0 :     PyObject *r = NULL;
     113                 :            :     PyObject *pathobj;
     114                 :            :     const wchar_t *path;
     115         [ #  # ]:          0 :     if (!PyArg_ParseTuple(args, "U", &pathobj)) {
     116                 :          0 :         return NULL;
     117                 :            :     }
     118                 :          0 :     path = PyUnicode_AsWideCharString(pathobj, NULL);
     119         [ #  # ]:          0 :     if (path) {
     120         [ #  # ]:          0 :         r = _Py_isabs(path) ? Py_True : Py_False;
     121                 :          0 :         PyMem_Free((void *)path);
     122                 :            :     }
     123                 :          0 :     Py_XINCREF(r);
     124                 :          0 :     return r;
     125                 :            : }
     126                 :            : 
     127                 :            : 
     128                 :            : static PyObject *
     129                 :          0 : getpath_hassuffix(PyObject *Py_UNUSED(self), PyObject *args)
     130                 :            : {
     131                 :          0 :     PyObject *r = NULL;
     132                 :            :     PyObject *pathobj;
     133                 :            :     PyObject *suffixobj;
     134                 :            :     const wchar_t *path;
     135                 :            :     const wchar_t *suffix;
     136         [ #  # ]:          0 :     if (!PyArg_ParseTuple(args, "UU", &pathobj, &suffixobj)) {
     137                 :          0 :         return NULL;
     138                 :            :     }
     139                 :            :     Py_ssize_t len, suffixLen;
     140                 :          0 :     path = PyUnicode_AsWideCharString(pathobj, &len);
     141         [ #  # ]:          0 :     if (path) {
     142                 :          0 :         suffix = PyUnicode_AsWideCharString(suffixobj, &suffixLen);
     143         [ #  # ]:          0 :         if (suffix) {
     144         [ #  # ]:          0 :             if (suffixLen > len ||
     145                 :            : #ifdef MS_WINDOWS
     146                 :            :                 wcsicmp(&path[len - suffixLen], suffix) != 0
     147                 :            : #else
     148         [ #  # ]:          0 :                 wcscmp(&path[len - suffixLen], suffix) != 0
     149                 :            : #endif
     150                 :            :             ) {
     151                 :          0 :                 r = Py_False;
     152                 :            :             } else {
     153                 :          0 :                 r = Py_True;
     154                 :            :             }
     155                 :          0 :             Py_INCREF(r);
     156                 :          0 :             PyMem_Free((void *)suffix);
     157                 :            :         }
     158                 :          0 :         PyMem_Free((void *)path);
     159                 :            :     }
     160                 :          0 :     return r;
     161                 :            : }
     162                 :            : 
     163                 :            : 
     164                 :            : static PyObject *
     165                 :          1 : getpath_isdir(PyObject *Py_UNUSED(self), PyObject *args)
     166                 :            : {
     167                 :          1 :     PyObject *r = NULL;
     168                 :            :     PyObject *pathobj;
     169                 :            :     const wchar_t *path;
     170         [ -  + ]:          1 :     if (!PyArg_ParseTuple(args, "U", &pathobj)) {
     171                 :          0 :         return NULL;
     172                 :            :     }
     173                 :          1 :     path = PyUnicode_AsWideCharString(pathobj, NULL);
     174         [ +  - ]:          1 :     if (path) {
     175                 :            : #ifdef MS_WINDOWS
     176                 :            :         DWORD attr = GetFileAttributesW(path);
     177                 :            :         r = (attr != INVALID_FILE_ATTRIBUTES) &&
     178                 :            :             (attr & FILE_ATTRIBUTE_DIRECTORY) ? Py_True : Py_False;
     179                 :            : #else
     180                 :            :         struct stat st;
     181   [ +  -  +  - ]:          1 :         r = (_Py_wstat(path, &st) == 0) && S_ISDIR(st.st_mode) ? Py_True : Py_False;
     182                 :            : #endif
     183                 :          1 :         PyMem_Free((void *)path);
     184                 :            :     }
     185                 :          1 :     Py_XINCREF(r);
     186                 :          1 :     return r;
     187                 :            : }
     188                 :            : 
     189                 :            : 
     190                 :            : static PyObject *
     191                 :       3214 : getpath_isfile(PyObject *Py_UNUSED(self), PyObject *args)
     192                 :            : {
     193                 :       3214 :     PyObject *r = NULL;
     194                 :            :     PyObject *pathobj;
     195                 :            :     const wchar_t *path;
     196         [ -  + ]:       3214 :     if (!PyArg_ParseTuple(args, "U", &pathobj)) {
     197                 :          0 :         return NULL;
     198                 :            :     }
     199                 :       3214 :     path = PyUnicode_AsWideCharString(pathobj, NULL);
     200         [ +  - ]:       3214 :     if (path) {
     201                 :            : #ifdef MS_WINDOWS
     202                 :            :         DWORD attr = GetFileAttributesW(path);
     203                 :            :         r = (attr != INVALID_FILE_ATTRIBUTES) &&
     204                 :            :             !(attr & FILE_ATTRIBUTE_DIRECTORY) ? Py_True : Py_False;
     205                 :            : #else
     206                 :            :         struct stat st;
     207   [ +  +  +  - ]:       3214 :         r = (_Py_wstat(path, &st) == 0) && S_ISREG(st.st_mode) ? Py_True : Py_False;
     208                 :            : #endif
     209                 :       3214 :         PyMem_Free((void *)path);
     210                 :            :     }
     211                 :       3214 :     Py_XINCREF(r);
     212                 :       3214 :     return r;
     213                 :            : }
     214                 :            : 
     215                 :            : 
     216                 :            : static PyObject *
     217                 :         49 : getpath_isxfile(PyObject *Py_UNUSED(self), PyObject *args)
     218                 :            : {
     219                 :         49 :     PyObject *r = NULL;
     220                 :            :     PyObject *pathobj;
     221                 :            :     const wchar_t *path;
     222                 :            :     Py_ssize_t cchPath;
     223         [ -  + ]:         49 :     if (!PyArg_ParseTuple(args, "U", &pathobj)) {
     224                 :          0 :         return NULL;
     225                 :            :     }
     226                 :         49 :     path = PyUnicode_AsWideCharString(pathobj, &cchPath);
     227         [ +  - ]:         49 :     if (path) {
     228                 :            : #ifdef MS_WINDOWS
     229                 :            :         const wchar_t *ext;
     230                 :            :         DWORD attr = GetFileAttributesW(path);
     231                 :            :         r = (attr != INVALID_FILE_ATTRIBUTES) &&
     232                 :            :             !(attr & FILE_ATTRIBUTE_DIRECTORY) &&
     233                 :            :             SUCCEEDED(PathCchFindExtension(path, cchPath + 1, &ext)) &&
     234                 :            :             (CompareStringOrdinal(ext, -1, L".exe", -1, 1 /* ignore case */) == CSTR_EQUAL)
     235                 :            :             ? Py_True : Py_False;
     236                 :            : #else
     237                 :            :         struct stat st;
     238                 :         49 :         r = (_Py_wstat(path, &st) == 0) &&
     239         [ +  - ]:          3 :             S_ISREG(st.st_mode) &&
     240         [ +  - ]:          3 :             (st.st_mode & 0111)
     241         [ +  + ]:         52 :             ? Py_True : Py_False;
     242                 :            : #endif
     243                 :         49 :         PyMem_Free((void *)path);
     244                 :            :     }
     245                 :         49 :     Py_XINCREF(r);
     246                 :         49 :     return r;
     247                 :            : }
     248                 :            : 
     249                 :            : 
     250                 :            : static PyObject *
     251                 :      25648 : getpath_joinpath(PyObject *Py_UNUSED(self), PyObject *args)
     252                 :            : {
     253         [ -  + ]:      25648 :     if (!PyTuple_Check(args)) {
     254                 :          0 :         PyErr_SetString(PyExc_TypeError, "requires tuple of arguments");
     255                 :          0 :         return NULL;
     256                 :            :     }
     257                 :      25648 :     Py_ssize_t n = PyTuple_GET_SIZE(args);
     258         [ -  + ]:      25648 :     if (n == 0) {
     259                 :          0 :         return PyUnicode_FromString(NULL);
     260                 :            :     }
     261                 :            :     /* Convert all parts to wchar and accumulate max final length */
     262                 :      25648 :     wchar_t **parts = (wchar_t **)PyMem_Malloc(n * sizeof(wchar_t *));
     263                 :      25648 :     memset(parts, 0, n * sizeof(wchar_t *));
     264                 :      25648 :     Py_ssize_t cchFinal = 0;
     265                 :      25648 :     Py_ssize_t first = 0;
     266                 :            : 
     267         [ +  + ]:      76944 :     for (Py_ssize_t i = 0; i < n; ++i) {
     268                 :      51296 :         PyObject *s = PyTuple_GET_ITEM(args, i);
     269                 :            :         Py_ssize_t cch;
     270         [ -  + ]:      51296 :         if (s == Py_None) {
     271                 :          0 :             cch = 0;
     272         [ +  - ]:      51296 :         } else if (PyUnicode_Check(s)) {
     273                 :      51296 :             parts[i] = PyUnicode_AsWideCharString(s, &cch);
     274         [ -  + ]:      51296 :             if (!parts[i]) {
     275                 :          0 :                 cchFinal = -1;
     276                 :          0 :                 break;
     277                 :            :             }
     278         [ +  + ]:      51296 :             if (_Py_isabs(parts[i])) {
     279                 :      26043 :                 first = i;
     280                 :            :             }
     281                 :            :         } else {
     282                 :          0 :             PyErr_SetString(PyExc_TypeError, "all arguments to joinpath() must be str or None");
     283                 :          0 :             cchFinal = -1;
     284                 :          0 :             break;
     285                 :            :         }
     286                 :      51296 :         cchFinal += cch + 1;
     287                 :            :     }
     288                 :            : 
     289         [ +  - ]:      25648 :     wchar_t *final = cchFinal > 0 ? (wchar_t *)PyMem_Malloc(cchFinal * sizeof(wchar_t)) : NULL;
     290         [ -  + ]:      25648 :     if (!final) {
     291         [ #  # ]:          0 :         for (Py_ssize_t i = 0; i < n; ++i) {
     292                 :          0 :             PyMem_Free(parts[i]);
     293                 :            :         }
     294                 :          0 :         PyMem_Free(parts);
     295         [ #  # ]:          0 :         if (cchFinal) {
     296                 :            :             PyErr_NoMemory();
     297                 :          0 :             return NULL;
     298                 :            :         }
     299                 :          0 :         return PyUnicode_FromStringAndSize(NULL, 0);
     300                 :            :     }
     301                 :            : 
     302                 :      25648 :     final[0] = '\0';
     303                 :            :     /* Now join all the paths. The final result should be shorter than the buffer */
     304         [ +  + ]:      76944 :     for (Py_ssize_t i = 0; i < n; ++i) {
     305         [ -  + ]:      51296 :         if (!parts[i]) {
     306                 :          0 :             continue;
     307                 :            :         }
     308   [ +  +  +  - ]:      51296 :         if (i >= first && final) {
     309         [ +  + ]:      50891 :             if (!final[0]) {
     310                 :            :                 /* final is definitely long enough to fit any individual part */
     311                 :      25656 :                 wcscpy(final, parts[i]);
     312         [ -  + ]:      25235 :             } else if (_Py_add_relfile(final, parts[i], cchFinal) < 0) {
     313                 :            :                 /* if we fail, keep iterating to free memory, but stop adding parts */
     314                 :          0 :                 PyMem_Free(final);
     315                 :          0 :                 final = NULL;
     316                 :            :             }
     317                 :            :         }
     318                 :      51296 :         PyMem_Free(parts[i]);
     319                 :            :     }
     320                 :      25648 :     PyMem_Free(parts);
     321         [ -  + ]:      25648 :     if (!final) {
     322                 :          0 :         PyErr_SetString(PyExc_SystemError, "failed to join paths");
     323                 :          0 :         return NULL;
     324                 :            :     }
     325                 :      25648 :     PyObject *r = PyUnicode_FromWideChar(_Py_normpath(final, -1), -1);
     326                 :      25648 :     PyMem_Free(final);
     327                 :      25648 :     return r;
     328                 :            : }
     329                 :            : 
     330                 :            : 
     331                 :            : static PyObject *
     332                 :      15792 : getpath_readlines(PyObject *Py_UNUSED(self), PyObject *args)
     333                 :            : {
     334                 :      15792 :     PyObject *r = NULL;
     335                 :            :     PyObject *pathobj;
     336                 :            :     const wchar_t *path;
     337         [ -  + ]:      15792 :     if (!PyArg_ParseTuple(args, "U", &pathobj)) {
     338                 :          0 :         return NULL;
     339                 :            :     }
     340                 :      15792 :     path = PyUnicode_AsWideCharString(pathobj, NULL);
     341         [ -  + ]:      15792 :     if (!path) {
     342                 :          0 :         return NULL;
     343                 :            :     }
     344                 :      15792 :     FILE *fp = _Py_wfopen(path, L"rb");
     345                 :      15792 :     PyMem_Free((void *)path);
     346         [ +  + ]:      15792 :     if (!fp) {
     347                 :      12599 :         PyErr_SetFromErrno(PyExc_OSError);
     348                 :      12599 :         return NULL;
     349                 :            :     }
     350                 :            : 
     351                 :       3193 :     r = PyList_New(0);
     352         [ -  + ]:       3193 :     if (!r) {
     353                 :          0 :         fclose(fp);
     354                 :          0 :         return NULL;
     355                 :            :     }
     356                 :       3193 :     const size_t MAX_FILE = 32 * 1024;
     357                 :       3193 :     char *buffer = (char *)PyMem_Malloc(MAX_FILE);
     358         [ -  + ]:       3193 :     if (!buffer) {
     359                 :          0 :         Py_DECREF(r);
     360                 :          0 :         fclose(fp);
     361                 :          0 :         return NULL;
     362                 :            :     }
     363                 :            : 
     364                 :       3193 :     size_t cb = fread(buffer, 1, MAX_FILE, fp);
     365                 :       3193 :     fclose(fp);
     366         [ -  + ]:       3193 :     if (!cb) {
     367                 :          0 :         return r;
     368                 :            :     }
     369         [ -  + ]:       3193 :     if (cb >= MAX_FILE) {
     370                 :          0 :         Py_DECREF(r);
     371                 :          0 :         PyErr_SetString(PyExc_MemoryError,
     372                 :            :             "cannot read file larger than 32KB during initialization");
     373                 :          0 :         return NULL;
     374                 :            :     }
     375                 :       3193 :     buffer[cb] = '\0';
     376                 :            : 
     377                 :            :     size_t len;
     378                 :       3193 :     wchar_t *wbuffer = _Py_DecodeUTF8_surrogateescape(buffer, cb, &len);
     379                 :       3193 :     PyMem_Free((void *)buffer);
     380         [ -  + ]:       3193 :     if (!wbuffer) {
     381                 :          0 :         Py_DECREF(r);
     382                 :            :         PyErr_NoMemory();
     383                 :          0 :         return NULL;
     384                 :            :     }
     385                 :            : 
     386                 :       3193 :     wchar_t *p1 = wbuffer;
     387                 :       3193 :     wchar_t *p2 = p1;
     388         [ +  + ]:       3822 :     while ((p2 = wcschr(p1, L'\n')) != NULL) {
     389                 :        629 :         Py_ssize_t cb = p2 - p1;
     390   [ +  +  +  +  :       1258 :         while (cb >= 0 && (p1[cb] == L'\n' || p1[cb] == L'\r')) {
                   -  + ]
     391                 :        629 :             --cb;
     392                 :            :         }
     393                 :        629 :         PyObject *u = PyUnicode_FromWideChar(p1, cb >= 0 ? cb + 1 : 0);
     394   [ +  -  -  + ]:        629 :         if (!u || PyList_Append(r, u) < 0) {
     395                 :          0 :             Py_XDECREF(u);
     396         [ #  # ]:          0 :             Py_CLEAR(r);
     397                 :          0 :             break;
     398                 :            :         }
     399                 :        629 :         Py_DECREF(u);
     400                 :        629 :         p1 = p2 + 1;
     401                 :            :     }
     402   [ +  -  +  -  :       3193 :     if (r && p1 && *p1) {
                   +  + ]
     403                 :       3146 :         PyObject *u = PyUnicode_FromWideChar(p1, -1);
     404   [ +  -  -  + ]:       3146 :         if (!u || PyList_Append(r, u) < 0) {
     405         [ #  # ]:          0 :             Py_CLEAR(r);
     406                 :            :         }
     407                 :       3146 :         Py_XDECREF(u);
     408                 :            :     }
     409                 :       3193 :     PyMem_RawFree(wbuffer);
     410                 :       3193 :     return r;
     411                 :            : }
     412                 :            : 
     413                 :            : 
     414                 :            : static PyObject *
     415                 :       3219 : getpath_realpath(PyObject *Py_UNUSED(self) , PyObject *args)
     416                 :            : {
     417                 :            :     PyObject *pathobj;
     418         [ -  + ]:       3219 :     if (!PyArg_ParseTuple(args, "U", &pathobj)) {
     419                 :          0 :         return NULL;
     420                 :            :     }
     421                 :            : #if defined(HAVE_READLINK)
     422                 :            :     /* This readlink calculation only resolves a symlinked file, and
     423                 :            :        does not resolve any path segments. This is consistent with
     424                 :            :        prior releases, however, the realpath implementation below is
     425                 :            :        potentially correct in more cases. */
     426                 :       3219 :     PyObject *r = NULL;
     427                 :       3219 :     int nlink = 0;
     428                 :       3219 :     wchar_t *path = PyUnicode_AsWideCharString(pathobj, NULL);
     429         [ -  + ]:       3219 :     if (!path) {
     430                 :          0 :         goto done;
     431                 :            :     }
     432                 :       3219 :     wchar_t *path2 = _PyMem_RawWcsdup(path);
     433                 :       3219 :     PyMem_Free((void *)path);
     434                 :       3219 :     path = path2;
     435         [ +  - ]:       3258 :     while (path) {
     436                 :            :         wchar_t resolved[MAXPATHLEN + 1];
     437                 :       3258 :         int linklen = _Py_wreadlink(path, resolved, Py_ARRAY_LENGTH(resolved));
     438         [ +  + ]:       3258 :         if (linklen == -1) {
     439                 :       3219 :             r = PyUnicode_FromWideChar(path, -1);
     440                 :       3219 :             break;
     441                 :            :         }
     442         [ +  + ]:         39 :         if (_Py_isabs(resolved)) {
     443                 :         37 :             PyMem_RawFree((void *)path);
     444                 :         37 :             path = _PyMem_RawWcsdup(resolved);
     445                 :            :         } else {
     446                 :          2 :             wchar_t *s = wcsrchr(path, SEP);
     447         [ +  - ]:          2 :             if (s) {
     448                 :          2 :                 *s = L'\0';
     449                 :            :             }
     450                 :          2 :             path2 = _Py_normpath(_Py_join_relfile(path, resolved), -1);
     451                 :          2 :             PyMem_RawFree((void *)path);
     452                 :          2 :             path = path2;
     453                 :            :         }
     454                 :         39 :         nlink++;
     455                 :            :         /* 40 is the Linux kernel 4.2 limit */
     456         [ -  + ]:         39 :         if (nlink >= 40) {
     457                 :          0 :             PyErr_SetString(PyExc_OSError, "maximum number of symbolic links reached");
     458                 :          0 :             break;
     459                 :            :         }
     460                 :            :     }
     461         [ +  - ]:       3219 :     if (!path) {
     462                 :            :         PyErr_NoMemory();
     463                 :            :     }
     464                 :       3219 : done:
     465                 :       3219 :     PyMem_RawFree((void *)path);
     466                 :       3219 :     return r;
     467                 :            : 
     468                 :            : #elif defined(HAVE_REALPATH)
     469                 :            :     PyObject *r = NULL;
     470                 :            :     struct stat st;
     471                 :            :     const char *narrow = NULL;
     472                 :            :     wchar_t *path = PyUnicode_AsWideCharString(pathobj, NULL);
     473                 :            :     if (!path) {
     474                 :            :         goto done;
     475                 :            :     }
     476                 :            :     narrow = Py_EncodeLocale(path, NULL);
     477                 :            :     if (!narrow) {
     478                 :            :         PyErr_NoMemory();
     479                 :            :         goto done;
     480                 :            :     }
     481                 :            :     if (lstat(narrow, &st)) {
     482                 :            :         PyErr_SetFromErrno(PyExc_OSError);
     483                 :            :         goto done;
     484                 :            :     }
     485                 :            :     if (!S_ISLNK(st.st_mode)) {
     486                 :            :         Py_INCREF(pathobj);
     487                 :            :         r = pathobj;
     488                 :            :         goto done;
     489                 :            :     }
     490                 :            :     wchar_t resolved[MAXPATHLEN+1];
     491                 :            :     if (_Py_wrealpath(path, resolved, MAXPATHLEN) == NULL) {
     492                 :            :         PyErr_SetFromErrno(PyExc_OSError);
     493                 :            :     } else {
     494                 :            :         r = PyUnicode_FromWideChar(resolved, -1);
     495                 :            :     }
     496                 :            : done:
     497                 :            :     PyMem_Free((void *)path);
     498                 :            :     PyMem_Free((void *)narrow);
     499                 :            :     return r;
     500                 :            : #endif
     501                 :            : 
     502                 :            :     Py_INCREF(pathobj);
     503                 :            :     return pathobj;
     504                 :            : }
     505                 :            : 
     506                 :            : 
     507                 :            : static PyMethodDef getpath_methods[] = {
     508                 :            :     {"abspath", getpath_abspath, METH_VARARGS, NULL},
     509                 :            :     {"basename", getpath_basename, METH_VARARGS, NULL},
     510                 :            :     {"dirname", getpath_dirname, METH_VARARGS, NULL},
     511                 :            :     {"hassuffix", getpath_hassuffix, METH_VARARGS, NULL},
     512                 :            :     {"isabs", getpath_isabs, METH_VARARGS, NULL},
     513                 :            :     {"isdir", getpath_isdir, METH_VARARGS, NULL},
     514                 :            :     {"isfile", getpath_isfile, METH_VARARGS, NULL},
     515                 :            :     {"isxfile", getpath_isxfile, METH_VARARGS, NULL},
     516                 :            :     {"joinpath", getpath_joinpath, METH_VARARGS, NULL},
     517                 :            :     {"readlines", getpath_readlines, METH_VARARGS, NULL},
     518                 :            :     {"realpath", getpath_realpath, METH_VARARGS, NULL},
     519                 :            :     {NULL, NULL, 0, NULL}
     520                 :            : };
     521                 :            : 
     522                 :            : 
     523                 :            : /* Two implementations of warn() to use depending on whether warnings
     524                 :            :    are enabled or not. */
     525                 :            : 
     526                 :            : static PyObject *
     527                 :          2 : getpath_warn(PyObject *Py_UNUSED(self), PyObject *args)
     528                 :            : {
     529                 :            :     PyObject *msgobj;
     530         [ -  + ]:          2 :     if (!PyArg_ParseTuple(args, "U", &msgobj)) {
     531                 :          0 :         return NULL;
     532                 :            :     }
     533                 :          2 :     fprintf(stderr, "%s\n", PyUnicode_AsUTF8(msgobj));
     534                 :          2 :     Py_RETURN_NONE;
     535                 :            : }
     536                 :            : 
     537                 :            : 
     538                 :            : static PyObject *
     539                 :          0 : getpath_nowarn(PyObject *Py_UNUSED(self), PyObject *args)
     540                 :            : {
     541                 :          0 :     Py_RETURN_NONE;
     542                 :            : }
     543                 :            : 
     544                 :            : 
     545                 :            : static PyMethodDef getpath_warn_method = {"warn", getpath_warn, METH_VARARGS, NULL};
     546                 :            : static PyMethodDef getpath_nowarn_method = {"warn", getpath_nowarn, METH_VARARGS, NULL};
     547                 :            : 
     548                 :            : /* Add the helper functions to the dict */
     549                 :            : static int
     550                 :       3176 : funcs_to_dict(PyObject *dict, int warnings)
     551                 :            : {
     552         [ +  + ]:      38112 :     for (PyMethodDef *m = getpath_methods; m->ml_name; ++m) {
     553                 :      34936 :         PyObject *f = PyCFunction_NewEx(m, NULL, NULL);
     554         [ -  + ]:      34936 :         if (!f) {
     555                 :          0 :             return 0;
     556                 :            :         }
     557         [ -  + ]:      34936 :         if (PyDict_SetItemString(dict, m->ml_name, f) < 0) {
     558                 :          0 :             Py_DECREF(f);
     559                 :          0 :             return 0;
     560                 :            :         }
     561                 :      34936 :         Py_DECREF(f);
     562                 :            :     }
     563         [ +  + ]:       3176 :     PyMethodDef *m2 = warnings ? &getpath_warn_method : &getpath_nowarn_method;
     564                 :       3176 :     PyObject *f = PyCFunction_NewEx(m2, NULL, NULL);
     565         [ -  + ]:       3176 :     if (!f) {
     566                 :          0 :         return 0;
     567                 :            :     }
     568         [ -  + ]:       3176 :     if (PyDict_SetItemString(dict, m2->ml_name, f) < 0) {
     569                 :          0 :         Py_DECREF(f);
     570                 :          0 :         return 0;
     571                 :            :     }
     572                 :       3176 :     Py_DECREF(f);
     573                 :       3176 :     return 1;
     574                 :            : }
     575                 :            : 
     576                 :            : 
     577                 :            : /* Add a wide-character string constant to the dict */
     578                 :            : static int
     579                 :       9528 : wchar_to_dict(PyObject *dict, const char *key, const wchar_t *s)
     580                 :            : {
     581                 :            :     PyObject *u;
     582                 :            :     int r;
     583   [ +  +  +  - ]:       9528 :     if (s && s[0]) {
     584                 :          2 :         u = PyUnicode_FromWideChar(s, -1);
     585         [ -  + ]:          2 :         if (!u) {
     586                 :          0 :             return 0;
     587                 :            :         }
     588                 :            :     } else {
     589                 :       9526 :         u = Py_None;
     590                 :       9526 :         Py_INCREF(u);
     591                 :            :     }
     592                 :       9528 :     r = PyDict_SetItemString(dict, key, u) == 0;
     593                 :       9528 :     Py_DECREF(u);
     594                 :       9528 :     return r;
     595                 :            : }
     596                 :            : 
     597                 :            : 
     598                 :            : /* Add a narrow string constant to the dict, using default locale decoding */
     599                 :            : static int
     600                 :      25408 : decode_to_dict(PyObject *dict, const char *key, const char *s)
     601                 :            : {
     602                 :      25408 :     PyObject *u = NULL;
     603                 :            :     int r;
     604   [ +  +  +  + ]:      41288 :     if (s && s[0]) {
     605                 :            :         size_t len;
     606                 :      15880 :         const wchar_t *w = Py_DecodeLocale(s, &len);
     607         [ +  - ]:      15880 :         if (w) {
     608                 :      15880 :             u = PyUnicode_FromWideChar(w, len);
     609                 :      15880 :             PyMem_RawFree((void *)w);
     610                 :            :         }
     611         [ -  + ]:      15880 :         if (!u) {
     612                 :          0 :             return 0;
     613                 :            :         }
     614                 :            :     } else {
     615                 :       9528 :         u = Py_None;
     616                 :       9528 :         Py_INCREF(u);
     617                 :            :     }
     618                 :      25408 :     r = PyDict_SetItemString(dict, key, u) == 0;
     619                 :      25408 :     Py_DECREF(u);
     620                 :      25408 :     return r;
     621                 :            : }
     622                 :            : 
     623                 :            : /* Add an environment variable to the dict, optionally clearing it afterwards */
     624                 :            : static int
     625                 :      12704 : env_to_dict(PyObject *dict, const char *key, int and_clear)
     626                 :            : {
     627                 :      12704 :     PyObject *u = NULL;
     628                 :      12704 :     int r = 0;
     629                 :            :     assert(strncmp(key, "ENV_", 4) == 0);
     630                 :            :     assert(strlen(key) < 64);
     631                 :            : #ifdef MS_WINDOWS
     632                 :            :     wchar_t wkey[64];
     633                 :            :     // Quick convert to wchar_t, since we know key is ASCII
     634                 :            :     wchar_t *wp = wkey;
     635                 :            :     for (const char *p = &key[4]; *p; ++p) {
     636                 :            :         assert(*p < 128);
     637                 :            :         *wp++ = *p;
     638                 :            :     }
     639                 :            :     *wp = L'\0';
     640                 :            :     const wchar_t *v = _wgetenv(wkey);
     641                 :            :     if (v) {
     642                 :            :         u = PyUnicode_FromWideChar(v, -1);
     643                 :            :         if (!u) {
     644                 :            :             PyErr_Clear();
     645                 :            :         }
     646                 :            :     }
     647                 :            : #else
     648                 :      12704 :     const char *v = getenv(&key[4]);
     649         [ +  + ]:      12704 :     if (v) {
     650                 :            :         size_t len;
     651                 :       3174 :         const wchar_t *w = Py_DecodeLocale(v, &len);
     652         [ +  - ]:       3174 :         if (w) {
     653                 :       3174 :             u = PyUnicode_FromWideChar(w, len);
     654         [ -  + ]:       3174 :             if (!u) {
     655                 :          0 :                 PyErr_Clear();
     656                 :            :             }
     657                 :       3174 :             PyMem_RawFree((void *)w);
     658                 :            :         }
     659                 :            :     }
     660                 :            : #endif
     661         [ +  + ]:      12704 :     if (u) {
     662                 :       3174 :         r = PyDict_SetItemString(dict, key, u) == 0;
     663                 :       3174 :         Py_DECREF(u);
     664                 :            :     } else {
     665                 :       9530 :         r = PyDict_SetItemString(dict, key, Py_None) == 0;
     666                 :            :     }
     667   [ +  -  +  + ]:      12704 :     if (r && and_clear) {
     668                 :            : #ifdef MS_WINDOWS
     669                 :            :         _wputenv_s(wkey, L"");
     670                 :            : #else
     671                 :       3176 :         unsetenv(&key[4]);
     672                 :            : #endif
     673                 :            :     }
     674                 :      12704 :     return r;
     675                 :            : }
     676                 :            : 
     677                 :            : 
     678                 :            : /* Add an integer constant to the dict */
     679                 :            : static int
     680                 :       9528 : int_to_dict(PyObject *dict, const char *key, int v)
     681                 :            : {
     682                 :            :     PyObject *o;
     683                 :            :     int r;
     684                 :       9528 :     o = PyLong_FromLong(v);
     685         [ -  + ]:       9528 :     if (!o) {
     686                 :          0 :         return 0;
     687                 :            :     }
     688                 :       9528 :     r = PyDict_SetItemString(dict, key, o) == 0;
     689                 :       9528 :     Py_DECREF(o);
     690                 :       9528 :     return r;
     691                 :            : }
     692                 :            : 
     693                 :            : 
     694                 :            : #ifdef MS_WINDOWS
     695                 :            : static int
     696                 :            : winmodule_to_dict(PyObject *dict, const char *key, HMODULE mod)
     697                 :            : {
     698                 :            :     wchar_t *buffer = NULL;
     699                 :            :     for (DWORD cch = 256; buffer == NULL && cch < (1024 * 1024); cch *= 2) {
     700                 :            :         buffer = (wchar_t*)PyMem_RawMalloc(cch * sizeof(wchar_t));
     701                 :            :         if (buffer) {
     702                 :            :             if (GetModuleFileNameW(mod, buffer, cch) == cch) {
     703                 :            :                 PyMem_RawFree(buffer);
     704                 :            :                 buffer = NULL;
     705                 :            :             }
     706                 :            :         }
     707                 :            :     }
     708                 :            :     int r = wchar_to_dict(dict, key, buffer);
     709                 :            :     PyMem_RawFree(buffer);
     710                 :            :     return r;
     711                 :            : }
     712                 :            : #endif
     713                 :            : 
     714                 :            : 
     715                 :            : /* Add the current executable's path to the dict */
     716                 :            : static int
     717                 :       3176 : progname_to_dict(PyObject *dict, const char *key)
     718                 :            : {
     719                 :            : #ifdef MS_WINDOWS
     720                 :            :     return winmodule_to_dict(dict, key, NULL);
     721                 :            : #elif defined(__APPLE__)
     722                 :            :     char *path;
     723                 :            :     uint32_t pathLen = 256;
     724                 :            :     while (pathLen) {
     725                 :            :         path = PyMem_RawMalloc((pathLen + 1) * sizeof(char));
     726                 :            :         if (!path) {
     727                 :            :             return 0;
     728                 :            :         }
     729                 :            :         if (_NSGetExecutablePath(path, &pathLen) != 0) {
     730                 :            :             PyMem_RawFree(path);
     731                 :            :             continue;
     732                 :            :         }
     733                 :            :         // Only keep if the path is absolute
     734                 :            :         if (path[0] == SEP) {
     735                 :            :             int r = decode_to_dict(dict, key, path);
     736                 :            :             PyMem_RawFree(path);
     737                 :            :             return r;
     738                 :            :         }
     739                 :            :         // Fall back and store None
     740                 :            :         PyMem_RawFree(path);
     741                 :            :         break;
     742                 :            :     }
     743                 :            : #endif
     744                 :       3176 :     return PyDict_SetItemString(dict, key, Py_None) == 0;
     745                 :            : }
     746                 :            : 
     747                 :            : 
     748                 :            : /* Add the runtime library's path to the dict */
     749                 :            : static int
     750                 :       3176 : library_to_dict(PyObject *dict, const char *key)
     751                 :            : {
     752                 :            : #ifdef MS_WINDOWS
     753                 :            :     extern HMODULE PyWin_DLLhModule;
     754                 :            :     if (PyWin_DLLhModule) {
     755                 :            :         return winmodule_to_dict(dict, key, PyWin_DLLhModule);
     756                 :            :     }
     757                 :            : #elif defined(WITH_NEXT_FRAMEWORK)
     758                 :            :     static char modPath[MAXPATHLEN + 1];
     759                 :            :     static int modPathInitialized = -1;
     760                 :            :     if (modPathInitialized < 0) {
     761                 :            :         modPathInitialized = 0;
     762                 :            : 
     763                 :            :         /* On Mac OS X we have a special case if we're running from a framework.
     764                 :            :            This is because the python home should be set relative to the library,
     765                 :            :            which is in the framework, not relative to the executable, which may
     766                 :            :            be outside of the framework. Except when we're in the build
     767                 :            :            directory... */
     768                 :            :         NSSymbol symbol = NSLookupAndBindSymbol("_Py_Initialize");
     769                 :            :         if (symbol != NULL) {
     770                 :            :             NSModule pythonModule = NSModuleForSymbol(symbol);
     771                 :            :             if (pythonModule != NULL) {
     772                 :            :                 /* Use dylib functions to find out where the framework was loaded from */
     773                 :            :                 const char *path = NSLibraryNameForModule(pythonModule);
     774                 :            :                 if (path) {
     775                 :            :                     strncpy(modPath, path, MAXPATHLEN);
     776                 :            :                     modPathInitialized = 1;
     777                 :            :                 }
     778                 :            :             }
     779                 :            :         }
     780                 :            :     }
     781                 :            :     if (modPathInitialized > 0) {
     782                 :            :         return decode_to_dict(dict, key, modPath);
     783                 :            :     }
     784                 :            : #endif
     785                 :       3176 :     return PyDict_SetItemString(dict, key, Py_None) == 0;
     786                 :            : }
     787                 :            : 
     788                 :            : 
     789                 :            : PyObject *
     790                 :       3176 : _Py_Get_Getpath_CodeObject(void)
     791                 :            : {
     792                 :       3176 :     return PyMarshal_ReadObjectFromString(
     793                 :            :         (const char*)_Py_M__getpath, sizeof(_Py_M__getpath));
     794                 :            : }
     795                 :            : 
     796                 :            : 
     797                 :            : /* Perform the actual path calculation.
     798                 :            : 
     799                 :            :    When compute_path_config is 0, this only reads any initialised path
     800                 :            :    config values into the PyConfig struct. For example, Py_SetHome() or
     801                 :            :    Py_SetPath(). The only error should be due to failed memory allocation.
     802                 :            : 
     803                 :            :    When compute_path_config is 1, full path calculation is performed.
     804                 :            :    The GIL must be held, and there may be filesystem access, side
     805                 :            :    effects, and potential unraisable errors that are reported directly
     806                 :            :    to stderr.
     807                 :            : 
     808                 :            :    Calling this function multiple times on the same PyConfig is only
     809                 :            :    safe because already-configured values are not recalculated. To
     810                 :            :    actually recalculate paths, you need a clean PyConfig.
     811                 :            : */
     812                 :            : PyStatus
     813                 :       6163 : _PyConfig_InitPathConfig(PyConfig *config, int compute_path_config)
     814                 :            : {
     815                 :       6163 :     PyStatus status = _PyPathConfig_ReadGlobal(config);
     816                 :            : 
     817   [ +  -  +  + ]:       6163 :     if (_PyStatus_EXCEPTION(status) || !compute_path_config) {
     818                 :       2987 :         return status;
     819                 :            :     }
     820                 :            : 
     821         [ -  + ]:       3176 :     if (!_PyThreadState_UncheckedGet()) {
     822                 :          0 :         return PyStatus_Error("cannot calculate path configuration without GIL");
     823                 :            :     }
     824                 :            : 
     825                 :       3176 :     PyObject *configDict = _PyConfig_AsDict(config);
     826         [ -  + ]:       3176 :     if (!configDict) {
     827                 :          0 :         PyErr_Clear();
     828                 :          0 :         return PyStatus_NoMemory();
     829                 :            :     }
     830                 :            : 
     831                 :       3176 :     PyObject *dict = PyDict_New();
     832         [ -  + ]:       3176 :     if (!dict) {
     833                 :          0 :         PyErr_Clear();
     834                 :          0 :         Py_DECREF(configDict);
     835                 :          0 :         return PyStatus_NoMemory();
     836                 :            :     }
     837                 :            : 
     838         [ -  + ]:       3176 :     if (PyDict_SetItemString(dict, "config", configDict) < 0) {
     839                 :          0 :         PyErr_Clear();
     840                 :          0 :         Py_DECREF(configDict);
     841                 :          0 :         Py_DECREF(dict);
     842                 :          0 :         return PyStatus_NoMemory();
     843                 :            :     }
     844                 :            :     /* reference now held by dict */
     845                 :       3176 :     Py_DECREF(configDict);
     846                 :            : 
     847                 :       3176 :     PyObject *co = _Py_Get_Getpath_CodeObject();
     848   [ +  -  -  + ]:       3176 :     if (!co || !PyCode_Check(co)) {
     849                 :          0 :         PyErr_Clear();
     850                 :          0 :         Py_XDECREF(co);
     851                 :          0 :         Py_DECREF(dict);
     852                 :          0 :         return PyStatus_Error("error reading frozen getpath.py");
     853                 :            :     }
     854                 :            : 
     855                 :            : #ifdef MS_WINDOWS
     856                 :            :     PyObject *winreg = PyImport_ImportModule("winreg");
     857                 :            :     if (!winreg || PyDict_SetItemString(dict, "winreg", winreg) < 0) {
     858                 :            :         PyErr_Clear();
     859                 :            :         Py_XDECREF(winreg);
     860                 :            :         if (PyDict_SetItemString(dict, "winreg", Py_None) < 0) {
     861                 :            :             PyErr_Clear();
     862                 :            :             Py_DECREF(co);
     863                 :            :             Py_DECREF(dict);
     864                 :            :             return PyStatus_Error("error importing winreg module");
     865                 :            :         }
     866                 :            :     } else {
     867                 :            :         Py_DECREF(winreg);
     868                 :            :     }
     869                 :            : #endif
     870                 :            : 
     871         [ +  - ]:       3176 :     if (
     872                 :            : #ifdef MS_WINDOWS
     873                 :            :         !decode_to_dict(dict, "os_name", "nt") ||
     874                 :            : #elif defined(__APPLE__)
     875                 :            :         !decode_to_dict(dict, "os_name", "darwin") ||
     876                 :            : #else
     877         [ +  - ]:       6352 :         !decode_to_dict(dict, "os_name", "posix") ||
     878                 :            : #endif
     879                 :            : #ifdef WITH_NEXT_FRAMEWORK
     880                 :            :         !int_to_dict(dict, "WITH_NEXT_FRAMEWORK", 1) ||
     881                 :            : #else
     882         [ +  - ]:       6352 :         !int_to_dict(dict, "WITH_NEXT_FRAMEWORK", 0) ||
     883                 :            : #endif
     884         [ +  - ]:       6352 :         !decode_to_dict(dict, "PREFIX", PREFIX) ||
     885         [ +  - ]:       6352 :         !decode_to_dict(dict, "EXEC_PREFIX", EXEC_PREFIX) ||
     886         [ +  - ]:       6352 :         !decode_to_dict(dict, "PYTHONPATH", PYTHONPATH) ||
     887         [ +  - ]:       6352 :         !decode_to_dict(dict, "VPATH", VPATH) ||
     888         [ +  - ]:       6352 :         !decode_to_dict(dict, "PLATLIBDIR", PLATLIBDIR) ||
     889         [ +  - ]:       6352 :         !decode_to_dict(dict, "PYDEBUGEXT", PYDEBUGEXT) ||
     890         [ +  - ]:       6352 :         !int_to_dict(dict, "VERSION_MAJOR", PY_MAJOR_VERSION) ||
     891         [ +  - ]:       6352 :         !int_to_dict(dict, "VERSION_MINOR", PY_MINOR_VERSION) ||
     892         [ +  - ]:       6352 :         !decode_to_dict(dict, "PYWINVER", PYWINVER) ||
     893         [ +  - ]:       6352 :         !wchar_to_dict(dict, "EXE_SUFFIX", EXE_SUFFIX) ||
     894         [ +  - ]:       6352 :         !env_to_dict(dict, "ENV_PATH", 0) ||
     895         [ +  - ]:       6352 :         !env_to_dict(dict, "ENV_PYTHONHOME", 0) ||
     896         [ +  - ]:       6352 :         !env_to_dict(dict, "ENV_PYTHONEXECUTABLE", 0) ||
     897         [ +  - ]:       6352 :         !env_to_dict(dict, "ENV___PYVENV_LAUNCHER__", 1) ||
     898         [ +  - ]:       6352 :         !progname_to_dict(dict, "real_executable") ||
     899         [ +  - ]:       6352 :         !library_to_dict(dict, "library") ||
     900         [ +  - ]:       6352 :         !wchar_to_dict(dict, "executable_dir", NULL) ||
     901         [ +  - ]:       6352 :         !wchar_to_dict(dict, "py_setpath", _PyPathConfig_GetGlobalModuleSearchPath()) ||
     902         [ +  - ]:       6352 :         !funcs_to_dict(dict, config->pathconfig_warnings) ||
     903                 :            : #ifndef MS_WINDOWS
     904         [ -  + ]:       6352 :         PyDict_SetItemString(dict, "winreg", Py_None) < 0 ||
     905                 :            : #endif
     906                 :       3176 :         PyDict_SetItemString(dict, "__builtins__", PyEval_GetBuiltins()) < 0
     907                 :            :     ) {
     908                 :          0 :         Py_DECREF(co);
     909                 :          0 :         Py_DECREF(dict);
     910                 :          0 :         _PyErr_WriteUnraisableMsg("error evaluating initial values", NULL);
     911                 :          0 :         return PyStatus_Error("error evaluating initial values");
     912                 :            :     }
     913                 :            : 
     914                 :       3176 :     PyObject *r = PyEval_EvalCode(co, dict, dict);
     915                 :       3176 :     Py_DECREF(co);
     916                 :            : 
     917         [ -  + ]:       3176 :     if (!r) {
     918                 :          0 :         Py_DECREF(dict);
     919                 :          0 :         _PyErr_WriteUnraisableMsg("error evaluating path", NULL);
     920                 :          0 :         return PyStatus_Error("error evaluating path");
     921                 :            :     }
     922                 :       3176 :     Py_DECREF(r);
     923                 :            : 
     924                 :            : #if 0
     925                 :            :     PyObject *it = PyObject_GetIter(configDict);
     926                 :            :     for (PyObject *k = PyIter_Next(it); k; k = PyIter_Next(it)) {
     927                 :            :         if (!strcmp("__builtins__", PyUnicode_AsUTF8(k))) {
     928                 :            :             Py_DECREF(k);
     929                 :            :             continue;
     930                 :            :         }
     931                 :            :         fprintf(stderr, "%s = ", PyUnicode_AsUTF8(k));
     932                 :            :         PyObject *o = PyDict_GetItem(configDict, k);
     933                 :            :         o = PyObject_Repr(o);
     934                 :            :         fprintf(stderr, "%s\n", PyUnicode_AsUTF8(o));
     935                 :            :         Py_DECREF(o);
     936                 :            :         Py_DECREF(k);
     937                 :            :     }
     938                 :            :     Py_DECREF(it);
     939                 :            : #endif
     940                 :            : 
     941         [ -  + ]:       3176 :     if (_PyConfig_FromDict(config, configDict) < 0) {
     942                 :          0 :         _PyErr_WriteUnraisableMsg("reading getpath results", NULL);
     943                 :          0 :         Py_DECREF(dict);
     944                 :          0 :         return PyStatus_Error("error getting getpath results");
     945                 :            :     }
     946                 :            : 
     947                 :       3176 :     Py_DECREF(dict);
     948                 :            : 
     949                 :       3176 :     return _PyStatus_OK();
     950                 :            : }
     951                 :            : 

Generated by: LCOV version 1.14