LCOV - code coverage report
Current view: | top level - Python - initconfig.c (source / functions) |  |  | Hit | Total | Coverage
Test: | CPython 3.12 LCOV report [commit 5e6661bce9] |  | Lines: | 831 | 1406 | 59.1 %
Date: | 2023-03-20 08:15:36 |  | Functions: | 61 | 86 | 70.9 %
|  |  | Branches: | 543 | 1351 | 40.2 %

               Branch data     Line data    Source code
           1                 :            : #include "Python.h"
           2                 :            : #include "pycore_fileutils.h"     // _Py_HasFileSystemDefaultEncodeErrors
           3                 :            : #include "pycore_getopt.h"        // _PyOS_GetOpt()
           4                 :            : #include "pycore_initconfig.h"    // _PyStatus_OK()
           5                 :            : #include "pycore_interp.h"        // _PyInterpreterState.runtime
           6                 :            : #include "pycore_long.h"          // _PY_LONG_MAX_STR_DIGITS_THRESHOLD
           7                 :            : #include "pycore_pathconfig.h"    // _Py_path_config
           8                 :            : #include "pycore_pyerrors.h"      // _PyErr_GetRaisedException()
           9                 :            : #include "pycore_pylifecycle.h"   // _Py_PreInitializeFromConfig()
          10                 :            : #include "pycore_pymem.h"         // _PyMem_SetDefaultAllocator()
          11                 :            : #include "pycore_pystate.h"       // _PyThreadState_GET()
          12                 :            :
          13                 :            : #include "osdefs.h"               // DELIM
          14                 :            :
          15                 :            : #include <locale.h>               // setlocale()
          16                 :            : #include <stdlib.h>               // getenv()
          17                 :            : #if defined(MS_WINDOWS) || defined(__CYGWIN__)
          18                 :            : #  ifdef HAVE_IO_H
          19                 :            : #    include <io.h>
          20                 :            : #  endif
          21                 :            : #  ifdef HAVE_FCNTL_H
          22                 :            : #    include <fcntl.h>            // O_BINARY
          23                 :            : #  endif
          24                 :            : #endif
          25                 :            :
          26                 :            : /* --- Command line options --------------------------------------- */
          27                 :            :
          28                 :            : /* Short usage message (with %s for argv0) */
          29                 :            : static const char usage_line[] =
          30                 :            : "usage: %ls [option] ... [-c cmd | -m mod | file | -] [arg] ...\n";
          31                 :            :
          32                 :            : /* Long help message */
          33                 :            : /* Lines sorted by option name; keep in sync with usage_envvars* below */
          34                 :            : static const char usage_help[] = "\
          35                 :            : Options (and corresponding environment variables):\n\
          36                 :            : -b     : issue warnings about str(bytes_instance), str(bytearray_instance)\n\
          37                 :            :          and comparing bytes/bytearray with str. (-bb: issue errors)\n\
          38                 :            : -B     : don't write .pyc files on import; also PYTHONDONTWRITEBYTECODE=x\n\
          39                 :            : -c cmd : program passed in as string (terminates option list)\n\
          40                 :            : -d     : turn on parser debugging output (for experts only, only works on\n\
          41                 :            :          debug builds); also PYTHONDEBUG=x\n\
          42                 :            : -E     : ignore PYTHON* environment variables (such as PYTHONPATH)\n\
          43                 :            : -h     : print this help message and exit (also -? or --help)\n\
          44                 :            : -i     : inspect interactively after running script; forces a prompt even\n\
          45                 :            :          if stdin does not appear to be a terminal; also PYTHONINSPECT=x\n\
          46                 :            : -I     : isolate Python from the user's environment (implies -E and -s)\n\
          47                 :            : -m mod : run library module as a script (terminates option list)\n\
          48                 :            : -O     : remove assert and __debug__-dependent statements; add .opt-1 before\n\
          49                 :            :          .pyc extension; also PYTHONOPTIMIZE=x\n\
          50                 :            : -OO    : do -O changes and also discard docstrings; add .opt-2 before\n\
          51                 :            :          .pyc extension\n\
          52                 :            : -P     : don't prepend a potentially unsafe path to sys.path\n\
          53                 :            : -q     : don't print version and copyright messages on interactive startup\n\
          54                 :            : -s     : don't add user site directory to sys.path; also PYTHONNOUSERSITE\n\
          55                 :            : -S     : don't imply 'import site' on initialization\n\
          56                 :            : -u     : force the stdout and stderr streams to be unbuffered;\n\
          57                 :            :          this option has no effect on stdin; also PYTHONUNBUFFERED=x\n\
          58                 :            : -v     : verbose (trace import statements); also PYTHONVERBOSE=x\n\
          59                 :            :          can be supplied multiple times to increase verbosity\n\
          60                 :            : -V     : print the Python version number and exit (also --version)\n\
          61                 :            :          when given twice, print more information about the build\n\
          62                 :            : -W arg : warning control; arg is action:message:category:module:lineno\n\
          63                 :            :          also PYTHONWARNINGS=arg\n\
          64                 :            : -x     : skip first line of source, allowing use of non-Unix forms of #!cmd\n\
          65                 :            : -X opt : set implementation-specific option\n\
          66                 :            : --check-hash-based-pycs always|default|never:\n\
          67                 :            :          control how Python invalidates hash-based .pyc files\n\
          68                 :            : --help-env      : print help about Python environment variables and exit\n\
          69                 :            : --help-xoptions : print help about implementation-specific -X options and exit\n\
          70                 :            : --help-all      : print complete help information and exit\n\
          71                 :            : Arguments:\n\
          72                 :            : file   : program read from script file\n\
          73                 :            : -      : program read from stdin (default; interactive mode if a tty)\n\
          74                 :            : arg ...: arguments passed to program in sys.argv[1:]\n\
          75                 :            : ";
          76                 :            :
          77                 :            : static const char usage_xoptions[] = "\
          78                 :            : The following implementation-specific options are available:\n\
          79                 :            : \n\
          80                 :            : -X faulthandler: enable faulthandler\n\
          81                 :            : \n\
          82                 :            : -X showrefcount: output the total reference count and number of used\n\
          83                 :            :     memory blocks when the program finishes or after each statement in the\n\
          84                 :            :     interactive interpreter. This only works on debug builds\n\
          85                 :            : \n\
          86                 :            : -X tracemalloc: start tracing Python memory allocations using the\n\
          87                 :            :     tracemalloc module. By default, only the most recent frame is stored in a\n\
          88                 :            :     traceback of a trace. Use -X tracemalloc=NFRAME to start tracing with a\n\
          89                 :            :     traceback limit of NFRAME frames\n\
          90                 :            : \n\
          91                 :            : -X importtime: show how long each import takes. It shows module name,\n\
          92                 :            :     cumulative time (including nested imports) and self time (excluding\n\
          93                 :            :     nested imports). Note that its output may be broken in multi-threaded\n\
          94                 :            :     application. Typical usage is python3 -X importtime -c 'import asyncio'\n\
          95                 :            : \n\
          96                 :            : -X dev: enable CPython's \"development mode\", introducing additional runtime\n\
          97                 :            :     checks which are too expensive to be enabled by default. Effect of the\n\
          98                 :            :     developer mode:\n\
          99                 :            :        * Add default warning filter, as -W default\n\
         100                 :            :        * Install debug hooks on memory allocators: see the PyMem_SetupDebugHooks()\n\
         101                 :            :          C function\n\
         102                 :            :        * Enable the faulthandler module to dump the Python traceback on a crash\n\
         103                 :            :        * Enable asyncio debug mode\n\
         104                 :            :        * Set the dev_mode attribute of sys.flags to True\n\
         105                 :            :        * io.IOBase destructor logs close() exceptions\n\
         106                 :            : \n\
         107                 :            : -X utf8: enable UTF-8 mode for operating system interfaces, overriding the default\n\
         108                 :            :     locale-aware mode. -X utf8=0 explicitly disables UTF-8 mode (even when it would\n\
         109                 :            :     otherwise activate automatically)\n\
         110                 :            : \n\
         111                 :            : -X pycache_prefix=PATH: enable writing .pyc files to a parallel tree rooted at the\n\
         112                 :            :     given directory instead of to the code tree\n\
         113                 :            : \n\
         114                 :            : -X warn_default_encoding: enable opt-in EncodingWarning for 'encoding=None'\n\
         115                 :            : \n\
         116                 :            : -X no_debug_ranges: disable the inclusion of the tables mapping extra location \n\
         117                 :            :    information (end line, start column offset and end column offset) to every \n\
         118                 :            :    instruction in code objects. This is useful when smaller code objects and pyc \n\
         119                 :            :    files are desired as well as suppressing the extra visual location indicators \n\
         120                 :            :    when the interpreter displays tracebacks.\n\
         121                 :            : \n\
         122                 :            : -X perf: activate support for the Linux \"perf\" profiler by activating the \"perf\"\n\
         123                 :            :     trampoline. When this option is activated, the Linux \"perf\" profiler will be \n\
         124                 :            :     able to report Python calls. This option is only available on some platforms and will \n\
         125                 :            :     do nothing if is not supported on the current system. The default value is \"off\".\n\
         126                 :            : \n\
         127                 :            : -X frozen_modules=[on|off]: whether or not frozen modules should be used.\n\
         128                 :            :    The default is \"on\" (or \"off\" if you are running a local build).\n\
         129                 :            : \n\
         130                 :            : -X int_max_str_digits=number: limit the size of int<->str conversions.\n\
         131                 :            :     This helps avoid denial of service attacks when parsing untrusted data.\n\
         132                 :            :     The default is sys.int_info.default_max_str_digits.  0 disables."
         133                 :            :
         134                 :            : #ifdef Py_STATS
         135                 :            : "\n\
         136                 :            : \n\
         137                 :            : -X pystats: Enable pystats collection at startup."
         138                 :            : #endif
         139                 :            : ;
         140                 :            :
         141                 :            : /* Envvars that don't have equivalent command-line options are listed first */
         142                 :            : static const char usage_envvars[] =
         143                 :            : "Environment variables that change behavior:\n"
         144                 :            : "PYTHONSTARTUP: file executed on interactive startup (no default)\n"
         145                 :            : "PYTHONPATH   : '%lc'-separated list of directories prefixed to the\n"
         146                 :            : "               default module search path.  The result is sys.path.\n"
         147                 :            : "PYTHONSAFEPATH: don't prepend a potentially unsafe path to sys.path.\n"
         148                 :            : "PYTHONHOME   : alternate <prefix> directory (or <prefix>%lc<exec_prefix>).\n"
         149                 :            : "               The default module search path uses %s.\n"
         150                 :            : "PYTHONPLATLIBDIR : override sys.platlibdir.\n"
         151                 :            : "PYTHONCASEOK : ignore case in 'import' statements (Windows).\n"
         152                 :            : "PYTHONUTF8: if set to 1, enable the UTF-8 mode.\n"
         153                 :            : "PYTHONIOENCODING: Encoding[:errors] used for stdin/stdout/stderr.\n"
         154                 :            : "PYTHONFAULTHANDLER: dump the Python traceback on fatal errors.\n"
         155                 :            : "PYTHONHASHSEED: if this variable is set to 'random', a random value is used\n"
         156                 :            : "   to seed the hashes of str and bytes objects.  It can also be set to an\n"
         157                 :            : "   integer in the range [0,4294967295] to get hash values with a\n"
         158                 :            : "   predictable seed.\n"
         159                 :            : "PYTHONINTMAXSTRDIGITS: limits the maximum digit characters in an int value\n"
         160                 :            : "   when converting from a string and when converting an int back to a str.\n"
         161                 :            : "   A value of 0 disables the limit.  Conversions to or from bases 2, 4, 8,\n"
         162                 :            : "   16, and 32 are never limited.\n"
         163                 :            : "PYTHONMALLOC: set the Python memory allocators and/or install debug hooks\n"
         164                 :            : "   on Python memory allocators. Use PYTHONMALLOC=debug to install debug\n"
         165                 :            : "   hooks.\n"
         166                 :            : "PYTHONCOERCECLOCALE: if this variable is set to 0, it disables the locale\n"
         167                 :            : "   coercion behavior. Use PYTHONCOERCECLOCALE=warn to request display of\n"
         168                 :            : "   locale coercion and locale compatibility warnings on stderr.\n"
         169                 :            : "PYTHONBREAKPOINT: if this variable is set to 0, it disables the default\n"
         170                 :            : "   debugger. It can be set to the callable of your debugger of choice.\n"
         171                 :            : "PYTHONDEVMODE: enable the development mode.\n"
         172                 :            : "PYTHONPYCACHEPREFIX: root directory for bytecode cache (pyc) files.\n"
         173                 :            : "PYTHONWARNDEFAULTENCODING: enable opt-in EncodingWarning for 'encoding=None'.\n"
         174                 :            : "PYTHONNODEBUGRANGES: If this variable is set, it disables the inclusion of the \n"
         175                 :            : "   tables mapping extra location information (end line, start column offset \n"
         176                 :            : "   and end column offset) to every instruction in code objects. This is useful \n"
         177                 :            : "   when smaller code objects and pyc files are desired as well as suppressing the \n"
         178                 :            : "   extra visual location indicators when the interpreter displays tracebacks.\n"
         179                 :            : "These variables have equivalent command-line parameters (see --help for details):\n"
         180                 :            : "PYTHONDEBUG             : enable parser debug mode (-d)\n"
         181                 :            : "PYTHONDONTWRITEBYTECODE : don't write .pyc files (-B)\n"
         182                 :            : "PYTHONINSPECT           : inspect interactively after running script (-i)\n"
         183                 :            : "PYTHONINTMAXSTRDIGITS   : limit max digit characters in an int value\n"
         184                 :            : "                          (-X int_max_str_digits=number)\n"
         185                 :            : "PYTHONNOUSERSITE        : disable user site directory (-s)\n"
         186                 :            : "PYTHONOPTIMIZE          : enable level 1 optimizations (-O)\n"
         187                 :            : "PYTHONUNBUFFERED        : disable stdout/stderr buffering (-u)\n"
         188                 :            : "PYTHONVERBOSE           : trace import statements (-v)\n"
         189                 :            : "PYTHONWARNINGS=arg      : warning control (-W arg)\n";
         190                 :            :
         191                 :            : #if defined(MS_WINDOWS)
         192                 :            : #  define PYTHONHOMEHELP "<prefix>\\python{major}{minor}"
         193                 :            : #else
         194                 :            : #  define PYTHONHOMEHELP "<prefix>/lib/pythonX.X"
         195                 :            : #endif
         196                 :            :
         197                 :            :
         198                 :            : /* --- Global configuration variables ----------------------------- */
         199                 :            :
         200                 :            : /* UTF-8 mode (PEP 540): if equals to 1, use the UTF-8 encoding, and change
         201                 :            :    stdin and stdout error handler to "surrogateescape". */
         202                 :            : int Py_UTF8Mode = 0;
         203                 :            : int Py_DebugFlag = 0; /* Needed by parser.c */
         204                 :            : int Py_VerboseFlag = 0; /* Needed by import.c */
         205                 :            : int Py_QuietFlag = 0; /* Needed by sysmodule.c */
         206                 :            : int Py_InteractiveFlag = 0; /* Previously, was used by Py_FdIsInteractive() */
         207                 :            : int Py_InspectFlag = 0; /* Needed to determine whether to exit at SystemExit */
         208                 :            : int Py_OptimizeFlag = 0; /* Needed by compile.c */
         209                 :            : int Py_NoSiteFlag = 0; /* Suppress 'import site' */
         210                 :            : int Py_BytesWarningFlag = 0; /* Warn on str(bytes) and str(buffer) */
         211                 :            : int Py_FrozenFlag = 0; /* Needed by getpath.c */
         212                 :            : int Py_IgnoreEnvironmentFlag = 0; /* e.g. PYTHONPATH, PYTHONHOME */
         213                 :            : int Py_DontWriteBytecodeFlag = 0; /* Suppress writing bytecode files (*.pyc) */
         214                 :            : int Py_NoUserSiteDirectory = 0; /* for -s and site.py */
         215                 :            : int Py_UnbufferedStdioFlag = 0; /* Unbuffered binary std{in,out,err} */
         216                 :            : int Py_HashRandomizationFlag = 0; /* for -R and PYTHONHASHSEED */
         217                 :            : int Py_IsolatedFlag = 0; /* for -I, isolate from user's env */
         218                 :            : #ifdef MS_WINDOWS
         219                 :            : int Py_LegacyWindowsFSEncodingFlag = 0; /* Uses mbcs instead of utf-8 */
         220                 :            : int Py_LegacyWindowsStdioFlag = 0; /* Uses FileIO instead of WindowsConsoleIO */
         221                 :            : #endif
         222                 :            :
         223                 :            :
         224                 :            : static PyObject *
         225                 :          0 : _Py_GetGlobalVariablesAsDict(void)
         226                 :            : {
         227                 :            : _Py_COMP_DIAG_PUSH
         228                 :            : _Py_COMP_DIAG_IGNORE_DEPR_DECLS
         229                 :            :     PyObject *dict, *obj;
         230                 :            :
         231                 :          0 :     dict = PyDict_New();
         232         [ #  # ]:          0 :     if (dict == NULL) {
         233                 :          0 :         return NULL;
         234                 :            :     }
         235                 :            :
         236                 :            : #define SET_ITEM(KEY, EXPR) \
         237                 :            :         do { \
         238                 :            :             obj = (EXPR); \
         239                 :            :             if (obj == NULL) { \
         240                 :            :                 return NULL; \
         241                 :            :             } \
         242                 :            :             int res = PyDict_SetItemString(dict, (KEY), obj); \
         243                 :            :             Py_DECREF(obj); \
         244                 :            :             if (res < 0) { \
         245                 :            :                 goto fail; \
         246                 :            :             } \
         247                 :            :         } while (0)
         248                 :            : #define SET_ITEM_INT(VAR) \
         249                 :            :     SET_ITEM(#VAR, PyLong_FromLong(VAR))
         250                 :            : #define FROM_STRING(STR) \
         251                 :            :     ((STR != NULL) ? \
         252                 :            :         PyUnicode_FromString(STR) \
         253                 :            :         : Py_NewRef(Py_None))
         254                 :            : #define SET_ITEM_STR(VAR) \
         255                 :            :     SET_ITEM(#VAR, FROM_STRING(VAR))
         256                 :            :
         257   [ #  #  #  #  :          0 :     SET_ITEM_STR(Py_FileSystemDefaultEncoding);
                       #  # ]
         258   [ #  #  #  # ]:          0 :     SET_ITEM_INT(Py_HasFileSystemDefaultEncoding);
         259   [ #  #  #  #  :          0 :     SET_ITEM_STR(Py_FileSystemDefaultEncodeErrors);
                       #  # ]
         260   [ #  #  #  # ]:          0 :     SET_ITEM_INT(_Py_HasFileSystemDefaultEncodeErrors);
         261                 :            :
         262   [ #  #  #  # ]:          0 :     SET_ITEM_INT(Py_UTF8Mode);
         263   [ #  #  #  # ]:          0 :     SET_ITEM_INT(Py_DebugFlag);
         264   [ #  #  #  # ]:          0 :     SET_ITEM_INT(Py_VerboseFlag);
         265   [ #  #  #  # ]:          0 :     SET_ITEM_INT(Py_QuietFlag);
         266   [ #  #  #  # ]:          0 :     SET_ITEM_INT(Py_InteractiveFlag);
         267   [ #  #  #  # ]:          0 :     SET_ITEM_INT(Py_InspectFlag);
         268                 :            :
         269   [ #  #  #  # ]:          0 :     SET_ITEM_INT(Py_OptimizeFlag);
         270   [ #  #  #  # ]:          0 :     SET_ITEM_INT(Py_NoSiteFlag);
         271   [ #  #  #  # ]:          0 :     SET_ITEM_INT(Py_BytesWarningFlag);
         272   [ #  #  #  # ]:          0 :     SET_ITEM_INT(Py_FrozenFlag);
         273   [ #  #  #  # ]:          0 :     SET_ITEM_INT(Py_IgnoreEnvironmentFlag);
         274   [ #  #  #  # ]:          0 :     SET_ITEM_INT(Py_DontWriteBytecodeFlag);
         275   [ #  #  #  # ]:          0 :     SET_ITEM_INT(Py_NoUserSiteDirectory);
         276   [ #  #  #  # ]:          0 :     SET_ITEM_INT(Py_UnbufferedStdioFlag);
         277   [ #  #  #  # ]:          0 :     SET_ITEM_INT(Py_HashRandomizationFlag);
         278   [ #  #  #  # ]:          0 :     SET_ITEM_INT(Py_IsolatedFlag);
         279                 :            :
         280                 :            : #ifdef MS_WINDOWS
         281                 :            :     SET_ITEM_INT(Py_LegacyWindowsFSEncodingFlag);
         282                 :            :     SET_ITEM_INT(Py_LegacyWindowsStdioFlag);
         283                 :            : #endif
         284                 :            :
         285                 :          0 :     return dict;
         286                 :            :
         287                 :          0 : fail:
         288                 :          0 :     Py_DECREF(dict);
         289                 :          0 :     return NULL;
         290                 :            :
         291                 :            : #undef FROM_STRING
         292                 :            : #undef SET_ITEM
         293                 :            : #undef SET_ITEM_INT
         294                 :            : #undef SET_ITEM_STR
         295                 :            : _Py_COMP_DIAG_POP
         296                 :            : }
         297                 :            :
         298                 :            : char*
         299                 :         29 : Py_GETENV(const char *name)
         300                 :            : {
         301                 :            : _Py_COMP_DIAG_PUSH
         302                 :            : _Py_COMP_DIAG_IGNORE_DEPR_DECLS
         303         [ +  + ]:         29 :     if (Py_IgnoreEnvironmentFlag) {
         304                 :         28 :         return NULL;
         305                 :            :     }
         306                 :          1 :     return getenv(name);
         307                 :            : _Py_COMP_DIAG_POP
         308                 :            : }
         309                 :            :
         310                 :            : /* --- PyStatus ----------------------------------------------- */
         311                 :            :
         312                 :         29 : PyStatus PyStatus_Ok(void)
         313                 :         29 : { return _PyStatus_OK(); }
         314                 :            :
         315                 :          0 : PyStatus PyStatus_Error(const char *err_msg)
         316                 :            : {
         317                 :            :     assert(err_msg != NULL);
         318                 :          0 :     return (PyStatus){._type = _PyStatus_TYPE_ERROR,
         319                 :            :                       .err_msg = err_msg};
         320                 :            : }
         321                 :            :
         322                 :          0 : PyStatus PyStatus_NoMemory(void)
         323                 :          0 : { return PyStatus_Error("memory allocation failed"); }
         324                 :            :
         325                 :          0 : PyStatus PyStatus_Exit(int exitcode)
         326                 :          0 : { return _PyStatus_EXIT(exitcode); }
         327                 :            :
         328                 :            :
         329                 :          0 : int PyStatus_IsError(PyStatus status)
         330                 :          0 : { return _PyStatus_IS_ERROR(status); }
         331                 :            :
         332                 :          0 : int PyStatus_IsExit(PyStatus status)
         333                 :          0 : { return _PyStatus_IS_EXIT(status); }
         334                 :            :
         335                 :         50 : int PyStatus_Exception(PyStatus status)
         336                 :         50 : { return _PyStatus_EXCEPTION(status); }
         337                 :            :
         338                 :            : PyObject*
         339                 :          0 : _PyErr_SetFromPyStatus(PyStatus status)
         340                 :            : {
         341         [ #  # ]:          0 :     if (!_PyStatus_IS_ERROR(status)) {
         342                 :          0 :         PyErr_Format(PyExc_SystemError,
         343                 :            :                      "%s() expects an error PyStatus",
         344                 :            :                      _PyStatus_GET_FUNC());
         345                 :            :     }
         346         [ #  # ]:          0 :     else if (status.func) {
         347                 :          0 :         PyErr_Format(PyExc_ValueError, "%s: %s", status.func, status.err_msg);
         348                 :            :     }
         349                 :            :     else {
         350                 :          0 :         PyErr_Format(PyExc_ValueError, "%s", status.err_msg);
         351                 :            :     }
         352                 :          0 :     return NULL;
         353                 :            : }
         354                 :            :
         355                 :            :
         356                 :            : /* --- PyWideStringList ------------------------------------------------ */
         357                 :            :
         358                 :            : #ifndef NDEBUG
         359                 :            : int
         360                 :            : _PyWideStringList_CheckConsistency(const PyWideStringList *list)
         361                 :            : {
         362                 :            :     assert(list->length >= 0);
         363                 :            :     if (list->length != 0) {
         364                 :            :         assert(list->items != NULL);
         365                 :            :     }
         366                 :            :     for (Py_ssize_t i = 0; i < list->length; i++) {
         367                 :            :         assert(list->items[i] != NULL);
         368                 :            :     }
         369                 :            :     return 1;
         370                 :            : }
         371                 :            : #endif   /* Py_DEBUG */
         372                 :            :
         373                 :            :
         374                 :            : void
         375                 :       1811 : _PyWideStringList_Clear(PyWideStringList *list)
         376                 :            : {
         377                 :            :     assert(_PyWideStringList_CheckConsistency(list));
         378         [ +  + ]:       3815 :     for (Py_ssize_t i=0; i < list->length; i++) {
         379                 :       2004 :         PyMem_RawFree(list->items[i]);
         380                 :            :     }
         381                 :       1811 :     PyMem_RawFree(list->items);
         382                 :       1811 :     list->length = 0;
         383                 :       1811 :     list->items = NULL;
         384                 :       1811 : }
         385                 :            :
         386                 :            :
         387                 :            : int
         388                 :        523 : _PyWideStringList_Copy(PyWideStringList *list, const PyWideStringList *list2)
         389                 :            : {
         390                 :            :     assert(_PyWideStringList_CheckConsistency(list));
         391                 :            :     assert(_PyWideStringList_CheckConsistency(list2));
         392                 :            :
         393         [ +  + ]:        523 :     if (list2->length == 0) {
         394                 :        248 :         _PyWideStringList_Clear(list);
         395                 :        248 :         return 0;
         396                 :            :     }
         397                 :            :
         398                 :        275 :     PyWideStringList copy = _PyWideStringList_INIT;
         399                 :            :
         400                 :        275 :     size_t size = list2->length * sizeof(list2->items[0]);
         401                 :        275 :     copy.items = PyMem_RawMalloc(size);
         402         [ -  + ]:        275 :     if (copy.items == NULL) {
         403                 :          0 :         return -1;
         404                 :            :     }
         405                 :            :
         406         [ +  + ]:       1660 :     for (Py_ssize_t i=0; i < list2->length; i++) {
         407                 :       1385 :         wchar_t *item = _PyMem_RawWcsdup(list2->items[i]);
         408         [ -  + ]:       1385 :         if (item == NULL) {
         409                 :          0 :             _PyWideStringList_Clear(&copy);
         410                 :          0 :             return -1;
         411                 :            :         }
         412                 :       1385 :         copy.items[i] = item;
         413                 :       1385 :         copy.length = i + 1;
         414                 :            :     }
         415                 :            :
         416                 :        275 :     _PyWideStringList_Clear(list);
         417                 :        275 :     *list = copy;
         418                 :        275 :     return 0;
         419                 :            : }
         420                 :            :
         421                 :            :
         422                 :            : PyStatus
         423                 :        335 : PyWideStringList_Insert(PyWideStringList *list,
         424                 :            :                         Py_ssize_t index, const wchar_t *item)
         425                 :            : {
         426                 :        335 :     Py_ssize_t len = list->length;
         427         [ -  + ]:        335 :     if (len == PY_SSIZE_T_MAX) {
         428                 :            :         /* length+1 would overflow */
         429                 :          0 :         return _PyStatus_NO_MEMORY();
         430                 :            :     }
         431         [ -  + ]:        335 :     if (index < 0) {
         432                 :          0 :         return _PyStatus_ERR("PyWideStringList_Insert index must be >= 0");
         433                 :            :     }
         434         [ -  + ]:        335 :     if (index > len) {
         435                 :          0 :         index = len;
         436                 :            :     }
         437                 :            :
         438                 :        335 :     wchar_t *item2 = _PyMem_RawWcsdup(item);
         439         [ -  + ]:        335 :     if (item2 == NULL) {
         440                 :          0 :         return _PyStatus_NO_MEMORY();
         441                 :            :     }
         442                 :            :
         443                 :        335 :     size_t size = (len + 1) * sizeof(list->items[0]);
         444                 :        335 :     wchar_t **items2 = (wchar_t **)PyMem_RawRealloc(list->items, size);
         445         [ -  + ]:        335 :     if (items2 == NULL) {
         446                 :          0 :         PyMem_RawFree(item2);
         447                 :          0 :         return _PyStatus_NO_MEMORY();
         448                 :            :     }
         449                 :            :
         450         [ -  + ]:        335 :     if (index < len) {
         451                 :          0 :         memmove(&items2[index + 1],
         452                 :          0 :                 &items2[index],
         453                 :          0 :                 (len - index) * sizeof(items2[0]));
         454                 :            :     }
         455                 :            :
         456                 :        335 :     items2[index] = item2;
         457                 :        335 :     list->items = items2;
         458                 :        335 :     list->length++;
         459                 :        335 :     return _PyStatus_OK();
         460                 :            : }
         461                 :            :
         462                 :            :
         463                 :            : PyStatus
         464                 :        335 : PyWideStringList_Append(PyWideStringList *list, const wchar_t *item)
         465                 :            : {
         466                 :        335 :     return PyWideStringList_Insert(list, list->length, item);
         467                 :            : }
         468                 :            :
         469                 :            :
         470                 :            : PyStatus
         471                 :        100 : _PyWideStringList_Extend(PyWideStringList *list, const PyWideStringList *list2)
         472                 :            : {
         473         [ -  + ]:        100 :     for (Py_ssize_t i = 0; i < list2->length; i++) {
         474                 :          0 :         PyStatus status = PyWideStringList_Append(list, list2->items[i]);
         475         [ #  # ]:          0 :         if (_PyStatus_EXCEPTION(status)) {
         476                 :          0 :             return status;
         477                 :            :         }
         478                 :            :     }
         479                 :        100 :     return _PyStatus_OK();
         480                 :            : }
         481                 :            :
         482                 :            :
         483                 :            : static int
         484                 :          0 : _PyWideStringList_Find(PyWideStringList *list, const wchar_t *item)
         485                 :            : {
         486         [ #  # ]:          0 :     for (Py_ssize_t i = 0; i < list->length; i++) {
         487         [ #  # ]:          0 :         if (wcscmp(list->items[i], item) == 0) {
         488                 :          0 :             return 1;
         489                 :            :         }
         490                 :            :     }
         491                 :          0 :     return 0;
         492                 :            : }
         493                 :            :
         494                 :            :
         495                 :            : PyObject*
         496                 :        225 : _PyWideStringList_AsList(const PyWideStringList *list)
         497                 :            : {
         498                 :            :     assert(_PyWideStringList_CheckConsistency(list));
         499                 :            :
         500                 :        225 :     PyObject *pylist = PyList_New(list->length);
         501         [ -  + ]:        225 :     if (pylist == NULL) {
         502                 :          0 :         return NULL;
         503                 :            :     }
         504                 :            :
         505         [ +  + ]:        812 :     for (Py_ssize_t i = 0; i < list->length; i++) {
         506                 :        587 :         PyObject *item = PyUnicode_FromWideChar(list->items[i], -1);
         507         [ -  + ]:        587 :         if (item == NULL) {
         508                 :          0 :             Py_DECREF(pylist);
         509                 :          0 :             return NULL;
         510                 :            :         }
         511                 :        587 :         PyList_SET_ITEM(pylist, i, item);
         512                 :            :     }
         513                 :        225 :     return pylist;
         514                 :            : }
         515                 :            :
         516                 :            :
         517                 :            : /* --- Py_SetStandardStreamEncoding() ----------------------------- */
         518                 :            :
         519                 :            : /* Helper to allow an embedding application to override the normal
         520                 :            :  * mechanism that attempts to figure out an appropriate IO encoding
         521                 :            :  */
         522                 :            :
         523                 :            : static char *_Py_StandardStreamEncoding = NULL;
         524                 :            : static char *_Py_StandardStreamErrors = NULL;
         525                 :            :
         526                 :            : int
         527                 :          0 : Py_SetStandardStreamEncoding(const char *encoding, const char *errors)
         528                 :            : {
         529         [ #  # ]:          0 :     if (Py_IsInitialized()) {
         530                 :            :         /* This is too late to have any effect */
         531                 :          0 :         return -1;
         532                 :            :     }
         533                 :            :
         534                 :          0 :     int res = 0;
         535                 :            :
         536                 :            :     /* Py_SetStandardStreamEncoding() can be called before Py_Initialize(),
         537                 :            :        but Py_Initialize() can change the allocator. Use a known allocator
         538                 :            :        to be able to release the memory later. */
         539                 :            :     PyMemAllocatorEx old_alloc;
         540                 :          0 :     _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
         541                 :            :
         542                 :            :     /* Can't call PyErr_NoMemory() on errors, as Python hasn't been
         543                 :            :      * initialised yet.
         544                 :            :      *
         545                 :            :      * However, the raw memory allocators are initialised appropriately
         546                 :            :      * as C static variables, so _PyMem_RawStrdup is OK even though
         547                 :            :      * Py_Initialize hasn't been called yet.
         548                 :            :      */
         549         [ #  # ]:          0 :     if (encoding) {
         550                 :          0 :         PyMem_RawFree(_Py_StandardStreamEncoding);
         551                 :          0 :         _Py_StandardStreamEncoding = _PyMem_RawStrdup(encoding);
         552         [ #  # ]:          0 :         if (!_Py_StandardStreamEncoding) {
         553                 :          0 :             res = -2;
         554                 :          0 :             goto done;
         555                 :            :         }
         556                 :            :     }
         557         [ #  # ]:          0 :     if (errors) {
         558                 :          0 :         PyMem_RawFree(_Py_StandardStreamErrors);
         559                 :          0 :         _Py_StandardStreamErrors = _PyMem_RawStrdup(errors);
         560         [ #  # ]:          0 :         if (!_Py_StandardStreamErrors) {
         561                 :          0 :             PyMem_RawFree(_Py_StandardStreamEncoding);
         562                 :          0 :             _Py_StandardStreamEncoding = NULL;
         563                 :          0 :             res = -3;
         564                 :          0 :             goto done;
         565                 :            :         }
         566                 :            :     }
         567                 :            : #ifdef MS_WINDOWS
         568                 :            :     if (_Py_StandardStreamEncoding) {
         569                 :            : _Py_COMP_DIAG_PUSH
         570                 :            : _Py_COMP_DIAG_IGNORE_DEPR_DECLS
         571                 :            :         /* Overriding the stream encoding implies legacy streams */
         572                 :            :         Py_LegacyWindowsStdioFlag = 1;
         573                 :            : _Py_COMP_DIAG_POP
         574                 :            :     }
         575                 :            : #endif
         576                 :            :
         577                 :          0 : done:
         578                 :          0 :     PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
         579                 :            :
         580                 :          0 :     return res;
         581                 :            : }
         582                 :            :
         583                 :            :
         584                 :            : void
         585                 :         50 : _Py_ClearStandardStreamEncoding(void)
         586                 :            : {
         587                 :            :     /* Use the same allocator than Py_SetStandardStreamEncoding() */
         588                 :            :     PyMemAllocatorEx old_alloc;
         589                 :         50 :     _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
         590                 :            :
         591                 :            :     /* We won't need them anymore. */
         592         [ -  + ]:         50 :     if (_Py_StandardStreamEncoding) {
         593                 :          0 :         PyMem_RawFree(_Py_StandardStreamEncoding);
         594                 :          0 :         _Py_StandardStreamEncoding = NULL;
         595                 :            :     }
         596         [ -  + ]:         50 :     if (_Py_StandardStreamErrors) {
         597                 :          0 :         PyMem_RawFree(_Py_StandardStreamErrors);
         598                 :          0 :         _Py_StandardStreamErrors = NULL;
         599                 :            :     }
         600                 :            :
         601                 :         50 :     PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
         602                 :         50 : }
         603                 :            :
         604                 :            :
         605                 :            : /* --- Py_GetArgcArgv() ------------------------------------------- */
         606                 :            :
         607                 :            : void
         608                 :         25 : _Py_ClearArgcArgv(void)
         609                 :            : {
         610                 :            :     PyMemAllocatorEx old_alloc;
         611                 :         25 :     _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
         612                 :            :
         613                 :         25 :     _PyWideStringList_Clear(&_PyRuntime.orig_argv);
         614                 :            :
         615                 :         25 :     PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
         616                 :         25 : }
         617                 :            :
         618                 :            :
         619                 :            : static int
         620                 :         29 : _Py_SetArgcArgv(Py_ssize_t argc, wchar_t * const *argv)
         621                 :            : {
         622                 :         29 :     const PyWideStringList argv_list = {.length = argc, .items = (wchar_t **)argv};
         623                 :            :     int res;
         624                 :            :
         625                 :            :     PyMemAllocatorEx old_alloc;
         626                 :         29 :     _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
         627                 :            :
         628                 :            :     // XXX _PyRuntime.orig_argv only gets cleared by Py_Main(),
         629                 :            :     // so it it currently leaks for embedders.
         630                 :         29 :     res = _PyWideStringList_Copy(&_PyRuntime.orig_argv, &argv_list);
         631                 :            :
         632                 :         29 :     PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
         633                 :         29 :     return res;
         634                 :            : }
         635                 :            :
         636                 :            :
         637                 :            : // _PyConfig_Write() calls _Py_SetArgcArgv() with PyConfig.orig_argv.
         638                 :            : void
         639                 :          0 : Py_GetArgcArgv(int *argc, wchar_t ***argv)
         640                 :            : {
         641                 :          0 :     *argc = (int)_PyRuntime.orig_argv.length;
         642                 :          0 :     *argv = _PyRuntime.orig_argv.items;
         643                 :          0 : }
         644                 :            :
         645                 :            :
         646                 :            : /* --- PyConfig ---------------------------------------------- */
         647                 :            :
         648                 :            : #define MAX_HASH_SEED 4294967295UL
         649                 :            :
         650                 :            :
         651                 :            : #ifndef NDEBUG
         652                 :            : static int
         653                 :            : config_check_consistency(const PyConfig *config)
         654                 :            : {
         655                 :            :     /* Check config consistency */
         656                 :            :     assert(config->isolated >= 0);
         657                 :            :     assert(config->use_environment >= 0);
         658                 :            :     assert(config->dev_mode >= 0);
         659                 :            :     assert(config->install_signal_handlers >= 0);
         660                 :            :     assert(config->use_hash_seed >= 0);
         661                 :            :     assert(config->hash_seed <= MAX_HASH_SEED);
         662                 :            :     assert(config->faulthandler >= 0);
         663                 :            :     assert(config->tracemalloc >= 0);
         664                 :            :     assert(config->import_time >= 0);
         665                 :            :     assert(config->code_debug_ranges >= 0);
         666                 :            :     assert(config->show_ref_count >= 0);
         667                 :            :     assert(config->dump_refs >= 0);
         668                 :            :     assert(config->malloc_stats >= 0);
         669                 :            :     assert(config->site_import >= 0);
         670                 :            :     assert(config->bytes_warning >= 0);
         671                 :            :     assert(config->warn_default_encoding >= 0);
         672                 :            :     assert(config->inspect >= 0);
         673                 :            :     assert(config->interactive >= 0);
         674                 :            :     assert(config->optimization_level >= 0);
         675                 :            :     assert(config->parser_debug >= 0);
         676                 :            :     assert(config->write_bytecode >= 0);
         677                 :            :     assert(config->verbose >= 0);
         678                 :            :     assert(config->quiet >= 0);
         679                 :            :     assert(config->user_site_directory >= 0);
         680                 :            :     assert(config->parse_argv >= 0);
         681                 :            :     assert(config->configure_c_stdio >= 0);
         682                 :            :     assert(config->buffered_stdio >= 0);
         683                 :            :     assert(_PyWideStringList_CheckConsistency(&config->orig_argv));
         684                 :            :     assert(_PyWideStringList_CheckConsistency(&config->argv));
         685                 :            :     /* sys.argv must be non-empty: empty argv is replaced with [''] */
         686                 :            :     assert(config->argv.length >= 1);
         687                 :            :     assert(_PyWideStringList_CheckConsistency(&config->xoptions));
         688                 :            :     assert(_PyWideStringList_CheckConsistency(&config->warnoptions));
         689                 :            :     assert(_PyWideStringList_CheckConsistency(&config->module_search_paths));
         690                 :            :     assert(config->module_search_paths_set >= 0);
         691                 :            :     assert(config->filesystem_encoding != NULL);
         692                 :            :     assert(config->filesystem_errors != NULL);
         693                 :            :     assert(config->stdio_encoding != NULL);
         694                 :            :     assert(config->stdio_errors != NULL);
         695                 :            : #ifdef MS_WINDOWS
         696                 :            :     assert(config->legacy_windows_stdio >= 0);
         697                 :            : #endif
         698                 :            :     /* -c and -m options are exclusive */
         699                 :            :     assert(!(config->run_command != NULL && config->run_module != NULL));
         700                 :            :     assert(config->check_hash_pycs_mode != NULL);
         701                 :            :     assert(config->_install_importlib >= 0);
         702                 :            :     assert(config->pathconfig_warnings >= 0);
         703                 :            :     assert(config->_is_python_build >= 0);
         704                 :            :     assert(config->safe_path >= 0);
         705                 :            :     assert(config->int_max_str_digits >= 0);
         706                 :            :     // config->use_frozen_modules is initialized later
         707                 :            :     // by _PyConfig_InitImportConfig().
         708                 :            :     return 1;
         709                 :            : }
         710                 :            : #endif
         711                 :            :
         712                 :            :
         713                 :            : /* Free memory allocated in config, but don't clear all attributes */
         714                 :            : void
         715                 :        141 : PyConfig_Clear(PyConfig *config)
         716                 :            : {
         717                 :            : #define CLEAR(ATTR) \
         718                 :            :     do { \
         719                 :            :         PyMem_RawFree(ATTR); \
         720                 :            :         ATTR = NULL; \
         721                 :            :     } while (0)
         722                 :            :
         723                 :        141 :     CLEAR(config->pycache_prefix);
         724                 :        141 :     CLEAR(config->pythonpath_env);
         725                 :        141 :     CLEAR(config->home);
         726                 :        141 :     CLEAR(config->program_name);
         727                 :            :
         728                 :        141 :     _PyWideStringList_Clear(&config->argv);
         729                 :        141 :     _PyWideStringList_Clear(&config->warnoptions);
         730                 :        141 :     _PyWideStringList_Clear(&config->xoptions);
         731                 :        141 :     _PyWideStringList_Clear(&config->module_search_paths);
         732                 :        141 :     config->module_search_paths_set = 0;
         733                 :        141 :     CLEAR(config->stdlib_dir);
         734                 :            :
         735                 :        141 :     CLEAR(config->executable);
         736                 :        141 :     CLEAR(config->base_executable);
         737                 :        141 :     CLEAR(config->prefix);
         738                 :        141 :     CLEAR(config->base_prefix);
         739                 :        141 :     CLEAR(config->exec_prefix);
         740                 :        141 :     CLEAR(config->base_exec_prefix);
         741                 :        141 :     CLEAR(config->platlibdir);
         742                 :            :
         743                 :        141 :     CLEAR(config->filesystem_encoding);
         744                 :        141 :     CLEAR(config->filesystem_errors);
         745                 :        141 :     CLEAR(config->stdio_encoding);
         746                 :        141 :     CLEAR(config->stdio_errors);
         747                 :        141 :     CLEAR(config->run_command);
         748                 :        141 :     CLEAR(config->run_module);
         749                 :        141 :     CLEAR(config->run_filename);
         750                 :        141 :     CLEAR(config->check_hash_pycs_mode);
         751                 :            :
         752                 :        141 :     _PyWideStringList_Clear(&config->orig_argv);
         753                 :            : #undef CLEAR
         754                 :        141 : }
         755                 :            :
         756                 :            :
         757                 :            : void
         758                 :         87 : _PyConfig_InitCompatConfig(PyConfig *config)
         759                 :            : {
         760                 :         87 :     memset(config, 0, sizeof(*config));
         761                 :            :
         762                 :         87 :     config->_config_init = (int)_PyConfig_INIT_COMPAT;
         763                 :         87 :     config->isolated = -1;
         764                 :         87 :     config->use_environment = -1;
         765                 :         87 :     config->dev_mode = -1;
         766                 :         87 :     config->install_signal_handlers = 1;
         767                 :         87 :     config->use_hash_seed = -1;
         768                 :         87 :     config->faulthandler = -1;
         769                 :         87 :     config->tracemalloc = -1;
         770                 :         87 :     config->perf_profiling = -1;
         771                 :         87 :     config->module_search_paths_set = 0;
         772                 :         87 :     config->parse_argv = 0;
         773                 :         87 :     config->site_import = -1;
         774                 :         87 :     config->bytes_warning = -1;
         775                 :         87 :     config->warn_default_encoding = 0;
         776                 :         87 :     config->inspect = -1;
         777                 :         87 :     config->interactive = -1;
         778                 :         87 :     config->optimization_level = -1;
         779                 :         87 :     config->parser_debug= -1;
         780                 :         87 :     config->write_bytecode = -1;
         781                 :         87 :     config->verbose = -1;
         782                 :         87 :     config->quiet = -1;
         783                 :         87 :     config->user_site_directory = -1;
         784                 :         87 :     config->configure_c_stdio = 0;
         785                 :         87 :     config->buffered_stdio = -1;
         786                 :         87 :     config->_install_importlib = 1;
         787                 :         87 :     config->check_hash_pycs_mode = NULL;
         788                 :         87 :     config->pathconfig_warnings = -1;
         789                 :         87 :     config->_init_main = 1;
         790                 :            : #ifdef MS_WINDOWS
         791                 :            :     config->legacy_windows_stdio = -1;
         792                 :            : #endif
         793                 :            : #ifdef Py_DEBUG
         794                 :            :     config->use_frozen_modules = 0;
         795                 :            : #else
         796                 :         87 :     config->use_frozen_modules = 1;
         797                 :            : #endif
         798                 :         87 :     config->safe_path = 0;
         799                 :         87 :     config->int_max_str_digits = -1;
         800                 :         87 :     config->_is_python_build = 0;
         801                 :         87 :     config->code_debug_ranges = 1;
         802                 :         87 : }
         803                 :            :
         804                 :            :
         805                 :            : static void
         806                 :         87 : config_init_defaults(PyConfig *config)
         807                 :            : {
         808                 :         87 :     _PyConfig_InitCompatConfig(config);
         809                 :            :
         810                 :         87 :     config->isolated = 0;
         811                 :         87 :     config->use_environment = 1;
         812                 :         87 :     config->site_import = 1;
         813                 :         87 :     config->bytes_warning = 0;
         814                 :         87 :     config->inspect = 0;
         815                 :         87 :     config->interactive = 0;
         816                 :         87 :     config->optimization_level = 0;
         817                 :         87 :     config->parser_debug= 0;
         818                 :         87 :     config->write_bytecode = 1;
         819                 :         87 :     config->verbose = 0;
         820                 :         87 :     config->quiet = 0;
         821                 :         87 :     config->user_site_directory = 1;
         822                 :         87 :     config->buffered_stdio = 1;
         823                 :         87 :     config->pathconfig_warnings = 1;
         824                 :            : #ifdef MS_WINDOWS
         825                 :            :     config->legacy_windows_stdio = 0;
         826                 :            : #endif
         827                 :         87 : }
         828                 :            :
         829                 :            :
         830                 :            : void
         831                 :         62 : PyConfig_InitPythonConfig(PyConfig *config)
         832                 :            : {
         833                 :         62 :     config_init_defaults(config);
         834                 :            :
         835                 :         62 :     config->_config_init = (int)_PyConfig_INIT_PYTHON;
         836                 :         62 :     config->configure_c_stdio = 1;
         837                 :         62 :     config->parse_argv = 1;
         838                 :         62 : }
         839                 :            :
         840                 :            :
         841                 :            : void
         842                 :         25 : PyConfig_InitIsolatedConfig(PyConfig *config)
         843                 :            : {
         844                 :         25 :     config_init_defaults(config);
         845                 :            :
         846                 :         25 :     config->_config_init = (int)_PyConfig_INIT_ISOLATED;
         847                 :         25 :     config->isolated = 1;
         848                 :         25 :     config->use_environment = 0;
         849                 :         25 :     config->user_site_directory = 0;
         850                 :         25 :     config->dev_mode = 0;
         851                 :         25 :     config->install_signal_handlers = 0;
         852                 :         25 :     config->use_hash_seed = 0;
         853                 :         25 :     config->faulthandler = 0;
         854                 :         25 :     config->tracemalloc = 0;
         855                 :         25 :     config->perf_profiling = 0;
         856                 :         25 :     config->int_max_str_digits = _PY_LONG_DEFAULT_MAX_STR_DIGITS;
         857                 :         25 :     config->safe_path = 1;
         858                 :         25 :     config->pathconfig_warnings = 0;
         859                 :            : #ifdef MS_WINDOWS
         860                 :            :     config->legacy_windows_stdio = 0;
         861                 :            : #endif
         862                 :         25 : }
         863                 :            :
         864                 :            :
         865                 :            : /* Copy str into *config_str (duplicate the string) */
         866                 :            : PyStatus
         867                 :       1809 : PyConfig_SetString(PyConfig *config, wchar_t **config_str, const wchar_t *str)
         868                 :            : {
         869                 :       1809 :     PyStatus status = _Py_PreInitializeFromConfig(config, NULL);
         870         [ -  + ]:       1809 :     if (_PyStatus_EXCEPTION(status)) {
         871                 :          0 :         return status;
         872                 :            :     }
         873                 :            :
         874                 :            :     wchar_t *str2;
         875         [ +  + ]:       1809 :     if (str != NULL) {
         876                 :        828 :         str2 = _PyMem_RawWcsdup(str);
         877         [ -  + ]:        828 :         if (str2 == NULL) {
         878                 :          0 :             return _PyStatus_NO_MEMORY();
         879                 :            :         }
         880                 :            :     }
         881                 :            :     else {
         882                 :        981 :         str2 = NULL;
         883                 :            :     }
         884                 :       1809 :     PyMem_RawFree(*config_str);
         885                 :       1809 :     *config_str = str2;
         886                 :       1809 :     return _PyStatus_OK();
         887                 :            : }
         888                 :            :
         889                 :            :
         890                 :            : static PyStatus
         891                 :          0 : config_set_bytes_string(PyConfig *config, wchar_t **config_str,
         892                 :            :                         const char *str, const char *decode_err_msg)
         893                 :            : {
         894                 :          0 :     PyStatus status = _Py_PreInitializeFromConfig(config, NULL);
         895         [ #  # ]:          0 :     if (_PyStatus_EXCEPTION(status)) {
         896                 :          0 :         return status;
         897                 :            :     }
         898                 :            :
         899                 :            :     wchar_t *str2;
         900         [ #  # ]:          0 :     if (str != NULL) {
         901                 :            :         size_t len;
         902                 :          0 :         str2 = Py_DecodeLocale(str, &len);
         903         [ #  # ]:          0 :         if (str2 == NULL) {
         904         [ #  # ]:          0 :             if (len == (size_t)-2) {
         905                 :          0 :                 return _PyStatus_ERR(decode_err_msg);
         906                 :            :             }
         907                 :            :             else {
         908                 :          0 :                 return  _PyStatus_NO_MEMORY();
         909                 :            :             }
         910                 :            :         }
         911                 :            :     }
         912                 :            :     else {
         913                 :          0 :         str2 = NULL;
         914                 :            :     }
         915                 :          0 :     PyMem_RawFree(*config_str);
         916                 :          0 :     *config_str = str2;
         917                 :          0 :     return _PyStatus_OK();
         918                 :            : }
         919                 :            :
         920                 :            :
         921                 :            : #define CONFIG_SET_BYTES_STR(config, config_str, str, NAME) \
         922                 :            :     config_set_bytes_string(config, config_str, str, "cannot decode " NAME)
         923                 :            :
         924                 :            :
         925                 :            : /* Decode str using Py_DecodeLocale() and set the result into *config_str.
         926                 :            :    Pre-initialize Python if needed to ensure that encodings are properly
         927                 :            :    configured. */
         928                 :            : PyStatus
         929                 :          0 : PyConfig_SetBytesString(PyConfig *config, wchar_t **config_str,
         930                 :            :                         const char *str)
         931                 :            : {
         932                 :          0 :     return CONFIG_SET_BYTES_STR(config, config_str, str, "string");
         933                 :            : }
         934                 :            :
         935                 :            :
         936                 :            : PyStatus
         937                 :         58 : _PyConfig_Copy(PyConfig *config, const PyConfig *config2)
         938                 :            : {
         939                 :            :     PyStatus status;
         940                 :            :
         941                 :         58 :     PyConfig_Clear(config);
         942                 :            :
         943                 :            : #define COPY_ATTR(ATTR) config->ATTR = config2->ATTR
         944                 :            : #define COPY_WSTR_ATTR(ATTR) \
         945                 :            :     do { \
         946                 :            :         status = PyConfig_SetString(config, &config->ATTR, config2->ATTR); \
         947                 :            :         if (_PyStatus_EXCEPTION(status)) { \
         948                 :            :             return status; \
         949                 :            :         } \
         950                 :            :     } while (0)
         951                 :            : #define COPY_WSTRLIST(LIST) \
         952                 :            :     do { \
         953                 :            :         if (_PyWideStringList_Copy(&config->LIST, &config2->LIST) < 0) { \
         954                 :            :             return _PyStatus_NO_MEMORY(); \
         955                 :            :         } \
         956                 :            :     } while (0)
         957                 :            :
         958                 :         58 :     COPY_ATTR(_config_init);
         959                 :         58 :     COPY_ATTR(isolated);
         960                 :         58 :     COPY_ATTR(use_environment);
         961                 :         58 :     COPY_ATTR(dev_mode);
         962                 :         58 :     COPY_ATTR(install_signal_handlers);
         963                 :         58 :     COPY_ATTR(use_hash_seed);
         964                 :         58 :     COPY_ATTR(hash_seed);
         965                 :         58 :     COPY_ATTR(_install_importlib);
         966                 :         58 :     COPY_ATTR(faulthandler);
         967                 :         58 :     COPY_ATTR(tracemalloc);
         968                 :         58 :     COPY_ATTR(perf_profiling);
         969                 :         58 :     COPY_ATTR(import_time);
         970                 :         58 :     COPY_ATTR(code_debug_ranges);
         971                 :         58 :     COPY_ATTR(show_ref_count);
         972                 :         58 :     COPY_ATTR(dump_refs);
         973                 :         58 :     COPY_ATTR(dump_refs_file);
         974                 :         58 :     COPY_ATTR(malloc_stats);
         975                 :            :
         976         [ -  + ]:         58 :     COPY_WSTR_ATTR(pycache_prefix);
         977         [ -  + ]:         58 :     COPY_WSTR_ATTR(pythonpath_env);
         978         [ -  + ]:         58 :     COPY_WSTR_ATTR(home);
         979         [ -  + ]:         58 :     COPY_WSTR_ATTR(program_name);
         980                 :            :
         981                 :         58 :     COPY_ATTR(parse_argv);
         982         [ -  + ]:         58 :     COPY_WSTRLIST(argv);
         983         [ -  + ]:         58 :     COPY_WSTRLIST(warnoptions);
         984         [ -  + ]:         58 :     COPY_WSTRLIST(xoptions);
         985         [ -  + ]:         58 :     COPY_WSTRLIST(module_search_paths);
         986                 :         58 :     COPY_ATTR(module_search_paths_set);
         987         [ -  + ]:         58 :     COPY_WSTR_ATTR(stdlib_dir);
         988                 :            :
         989         [ -  + ]:         58 :     COPY_WSTR_ATTR(executable);
         990         [ -  + ]:         58 :     COPY_WSTR_ATTR(base_executable);
         991         [ -  + ]:         58 :     COPY_WSTR_ATTR(prefix);
         992         [ -  + ]:         58 :     COPY_WSTR_ATTR(base_prefix);
         993         [ -  + ]:         58 :     COPY_WSTR_ATTR(exec_prefix);
         994         [ -  + ]:         58 :     COPY_WSTR_ATTR(base_exec_prefix);
         995         [ -  + ]:         58 :     COPY_WSTR_ATTR(platlibdir);
         996                 :            :
         997                 :         58 :     COPY_ATTR(site_import);
         998                 :         58 :     COPY_ATTR(bytes_warning);
         999                 :         58 :     COPY_ATTR(warn_default_encoding);
        1000                 :         58 :     COPY_ATTR(inspect);
        1001                 :         58 :     COPY_ATTR(interactive);
        1002                 :         58 :     COPY_ATTR(optimization_level);
        1003                 :         58 :     COPY_ATTR(parser_debug);
        1004                 :         58 :     COPY_ATTR(write_bytecode);
        1005                 :         58 :     COPY_ATTR(verbose);
        1006                 :         58 :     COPY_ATTR(quiet);
        1007                 :         58 :     COPY_ATTR(user_site_directory);
        1008                 :         58 :     COPY_ATTR(configure_c_stdio);
        1009                 :         58 :     COPY_ATTR(buffered_stdio);
        1010         [ -  + ]:         58 :     COPY_WSTR_ATTR(filesystem_encoding);
        1011         [ -  + ]:         58 :     COPY_WSTR_ATTR(filesystem_errors);
        1012         [ -  + ]:         58 :     COPY_WSTR_ATTR(stdio_encoding);
        1013         [ -  + ]:         58 :     COPY_WSTR_ATTR(stdio_errors);
        1014                 :            : #ifdef MS_WINDOWS
        1015                 :            :     COPY_ATTR(legacy_windows_stdio);
        1016                 :            : #endif
        1017                 :         58 :     COPY_ATTR(skip_source_first_line);
        1018         [ -  + ]:         58 :     COPY_WSTR_ATTR(run_command);
        1019         [ -  + ]:         58 :     COPY_WSTR_ATTR(run_module);
        1020         [ -  + ]:         58 :     COPY_WSTR_ATTR(run_filename);
        1021         [ -  + ]:         58 :     COPY_WSTR_ATTR(check_hash_pycs_mode);
        1022                 :         58 :     COPY_ATTR(pathconfig_warnings);
        1023                 :         58 :     COPY_ATTR(_init_main);
        1024                 :         58 :     COPY_ATTR(use_frozen_modules);
        1025                 :         58 :     COPY_ATTR(safe_path);
        1026         [ -  + ]:         58 :     COPY_WSTRLIST(orig_argv);
        1027                 :         58 :     COPY_ATTR(_is_python_build);
        1028                 :         58 :     COPY_ATTR(int_max_str_digits);
        1029                 :            :
        1030                 :            : #undef COPY_ATTR
        1031                 :            : #undef COPY_WSTR_ATTR
        1032                 :            : #undef COPY_WSTRLIST
        1033                 :         58 :     return _PyStatus_OK();
        1034                 :            : }
        1035                 :            :
        1036                 :            :
        1037                 :            : PyObject *
        1038                 :         25 : _PyConfig_AsDict(const PyConfig *config)
        1039                 :            : {
        1040                 :         25 :     PyObject *dict = PyDict_New();
        1041         [ -  + ]:         25 :     if (dict == NULL) {
        1042                 :          0 :         return NULL;
        1043                 :            :     }
        1044                 :            :
        1045                 :            : #define SET_ITEM(KEY, EXPR) \
        1046                 :            :         do { \
        1047                 :            :             PyObject *obj = (EXPR); \
        1048                 :            :             if (obj == NULL) { \
        1049                 :            :                 goto fail; \
        1050                 :            :             } \
        1051                 :            :             int res = PyDict_SetItemString(dict, (KEY), obj); \
        1052                 :            :             Py_DECREF(obj); \
        1053                 :            :             if (res < 0) { \
        1054                 :            :                 goto fail; \
        1055                 :            :             } \
        1056                 :            :         } while (0)
        1057                 :            : #define SET_ITEM_INT(ATTR) \
        1058                 :            :     SET_ITEM(#ATTR, PyLong_FromLong(config->ATTR))
        1059                 :            : #define SET_ITEM_UINT(ATTR) \
        1060                 :            :     SET_ITEM(#ATTR, PyLong_FromUnsignedLong(config->ATTR))
        1061                 :            : #define FROM_WSTRING(STR) \
        1062                 :            :     ((STR != NULL) ? \
        1063                 :            :         PyUnicode_FromWideChar(STR, -1) \
        1064                 :            :         : Py_NewRef(Py_None))
        1065                 :            : #define SET_ITEM_WSTR(ATTR) \
        1066                 :            :     SET_ITEM(#ATTR, FROM_WSTRING(config->ATTR))
        1067                 :            : #define SET_ITEM_WSTRLIST(LIST) \
        1068                 :            :     SET_ITEM(#LIST, _PyWideStringList_AsList(&config->LIST))
        1069                 :            :
        1070   [ -  +  -  + ]:         25 :     SET_ITEM_INT(_config_init);
        1071   [ -  +  -  + ]:         25 :     SET_ITEM_INT(isolated);
        1072   [ -  +  -  + ]:         25 :     SET_ITEM_INT(use_environment);
        1073   [ -  +  -  + ]:         25 :     SET_ITEM_INT(dev_mode);
        1074   [ -  +  -  + ]:         25 :     SET_ITEM_INT(install_signal_handlers);
        1075   [ -  +  -  + ]:         25 :     SET_ITEM_INT(use_hash_seed);
        1076   [ -  +  -  + ]:         25 :     SET_ITEM_UINT(hash_seed);
        1077   [ -  +  -  + ]:         25 :     SET_ITEM_INT(faulthandler);
        1078   [ -  +  -  + ]:         25 :     SET_ITEM_INT(tracemalloc);
        1079   [ -  +  -  + ]:         25 :     SET_ITEM_INT(perf_profiling);
        1080   [ -  +  -  + ]:         25 :     SET_ITEM_INT(import_time);
        1081   [ -  +  -  + ]:         25 :     SET_ITEM_INT(code_debug_ranges);
        1082   [ -  +  -  + ]:         25 :     SET_ITEM_INT(show_ref_count);
        1083   [ -  +  -  + ]:         25 :     SET_ITEM_INT(dump_refs);
        1084   [ -  +  -  + ]:         25 :     SET_ITEM_INT(malloc_stats);
        1085   [ +  -  -  +  :         25 :     SET_ITEM_WSTR(filesystem_encoding);
                       -  + ]
        1086   [ +  -  -  +  :         25 :     SET_ITEM_WSTR(filesystem_errors);
                       -  + ]
        1087   [ -  +  -  +  :         25 :     SET_ITEM_WSTR(pycache_prefix);
                       -  + ]
        1088   [ -  +  -  +  :         25 :     SET_ITEM_WSTR(program_name);
                       -  + ]
        1089   [ -  +  -  + ]:         25 :     SET_ITEM_INT(parse_argv);
        1090   [ -  +  -  + ]:         25 :     SET_ITEM_WSTRLIST(argv);
        1091   [ -  +  -  + ]:         25 :     SET_ITEM_WSTRLIST(xoptions);
        1092   [ -  +  -  + ]:         25 :     SET_ITEM_WSTRLIST(warnoptions);
        1093   [ -  +  -  +  :         25 :     SET_ITEM_WSTR(pythonpath_env);
                       -  + ]
        1094   [ -  +  -  +  :         25 :     SET_ITEM_WSTR(home);
                       -  + ]
        1095   [ -  +  -  + ]:         25 :     SET_ITEM_INT(module_search_paths_set);
        1096   [ -  +  -  + ]:         25 :     SET_ITEM_WSTRLIST(module_search_paths);
        1097   [ -  +  -  +  :         25 :     SET_ITEM_WSTR(stdlib_dir);
                       -  + ]
        1098   [ -  +  -  +  :         25 :     SET_ITEM_WSTR(executable);
                       -  + ]
        1099   [ -  +  -  +  :         25 :     SET_ITEM_WSTR(base_executable);
                       -  + ]
        1100   [ -  +  -  +  :         25 :     SET_ITEM_WSTR(prefix);
                       -  + ]
        1101   [ -  +  -  +  :         25 :     SET_ITEM_WSTR(base_prefix);
                       -  + ]
        1102   [ -  +  -  +  :         25 :     SET_ITEM_WSTR(exec_prefix);
                       -  + ]
        1103   [ -  +  -  +  :         25 :     SET_ITEM_WSTR(base_exec_prefix);
                       -  + ]
        1104   [ -  +  -  +  :         25 :     SET_ITEM_WSTR(platlibdir);
                       -  + ]
        1105   [ -  +  -  + ]:         25 :     SET_ITEM_INT(site_import);
        1106   [ -  +  -  + ]:         25 :     SET_ITEM_INT(bytes_warning);
        1107   [ -  +  -  + ]:         25 :     SET_ITEM_INT(warn_default_encoding);
        1108   [ -  +  -  + ]:         25 :     SET_ITEM_INT(inspect);
        1109   [ -  +  -  + ]:         25 :     SET_ITEM_INT(interactive);
        1110   [ -  +  -  + ]:         25 :     SET_ITEM_INT(optimization_level);
        1111   [ -  +  -  + ]:         25 :     SET_ITEM_INT(parser_debug);
        1112   [ -  +  -  + ]:         25 :     SET_ITEM_INT(write_bytecode);
        1113   [ -  +  -  + ]:         25 :     SET_ITEM_INT(verbose);
        1114   [ -  +  -  + ]:         25 :     SET_ITEM_INT(quiet);
        1115   [ -  +  -  + ]:         25 :     SET_ITEM_INT(user_site_directory);
        1116   [ -  +  -  + ]:         25 :     SET_ITEM_INT(configure_c_stdio);
        1117   [ -  +  -  + ]:         25 :     SET_ITEM_INT(buffered_stdio);
        1118   [ +  -  -  +  :         25 :     SET_ITEM_WSTR(stdio_encoding);
                       -  + ]
        1119   [ +  -  -  +  :         25 :     SET_ITEM_WSTR(stdio_errors);
                       -  + ]
        1120                 :            : #ifdef MS_WINDOWS
        1121                 :            :     SET_ITEM_INT(legacy_windows_stdio);
        1122                 :            : #endif
        1123   [ -  +  -  + ]:         25 :     SET_ITEM_INT(skip_source_first_line);
        1124   [ +  +  -  +  :         25 :     SET_ITEM_WSTR(run_command);
                       -  + ]
        1125   [ +  +  -  +  :         25 :     SET_ITEM_WSTR(run_module);
                       -  + ]
        1126   [ +  +  -  +  :         25 :     SET_ITEM_WSTR(run_filename);
                       -  + ]
        1127   [ -  +  -  + ]:         25 :     SET_ITEM_INT(_install_importlib);
        1128   [ +  -  -  +  :         25 :     SET_ITEM_WSTR(check_hash_pycs_mode);
                       -  + ]
        1129   [ -  +  -  + ]:         25 :     SET_ITEM_INT(pathconfig_warnings);
        1130   [ -  +  -  + ]:         25 :     SET_ITEM_INT(_init_main);
        1131   [ -  +  -  + ]:         25 :     SET_ITEM_WSTRLIST(orig_argv);
        1132   [ -  +  -  + ]:         25 :     SET_ITEM_INT(use_frozen_modules);
        1133   [ -  +  -  + ]:         25 :     SET_ITEM_INT(safe_path);
        1134   [ -  +  -  + ]:         25 :     SET_ITEM_INT(_is_python_build);
        1135   [ -  +  -  + ]:         25 :     SET_ITEM_INT(int_max_str_digits);
        1136                 :            :
        1137                 :         25 :     return dict;
        1138                 :            :
        1139                 :          0 : fail:
        1140                 :          0 :     Py_DECREF(dict);
        1141                 :          0 :     return NULL;
        1142                 :            :
        1143                 :            : #undef FROM_WSTRING
        1144                 :            : #undef SET_ITEM
        1145                 :            : #undef SET_ITEM_INT
        1146                 :            : #undef SET_ITEM_UINT
        1147                 :            : #undef SET_ITEM_WSTR
        1148                 :            : #undef SET_ITEM_WSTRLIST
        1149                 :            : }
        1150                 :            :
        1151                 :            :
        1152                 :            : static PyObject*
        1153                 :       1575 : config_dict_get(PyObject *dict, const char *name)
        1154                 :            : {
        1155                 :       1575 :     PyObject *item = _PyDict_GetItemStringWithError(dict, name);
        1156   [ -  +  -  - ]:       1575 :     if (item == NULL && !PyErr_Occurred()) {
        1157                 :          0 :         PyErr_Format(PyExc_ValueError, "missing config key: %s", name);
        1158                 :          0 :         return NULL;
        1159                 :            :     }
        1160                 :       1575 :     return item;
        1161                 :            : }
        1162                 :            :
        1163                 :            :
        1164                 :            : static void
        1165                 :          0 : config_dict_invalid_value(const char *name)
        1166                 :            : {
        1167                 :          0 :     PyErr_Format(PyExc_ValueError, "invalid config value: %s", name);
        1168                 :          0 : }
        1169                 :            :
        1170                 :            :
        1171                 :            : static void
        1172                 :          0 : config_dict_invalid_type(const char *name)
        1173                 :            : {
        1174                 :          0 :     PyErr_Format(PyExc_TypeError, "invalid config type: %s", name);
        1175                 :          0 : }
        1176                 :            :
        1177                 :            :
        1178                 :            : static int
        1179                 :        925 : config_dict_get_int(PyObject *dict, const char *name, int *result)
        1180                 :            : {
        1181                 :        925 :     PyObject *item = config_dict_get(dict, name);
        1182         [ -  + ]:        925 :     if (item == NULL) {
        1183                 :          0 :         return -1;
        1184                 :            :     }
        1185                 :        925 :     int value = _PyLong_AsInt(item);
        1186   [ -  +  -  - ]:        925 :     if (value == -1 && PyErr_Occurred()) {
        1187         [ #  # ]:          0 :         if (PyErr_ExceptionMatches(PyExc_TypeError)) {
        1188                 :          0 :             config_dict_invalid_type(name);
        1189                 :            :         }
        1190         [ #  # ]:          0 :         else if (PyErr_ExceptionMatches(PyExc_OverflowError)) {
        1191                 :          0 :             config_dict_invalid_value(name);
        1192                 :            :         }
        1193                 :          0 :         return -1;
        1194                 :            :     }
        1195                 :        925 :     *result = value;
        1196                 :        925 :     return 0;
        1197                 :            : }
        1198                 :            :
        1199                 :            :
        1200                 :            : static int
        1201                 :         25 : config_dict_get_ulong(PyObject *dict, const char *name, unsigned long *result)
        1202                 :            : {
        1203                 :         25 :     PyObject *item = config_dict_get(dict, name);
        1204         [ -  + ]:         25 :     if (item == NULL) {
        1205                 :          0 :         return -1;
        1206                 :            :     }
        1207                 :         25 :     unsigned long value = PyLong_AsUnsignedLong(item);
        1208   [ -  +  -  - ]:         25 :     if (value == (unsigned long)-1 && PyErr_Occurred()) {
        1209         [ #  # ]:          0 :         if (PyErr_ExceptionMatches(PyExc_TypeError)) {
        1210                 :          0 :             config_dict_invalid_type(name);
        1211                 :            :         }
        1212         [ #  # ]:          0 :         else if (PyErr_ExceptionMatches(PyExc_OverflowError)) {
        1213                 :          0 :             config_dict_invalid_value(name);
        1214                 :            :         }
        1215                 :          0 :         return -1;
        1216                 :            :     }
        1217                 :         25 :     *result = value;
        1218                 :         25 :     return 0;
        1219                 :            : }
        1220                 :            :
        1221                 :            :
        1222                 :            : static int
        1223                 :        500 : config_dict_get_wstr(PyObject *dict, const char *name, PyConfig *config,
        1224                 :            :                      wchar_t **result)
        1225                 :            : {
        1226                 :        500 :     PyObject *item = config_dict_get(dict, name);
        1227         [ -  + ]:        500 :     if (item == NULL) {
        1228                 :          0 :         return -1;
        1229                 :            :     }
        1230                 :            :     PyStatus status;
        1231         [ +  + ]:        500 :     if (item == Py_None) {
        1232                 :        125 :         status = PyConfig_SetString(config, result, NULL);
        1233                 :            :     }
        1234         [ -  + ]:        375 :     else if (!PyUnicode_Check(item)) {
        1235                 :          0 :         config_dict_invalid_type(name);
        1236                 :          0 :         return -1;
        1237                 :            :     }
        1238                 :            :     else {
        1239                 :        375 :         wchar_t *wstr = PyUnicode_AsWideCharString(item, NULL);
        1240         [ -  + ]:        375 :         if (wstr == NULL) {
        1241                 :          0 :             return -1;
        1242                 :            :         }
        1243                 :        375 :         status = PyConfig_SetString(config, result, wstr);
        1244                 :        375 :         PyMem_Free(wstr);
        1245                 :            :     }
        1246         [ -  + ]:        500 :     if (_PyStatus_EXCEPTION(status)) {
        1247                 :          0 :         PyErr_NoMemory();
        1248                 :          0 :         return -1;
        1249                 :            :     }
        1250                 :        500 :     return 0;
        1251                 :            : }
        1252                 :            :
        1253                 :            :
        1254                 :            : static int
        1255                 :        125 : config_dict_get_wstrlist(PyObject *dict, const char *name, PyConfig *config,
        1256                 :            :                          PyWideStringList *result)
        1257                 :            : {
        1258                 :        125 :     PyObject *list = config_dict_get(dict, name);
        1259         [ -  + ]:        125 :     if (list == NULL) {
        1260                 :          0 :         return -1;
        1261                 :            :     }
        1262                 :            :
        1263         [ -  + ]:        125 :     if (!PyList_CheckExact(list)) {
        1264                 :          0 :         config_dict_invalid_type(name);
        1265                 :          0 :         return -1;
        1266                 :            :     }
        1267                 :            :
        1268                 :        125 :     PyWideStringList wstrlist = _PyWideStringList_INIT;
        1269         [ +  + ]:        456 :     for (Py_ssize_t i=0; i < PyList_GET_SIZE(list); i++) {
        1270                 :        331 :         PyObject *item = PyList_GET_ITEM(list, i);
        1271                 :            :
        1272         [ -  + ]:        331 :         if (item == Py_None) {
        1273                 :          0 :             config_dict_invalid_value(name);
        1274                 :          0 :             goto error;
        1275                 :            :         }
        1276         [ -  + ]:        331 :         else if (!PyUnicode_Check(item)) {
        1277                 :          0 :             config_dict_invalid_type(name);
        1278                 :          0 :             goto error;
        1279                 :            :         }
        1280                 :        331 :         wchar_t *wstr = PyUnicode_AsWideCharString(item, NULL);
        1281         [ -  + ]:        331 :         if (wstr == NULL) {
        1282                 :          0 :             goto error;
        1283                 :            :         }
        1284                 :        331 :         PyStatus status = PyWideStringList_Append(&wstrlist, wstr);
        1285                 :        331 :         PyMem_Free(wstr);
        1286         [ -  + ]:        331 :         if (_PyStatus_EXCEPTION(status)) {
        1287                 :          0 :             PyErr_NoMemory();
        1288                 :          0 :             goto error;
        1289                 :            :         }
        1290                 :            :     }
        1291                 :            :
        1292         [ -  + ]:        125 :     if (_PyWideStringList_Copy(result, &wstrlist) < 0) {
        1293                 :          0 :         PyErr_NoMemory();
        1294                 :          0 :         goto error;
        1295                 :            :     }
        1296                 :        125 :     _PyWideStringList_Clear(&wstrlist);
        1297                 :        125 :     return 0;
        1298                 :            :
        1299                 :          0 : error:
        1300                 :          0 :     _PyWideStringList_Clear(&wstrlist);
        1301                 :          0 :     return -1;
        1302                 :            : }
        1303                 :            :
        1304                 :            :
        1305                 :            : int
        1306                 :         25 : _PyConfig_FromDict(PyConfig *config, PyObject *dict)
        1307                 :            : {
        1308         [ -  + ]:         25 :     if (!PyDict_Check(dict)) {
        1309                 :          0 :         PyErr_SetString(PyExc_TypeError, "dict expected");
        1310                 :          0 :         return -1;
        1311                 :            :     }
        1312                 :            :
        1313                 :            : #define CHECK_VALUE(NAME, TEST) \
        1314                 :            :     if (!(TEST)) { \
        1315                 :            :         config_dict_invalid_value(NAME); \
        1316                 :            :         return -1; \
        1317                 :            :     }
        1318                 :            : #define GET_UINT(KEY) \
        1319                 :            :     do { \
        1320                 :            :         if (config_dict_get_int(dict, #KEY, &config->KEY) < 0) { \
        1321                 :            :             return -1; \
        1322                 :            :         } \
        1323                 :            :         CHECK_VALUE(#KEY, config->KEY >= 0); \
        1324                 :            :     } while (0)
        1325                 :            : #define GET_INT(KEY) \
        1326                 :            :     do { \
        1327                 :            :         if (config_dict_get_int(dict, #KEY, &config->KEY) < 0) { \
        1328                 :            :             return -1; \
        1329                 :            :         } \
        1330                 :            :     } while (0)
        1331                 :            : #define GET_WSTR(KEY) \
        1332                 :            :     do { \
        1333                 :            :         if (config_dict_get_wstr(dict, #KEY, config, &config->KEY) < 0) { \
        1334                 :            :             return -1; \
        1335                 :            :         } \
        1336                 :            :         CHECK_VALUE(#KEY, config->KEY != NULL); \
        1337                 :            :     } while (0)
        1338                 :            : #define GET_WSTR_OPT(KEY) \
        1339                 :            :     do { \
        1340                 :            :         if (config_dict_get_wstr(dict, #KEY, config, &config->KEY) < 0) { \
        1341                 :            :             return -1; \
        1342                 :            :         } \
        1343                 :            :     } while (0)
        1344                 :            : #define GET_WSTRLIST(KEY) \
        1345                 :            :     do { \
        1346                 :            :         if (config_dict_get_wstrlist(dict, #KEY, config, &config->KEY) < 0) { \
        1347                 :            :             return -1; \
        1348                 :            :         } \
        1349                 :            :     } while (0)
        1350                 :            :
        1351   [ -  +  -  + ]:         25 :     GET_UINT(_config_init);
        1352   [ +  -  +  +  :         25 :     CHECK_VALUE("_config_init",
                       -  + ]
        1353                 :            :                 config->_config_init == _PyConfig_INIT_COMPAT
        1354                 :            :                 || config->_config_init == _PyConfig_INIT_PYTHON
        1355                 :            :                 || config->_config_init == _PyConfig_INIT_ISOLATED);
        1356   [ -  +  -  + ]:         25 :     GET_UINT(isolated);
        1357   [ -  +  -  + ]:         25 :     GET_UINT(use_environment);
        1358   [ -  +  -  + ]:         25 :     GET_UINT(dev_mode);
        1359   [ -  +  -  + ]:         25 :     GET_UINT(install_signal_handlers);
        1360   [ -  +  -  + ]:         25 :     GET_UINT(use_hash_seed);
        1361         [ -  + ]:         25 :     if (config_dict_get_ulong(dict, "hash_seed", &config->hash_seed) < 0) {
        1362                 :          0 :         return -1;
        1363                 :            :     }
        1364         [ -  + ]:         25 :     CHECK_VALUE("hash_seed", config->hash_seed <= MAX_HASH_SEED);
        1365   [ -  +  -  + ]:         25 :     GET_UINT(faulthandler);
        1366   [ -  +  -  + ]:         25 :     GET_UINT(tracemalloc);
        1367   [ -  +  -  + ]:         25 :     GET_UINT(perf_profiling);
        1368   [ -  +  -  + ]:         25 :     GET_UINT(import_time);
        1369   [ -  +  -  + ]:         25 :     GET_UINT(code_debug_ranges);
        1370   [ -  +  -  + ]:         25 :     GET_UINT(show_ref_count);
        1371   [ -  +  -  + ]:         25 :     GET_UINT(dump_refs);
        1372   [ -  +  -  + ]:         25 :     GET_UINT(malloc_stats);
        1373   [ -  +  -  + ]:         25 :     GET_WSTR(filesystem_encoding);
        1374   [ -  +  -  + ]:         25 :     GET_WSTR(filesystem_errors);
        1375         [ -  + ]:         25 :     GET_WSTR_OPT(pycache_prefix);
        1376   [ -  +  -  + ]:         25 :     GET_UINT(parse_argv);
        1377         [ -  + ]:         25 :     GET_WSTRLIST(orig_argv);
        1378         [ -  + ]:         25 :     GET_WSTRLIST(argv);
        1379         [ -  + ]:         25 :     GET_WSTRLIST(xoptions);
        1380         [ -  + ]:         25 :     GET_WSTRLIST(warnoptions);
        1381   [ -  +  -  + ]:         25 :     GET_UINT(site_import);
        1382   [ -  +  -  + ]:         25 :     GET_UINT(bytes_warning);
        1383   [ -  +  -  + ]:         25 :     GET_UINT(warn_default_encoding);
        1384   [ -  +  -  + ]:         25 :     GET_UINT(inspect);
        1385   [ -  +  -  + ]:         25 :     GET_UINT(interactive);
        1386   [ -  +  -  + ]:         25 :     GET_UINT(optimization_level);
        1387   [ -  +  -  + ]:         25 :     GET_UINT(parser_debug);
        1388   [ -  +  -  + ]:         25 :     GET_UINT(write_bytecode);
        1389   [ -  +  -  + ]:         25 :     GET_UINT(verbose);
        1390   [ -  +  -  + ]:         25 :     GET_UINT(quiet);
        1391   [ -  +  -  + ]:         25 :     GET_UINT(user_site_directory);
        1392   [ -  +  -  + ]:         25 :     GET_UINT(configure_c_stdio);
        1393   [ -  +  -  + ]:         25 :     GET_UINT(buffered_stdio);
        1394   [ -  +  -  + ]:         25 :     GET_WSTR(stdio_encoding);
        1395   [ -  +  -  + ]:         25 :     GET_WSTR(stdio_errors);
        1396                 :            : #ifdef MS_WINDOWS
        1397                 :            :     GET_UINT(legacy_windows_stdio);
        1398                 :            : #endif
        1399   [ -  +  -  + ]:         25 :     GET_WSTR(check_hash_pycs_mode);
        1400                 :            :
        1401   [ -  +  -  + ]:         25 :     GET_UINT(pathconfig_warnings);
        1402   [ -  +  -  + ]:         25 :     GET_WSTR(program_name);
        1403         [ -  + ]:         25 :     GET_WSTR_OPT(pythonpath_env);
        1404         [ -  + ]:         25 :     GET_WSTR_OPT(home);
        1405   [ -  +  -  + ]:         25 :     GET_WSTR(platlibdir);
        1406                 :            :
        1407                 :            :     // Path configuration output
        1408   [ -  +  -  + ]:         25 :     GET_UINT(module_search_paths_set);
        1409         [ -  + ]:         25 :     GET_WSTRLIST(module_search_paths);
        1410         [ -  + ]:         25 :     GET_WSTR_OPT(stdlib_dir);
        1411         [ -  + ]:         25 :     GET_WSTR_OPT(executable);
        1412         [ -  + ]:         25 :     GET_WSTR_OPT(base_executable);
        1413         [ -  + ]:         25 :     GET_WSTR_OPT(prefix);
        1414         [ -  + ]:         25 :     GET_WSTR_OPT(base_prefix);
        1415         [ -  + ]:         25 :     GET_WSTR_OPT(exec_prefix);
        1416         [ -  + ]:         25 :     GET_WSTR_OPT(base_exec_prefix);
        1417                 :            :
        1418   [ -  +  -  + ]:         25 :     GET_UINT(skip_source_first_line);
        1419         [ -  + ]:         25 :     GET_WSTR_OPT(run_command);
        1420         [ -  + ]:         25 :     GET_WSTR_OPT(run_module);
        1421         [ -  + ]:         25 :     GET_WSTR_OPT(run_filename);
        1422                 :            :
        1423   [ -  +  -  + ]:         25 :     GET_UINT(_install_importlib);
        1424   [ -  +  -  + ]:         25 :     GET_UINT(_init_main);
        1425   [ -  +  -  + ]:         25 :     GET_UINT(use_frozen_modules);
        1426   [ -  +  -  + ]:         25 :     GET_UINT(safe_path);
        1427   [ -  +  -  + ]:         25 :     GET_UINT(_is_python_build);
        1428         [ -  + ]:         25 :     GET_INT(int_max_str_digits);
        1429                 :            :
        1430                 :            : #undef CHECK_VALUE
        1431                 :            : #undef GET_UINT
        1432                 :            : #undef GET_INT
        1433                 :            : #undef GET_WSTR
        1434                 :            : #undef GET_WSTR_OPT
        1435                 :         25 :     return 0;
        1436                 :            : }
        1437                 :            :
        1438                 :            :
        1439                 :            : static const char*
        1440                 :        149 : config_get_env(const PyConfig *config, const char *name)
        1441                 :            : {
        1442                 :        149 :     return _Py_GetEnv(config->use_environment, name);
        1443                 :            : }
        1444                 :            :
        1445                 :            :
        1446                 :            : /* Get a copy of the environment variable as wchar_t*.
        1447                 :            :    Return 0 on success, but *dest can be NULL.
        1448                 :            :    Return -1 on memory allocation failure. Return -2 on decoding error. */
        1449                 :            : static PyStatus
        1450                 :         54 : config_get_env_dup(PyConfig *config,
        1451                 :            :                    wchar_t **dest,
        1452                 :            :                    wchar_t *wname, char *name,
        1453                 :            :                    const char *decode_err_msg)
        1454                 :            : {
        1455                 :            :     assert(*dest == NULL);
        1456                 :            :     assert(config->use_environment >= 0);
        1457                 :            :
        1458         [ +  + ]:         54 :     if (!config->use_environment) {
        1459                 :         49 :         *dest = NULL;
        1460                 :         49 :         return _PyStatus_OK();
        1461                 :            :     }
        1462                 :            :
        1463                 :            : #ifdef MS_WINDOWS
        1464                 :            :     const wchar_t *var = _wgetenv(wname);
        1465                 :            :     if (!var || var[0] == '\0') {
        1466                 :            :         *dest = NULL;
        1467                 :            :         return _PyStatus_OK();
        1468                 :            :     }
        1469                 :            :
        1470                 :            :     return PyConfig_SetString(config, dest, var);
        1471                 :            : #else
        1472                 :          5 :     const char *var = getenv(name);
        1473   [ -  +  -  - ]:          5 :     if (!var || var[0] == '\0') {
        1474                 :          5 :         *dest = NULL;
        1475                 :          5 :         return _PyStatus_OK();
        1476                 :            :     }
        1477                 :            :
        1478                 :          0 :     return config_set_bytes_string(config, dest, var, decode_err_msg);
        1479                 :            : #endif
        1480                 :            : }
        1481                 :            :
        1482                 :            :
        1483                 :            : #define CONFIG_GET_ENV_DUP(CONFIG, DEST, WNAME, NAME) \
        1484                 :            :     config_get_env_dup(CONFIG, DEST, WNAME, NAME, "cannot decode " NAME)
        1485                 :            :
        1486                 :            :
        1487                 :            : static void
        1488                 :         50 : config_get_global_vars(PyConfig *config)
        1489                 :            : {
        1490                 :            : _Py_COMP_DIAG_PUSH
        1491                 :            : _Py_COMP_DIAG_IGNORE_DEPR_DECLS
        1492         [ +  - ]:         50 :     if (config->_config_init != _PyConfig_INIT_COMPAT) {
        1493                 :            :         /* Python and Isolated configuration ignore global variables */
        1494                 :         50 :         return;
        1495                 :            :     }
        1496                 :            :
        1497                 :            : #define COPY_FLAG(ATTR, VALUE) \
        1498                 :            :         if (config->ATTR == -1) { \
        1499                 :            :             config->ATTR = VALUE; \
        1500                 :            :         }
        1501                 :            : #define COPY_NOT_FLAG(ATTR, VALUE) \
        1502                 :            :         if (config->ATTR == -1) { \
        1503                 :            :             config->ATTR = !(VALUE); \
        1504                 :            :         }
        1505                 :            :
        1506         [ #  # ]:          0 :     COPY_FLAG(isolated, Py_IsolatedFlag);
        1507         [ #  # ]:          0 :     COPY_NOT_FLAG(use_environment, Py_IgnoreEnvironmentFlag);
        1508         [ #  # ]:          0 :     COPY_FLAG(bytes_warning, Py_BytesWarningFlag);
        1509         [ #  # ]:          0 :     COPY_FLAG(inspect, Py_InspectFlag);
        1510         [ #  # ]:          0 :     COPY_FLAG(interactive, Py_InteractiveFlag);
        1511         [ #  # ]:          0 :     COPY_FLAG(optimization_level, Py_OptimizeFlag);
        1512         [ #  # ]:          0 :     COPY_FLAG(parser_debug, Py_DebugFlag);
        1513         [ #  # ]:          0 :     COPY_FLAG(verbose, Py_VerboseFlag);
        1514         [ #  # ]:          0 :     COPY_FLAG(quiet, Py_QuietFlag);
        1515                 :            : #ifdef MS_WINDOWS
        1516                 :            :     COPY_FLAG(legacy_windows_stdio, Py_LegacyWindowsStdioFlag);
        1517                 :            : #endif
        1518         [ #  # ]:          0 :     COPY_NOT_FLAG(pathconfig_warnings, Py_FrozenFlag);
        1519                 :            :
        1520         [ #  # ]:          0 :     COPY_NOT_FLAG(buffered_stdio, Py_UnbufferedStdioFlag);
        1521         [ #  # ]:          0 :     COPY_NOT_FLAG(site_import, Py_NoSiteFlag);
        1522         [ #  # ]:          0 :     COPY_NOT_FLAG(write_bytecode, Py_DontWriteBytecodeFlag);
        1523         [ #  # ]:          0 :     COPY_NOT_FLAG(user_site_directory, Py_NoUserSiteDirectory);
        1524                 :            :
        1525                 :            : #undef COPY_FLAG
        1526                 :            : #undef COPY_NOT_FLAG
        1527                 :            : _Py_COMP_DIAG_POP
        1528                 :            : }
        1529                 :            :
        1530                 :            :
        1531                 :            : /* Set Py_xxx global configuration variables from 'config' configuration. */
        1532                 :            : static void
        1533                 :         29 : config_set_global_vars(const PyConfig *config)
        1534                 :            : {
        1535                 :            : _Py_COMP_DIAG_PUSH
        1536                 :            : _Py_COMP_DIAG_IGNORE_DEPR_DECLS
        1537                 :            : #define COPY_FLAG(ATTR, VAR) \
        1538                 :            :         if (config->ATTR != -1) { \
        1539                 :            :             VAR = config->ATTR; \
        1540                 :            :         }
        1541                 :            : #define COPY_NOT_FLAG(ATTR, VAR) \
        1542                 :            :         if (config->ATTR != -1) { \
        1543                 :            :             VAR = !config->ATTR; \
        1544                 :            :         }
        1545                 :            :
        1546         [ +  - ]:         29 :     COPY_FLAG(isolated, Py_IsolatedFlag);
        1547         [ +  - ]:         29 :     COPY_NOT_FLAG(use_environment, Py_IgnoreEnvironmentFlag);
        1548         [ +  - ]:         29 :     COPY_FLAG(bytes_warning, Py_BytesWarningFlag);
        1549         [ +  - ]:         29 :     COPY_FLAG(inspect, Py_InspectFlag);
        1550         [ +  - ]:         29 :     COPY_FLAG(interactive, Py_InteractiveFlag);
        1551         [ +  - ]:         29 :     COPY_FLAG(optimization_level, Py_OptimizeFlag);
        1552         [ +  - ]:         29 :     COPY_FLAG(parser_debug, Py_DebugFlag);
        1553         [ +  - ]:         29 :     COPY_FLAG(verbose, Py_VerboseFlag);
        1554         [ +  - ]:         29 :     COPY_FLAG(quiet, Py_QuietFlag);
        1555                 :            : #ifdef MS_WINDOWS
        1556                 :            :     COPY_FLAG(legacy_windows_stdio, Py_LegacyWindowsStdioFlag);
        1557                 :            : #endif
        1558         [ +  - ]:         29 :     COPY_NOT_FLAG(pathconfig_warnings, Py_FrozenFlag);
        1559                 :            :
        1560         [ +  - ]:         29 :     COPY_NOT_FLAG(buffered_stdio, Py_UnbufferedStdioFlag);
        1561         [ +  - ]:         29 :     COPY_NOT_FLAG(site_import, Py_NoSiteFlag);
        1562         [ +  - ]:         29 :     COPY_NOT_FLAG(write_bytecode, Py_DontWriteBytecodeFlag);
        1563         [ +  - ]:         29 :     COPY_NOT_FLAG(user_site_directory, Py_NoUserSiteDirectory);
        1564                 :            :
        1565                 :            :     /* Random or non-zero hash seed */
        1566         [ -  + ]:         29 :     Py_HashRandomizationFlag = (config->use_hash_seed == 0 ||
        1567         [ #  # ]:          0 :                                 config->hash_seed != 0);
        1568                 :            :
        1569                 :            : #undef COPY_FLAG
        1570                 :            : #undef COPY_NOT_FLAG
        1571                 :            : _Py_COMP_DIAG_POP
        1572                 :         29 : }
        1573                 :            :
        1574                 :            :
        1575                 :            : static const wchar_t*
        1576                 :        287 : config_get_xoption(const PyConfig *config, wchar_t *name)
        1577                 :            : {
        1578                 :        287 :     return _Py_get_xoption(&config->xoptions, name);
        1579                 :            : }
        1580                 :            :
        1581                 :            : static const wchar_t*
        1582                 :         71 : config_get_xoption_value(const PyConfig *config, wchar_t *name)
        1583                 :            : {
        1584                 :         71 :     const wchar_t *xoption = config_get_xoption(config, name);
        1585         [ +  - ]:         71 :     if (xoption == NULL) {
        1586                 :         71 :         return NULL;
        1587                 :            :     }
        1588                 :          0 :     const wchar_t *sep = wcschr(xoption, L'=');
        1589         [ #  # ]:          0 :     return sep ? sep + 1 : L"";
        1590                 :            : }
        1591                 :            :
        1592                 :            :
        1593                 :            : static PyStatus
        1594                 :          1 : config_init_hash_seed(PyConfig *config)
        1595                 :            : {
        1596                 :            :     static_assert(sizeof(_Py_HashSecret_t) == sizeof(_Py_HashSecret.uc),
        1597                 :            :                   "_Py_HashSecret_t has wrong size");
        1598                 :            :
        1599                 :          1 :     const char *seed_text = config_get_env(config, "PYTHONHASHSEED");
        1600                 :            :
        1601                 :            :     /* Convert a text seed to a numeric one */
        1602   [ -  +  -  - ]:          1 :     if (seed_text && strcmp(seed_text, "random") != 0) {
        1603                 :          0 :         const char *endptr = seed_text;
        1604                 :            :         unsigned long seed;
        1605                 :          0 :         errno = 0;
        1606                 :          0 :         seed = strtoul(seed_text, (char **)&endptr, 10);
        1607         [ #  # ]:          0 :         if (*endptr != '\0'
        1608         [ #  # ]:          0 :             || seed > MAX_HASH_SEED
        1609   [ #  #  #  # ]:          0 :             || (errno == ERANGE && seed == ULONG_MAX))
        1610                 :            :         {
        1611                 :          0 :             return _PyStatus_ERR("PYTHONHASHSEED must be \"random\" "
        1612                 :            :                                 "or an integer in range [0; 4294967295]");
        1613                 :            :         }
        1614                 :            :         /* Use a specific hash */
        1615                 :          0 :         config->use_hash_seed = 1;
        1616                 :          0 :         config->hash_seed = seed;
        1617                 :            :     }
        1618                 :            :     else {
        1619                 :            :         /* Use a random hash */
        1620                 :          1 :         config->use_hash_seed = 0;
        1621                 :          1 :         config->hash_seed = 0;
        1622                 :            :     }
        1623                 :          1 :     return _PyStatus_OK();
        1624                 :            : }
        1625                 :            :
        1626                 :            :
        1627                 :            : static int
        1628                 :          0 : config_wstr_to_int(const wchar_t *wstr, int *result)
        1629                 :            : {
        1630                 :          0 :     const wchar_t *endptr = wstr;
        1631                 :          0 :     errno = 0;
        1632                 :          0 :     long value = wcstol(wstr, (wchar_t **)&endptr, 10);
        1633   [ #  #  #  # ]:          0 :     if (*endptr != '\0' || errno == ERANGE) {
        1634                 :          0 :         return -1;
        1635                 :            :     }
        1636   [ #  #  #  # ]:          0 :     if (value < INT_MIN || value > INT_MAX) {
        1637                 :          0 :         return -1;
        1638                 :            :     }
        1639                 :            :
        1640                 :          0 :     *result = (int)value;
        1641                 :          0 :     return 0;
        1642                 :            : }
        1643                 :            :
        1644                 :            :
        1645                 :            : static PyStatus
        1646                 :          1 : config_read_env_vars(PyConfig *config)
        1647                 :            : {
        1648                 :            :     PyStatus status;
        1649                 :          1 :     int use_env = config->use_environment;
        1650                 :            :
        1651                 :            :     /* Get environment variables */
        1652                 :          1 :     _Py_get_env_flag(use_env, &config->parser_debug, "PYTHONDEBUG");
        1653                 :          1 :     _Py_get_env_flag(use_env, &config->verbose, "PYTHONVERBOSE");
        1654                 :          1 :     _Py_get_env_flag(use_env, &config->optimization_level, "PYTHONOPTIMIZE");
        1655                 :          1 :     _Py_get_env_flag(use_env, &config->inspect, "PYTHONINSPECT");
        1656                 :            :
        1657                 :          1 :     int dont_write_bytecode = 0;
        1658                 :          1 :     _Py_get_env_flag(use_env, &dont_write_bytecode, "PYTHONDONTWRITEBYTECODE");
        1659         [ -  + ]:          1 :     if (dont_write_bytecode) {
        1660                 :          0 :         config->write_bytecode = 0;
        1661                 :            :     }
        1662                 :            :
        1663                 :          1 :     int no_user_site_directory = 0;
        1664                 :          1 :     _Py_get_env_flag(use_env, &no_user_site_directory, "PYTHONNOUSERSITE");
        1665         [ -  + ]:          1 :     if (no_user_site_directory) {
        1666                 :          0 :         config->user_site_directory = 0;
        1667                 :            :     }
        1668                 :            :
        1669                 :          1 :     int unbuffered_stdio = 0;
        1670                 :          1 :     _Py_get_env_flag(use_env, &unbuffered_stdio, "PYTHONUNBUFFERED");
        1671         [ -  + ]:          1 :     if (unbuffered_stdio) {
        1672                 :          0 :         config->buffered_stdio = 0;
        1673                 :            :     }
        1674                 :            :
        1675                 :            : #ifdef MS_WINDOWS
        1676                 :            :     _Py_get_env_flag(use_env, &config->legacy_windows_stdio,
        1677                 :            :                      "PYTHONLEGACYWINDOWSSTDIO");
        1678                 :            : #endif
        1679                 :            :
        1680         [ -  + ]:          1 :     if (config_get_env(config, "PYTHONDUMPREFS")) {
        1681                 :          0 :         config->dump_refs = 1;
        1682                 :            :     }
        1683         [ -  + ]:          1 :     if (config_get_env(config, "PYTHONMALLOCSTATS")) {
        1684                 :          0 :         config->malloc_stats = 1;
        1685                 :            :     }
        1686                 :            :
        1687         [ +  - ]:          1 :     if (config->dump_refs_file == NULL) {
        1688                 :          1 :         status = CONFIG_GET_ENV_DUP(config, &config->dump_refs_file,
        1689                 :            :                                     L"PYTHONDUMPREFSFILE", "PYTHONDUMPREFSFILE");
        1690         [ -  + ]:          1 :         if (_PyStatus_EXCEPTION(status)) {
        1691                 :          0 :             return status;
        1692                 :            :         }
        1693                 :            :     }
        1694                 :            :
        1695         [ +  - ]:          1 :     if (config->pythonpath_env == NULL) {
        1696                 :          1 :         status = CONFIG_GET_ENV_DUP(config, &config->pythonpath_env,
        1697                 :            :                                     L"PYTHONPATH", "PYTHONPATH");
        1698         [ -  + ]:          1 :         if (_PyStatus_EXCEPTION(status)) {
        1699                 :          0 :             return status;
        1700                 :            :         }
        1701                 :            :     }
        1702                 :            :
        1703         [ +  - ]:          1 :     if(config->platlibdir == NULL) {
        1704                 :          1 :         status = CONFIG_GET_ENV_DUP(config, &config->platlibdir,
        1705                 :            :                                     L"PYTHONPLATLIBDIR", "PYTHONPLATLIBDIR");
        1706         [ -  + ]:          1 :         if (_PyStatus_EXCEPTION(status)) {
        1707                 :          0 :             return status;
        1708                 :            :         }
        1709                 :            :     }
        1710                 :            :
        1711         [ +  - ]:          1 :     if (config->use_hash_seed < 0) {
        1712                 :          1 :         status = config_init_hash_seed(config);
        1713         [ -  + ]:          1 :         if (_PyStatus_EXCEPTION(status)) {
        1714                 :          0 :             return status;
        1715                 :            :         }
        1716                 :            :     }
        1717                 :            :
        1718         [ -  + ]:          1 :     if (config_get_env(config, "PYTHONSAFEPATH")) {
        1719                 :          0 :         config->safe_path = 1;
        1720                 :            :     }
        1721                 :            :
        1722                 :          1 :     return _PyStatus_OK();
        1723                 :            : }
        1724                 :            :
        1725                 :            : static PyStatus
        1726                 :          4 : config_init_perf_profiling(PyConfig *config)
        1727                 :            : {
        1728                 :          4 :     int active = 0;
        1729                 :          4 :     const char *env = config_get_env(config, "PYTHONPERFSUPPORT");
        1730         [ -  + ]:          4 :     if (env) {
        1731         [ #  # ]:          0 :         if (_Py_str_to_int(env, &active) != 0) {
        1732                 :          0 :             active = 0;
        1733                 :            :         }
        1734         [ #  # ]:          0 :         if (active) {
        1735                 :          0 :             config->perf_profiling = 1;
        1736                 :            :         }
        1737                 :            :     }
        1738                 :          4 :     const wchar_t *xoption = config_get_xoption(config, L"perf");
        1739         [ -  + ]:          4 :     if (xoption) {
        1740                 :          0 :         config->perf_profiling = 1;
        1741                 :            :     }
        1742                 :          4 :     return _PyStatus_OK();
        1743                 :            :
        1744                 :            : }
        1745                 :            :
        1746                 :            : static PyStatus
        1747                 :          4 : config_init_tracemalloc(PyConfig *config)
        1748                 :            : {
        1749                 :            :     int nframe;
        1750                 :            :     int valid;
        1751                 :            :
        1752                 :          4 :     const char *env = config_get_env(config, "PYTHONTRACEMALLOC");
        1753         [ -  + ]:          4 :     if (env) {
        1754         [ #  # ]:          0 :         if (!_Py_str_to_int(env, &nframe)) {
        1755                 :          0 :             valid = (nframe >= 0);
        1756                 :            :         }
        1757                 :            :         else {
        1758                 :          0 :             valid = 0;
        1759                 :            :         }
        1760         [ #  # ]:          0 :         if (!valid) {
        1761                 :          0 :             return _PyStatus_ERR("PYTHONTRACEMALLOC: invalid number of frames");
        1762                 :            :         }
        1763                 :          0 :         config->tracemalloc = nframe;
        1764                 :            :     }
        1765                 :            :
        1766                 :          4 :     const wchar_t *xoption = config_get_xoption(config, L"tracemalloc");
        1767         [ -  + ]:          4 :     if (xoption) {
        1768                 :          0 :         const wchar_t *sep = wcschr(xoption, L'=');
        1769         [ #  # ]:          0 :         if (sep) {
        1770         [ #  # ]:          0 :             if (!config_wstr_to_int(sep + 1, &nframe)) {
        1771                 :          0 :                 valid = (nframe >= 0);
        1772                 :            :             }
        1773                 :            :             else {
        1774                 :          0 :                 valid = 0;
        1775                 :            :             }
        1776         [ #  # ]:          0 :             if (!valid) {
        1777                 :          0 :                 return _PyStatus_ERR("-X tracemalloc=NFRAME: "
        1778                 :            :                                      "invalid number of frames");
        1779                 :            :             }
        1780                 :            :         }
        1781                 :            :         else {
        1782                 :            :             /* -X tracemalloc behaves as -X tracemalloc=1 */
        1783                 :          0 :             nframe = 1;
        1784                 :            :         }
        1785                 :          0 :         config->tracemalloc = nframe;
        1786                 :            :     }
        1787                 :          4 :     return _PyStatus_OK();
        1788                 :            : }
        1789                 :            :
        1790                 :            : static PyStatus
        1791                 :          4 : config_init_int_max_str_digits(PyConfig *config)
        1792                 :            : {
        1793                 :            :     int maxdigits;
        1794                 :            :
        1795                 :          4 :     const char *env = config_get_env(config, "PYTHONINTMAXSTRDIGITS");
        1796         [ -  + ]:          4 :     if (env) {
        1797                 :          0 :         bool valid = 0;
        1798         [ #  # ]:          0 :         if (!_Py_str_to_int(env, &maxdigits)) {
        1799   [ #  #  #  # ]:          0 :             valid = ((maxdigits == 0) || (maxdigits >= _PY_LONG_MAX_STR_DIGITS_THRESHOLD));
        1800                 :            :         }
        1801         [ #  # ]:          0 :         if (!valid) {
        1802                 :            : #define STRINGIFY(VAL) _STRINGIFY(VAL)
        1803                 :            : #define _STRINGIFY(VAL) #VAL
        1804                 :          0 :             return _PyStatus_ERR(
        1805                 :            :                     "PYTHONINTMAXSTRDIGITS: invalid limit; must be >= "
        1806                 :            :                     STRINGIFY(_PY_LONG_MAX_STR_DIGITS_THRESHOLD)
        1807                 :            :                     " or 0 for unlimited.");
        1808                 :            :         }
        1809                 :          0 :         config->int_max_str_digits = maxdigits;
        1810                 :            :     }
        1811                 :            :
        1812                 :          4 :     const wchar_t *xoption = config_get_xoption(config, L"int_max_str_digits");
        1813         [ -  + ]:          4 :     if (xoption) {
        1814                 :          0 :         const wchar_t *sep = wcschr(xoption, L'=');
        1815                 :          0 :         bool valid = 0;
        1816         [ #  # ]:          0 :         if (sep) {
        1817         [ #  # ]:          0 :             if (!config_wstr_to_int(sep + 1, &maxdigits)) {
        1818   [ #  #  #  # ]:          0 :                 valid = ((maxdigits == 0) || (maxdigits >= _PY_LONG_MAX_STR_DIGITS_THRESHOLD));
        1819                 :            :             }
        1820                 :            :         }
        1821         [ #  # ]:          0 :         if (!valid) {
        1822                 :          0 :             return _PyStatus_ERR(
        1823                 :            :                     "-X int_max_str_digits: invalid limit; must be >= "
        1824                 :            :                     STRINGIFY(_PY_LONG_MAX_STR_DIGITS_THRESHOLD)
        1825                 :            :                     " or 0 for unlimited.");
        1826                 :            : #undef _STRINGIFY
        1827                 :            : #undef STRINGIFY
        1828                 :            :         }
        1829                 :          0 :         config->int_max_str_digits = maxdigits;
        1830                 :            :     }
        1831         [ +  - ]:          4 :     if (config->int_max_str_digits < 0) {
        1832                 :          4 :         config->int_max_str_digits = _PY_LONG_DEFAULT_MAX_STR_DIGITS;
        1833                 :            :     }
        1834                 :          4 :     return _PyStatus_OK();
        1835                 :            : }
        1836                 :            :
        1837                 :            : static PyStatus
        1838                 :         50 : config_init_pycache_prefix(PyConfig *config)
        1839                 :            : {
        1840                 :            :     assert(config->pycache_prefix == NULL);
        1841                 :            :
        1842                 :         50 :     const wchar_t *xoption = config_get_xoption(config, L"pycache_prefix");
        1843         [ -  + ]:         50 :     if (xoption) {
        1844                 :          0 :         const wchar_t *sep = wcschr(xoption, L'=');
        1845   [ #  #  #  # ]:          0 :         if (sep && wcslen(sep) > 1) {
        1846                 :          0 :             config->pycache_prefix = _PyMem_RawWcsdup(sep + 1);
        1847         [ #  # ]:          0 :             if (config->pycache_prefix == NULL) {
        1848                 :          0 :                 return _PyStatus_NO_MEMORY();
        1849                 :            :             }
        1850                 :            :         }
        1851                 :            :         else {
        1852                 :            :             // PYTHONPYCACHEPREFIX env var ignored
        1853                 :            :             // if "-X pycache_prefix=" option is used
        1854                 :          0 :             config->pycache_prefix = NULL;
        1855                 :            :         }
        1856                 :          0 :         return _PyStatus_OK();
        1857                 :            :     }
        1858                 :            :
        1859                 :         50 :     return CONFIG_GET_ENV_DUP(config, &config->pycache_prefix,
        1860                 :            :                               L"PYTHONPYCACHEPREFIX",
        1861                 :            :                               "PYTHONPYCACHEPREFIX");
        1862                 :            : }
        1863                 :            :
        1864                 :            :
        1865                 :            : static PyStatus
        1866                 :         50 : config_read_complex_options(PyConfig *config)
        1867                 :            : {
        1868                 :            :     /* More complex options configured by env var and -X option */
        1869         [ +  + ]:         50 :     if (config->faulthandler < 0) {
        1870         [ +  - ]:          4 :         if (config_get_env(config, "PYTHONFAULTHANDLER")
        1871         [ -  + ]:          4 :            || config_get_xoption(config, L"faulthandler")) {
        1872                 :          0 :             config->faulthandler = 1;
        1873                 :            :         }
        1874                 :            :     }
        1875         [ +  - ]:         50 :     if (config_get_env(config, "PYTHONPROFILEIMPORTTIME")
        1876         [ -  + ]:         50 :        || config_get_xoption(config, L"importtime")) {
        1877                 :          0 :         config->import_time = 1;
        1878                 :            :     }
        1879                 :            :
        1880         [ +  - ]:         50 :     if (config_get_env(config, "PYTHONNODEBUGRANGES")
        1881         [ -  + ]:         50 :        || config_get_xoption(config, L"no_debug_ranges")) {
        1882                 :          0 :         config->code_debug_ranges = 0;
        1883                 :            :     }
        1884                 :            :
        1885                 :            :     PyStatus status;
        1886         [ +  + ]:         50 :     if (config->tracemalloc < 0) {
        1887                 :          4 :         status = config_init_tracemalloc(config);
        1888         [ -  + ]:          4 :         if (_PyStatus_EXCEPTION(status)) {
        1889                 :          0 :             return status;
        1890                 :            :         }
        1891                 :            :     }
        1892                 :            :
        1893         [ +  + ]:         50 :     if (config->perf_profiling < 0) {
        1894                 :          4 :         status = config_init_perf_profiling(config);
        1895         [ -  + ]:          4 :         if (_PyStatus_EXCEPTION(status)) {
        1896                 :          0 :             return status;
        1897                 :            :         }
        1898                 :            :     }
        1899                 :            :
        1900         [ +  + ]:         50 :     if (config->int_max_str_digits < 0) {
        1901                 :          4 :         status = config_init_int_max_str_digits(config);
        1902         [ -  + ]:          4 :         if (_PyStatus_EXCEPTION(status)) {
        1903                 :          0 :             return status;
        1904                 :            :         }
        1905                 :            :     }
        1906                 :            :
        1907         [ +  - ]:         50 :     if (config->pycache_prefix == NULL) {
        1908                 :         50 :         status = config_init_pycache_prefix(config);
        1909         [ -  + ]:         50 :         if (_PyStatus_EXCEPTION(status)) {
        1910                 :          0 :             return status;
        1911                 :            :         }
        1912                 :            :     }
        1913                 :         50 :     return _PyStatus_OK();
        1914                 :            : }
        1915                 :            :
        1916                 :            :
        1917                 :            : static const wchar_t *
        1918                 :         29 : config_get_stdio_errors(const PyPreConfig *preconfig)
        1919                 :            : {
        1920         [ -  + ]:         29 :     if (preconfig->utf8_mode) {
        1921                 :            :         /* UTF-8 Mode uses UTF-8/surrogateescape */
        1922                 :          0 :         return L"surrogateescape";
        1923                 :            :     }
        1924                 :            :
        1925                 :            : #ifndef MS_WINDOWS
        1926                 :         29 :     const char *loc = setlocale(LC_CTYPE, NULL);
        1927         [ +  - ]:         29 :     if (loc != NULL) {
        1928                 :            :         /* surrogateescape is the default in the legacy C and POSIX locales */
        1929   [ +  +  -  + ]:         29 :         if (strcmp(loc, "C") == 0 || strcmp(loc, "POSIX") == 0) {
        1930                 :         25 :             return L"surrogateescape";
        1931                 :            :         }
        1932                 :            :
        1933                 :            : #ifdef PY_COERCE_C_LOCALE
        1934                 :            :         /* surrogateescape is the default in locale coercion target locales */
        1935         [ -  + ]:          4 :         if (_Py_IsLocaleCoercionTarget(loc)) {
        1936                 :          0 :             return L"surrogateescape";
        1937                 :            :         }
        1938                 :            : #endif
        1939                 :            :     }
        1940                 :            :
        1941                 :          4 :     return L"strict";
        1942                 :            : #else
        1943                 :            :     /* On Windows, always use surrogateescape by default */
        1944                 :            :     return L"surrogateescape";
        1945                 :            : #endif
        1946                 :            : }
        1947                 :            :
        1948                 :            :
        1949                 :            : // See also config_get_fs_encoding()
        1950                 :            : static PyStatus
        1951                 :         58 : config_get_locale_encoding(PyConfig *config, const PyPreConfig *preconfig,
        1952                 :            :                            wchar_t **locale_encoding)
        1953                 :            : {
        1954                 :            :     wchar_t *encoding;
        1955         [ -  + ]:         58 :     if (preconfig->utf8_mode) {
        1956                 :          0 :         encoding = _PyMem_RawWcsdup(L"utf-8");
        1957                 :            :     }
        1958                 :            :     else {
        1959                 :         58 :         encoding = _Py_GetLocaleEncoding();
        1960                 :            :     }
        1961         [ -  + ]:         58 :     if (encoding == NULL) {
        1962                 :          0 :         return _PyStatus_NO_MEMORY();
        1963                 :            :     }
        1964                 :         58 :     PyStatus status = PyConfig_SetString(config, locale_encoding, encoding);
        1965                 :         58 :     PyMem_RawFree(encoding);
        1966                 :         58 :     return status;
        1967                 :            : }
        1968                 :            :
        1969                 :            :
        1970                 :            : static PyStatus
        1971                 :         50 : config_init_stdio_encoding(PyConfig *config,
        1972                 :            :                            const PyPreConfig *preconfig)
        1973                 :            : {
        1974                 :            :     PyStatus status;
        1975                 :            :
        1976                 :            :     /* If Py_SetStandardStreamEncoding() has been called, use its
        1977                 :            :         arguments if they are not NULL. */
        1978   [ +  +  -  + ]:         50 :     if (config->stdio_encoding == NULL && _Py_StandardStreamEncoding != NULL) {
        1979                 :          0 :         status = CONFIG_SET_BYTES_STR(config, &config->stdio_encoding,
        1980                 :            :                                       _Py_StandardStreamEncoding,
        1981                 :            :                                       "_Py_StandardStreamEncoding");
        1982         [ #  # ]:          0 :         if (_PyStatus_EXCEPTION(status)) {
        1983                 :          0 :             return status;
        1984                 :            :         }
        1985                 :            :     }
        1986                 :            :
        1987   [ +  +  -  + ]:         50 :     if (config->stdio_errors == NULL && _Py_StandardStreamErrors != NULL) {
        1988                 :          0 :         status = CONFIG_SET_BYTES_STR(config, &config->stdio_errors,
        1989                 :            :                                       _Py_StandardStreamErrors,
        1990                 :            :                                       "_Py_StandardStreamErrors");
        1991         [ #  # ]:          0 :         if (_PyStatus_EXCEPTION(status)) {
        1992                 :          0 :             return status;
        1993                 :            :         }
        1994                 :            :     }
        1995                 :            :
        1996                 :            :     // Exit if encoding and errors are defined
        1997   [ +  +  +  - ]:         50 :     if (config->stdio_encoding != NULL && config->stdio_errors != NULL) {
        1998                 :         21 :         return _PyStatus_OK();
        1999                 :            :     }
        2000                 :            :
        2001                 :            :     /* PYTHONIOENCODING environment variable */
        2002                 :         29 :     const char *opt = config_get_env(config, "PYTHONIOENCODING");
        2003         [ -  + ]:         29 :     if (opt) {
        2004                 :          0 :         char *pythonioencoding = _PyMem_RawStrdup(opt);
        2005         [ #  # ]:          0 :         if (pythonioencoding == NULL) {
        2006                 :          0 :             return _PyStatus_NO_MEMORY();
        2007                 :            :         }
        2008                 :            :
        2009                 :          0 :         char *errors = strchr(pythonioencoding, ':');
        2010         [ #  # ]:          0 :         if (errors) {
        2011                 :          0 :             *errors = '\0';
        2012                 :          0 :             errors++;
        2013         [ #  # ]:          0 :             if (!errors[0]) {
        2014                 :          0 :                 errors = NULL;
        2015                 :            :             }
        2016                 :            :         }
        2017                 :            :
        2018                 :            :         /* Does PYTHONIOENCODING contain an encoding? */
        2019         [ #  # ]:          0 :         if (pythonioencoding[0]) {
        2020         [ #  # ]:          0 :             if (config->stdio_encoding == NULL) {
        2021                 :          0 :                 status = CONFIG_SET_BYTES_STR(config, &config->stdio_encoding,
        2022                 :            :                                               pythonioencoding,
        2023                 :            :                                               "PYTHONIOENCODING environment variable");
        2024         [ #  # ]:          0 :                 if (_PyStatus_EXCEPTION(status)) {
        2025                 :          0 :                     PyMem_RawFree(pythonioencoding);
        2026                 :          0 :                     return status;
        2027                 :            :                 }
        2028                 :            :             }
        2029                 :            :
        2030                 :            :             /* If the encoding is set but not the error handler,
        2031                 :            :                use "strict" error handler by default.
        2032                 :            :                PYTHONIOENCODING=latin1 behaves as
        2033                 :            :                PYTHONIOENCODING=latin1:strict. */
        2034         [ #  # ]:          0 :             if (!errors) {
        2035                 :          0 :                 errors = "strict";
        2036                 :            :             }
        2037                 :            :         }
        2038                 :            :
        2039   [ #  #  #  # ]:          0 :         if (config->stdio_errors == NULL && errors != NULL) {
        2040                 :          0 :             status = CONFIG_SET_BYTES_STR(config, &config->stdio_errors,
        2041                 :            :                                           errors,
        2042                 :            :                                           "PYTHONIOENCODING environment variable");
        2043         [ #  # ]:          0 :             if (_PyStatus_EXCEPTION(status)) {
        2044                 :          0 :                 PyMem_RawFree(pythonioencoding);
        2045                 :          0 :                 return status;
        2046                 :            :             }
        2047                 :            :         }
        2048                 :            :
        2049                 :          0 :         PyMem_RawFree(pythonioencoding);
        2050                 :            :     }
        2051                 :            :
        2052                 :            :     /* Choose the default error handler based on the current locale. */
        2053         [ +  - ]:         29 :     if (config->stdio_encoding == NULL) {
        2054                 :         29 :         status = config_get_locale_encoding(config, preconfig,
        2055                 :            :                                             &config->stdio_encoding);
        2056         [ -  + ]:         29 :         if (_PyStatus_EXCEPTION(status)) {
        2057                 :          0 :             return status;
        2058                 :            :         }
        2059                 :            :     }
        2060         [ +  - ]:         29 :     if (config->stdio_errors == NULL) {
        2061                 :         29 :         const wchar_t *errors = config_get_stdio_errors(preconfig);
        2062                 :            :         assert(errors != NULL);
        2063                 :            :
        2064                 :         29 :         status = PyConfig_SetString(config, &config->stdio_errors, errors);
        2065         [ -  + ]:         29 :         if (_PyStatus_EXCEPTION(status)) {
        2066                 :          0 :             return status;
        2067                 :            :         }
        2068                 :            :     }
        2069                 :            :
        2070                 :         29 :     return _PyStatus_OK();
        2071                 :            : }
        2072                 :            :
        2073                 :            :
        2074                 :            : // See also config_get_locale_encoding()
        2075                 :            : static PyStatus
        2076                 :         29 : config_get_fs_encoding(PyConfig *config, const PyPreConfig *preconfig,
        2077                 :            :                        wchar_t **fs_encoding)
        2078                 :            : {
        2079                 :            : #ifdef _Py_FORCE_UTF8_FS_ENCODING
        2080                 :            :     return PyConfig_SetString(config, fs_encoding, L"utf-8");
        2081                 :            : #elif defined(MS_WINDOWS)
        2082                 :            :     const wchar_t *encoding;
        2083                 :            :     if (preconfig->legacy_windows_fs_encoding) {
        2084                 :            :         // Legacy Windows filesystem encoding: mbcs/replace
        2085                 :            :         encoding = L"mbcs";
        2086                 :            :     }
        2087                 :            :     else {
        2088                 :            :         // Windows defaults to utf-8/surrogatepass (PEP 529)
        2089                 :            :         encoding = L"utf-8";
        2090                 :            :     }
        2091                 :            :      return PyConfig_SetString(config, fs_encoding, encoding);
        2092                 :            : #else  // !MS_WINDOWS
        2093         [ -  + ]:         29 :     if (preconfig->utf8_mode) {
        2094                 :          0 :         return PyConfig_SetString(config, fs_encoding, L"utf-8");
        2095                 :            :     }
        2096                 :            :
        2097         [ -  + ]:         29 :     if (_Py_GetForceASCII()) {
        2098                 :          0 :         return PyConfig_SetString(config, fs_encoding, L"ascii");
        2099                 :            :     }
        2100                 :            :
        2101                 :         29 :     return config_get_locale_encoding(config, preconfig, fs_encoding);
        2102                 :            : #endif  // !MS_WINDOWS
        2103                 :            : }
        2104                 :            :
        2105                 :            :
        2106                 :            : static PyStatus
        2107                 :         29 : config_init_fs_encoding(PyConfig *config, const PyPreConfig *preconfig)
        2108                 :            : {
        2109                 :            :     PyStatus status;
        2110                 :            :
        2111         [ +  - ]:         29 :     if (config->filesystem_encoding == NULL) {
        2112                 :         29 :         status = config_get_fs_encoding(config, preconfig,
        2113                 :            :                                         &config->filesystem_encoding);
        2114         [ -  + ]:         29 :         if (_PyStatus_EXCEPTION(status)) {
        2115                 :          0 :             return status;
        2116                 :            :         }
        2117                 :            :     }
        2118                 :            :
        2119         [ +  - ]:         29 :     if (config->filesystem_errors == NULL) {
        2120                 :            :         const wchar_t *errors;
        2121                 :            : #ifdef MS_WINDOWS
        2122                 :            :         if (preconfig->legacy_windows_fs_encoding) {
        2123                 :            :             errors = L"replace";
        2124                 :            :         }
        2125                 :            :         else {
        2126                 :            :             errors = L"surrogatepass";
        2127                 :            :         }
        2128                 :            : #else
        2129                 :         29 :         errors = L"surrogateescape";
        2130                 :            : #endif
        2131                 :         29 :         status = PyConfig_SetString(config, &config->filesystem_errors, errors);
        2132         [ -  + ]:         29 :         if (_PyStatus_EXCEPTION(status)) {
        2133                 :          0 :             return status;
        2134                 :            :         }
        2135                 :            :     }
        2136                 :         29 :     return _PyStatus_OK();
        2137                 :            : }
        2138                 :            :
        2139                 :            :
        2140                 :            : static PyStatus
        2141                 :         71 : config_init_import(PyConfig *config, int compute_path_config)
        2142                 :            : {
        2143                 :            :     PyStatus status;
        2144                 :            :
        2145                 :         71 :     status = _PyConfig_InitPathConfig(config, compute_path_config);
        2146         [ -  + ]:         71 :     if (_PyStatus_EXCEPTION(status)) {
        2147                 :          0 :         return status;
        2148                 :            :     }
        2149                 :            :
        2150                 :            :     /* -X frozen_modules=[on|off] */
        2151                 :         71 :     const wchar_t *value = config_get_xoption_value(config, L"frozen_modules");
        2152         [ -  + ]:         71 :     if (value == NULL) {
        2153                 :            :     }
        2154         [ #  # ]:          0 :     else if (wcscmp(value, L"on") == 0) {
        2155                 :          0 :         config->use_frozen_modules = 1;
        2156                 :            :     }
        2157         [ #  # ]:          0 :     else if (wcscmp(value, L"off") == 0) {
        2158                 :          0 :         config->use_frozen_modules = 0;
        2159                 :            :     }
        2160         [ #  # ]:          0 :     else if (wcslen(value) == 0) {
        2161                 :            :         // "-X frozen_modules" and "-X frozen_modules=" both imply "on".
        2162                 :          0 :         config->use_frozen_modules = 1;
        2163                 :            :     }
        2164                 :            :     else {
        2165                 :          0 :         return PyStatus_Error("bad value for option -X frozen_modules "
        2166                 :            :                               "(expected \"on\" or \"off\")");
        2167                 :            :     }
        2168                 :            :
        2169                 :            :     assert(config->use_frozen_modules >= 0);
        2170                 :         71 :     return _PyStatus_OK();
        2171                 :            : }
        2172                 :            :
        2173                 :            : PyStatus
        2174                 :         25 : _PyConfig_InitImportConfig(PyConfig *config)
        2175                 :            : {
        2176                 :         25 :     return config_init_import(config, 1);
        2177                 :            : }
        2178                 :            :
        2179                 :            :
        2180                 :            : static PyStatus
        2181                 :         50 : config_read(PyConfig *config, int compute_path_config)
        2182                 :            : {
        2183                 :            :     PyStatus status;
        2184                 :         50 :     const PyPreConfig *preconfig = &_PyRuntime.preconfig;
        2185                 :            :
        2186         [ +  + ]:         50 :     if (config->use_environment) {
        2187                 :          1 :         status = config_read_env_vars(config);
        2188         [ -  + ]:          1 :         if (_PyStatus_EXCEPTION(status)) {
        2189                 :          0 :             return status;
        2190                 :            :         }
        2191                 :            :     }
        2192                 :            :
        2193                 :            :     /* -X options */
        2194         [ -  + ]:         50 :     if (config_get_xoption(config, L"showrefcount")) {
        2195                 :          0 :         config->show_ref_count = 1;
        2196                 :            :     }
        2197                 :            :
        2198                 :            : #ifdef Py_STATS
        2199                 :            :     if (config_get_xoption(config, L"pystats")) {
        2200                 :            :         _py_stats = &_py_stats_struct;
        2201                 :            :     }
        2202                 :            : #endif
        2203                 :            :
        2204                 :         50 :     status = config_read_complex_options(config);
        2205         [ -  + ]:         50 :     if (_PyStatus_EXCEPTION(status)) {
        2206                 :          0 :         return status;
        2207                 :            :     }
        2208                 :            :
        2209         [ +  + ]:         50 :     if (config->_install_importlib) {
        2210                 :         46 :         status = config_init_import(config, compute_path_config);
        2211         [ -  + ]:         46 :         if (_PyStatus_EXCEPTION(status)) {
        2212                 :          0 :             return status;
        2213                 :            :         }
        2214                 :            :     }
        2215                 :            :
        2216                 :            :     /* default values */
        2217         [ -  + ]:         50 :     if (config->dev_mode) {
        2218         [ #  # ]:          0 :         if (config->faulthandler < 0) {
        2219                 :          0 :             config->faulthandler = 1;
        2220                 :            :         }
        2221                 :            :     }
        2222         [ +  + ]:         50 :     if (config->faulthandler < 0) {
        2223                 :          4 :         config->faulthandler = 0;
        2224                 :            :     }
        2225         [ +  + ]:         50 :     if (config->tracemalloc < 0) {
        2226                 :          4 :         config->tracemalloc = 0;
        2227                 :            :     }
        2228         [ +  + ]:         50 :     if (config->perf_profiling < 0) {
        2229                 :          4 :         config->perf_profiling = 0;
        2230                 :            :     }
        2231         [ +  + ]:         50 :     if (config->use_hash_seed < 0) {
        2232                 :          3 :         config->use_hash_seed = 0;
        2233                 :          3 :         config->hash_seed = 0;
        2234                 :            :     }
        2235                 :            :
        2236   [ +  +  -  + ]:         50 :     if (config->filesystem_encoding == NULL || config->filesystem_errors == NULL) {
        2237                 :         29 :         status = config_init_fs_encoding(config, preconfig);
        2238         [ -  + ]:         29 :         if (_PyStatus_EXCEPTION(status)) {
        2239                 :          0 :             return status;
        2240                 :            :         }
        2241                 :            :     }
        2242                 :            :
        2243                 :         50 :     status = config_init_stdio_encoding(config, preconfig);
        2244         [ -  + ]:         50 :     if (_PyStatus_EXCEPTION(status)) {
        2245                 :          0 :         return status;
        2246                 :            :     }
        2247                 :            :
        2248         [ +  + ]:         50 :     if (config->argv.length < 1) {
        2249                 :            :         /* Ensure at least one (empty) argument is seen */
        2250                 :          4 :         status = PyWideStringList_Append(&config->argv, L"");
        2251         [ -  + ]:          4 :         if (_PyStatus_EXCEPTION(status)) {
        2252                 :          0 :             return status;
        2253                 :            :         }
        2254                 :            :     }
        2255                 :            :
        2256         [ +  + ]:         50 :     if (config->check_hash_pycs_mode == NULL) {
        2257                 :         29 :         status = PyConfig_SetString(config, &config->check_hash_pycs_mode,
        2258                 :            :                                     L"default");
        2259         [ -  + ]:         29 :         if (_PyStatus_EXCEPTION(status)) {
        2260                 :          0 :             return status;
        2261                 :            :         }
        2262                 :            :     }
        2263                 :            :
        2264         [ -  + ]:         50 :     if (config->configure_c_stdio < 0) {
        2265                 :          0 :         config->configure_c_stdio = 1;
        2266                 :            :     }
        2267                 :            :
        2268                 :            :     // Only parse arguments once.
        2269         [ +  + ]:         50 :     if (config->parse_argv == 1) {
        2270                 :         25 :         config->parse_argv = 2;
        2271                 :            :     }
        2272                 :            :
        2273                 :         50 :     return _PyStatus_OK();
        2274                 :            : }
        2275                 :            :
        2276                 :            :
        2277                 :            : static void
        2278                 :          4 : config_init_stdio(const PyConfig *config)
        2279                 :            : {
        2280                 :            : #if defined(MS_WINDOWS) || defined(__CYGWIN__)
        2281                 :            :     /* don't translate newlines (\r\n <=> \n) */
        2282                 :            :     _setmode(fileno(stdin), O_BINARY);
        2283                 :            :     _setmode(fileno(stdout), O_BINARY);
        2284                 :            :     _setmode(fileno(stderr), O_BINARY);
        2285                 :            : #endif
        2286                 :            :
        2287         [ -  + ]:          4 :     if (!config->buffered_stdio) {
        2288                 :            : #ifdef HAVE_SETVBUF
        2289                 :          0 :         setvbuf(stdin,  (char *)NULL, _IONBF, BUFSIZ);
        2290                 :          0 :         setvbuf(stdout, (char *)NULL, _IONBF, BUFSIZ);
        2291                 :          0 :         setvbuf(stderr, (char *)NULL, _IONBF, BUFSIZ);
        2292                 :            : #else /* !HAVE_SETVBUF */
        2293                 :            :         setbuf(stdin,  (char *)NULL);
        2294                 :            :         setbuf(stdout, (char *)NULL);
        2295                 :            :         setbuf(stderr, (char *)NULL);
        2296                 :            : #endif /* !HAVE_SETVBUF */
        2297                 :            :     }
        2298         [ -  + ]:          4 :     else if (config->interactive) {
        2299                 :            : #ifdef MS_WINDOWS
        2300                 :            :         /* Doesn't have to have line-buffered -- use unbuffered */
        2301                 :            :         /* Any set[v]buf(stdin, ...) screws up Tkinter :-( */
        2302                 :            :         setvbuf(stdout, (char *)NULL, _IONBF, BUFSIZ);
        2303                 :            : #else /* !MS_WINDOWS */
        2304                 :            : #ifdef HAVE_SETVBUF
        2305                 :          0 :         setvbuf(stdin,  (char *)NULL, _IOLBF, BUFSIZ);
        2306                 :          0 :         setvbuf(stdout, (char *)NULL, _IOLBF, BUFSIZ);
        2307                 :            : #endif /* HAVE_SETVBUF */
        2308                 :            : #endif /* !MS_WINDOWS */
        2309                 :            :         /* Leave stderr alone - it should be unbuffered anyway. */
        2310                 :            :     }
        2311                 :          4 : }
        2312                 :            :
        2313                 :            :
        2314                 :            : /* Write the configuration:
        2315                 :            :
        2316                 :            :    - set Py_xxx global configuration variables
        2317                 :            :    - initialize C standard streams (stdin, stdout, stderr) */
        2318                 :            : PyStatus
        2319                 :         29 : _PyConfig_Write(const PyConfig *config, _PyRuntimeState *runtime)
        2320                 :            : {
        2321                 :         29 :     config_set_global_vars(config);
        2322                 :            :
        2323         [ +  + ]:         29 :     if (config->configure_c_stdio) {
        2324                 :          4 :         config_init_stdio(config);
        2325                 :            :     }
        2326                 :            :
        2327                 :            :     /* Write the new pre-configuration into _PyRuntime */
        2328                 :         29 :     PyPreConfig *preconfig = &runtime->preconfig;
        2329                 :         29 :     preconfig->isolated = config->isolated;
        2330                 :         29 :     preconfig->use_environment = config->use_environment;
        2331                 :         29 :     preconfig->dev_mode = config->dev_mode;
        2332                 :            :
        2333         [ -  + ]:         29 :     if (_Py_SetArgcArgv(config->orig_argv.length,
        2334                 :         29 :                         config->orig_argv.items) < 0)
        2335                 :            :     {
        2336                 :          0 :         return _PyStatus_NO_MEMORY();
        2337                 :            :     }
        2338                 :         29 :     return _PyStatus_OK();
        2339                 :            : }
        2340                 :            :
        2341                 :            :
        2342                 :            : /* --- PyConfig command line parser -------------------------- */
        2343                 :            :
        2344                 :            : static void
        2345                 :          0 : config_usage(int error, const wchar_t* program)
        2346                 :            : {
        2347         [ #  # ]:          0 :     FILE *f = error ? stderr : stdout;
        2348                 :            :
        2349                 :          0 :     fprintf(f, usage_line, program);
        2350         [ #  # ]:          0 :     if (error)
        2351                 :          0 :         fprintf(f, "Try `python -h' for more information.\n");
        2352                 :            :     else {
        2353                 :          0 :         fputs(usage_help, f);
        2354                 :            :     }
        2355                 :          0 : }
        2356                 :            :
        2357                 :            : static void
        2358                 :          0 : config_envvars_usage()
        2359                 :            : {
        2360                 :          0 :     printf(usage_envvars, (wint_t)DELIM, (wint_t)DELIM, PYTHONHOMEHELP);
        2361                 :          0 : }
        2362                 :            :
        2363                 :            : static void
        2364                 :          0 : config_xoptions_usage()
        2365                 :            : {
        2366                 :          0 :     puts(usage_xoptions);
        2367                 :          0 : }
        2368                 :            :
        2369                 :            : static void
        2370                 :          0 : config_complete_usage(const wchar_t* program)
        2371                 :            : {
        2372                 :          0 :    config_usage(0, program);
        2373                 :          0 :    puts("\n");
        2374                 :          0 :    config_envvars_usage();
        2375                 :          0 :    puts("\n");
        2376                 :          0 :    config_xoptions_usage();
        2377                 :          0 : }
        2378                 :            :
        2379                 :            :
        2380                 :            : /* Parse the command line arguments */
        2381                 :            : static PyStatus
        2382                 :         25 : config_parse_cmdline(PyConfig *config, PyWideStringList *warnoptions,
        2383                 :            :                      Py_ssize_t *opt_index)
        2384                 :            : {
        2385                 :            :     PyStatus status;
        2386                 :         25 :     const PyWideStringList *argv = &config->argv;
        2387                 :         25 :     int print_version = 0;
        2388                 :         25 :     const wchar_t* program = config->program_name;
        2389   [ +  -  +  - ]:         25 :     if (!program && argv->length >= 1) {
        2390                 :         25 :         program = argv->items[0];
        2391                 :            :     }
        2392                 :            :
        2393                 :         25 :     _PyOS_ResetGetOpt();
        2394                 :          4 :     do {
        2395                 :         29 :         int longindex = -1;
        2396                 :         29 :         int c = _PyOS_GetOpt(argv->length, argv->items, &longindex);
        2397         [ +  + ]:         29 :         if (c == EOF) {
        2398                 :         22 :             break;
        2399                 :            :         }
        2400                 :            :
        2401         [ +  + ]:          7 :         if (c == 'c') {
        2402         [ +  - ]:          1 :             if (config->run_command == NULL) {
        2403                 :            :                 /* -c is the last option; following arguments
        2404                 :            :                    that look like options are left for the
        2405                 :            :                    command to interpret. */
        2406                 :          1 :                 size_t len = wcslen(_PyOS_optarg) + 1 + 1;
        2407                 :          1 :                 wchar_t *command = PyMem_RawMalloc(sizeof(wchar_t) * len);
        2408         [ -  + ]:          1 :                 if (command == NULL) {
        2409                 :          0 :                     return _PyStatus_NO_MEMORY();
        2410                 :            :                 }
        2411                 :          1 :                 memcpy(command, _PyOS_optarg, (len - 2) * sizeof(wchar_t));
        2412                 :          1 :                 command[len - 2] = '\n';
        2413                 :          1 :                 command[len - 1] = 0;
        2414                 :          1 :                 config->run_command = command;
        2415                 :            :             }
        2416                 :          1 :             break;
        2417                 :            :         }
        2418                 :            :
        2419         [ +  + ]:          6 :         if (c == 'm') {
        2420                 :            :             /* -m is the last option; following arguments
        2421                 :            :                that look like options are left for the
        2422                 :            :                module to interpret. */
        2423         [ +  - ]:          2 :             if (config->run_module == NULL) {
        2424                 :          2 :                 config->run_module = _PyMem_RawWcsdup(_PyOS_optarg);
        2425         [ -  + ]:          2 :                 if (config->run_module == NULL) {
        2426                 :          0 :                     return _PyStatus_NO_MEMORY();
        2427                 :            :                 }
        2428                 :            :             }
        2429                 :          2 :             break;
        2430                 :            :         }
        2431                 :            :
        2432   [ -  -  -  -  :          4 :         switch (c) {
              -  -  -  +  -
              -  -  -  +  -
              -  -  -  -  -
                 -  -  -  - ]
        2433                 :            :         // Integers represent long options, see Python/getopt.c
        2434                 :          0 :         case 0:
        2435                 :            :             // check-hash-based-pycs
        2436         [ #  # ]:          0 :             if (wcscmp(_PyOS_optarg, L"always") == 0
        2437         [ #  # ]:          0 :                 || wcscmp(_PyOS_optarg, L"never") == 0
        2438         [ #  # ]:          0 :                 || wcscmp(_PyOS_optarg, L"default") == 0)
        2439                 :            :             {
        2440                 :          0 :                 status = PyConfig_SetString(config, &config->check_hash_pycs_mode,
        2441                 :            :                                             _PyOS_optarg);
        2442         [ #  # ]:          0 :                 if (_PyStatus_EXCEPTION(status)) {
        2443                 :          0 :                     return status;
        2444                 :            :                 }
        2445                 :            :             } else {
        2446                 :          0 :                 fprintf(stderr, "--check-hash-based-pycs must be one of "
        2447                 :            :                         "'default', 'always', or 'never'\n");
        2448                 :          0 :                 config_usage(1, program);
        2449                 :          0 :                 return _PyStatus_EXIT(2);
        2450                 :            :             }
        2451                 :          4 :             break;
        2452                 :            :
        2453                 :          0 :         case 1:
        2454                 :            :             // help-all
        2455                 :          0 :             config_complete_usage(program);
        2456                 :          0 :             return _PyStatus_EXIT(0);
        2457                 :            :
        2458                 :          0 :         case 2:
        2459                 :            :             // help-env
        2460                 :          0 :             config_envvars_usage();
        2461                 :          0 :             return _PyStatus_EXIT(0);
        2462                 :            :
        2463                 :          0 :         case 3:
        2464                 :            :             // help-xoptions
        2465                 :          0 :             config_xoptions_usage();
        2466                 :          0 :             return _PyStatus_EXIT(0);
        2467                 :            :
        2468                 :          0 :         case 'b':
        2469                 :          0 :             config->bytes_warning++;
        2470                 :          0 :             break;
        2471                 :            :
        2472                 :          0 :         case 'd':
        2473                 :          0 :             config->parser_debug++;
        2474                 :          0 :             break;
        2475                 :            :
        2476                 :          0 :         case 'i':
        2477                 :          0 :             config->inspect++;
        2478                 :          0 :             config->interactive++;
        2479                 :          0 :             break;
        2480                 :            :
        2481                 :          3 :         case 'E':
        2482                 :            :         case 'I':
        2483                 :            :         case 'X':
        2484                 :            :             /* option handled by _PyPreCmdline_Read() */
        2485                 :          3 :             break;
        2486                 :            :
        2487                 :            :         /* case 'J': reserved for Jython */
        2488                 :            :
        2489                 :          0 :         case 'O':
        2490                 :          0 :             config->optimization_level++;
        2491                 :          0 :             break;
        2492                 :            :
        2493                 :          0 :         case 'P':
        2494                 :          0 :             config->safe_path = 1;
        2495                 :          0 :             break;
        2496                 :            :
        2497                 :          0 :         case 'B':
        2498                 :          0 :             config->write_bytecode = 0;
        2499                 :          0 :             break;
        2500                 :            :
        2501                 :          0 :         case 's':
        2502                 :          0 :             config->user_site_directory = 0;
        2503                 :          0 :             break;
        2504                 :            :
        2505                 :          1 :         case 'S':
        2506                 :          1 :             config->site_import = 0;
        2507                 :          1 :             break;
        2508                 :            :
        2509                 :          0 :         case 't':
        2510                 :            :             /* ignored for backwards compatibility */
        2511                 :          0 :             break;
        2512                 :            :
        2513                 :          0 :         case 'u':
        2514                 :          0 :             config->buffered_stdio = 0;
        2515                 :          0 :             break;
        2516                 :            :
        2517                 :          0 :         case 'v':
        2518                 :          0 :             config->verbose++;
        2519                 :          0 :             break;
        2520                 :            :
        2521                 :          0 :         case 'x':
        2522                 :          0 :             config->skip_source_first_line = 1;
        2523                 :          0 :             break;
        2524                 :            :
        2525                 :          0 :         case 'h':
        2526                 :            :         case '?':
        2527                 :          0 :             config_usage(0, program);
        2528                 :          0 :             return _PyStatus_EXIT(0);
        2529                 :            :
        2530                 :          0 :         case 'V':
        2531                 :          0 :             print_version++;
        2532                 :          0 :             break;
        2533                 :            :
        2534                 :          0 :         case 'W':
        2535                 :          0 :             status = PyWideStringList_Append(warnoptions, _PyOS_optarg);
        2536         [ #  # ]:          0 :             if (_PyStatus_EXCEPTION(status)) {
        2537                 :          0 :                 return status;
        2538                 :            :             }
        2539                 :          0 :             break;
        2540                 :            :
        2541                 :          0 :         case 'q':
        2542                 :          0 :             config->quiet++;
        2543                 :          0 :             break;
        2544                 :            :
        2545                 :          0 :         case 'R':
        2546                 :          0 :             config->use_hash_seed = 0;
        2547                 :          0 :             break;
        2548                 :            :
        2549                 :            :         /* This space reserved for other options */
        2550                 :            :
        2551                 :          0 :         default:
        2552                 :            :             /* unknown argument: parsing failed */
        2553                 :          0 :             config_usage(1, program);
        2554                 :          0 :             return _PyStatus_EXIT(2);
        2555                 :            :         }
        2556                 :            :     } while (1);
        2557                 :            :
        2558         [ -  + ]:         25 :     if (print_version) {
        2559         [ #  # ]:          0 :         printf("Python %s\n",
        2560                 :          0 :                 (print_version >= 2) ? Py_GetVersion() : PY_VERSION);
        2561                 :          0 :         return _PyStatus_EXIT(0);
        2562                 :            :     }
        2563                 :            :
        2564   [ +  +  +  + ]:         25 :     if (config->run_command == NULL && config->run_module == NULL
        2565         [ +  - ]:         22 :         && _PyOS_optind < argv->length
        2566         [ +  - ]:         22 :         && wcscmp(argv->items[_PyOS_optind], L"-") != 0
        2567         [ +  - ]:         22 :         && config->run_filename == NULL)
        2568                 :            :     {
        2569                 :         22 :         config->run_filename = _PyMem_RawWcsdup(argv->items[_PyOS_optind]);
        2570         [ -  + ]:         22 :         if (config->run_filename == NULL) {
        2571                 :          0 :             return _PyStatus_NO_MEMORY();
        2572                 :            :         }
        2573                 :            :     }
        2574                 :            :
        2575   [ +  +  +  + ]:         25 :     if (config->run_command != NULL || config->run_module != NULL) {
        2576                 :            :         /* Backup _PyOS_optind */
        2577                 :          3 :         _PyOS_optind--;
        2578                 :            :     }
        2579                 :            :
        2580                 :         25 :     *opt_index = _PyOS_optind;
        2581                 :            :
        2582                 :         25 :     return _PyStatus_OK();
        2583                 :            : }
        2584                 :            :
        2585                 :            :
        2586                 :            : #ifdef MS_WINDOWS
        2587                 :            : #  define WCSTOK wcstok_s
        2588                 :            : #else
        2589                 :            : #  define WCSTOK wcstok
        2590                 :            : #endif
        2591                 :            :
        2592                 :            : /* Get warning options from PYTHONWARNINGS environment variable. */
        2593                 :            : static PyStatus
        2594                 :          1 : config_init_env_warnoptions(PyConfig *config, PyWideStringList *warnoptions)
        2595                 :            : {
        2596                 :            :     PyStatus status;
        2597                 :            :     /* CONFIG_GET_ENV_DUP requires dest to be initialized to NULL */
        2598                 :          1 :     wchar_t *env = NULL;
        2599                 :          1 :     status = CONFIG_GET_ENV_DUP(config, &env,
        2600                 :            :                              L"PYTHONWARNINGS", "PYTHONWARNINGS");
        2601         [ -  + ]:          1 :     if (_PyStatus_EXCEPTION(status)) {
        2602                 :          0 :         return status;
        2603                 :            :     }
        2604                 :            :
        2605                 :            :     /* env var is not set or is empty */
        2606         [ +  - ]:          1 :     if (env == NULL) {
        2607                 :          1 :         return _PyStatus_OK();
        2608                 :            :     }
        2609                 :            :
        2610                 :            :
        2611                 :          0 :     wchar_t *warning, *context = NULL;
        2612         [ #  # ]:          0 :     for (warning = WCSTOK(env, L",", &context);
        2613                 :            :          warning != NULL;
        2614                 :          0 :          warning = WCSTOK(NULL, L",", &context))
        2615                 :            :     {
        2616                 :          0 :         status = PyWideStringList_Append(warnoptions, warning);
        2617         [ #  # ]:          0 :         if (_PyStatus_EXCEPTION(status)) {
        2618                 :          0 :             PyMem_RawFree(env);
        2619                 :          0 :             return status;
        2620                 :            :         }
        2621                 :            :     }
        2622                 :          0 :     PyMem_RawFree(env);
        2623                 :          0 :     return _PyStatus_OK();
        2624                 :            : }
        2625                 :            :
        2626                 :            :
        2627                 :            : static PyStatus
        2628                 :          0 : warnoptions_append(PyConfig *config, PyWideStringList *options,
        2629                 :            :                    const wchar_t *option)
        2630                 :            : {
        2631                 :            :     /* config_init_warnoptions() add existing config warnoptions at the end:
        2632                 :            :        ensure that the new option is not already present in this list to
        2633                 :            :        prevent change the options order when config_init_warnoptions() is
        2634                 :            :        called twice. */
        2635         [ #  # ]:          0 :     if (_PyWideStringList_Find(&config->warnoptions, option)) {
        2636                 :            :         /* Already present: do nothing */
        2637                 :          0 :         return _PyStatus_OK();
        2638                 :            :     }
        2639         [ #  # ]:          0 :     if (_PyWideStringList_Find(options, option)) {
        2640                 :            :         /* Already present: do nothing */
        2641                 :          0 :         return _PyStatus_OK();
        2642                 :            :     }
        2643                 :          0 :     return PyWideStringList_Append(options, option);
        2644                 :            : }
        2645                 :            :
        2646                 :            :
        2647                 :            : static PyStatus
        2648                 :        150 : warnoptions_extend(PyConfig *config, PyWideStringList *options,
        2649                 :            :                    const PyWideStringList *options2)
        2650                 :            : {
        2651                 :        150 :     const Py_ssize_t len = options2->length;
        2652                 :        150 :     wchar_t *const *items = options2->items;
        2653                 :            :
        2654         [ -  + ]:        150 :     for (Py_ssize_t i = 0; i < len; i++) {
        2655                 :          0 :         PyStatus status = warnoptions_append(config, options, items[i]);
        2656         [ #  # ]:          0 :         if (_PyStatus_EXCEPTION(status)) {
        2657                 :          0 :             return status;
        2658                 :            :         }
        2659                 :            :     }
        2660                 :        150 :     return _PyStatus_OK();
        2661                 :            : }
        2662                 :            :
        2663                 :            :
        2664                 :            : static PyStatus
        2665                 :         50 : config_init_warnoptions(PyConfig *config,
        2666                 :            :                         const PyWideStringList *cmdline_warnoptions,
        2667                 :            :                         const PyWideStringList *env_warnoptions,
        2668                 :            :                         const PyWideStringList *sys_warnoptions)
        2669                 :            : {
        2670                 :            :     PyStatus status;
        2671                 :         50 :     PyWideStringList options = _PyWideStringList_INIT;
        2672                 :            :
        2673                 :            :     /* Priority of warnings options, lowest to highest:
        2674                 :            :      *
        2675                 :            :      * - any implicit filters added by _warnings.c/warnings.py
        2676                 :            :      * - PyConfig.dev_mode: "default" filter
        2677                 :            :      * - PYTHONWARNINGS environment variable
        2678                 :            :      * - '-W' command line options
        2679                 :            :      * - PyConfig.bytes_warning ('-b' and '-bb' command line options):
        2680                 :            :      *   "default::BytesWarning" or "error::BytesWarning" filter
        2681                 :            :      * - early PySys_AddWarnOption() calls
        2682                 :            :      * - PyConfig.warnoptions
        2683                 :            :      *
        2684                 :            :      * PyConfig.warnoptions is copied to sys.warnoptions. Since the warnings
        2685                 :            :      * module works on the basis of "the most recently added filter will be
        2686                 :            :      * checked first", we add the lowest precedence entries first so that later
        2687                 :            :      * entries override them.
        2688                 :            :      */
        2689                 :            :
        2690         [ -  + ]:         50 :     if (config->dev_mode) {
        2691                 :          0 :         status = warnoptions_append(config, &options, L"default");
        2692         [ #  # ]:          0 :         if (_PyStatus_EXCEPTION(status)) {
        2693                 :          0 :             goto error;
        2694                 :            :         }
        2695                 :            :     }
        2696                 :            :
        2697                 :         50 :     status = warnoptions_extend(config, &options, env_warnoptions);
        2698         [ -  + ]:         50 :     if (_PyStatus_EXCEPTION(status)) {
        2699                 :          0 :         goto error;
        2700                 :            :     }
        2701                 :            :
        2702                 :         50 :     status = warnoptions_extend(config, &options, cmdline_warnoptions);
        2703         [ -  + ]:         50 :     if (_PyStatus_EXCEPTION(status)) {
        2704                 :          0 :         goto error;
        2705                 :            :     }
        2706                 :            :
        2707                 :            :     /* If the bytes_warning_flag isn't set, bytesobject.c and bytearrayobject.c
        2708                 :            :      * don't even try to emit a warning, so we skip setting the filter in that
        2709                 :            :      * case.
        2710                 :            :      */
        2711         [ -  + ]:         50 :     if (config->bytes_warning) {
        2712                 :            :         const wchar_t *filter;
        2713         [ #  # ]:          0 :         if (config->bytes_warning> 1) {
        2714                 :          0 :             filter = L"error::BytesWarning";
        2715                 :            :         }
        2716                 :            :         else {
        2717                 :          0 :             filter = L"default::BytesWarning";
        2718                 :            :         }
        2719                 :          0 :         status = warnoptions_append(config, &options, filter);
        2720         [ #  # ]:          0 :         if (_PyStatus_EXCEPTION(status)) {
        2721                 :          0 :             goto error;
        2722                 :            :         }
        2723                 :            :     }
        2724                 :            :
        2725                 :         50 :     status = warnoptions_extend(config, &options, sys_warnoptions);
        2726         [ -  + ]:         50 :     if (_PyStatus_EXCEPTION(status)) {
        2727                 :          0 :         goto error;
        2728                 :            :     }
        2729                 :            :
        2730                 :            :     /* Always add all PyConfig.warnoptions options */
        2731                 :         50 :     status = _PyWideStringList_Extend(&options, &config->warnoptions);
        2732         [ -  + ]:         50 :     if (_PyStatus_EXCEPTION(status)) {
        2733                 :          0 :         goto error;
        2734                 :            :     }
        2735                 :            :
        2736                 :         50 :     _PyWideStringList_Clear(&config->warnoptions);
        2737                 :         50 :     config->warnoptions = options;
        2738                 :         50 :     return _PyStatus_OK();
        2739                 :            :
        2740                 :          0 : error:
        2741                 :          0 :     _PyWideStringList_Clear(&options);
        2742                 :          0 :     return status;
        2743                 :            : }
        2744                 :            :
        2745                 :            :
        2746                 :            : static PyStatus
        2747                 :         25 : config_update_argv(PyConfig *config, Py_ssize_t opt_index)
        2748                 :            : {
        2749                 :         25 :     const PyWideStringList *cmdline_argv = &config->argv;
        2750                 :         25 :     PyWideStringList config_argv = _PyWideStringList_INIT;
        2751                 :            :
        2752                 :            :     /* Copy argv to be able to modify it (to force -c/-m) */
        2753         [ -  + ]:         25 :     if (cmdline_argv->length <= opt_index) {
        2754                 :            :         /* Ensure at least one (empty) argument is seen */
        2755                 :          0 :         PyStatus status = PyWideStringList_Append(&config_argv, L"");
        2756         [ #  # ]:          0 :         if (_PyStatus_EXCEPTION(status)) {
        2757                 :          0 :             return status;
        2758                 :            :         }
        2759                 :            :     }
        2760                 :            :     else {
        2761                 :            :         PyWideStringList slice;
        2762                 :         25 :         slice.length = cmdline_argv->length - opt_index;
        2763                 :         25 :         slice.items = &cmdline_argv->items[opt_index];
        2764         [ -  + ]:         25 :         if (_PyWideStringList_Copy(&config_argv, &slice) < 0) {
        2765                 :          0 :             return _PyStatus_NO_MEMORY();
        2766                 :            :         }
        2767                 :            :     }
        2768                 :            :     assert(config_argv.length >= 1);
        2769                 :            :
        2770                 :         25 :     wchar_t *arg0 = NULL;
        2771         [ +  + ]:         25 :     if (config->run_command != NULL) {
        2772                 :            :         /* Force sys.argv[0] = '-c' */
        2773                 :          1 :         arg0 = L"-c";
        2774                 :            :     }
        2775         [ +  + ]:         24 :     else if (config->run_module != NULL) {
        2776                 :            :         /* Force sys.argv[0] = '-m'*/
        2777                 :          2 :         arg0 = L"-m";
        2778                 :            :     }
        2779                 :            :
        2780         [ +  + ]:         25 :     if (arg0 != NULL) {
        2781                 :          3 :         arg0 = _PyMem_RawWcsdup(arg0);
        2782         [ -  + ]:          3 :         if (arg0 == NULL) {
        2783                 :          0 :             _PyWideStringList_Clear(&config_argv);
        2784                 :          0 :             return _PyStatus_NO_MEMORY();
        2785                 :            :         }
        2786                 :            :
        2787                 :          3 :         PyMem_RawFree(config_argv.items[0]);
        2788                 :          3 :         config_argv.items[0] = arg0;
        2789                 :            :     }
        2790                 :            :
        2791                 :         25 :     _PyWideStringList_Clear(&config->argv);
        2792                 :         25 :     config->argv = config_argv;
        2793                 :         25 :     return _PyStatus_OK();
        2794                 :            : }
        2795                 :            :
        2796                 :            :
        2797                 :            : static PyStatus
        2798                 :         50 : core_read_precmdline(PyConfig *config, _PyPreCmdline *precmdline)
        2799                 :            : {
        2800                 :            :     PyStatus status;
        2801                 :            :
        2802         [ +  + ]:         50 :     if (config->parse_argv == 1) {
        2803         [ -  + ]:         25 :         if (_PyWideStringList_Copy(&precmdline->argv, &config->argv) < 0) {
        2804                 :          0 :             return _PyStatus_NO_MEMORY();
        2805                 :            :         }
        2806                 :            :     }
        2807                 :            :
        2808                 :            :     PyPreConfig preconfig;
        2809                 :            :
        2810                 :         50 :     status = _PyPreConfig_InitFromPreConfig(&preconfig, &_PyRuntime.preconfig);
        2811         [ -  + ]:         50 :     if (_PyStatus_EXCEPTION(status)) {
        2812                 :          0 :         return status;
        2813                 :            :     }
        2814                 :            :
        2815                 :         50 :     _PyPreConfig_GetConfig(&preconfig, config);
        2816                 :            :
        2817                 :         50 :     status = _PyPreCmdline_Read(precmdline, &preconfig);
        2818         [ -  + ]:         50 :     if (_PyStatus_EXCEPTION(status)) {
        2819                 :          0 :         return status;
        2820                 :            :     }
        2821                 :            :
        2822                 :         50 :     status = _PyPreCmdline_SetConfig(precmdline, config);
        2823         [ -  + ]:         50 :     if (_PyStatus_EXCEPTION(status)) {
        2824                 :          0 :         return status;
        2825                 :            :     }
        2826                 :         50 :     return _PyStatus_OK();
        2827                 :            : }
        2828                 :            :
        2829                 :            :
        2830                 :            : /* Get run_filename absolute path */
        2831                 :            : static PyStatus
        2832                 :         50 : config_run_filename_abspath(PyConfig *config)
        2833                 :            : {
        2834         [ +  + ]:         50 :     if (!config->run_filename) {
        2835                 :          7 :         return _PyStatus_OK();
        2836                 :            :     }
        2837                 :            :
        2838                 :            : #ifndef MS_WINDOWS
        2839         [ +  + ]:         43 :     if (_Py_isabs(config->run_filename)) {
        2840                 :            :         /* path is already absolute */
        2841                 :         21 :         return _PyStatus_OK();
        2842                 :            :     }
        2843                 :            : #endif
        2844                 :            :
        2845                 :            :     wchar_t *abs_filename;
        2846         [ -  + ]:         22 :     if (_Py_abspath(config->run_filename, &abs_filename) < 0) {
        2847                 :            :         /* failed to get the absolute path of the command line filename:
        2848                 :            :            ignore the error, keep the relative path */
        2849                 :          0 :         return _PyStatus_OK();
        2850                 :            :     }
        2851         [ -  + ]:         22 :     if (abs_filename == NULL) {
        2852                 :          0 :         return _PyStatus_NO_MEMORY();
        2853                 :            :     }
        2854                 :            :
        2855                 :         22 :     PyMem_RawFree(config->run_filename);
        2856                 :         22 :     config->run_filename = abs_filename;
        2857                 :         22 :     return _PyStatus_OK();
        2858                 :            : }
        2859                 :            :
        2860                 :            :
        2861                 :            : static PyStatus
        2862                 :         50 : config_read_cmdline(PyConfig *config)
        2863                 :            : {
        2864                 :            :     PyStatus status;
        2865                 :         50 :     PyWideStringList cmdline_warnoptions = _PyWideStringList_INIT;
        2866                 :         50 :     PyWideStringList env_warnoptions = _PyWideStringList_INIT;
        2867                 :         50 :     PyWideStringList sys_warnoptions = _PyWideStringList_INIT;
        2868                 :            :
        2869         [ -  + ]:         50 :     if (config->parse_argv < 0) {
        2870                 :          0 :         config->parse_argv = 1;
        2871                 :            :     }
        2872                 :            :
        2873         [ +  + ]:         50 :     if (config->parse_argv == 1) {
        2874                 :            :         Py_ssize_t opt_index;
        2875                 :         25 :         status = config_parse_cmdline(config, &cmdline_warnoptions, &opt_index);
        2876         [ -  + ]:         25 :         if (_PyStatus_EXCEPTION(status)) {
        2877                 :          0 :             goto done;
        2878                 :            :         }
        2879                 :            :
        2880                 :         25 :         status = config_run_filename_abspath(config);
        2881         [ -  + ]:         25 :         if (_PyStatus_EXCEPTION(status)) {
        2882                 :          0 :             goto done;
        2883                 :            :         }
        2884                 :            :
        2885                 :         25 :         status = config_update_argv(config, opt_index);
        2886         [ -  + ]:         25 :         if (_PyStatus_EXCEPTION(status)) {
        2887                 :          0 :             goto done;
        2888                 :            :         }
        2889                 :            :     }
        2890                 :            :     else {
        2891                 :         25 :         status = config_run_filename_abspath(config);
        2892         [ -  + ]:         25 :         if (_PyStatus_EXCEPTION(status)) {
        2893                 :          0 :             goto done;
        2894                 :            :         }
        2895                 :            :     }
        2896                 :            :
        2897         [ +  + ]:         50 :     if (config->use_environment) {
        2898                 :          1 :         status = config_init_env_warnoptions(config, &env_warnoptions);
        2899         [ -  + ]:          1 :         if (_PyStatus_EXCEPTION(status)) {
        2900                 :          0 :             goto done;
        2901                 :            :         }
        2902                 :            :     }
        2903                 :            :
        2904                 :            :     /* Handle early PySys_AddWarnOption() calls */
        2905                 :         50 :     status = _PySys_ReadPreinitWarnOptions(&sys_warnoptions);
        2906         [ -  + ]:         50 :     if (_PyStatus_EXCEPTION(status)) {
        2907                 :          0 :         goto done;
        2908                 :            :     }
        2909                 :            :
        2910                 :         50 :     status = config_init_warnoptions(config,
        2911                 :            :                                      &cmdline_warnoptions,
        2912                 :            :                                      &env_warnoptions,
        2913                 :            :                                      &sys_warnoptions);
        2914         [ -  + ]:         50 :     if (_PyStatus_EXCEPTION(status)) {
        2915                 :          0 :         goto done;
        2916                 :            :     }
        2917                 :            :
        2918                 :         50 :     status = _PyStatus_OK();
        2919                 :            :
        2920                 :         50 : done:
        2921                 :         50 :     _PyWideStringList_Clear(&cmdline_warnoptions);
        2922                 :         50 :     _PyWideStringList_Clear(&env_warnoptions);
        2923                 :         50 :     _PyWideStringList_Clear(&sys_warnoptions);
        2924                 :         50 :     return status;
        2925                 :            : }
        2926                 :            :
        2927                 :            :
        2928                 :            : PyStatus
        2929                 :         25 : _PyConfig_SetPyArgv(PyConfig *config, const _PyArgv *args)
        2930                 :            : {
        2931                 :         25 :     PyStatus status = _Py_PreInitializeFromConfig(config, args);
        2932         [ -  + ]:         25 :     if (_PyStatus_EXCEPTION(status)) {
        2933                 :          0 :         return status;
        2934                 :            :     }
        2935                 :            :
        2936                 :         25 :     return _PyArgv_AsWstrList(args, &config->argv);
        2937                 :            : }
        2938                 :            :
        2939                 :            :
        2940                 :            : /* Set config.argv: decode argv using Py_DecodeLocale(). Pre-initialize Python
        2941                 :            :    if needed to ensure that encodings are properly configured. */
        2942                 :            : PyStatus
        2943                 :         25 : PyConfig_SetBytesArgv(PyConfig *config, Py_ssize_t argc, char * const *argv)
        2944                 :            : {
        2945                 :         25 :     _PyArgv args = {
        2946                 :            :         .argc = argc,
        2947                 :            :         .use_bytes_argv = 1,
        2948                 :            :         .bytes_argv = argv,
        2949                 :            :         .wchar_argv = NULL};
        2950                 :         25 :     return _PyConfig_SetPyArgv(config, &args);
        2951                 :            : }
        2952                 :            :
        2953                 :            :
        2954                 :            : PyStatus
        2955                 :          0 : PyConfig_SetArgv(PyConfig *config, Py_ssize_t argc, wchar_t * const *argv)
        2956                 :            : {
        2957                 :          0 :     _PyArgv args = {
        2958                 :            :         .argc = argc,
        2959                 :            :         .use_bytes_argv = 0,
        2960                 :            :         .bytes_argv = NULL,
        2961                 :            :         .wchar_argv = argv};
        2962                 :          0 :     return _PyConfig_SetPyArgv(config, &args);
        2963                 :            : }
        2964                 :            :
        2965                 :            :
        2966                 :            : PyStatus
        2967                 :          0 : PyConfig_SetWideStringList(PyConfig *config, PyWideStringList *list,
        2968                 :            :                            Py_ssize_t length, wchar_t **items)
        2969                 :            : {
        2970                 :          0 :     PyStatus status = _Py_PreInitializeFromConfig(config, NULL);
        2971         [ #  # ]:          0 :     if (_PyStatus_EXCEPTION(status)) {
        2972                 :          0 :         return status;
        2973                 :            :     }
        2974                 :            :
        2975                 :          0 :     PyWideStringList list2 = {.length = length, .items = items};
        2976         [ #  # ]:          0 :     if (_PyWideStringList_Copy(list, &list2) < 0) {
        2977                 :          0 :         return _PyStatus_NO_MEMORY();
        2978                 :            :     }
        2979                 :          0 :     return _PyStatus_OK();
        2980                 :            : }
        2981                 :            :
        2982                 :            :
        2983                 :            : /* Read the configuration into PyConfig from:
        2984                 :            :
        2985                 :            :    * Command line arguments
        2986                 :            :    * Environment variables
        2987                 :            :    * Py_xxx global configuration variables
        2988                 :            :
        2989                 :            :    The only side effects are to modify config and to call _Py_SetArgcArgv(). */
        2990                 :            : PyStatus
        2991                 :         50 : _PyConfig_Read(PyConfig *config, int compute_path_config)
        2992                 :            : {
        2993                 :            :     PyStatus status;
        2994                 :            :
        2995                 :         50 :     status = _Py_PreInitializeFromConfig(config, NULL);
        2996         [ -  + ]:         50 :     if (_PyStatus_EXCEPTION(status)) {
        2997                 :          0 :         return status;
        2998                 :            :     }
        2999                 :            :
        3000                 :         50 :     config_get_global_vars(config);
        3001                 :            :
        3002         [ +  + ]:         50 :     if (config->orig_argv.length == 0
        3003         [ -  + ]:         29 :         && !(config->argv.length == 1
        3004         [ #  # ]:          0 :              && wcscmp(config->argv.items[0], L"") == 0))
        3005                 :            :     {
        3006         [ -  + ]:         29 :         if (_PyWideStringList_Copy(&config->orig_argv, &config->argv) < 0) {
        3007                 :          0 :             return _PyStatus_NO_MEMORY();
        3008                 :            :         }
        3009                 :            :     }
        3010                 :            :
        3011                 :         50 :     _PyPreCmdline precmdline = _PyPreCmdline_INIT;
        3012                 :         50 :     status = core_read_precmdline(config, &precmdline);
        3013         [ -  + ]:         50 :     if (_PyStatus_EXCEPTION(status)) {
        3014                 :          0 :         goto done;
        3015                 :            :     }
        3016                 :            :
        3017                 :            :     assert(config->isolated >= 0);
        3018         [ +  + ]:         50 :     if (config->isolated) {
        3019                 :          4 :         config->safe_path = 1;
        3020                 :          4 :         config->use_environment = 0;
        3021                 :          4 :         config->user_site_directory = 0;
        3022                 :            :     }
        3023                 :            :
        3024                 :         50 :     status = config_read_cmdline(config);
        3025         [ -  + ]:         50 :     if (_PyStatus_EXCEPTION(status)) {
        3026                 :          0 :         goto done;
        3027                 :            :     }
        3028                 :            :
        3029                 :            :     /* Handle early PySys_AddXOption() calls */
        3030                 :         50 :     status = _PySys_ReadPreinitXOptions(config);
        3031         [ -  + ]:         50 :     if (_PyStatus_EXCEPTION(status)) {
        3032                 :          0 :         goto done;
        3033                 :            :     }
        3034                 :            :
        3035                 :         50 :     status = config_read(config, compute_path_config);
        3036         [ -  + ]:         50 :     if (_PyStatus_EXCEPTION(status)) {
        3037                 :          0 :         goto done;
        3038                 :            :     }
        3039                 :            :
        3040                 :            :     assert(config_check_consistency(config));
        3041                 :            :
        3042                 :         50 :     status = _PyStatus_OK();
        3043                 :            :
        3044                 :         50 : done:
        3045                 :         50 :     _PyPreCmdline_Clear(&precmdline);
        3046                 :         50 :     return status;
        3047                 :            : }
        3048                 :            :
        3049                 :            :
        3050                 :            : PyStatus
        3051                 :         21 : PyConfig_Read(PyConfig *config)
        3052                 :            : {
        3053                 :         21 :     return _PyConfig_Read(config, 0);
        3054                 :            : }
        3055                 :            :
        3056                 :            :
        3057                 :            : PyObject*
        3058                 :          0 : _Py_GetConfigsAsDict(void)
        3059                 :            : {
        3060                 :          0 :     PyObject *result = NULL;
        3061                 :          0 :     PyObject *dict = NULL;
        3062                 :            :
        3063                 :          0 :     result = PyDict_New();
        3064         [ #  # ]:          0 :     if (result == NULL) {
        3065                 :          0 :         goto error;
        3066                 :            :     }
        3067                 :            :
        3068                 :            :     /* global result */
        3069                 :          0 :     dict = _Py_GetGlobalVariablesAsDict();
        3070         [ #  # ]:          0 :     if (dict == NULL) {
        3071                 :          0 :         goto error;
        3072                 :            :     }
        3073         [ #  # ]:          0 :     if (PyDict_SetItemString(result, "global_config", dict) < 0) {
        3074                 :          0 :         goto error;
        3075                 :            :     }
        3076         [ #  # ]:          0 :     Py_CLEAR(dict);
        3077                 :            :
        3078                 :            :     /* pre config */
        3079                 :          0 :     PyInterpreterState *interp = _PyInterpreterState_GET();
        3080                 :          0 :     const PyPreConfig *pre_config = &interp->runtime->preconfig;
        3081                 :          0 :     dict = _PyPreConfig_AsDict(pre_config);
        3082         [ #  # ]:          0 :     if (dict == NULL) {
        3083                 :          0 :         goto error;
        3084                 :            :     }
        3085         [ #  # ]:          0 :     if (PyDict_SetItemString(result, "pre_config", dict) < 0) {
        3086                 :          0 :         goto error;
        3087                 :            :     }
        3088         [ #  # ]:          0 :     Py_CLEAR(dict);
        3089                 :            :
        3090                 :            :     /* core config */
        3091                 :          0 :     const PyConfig *config = _PyInterpreterState_GetConfig(interp);
        3092                 :          0 :     dict = _PyConfig_AsDict(config);
        3093         [ #  # ]:          0 :     if (dict == NULL) {
        3094                 :          0 :         goto error;
        3095                 :            :     }
        3096         [ #  # ]:          0 :     if (PyDict_SetItemString(result, "config", dict) < 0) {
        3097                 :          0 :         goto error;
        3098                 :            :     }
        3099         [ #  # ]:          0 :     Py_CLEAR(dict);
        3100                 :            :
        3101                 :          0 :     return result;
        3102                 :            :
        3103                 :          0 : error:
        3104                 :          0 :     Py_XDECREF(result);
        3105                 :          0 :     Py_XDECREF(dict);
        3106                 :          0 :     return NULL;
        3107                 :            : }
        3108                 :            :
        3109                 :            :
        3110                 :            : static void
        3111                 :          0 : init_dump_ascii_wstr(const wchar_t *str)
        3112                 :            : {
        3113         [ #  # ]:          0 :     if (str == NULL) {
        3114                 :          0 :         PySys_WriteStderr("(not set)");
        3115                 :          0 :         return;
        3116                 :            :     }
        3117                 :            :
        3118                 :          0 :     PySys_WriteStderr("'");
        3119         [ #  # ]:          0 :     for (; *str != L'\0'; str++) {
        3120                 :          0 :         unsigned int ch = (unsigned int)*str;
        3121         [ #  # ]:          0 :         if (ch == L'\'') {
        3122                 :          0 :             PySys_WriteStderr("\\'");
        3123   [ #  #  #  # ]:          0 :         } else if (0x20 <= ch && ch < 0x7f) {
        3124                 :          0 :             PySys_WriteStderr("%c", ch);
        3125                 :            :         }
        3126         [ #  # ]:          0 :         else if (ch <= 0xff) {
        3127                 :          0 :             PySys_WriteStderr("\\x%02x", ch);
        3128                 :            :         }
        3129                 :            : #if SIZEOF_WCHAR_T > 2
        3130         [ #  # ]:          0 :         else if (ch > 0xffff) {
        3131                 :          0 :             PySys_WriteStderr("\\U%08x", ch);
        3132                 :            :         }
        3133                 :            : #endif
        3134                 :            :         else {
        3135                 :          0 :             PySys_WriteStderr("\\u%04x", ch);
        3136                 :            :         }
        3137                 :            :     }
        3138                 :          0 :     PySys_WriteStderr("'");
        3139                 :            : }
        3140                 :            :
        3141                 :            :
        3142                 :            : /* Dump the Python path configuration into sys.stderr */
        3143                 :            : void
        3144                 :          0 : _Py_DumpPathConfig(PyThreadState *tstate)
        3145                 :            : {
        3146                 :          0 :     PyObject *exc = _PyErr_GetRaisedException(tstate);
        3147                 :            :
        3148                 :          0 :     PySys_WriteStderr("Python path configuration:\n");
        3149                 :            :
        3150                 :            : #define DUMP_CONFIG(NAME, FIELD) \
        3151                 :            :         do { \
        3152                 :            :             PySys_WriteStderr("  " NAME " = "); \
        3153                 :            :             init_dump_ascii_wstr(config->FIELD); \
        3154                 :            :             PySys_WriteStderr("\n"); \
        3155                 :            :         } while (0)
        3156                 :            :
        3157                 :          0 :     const PyConfig *config = _PyInterpreterState_GetConfig(tstate->interp);
        3158                 :          0 :     DUMP_CONFIG("PYTHONHOME", home);
        3159                 :          0 :     DUMP_CONFIG("PYTHONPATH", pythonpath_env);
        3160                 :          0 :     DUMP_CONFIG("program name", program_name);
        3161                 :          0 :     PySys_WriteStderr("  isolated = %i\n", config->isolated);
        3162                 :          0 :     PySys_WriteStderr("  environment = %i\n", config->use_environment);
        3163                 :          0 :     PySys_WriteStderr("  user site = %i\n", config->user_site_directory);
        3164                 :          0 :     PySys_WriteStderr("  safe_path = %i\n", config->safe_path);
        3165                 :          0 :     PySys_WriteStderr("  import site = %i\n", config->site_import);
        3166                 :          0 :     PySys_WriteStderr("  is in build tree = %i\n", config->_is_python_build);
        3167                 :          0 :     DUMP_CONFIG("stdlib dir", stdlib_dir);
        3168                 :            : #undef DUMP_CONFIG
        3169                 :            :
        3170                 :            : #define DUMP_SYS(NAME) \
        3171                 :            :         do { \
        3172                 :            :             obj = PySys_GetObject(#NAME); \
        3173                 :            :             PySys_FormatStderr("  sys.%s = ", #NAME); \
        3174                 :            :             if (obj != NULL) { \
        3175                 :            :                 PySys_FormatStderr("%A", obj); \
        3176                 :            :             } \
        3177                 :            :             else { \
        3178                 :            :                 PySys_WriteStderr("(not set)"); \
        3179                 :            :             } \
        3180                 :            :             PySys_FormatStderr("\n"); \
        3181                 :            :         } while (0)
        3182                 :            :
        3183                 :            :     PyObject *obj;
        3184         [ #  # ]:          0 :     DUMP_SYS(_base_executable);
        3185         [ #  # ]:          0 :     DUMP_SYS(base_prefix);
        3186         [ #  # ]:          0 :     DUMP_SYS(base_exec_prefix);
        3187         [ #  # ]:          0 :     DUMP_SYS(platlibdir);
        3188         [ #  # ]:          0 :     DUMP_SYS(executable);
        3189         [ #  # ]:          0 :     DUMP_SYS(prefix);
        3190         [ #  # ]:          0 :     DUMP_SYS(exec_prefix);
        3191                 :            : #undef DUMP_SYS
        3192                 :            :
        3193                 :          0 :     PyObject *sys_path = PySys_GetObject("path");  /* borrowed reference */
        3194   [ #  #  #  # ]:          0 :     if (sys_path != NULL && PyList_Check(sys_path)) {
        3195                 :          0 :         PySys_WriteStderr("  sys.path = [\n");
        3196                 :          0 :         Py_ssize_t len = PyList_GET_SIZE(sys_path);
        3197         [ #  # ]:          0 :         for (Py_ssize_t i=0; i < len; i++) {
        3198                 :          0 :             PyObject *path = PyList_GET_ITEM(sys_path, i);
        3199                 :          0 :             PySys_FormatStderr("    %A,\n", path);
        3200                 :            :         }
        3201                 :          0 :         PySys_WriteStderr("  ]\n");
        3202                 :            :     }
        3203                 :            :
        3204                 :          0 :     _PyErr_SetRaisedException(tstate, exc);
        3205                 :          0 : }

Generated by: LCOV version 1.14