Unverified Kaydet (Commit) fa153768 authored tarafından Victor Stinner's avatar Victor Stinner Kaydeden (comit) GitHub

bpo-36301: Add _PyPreCmdline internal API (GH-12458)

_PyCoreConfig_ReadFromArgv() now reuses the code parsing command line
options from preconfig.c.
üst abbdd1fc
...@@ -9,6 +9,30 @@ extern "C" { ...@@ -9,6 +9,30 @@ extern "C" {
#endif #endif
/* --- _PyPreCmdline ------------------------------------------------- */
typedef struct {
_PyWstrList argv;
_PyWstrList xoptions; /* "-X value" option */
int use_environment; /* -E option */
int isolated; /* -I option */
} _PyPreCmdline;
#define _PyPreCmdline_INIT \
(_PyPreCmdline){ \
.use_environment = -1, \
.isolated = -1}
/* Note: _PyPreCmdline_INIT sets other fields to 0/NULL */
PyAPI_FUNC(void) _PyPreCmdline_Clear(_PyPreCmdline *cmdline);
PyAPI_FUNC(_PyInitError) _PyPreCmdline_Init(_PyPreCmdline *cmdline,
const _PyArgv *args);
PyAPI_FUNC(_PyInitError) _PyPreCmdline_Read(_PyPreCmdline *cmdline);
PyAPI_FUNC(void) _PyPreCmdline_SetPreConfig(
const _PyPreCmdline *cmdline,
_PyPreConfig *config);
/* --- _PyWstrList ------------------------------------------------ */ /* --- _PyWstrList ------------------------------------------------ */
#ifndef NDEBUG #ifndef NDEBUG
......
...@@ -1658,7 +1658,7 @@ fail: ...@@ -1658,7 +1658,7 @@ fail:
/* --- _PyCmdline ------------------------------------------------- */ /* --- _PyCmdline ------------------------------------------------- */
typedef struct { typedef struct {
_PyWstrList argv; _PyPreCmdline precmdline;
_PyWstrList warnoptions; /* Command line -W options */ _PyWstrList warnoptions; /* Command line -W options */
_PyWstrList env_warnoptions; /* PYTHONWARNINGS environment variables */ _PyWstrList env_warnoptions; /* PYTHONWARNINGS environment variables */
int print_help; /* -h, -? options */ int print_help; /* -h, -? options */
...@@ -1669,9 +1669,9 @@ typedef struct { ...@@ -1669,9 +1669,9 @@ typedef struct {
static void static void
cmdline_clear(_PyCmdline *cmdline) cmdline_clear(_PyCmdline *cmdline)
{ {
_PyPreCmdline_Clear(&cmdline->precmdline);
_PyWstrList_Clear(&cmdline->warnoptions); _PyWstrList_Clear(&cmdline->warnoptions);
_PyWstrList_Clear(&cmdline->env_warnoptions); _PyWstrList_Clear(&cmdline->env_warnoptions);
_PyWstrList_Clear(&cmdline->argv);
} }
...@@ -1682,10 +1682,12 @@ static _PyInitError ...@@ -1682,10 +1682,12 @@ static _PyInitError
config_parse_cmdline(_PyCoreConfig *config, _PyCmdline *cmdline, config_parse_cmdline(_PyCoreConfig *config, _PyCmdline *cmdline,
int *need_usage) int *need_usage)
{ {
const _PyWstrList *argv = &cmdline->precmdline.argv;
_PyOS_ResetGetOpt(); _PyOS_ResetGetOpt();
do { do {
int longindex = -1; int longindex = -1;
int c = _PyOS_GetOpt(cmdline->argv.length, cmdline->argv.items, &longindex); int c = _PyOS_GetOpt(argv->length, argv->items, &longindex);
if (c == EOF) { if (c == EOF) {
break; break;
} }
...@@ -1754,6 +1756,7 @@ config_parse_cmdline(_PyCoreConfig *config, _PyCmdline *cmdline, ...@@ -1754,6 +1756,7 @@ config_parse_cmdline(_PyCoreConfig *config, _PyCmdline *cmdline,
case 'E': case 'E':
case 'I': case 'I':
case 'X':
/* option handled by _PyPreConfig_ReadFromArgv() */ /* option handled by _PyPreConfig_ReadFromArgv() */
break; break;
...@@ -1806,12 +1809,6 @@ config_parse_cmdline(_PyCoreConfig *config, _PyCmdline *cmdline, ...@@ -1806,12 +1809,6 @@ config_parse_cmdline(_PyCoreConfig *config, _PyCmdline *cmdline,
} }
break; break;
case 'X':
if (_PyWstrList_Append(&config->xoptions, _PyOS_optarg) < 0) {
return _Py_INIT_NO_MEMORY();
}
break;
case 'q': case 'q':
config->quiet++; config->quiet++;
break; break;
...@@ -1830,11 +1827,11 @@ config_parse_cmdline(_PyCoreConfig *config, _PyCmdline *cmdline, ...@@ -1830,11 +1827,11 @@ config_parse_cmdline(_PyCoreConfig *config, _PyCmdline *cmdline,
} while (1); } while (1);
if (config->run_command == NULL && config->run_module == NULL if (config->run_command == NULL && config->run_module == NULL
&& _PyOS_optind < cmdline->argv.length && _PyOS_optind < argv->length
&& wcscmp(cmdline->argv.items[_PyOS_optind], L"-") != 0 && wcscmp(argv->items[_PyOS_optind], L"-") != 0
&& config->run_filename == NULL) && config->run_filename == NULL)
{ {
config->run_filename = _PyMem_RawWcsdup(cmdline->argv.items[_PyOS_optind]); config->run_filename = _PyMem_RawWcsdup(argv->items[_PyOS_optind]);
if (config->run_filename == NULL) { if (config->run_filename == NULL) {
return _Py_INIT_NO_MEMORY(); return _Py_INIT_NO_MEMORY();
} }
...@@ -1892,9 +1889,10 @@ cmdline_init_env_warnoptions(_PyCmdline *cmdline, const _PyCoreConfig *config) ...@@ -1892,9 +1889,10 @@ cmdline_init_env_warnoptions(_PyCmdline *cmdline, const _PyCoreConfig *config)
static _PyInitError static _PyInitError
config_init_program(_PyCoreConfig *config, const _PyCmdline *cmdline) config_init_program(_PyCoreConfig *config, const _PyCmdline *cmdline)
{ {
const _PyWstrList *argv = &cmdline->precmdline.argv;
wchar_t *program; wchar_t *program;
if (cmdline->argv.length >= 1) { if (argv->length >= 1) {
program = cmdline->argv.items[0]; program = argv->items[0];
} }
else { else {
program = L""; program = L"";
...@@ -1965,24 +1963,25 @@ config_init_warnoptions(_PyCoreConfig *config, const _PyCmdline *cmdline) ...@@ -1965,24 +1963,25 @@ config_init_warnoptions(_PyCoreConfig *config, const _PyCmdline *cmdline)
static _PyInitError static _PyInitError
config_init_argv(_PyCoreConfig *config, const _PyCmdline *cmdline) config_init_argv(_PyCoreConfig *config, const _PyCmdline *cmdline)
{ {
_PyWstrList wargv = _PyWstrList_INIT; const _PyWstrList *cmdline_argv = &cmdline->precmdline.argv;
_PyWstrList config_argv = _PyWstrList_INIT;
/* Copy argv to be able to modify it (to force -c/-m) */ /* Copy argv to be able to modify it (to force -c/-m) */
if (cmdline->argv.length <= _PyOS_optind) { if (cmdline_argv->length <= _PyOS_optind) {
/* Ensure at least one (empty) argument is seen */ /* Ensure at least one (empty) argument is seen */
if (_PyWstrList_Append(&wargv, L"") < 0) { if (_PyWstrList_Append(&config_argv, L"") < 0) {
return _Py_INIT_NO_MEMORY(); return _Py_INIT_NO_MEMORY();
} }
} }
else { else {
_PyWstrList slice; _PyWstrList slice;
slice.length = cmdline->argv.length - _PyOS_optind; slice.length = cmdline_argv->length - _PyOS_optind;
slice.items = &cmdline->argv.items[_PyOS_optind]; slice.items = &cmdline_argv->items[_PyOS_optind];
if (_PyWstrList_Copy(&wargv, &slice) < 0) { if (_PyWstrList_Copy(&config_argv, &slice) < 0) {
return _Py_INIT_NO_MEMORY(); return _Py_INIT_NO_MEMORY();
} }
} }
assert(wargv.length >= 1); assert(config_argv.length >= 1);
wchar_t *arg0 = NULL; wchar_t *arg0 = NULL;
if (config->run_command != NULL) { if (config->run_command != NULL) {
...@@ -1996,16 +1995,16 @@ config_init_argv(_PyCoreConfig *config, const _PyCmdline *cmdline) ...@@ -1996,16 +1995,16 @@ config_init_argv(_PyCoreConfig *config, const _PyCmdline *cmdline)
if (arg0 != NULL) { if (arg0 != NULL) {
arg0 = _PyMem_RawWcsdup(arg0); arg0 = _PyMem_RawWcsdup(arg0);
if (arg0 == NULL) { if (arg0 == NULL) {
_PyWstrList_Clear(&wargv); _PyWstrList_Clear(&config_argv);
return _Py_INIT_NO_MEMORY(); return _Py_INIT_NO_MEMORY();
} }
PyMem_RawFree(wargv.items[0]); PyMem_RawFree(config_argv.items[0]);
wargv.items[0] = arg0; config_argv.items[0] = arg0;
} }
_PyWstrList_Clear(&config->argv); _PyWstrList_Clear(&config->argv);
config->argv = wargv; config->argv = config_argv;
return _Py_INIT_OK(); return _Py_INIT_OK();
} }
...@@ -2046,6 +2045,16 @@ config_from_cmdline(_PyCoreConfig *config, _PyCmdline *cmdline, ...@@ -2046,6 +2045,16 @@ config_from_cmdline(_PyCoreConfig *config, _PyCmdline *cmdline,
} }
} }
err = _PyPreCmdline_Read(&cmdline->precmdline);
if (_Py_INIT_FAILED(err)) {
return err;
}
_PyPreCmdline_SetPreConfig(&cmdline->precmdline, &config->preconfig);
if (_PyWstrList_Extend(&config->xoptions, &cmdline->precmdline.xoptions) < 0) {
return _Py_INIT_NO_MEMORY();
}
err = config_parse_cmdline(config, cmdline, &need_usage); err = config_parse_cmdline(config, cmdline, &need_usage);
if (_Py_INIT_FAILED(err)) { if (_Py_INIT_FAILED(err)) {
return err; return err;
...@@ -2089,7 +2098,8 @@ config_from_cmdline(_PyCoreConfig *config, _PyCmdline *cmdline, ...@@ -2089,7 +2098,8 @@ config_from_cmdline(_PyCoreConfig *config, _PyCmdline *cmdline,
return err; return err;
} }
if (_Py_SetArgcArgv(cmdline->argv.length, cmdline->argv.items) < 0) { const _PyWstrList *argv = &cmdline->precmdline.argv;
if (_Py_SetArgcArgv(argv->length, argv->items) < 0) {
return _Py_INIT_NO_MEMORY(); return _Py_INIT_NO_MEMORY();
} }
return _Py_INIT_OK(); return _Py_INIT_OK();
...@@ -2107,10 +2117,9 @@ _PyCoreConfig_ReadFromArgv(_PyCoreConfig *config, const _PyArgv *args, ...@@ -2107,10 +2117,9 @@ _PyCoreConfig_ReadFromArgv(_PyCoreConfig *config, const _PyArgv *args,
{ {
_PyInitError err; _PyInitError err;
_PyCmdline cmdline; _PyCmdline cmdline = {.precmdline = _PyPreCmdline_INIT};
memset(&cmdline, 0, sizeof(cmdline));
err = _PyArgv_AsWstrList(args, &cmdline.argv); err = _PyPreCmdline_Init(&cmdline.precmdline, args);
if (_Py_INIT_FAILED(err)) { if (_Py_INIT_FAILED(err)) {
goto done; goto done;
} }
......
...@@ -102,20 +102,21 @@ _PyArgv_AsWstrList(const _PyArgv *args, _PyWstrList *list) ...@@ -102,20 +102,21 @@ _PyArgv_AsWstrList(const _PyArgv *args, _PyWstrList *list)
/* --- _PyPreCmdline ------------------------------------------------- */ /* --- _PyPreCmdline ------------------------------------------------- */
typedef struct { void
_PyWstrList argv; _PyPreCmdline_Clear(_PyPreCmdline *cmdline)
_PyWstrList xoptions; /* -X options */
} _PyPreCmdline;
static void
precmdline_clear(_PyPreCmdline *cmdline)
{ {
_PyWstrList_Clear(&cmdline->argv); _PyWstrList_Clear(&cmdline->argv);
_PyWstrList_Clear(&cmdline->xoptions); _PyWstrList_Clear(&cmdline->xoptions);
} }
_PyInitError
_PyPreCmdline_Init(_PyPreCmdline *cmdline, const _PyArgv *args)
{
return _PyArgv_AsWstrList(args, &cmdline->argv);
}
/* --- _PyPreConfig ----------------------------------------------- */ /* --- _PyPreConfig ----------------------------------------------- */
void void
...@@ -520,6 +521,21 @@ _PyPreConfig_Read(_PyPreConfig *config) ...@@ -520,6 +521,21 @@ _PyPreConfig_Read(_PyPreConfig *config)
} }
void
_PyPreCmdline_SetPreConfig(const _PyPreCmdline *cmdline, _PyPreConfig *config)
{
#define COPY_ATTR(ATTR) \
if (cmdline->ATTR != -1) { \
config->ATTR = cmdline->ATTR; \
}
COPY_ATTR(use_environment);
COPY_ATTR(isolated);
#undef COPY_ATTR
}
int int
_PyPreConfig_AsDict(const _PyPreConfig *config, PyObject *dict) _PyPreConfig_AsDict(const _PyPreConfig *config, PyObject *dict)
{ {
...@@ -567,16 +583,18 @@ fail: ...@@ -567,16 +583,18 @@ fail:
/* Parse the command line arguments */ /* Parse the command line arguments */
static _PyInitError _PyInitError
preconfig_parse_cmdline(_PyPreConfig *config, _PyPreCmdline *cmdline) _PyPreCmdline_Read(_PyPreCmdline *cmdline)
{ {
_PyWstrList *argv = &cmdline->argv;
_PyOS_ResetGetOpt(); _PyOS_ResetGetOpt();
/* Don't log parsing errors into stderr here: _PyCoreConfig_ReadFromArgv() /* Don't log parsing errors into stderr here: _PyCoreConfig_ReadFromArgv()
is responsible for that */ is responsible for that */
_PyOS_opterr = 0; _PyOS_opterr = 0;
do { do {
int longindex = -1; int longindex = -1;
int c = _PyOS_GetOpt(cmdline->argv.length, cmdline->argv.items, &longindex); int c = _PyOS_GetOpt(argv->length, argv->items, &longindex);
if (c == EOF || c == 'c' || c == 'm') { if (c == EOF || c == 'c' || c == 'm') {
break; break;
...@@ -584,11 +602,11 @@ preconfig_parse_cmdline(_PyPreConfig *config, _PyPreCmdline *cmdline) ...@@ -584,11 +602,11 @@ preconfig_parse_cmdline(_PyPreConfig *config, _PyPreCmdline *cmdline)
switch (c) { switch (c) {
case 'E': case 'E':
config->use_environment = 0; cmdline->use_environment = 0;
break; break;
case 'I': case 'I':
config->isolated++; cmdline->isolated = 1;
break; break;
case 'X': case 'X':
...@@ -615,19 +633,20 @@ preconfig_from_argv(_PyPreConfig *config, const _PyArgv *args) ...@@ -615,19 +633,20 @@ preconfig_from_argv(_PyPreConfig *config, const _PyArgv *args)
{ {
_PyInitError err; _PyInitError err;
_PyPreCmdline cmdline; _PyPreCmdline cmdline = _PyPreCmdline_INIT;
memset(&cmdline, 0, sizeof(cmdline));
err = _PyArgv_AsWstrList(args, &cmdline.argv); err = _PyPreCmdline_Init(&cmdline, args);
if (_Py_INIT_FAILED(err)) { if (_Py_INIT_FAILED(err)) {
goto done; goto done;
} }
err = preconfig_parse_cmdline(config, &cmdline); err = _PyPreCmdline_Read(&cmdline);
if (_Py_INIT_FAILED(err)) { if (_Py_INIT_FAILED(err)) {
goto done; goto done;
} }
_PyPreCmdline_SetPreConfig(&cmdline, config);
err = preconfig_read(config, &cmdline); err = preconfig_read(config, &cmdline);
if (_Py_INIT_FAILED(err)) { if (_Py_INIT_FAILED(err)) {
goto done; goto done;
...@@ -635,7 +654,7 @@ preconfig_from_argv(_PyPreConfig *config, const _PyArgv *args) ...@@ -635,7 +654,7 @@ preconfig_from_argv(_PyPreConfig *config, const _PyArgv *args)
err = _Py_INIT_OK(); err = _Py_INIT_OK();
done: done:
precmdline_clear(&cmdline); _PyPreCmdline_Clear(&cmdline);
return err; return err;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment