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:
Victor Stinner 2019-03-15 15:08:05 +01:00 committed by GitHub
parent 86082c22d2
commit 74f6568bbd
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 303 additions and 345 deletions

View file

@ -2739,35 +2739,35 @@ PySys_SetPath(const wchar_t *path)
}
static PyObject *
makeargvobject(int argc, wchar_t **argv)
make_sys_argv(int argc, wchar_t * const * argv)
{
PyObject *av;
if (argc <= 0 || argv == NULL) {
/* Ensure at least one (empty) argument is seen */
static wchar_t *empty_argv[1] = {L""};
argv = empty_argv;
argc = 1;
PyObject *list = PyList_New(argc);
if (list == NULL) {
return NULL;
}
av = PyList_New(argc);
if (av != NULL) {
int i;
for (i = 0; i < argc; i++) {
PyObject *v = PyUnicode_FromWideChar(argv[i], -1);
if (v == NULL) {
Py_DECREF(av);
av = NULL;
break;
}
PyList_SET_ITEM(av, i, v);
for (Py_ssize_t i = 0; i < argc; i++) {
PyObject *v = PyUnicode_FromWideChar(argv[i], -1);
if (v == NULL) {
Py_DECREF(list);
return NULL;
}
PyList_SET_ITEM(list, i, v);
}
return av;
return list;
}
void
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) {
Py_FatalError("no mem for sys.argv");
}
@ -2780,7 +2780,8 @@ PySys_SetArgvEx(int argc, wchar_t **argv, int updatepath)
if (updatepath) {
/* If argv[0] is not '-c' nor '-m', prepend argv[0] to sys.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) {
Py_FatalError("can't compute path0 from argv");
}