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

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
üst 86082c22
...@@ -46,6 +46,18 @@ typedef struct { ...@@ -46,6 +46,18 @@ typedef struct {
#define _Py_INIT_FAILED(err) \ #define _Py_INIT_FAILED(err) \
(err.msg != NULL || err.exitcode != -1) (err.msg != NULL || err.exitcode != -1)
/* --- _PyWstrList ------------------------------------------------ */
typedef struct {
/* If length is greater than zero, items must be non-NULL
and all items strings must be non-NULL */
Py_ssize_t length;
wchar_t **items;
} _PyWstrList;
#define _PyWstrList_INIT (_PyWstrList){.length = 0, .items = NULL}
/* --- _PyPreConfig ----------------------------------------------- */ /* --- _PyPreConfig ----------------------------------------------- */
typedef struct { typedef struct {
...@@ -163,18 +175,11 @@ typedef struct { ...@@ -163,18 +175,11 @@ typedef struct {
char *filesystem_errors; char *filesystem_errors;
wchar_t *pycache_prefix; /* PYTHONPYCACHEPREFIX, -X pycache_prefix=PATH */ wchar_t *pycache_prefix; /* PYTHONPYCACHEPREFIX, -X pycache_prefix=PATH */
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, _PyWstrList argv; /* Command line arguments */
-1 means unset */
wchar_t **argv; /* Command line arguments */
wchar_t *program; /* argv[0] or "" */ wchar_t *program; /* argv[0] or "" */
_PyWstrList xoptions; /* Command line -X options */
int nxoption; /* Number of -X options */ _PyWstrList warnoptions; /* Warnings options */
wchar_t **xoptions; /* -X options */
int nwarnoption; /* Number of warnings options */
wchar_t **warnoptions; /* Warnings options */
/* Path configuration inputs */ /* Path configuration inputs */
wchar_t *module_search_path_env; /* PYTHONPATH environment variable */ wchar_t *module_search_path_env; /* PYTHONPATH environment variable */
...@@ -182,9 +187,11 @@ typedef struct { ...@@ -182,9 +187,11 @@ typedef struct {
see also Py_SetPythonHome(). */ see also Py_SetPythonHome(). */
/* Path configuration outputs */ /* Path configuration outputs */
int nmodule_search_path; /* Number of sys.path paths, int use_module_search_paths; /* If non-zero, use module_search_paths */
-1 means unset */ _PyWstrList module_search_paths; /* sys.path paths. Computed if
wchar_t **module_search_paths; /* sys.path paths */ use_module_search_paths is equal
to zero. */
wchar_t *executable; /* sys.executable */ wchar_t *executable; /* sys.executable */
wchar_t *prefix; /* sys.prefix */ wchar_t *prefix; /* sys.prefix */
wchar_t *base_prefix; /* sys.base_prefix */ wchar_t *base_prefix; /* sys.base_prefix */
...@@ -366,8 +373,7 @@ typedef struct { ...@@ -366,8 +373,7 @@ typedef struct {
.use_hash_seed = -1, \ .use_hash_seed = -1, \
.faulthandler = -1, \ .faulthandler = -1, \
.tracemalloc = -1, \ .tracemalloc = -1, \
.argc = -1, \ .use_module_search_paths = 0, \
.nmodule_search_path = -1, \
.site_import = -1, \ .site_import = -1, \
.bytes_warning = -1, \ .bytes_warning = -1, \
.inspect = -1, \ .inspect = -1, \
......
...@@ -8,39 +8,38 @@ extern "C" { ...@@ -8,39 +8,38 @@ extern "C" {
# error "this header requires Py_BUILD_CORE or Py_BUILD_CORE_BUILTIN defined" # error "this header requires Py_BUILD_CORE or Py_BUILD_CORE_BUILTIN defined"
#endif #endif
/* --- _Py_wstrlist ----------------------------------------------- */
/* --- _PyWstrList ------------------------------------------------ */
PyAPI_FUNC(void) _Py_wstrlist_clear(
int len, #ifndef NDEBUG
wchar_t **list); PyAPI_FUNC(int) _PyWstrList_CheckConsistency(const _PyWstrList *list);
PyAPI_FUNC(wchar_t**) _Py_wstrlist_copy( #endif
int len, PyAPI_FUNC(void) _PyWstrList_Clear(_PyWstrList *list);
wchar_t * const *list); PyAPI_FUNC(int) _PyWstrList_Copy(_PyWstrList *list,
PyAPI_FUNC(_PyInitError) _Py_wstrlist_append( const _PyWstrList *list2);
int *len, PyAPI_FUNC(int) _PyWstrList_Append(_PyWstrList *list,
wchar_t ***list, const wchar_t *item);
const wchar_t *str); PyAPI_FUNC(PyObject*) _PyWstrList_AsList(const _PyWstrList *list);
PyAPI_FUNC(PyObject*) _Py_wstrlist_as_pylist(
int len,
wchar_t **list);
/* --- _PyArgv ---------------------------------------------------- */ /* --- _PyArgv ---------------------------------------------------- */
PyAPI_FUNC(_PyInitError) _PyArgv_Decode(const _PyArgv *args, PyAPI_FUNC(_PyInitError) _PyArgv_AsWstrList(const _PyArgv *args,
wchar_t*** argv_p); _PyWstrList *list);
/* --- Py_GetArgcArgv() helpers ----------------------------------- */ /* --- Py_GetArgcArgv() helpers ----------------------------------- */
PyAPI_FUNC(void) _Py_ClearArgcArgv(void); PyAPI_FUNC(void) _Py_ClearArgcArgv(void);
/* --- _PyPreConfig ----------------------------------------------- */ /* --- _PyPreConfig ----------------------------------------------- */
PyAPI_FUNC(int) _Py_str_to_int( PyAPI_FUNC(int) _Py_str_to_int(
const char *str, const char *str,
int *result); int *result);
PyAPI_FUNC(const wchar_t*) _Py_get_xoption( PyAPI_FUNC(const wchar_t*) _Py_get_xoption(
int nxoption, const _PyWstrList *xoptions,
wchar_t * const *xoptions,
const wchar_t *name); const wchar_t *name);
PyAPI_FUNC(void) _PyPreConfig_Clear(_PyPreConfig *config); PyAPI_FUNC(void) _PyPreConfig_Clear(_PyPreConfig *config);
......
...@@ -6,8 +6,8 @@ ...@@ -6,8 +6,8 @@
#endif #endif
extern int _PyOS_opterr; extern int _PyOS_opterr;
extern int _PyOS_optind; extern Py_ssize_t _PyOS_optind;
extern wchar_t *_PyOS_optarg; extern const wchar_t *_PyOS_optarg;
extern void _PyOS_ResetGetOpt(void); extern void _PyOS_ResetGetOpt(void);
...@@ -17,6 +17,6 @@ typedef struct { ...@@ -17,6 +17,6 @@ typedef struct {
int val; int val;
} _PyOS_LongOption; } _PyOS_LongOption;
extern int _PyOS_GetOpt(int argc, wchar_t **argv, int *longindex); extern int _PyOS_GetOpt(Py_ssize_t argc, wchar_t **argv, int *longindex);
#endif /* !Py_INTERNAL_PYGETOPT_H */ #endif /* !Py_INTERNAL_PYGETOPT_H */
...@@ -44,7 +44,7 @@ PyAPI_FUNC(_PyInitError) _PyPathConfig_SetGlobal( ...@@ -44,7 +44,7 @@ PyAPI_FUNC(_PyInitError) _PyPathConfig_SetGlobal(
PyAPI_FUNC(_PyInitError) _PyPathConfig_Calculate_impl( PyAPI_FUNC(_PyInitError) _PyPathConfig_Calculate_impl(
_PyPathConfig *config, _PyPathConfig *config,
const _PyCoreConfig *core_config); const _PyCoreConfig *core_config);
PyAPI_FUNC(PyObject*) _PyPathConfig_ComputeArgv0(int argc, wchar_t **argv); PyAPI_FUNC(PyObject*) _PyPathConfig_ComputeArgv0(const _PyWstrList *argv);
PyAPI_FUNC(int) _Py_FindEnvConfigValue( PyAPI_FUNC(int) _Py_FindEnvConfigValue(
FILE *env_file, FILE *env_file,
const wchar_t *key, const wchar_t *key,
......
...@@ -84,15 +84,15 @@ error: ...@@ -84,15 +84,15 @@ error:
static PyObject* static PyObject*
mainconfig_create_xoptions_dict(const _PyCoreConfig *config) mainconfig_create_xoptions_dict(const _PyCoreConfig *config)
{ {
int nxoption = config->nxoption; Py_ssize_t nxoption = config->xoptions.length;
wchar_t **xoptions = config->xoptions; wchar_t * const * xoptions = config->xoptions.items;
PyObject *dict = PyDict_New(); PyObject *dict = PyDict_New();
if (dict == NULL) { if (dict == NULL) {
return NULL; return NULL;
} }
for (int i=0; i < nxoption; i++) { for (Py_ssize_t i=0; i < nxoption; i++) {
wchar_t *option = xoptions[i]; const wchar_t *option = xoptions[i];
if (mainconfig_add_xoption(dict, option) < 0) { if (mainconfig_add_xoption(dict, option) < 0) {
Py_DECREF(dict); Py_DECREF(dict);
return NULL; return NULL;
...@@ -243,22 +243,18 @@ _PyMainInterpreterConfig_Read(_PyMainInterpreterConfig *main_config, ...@@ -243,22 +243,18 @@ _PyMainInterpreterConfig_Read(_PyMainInterpreterConfig *main_config,
} \ } \
} \ } \
} while (0) } while (0)
#define COPY_WSTRLIST(ATTR, LEN, LIST) \ #define COPY_WSTRLIST(ATTR, LIST) \
do { \ do { \
if (ATTR == NULL) { \ if (ATTR == NULL) { \
ATTR = _Py_wstrlist_as_pylist(LEN, LIST); \ ATTR = _PyWstrList_AsList(LIST); \
if (ATTR == NULL) { \ if (ATTR == NULL) { \
return _Py_INIT_NO_MEMORY(); \ return _Py_INIT_NO_MEMORY(); \
} \ } \
} \ } \
} while (0) } while (0)
COPY_WSTRLIST(main_config->warnoptions, COPY_WSTRLIST(main_config->warnoptions, &config->warnoptions);
config->nwarnoption, config->warnoptions); COPY_WSTRLIST(main_config->argv, &config->argv);
if (config->argc >= 0) {
COPY_WSTRLIST(main_config->argv,
config->argc, config->argv);
}
if (config->_install_importlib) { if (config->_install_importlib) {
COPY_WSTR(executable); COPY_WSTR(executable);
...@@ -268,7 +264,7 @@ _PyMainInterpreterConfig_Read(_PyMainInterpreterConfig *main_config, ...@@ -268,7 +264,7 @@ _PyMainInterpreterConfig_Read(_PyMainInterpreterConfig *main_config,
COPY_WSTR(base_exec_prefix); COPY_WSTR(base_exec_prefix);
COPY_WSTRLIST(main_config->module_search_path, COPY_WSTRLIST(main_config->module_search_path,
config->nmodule_search_path, config->module_search_paths); &config->module_search_paths);
if (config->pycache_prefix != NULL) { if (config->pycache_prefix != NULL) {
COPY_WSTR(pycache_prefix); COPY_WSTR(pycache_prefix);
...@@ -784,8 +780,7 @@ pymain_run_python(PyInterpreterState *interp, int *exitcode) ...@@ -784,8 +780,7 @@ pymain_run_python(PyInterpreterState *interp, int *exitcode)
} }
} }
else if (!config->preconfig.isolated) { else if (!config->preconfig.isolated) {
PyObject *path0 = _PyPathConfig_ComputeArgv0(config->argc, PyObject *path0 = _PyPathConfig_ComputeArgv0(&config->argv);
config->argv);
if (path0 == NULL) { if (path0 == NULL) {
err = _Py_INIT_NO_MEMORY(); err = _Py_INIT_NO_MEMORY();
goto done; goto done;
......
...@@ -479,8 +479,8 @@ static int test_init_from_config(void) ...@@ -479,8 +479,8 @@ static int test_init_from_config(void)
L"-c", L"-c",
L"pass", L"pass",
}; };
config.argc = Py_ARRAY_LENGTH(argv); config.argv.length = Py_ARRAY_LENGTH(argv);
config.argv = argv; config.argv.items = argv;
config.program = L"conf_program"; config.program = L"conf_program";
...@@ -489,15 +489,15 @@ static int test_init_from_config(void) ...@@ -489,15 +489,15 @@ static int test_init_from_config(void)
L"core_xoption2=", L"core_xoption2=",
L"core_xoption3", L"core_xoption3",
}; };
config.nxoption = Py_ARRAY_LENGTH(xoptions); config.xoptions.length = Py_ARRAY_LENGTH(xoptions);
config.xoptions = xoptions; config.xoptions.items = xoptions;
static wchar_t* warnoptions[2] = { static wchar_t* warnoptions[2] = {
L"default", L"default",
L"error::ResourceWarning", L"error::ResourceWarning",
}; };
config.nwarnoption = Py_ARRAY_LENGTH(warnoptions); config.warnoptions.length = Py_ARRAY_LENGTH(warnoptions);
config.warnoptions = warnoptions; config.warnoptions.items = warnoptions;
/* FIXME: test module_search_path_env */ /* FIXME: test module_search_path_env */
/* FIXME: test home */ /* FIXME: test home */
......
This diff is collapsed.
...@@ -38,8 +38,8 @@ extern "C" { ...@@ -38,8 +38,8 @@ extern "C" {
#endif #endif
int _PyOS_opterr = 1; /* generate error messages */ int _PyOS_opterr = 1; /* generate error messages */
int _PyOS_optind = 1; /* index into argv array */ Py_ssize_t _PyOS_optind = 1; /* index into argv array */
wchar_t *_PyOS_optarg = NULL; /* optional argument */ const wchar_t *_PyOS_optarg = NULL; /* optional argument */
static wchar_t *opt_ptr = L""; static wchar_t *opt_ptr = L"";
...@@ -61,7 +61,7 @@ void _PyOS_ResetGetOpt(void) ...@@ -61,7 +61,7 @@ void _PyOS_ResetGetOpt(void)
opt_ptr = L""; opt_ptr = L"";
} }
int _PyOS_GetOpt(int argc, wchar_t **argv, int *longindex) int _PyOS_GetOpt(Py_ssize_t argc, wchar_t **argv, int *longindex)
{ {
wchar_t *ptr; wchar_t *ptr;
wchar_t option; wchar_t option;
......
...@@ -154,14 +154,14 @@ _PyPathConfig_ClearGlobal(void) ...@@ -154,14 +154,14 @@ _PyPathConfig_ClearGlobal(void)
static wchar_t* static wchar_t*
wstrlist_join(wchar_t sep, int count, wchar_t **list) _PyWstrList_Join(const _PyWstrList *list, wchar_t sep)
{ {
size_t len = 1; /* NUL terminator */ size_t len = 1; /* NUL terminator */
for (int i=0; i < count; i++) { for (Py_ssize_t i=0; i < list->length; i++) {
if (i != 0) { if (i != 0) {
len++; len++;
} }
len += wcslen(list[i]); len += wcslen(list->items[i]);
} }
wchar_t *text = PyMem_RawMalloc(len * sizeof(wchar_t)); wchar_t *text = PyMem_RawMalloc(len * sizeof(wchar_t));
...@@ -169,8 +169,8 @@ wstrlist_join(wchar_t sep, int count, wchar_t **list) ...@@ -169,8 +169,8 @@ wstrlist_join(wchar_t sep, int count, wchar_t **list)
return NULL; return NULL;
} }
wchar_t *str = text; wchar_t *str = text;
for (int i=0; i < count; i++) { for (Py_ssize_t i=0; i < list->length; i++) {
wchar_t *path = list[i]; wchar_t *path = list->items[i];
if (i != 0) { if (i != 0) {
*str++ = SEP; *str++ = SEP;
} }
...@@ -194,9 +194,7 @@ _PyCoreConfig_SetPathConfig(const _PyCoreConfig *core_config) ...@@ -194,9 +194,7 @@ _PyCoreConfig_SetPathConfig(const _PyCoreConfig *core_config)
_PyInitError err; _PyInitError err;
_PyPathConfig path_config = _PyPathConfig_INIT; _PyPathConfig path_config = _PyPathConfig_INIT;
path_config.module_search_path = wstrlist_join(DELIM, path_config.module_search_path = _PyWstrList_Join(&core_config->module_search_paths, DELIM);
core_config->nmodule_search_path,
core_config->module_search_paths);
if (path_config.module_search_path == NULL) { if (path_config.module_search_path == NULL) {
goto no_memory; goto no_memory;
} }
...@@ -244,10 +242,9 @@ static _PyInitError ...@@ -244,10 +242,9 @@ static _PyInitError
core_config_init_module_search_paths(_PyCoreConfig *config, core_config_init_module_search_paths(_PyCoreConfig *config,
_PyPathConfig *path_config) _PyPathConfig *path_config)
{ {
assert(config->module_search_paths == NULL); assert(!config->use_module_search_paths);
assert(config->nmodule_search_path < 0);
config->nmodule_search_path = 0; _PyWstrList_Clear(&config->module_search_paths);
const wchar_t *sys_path = path_config->module_search_path; const wchar_t *sys_path = path_config->module_search_path;
const wchar_t delim = DELIM; const wchar_t delim = DELIM;
...@@ -266,12 +263,10 @@ core_config_init_module_search_paths(_PyCoreConfig *config, ...@@ -266,12 +263,10 @@ core_config_init_module_search_paths(_PyCoreConfig *config,
memcpy(path, sys_path, path_len * sizeof(wchar_t)); memcpy(path, sys_path, path_len * sizeof(wchar_t));
path[path_len] = L'\0'; path[path_len] = L'\0';
_PyInitError err = _Py_wstrlist_append(&config->nmodule_search_path, int res = _PyWstrList_Append(&config->module_search_paths, path);
&config->module_search_paths,
path);
PyMem_RawFree(path); PyMem_RawFree(path);
if (_Py_INIT_FAILED(err)) { if (res < 0) {
return err; return _Py_INIT_NO_MEMORY();
} }
if (*p == '\0') { if (*p == '\0') {
...@@ -279,6 +274,7 @@ core_config_init_module_search_paths(_PyCoreConfig *config, ...@@ -279,6 +274,7 @@ core_config_init_module_search_paths(_PyCoreConfig *config,
} }
sys_path = p + 1; sys_path = p + 1;
} }
config->use_module_search_paths = 1;
return _Py_INIT_OK(); return _Py_INIT_OK();
} }
...@@ -294,7 +290,7 @@ _PyCoreConfig_CalculatePathConfig(_PyCoreConfig *config) ...@@ -294,7 +290,7 @@ _PyCoreConfig_CalculatePathConfig(_PyCoreConfig *config)
goto error; goto error;
} }
if (config->nmodule_search_path < 0) { if (!config->use_module_search_paths) {
err = core_config_init_module_search_paths(config, &path_config); err = core_config_init_module_search_paths(config, &path_config);
if (_Py_INIT_FAILED(err)) { if (_Py_INIT_FAILED(err)) {
goto error; goto error;
...@@ -352,7 +348,7 @@ _PyInitError ...@@ -352,7 +348,7 @@ _PyInitError
_PyCoreConfig_InitPathConfig(_PyCoreConfig *config) _PyCoreConfig_InitPathConfig(_PyCoreConfig *config)
{ {
/* Do we need to calculate the path? */ /* Do we need to calculate the path? */
if ((config->nmodule_search_path < 0) if (!config->use_module_search_paths
|| (config->executable == NULL) || (config->executable == NULL)
|| (config->prefix == NULL) || (config->prefix == NULL)
#ifdef MS_WINDOWS #ifdef MS_WINDOWS
...@@ -567,8 +563,10 @@ Py_GetProgramName(void) ...@@ -567,8 +563,10 @@ Py_GetProgramName(void)
/* Compute argv[0] which will be prepended to sys.argv */ /* Compute argv[0] which will be prepended to sys.argv */
PyObject* PyObject*
_PyPathConfig_ComputeArgv0(int argc, wchar_t **argv) _PyPathConfig_ComputeArgv0(const _PyWstrList *argv)
{ {
assert(_PyWstrList_CheckConsistency(argv));
wchar_t *argv0; wchar_t *argv0;
wchar_t *p = NULL; wchar_t *p = NULL;
Py_ssize_t n = 0; Py_ssize_t n = 0;
...@@ -585,8 +583,8 @@ _PyPathConfig_ComputeArgv0(int argc, wchar_t **argv) ...@@ -585,8 +583,8 @@ _PyPathConfig_ComputeArgv0(int argc, wchar_t **argv)
wchar_t fullpath[MAX_PATH]; wchar_t fullpath[MAX_PATH];
#endif #endif
argv0 = argv[0]; if (argv->length > 0) {
if (argc > 0 && argv0 != NULL) { argv0 = argv->items[0];
have_module_arg = (wcscmp(argv0, L"-m") == 0); have_module_arg = (wcscmp(argv0, L"-m") == 0);
have_script_arg = !have_module_arg && (wcscmp(argv0, L"-c") != 0); have_script_arg = !have_module_arg && (wcscmp(argv0, L"-c") != 0);
} }
......
...@@ -64,33 +64,38 @@ _Py_SetFileSystemEncoding(const char *encoding, const char *errors) ...@@ -64,33 +64,38 @@ _Py_SetFileSystemEncoding(const char *encoding, const char *errors)
/* --- _PyArgv ---------------------------------------------------- */ /* --- _PyArgv ---------------------------------------------------- */
_PyInitError _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) { if (args->use_bytes_argv) {
/* +1 for a the NULL terminator */ size_t size = sizeof(wchar_t*) * args->argc;
size_t size = sizeof(wchar_t*) * (args->argc + 1); wargv.items = (wchar_t **)PyMem_RawMalloc(size);
argv = (wchar_t **)PyMem_RawMalloc(size); if (wargv.items == NULL) {
if (argv == NULL) {
return _Py_INIT_NO_MEMORY(); 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; size_t len;
wchar_t *arg = Py_DecodeLocale(args->bytes_argv[i], &len); wchar_t *arg = Py_DecodeLocale(args->bytes_argv[i], &len);
if (arg == NULL) { if (arg == NULL) {
_Py_wstrlist_clear(i, argv); _PyWstrList_Clear(&wargv);
return DECODE_LOCALE_ERR("command line arguments", return DECODE_LOCALE_ERR("command line arguments",
(Py_ssize_t)len); (Py_ssize_t)len);
} }
argv[i] = arg; wargv.items[i] = arg;
wargv.length++;
} }
argv[args->argc] = NULL;
_PyWstrList_Clear(list);
*list = wargv;
} }
else { 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(); return _Py_INIT_OK();
} }
...@@ -98,25 +103,16 @@ _PyArgv_Decode(const _PyArgv *args, wchar_t*** argv_p) ...@@ -98,25 +103,16 @@ _PyArgv_Decode(const _PyArgv *args, wchar_t*** argv_p)
/* --- _PyPreCmdline ------------------------------------------------- */ /* --- _PyPreCmdline ------------------------------------------------- */
typedef struct { typedef struct {
const _PyArgv *args; _PyWstrList argv;
int argc; _PyWstrList xoptions; /* -X options */
wchar_t **argv;
int nxoption; /* Number of -X options */
wchar_t **xoptions; /* -X options */
} _PyPreCmdline; } _PyPreCmdline;
static void static void
precmdline_clear(_PyPreCmdline *cmdline) precmdline_clear(_PyPreCmdline *cmdline)
{ {
if (cmdline->args->use_bytes_argv && cmdline->argv != NULL) { _PyWstrList_Clear(&cmdline->argv);
_Py_wstrlist_clear(cmdline->args->argc, cmdline->argv); _PyWstrList_Clear(&cmdline->xoptions);
}
cmdline->argv = NULL;
_Py_wstrlist_clear(cmdline->nxoption, cmdline->xoptions);
cmdline->nxoption = 0;
cmdline->xoptions = NULL;
} }
...@@ -267,10 +263,10 @@ _Py_get_env_flag(_PyPreConfig *config, int *flag, const char *name) ...@@ -267,10 +263,10 @@ _Py_get_env_flag(_PyPreConfig *config, int *flag, const char *name)
const wchar_t* 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++) { for (Py_ssize_t i=0; i < xoptions->length; i++) {
const wchar_t *option = xoptions[i]; const wchar_t *option = xoptions->items[i];
size_t len; size_t len;
wchar_t *sep = wcschr(option, L'='); wchar_t *sep = wcschr(option, L'=');
if (sep != NULL) { if (sep != NULL) {
...@@ -292,7 +288,7 @@ preconfig_init_utf8_mode(_PyPreConfig *config, const _PyPreCmdline *cmdline) ...@@ -292,7 +288,7 @@ preconfig_init_utf8_mode(_PyPreConfig *config, const _PyPreCmdline *cmdline)
{ {
const wchar_t *xopt; const wchar_t *xopt;
if (cmdline) { if (cmdline) {
xopt = _Py_get_xoption(cmdline->nxoption, cmdline->xoptions, L"utf8"); xopt = _Py_get_xoption(&cmdline->xoptions, L"utf8");
} }
else { else {
xopt = NULL; xopt = NULL;
...@@ -435,7 +431,7 @@ preconfig_read(_PyPreConfig *config, const _PyPreCmdline *cmdline) ...@@ -435,7 +431,7 @@ preconfig_read(_PyPreConfig *config, const _PyPreCmdline *cmdline)
} }
/* dev_mode */ /* 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")) || _PyPreConfig_GetEnv(config, "PYTHONDEVMODE"))
{ {
config->dev_mode = 1; config->dev_mode = 1;
...@@ -579,7 +575,7 @@ preconfig_parse_cmdline(_PyPreConfig *config, _PyPreCmdline *cmdline) ...@@ -579,7 +575,7 @@ preconfig_parse_cmdline(_PyPreConfig *config, _PyPreCmdline *cmdline)
_PyOS_opterr = 0; _PyOS_opterr = 0;
do { do {
int longindex = -1; 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') { if (c == EOF || c == 'c' || c == 'm') {
break; break;
...@@ -596,12 +592,8 @@ preconfig_parse_cmdline(_PyPreConfig *config, _PyPreCmdline *cmdline) ...@@ -596,12 +592,8 @@ preconfig_parse_cmdline(_PyPreConfig *config, _PyPreCmdline *cmdline)
case 'X': case 'X':
{ {
_PyInitError err; if (_PyWstrList_Append(&cmdline->xoptions, _PyOS_optarg) < 0) {
err = _Py_wstrlist_append(&cmdline->nxoption, return _Py_INIT_NO_MEMORY();
&cmdline->xoptions,
_PyOS_optarg);
if (_Py_INIT_FAILED(err)) {
return err;
} }
break; break;
} }
...@@ -624,9 +616,8 @@ preconfig_from_argv(_PyPreConfig *config, const _PyArgv *args) ...@@ -624,9 +616,8 @@ preconfig_from_argv(_PyPreConfig *config, const _PyArgv *args)
_PyPreCmdline cmdline; _PyPreCmdline cmdline;
memset(&cmdline, 0, sizeof(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)) { if (_Py_INIT_FAILED(err)) {
goto done; goto done;
} }
......
...@@ -2739,35 +2739,35 @@ PySys_SetPath(const wchar_t *path) ...@@ -2739,35 +2739,35 @@ PySys_SetPath(const wchar_t *path)
} }
static PyObject * static PyObject *
makeargvobject(int argc, wchar_t **argv) make_sys_argv(int argc, wchar_t * const * argv)
{ {
PyObject *av; PyObject *list = PyList_New(argc);
if (argc <= 0 || argv == NULL) { if (list == NULL) {
/* Ensure at least one (empty) argument is seen */ return NULL;
static wchar_t *empty_argv[1] = {L""};
argv = empty_argv;
argc = 1;
} }
av = PyList_New(argc);
if (av != NULL) { for (Py_ssize_t i = 0; i < argc; i++) {
int i;
for (i = 0; i < argc; i++) {
PyObject *v = PyUnicode_FromWideChar(argv[i], -1); PyObject *v = PyUnicode_FromWideChar(argv[i], -1);
if (v == NULL) { if (v == NULL) {
Py_DECREF(av); Py_DECREF(list);
av = NULL; return NULL;
break;
}
PyList_SET_ITEM(av, i, v);
} }
PyList_SET_ITEM(list, i, v);
} }
return av; return list;
} }
void void
PySys_SetArgvEx(int argc, wchar_t **argv, int updatepath) PySys_SetArgvEx(int argc, wchar_t **argv, int updatepath)
{ {
PyObject *av = makeargvobject(argc, argv); if (argc < 1 || argv == NULL) {
/* Ensure at least one (empty) argument is seen */
wchar_t* empty_argv[1] = {L""};
argv = empty_argv;
argc = 1;
}
PyObject *av = make_sys_argv(argc, argv);
if (av == NULL) { if (av == NULL) {
Py_FatalError("no mem for sys.argv"); Py_FatalError("no mem for sys.argv");
} }
...@@ -2780,7 +2780,8 @@ PySys_SetArgvEx(int argc, wchar_t **argv, int updatepath) ...@@ -2780,7 +2780,8 @@ PySys_SetArgvEx(int argc, wchar_t **argv, int updatepath)
if (updatepath) { if (updatepath) {
/* If argv[0] is not '-c' nor '-m', prepend argv[0] to sys.path. /* If argv[0] is not '-c' nor '-m', prepend argv[0] to sys.path.
If argv[0] is a symlink, use the real path. */ If argv[0] is a symlink, use the real path. */
PyObject *argv0 = _PyPathConfig_ComputeArgv0(argc, argv); const _PyWstrList argv_list = {.length = argc, .items = argv};
PyObject *argv0 = _PyPathConfig_ComputeArgv0(&argv_list);
if (argv0 == NULL) { if (argv0 == NULL) {
Py_FatalError("can't compute path0 from argv"); Py_FatalError("can't compute path0 from argv");
} }
......
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