mirror of
https://github.com/python/cpython.git
synced 2025-10-09 16:34:44 +00:00
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
This commit is contained in:
parent
86082c22d2
commit
74f6568bbd
11 changed files with 303 additions and 345 deletions
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue