diff options
author | Victor Stinner <vstinner@redhat.com> | 2019-03-26 16:58:50 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-03-26 16:58:50 +0100 |
commit | f8ba6f5afc317d1be3025db1be410ac66a7e5a27 (patch) | |
tree | 531f75949653a2843d2834f253d26f5d366e6111 /Python/coreconfig.c | |
parent | 414b1cde93764cdabb0798b02af4dd7df954424d (diff) | |
download | cpython-f8ba6f5afc317d1be3025db1be410ac66a7e5a27.tar.gz cpython-f8ba6f5afc317d1be3025db1be410ac66a7e5a27.zip |
bpo-36301: Cleanup preconfig.c and coreconfig.c (GH-12563)
* _PyCoreConfig_Write() now updates _PyRuntime.preconfig
* Remove _PyPreCmdline_Copy()
* _PyPreCmdline_Read() now accepts _PyPreConfig and _PyCoreConfig
optional configurations.
* Rename _PyPreConfig_ReadFromArgv() to _PyPreConfig_Read(). Simplify
the code.
* Calling _PyCoreConfig_Read() no longer adds the warning options
twice: don't add a warning option if it's already in the list.
* Rename _PyCoreConfig_ReadFromArgv() to _PyCoreConfig_Read().
* Rename config_from_cmdline() to _PyCoreConfig_ReadFromArgv().
* Add more assertions on _PyCoreConfig in _PyCoreConfig_Read().
* Move some functions.
* Make some config functions private.
Diffstat (limited to 'Python/coreconfig.c')
-rw-r--r-- | Python/coreconfig.c | 574 |
1 files changed, 299 insertions, 275 deletions
diff --git a/Python/coreconfig.c b/Python/coreconfig.c index 2e6eb402987..2f54e79081f 100644 --- a/Python/coreconfig.c +++ b/Python/coreconfig.c @@ -296,7 +296,7 @@ _PyWstrList_Append(_PyWstrList *list, const wchar_t *item) } -static int +int _PyWstrList_Extend(_PyWstrList *list, const _PyWstrList *list2) { for (Py_ssize_t i = 0; i < list2->length; i++) { @@ -308,6 +308,18 @@ _PyWstrList_Extend(_PyWstrList *list, const _PyWstrList *list2) } +static int +_PyWstrList_Find(_PyWstrList *list, const wchar_t *item) +{ + for (Py_ssize_t i = 0; i < list->length; i++) { + if (wcscmp(list->items[i], item) == 0) { + return 1; + } + } + return 0; +} + + PyObject* _PyWstrList_AsList(const _PyWstrList *list) { @@ -607,6 +619,120 @@ _PyCoreConfig_Copy(_PyCoreConfig *config, const _PyCoreConfig *config2) } +static PyObject * +_PyCoreConfig_AsDict(const _PyCoreConfig *config) +{ + PyObject *dict; + + dict = PyDict_New(); + if (dict == NULL) { + return NULL; + } + +#define SET_ITEM(KEY, EXPR) \ + do { \ + PyObject *obj = (EXPR); \ + if (obj == NULL) { \ + goto fail; \ + } \ + int res = PyDict_SetItemString(dict, (KEY), obj); \ + Py_DECREF(obj); \ + if (res < 0) { \ + goto fail; \ + } \ + } while (0) +#define FROM_STRING(STR) \ + ((STR != NULL) ? \ + PyUnicode_FromString(STR) \ + : (Py_INCREF(Py_None), Py_None)) +#define SET_ITEM_INT(ATTR) \ + SET_ITEM(#ATTR, PyLong_FromLong(config->ATTR)) +#define SET_ITEM_UINT(ATTR) \ + SET_ITEM(#ATTR, PyLong_FromUnsignedLong(config->ATTR)) +#define SET_ITEM_STR(ATTR) \ + SET_ITEM(#ATTR, FROM_STRING(config->ATTR)) +#define FROM_WSTRING(STR) \ + ((STR != NULL) ? \ + PyUnicode_FromWideChar(STR, -1) \ + : (Py_INCREF(Py_None), Py_None)) +#define SET_ITEM_WSTR(ATTR) \ + SET_ITEM(#ATTR, FROM_WSTRING(config->ATTR)) +#define SET_ITEM_WSTRLIST(LIST) \ + SET_ITEM(#LIST, _PyWstrList_AsList(&config->LIST)) + + SET_ITEM_INT(isolated); + SET_ITEM_INT(use_environment); + SET_ITEM_INT(dev_mode); + SET_ITEM_INT(install_signal_handlers); + SET_ITEM_INT(use_hash_seed); + SET_ITEM_UINT(hash_seed); + SET_ITEM_INT(faulthandler); + SET_ITEM_INT(tracemalloc); + SET_ITEM_INT(import_time); + SET_ITEM_INT(show_ref_count); + SET_ITEM_INT(show_alloc_count); + SET_ITEM_INT(dump_refs); + SET_ITEM_INT(malloc_stats); + SET_ITEM_STR(filesystem_encoding); + SET_ITEM_STR(filesystem_errors); + SET_ITEM_WSTR(pycache_prefix); + SET_ITEM_WSTR(program_name); + SET_ITEM_WSTRLIST(argv); + SET_ITEM_WSTR(program); + SET_ITEM_WSTRLIST(xoptions); + SET_ITEM_WSTRLIST(warnoptions); + SET_ITEM_WSTR(module_search_path_env); + SET_ITEM_WSTR(home); + SET_ITEM_WSTRLIST(module_search_paths); + SET_ITEM_WSTR(executable); + SET_ITEM_WSTR(prefix); + SET_ITEM_WSTR(base_prefix); + SET_ITEM_WSTR(exec_prefix); + SET_ITEM_WSTR(base_exec_prefix); +#ifdef MS_WINDOWS + SET_ITEM_WSTR(dll_path); +#endif + SET_ITEM_INT(site_import); + SET_ITEM_INT(bytes_warning); + SET_ITEM_INT(inspect); + SET_ITEM_INT(interactive); + SET_ITEM_INT(optimization_level); + SET_ITEM_INT(parser_debug); + SET_ITEM_INT(write_bytecode); + SET_ITEM_INT(verbose); + SET_ITEM_INT(quiet); + SET_ITEM_INT(user_site_directory); + SET_ITEM_INT(buffered_stdio); + SET_ITEM_STR(stdio_encoding); + SET_ITEM_STR(stdio_errors); +#ifdef MS_WINDOWS + SET_ITEM_INT(legacy_windows_stdio); +#endif + SET_ITEM_INT(skip_source_first_line); + SET_ITEM_WSTR(run_command); + SET_ITEM_WSTR(run_module); + SET_ITEM_WSTR(run_filename); + SET_ITEM_INT(_install_importlib); + SET_ITEM_STR(_check_hash_pycs_mode); + SET_ITEM_INT(_frozen); + + return dict; + +fail: + Py_DECREF(dict); + return NULL; + +#undef FROM_STRING +#undef FROM_WSTRING +#undef SET_ITEM +#undef SET_ITEM_INT +#undef SET_ITEM_UINT +#undef SET_ITEM_STR +#undef SET_ITEM_WSTR +#undef SET_ITEM_WSTRLIST +} + + static const char* _PyCoreConfig_GetEnv(const _PyCoreConfig *config, const char *name) { @@ -614,6 +740,9 @@ _PyCoreConfig_GetEnv(const _PyCoreConfig *config, const char *name) } +/* Get a copy of the environment variable as wchar_t*. + Return 0 on success, but *dest can be NULL. + Return -1 on memory allocation failure. Return -2 on decoding error. */ static int _PyCoreConfig_GetEnvDup(const _PyCoreConfig *config, wchar_t **dest, @@ -662,7 +791,7 @@ _PyCoreConfig_GetEnvDup(const _PyCoreConfig *config, } -void +static void _PyCoreConfig_GetGlobalConfig(_PyCoreConfig *config) { #define COPY_FLAG(ATTR, VALUE) \ @@ -699,7 +828,7 @@ _PyCoreConfig_GetGlobalConfig(_PyCoreConfig *config) /* Set Py_xxx global configuration variables from 'config' configuration. */ -void +static void _PyCoreConfig_SetGlobalConfig(const _PyCoreConfig *config) { #define COPY_FLAG(ATTR, VAR) \ @@ -848,10 +977,10 @@ config_get_xoption(const _PyCoreConfig *config, wchar_t *name) static _PyInitError config_init_home(_PyCoreConfig *config) { - wchar_t *home; + assert(config->home == NULL); /* If Py_SetPythonHome() was called, use its value */ - home = _Py_path_config.home; + wchar_t *home = _Py_path_config.home; if (home) { config->home = _PyMem_RawWcsdup(home); if (config->home == NULL) { @@ -1098,7 +1227,7 @@ config_read_complex_options(_PyCoreConfig *config) static const char * -get_stdio_errors(const _PyCoreConfig *config) +config_get_stdio_errors(const _PyCoreConfig *config) { #ifndef MS_WINDOWS const char *loc = setlocale(LC_CTYPE, NULL); @@ -1125,7 +1254,7 @@ get_stdio_errors(const _PyCoreConfig *config) static _PyInitError -get_locale_encoding(char **locale_encoding) +config_get_locale_encoding(char **locale_encoding) { #ifdef MS_WINDOWS char encoding[20]; @@ -1236,13 +1365,13 @@ config_init_stdio_encoding(_PyCoreConfig *config, /* Choose the default error handler based on the current locale. */ if (config->stdio_encoding == NULL) { - _PyInitError err = get_locale_encoding(&config->stdio_encoding); + _PyInitError err = config_get_locale_encoding(&config->stdio_encoding); if (_Py_INIT_FAILED(err)) { return err; } } if (config->stdio_errors == NULL) { - const char *errors = get_stdio_errors(config); + const char *errors = config_get_stdio_errors(config); config->stdio_errors = _PyMem_RawStrdup(errors); if (config->stdio_errors == NULL) { return _Py_INIT_NO_MEMORY(); @@ -1306,7 +1435,7 @@ config_init_fs_encoding(_PyCoreConfig *config, const _PyPreConfig *preconfig) #if defined(__APPLE__) || defined(__ANDROID__) config->filesystem_encoding = _PyMem_RawStrdup("utf-8"); #else - _PyInitError err = get_locale_encoding(&config->filesystem_encoding); + _PyInitError err = config_get_locale_encoding(&config->filesystem_encoding); if (_Py_INIT_FAILED(err)) { return err; } @@ -1330,38 +1459,22 @@ config_init_fs_encoding(_PyCoreConfig *config, const _PyPreConfig *preconfig) } -/* Read the configuration into _PyCoreConfig from: - - * Environment variables - * Py_xxx global configuration variables - - See _PyCoreConfig_ReadFromArgv() to parse also command line arguments. */ static _PyInitError -config_read_impl(_PyCoreConfig *config, _PyPreCmdline *cmdline) +config_read(_PyCoreConfig *config, _PyPreCmdline *cmdline) { _PyInitError err; const _PyPreConfig *preconfig = &_PyRuntime.preconfig; - _PyPreCmdline_GetPreConfig(cmdline, preconfig); - _PyPreCmdline_GetCoreConfig(cmdline, config); - - err = _PyPreCmdline_Read(cmdline); + err = _PyPreCmdline_Read(cmdline, preconfig, config); if (_Py_INIT_FAILED(err)) { return err; } - _PyPreCmdline_SetCoreConfig(cmdline, config); - - if (_PyWstrList_Extend(&config->xoptions, &cmdline->xoptions) < 0) { + if (_PyPreCmdline_SetCoreConfig(cmdline, config) < 0) { return _Py_INIT_NO_MEMORY(); } - _PyCoreConfig_GetGlobalConfig(config); - - assert(config->use_environment >= 0); - if (config->isolated > 0) { - config->use_environment = 0; config->user_site_directory = 0; } @@ -1419,16 +1532,16 @@ config_read_impl(_PyCoreConfig *config, _PyPreCmdline *cmdline) config->faulthandler = 1; } } - if (config->use_hash_seed < 0) { - config->use_hash_seed = 0; - config->hash_seed = 0; - } if (config->faulthandler < 0) { config->faulthandler = 0; } if (config->tracemalloc < 0) { config->tracemalloc = 0; } + if (config->use_hash_seed < 0) { + config->use_hash_seed = 0; + config->hash_seed = 0; + } if (config->filesystem_encoding == NULL || config->filesystem_errors == NULL) { err = config_init_fs_encoding(config, preconfig); @@ -1449,53 +1562,10 @@ config_read_impl(_PyCoreConfig *config, _PyPreCmdline *cmdline) } } - assert(config->use_environment >= 0); - assert(config->filesystem_encoding != NULL); - assert(config->filesystem_errors != NULL); - assert(config->stdio_encoding != NULL); - assert(config->stdio_errors != NULL); - assert(config->_check_hash_pycs_mode != NULL); - assert(_PyWstrList_CheckConsistency(&config->argv)); - return _Py_INIT_OK(); } -static _PyInitError -config_read(_PyCoreConfig *config, const _PyPreCmdline *src_cmdline) -{ - _PyInitError err; - - err = _Py_PreInitializeFromConfig(config); - if (_Py_INIT_FAILED(err)) { - return err; - } - - _PyPreCmdline cmdline = _PyPreCmdline_INIT; - - if (src_cmdline) { - if (_PyPreCmdline_Copy(&cmdline, src_cmdline) < 0) { - err = _Py_INIT_NO_MEMORY(); - goto done; - } - } - - err = config_read_impl(config, &cmdline); - -done: - _PyPreCmdline_Clear(&cmdline); - return err; - -} - - -_PyInitError -_PyCoreConfig_Read(_PyCoreConfig *config) -{ - return config_read(config, NULL); -} - - static void config_init_stdio(const _PyCoreConfig *config) { @@ -1542,139 +1612,30 @@ _PyCoreConfig_Write(const _PyCoreConfig *config) { _PyCoreConfig_SetGlobalConfig(config); config_init_stdio(config); -} - - -static PyObject * -_PyCoreConfig_AsDict(const _PyCoreConfig *config) -{ - PyObject *dict; - - dict = PyDict_New(); - if (dict == NULL) { - return NULL; - } -#define SET_ITEM(KEY, EXPR) \ - do { \ - PyObject *obj = (EXPR); \ - if (obj == NULL) { \ - goto fail; \ - } \ - int res = PyDict_SetItemString(dict, (KEY), obj); \ - Py_DECREF(obj); \ - if (res < 0) { \ - goto fail; \ - } \ - } while (0) -#define FROM_STRING(STR) \ - ((STR != NULL) ? \ - PyUnicode_FromString(STR) \ - : (Py_INCREF(Py_None), Py_None)) -#define SET_ITEM_INT(ATTR) \ - SET_ITEM(#ATTR, PyLong_FromLong(config->ATTR)) -#define SET_ITEM_UINT(ATTR) \ - SET_ITEM(#ATTR, PyLong_FromUnsignedLong(config->ATTR)) -#define SET_ITEM_STR(ATTR) \ - SET_ITEM(#ATTR, FROM_STRING(config->ATTR)) -#define FROM_WSTRING(STR) \ - ((STR != NULL) ? \ - PyUnicode_FromWideChar(STR, -1) \ - : (Py_INCREF(Py_None), Py_None)) -#define SET_ITEM_WSTR(ATTR) \ - SET_ITEM(#ATTR, FROM_WSTRING(config->ATTR)) -#define SET_ITEM_WSTRLIST(LIST) \ - SET_ITEM(#LIST, _PyWstrList_AsList(&config->LIST)) - - SET_ITEM_INT(isolated); - SET_ITEM_INT(use_environment); - SET_ITEM_INT(dev_mode); - SET_ITEM_INT(install_signal_handlers); - SET_ITEM_INT(use_hash_seed); - SET_ITEM_UINT(hash_seed); - SET_ITEM_INT(faulthandler); - SET_ITEM_INT(tracemalloc); - SET_ITEM_INT(import_time); - SET_ITEM_INT(show_ref_count); - SET_ITEM_INT(show_alloc_count); - SET_ITEM_INT(dump_refs); - SET_ITEM_INT(malloc_stats); - SET_ITEM_STR(filesystem_encoding); - SET_ITEM_STR(filesystem_errors); - SET_ITEM_WSTR(pycache_prefix); - SET_ITEM_WSTR(program_name); - SET_ITEM_WSTRLIST(argv); - SET_ITEM_WSTR(program); - SET_ITEM_WSTRLIST(xoptions); - SET_ITEM_WSTRLIST(warnoptions); - SET_ITEM_WSTR(module_search_path_env); - SET_ITEM_WSTR(home); - SET_ITEM_WSTRLIST(module_search_paths); - SET_ITEM_WSTR(executable); - SET_ITEM_WSTR(prefix); - SET_ITEM_WSTR(base_prefix); - SET_ITEM_WSTR(exec_prefix); - SET_ITEM_WSTR(base_exec_prefix); -#ifdef MS_WINDOWS - SET_ITEM_WSTR(dll_path); -#endif - SET_ITEM_INT(site_import); - SET_ITEM_INT(bytes_warning); - SET_ITEM_INT(inspect); - SET_ITEM_INT(interactive); - SET_ITEM_INT(optimization_level); - SET_ITEM_INT(parser_debug); - SET_ITEM_INT(write_bytecode); - SET_ITEM_INT(verbose); - SET_ITEM_INT(quiet); - SET_ITEM_INT(user_site_directory); - SET_ITEM_INT(buffered_stdio); - SET_ITEM_STR(stdio_encoding); - SET_ITEM_STR(stdio_errors); -#ifdef MS_WINDOWS - SET_ITEM_INT(legacy_windows_stdio); -#endif - SET_ITEM_INT(skip_source_first_line); - SET_ITEM_WSTR(run_command); - SET_ITEM_WSTR(run_module); - SET_ITEM_WSTR(run_filename); - SET_ITEM_INT(_install_importlib); - SET_ITEM_STR(_check_hash_pycs_mode); - SET_ITEM_INT(_frozen); - - return dict; - -fail: - Py_DECREF(dict); - return NULL; - -#undef FROM_STRING -#undef FROM_WSTRING -#undef SET_ITEM -#undef SET_ITEM_INT -#undef SET_ITEM_UINT -#undef SET_ITEM_STR -#undef SET_ITEM_WSTR -#undef SET_ITEM_WSTRLIST + /* Write the new pre-configuration into _PyRuntime */ + _PyPreConfig *preconfig = &_PyRuntime.preconfig; + preconfig->isolated = config->isolated; + preconfig->use_environment = config->use_environment; + preconfig->dev_mode = config->dev_mode; } /* --- _PyCmdline ------------------------------------------------- */ typedef struct { - _PyPreCmdline precmdline; - _PyWstrList warnoptions; /* Command line -W options */ + _PyWstrList cmdline_warnoptions; /* Command line -W options */ _PyWstrList env_warnoptions; /* PYTHONWARNINGS environment variables */ int print_help; /* -h, -? options */ int print_version; /* -V option */ + int need_usage; } _PyCmdline; static void cmdline_clear(_PyCmdline *cmdline) { - _PyPreCmdline_Clear(&cmdline->precmdline); - _PyWstrList_Clear(&cmdline->warnoptions); + _PyWstrList_Clear(&cmdline->cmdline_warnoptions); _PyWstrList_Clear(&cmdline->env_warnoptions); } @@ -1684,9 +1645,9 @@ cmdline_clear(_PyCmdline *cmdline) /* Parse the command line arguments */ static _PyInitError config_parse_cmdline(_PyCoreConfig *config, _PyCmdline *cmdline, - int *need_usage) + _PyPreCmdline *precmdline) { - const _PyWstrList *argv = &cmdline->precmdline.argv; + const _PyWstrList *argv = &precmdline->argv; _PyOS_ResetGetOpt(); do { @@ -1740,7 +1701,7 @@ config_parse_cmdline(_PyCoreConfig *config, _PyCmdline *cmdline, } else { fprintf(stderr, "--check-hash-based-pycs must be one of " "'default', 'always', or 'never'\n"); - *need_usage = 1; + cmdline->need_usage = 1; return _Py_INIT_OK(); } break; @@ -1761,7 +1722,7 @@ config_parse_cmdline(_PyCoreConfig *config, _PyCmdline *cmdline, case 'E': case 'I': case 'X': - /* option handled by _PyPreConfig_ReadFromArgv() */ + /* option handled by _PyPreCmdline_Read() */ break; /* case 'J': reserved for Jython */ @@ -1808,7 +1769,7 @@ config_parse_cmdline(_PyCoreConfig *config, _PyCmdline *cmdline, break; case 'W': - if (_PyWstrList_Append(&cmdline->warnoptions, _PyOS_optarg) < 0) { + if (_PyWstrList_Append(&cmdline->cmdline_warnoptions, _PyOS_optarg) < 0) { return _Py_INIT_NO_MEMORY(); } break; @@ -1825,7 +1786,7 @@ config_parse_cmdline(_PyCoreConfig *config, _PyCmdline *cmdline, default: /* unknown argument: parsing failed */ - *need_usage = 1; + cmdline->need_usage = 1; return _Py_INIT_OK(); } } while (1); @@ -1891,9 +1852,9 @@ cmdline_init_env_warnoptions(_PyCmdline *cmdline, const _PyCoreConfig *config) static _PyInitError -config_init_program(_PyCoreConfig *config, const _PyCmdline *cmdline) +config_init_program(_PyCoreConfig *config, const _PyPreCmdline *cmdline) { - const _PyWstrList *argv = &cmdline->precmdline.argv; + const _PyWstrList *argv = &cmdline->argv; wchar_t *program; if (argv->length >= 1) { program = argv->items[0]; @@ -1910,11 +1871,23 @@ config_init_program(_PyCoreConfig *config, const _PyCmdline *cmdline) } +static int +config_add_warnoption(_PyCoreConfig *config, const wchar_t *option) +{ + if (_PyWstrList_Find(&config->warnoptions, option)) { + /* Already present: do nothing */ + return 0; + } + if (_PyWstrList_Append(&config->warnoptions, option)) { + return -1; + } + return 0; +} + + static _PyInitError config_init_warnoptions(_PyCoreConfig *config, const _PyCmdline *cmdline) { - assert(config->warnoptions.length == 0); - /* The priority order for warnings configuration is (highest precedence * first): * @@ -1931,17 +1904,26 @@ config_init_warnoptions(_PyCoreConfig *config, const _PyCmdline *cmdline) */ if (config->dev_mode) { - if (_PyWstrList_Append(&config->warnoptions, L"default")) { + if (config_add_warnoption(config, L"default") < 0) { return _Py_INIT_NO_MEMORY(); } } - if (_PyWstrList_Extend(&config->warnoptions, &cmdline->env_warnoptions) < 0) { - return _Py_INIT_NO_MEMORY(); + Py_ssize_t i; + const _PyWstrList *options; + + options = &cmdline->env_warnoptions; + for (i = 0; i < options->length; i++) { + if (config_add_warnoption(config, options->items[i]) < 0) { + return _Py_INIT_NO_MEMORY(); + } } - if (_PyWstrList_Extend(&config->warnoptions, &cmdline->warnoptions) < 0) { - return _Py_INIT_NO_MEMORY(); + options = &cmdline->cmdline_warnoptions; + for (i = 0; i < options->length; i++) { + if (config_add_warnoption(config, options->items[i]) < 0) { + return _Py_INIT_NO_MEMORY(); + } } /* If the bytes_warning_flag isn't set, bytesobject.c and bytearrayobject.c @@ -1956,7 +1938,7 @@ config_init_warnoptions(_PyCoreConfig *config, const _PyCmdline *cmdline) else { filter = L"default::BytesWarning"; } - if (_PyWstrList_Append(&config->warnoptions, filter)) { + if (config_add_warnoption(config, filter) < 0) { return _Py_INIT_NO_MEMORY(); } } @@ -1965,9 +1947,9 @@ config_init_warnoptions(_PyCoreConfig *config, const _PyCmdline *cmdline) static _PyInitError -config_init_argv(_PyCoreConfig *config, const _PyCmdline *cmdline) +config_init_argv(_PyCoreConfig *config, const _PyPreCmdline *cmdline) { - const _PyWstrList *cmdline_argv = &cmdline->precmdline.argv; + const _PyWstrList *cmdline_argv = &cmdline->argv; _PyWstrList config_argv = _PyWstrList_INIT; /* Copy argv to be able to modify it (to force -c/-m) */ @@ -2032,110 +2014,152 @@ config_usage(int error, const wchar_t* program) } -/* Parse command line options and environment variables. */ -static _PyInitError -config_from_cmdline(_PyCoreConfig *config, _PyCmdline *cmdline) +/* Read the configuration into _PyCoreConfig from: + + * Command line arguments + * Environment variables + * Py_xxx global configuration variables */ +_PyInitError +_PyCoreConfig_Read(_PyCoreConfig *config, const _PyArgv *args) { - int need_usage = 0; _PyInitError err; + err = _Py_PreInitializeFromConfig(config); + if (_Py_INIT_FAILED(err)) { + return err; + } + _PyCoreConfig_GetGlobalConfig(config); + _PyPreCmdline precmdline = _PyPreCmdline_INIT; + if (args) { + err = _PyPreCmdline_SetArgv(&precmdline, args); + if (_Py_INIT_FAILED(err)) { + goto done; + } + } + if (config->program == NULL) { - err = config_init_program(config, cmdline); + err = config_init_program(config, &precmdline); if (_Py_INIT_FAILED(err)) { - return err; + goto done; } } - err = _PyPreCmdline_Read(&cmdline->precmdline); + const _PyPreConfig *preconfig = &_PyRuntime.preconfig; + err = _PyPreCmdline_Read(&precmdline, preconfig, config); if (_Py_INIT_FAILED(err)) { - return err; + goto done; } - _PyPreCmdline_SetPreConfig(&cmdline->precmdline, &_PyRuntime.preconfig); + _PyCmdline cmdline; + memset(&cmdline, 0, sizeof(cmdline)); - err = config_parse_cmdline(config, cmdline, &need_usage); - if (_Py_INIT_FAILED(err)) { - return err; - } + if (args) { + err = config_parse_cmdline(config, &cmdline, &precmdline); + if (_Py_INIT_FAILED(err)) { + goto done; + } - if (need_usage) { - config_usage(1, config->program); - return _Py_INIT_EXIT(2); - } + if (cmdline.need_usage) { + config_usage(1, config->program); + err = _Py_INIT_EXIT(2); + goto done; + } - if (cmdline->print_help) { - config_usage(0, config->program); - return _Py_INIT_EXIT(0); - } + if (cmdline.print_help) { + config_usage(0, config->program); + err = _Py_INIT_EXIT(0); + goto done; + } - if (cmdline->print_version) { - printf("Python %s\n", - (cmdline->print_version >= 2) ? Py_GetVersion() : PY_VERSION); - return _Py_INIT_EXIT(0); - } + if (cmdline.print_version) { + printf("Python %s\n", + (cmdline.print_version >= 2) ? Py_GetVersion() : PY_VERSION); + err = _Py_INIT_EXIT(0); + goto done; + } - err = config_init_argv(config, cmdline); - if (_Py_INIT_FAILED(err)) { - return err; + err = config_init_argv(config, &precmdline); + if (_Py_INIT_FAILED(err)) { + goto done; + } } - err = config_read(config, &cmdline->precmdline); + err = config_read(config, &precmdline); if (_Py_INIT_FAILED(err)) { - return err; + goto done; } if (config->use_environment) { - err = cmdline_init_env_warnoptions(cmdline, config); + err = cmdline_init_env_warnoptions(&cmdline, config); if (_Py_INIT_FAILED(err)) { - return err; + goto done; } } - err = config_init_warnoptions(config, cmdline); + err = config_init_warnoptions(config, &cmdline); if (_Py_INIT_FAILED(err)) { - return err; + goto done; } - const _PyWstrList *argv = &cmdline->precmdline.argv; + const _PyWstrList *argv = &precmdline.argv; if (_Py_SetArgcArgv(argv->length, argv->items) < 0) { - return _Py_INIT_NO_MEMORY(); - } - return _Py_INIT_OK(); -} - - -/* Read the configuration into _PyCoreConfig from: - - * Command line arguments - * Environment variables - * Py_xxx global configuration variables */ -_PyInitError -_PyCoreConfig_ReadFromArgv(_PyCoreConfig *config, const _PyArgv *args) -{ - _PyInitError err; - - err = _Py_PreInitializeFromConfig(config); - if (_Py_INIT_FAILED(err)) { - return err; - } - - _PyCmdline cmdline = {.precmdline = _PyPreCmdline_INIT}; - - err = _PyPreCmdline_SetArgv(&cmdline.precmdline, args); - if (_Py_INIT_FAILED(err)) { + err = _Py_INIT_NO_MEMORY(); goto done; } - err = config_from_cmdline(config, &cmdline); - if (_Py_INIT_FAILED(err)) { - goto done; + /* Check config consistency */ + assert(config->isolated >= 0); + assert(config->use_environment >= 0); + assert(config->dev_mode >= 0); + assert(config->install_signal_handlers >= 0); + assert(config->use_hash_seed >= 0); + assert(config->faulthandler >= 0); + assert(config->tracemalloc >= 0); + assert(config->site_import >= 0); + assert(config->bytes_warning >= 0); + assert(config->inspect >= 0); + assert(config->interactive >= 0); + assert(config->optimization_level >= 0); + assert(config->parser_debug >= 0); + assert(config->write_bytecode >= 0); + assert(config->verbose >= 0); + assert(config->quiet >= 0); + assert(config->user_site_directory >= 0); + assert(config->buffered_stdio >= 0); + assert(config->program_name != NULL); + assert(config->program != NULL); + assert(_PyWstrList_CheckConsistency(&config->argv)); + assert(_PyWstrList_CheckConsistency(&config->xoptions)); + assert(_PyWstrList_CheckConsistency(&config->warnoptions)); + assert(_PyWstrList_CheckConsistency(&config->module_search_paths)); + if (config->_install_importlib) { + assert(config->executable != NULL); + assert(config->prefix != NULL); + assert(config->base_prefix != NULL); + assert(config->exec_prefix != NULL); + assert(config->base_exec_prefix != NULL); +#ifdef MS_WINDOWS + assert(config->dll_path != NULL); +#endif } + assert(config->filesystem_encoding != NULL); + assert(config->filesystem_errors != NULL); + assert(config->stdio_encoding != NULL); + assert(config->stdio_errors != NULL); +#ifdef MS_WINDOWS + assert(config->legacy_windows_stdio >= 0); +#endif + assert(config->_check_hash_pycs_mode != NULL); + assert(config->_install_importlib >= 0); + assert(config->_frozen >= 0); + err = _Py_INIT_OK(); done: cmdline_clear(&cmdline); + _PyPreCmdline_Clear(&precmdline); return err; } |