LCOV - code coverage report
Current view: top level - Python - initconfig.c (source / functions) Hit Total Coverage
Test: CPython 3.12 LCOV report [commit acb105a7c1f] Lines: 1157 1371 84.4 %
Date: 2022-07-20 13:12:14 Functions: 77 85 90.6 %
Branches: 903 1317 68.6 %

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

Generated by: LCOV version 1.14