diff options
author | Victor Stinner <vstinner@redhat.com> | 2019-03-15 15:08:05 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-03-15 15:08:05 +0100 |
commit | 74f6568bbd3e70806ea3219e8bacb386ad802ccf (patch) | |
tree | 98516f3e71020f12109372492180a835307e129f /Python/preconfig.c | |
parent | 86082c22d23285995a32aabb491527c9f5629556 (diff) | |
download | cpython-git-74f6568bbd3e70806ea3219e8bacb386ad802ccf.tar.gz |
bpo-36301: Add _PyWstrList structure (GH-12343)
Replace messy _Py_wstrlist_xxx() functions with a new clean
_PyWstrList structure and new _PyWstrList_xxx() functions.
Changes:
* Add _PyCoreConfig.use_module_search_paths to decide if
_PyCoreConfig.module_search_paths should be computed or not, to
support empty search path list.
* _PyWstrList_Clear() sets length to 0 and items to NULL, whereas
_Py_wstrlist_clear() only freed memory.
* _PyWstrList_Append() returns an int, whereas _Py_wstrlist_append()
returned _PyInitError.
* _PyWstrList uses Py_ssize_t for the length, instead of int.
* Replace (int, wchar_t**) with _PyWstrList in:
* _PyPreConfig
* _PyCoreConfig
* _PyPreCmdline
* _PyCmdline
* Replace "int orig_argv; wchar_t **orig_argv;"
with "_PyWstrList orig_argv".
* _PyCmdline and _PyPreCmdline now also copy wchar_argv.
* Rename _PyArgv_Decode() to _PyArgv_AsWstrList().
* PySys_SetArgvEx() now pass the fixed (argc, argv) to
_PyPathConfig_ComputeArgv0() (don't pass negative argc or NULL
argv).
* _PyOS_GetOpt() uses Py_ssize_t
Diffstat (limited to 'Python/preconfig.c')
-rw-r--r-- | Python/preconfig.c | 69 |
1 files changed, 30 insertions, 39 deletions
diff --git a/Python/preconfig.c b/Python/preconfig.c index 50d66b1249..a86ece57cf 100644 --- a/Python/preconfig.c +++ b/Python/preconfig.c @@ -64,33 +64,38 @@ _Py_SetFileSystemEncoding(const char *encoding, const char *errors) /* --- _PyArgv ---------------------------------------------------- */ _PyInitError -_PyArgv_Decode(const _PyArgv *args, wchar_t*** argv_p) +_PyArgv_AsWstrList(const _PyArgv *args, _PyWstrList *list) { - wchar_t** argv; + _PyWstrList wargv = _PyWstrList_INIT; if (args->use_bytes_argv) { - /* +1 for a the NULL terminator */ - size_t size = sizeof(wchar_t*) * (args->argc + 1); - argv = (wchar_t **)PyMem_RawMalloc(size); - if (argv == NULL) { + size_t size = sizeof(wchar_t*) * args->argc; + wargv.items = (wchar_t **)PyMem_RawMalloc(size); + if (wargv.items == NULL) { return _Py_INIT_NO_MEMORY(); } - for (int i = 0; i < args->argc; i++) { + for (Py_ssize_t i = 0; i < args->argc; i++) { size_t len; wchar_t *arg = Py_DecodeLocale(args->bytes_argv[i], &len); if (arg == NULL) { - _Py_wstrlist_clear(i, argv); + _PyWstrList_Clear(&wargv); return DECODE_LOCALE_ERR("command line arguments", (Py_ssize_t)len); } - argv[i] = arg; + wargv.items[i] = arg; + wargv.length++; } - argv[args->argc] = NULL; + + _PyWstrList_Clear(list); + *list = wargv; } else { - argv = args->wchar_argv; + wargv.length = args->argc; + wargv.items = args->wchar_argv; + if (_PyWstrList_Copy(list, &wargv) < 0) { + return _Py_INIT_NO_MEMORY(); + } } - *argv_p = argv; return _Py_INIT_OK(); } @@ -98,25 +103,16 @@ _PyArgv_Decode(const _PyArgv *args, wchar_t*** argv_p) /* --- _PyPreCmdline ------------------------------------------------- */ typedef struct { - const _PyArgv *args; - int argc; - wchar_t **argv; - int nxoption; /* Number of -X options */ - wchar_t **xoptions; /* -X options */ + _PyWstrList argv; + _PyWstrList xoptions; /* -X options */ } _PyPreCmdline; static void precmdline_clear(_PyPreCmdline *cmdline) { - if (cmdline->args->use_bytes_argv && cmdline->argv != NULL) { - _Py_wstrlist_clear(cmdline->args->argc, cmdline->argv); - } - cmdline->argv = NULL; - - _Py_wstrlist_clear(cmdline->nxoption, cmdline->xoptions); - cmdline->nxoption = 0; - cmdline->xoptions = NULL; + _PyWstrList_Clear(&cmdline->argv); + _PyWstrList_Clear(&cmdline->xoptions); } @@ -267,10 +263,10 @@ _Py_get_env_flag(_PyPreConfig *config, int *flag, const char *name) const wchar_t* -_Py_get_xoption(int nxoption, wchar_t * const *xoptions, const wchar_t *name) +_Py_get_xoption(const _PyWstrList *xoptions, const wchar_t *name) { - for (int i=0; i < nxoption; i++) { - const wchar_t *option = xoptions[i]; + for (Py_ssize_t i=0; i < xoptions->length; i++) { + const wchar_t *option = xoptions->items[i]; size_t len; wchar_t *sep = wcschr(option, L'='); if (sep != NULL) { @@ -292,7 +288,7 @@ preconfig_init_utf8_mode(_PyPreConfig *config, const _PyPreCmdline *cmdline) { const wchar_t *xopt; if (cmdline) { - xopt = _Py_get_xoption(cmdline->nxoption, cmdline->xoptions, L"utf8"); + xopt = _Py_get_xoption(&cmdline->xoptions, L"utf8"); } else { xopt = NULL; @@ -435,7 +431,7 @@ preconfig_read(_PyPreConfig *config, const _PyPreCmdline *cmdline) } /* dev_mode */ - if ((cmdline && _Py_get_xoption(cmdline->nxoption, cmdline->xoptions, L"dev")) + if ((cmdline && _Py_get_xoption(&cmdline->xoptions, L"dev")) || _PyPreConfig_GetEnv(config, "PYTHONDEVMODE")) { config->dev_mode = 1; @@ -579,7 +575,7 @@ preconfig_parse_cmdline(_PyPreConfig *config, _PyPreCmdline *cmdline) _PyOS_opterr = 0; do { int longindex = -1; - int c = _PyOS_GetOpt(cmdline->args->argc, cmdline->argv, &longindex); + int c = _PyOS_GetOpt(cmdline->argv.length, cmdline->argv.items, &longindex); if (c == EOF || c == 'c' || c == 'm') { break; @@ -596,12 +592,8 @@ preconfig_parse_cmdline(_PyPreConfig *config, _PyPreCmdline *cmdline) case 'X': { - _PyInitError err; - err = _Py_wstrlist_append(&cmdline->nxoption, - &cmdline->xoptions, - _PyOS_optarg); - if (_Py_INIT_FAILED(err)) { - return err; + if (_PyWstrList_Append(&cmdline->xoptions, _PyOS_optarg) < 0) { + return _Py_INIT_NO_MEMORY(); } break; } @@ -624,9 +616,8 @@ preconfig_from_argv(_PyPreConfig *config, const _PyArgv *args) _PyPreCmdline cmdline; memset(&cmdline, 0, sizeof(cmdline)); - cmdline.args = args; - err = _PyArgv_Decode(cmdline.args, &cmdline.argv); + err = _PyArgv_AsWstrList(args, &cmdline.argv); if (_Py_INIT_FAILED(err)) { goto done; } |