summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVictor Stinner <vstinner@redhat.com>2019-03-20 03:25:38 (GMT)
committerGitHub <noreply@github.com>2019-03-20 03:25:38 (GMT)
commitfa1537684869186da7938e4330361bf02363bac8 (patch)
tree919f5d59429afe03b6bbfd24b0f289018a8a254e
parentabbdd1fc5c2017683da8d2ed3e8843e8c159bc8c (diff)
downloadcpython-fa1537684869186da7938e4330361bf02363bac8.zip
cpython-fa1537684869186da7938e4330361bf02363bac8.tar.gz
cpython-fa1537684869186da7938e4330361bf02363bac8.tar.bz2
bpo-36301: Add _PyPreCmdline internal API (GH-12458)
_PyCoreConfig_ReadFromArgv() now reuses the code parsing command line options from preconfig.c.
-rw-r--r--Include/internal/pycore_coreconfig.h24
-rw-r--r--Python/coreconfig.c67
-rw-r--r--Python/preconfig.c55
3 files changed, 99 insertions, 47 deletions
diff --git a/Include/internal/pycore_coreconfig.h b/Include/internal/pycore_coreconfig.h
index 8c5a072..29261df 100644
--- a/Include/internal/pycore_coreconfig.h
+++ b/Include/internal/pycore_coreconfig.h
@@ -9,6 +9,30 @@ extern "C" {
#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 ------------------------------------------------ */
#ifndef NDEBUG
diff --git a/Python/coreconfig.c b/Python/coreconfig.c
index e1d883c..1881f00 100644
--- a/Python/coreconfig.c
+++ b/Python/coreconfig.c
@@ -1658,7 +1658,7 @@ fail:
/* --- _PyCmdline ------------------------------------------------- */
typedef struct {
- _PyWstrList argv;
+ _PyPreCmdline precmdline;
_PyWstrList warnoptions; /* Command line -W options */
_PyWstrList env_warnoptions; /* PYTHONWARNINGS environment variables */
int print_help; /* -h, -? options */
@@ -1669,9 +1669,9 @@ typedef struct {
static void
cmdline_clear(_PyCmdline *cmdline)
{
+ _PyPreCmdline_Clear(&cmdline->precmdline);
_PyWstrList_Clear(&cmdline->warnoptions);
_PyWstrList_Clear(&cmdline->env_warnoptions);
- _PyWstrList_Clear(&cmdline->argv);
}
@@ -1682,10 +1682,12 @@ static _PyInitError
config_parse_cmdline(_PyCoreConfig *config, _PyCmdline *cmdline,
int *need_usage)
{
+ const _PyWstrList *argv = &cmdline->precmdline.argv;
+
_PyOS_ResetGetOpt();
do {
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) {
break;
}
@@ -1754,6 +1756,7 @@ config_parse_cmdline(_PyCoreConfig *config, _PyCmdline *cmdline,
case 'E':
case 'I':
+ case 'X':
/* option handled by _PyPreConfig_ReadFromArgv() */
break;
@@ -1806,12 +1809,6 @@ config_parse_cmdline(_PyCoreConfig *config, _PyCmdline *cmdline,
}
break;
- case 'X':
- if (_PyWstrList_Append(&config->xoptions, _PyOS_optarg) < 0) {
- return _Py_INIT_NO_MEMORY();
- }
- break;
-
case 'q':
config->quiet++;
break;
@@ -1830,11 +1827,11 @@ config_parse_cmdline(_PyCoreConfig *config, _PyCmdline *cmdline,
} while (1);
if (config->run_command == NULL && config->run_module == NULL
- && _PyOS_optind < cmdline->argv.length
- && wcscmp(cmdline->argv.items[_PyOS_optind], L"-") != 0
+ && _PyOS_optind < argv->length
+ && wcscmp(argv->items[_PyOS_optind], L"-") != 0
&& 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) {
return _Py_INIT_NO_MEMORY();
}
@@ -1892,9 +1889,10 @@ cmdline_init_env_warnoptions(_PyCmdline *cmdline, const _PyCoreConfig *config)
static _PyInitError
config_init_program(_PyCoreConfig *config, const _PyCmdline *cmdline)
{
+ const _PyWstrList *argv = &cmdline->precmdline.argv;
wchar_t *program;
- if (cmdline->argv.length >= 1) {
- program = cmdline->argv.items[0];
+ if (argv->length >= 1) {
+ program = argv->items[0];
}
else {
program = L"";
@@ -1965,24 +1963,25 @@ config_init_warnoptions(_PyCoreConfig *config, const _PyCmdline *cmdline)
static _PyInitError
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) */
- if (cmdline->argv.length <= _PyOS_optind) {
+ if (cmdline_argv->length <= _PyOS_optind) {
/* 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();
}
}
else {
_PyWstrList slice;
- slice.length = cmdline->argv.length - _PyOS_optind;
- slice.items = &cmdline->argv.items[_PyOS_optind];
- if (_PyWstrList_Copy(&wargv, &slice) < 0) {
+ slice.length = cmdline_argv->length - _PyOS_optind;
+ slice.items = &cmdline_argv->items[_PyOS_optind];
+ if (_PyWstrList_Copy(&config_argv, &slice) < 0) {
return _Py_INIT_NO_MEMORY();
}
}
- assert(wargv.length >= 1);
+ assert(config_argv.length >= 1);
wchar_t *arg0 = NULL;
if (config->run_command != NULL) {
@@ -1996,16 +1995,16 @@ config_init_argv(_PyCoreConfig *config, const _PyCmdline *cmdline)
if (arg0 != NULL) {
arg0 = _PyMem_RawWcsdup(arg0);
if (arg0 == NULL) {
- _PyWstrList_Clear(&wargv);
+ _PyWstrList_Clear(&config_argv);
return _Py_INIT_NO_MEMORY();
}
- PyMem_RawFree(wargv.items[0]);
- wargv.items[0] = arg0;
+ PyMem_RawFree(config_argv.items[0]);
+ config_argv.items[0] = arg0;
}
_PyWstrList_Clear(&config->argv);
- config->argv = wargv;
+ config->argv = config_argv;
return _Py_INIT_OK();
}
@@ -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);
if (_Py_INIT_FAILED(err)) {
return err;
@@ -2089,7 +2098,8 @@ config_from_cmdline(_PyCoreConfig *config, _PyCmdline *cmdline,
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_OK();
@@ -2107,10 +2117,9 @@ _PyCoreConfig_ReadFromArgv(_PyCoreConfig *config, const _PyArgv *args,
{
_PyInitError err;
- _PyCmdline cmdline;
- memset(&cmdline, 0, sizeof(cmdline));
+ _PyCmdline cmdline = {.precmdline = _PyPreCmdline_INIT};
- err = _PyArgv_AsWstrList(args, &cmdline.argv);
+ err = _PyPreCmdline_Init(&cmdline.precmdline, args);
if (_Py_INIT_FAILED(err)) {
goto done;
}
diff --git a/Python/preconfig.c b/Python/preconfig.c
index a149ea5..d856c12 100644
--- a/Python/preconfig.c
+++ b/Python/preconfig.c
@@ -102,20 +102,21 @@ _PyArgv_AsWstrList(const _PyArgv *args, _PyWstrList *list)
/* --- _PyPreCmdline ------------------------------------------------- */
-typedef struct {
- _PyWstrList argv;
- _PyWstrList xoptions; /* -X options */
-} _PyPreCmdline;
-
-
-static void
-precmdline_clear(_PyPreCmdline *cmdline)
+void
+_PyPreCmdline_Clear(_PyPreCmdline *cmdline)
{
_PyWstrList_Clear(&cmdline->argv);
_PyWstrList_Clear(&cmdline->xoptions);
}
+_PyInitError
+_PyPreCmdline_Init(_PyPreCmdline *cmdline, const _PyArgv *args)
+{
+ return _PyArgv_AsWstrList(args, &cmdline->argv);
+}
+
+
/* --- _PyPreConfig ----------------------------------------------- */
void
@@ -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
_PyPreConfig_AsDict(const _PyPreConfig *config, PyObject *dict)
{
@@ -567,16 +583,18 @@ fail:
/* Parse the command line arguments */
-static _PyInitError
-preconfig_parse_cmdline(_PyPreConfig *config, _PyPreCmdline *cmdline)
+_PyInitError
+_PyPreCmdline_Read(_PyPreCmdline *cmdline)
{
+ _PyWstrList *argv = &cmdline->argv;
+
_PyOS_ResetGetOpt();
/* Don't log parsing errors into stderr here: _PyCoreConfig_ReadFromArgv()
is responsible for that */
_PyOS_opterr = 0;
do {
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') {
break;
@@ -584,11 +602,11 @@ preconfig_parse_cmdline(_PyPreConfig *config, _PyPreCmdline *cmdline)
switch (c) {
case 'E':
- config->use_environment = 0;
+ cmdline->use_environment = 0;
break;
case 'I':
- config->isolated++;
+ cmdline->isolated = 1;
break;
case 'X':
@@ -615,19 +633,20 @@ preconfig_from_argv(_PyPreConfig *config, const _PyArgv *args)
{
_PyInitError err;
- _PyPreCmdline cmdline;
- memset(&cmdline, 0, sizeof(cmdline));
+ _PyPreCmdline cmdline = _PyPreCmdline_INIT;
- err = _PyArgv_AsWstrList(args, &cmdline.argv);
+ err = _PyPreCmdline_Init(&cmdline, args);
if (_Py_INIT_FAILED(err)) {
goto done;
}
- err = preconfig_parse_cmdline(config, &cmdline);
+ err = _PyPreCmdline_Read(&cmdline);
if (_Py_INIT_FAILED(err)) {
goto done;
}
+ _PyPreCmdline_SetPreConfig(&cmdline, config);
+
err = preconfig_read(config, &cmdline);
if (_Py_INIT_FAILED(err)) {
goto done;
@@ -635,7 +654,7 @@ preconfig_from_argv(_PyPreConfig *config, const _PyArgv *args)
err = _Py_INIT_OK();
done:
- precmdline_clear(&cmdline);
+ _PyPreCmdline_Clear(&cmdline);
return err;
}