mirror of
https://github.com/python/cpython.git
synced 2025-09-26 18:29:57 +00:00
bpo-32030: Add _PyCoreConfig.argv (#4934)
* Add argc and argv to _PyCoreConfig * _PyMainInterpreterConfig_Read() now builds its argv from _PyCoreConfig.arg * Move _PyMain.env_warning_options into _Py_CommandLineDetails * Reorder pymain_free()
This commit is contained in:
parent
f4e21a2a72
commit
c4bca95106
3 changed files with 263 additions and 181 deletions
|
@ -61,7 +61,9 @@ PyAPI_FUNC(int) _PyCoreConfig_Copy(
|
||||||
_PyCoreConfig *config,
|
_PyCoreConfig *config,
|
||||||
const _PyCoreConfig *config2);
|
const _PyCoreConfig *config2);
|
||||||
|
|
||||||
PyAPI_FUNC(_PyInitError) _PyMainInterpreterConfig_Read(_PyMainInterpreterConfig *, _PyCoreConfig *);
|
PyAPI_FUNC(_PyInitError) _PyMainInterpreterConfig_Read(
|
||||||
|
_PyMainInterpreterConfig *config,
|
||||||
|
const _PyCoreConfig *core_config);
|
||||||
PyAPI_FUNC(void) _PyMainInterpreterConfig_Clear(_PyMainInterpreterConfig *);
|
PyAPI_FUNC(void) _PyMainInterpreterConfig_Clear(_PyMainInterpreterConfig *);
|
||||||
PyAPI_FUNC(int) _PyMainInterpreterConfig_Copy(
|
PyAPI_FUNC(int) _PyMainInterpreterConfig_Copy(
|
||||||
_PyMainInterpreterConfig *config,
|
_PyMainInterpreterConfig *config,
|
||||||
|
|
|
@ -47,10 +47,18 @@ typedef struct {
|
||||||
wchar_t *home; /* PYTHONHOME environment variable,
|
wchar_t *home; /* PYTHONHOME environment variable,
|
||||||
see also Py_SetPythonHome(). */
|
see also Py_SetPythonHome(). */
|
||||||
wchar_t *program_name; /* Program name, see also Py_GetProgramName() */
|
wchar_t *program_name; /* Program name, see also Py_GetProgramName() */
|
||||||
|
|
||||||
|
int argc; /* Number of command line arguments,
|
||||||
|
-1 means unset */
|
||||||
|
wchar_t **argv; /* sys.argv, ignored if argc is negative */
|
||||||
} _PyCoreConfig;
|
} _PyCoreConfig;
|
||||||
|
|
||||||
#define _PyCoreConfig_INIT \
|
#define _PyCoreConfig_INIT \
|
||||||
(_PyCoreConfig){.use_hash_seed = -1, .coerce_c_locale = -1, .utf8_mode = -1}
|
(_PyCoreConfig){ \
|
||||||
|
.use_hash_seed = -1, \
|
||||||
|
.coerce_c_locale = -1, \
|
||||||
|
.utf8_mode = -1, \
|
||||||
|
.argc = -1}
|
||||||
/* Note: _PyCoreConfig_INIT sets other fields to 0/NULL */
|
/* Note: _PyCoreConfig_INIT sets other fields to 0/NULL */
|
||||||
|
|
||||||
/* Placeholders while working on the new configuration API
|
/* Placeholders while working on the new configuration API
|
||||||
|
|
428
Modules/main.c
428
Modules/main.c
|
@ -229,7 +229,7 @@ error:
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
pymain_run_module(wchar_t *modname, int set_argv0)
|
pymain_run_module(const wchar_t *modname, int set_argv0)
|
||||||
{
|
{
|
||||||
PyObject *module, *runpy, *runmodule, *runargs, *result;
|
PyObject *module, *runpy, *runmodule, *runargs, *result;
|
||||||
runpy = PyImport_ImportModule("runpy");
|
runpy = PyImport_ImportModule("runpy");
|
||||||
|
@ -279,7 +279,7 @@ pymain_run_module(wchar_t *modname, int set_argv0)
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
pymain_get_importer(wchar_t *filename)
|
pymain_get_importer(const wchar_t *filename)
|
||||||
{
|
{
|
||||||
PyObject *sys_path0 = NULL, *importer;
|
PyObject *sys_path0 = NULL, *importer;
|
||||||
|
|
||||||
|
@ -384,9 +384,10 @@ typedef struct {
|
||||||
} _Py_OptList;
|
} _Py_OptList;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
wchar_t *filename; /* Trailing arg without -c or -m */
|
wchar_t **argv;
|
||||||
|
const wchar_t *filename; /* Trailing arg without -c or -m */
|
||||||
wchar_t *command; /* -c argument */
|
wchar_t *command; /* -c argument */
|
||||||
wchar_t *module; /* -m argument */
|
const wchar_t *module; /* -m argument */
|
||||||
_Py_OptList warning_options; /* -W options */
|
_Py_OptList warning_options; /* -W options */
|
||||||
int print_help; /* -h, -? options */
|
int print_help; /* -h, -? options */
|
||||||
int print_version; /* -V option */
|
int print_version; /* -V option */
|
||||||
|
@ -411,6 +412,7 @@ typedef struct {
|
||||||
int legacy_windows_stdio; /* Py_LegacyWindowsStdioFlag,
|
int legacy_windows_stdio; /* Py_LegacyWindowsStdioFlag,
|
||||||
PYTHONLEGACYWINDOWSSTDIO */
|
PYTHONLEGACYWINDOWSSTDIO */
|
||||||
#endif
|
#endif
|
||||||
|
_Py_OptList env_warning_options; /* PYTHONWARNINGS env var */
|
||||||
} _Py_CommandLineDetails;
|
} _Py_CommandLineDetails;
|
||||||
|
|
||||||
/* Structure used by Py_Main() to pass data to subfunctions */
|
/* Structure used by Py_Main() to pass data to subfunctions */
|
||||||
|
@ -429,16 +431,11 @@ typedef struct {
|
||||||
int run_code;
|
int run_code;
|
||||||
/* Error message if a function failed */
|
/* Error message if a function failed */
|
||||||
_PyInitError err;
|
_PyInitError err;
|
||||||
/* PYTHONWARNINGS env var */
|
|
||||||
_Py_OptList env_warning_options;
|
|
||||||
|
|
||||||
int argc;
|
int argc;
|
||||||
wchar_t **argv;
|
|
||||||
int use_bytes_argv;
|
int use_bytes_argv;
|
||||||
char **bytes_argv;
|
char **bytes_argv;
|
||||||
|
wchar_t **wchar_argv;
|
||||||
int sys_argc;
|
|
||||||
wchar_t **sys_argv;
|
|
||||||
} _PyMain;
|
} _PyMain;
|
||||||
|
|
||||||
/* .cmdline is initialized to zeros */
|
/* .cmdline is initialized to zeros */
|
||||||
|
@ -462,17 +459,95 @@ pymain_optlist_clear(_Py_OptList *list)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Free global variables which cannot be freed in Py_Finalize():
|
|
||||||
configuration options set before Py_Initialize() which should
|
|
||||||
remain valid after Py_Finalize(), since Py_Initialize()/Py_Finalize() can
|
|
||||||
be called multiple times.
|
|
||||||
|
|
||||||
Called with the current memory allocators. */
|
|
||||||
static void
|
static void
|
||||||
pymain_free_globals(_PyMain *pymain)
|
clear_argv(int argc, wchar_t **argv)
|
||||||
{
|
{
|
||||||
_PyPathConfig_Clear(&_Py_path_config);
|
for (int i=0; i < argc; i++) {
|
||||||
_PyImport_Fini2();
|
PyMem_RawFree(argv[i]);
|
||||||
|
}
|
||||||
|
PyMem_RawFree(argv);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
pymain_init_cmdline_argv(_PyMain *pymain)
|
||||||
|
{
|
||||||
|
assert(pymain->cmdline.argv == NULL);
|
||||||
|
|
||||||
|
if (!pymain->use_bytes_argv) {
|
||||||
|
pymain->cmdline.argv = pymain->wchar_argv;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* +1 for a the NULL terminator */
|
||||||
|
size_t size = sizeof(wchar_t*) * (pymain->argc + 1);
|
||||||
|
wchar_t** argv = (wchar_t **)PyMem_RawMalloc(size);
|
||||||
|
if (argv == NULL) {
|
||||||
|
pymain->err = _Py_INIT_NO_MEMORY();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < pymain->argc; i++) {
|
||||||
|
size_t len;
|
||||||
|
wchar_t *arg = Py_DecodeLocale(pymain->bytes_argv[i], &len);
|
||||||
|
if (arg == NULL) {
|
||||||
|
clear_argv(i, argv);
|
||||||
|
pymain->err = DECODE_LOCALE_ERR("command line arguments",
|
||||||
|
(Py_ssize_t)len);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
argv[i] = arg;
|
||||||
|
}
|
||||||
|
argv[pymain->argc] = NULL;
|
||||||
|
|
||||||
|
pymain->cmdline.argv = argv;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
pymain_clear_cmdline(_PyMain *pymain)
|
||||||
|
{
|
||||||
|
/* Clear orig_argv: pymain_init_python_core() uses a borrowed pointer
|
||||||
|
to pymain->argv */
|
||||||
|
orig_argc = 0;
|
||||||
|
orig_argv = NULL;
|
||||||
|
|
||||||
|
_Py_CommandLineDetails *cmdline = &pymain->cmdline;
|
||||||
|
pymain_optlist_clear(&cmdline->warning_options);
|
||||||
|
pymain_optlist_clear(&cmdline->xoptions);
|
||||||
|
PyMem_RawFree(cmdline->command);
|
||||||
|
cmdline->command = NULL;
|
||||||
|
pymain_optlist_clear(&cmdline->env_warning_options);
|
||||||
|
|
||||||
|
if (pymain->use_bytes_argv && cmdline->argv != NULL) {
|
||||||
|
clear_argv(pymain->argc, cmdline->argv);
|
||||||
|
}
|
||||||
|
cmdline->argv = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
pymain_clear_configs(_PyMain *pymain)
|
||||||
|
{
|
||||||
|
_PyMainInterpreterConfig_Clear(&pymain->config);
|
||||||
|
|
||||||
|
/* Clear core config with the memory allocator
|
||||||
|
used by pymain_read_conf() */
|
||||||
|
PyMemAllocatorEx old_alloc;
|
||||||
|
_PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
|
||||||
|
|
||||||
|
_PyCoreConfig_Clear(&pymain->core_config);
|
||||||
|
|
||||||
|
PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
pymain_free_python(_PyMain *pymain)
|
||||||
|
{
|
||||||
|
Py_CLEAR(pymain->main_importer_path);
|
||||||
|
_PyMainInterpreterConfig_Clear(&pymain->config);
|
||||||
|
|
||||||
#ifdef __INSURE__
|
#ifdef __INSURE__
|
||||||
/* Insure++ is a memory analysis tool that aids in discovering
|
/* Insure++ is a memory analysis tool that aids in discovering
|
||||||
|
@ -489,88 +564,33 @@ pymain_free_globals(_PyMain *pymain)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Clear argv allocated by pymain_decode_bytes_argv() */
|
|
||||||
static void
|
static void
|
||||||
pymain_clear_bytes_argv(_PyMain *pymain, int argc)
|
pymain_free_raw(_PyMain *pymain)
|
||||||
{
|
{
|
||||||
if (pymain->use_bytes_argv && pymain->argv != NULL) {
|
_PyImport_Fini2();
|
||||||
for (int i = 0; i < argc; i++) {
|
|
||||||
PyMem_RawFree(pymain->argv[i]);
|
|
||||||
}
|
|
||||||
PyMem_RawFree(pymain->argv);
|
|
||||||
pymain->argv = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
/* Free global variables which cannot be freed in Py_Finalize():
|
||||||
|
configuration options set before Py_Initialize() which should
|
||||||
|
remain valid after Py_Finalize(), since
|
||||||
|
Py_Initialize()-Py_Finalize() can be called multiple times. */
|
||||||
|
_PyPathConfig_Clear(&_Py_path_config);
|
||||||
|
|
||||||
static int
|
/* Force the allocator used by pymain_read_conf() */
|
||||||
pymain_decode_bytes_argv(_PyMain *pymain)
|
PyMemAllocatorEx old_alloc;
|
||||||
{
|
_PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
|
||||||
assert(pymain->argv == NULL);
|
|
||||||
|
|
||||||
/* +1 for a the NULL terminator */
|
|
||||||
size_t size = sizeof(wchar_t*) * (pymain->argc + 1);
|
|
||||||
pymain->argv = (wchar_t **)PyMem_RawMalloc(size);
|
|
||||||
if (pymain->argv == NULL) {
|
|
||||||
pymain->err = _Py_INIT_NO_MEMORY();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < pymain->argc; i++) {
|
|
||||||
size_t len;
|
|
||||||
pymain->argv[i] = Py_DecodeLocale(pymain->bytes_argv[i], &len);
|
|
||||||
if (pymain->argv[i] == NULL) {
|
|
||||||
pymain_clear_bytes_argv(pymain, i);
|
|
||||||
pymain->err = DECODE_LOCALE_ERR("command line arguments",
|
|
||||||
(Py_ssize_t)len);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pymain->argv[pymain->argc] = NULL;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void
|
|
||||||
pymain_clear_pymain(_PyMain *pymain)
|
|
||||||
{
|
|
||||||
_Py_CommandLineDetails *cmdline = &pymain->cmdline;
|
|
||||||
pymain_optlist_clear(&cmdline->warning_options);
|
|
||||||
pymain_optlist_clear(&cmdline->xoptions);
|
|
||||||
PyMem_RawFree(cmdline->command);
|
|
||||||
cmdline->command = NULL;
|
|
||||||
|
|
||||||
PyMem_RawFree(pymain->sys_argv);
|
|
||||||
pymain->sys_argv = NULL;
|
|
||||||
pymain_optlist_clear(&pymain->env_warning_options);
|
|
||||||
pymain_clear_bytes_argv(pymain, pymain->argc);
|
|
||||||
|
|
||||||
_PyCoreConfig_Clear(&pymain->core_config);
|
_PyCoreConfig_Clear(&pymain->core_config);
|
||||||
}
|
pymain_clear_cmdline(pymain);
|
||||||
|
|
||||||
|
PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
|
||||||
/* Clear Python ojects */
|
|
||||||
static void
|
|
||||||
pymain_clear_python(_PyMain *pymain)
|
|
||||||
{
|
|
||||||
Py_CLEAR(pymain->main_importer_path);
|
|
||||||
|
|
||||||
_PyMainInterpreterConfig_Clear(&pymain->config);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
pymain_free(_PyMain *pymain)
|
pymain_free(_PyMain *pymain)
|
||||||
{
|
{
|
||||||
/* Force the allocator used by pymain_read_conf() */
|
pymain_free_python(pymain);
|
||||||
PyMemAllocatorEx old_alloc;
|
pymain_free_raw(pymain);
|
||||||
_PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
|
|
||||||
|
|
||||||
pymain_clear_python(pymain);
|
|
||||||
pymain_clear_pymain(pymain);
|
|
||||||
pymain_free_globals(pymain);
|
|
||||||
|
|
||||||
PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -645,7 +665,7 @@ pymain_parse_cmdline_impl(_PyMain *pymain)
|
||||||
_PyOS_ResetGetOpt();
|
_PyOS_ResetGetOpt();
|
||||||
do {
|
do {
|
||||||
int longindex = -1;
|
int longindex = -1;
|
||||||
int c = _PyOS_GetOpt(pymain->argc, pymain->argv, PROGRAM_OPTS,
|
int c = _PyOS_GetOpt(pymain->argc, cmdline->argv, PROGRAM_OPTS,
|
||||||
longoptions, &longindex);
|
longoptions, &longindex);
|
||||||
if (c == EOF) {
|
if (c == EOF) {
|
||||||
break;
|
break;
|
||||||
|
@ -791,9 +811,9 @@ pymain_parse_cmdline_impl(_PyMain *pymain)
|
||||||
|
|
||||||
if (cmdline->command == NULL && cmdline->module == NULL
|
if (cmdline->command == NULL && cmdline->module == NULL
|
||||||
&& _PyOS_optind < pymain->argc
|
&& _PyOS_optind < pymain->argc
|
||||||
&& wcscmp(pymain->argv[_PyOS_optind], L"-") != 0)
|
&& wcscmp(cmdline->argv[_PyOS_optind], L"-") != 0)
|
||||||
{
|
{
|
||||||
cmdline->filename = pymain->argv[_PyOS_optind];
|
cmdline->filename = cmdline->argv[_PyOS_optind];
|
||||||
}
|
}
|
||||||
|
|
||||||
pymain->run_code = (cmdline->command != NULL || cmdline->filename != NULL
|
pymain->run_code = (cmdline->command != NULL || cmdline->filename != NULL
|
||||||
|
@ -947,7 +967,7 @@ pymain_init_warnoptions(_PyMain *pymain)
|
||||||
if (pymain_add_warning_dev_mode(warnoptions, &pymain->core_config) < 0) {
|
if (pymain_add_warning_dev_mode(warnoptions, &pymain->core_config) < 0) {
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
if (pymain_add_warnings_optlist(warnoptions, &pymain->env_warning_options) < 0) {
|
if (pymain_add_warnings_optlist(warnoptions, &pymain->cmdline.env_warning_options) < 0) {
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
if (pymain_add_warnings_optlist(warnoptions, &pymain->cmdline.warning_options) < 0) {
|
if (pymain_add_warnings_optlist(warnoptions, &pymain->cmdline.warning_options) < 0) {
|
||||||
|
@ -990,7 +1010,7 @@ pymain_warnings_envvar(_PyMain *pymain)
|
||||||
warning != NULL;
|
warning != NULL;
|
||||||
warning = wcstok_s(NULL, L",", &context)) {
|
warning = wcstok_s(NULL, L",", &context)) {
|
||||||
|
|
||||||
if (pymain_optlist_append(pymain, &pymain->env_warning_options,
|
if (pymain_optlist_append(pymain, &pymain->cmdline.env_warning_options,
|
||||||
warning) < 0) {
|
warning) < 0) {
|
||||||
PyMem_RawFree(buf);
|
PyMem_RawFree(buf);
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -1020,7 +1040,7 @@ pymain_warnings_envvar(_PyMain *pymain)
|
||||||
SET_DECODE_ERROR("PYTHONWARNINGS environment variable", len);
|
SET_DECODE_ERROR("PYTHONWARNINGS environment variable", len);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (pymain_optlist_append(pymain, &pymain->env_warning_options,
|
if (pymain_optlist_append(pymain, &pymain->cmdline.env_warning_options,
|
||||||
warning) < 0) {
|
warning) < 0) {
|
||||||
PyMem_RawFree(warning);
|
PyMem_RawFree(warning);
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -1142,7 +1162,7 @@ pymain_get_program_name(_PyMain *pymain)
|
||||||
{
|
{
|
||||||
if (pymain->core_config.program_name == NULL) {
|
if (pymain->core_config.program_name == NULL) {
|
||||||
/* Use argv[0] by default */
|
/* Use argv[0] by default */
|
||||||
pymain->core_config.program_name = pymain_wstrdup(pymain, pymain->argv[0]);
|
pymain->core_config.program_name = pymain_wstrdup(pymain, pymain->cmdline.argv[0]);
|
||||||
if (pymain->core_config.program_name == NULL) {
|
if (pymain->core_config.program_name == NULL) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -1170,18 +1190,86 @@ pymain_header(_PyMain *pymain)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int
|
static wchar_t**
|
||||||
pymain_init_argv(_PyMain *pymain)
|
copy_argv(int argc, wchar_t **argv)
|
||||||
{
|
{
|
||||||
int argc = pymain->sys_argc;
|
assert(argc >= 0 && argv != NULL);
|
||||||
wchar_t** argv = pymain->sys_argv;
|
size_t size = argc * sizeof(argv[0]);
|
||||||
|
wchar_t **argv_copy = PyMem_RawMalloc(size);
|
||||||
|
for (int i=0; i < argc; i++) {
|
||||||
|
wchar_t* arg = _PyMem_RawWcsdup(argv[i]);
|
||||||
|
if (arg == NULL) {
|
||||||
|
clear_argv(i, argv);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
argv_copy[i] = arg;
|
||||||
|
}
|
||||||
|
return argv_copy;
|
||||||
|
}
|
||||||
|
|
||||||
if (argc <= 0 || pymain->sys_argv == NULL) {
|
|
||||||
|
static int
|
||||||
|
pymain_init_core_argv(_PyMain *pymain)
|
||||||
|
{
|
||||||
|
_Py_CommandLineDetails *cmdline = &pymain->cmdline;
|
||||||
|
|
||||||
|
/* Copy argv to be able to modify it (to force -c/-m) */
|
||||||
|
int argc = pymain->argc - _PyOS_optind;
|
||||||
|
wchar_t **argv;
|
||||||
|
|
||||||
|
if (argc <= 0 || cmdline->argv == NULL) {
|
||||||
/* Ensure at least one (empty) argument is seen */
|
/* Ensure at least one (empty) argument is seen */
|
||||||
static wchar_t *empty_argv[1] = {L""};
|
static wchar_t *empty_argv[1] = {L""};
|
||||||
argv = empty_argv;
|
|
||||||
argc = 1;
|
argc = 1;
|
||||||
|
argv = copy_argv(1, empty_argv);
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
argv = copy_argv(argc, &cmdline->argv[_PyOS_optind]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (argv == NULL) {
|
||||||
|
pymain->err = _Py_INIT_NO_MEMORY();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
wchar_t *arg0 = NULL;
|
||||||
|
if (cmdline->command != NULL) {
|
||||||
|
/* Force sys.argv[0] = '-c' */
|
||||||
|
arg0 = L"-c";
|
||||||
|
}
|
||||||
|
else if (cmdline->module != NULL) {
|
||||||
|
/* Force sys.argv[0] = '-m'*/
|
||||||
|
arg0 = L"-m";
|
||||||
|
}
|
||||||
|
if (arg0 != NULL) {
|
||||||
|
arg0 = _PyMem_RawWcsdup(arg0);
|
||||||
|
if (arg0 == NULL) {
|
||||||
|
clear_argv(argc, argv);
|
||||||
|
pymain->err = _Py_INIT_NO_MEMORY();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
PyMem_RawFree(argv[0]);
|
||||||
|
argv[0] = arg0;
|
||||||
|
}
|
||||||
|
|
||||||
|
pymain->core_config.argc = argc;
|
||||||
|
pymain->core_config.argv = argv;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
config_init_argv(_PyMainInterpreterConfig *config, const _PyCoreConfig *core_config)
|
||||||
|
{
|
||||||
|
assert(config->argv == NULL);
|
||||||
|
|
||||||
|
if (core_config->argc < 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int argc = core_config->argc;
|
||||||
|
wchar_t** argv = core_config->argv;
|
||||||
|
assert(argc >= 1 && argv != NULL);
|
||||||
|
|
||||||
PyObject *list = PyList_New(argc);
|
PyObject *list = PyList_New(argc);
|
||||||
if (list == NULL) {
|
if (list == NULL) {
|
||||||
|
@ -1197,39 +1285,7 @@ pymain_init_argv(_PyMain *pymain)
|
||||||
PyList_SET_ITEM(list, i, v);
|
PyList_SET_ITEM(list, i, v);
|
||||||
}
|
}
|
||||||
|
|
||||||
pymain->config.argv = list;
|
config->argv = list;
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static int
|
|
||||||
pymain_init_sys_argv(_PyMain *pymain)
|
|
||||||
{
|
|
||||||
_Py_CommandLineDetails *cmdline = &pymain->cmdline;
|
|
||||||
|
|
||||||
if (cmdline->command != NULL || cmdline->module != NULL) {
|
|
||||||
/* Backup _PyOS_optind */
|
|
||||||
_PyOS_optind--;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Copy argv to be able to modify it (to force -c/-m) */
|
|
||||||
pymain->sys_argc = pymain->argc - _PyOS_optind;
|
|
||||||
size_t size = pymain->sys_argc * sizeof(pymain->argv[0]);
|
|
||||||
pymain->sys_argv = PyMem_RawMalloc(size);
|
|
||||||
if (pymain->sys_argv == NULL) {
|
|
||||||
pymain->err = _Py_INIT_NO_MEMORY();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
memcpy(pymain->sys_argv, &pymain->argv[_PyOS_optind], size);
|
|
||||||
|
|
||||||
if (cmdline->command != NULL) {
|
|
||||||
/* Force sys.argv[0] = '-c' */
|
|
||||||
pymain->sys_argv[0] = L"-c";
|
|
||||||
}
|
|
||||||
else if (cmdline->module != NULL) {
|
|
||||||
/* Force sys.argv[0] = '-m'*/
|
|
||||||
pymain->sys_argv[0] = L"-m";
|
|
||||||
}
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1254,7 +1310,7 @@ pymain_update_sys_path(_PyMain *pymain)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
PyObject *path0 = _PyPathConfig_ComputeArgv0(pymain->sys_argc, pymain->sys_argv);
|
PyObject *path0 = _PyPathConfig_ComputeArgv0(pymain->core_config.argc, pymain->core_config.argv);
|
||||||
if (path0 == NULL) {
|
if (path0 == NULL) {
|
||||||
pymain->err = _Py_INIT_NO_MEMORY();
|
pymain->err = _Py_INIT_NO_MEMORY();
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -1374,7 +1430,7 @@ pymain_open_filename(_PyMain *pymain)
|
||||||
else
|
else
|
||||||
cfilename = "<unprintable file name>";
|
cfilename = "<unprintable file name>";
|
||||||
fprintf(stderr, "%ls: can't open file '%s': [Errno %d] %s\n",
|
fprintf(stderr, "%ls: can't open file '%s': [Errno %d] %s\n",
|
||||||
pymain->argv[0], cfilename, err, strerror(err));
|
cmdline->argv[0], cfilename, err, strerror(err));
|
||||||
PyMem_Free(cfilename_buffer);
|
PyMem_Free(cfilename_buffer);
|
||||||
pymain->status = 2;
|
pymain->status = 2;
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -1397,7 +1453,7 @@ pymain_open_filename(_PyMain *pymain)
|
||||||
S_ISDIR(sb.st_mode)) {
|
S_ISDIR(sb.st_mode)) {
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"%ls: '%ls' is a directory, cannot continue\n",
|
"%ls: '%ls' is a directory, cannot continue\n",
|
||||||
pymain->argv[0], cmdline->filename);
|
cmdline->argv[0], cmdline->filename);
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
pymain->status = 1;
|
pymain->status = 1;
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -1474,11 +1530,16 @@ pymain_parse_cmdline(_PyMain *pymain)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (res) {
|
if (res) {
|
||||||
pymain_usage(1, pymain->argv[0]);
|
pymain_usage(1, pymain->cmdline.argv[0]);
|
||||||
pymain->status = 2;
|
pymain->status = 2;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (pymain->cmdline.command != NULL || pymain->cmdline.module != NULL) {
|
||||||
|
/* Backup _PyOS_optind */
|
||||||
|
_PyOS_optind--;
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1912,7 +1973,7 @@ pymain_read_conf_impl(_PyMain *pymain)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pymain_init_sys_argv(pymain) < 0) {
|
if (pymain_init_core_argv(pymain) < 0) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1960,11 +2021,9 @@ pymain_read_conf(_PyMain *pymain)
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pymain->use_bytes_argv) {
|
if (pymain_init_cmdline_argv(pymain) < 0) {
|
||||||
if (pymain_decode_bytes_argv(pymain) < 0) {
|
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
res = pymain_read_conf_impl(pymain);
|
res = pymain_read_conf_impl(pymain);
|
||||||
if (res != 0) {
|
if (res != 0) {
|
||||||
|
@ -2008,7 +2067,8 @@ pymain_read_conf(_PyMain *pymain)
|
||||||
pymain_read_conf_impl(). */
|
pymain_read_conf_impl(). */
|
||||||
Py_UTF8Mode = pymain->core_config.utf8_mode;
|
Py_UTF8Mode = pymain->core_config.utf8_mode;
|
||||||
Py_IgnoreEnvironmentFlag = init_ignore_env;
|
Py_IgnoreEnvironmentFlag = init_ignore_env;
|
||||||
pymain_clear_pymain(pymain);
|
_PyCoreConfig_Clear(&pymain->core_config);
|
||||||
|
pymain_clear_cmdline(pymain);
|
||||||
pymain_get_global_config(pymain);
|
pymain_get_global_config(pymain);
|
||||||
|
|
||||||
/* The encoding changed: read again the configuration
|
/* The encoding changed: read again the configuration
|
||||||
|
@ -2089,6 +2149,12 @@ _PyCoreConfig_Clear(_PyCoreConfig *config)
|
||||||
CLEAR(config->home);
|
CLEAR(config->home);
|
||||||
CLEAR(config->program_name);
|
CLEAR(config->program_name);
|
||||||
#undef CLEAR
|
#undef CLEAR
|
||||||
|
|
||||||
|
if (config->argc >= 0) {
|
||||||
|
clear_argv(config->argc, config->argv);
|
||||||
|
config->argc = -1;
|
||||||
|
config->argv = NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -2098,6 +2164,16 @@ _PyCoreConfig_Copy(_PyCoreConfig *config, const _PyCoreConfig *config2)
|
||||||
_PyCoreConfig_Clear(config);
|
_PyCoreConfig_Clear(config);
|
||||||
|
|
||||||
#define COPY_ATTR(ATTR) config->ATTR = config2->ATTR
|
#define COPY_ATTR(ATTR) config->ATTR = config2->ATTR
|
||||||
|
#define COPY_STR_ATTR(ATTR) \
|
||||||
|
do { \
|
||||||
|
if (config2->ATTR != NULL) { \
|
||||||
|
config->ATTR = _PyMem_RawWcsdup(config2->ATTR); \
|
||||||
|
if (config->ATTR == NULL) { \
|
||||||
|
return -1; \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
COPY_ATTR(ignore_environment);
|
COPY_ATTR(ignore_environment);
|
||||||
COPY_ATTR(use_hash_seed);
|
COPY_ATTR(use_hash_seed);
|
||||||
COPY_ATTR(hash_seed);
|
COPY_ATTR(hash_seed);
|
||||||
|
@ -2112,21 +2188,21 @@ _PyCoreConfig_Copy(_PyCoreConfig *config, const _PyCoreConfig *config2)
|
||||||
COPY_ATTR(dump_refs);
|
COPY_ATTR(dump_refs);
|
||||||
COPY_ATTR(malloc_stats);
|
COPY_ATTR(malloc_stats);
|
||||||
COPY_ATTR(utf8_mode);
|
COPY_ATTR(utf8_mode);
|
||||||
#undef COPY_ATTR
|
|
||||||
|
|
||||||
#define COPY_STR_ATTR(ATTR) \
|
|
||||||
do { \
|
|
||||||
if (config2->ATTR != NULL) { \
|
|
||||||
config->ATTR = _PyMem_RawWcsdup(config2->ATTR); \
|
|
||||||
if (config->ATTR == NULL) { \
|
|
||||||
return -1; \
|
|
||||||
} \
|
|
||||||
} \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
COPY_STR_ATTR(module_search_path_env);
|
COPY_STR_ATTR(module_search_path_env);
|
||||||
COPY_STR_ATTR(home);
|
COPY_STR_ATTR(home);
|
||||||
COPY_STR_ATTR(program_name);
|
COPY_STR_ATTR(program_name);
|
||||||
|
|
||||||
|
if (config2->argc >= 0) {
|
||||||
|
wchar_t **argv = copy_argv(config2->argc, config2->argv);
|
||||||
|
if (argv == NULL) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
config->argv = argv;
|
||||||
|
}
|
||||||
|
COPY_ATTR(argc);
|
||||||
|
|
||||||
|
#undef COPY_ATTR
|
||||||
#undef COPY_STR_ATTR
|
#undef COPY_STR_ATTR
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -2241,13 +2317,17 @@ config_create_path_list(const wchar_t *path, wchar_t delim)
|
||||||
|
|
||||||
|
|
||||||
_PyInitError
|
_PyInitError
|
||||||
_PyMainInterpreterConfig_Read(_PyMainInterpreterConfig *config, _PyCoreConfig *core_config)
|
_PyMainInterpreterConfig_Read(_PyMainInterpreterConfig *config, const _PyCoreConfig *core_config)
|
||||||
{
|
{
|
||||||
_PyInitError err = _PyPathConfig_Init(core_config);
|
_PyInitError err = _PyPathConfig_Init(core_config);
|
||||||
if (_Py_INIT_FAILED(err)) {
|
if (_Py_INIT_FAILED(err)) {
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (config_init_argv(config, core_config) < 0) {
|
||||||
|
return _Py_INIT_ERR("failed to create sys.argv");
|
||||||
|
}
|
||||||
|
|
||||||
/* Signal handlers are installed by default */
|
/* Signal handlers are installed by default */
|
||||||
if (config->install_signal_handlers < 0) {
|
if (config->install_signal_handlers < 0) {
|
||||||
config->install_signal_handlers = 1;
|
config->install_signal_handlers = 1;
|
||||||
|
@ -2324,10 +2404,6 @@ pymain_init_python_main(_PyMain *pymain)
|
||||||
pymain->err = _Py_INIT_NO_MEMORY();
|
pymain->err = _Py_INIT_NO_MEMORY();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (pymain_init_argv(pymain) < 0) {
|
|
||||||
pymain->err = _Py_INIT_ERR("failed to create sys.argv");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
_PyInitError err = _PyMainInterpreterConfig_Read(&pymain->config,
|
_PyInitError err = _PyMainInterpreterConfig_Read(&pymain->config,
|
||||||
&pymain->core_config);
|
&pymain->core_config);
|
||||||
|
@ -2378,9 +2454,11 @@ pymain_run_python(_PyMain *pymain)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int
|
static void
|
||||||
pymain_init(_PyMain *pymain)
|
pymain_init(_PyMain *pymain)
|
||||||
{
|
{
|
||||||
|
memset(&pymain->cmdline, 0, sizeof(pymain->cmdline));
|
||||||
|
|
||||||
/* 754 requires that FP exceptions run in "no stop" mode by default,
|
/* 754 requires that FP exceptions run in "no stop" mode by default,
|
||||||
* and until C vendors implement C99's ways to control FP exceptions,
|
* and until C vendors implement C99's ways to control FP exceptions,
|
||||||
* Python requires non-stop mode. Alas, some platforms enable FP
|
* Python requires non-stop mode. Alas, some platforms enable FP
|
||||||
|
@ -2390,23 +2468,18 @@ pymain_init(_PyMain *pymain)
|
||||||
fedisableexcept(FE_OVERFLOW);
|
fedisableexcept(FE_OVERFLOW);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
pymain->err = _PyRuntime_Initialize();
|
|
||||||
if (_Py_INIT_FAILED(pymain->err)) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
pymain->core_config._disable_importlib = 0;
|
pymain->core_config._disable_importlib = 0;
|
||||||
pymain->config.install_signal_handlers = 1;
|
pymain->config.install_signal_handlers = 1;
|
||||||
|
|
||||||
pymain_get_global_config(pymain);
|
pymain_get_global_config(pymain);
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
pymain_impl(_PyMain *pymain)
|
pymain_impl(_PyMain *pymain)
|
||||||
{
|
{
|
||||||
if (pymain_init(pymain) < 0) {
|
pymain->err = _PyRuntime_Initialize();
|
||||||
|
if (_Py_INIT_FAILED(pymain->err)) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2423,7 +2496,7 @@ pymain_impl(_PyMain *pymain)
|
||||||
|
|
||||||
_Py_CommandLineDetails *cmdline = &pymain->cmdline;
|
_Py_CommandLineDetails *cmdline = &pymain->cmdline;
|
||||||
if (cmdline->print_help) {
|
if (cmdline->print_help) {
|
||||||
pymain_usage(0, pymain->argv[0]);
|
pymain_usage(0, cmdline->argv[0]);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2433,8 +2506,9 @@ pymain_impl(_PyMain *pymain)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
orig_argc = pymain->argc; /* For Py_GetArgcArgv() */
|
/* For Py_GetArgcArgv(). Cleared by pymain_free(). */
|
||||||
orig_argv = pymain->argv;
|
orig_argc = pymain->argc;
|
||||||
|
orig_argv = cmdline->argv;
|
||||||
|
|
||||||
res = pymain_init_python_core(pymain);
|
res = pymain_init_python_core(pymain);
|
||||||
if (res < 0) {
|
if (res < 0) {
|
||||||
|
@ -2446,9 +2520,9 @@ pymain_impl(_PyMain *pymain)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
pymain_run_python(pymain);
|
pymain_clear_configs(pymain);
|
||||||
|
|
||||||
pymain_clear_python(pymain);
|
pymain_run_python(pymain);
|
||||||
|
|
||||||
if (Py_FinalizeEx() < 0) {
|
if (Py_FinalizeEx() < 0) {
|
||||||
/* Value unlikely to be confused with a non-error exit status or
|
/* Value unlikely to be confused with a non-error exit status or
|
||||||
|
@ -2462,16 +2536,13 @@ pymain_impl(_PyMain *pymain)
|
||||||
static int
|
static int
|
||||||
pymain_main(_PyMain *pymain)
|
pymain_main(_PyMain *pymain)
|
||||||
{
|
{
|
||||||
memset(&pymain->cmdline, 0, sizeof(pymain->cmdline));
|
pymain_init(pymain);
|
||||||
|
|
||||||
if (pymain_impl(pymain) < 0) {
|
if (pymain_impl(pymain) < 0) {
|
||||||
_Py_FatalInitError(pymain->err);
|
_Py_FatalInitError(pymain->err);
|
||||||
}
|
}
|
||||||
pymain_free(pymain);
|
pymain_free(pymain);
|
||||||
|
|
||||||
orig_argc = 0;
|
|
||||||
orig_argv = NULL;
|
|
||||||
|
|
||||||
return pymain->status;
|
return pymain->status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2480,8 +2551,9 @@ int
|
||||||
Py_Main(int argc, wchar_t **argv)
|
Py_Main(int argc, wchar_t **argv)
|
||||||
{
|
{
|
||||||
_PyMain pymain = _PyMain_INIT;
|
_PyMain pymain = _PyMain_INIT;
|
||||||
|
pymain.use_bytes_argv = 0;
|
||||||
pymain.argc = argc;
|
pymain.argc = argc;
|
||||||
pymain.argv = argv;
|
pymain.wchar_argv = argv;
|
||||||
|
|
||||||
return pymain_main(&pymain);
|
return pymain_main(&pymain);
|
||||||
}
|
}
|
||||||
|
@ -2491,8 +2563,8 @@ int
|
||||||
_Py_UnixMain(int argc, char **argv)
|
_Py_UnixMain(int argc, char **argv)
|
||||||
{
|
{
|
||||||
_PyMain pymain = _PyMain_INIT;
|
_PyMain pymain = _PyMain_INIT;
|
||||||
pymain.argc = argc;
|
|
||||||
pymain.use_bytes_argv = 1;
|
pymain.use_bytes_argv = 1;
|
||||||
|
pymain.argc = argc;
|
||||||
pymain.bytes_argv = argv;
|
pymain.bytes_argv = argv;
|
||||||
|
|
||||||
return pymain_main(&pymain);
|
return pymain_main(&pymain);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue