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
|
@ -46,6 +46,18 @@ typedef struct {
|
|||
#define _Py_INIT_FAILED(err) \
|
||||
(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 ----------------------------------------------- */
|
||||
|
||||
typedef struct {
|
||||
|
@ -162,19 +174,12 @@ typedef struct {
|
|||
char *filesystem_encoding;
|
||||
char *filesystem_errors;
|
||||
|
||||
wchar_t *pycache_prefix; /* PYTHONPYCACHEPREFIX, -X pycache_prefix=PATH */
|
||||
|
||||
wchar_t *program_name; /* Program name, see also Py_GetProgramName() */
|
||||
int argc; /* Number of command line arguments,
|
||||
-1 means unset */
|
||||
wchar_t **argv; /* Command line arguments */
|
||||
wchar_t *program; /* argv[0] or "" */
|
||||
|
||||
int nxoption; /* Number of -X options */
|
||||
wchar_t **xoptions; /* -X options */
|
||||
|
||||
int nwarnoption; /* Number of warnings options */
|
||||
wchar_t **warnoptions; /* Warnings options */
|
||||
wchar_t *pycache_prefix; /* PYTHONPYCACHEPREFIX, -X pycache_prefix=PATH */
|
||||
wchar_t *program_name; /* Program name, see also Py_GetProgramName() */
|
||||
_PyWstrList argv; /* Command line arguments */
|
||||
wchar_t *program; /* argv[0] or "" */
|
||||
_PyWstrList xoptions; /* Command line -X options */
|
||||
_PyWstrList warnoptions; /* Warnings options */
|
||||
|
||||
/* Path configuration inputs */
|
||||
wchar_t *module_search_path_env; /* PYTHONPATH environment variable */
|
||||
|
@ -182,9 +187,11 @@ typedef struct {
|
|||
see also Py_SetPythonHome(). */
|
||||
|
||||
/* Path configuration outputs */
|
||||
int nmodule_search_path; /* Number of sys.path paths,
|
||||
-1 means unset */
|
||||
wchar_t **module_search_paths; /* sys.path paths */
|
||||
int use_module_search_paths; /* If non-zero, use module_search_paths */
|
||||
_PyWstrList module_search_paths; /* sys.path paths. Computed if
|
||||
use_module_search_paths is equal
|
||||
to zero. */
|
||||
|
||||
wchar_t *executable; /* sys.executable */
|
||||
wchar_t *prefix; /* sys.prefix */
|
||||
wchar_t *base_prefix; /* sys.base_prefix */
|
||||
|
@ -366,8 +373,7 @@ typedef struct {
|
|||
.use_hash_seed = -1, \
|
||||
.faulthandler = -1, \
|
||||
.tracemalloc = -1, \
|
||||
.argc = -1, \
|
||||
.nmodule_search_path = -1, \
|
||||
.use_module_search_paths = 0, \
|
||||
.site_import = -1, \
|
||||
.bytes_warning = -1, \
|
||||
.inspect = -1, \
|
||||
|
|
|
@ -8,39 +8,38 @@ extern "C" {
|
|||
# error "this header requires Py_BUILD_CORE or Py_BUILD_CORE_BUILTIN defined"
|
||||
#endif
|
||||
|
||||
/* --- _Py_wstrlist ----------------------------------------------- */
|
||||
|
||||
PyAPI_FUNC(void) _Py_wstrlist_clear(
|
||||
int len,
|
||||
wchar_t **list);
|
||||
PyAPI_FUNC(wchar_t**) _Py_wstrlist_copy(
|
||||
int len,
|
||||
wchar_t * const *list);
|
||||
PyAPI_FUNC(_PyInitError) _Py_wstrlist_append(
|
||||
int *len,
|
||||
wchar_t ***list,
|
||||
const wchar_t *str);
|
||||
PyAPI_FUNC(PyObject*) _Py_wstrlist_as_pylist(
|
||||
int len,
|
||||
wchar_t **list);
|
||||
/* --- _PyWstrList ------------------------------------------------ */
|
||||
|
||||
#ifndef NDEBUG
|
||||
PyAPI_FUNC(int) _PyWstrList_CheckConsistency(const _PyWstrList *list);
|
||||
#endif
|
||||
PyAPI_FUNC(void) _PyWstrList_Clear(_PyWstrList *list);
|
||||
PyAPI_FUNC(int) _PyWstrList_Copy(_PyWstrList *list,
|
||||
const _PyWstrList *list2);
|
||||
PyAPI_FUNC(int) _PyWstrList_Append(_PyWstrList *list,
|
||||
const wchar_t *item);
|
||||
PyAPI_FUNC(PyObject*) _PyWstrList_AsList(const _PyWstrList *list);
|
||||
|
||||
|
||||
/* --- _PyArgv ---------------------------------------------------- */
|
||||
|
||||
PyAPI_FUNC(_PyInitError) _PyArgv_Decode(const _PyArgv *args,
|
||||
wchar_t*** argv_p);
|
||||
PyAPI_FUNC(_PyInitError) _PyArgv_AsWstrList(const _PyArgv *args,
|
||||
_PyWstrList *list);
|
||||
|
||||
|
||||
/* --- Py_GetArgcArgv() helpers ----------------------------------- */
|
||||
|
||||
PyAPI_FUNC(void) _Py_ClearArgcArgv(void);
|
||||
|
||||
|
||||
/* --- _PyPreConfig ----------------------------------------------- */
|
||||
|
||||
PyAPI_FUNC(int) _Py_str_to_int(
|
||||
const char *str,
|
||||
int *result);
|
||||
PyAPI_FUNC(const wchar_t*) _Py_get_xoption(
|
||||
int nxoption,
|
||||
wchar_t * const *xoptions,
|
||||
const _PyWstrList *xoptions,
|
||||
const wchar_t *name);
|
||||
|
||||
PyAPI_FUNC(void) _PyPreConfig_Clear(_PyPreConfig *config);
|
||||
|
|
|
@ -6,8 +6,8 @@
|
|||
#endif
|
||||
|
||||
extern int _PyOS_opterr;
|
||||
extern int _PyOS_optind;
|
||||
extern wchar_t *_PyOS_optarg;
|
||||
extern Py_ssize_t _PyOS_optind;
|
||||
extern const wchar_t *_PyOS_optarg;
|
||||
|
||||
extern void _PyOS_ResetGetOpt(void);
|
||||
|
||||
|
@ -17,6 +17,6 @@ typedef struct {
|
|||
int val;
|
||||
} _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 */
|
||||
|
|
|
@ -44,7 +44,7 @@ PyAPI_FUNC(_PyInitError) _PyPathConfig_SetGlobal(
|
|||
PyAPI_FUNC(_PyInitError) _PyPathConfig_Calculate_impl(
|
||||
_PyPathConfig *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(
|
||||
FILE *env_file,
|
||||
const wchar_t *key,
|
||||
|
|
|
@ -84,15 +84,15 @@ error:
|
|||
static PyObject*
|
||||
mainconfig_create_xoptions_dict(const _PyCoreConfig *config)
|
||||
{
|
||||
int nxoption = config->nxoption;
|
||||
wchar_t **xoptions = config->xoptions;
|
||||
Py_ssize_t nxoption = config->xoptions.length;
|
||||
wchar_t * const * xoptions = config->xoptions.items;
|
||||
PyObject *dict = PyDict_New();
|
||||
if (dict == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (int i=0; i < nxoption; i++) {
|
||||
wchar_t *option = xoptions[i];
|
||||
for (Py_ssize_t i=0; i < nxoption; i++) {
|
||||
const wchar_t *option = xoptions[i];
|
||||
if (mainconfig_add_xoption(dict, option) < 0) {
|
||||
Py_DECREF(dict);
|
||||
return NULL;
|
||||
|
@ -243,22 +243,18 @@ _PyMainInterpreterConfig_Read(_PyMainInterpreterConfig *main_config,
|
|||
} \
|
||||
} \
|
||||
} while (0)
|
||||
#define COPY_WSTRLIST(ATTR, LEN, LIST) \
|
||||
#define COPY_WSTRLIST(ATTR, LIST) \
|
||||
do { \
|
||||
if (ATTR == NULL) { \
|
||||
ATTR = _Py_wstrlist_as_pylist(LEN, LIST); \
|
||||
ATTR = _PyWstrList_AsList(LIST); \
|
||||
if (ATTR == NULL) { \
|
||||
return _Py_INIT_NO_MEMORY(); \
|
||||
} \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
COPY_WSTRLIST(main_config->warnoptions,
|
||||
config->nwarnoption, config->warnoptions);
|
||||
if (config->argc >= 0) {
|
||||
COPY_WSTRLIST(main_config->argv,
|
||||
config->argc, config->argv);
|
||||
}
|
||||
COPY_WSTRLIST(main_config->warnoptions, &config->warnoptions);
|
||||
COPY_WSTRLIST(main_config->argv, &config->argv);
|
||||
|
||||
if (config->_install_importlib) {
|
||||
COPY_WSTR(executable);
|
||||
|
@ -268,7 +264,7 @@ _PyMainInterpreterConfig_Read(_PyMainInterpreterConfig *main_config,
|
|||
COPY_WSTR(base_exec_prefix);
|
||||
|
||||
COPY_WSTRLIST(main_config->module_search_path,
|
||||
config->nmodule_search_path, config->module_search_paths);
|
||||
&config->module_search_paths);
|
||||
|
||||
if (config->pycache_prefix != NULL) {
|
||||
COPY_WSTR(pycache_prefix);
|
||||
|
@ -784,8 +780,7 @@ pymain_run_python(PyInterpreterState *interp, int *exitcode)
|
|||
}
|
||||
}
|
||||
else if (!config->preconfig.isolated) {
|
||||
PyObject *path0 = _PyPathConfig_ComputeArgv0(config->argc,
|
||||
config->argv);
|
||||
PyObject *path0 = _PyPathConfig_ComputeArgv0(&config->argv);
|
||||
if (path0 == NULL) {
|
||||
err = _Py_INIT_NO_MEMORY();
|
||||
goto done;
|
||||
|
|
|
@ -479,8 +479,8 @@ static int test_init_from_config(void)
|
|||
L"-c",
|
||||
L"pass",
|
||||
};
|
||||
config.argc = Py_ARRAY_LENGTH(argv);
|
||||
config.argv = argv;
|
||||
config.argv.length = Py_ARRAY_LENGTH(argv);
|
||||
config.argv.items = argv;
|
||||
|
||||
config.program = L"conf_program";
|
||||
|
||||
|
@ -489,15 +489,15 @@ static int test_init_from_config(void)
|
|||
L"core_xoption2=",
|
||||
L"core_xoption3",
|
||||
};
|
||||
config.nxoption = Py_ARRAY_LENGTH(xoptions);
|
||||
config.xoptions = xoptions;
|
||||
config.xoptions.length = Py_ARRAY_LENGTH(xoptions);
|
||||
config.xoptions.items = xoptions;
|
||||
|
||||
static wchar_t* warnoptions[2] = {
|
||||
L"default",
|
||||
L"error::ResourceWarning",
|
||||
};
|
||||
config.nwarnoption = Py_ARRAY_LENGTH(warnoptions);
|
||||
config.warnoptions = warnoptions;
|
||||
config.warnoptions.length = Py_ARRAY_LENGTH(warnoptions);
|
||||
config.warnoptions.items = warnoptions;
|
||||
|
||||
/* FIXME: test module_search_path_env */
|
||||
/* FIXME: test home */
|
||||
|
|
|
@ -202,81 +202,128 @@ fail:
|
|||
}
|
||||
|
||||
|
||||
/* --- _Py_wstrlist ----------------------------------------------- */
|
||||
/* --- _PyWstrList ------------------------------------------------ */
|
||||
|
||||
#ifndef NDEBUG
|
||||
int
|
||||
_PyWstrList_CheckConsistency(const _PyWstrList *list)
|
||||
{
|
||||
assert(list->length >= 0);
|
||||
if (list->length != 0) {
|
||||
assert(list->items != NULL);
|
||||
}
|
||||
for (Py_ssize_t i = 0; i < list->length; i++) {
|
||||
assert(list->items[i] != NULL);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
#endif /* Py_DEBUG */
|
||||
|
||||
|
||||
void
|
||||
_Py_wstrlist_clear(int len, wchar_t **list)
|
||||
_PyWstrList_Clear(_PyWstrList *list)
|
||||
{
|
||||
for (int i=0; i < len; i++) {
|
||||
PyMem_RawFree(list[i]);
|
||||
assert(_PyWstrList_CheckConsistency(list));
|
||||
for (Py_ssize_t i=0; i < list->length; i++) {
|
||||
PyMem_RawFree(list->items[i]);
|
||||
}
|
||||
PyMem_RawFree(list);
|
||||
PyMem_RawFree(list->items);
|
||||
list->length = 0;
|
||||
list->items = NULL;
|
||||
}
|
||||
|
||||
|
||||
wchar_t**
|
||||
_Py_wstrlist_copy(int len, wchar_t * const *list)
|
||||
int
|
||||
_PyWstrList_Copy(_PyWstrList *list, const _PyWstrList *list2)
|
||||
{
|
||||
assert((len > 0 && list != NULL) || len == 0);
|
||||
size_t size = len * sizeof(list[0]);
|
||||
wchar_t **list_copy = PyMem_RawMalloc(size);
|
||||
if (list_copy == NULL) {
|
||||
return NULL;
|
||||
assert(_PyWstrList_CheckConsistency(list));
|
||||
assert(_PyWstrList_CheckConsistency(list2));
|
||||
|
||||
if (list2->length == 0) {
|
||||
_PyWstrList_Clear(list);
|
||||
return 0;
|
||||
}
|
||||
for (int i=0; i < len; i++) {
|
||||
wchar_t* arg = _PyMem_RawWcsdup(list[i]);
|
||||
if (arg == NULL) {
|
||||
_Py_wstrlist_clear(i, list_copy);
|
||||
return NULL;
|
||||
|
||||
_PyWstrList copy = _PyWstrList_INIT;
|
||||
|
||||
size_t size = list2->length * sizeof(list2->items[0]);
|
||||
copy.items = PyMem_RawMalloc(size);
|
||||
if (copy.items == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (Py_ssize_t i=0; i < list2->length; i++) {
|
||||
wchar_t *item = _PyMem_RawWcsdup(list2->items[i]);
|
||||
if (item == NULL) {
|
||||
_PyWstrList_Clear(©);
|
||||
return -1;
|
||||
}
|
||||
list_copy[i] = arg;
|
||||
copy.items[i] = item;
|
||||
copy.length = i + 1;
|
||||
}
|
||||
return list_copy;
|
||||
|
||||
_PyWstrList_Clear(list);
|
||||
*list = copy;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
_PyInitError
|
||||
_Py_wstrlist_append(int *len, wchar_t ***list, const wchar_t *str)
|
||||
int
|
||||
_PyWstrList_Append(_PyWstrList *list, const wchar_t *item)
|
||||
{
|
||||
if (*len == INT_MAX) {
|
||||
/* len+1 would overflow */
|
||||
return _Py_INIT_NO_MEMORY();
|
||||
}
|
||||
wchar_t *str2 = _PyMem_RawWcsdup(str);
|
||||
if (str2 == NULL) {
|
||||
return _Py_INIT_NO_MEMORY();
|
||||
if (list->length == PY_SSIZE_T_MAX) {
|
||||
/* lenght+1 would overflow */
|
||||
return -1;
|
||||
}
|
||||
|
||||
size_t size = (*len + 1) * sizeof(list[0]);
|
||||
wchar_t **list2 = (wchar_t **)PyMem_RawRealloc(*list, size);
|
||||
if (list2 == NULL) {
|
||||
PyMem_RawFree(str2);
|
||||
return _Py_INIT_NO_MEMORY();
|
||||
wchar_t *item2 = _PyMem_RawWcsdup(item);
|
||||
if (item2 == NULL) {
|
||||
return -1;
|
||||
}
|
||||
list2[*len] = str2;
|
||||
*list = list2;
|
||||
(*len)++;
|
||||
return _Py_INIT_OK();
|
||||
|
||||
size_t size = (list->length + 1) * sizeof(list->items[0]);
|
||||
wchar_t **items2 = (wchar_t **)PyMem_RawRealloc(list->items, size);
|
||||
if (items2 == NULL) {
|
||||
PyMem_RawFree(item2);
|
||||
return -1;
|
||||
}
|
||||
|
||||
items2[list->length] = item2;
|
||||
list->items = items2;
|
||||
list->length++;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
_PyWstrList_Extend(_PyWstrList *list, const _PyWstrList *list2)
|
||||
{
|
||||
for (Py_ssize_t i = 0; i < list2->length; i++) {
|
||||
if (_PyWstrList_Append(list, list2->items[i])) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
PyObject*
|
||||
_Py_wstrlist_as_pylist(int len, wchar_t **list)
|
||||
_PyWstrList_AsList(const _PyWstrList *list)
|
||||
{
|
||||
assert(list != NULL || len < 1);
|
||||
assert(_PyWstrList_CheckConsistency(list));
|
||||
|
||||
PyObject *pylist = PyList_New(len);
|
||||
PyObject *pylist = PyList_New(list->length);
|
||||
if (pylist == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (int i = 0; i < len; i++) {
|
||||
PyObject *v = PyUnicode_FromWideChar(list[i], -1);
|
||||
if (v == NULL) {
|
||||
for (Py_ssize_t i = 0; i < list->length; i++) {
|
||||
PyObject *item = PyUnicode_FromWideChar(list->items[i], -1);
|
||||
if (item == NULL) {
|
||||
Py_DECREF(pylist);
|
||||
return NULL;
|
||||
}
|
||||
PyList_SET_ITEM(pylist, i, v);
|
||||
PyList_SET_ITEM(pylist, i, item);
|
||||
}
|
||||
return pylist;
|
||||
}
|
||||
|
@ -369,8 +416,7 @@ _Py_ClearStandardStreamEncoding(void)
|
|||
/* --- Py_GetArgcArgv() ------------------------------------------- */
|
||||
|
||||
/* For Py_GetArgcArgv(); set by _Py_SetArgcArgv() */
|
||||
static int orig_argc = 0;
|
||||
static wchar_t **orig_argv = NULL;
|
||||
static _PyWstrList orig_argv = {.length = 0, .items = NULL};
|
||||
|
||||
|
||||
void
|
||||
|
@ -379,32 +425,22 @@ _Py_ClearArgcArgv(void)
|
|||
PyMemAllocatorEx old_alloc;
|
||||
_PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
|
||||
|
||||
_Py_wstrlist_clear(orig_argc, orig_argv);
|
||||
orig_argc = 0;
|
||||
orig_argv = NULL;
|
||||
_PyWstrList_Clear(&orig_argv);
|
||||
|
||||
PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
_Py_SetArgcArgv(int argc, wchar_t * const *argv)
|
||||
_Py_SetArgcArgv(Py_ssize_t argc, wchar_t * const *argv)
|
||||
{
|
||||
const _PyWstrList argv_list = {.length = argc, .items = (wchar_t **)argv};
|
||||
int res;
|
||||
|
||||
PyMemAllocatorEx old_alloc;
|
||||
_PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
|
||||
|
||||
wchar_t **argv_copy = _Py_wstrlist_copy(argc, argv);
|
||||
if (argv_copy != NULL) {
|
||||
_Py_ClearArgcArgv();
|
||||
orig_argc = argc;
|
||||
orig_argv = argv_copy;
|
||||
res = 0;
|
||||
}
|
||||
else {
|
||||
res = -1;
|
||||
}
|
||||
res = _PyWstrList_Copy(&orig_argv, &argv_list);
|
||||
|
||||
PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
|
||||
return res;
|
||||
|
@ -416,8 +452,8 @@ _Py_SetArgcArgv(int argc, wchar_t * const *argv)
|
|||
void
|
||||
Py_GetArgcArgv(int *argc, wchar_t ***argv)
|
||||
{
|
||||
*argc = orig_argc;
|
||||
*argv = orig_argv;
|
||||
*argc = (int)orig_argv.length;
|
||||
*argv = orig_argv.items;
|
||||
}
|
||||
|
||||
|
||||
|
@ -439,12 +475,6 @@ _PyCoreConfig_Clear(_PyCoreConfig *config)
|
|||
PyMem_RawFree(ATTR); \
|
||||
ATTR = NULL; \
|
||||
} while (0)
|
||||
#define CLEAR_WSTRLIST(LEN, LIST) \
|
||||
do { \
|
||||
_Py_wstrlist_clear(LEN, LIST); \
|
||||
LEN = 0; \
|
||||
LIST = NULL; \
|
||||
} while (0)
|
||||
|
||||
CLEAR(config->pycache_prefix);
|
||||
CLEAR(config->module_search_path_env);
|
||||
|
@ -452,13 +482,11 @@ _PyCoreConfig_Clear(_PyCoreConfig *config)
|
|||
CLEAR(config->program_name);
|
||||
CLEAR(config->program);
|
||||
|
||||
CLEAR_WSTRLIST(config->argc, config->argv);
|
||||
config->argc = -1;
|
||||
|
||||
CLEAR_WSTRLIST(config->nwarnoption, config->warnoptions);
|
||||
CLEAR_WSTRLIST(config->nxoption, config->xoptions);
|
||||
CLEAR_WSTRLIST(config->nmodule_search_path, config->module_search_paths);
|
||||
config->nmodule_search_path = -1;
|
||||
_PyWstrList_Clear(&config->argv);
|
||||
_PyWstrList_Clear(&config->warnoptions);
|
||||
_PyWstrList_Clear(&config->xoptions);
|
||||
_PyWstrList_Clear(&config->module_search_paths);
|
||||
config->use_module_search_paths = 0;
|
||||
|
||||
CLEAR(config->executable);
|
||||
CLEAR(config->prefix);
|
||||
|
@ -477,7 +505,6 @@ _PyCoreConfig_Clear(_PyCoreConfig *config)
|
|||
CLEAR(config->run_module);
|
||||
CLEAR(config->run_filename);
|
||||
#undef CLEAR
|
||||
#undef CLEAR_WSTRLIST
|
||||
}
|
||||
|
||||
|
||||
|
@ -509,15 +536,11 @@ _PyCoreConfig_Copy(_PyCoreConfig *config, const _PyCoreConfig *config2)
|
|||
} \
|
||||
} \
|
||||
} while (0)
|
||||
#define COPY_WSTRLIST(LEN, LIST) \
|
||||
#define COPY_WSTRLIST(LIST) \
|
||||
do { \
|
||||
if (config2->LIST != NULL) { \
|
||||
config->LIST = _Py_wstrlist_copy(config2->LEN, config2->LIST); \
|
||||
if (config->LIST == NULL) { \
|
||||
return -1; \
|
||||
} \
|
||||
if (_PyWstrList_Copy(&config->LIST, &config2->LIST) < 0 ) { \
|
||||
return -1; \
|
||||
} \
|
||||
config->LEN = config2->LEN; \
|
||||
} while (0)
|
||||
|
||||
COPY_ATTR(install_signal_handlers);
|
||||
|
@ -538,10 +561,11 @@ _PyCoreConfig_Copy(_PyCoreConfig *config, const _PyCoreConfig *config2)
|
|||
COPY_WSTR_ATTR(program_name);
|
||||
COPY_WSTR_ATTR(program);
|
||||
|
||||
COPY_WSTRLIST(argc, argv);
|
||||
COPY_WSTRLIST(nwarnoption, warnoptions);
|
||||
COPY_WSTRLIST(nxoption, xoptions);
|
||||
COPY_WSTRLIST(nmodule_search_path, module_search_paths);
|
||||
COPY_WSTRLIST(argv);
|
||||
COPY_WSTRLIST(warnoptions);
|
||||
COPY_WSTRLIST(xoptions);
|
||||
COPY_WSTRLIST(module_search_paths);
|
||||
COPY_ATTR(use_module_search_paths);
|
||||
|
||||
COPY_WSTR_ATTR(executable);
|
||||
COPY_WSTR_ATTR(prefix);
|
||||
|
@ -817,7 +841,7 @@ config_init_executable(_PyCoreConfig *config)
|
|||
static const wchar_t*
|
||||
config_get_xoption(const _PyCoreConfig *config, wchar_t *name)
|
||||
{
|
||||
return _Py_get_xoption(config->nxoption, config->xoptions, name);
|
||||
return _Py_get_xoption(&config->xoptions, name);
|
||||
}
|
||||
|
||||
|
||||
|
@ -1427,9 +1451,6 @@ _PyCoreConfig_Read(_PyCoreConfig *config, const _PyPreConfig *preconfig)
|
|||
if (config->tracemalloc < 0) {
|
||||
config->tracemalloc = 0;
|
||||
}
|
||||
if (config->argc < 0) {
|
||||
config->argc = 0;
|
||||
}
|
||||
|
||||
if (config->filesystem_encoding == NULL || config->filesystem_errors == NULL) {
|
||||
err = config_init_fs_encoding(config);
|
||||
|
@ -1449,6 +1470,7 @@ _PyCoreConfig_Read(_PyCoreConfig *config, const _PyPreConfig *preconfig)
|
|||
assert(config->stdio_encoding != NULL);
|
||||
assert(config->stdio_errors != NULL);
|
||||
assert(config->_check_hash_pycs_mode != NULL);
|
||||
assert(_PyWstrList_CheckConsistency(&config->argv));
|
||||
|
||||
return _Py_INIT_OK();
|
||||
}
|
||||
|
@ -1546,8 +1568,8 @@ _PyCoreConfig_AsDict(const _PyCoreConfig *config)
|
|||
: (Py_INCREF(Py_None), Py_None))
|
||||
#define SET_ITEM_WSTR(ATTR) \
|
||||
SET_ITEM(#ATTR, FROM_WSTRING(config->ATTR))
|
||||
#define SET_ITEM_WSTRLIST(NOPTION, OPTIONS) \
|
||||
SET_ITEM(#OPTIONS, _Py_wstrlist_as_pylist(config->NOPTION, config->OPTIONS))
|
||||
#define SET_ITEM_WSTRLIST(LIST) \
|
||||
SET_ITEM(#LIST, _PyWstrList_AsList(&config->LIST))
|
||||
|
||||
SET_ITEM_INT(install_signal_handlers);
|
||||
SET_ITEM_INT(use_hash_seed);
|
||||
|
@ -1563,13 +1585,13 @@ _PyCoreConfig_AsDict(const _PyCoreConfig *config)
|
|||
SET_ITEM_STR(filesystem_errors);
|
||||
SET_ITEM_WSTR(pycache_prefix);
|
||||
SET_ITEM_WSTR(program_name);
|
||||
SET_ITEM_WSTRLIST(argc, argv);
|
||||
SET_ITEM_WSTRLIST(argv);
|
||||
SET_ITEM_WSTR(program);
|
||||
SET_ITEM_WSTRLIST(nxoption, xoptions);
|
||||
SET_ITEM_WSTRLIST(nwarnoption, warnoptions);
|
||||
SET_ITEM_WSTRLIST(xoptions);
|
||||
SET_ITEM_WSTRLIST(warnoptions);
|
||||
SET_ITEM_WSTR(module_search_path_env);
|
||||
SET_ITEM_WSTR(home);
|
||||
SET_ITEM_WSTRLIST(nmodule_search_path, module_search_paths);
|
||||
SET_ITEM_WSTRLIST(module_search_paths);
|
||||
SET_ITEM_WSTR(executable);
|
||||
SET_ITEM_WSTR(prefix);
|
||||
SET_ITEM_WSTR(base_prefix);
|
||||
|
@ -1622,13 +1644,9 @@ fail:
|
|||
/* --- _PyCmdline ------------------------------------------------- */
|
||||
|
||||
typedef struct {
|
||||
const _PyArgv *args;
|
||||
int argc;
|
||||
wchar_t **argv;
|
||||
int nwarnoption; /* Number of -W command line options */
|
||||
wchar_t **warnoptions; /* Command line -W options */
|
||||
int nenv_warnoption; /* Number of PYTHONWARNINGS environment variables */
|
||||
wchar_t **env_warnoptions; /* PYTHONWARNINGS environment variables */
|
||||
_PyWstrList argv;
|
||||
_PyWstrList warnoptions; /* Command line -W options */
|
||||
_PyWstrList env_warnoptions; /* PYTHONWARNINGS environment variables */
|
||||
int print_help; /* -h, -? options */
|
||||
int print_version; /* -V option */
|
||||
} _PyCmdline;
|
||||
|
@ -1637,18 +1655,9 @@ typedef struct {
|
|||
static void
|
||||
cmdline_clear(_PyCmdline *cmdline)
|
||||
{
|
||||
_Py_wstrlist_clear(cmdline->nwarnoption, cmdline->warnoptions);
|
||||
cmdline->nwarnoption = 0;
|
||||
cmdline->warnoptions = NULL;
|
||||
|
||||
_Py_wstrlist_clear(cmdline->nenv_warnoption, cmdline->env_warnoptions);
|
||||
cmdline->nenv_warnoption = 0;
|
||||
cmdline->env_warnoptions = NULL;
|
||||
|
||||
if (cmdline->args->use_bytes_argv && cmdline->argv != NULL) {
|
||||
_Py_wstrlist_clear(cmdline->args->argc, cmdline->argv);
|
||||
}
|
||||
cmdline->argv = NULL;
|
||||
_PyWstrList_Clear(&cmdline->warnoptions);
|
||||
_PyWstrList_Clear(&cmdline->env_warnoptions);
|
||||
_PyWstrList_Clear(&cmdline->argv);
|
||||
}
|
||||
|
||||
|
||||
|
@ -1659,11 +1668,10 @@ static _PyInitError
|
|||
config_parse_cmdline(_PyCoreConfig *config, _PyCmdline *cmdline,
|
||||
int *need_usage)
|
||||
{
|
||||
_PyInitError err;
|
||||
_PyOS_ResetGetOpt();
|
||||
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) {
|
||||
break;
|
||||
}
|
||||
|
@ -1775,20 +1783,14 @@ config_parse_cmdline(_PyCoreConfig *config, _PyCmdline *cmdline,
|
|||
break;
|
||||
|
||||
case 'W':
|
||||
err = _Py_wstrlist_append(&cmdline->nwarnoption,
|
||||
&cmdline->warnoptions,
|
||||
_PyOS_optarg);
|
||||
if (_Py_INIT_FAILED(err)) {
|
||||
return err;
|
||||
if (_PyWstrList_Append(&cmdline->warnoptions, _PyOS_optarg) < 0) {
|
||||
return _Py_INIT_NO_MEMORY();
|
||||
}
|
||||
break;
|
||||
|
||||
case 'X':
|
||||
err = _Py_wstrlist_append(&config->nxoption,
|
||||
&config->xoptions,
|
||||
_PyOS_optarg);
|
||||
if (_Py_INIT_FAILED(err)) {
|
||||
return err;
|
||||
if (_PyWstrList_Append(&config->xoptions, _PyOS_optarg) < 0) {
|
||||
return _Py_INIT_NO_MEMORY();
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -1810,10 +1812,10 @@ config_parse_cmdline(_PyCoreConfig *config, _PyCmdline *cmdline,
|
|||
} while (1);
|
||||
|
||||
if (config->run_command == NULL && config->run_module == NULL
|
||||
&& _PyOS_optind < cmdline->args->argc
|
||||
&& wcscmp(cmdline->argv[_PyOS_optind], L"-") != 0)
|
||||
&& _PyOS_optind < cmdline->argv.length
|
||||
&& wcscmp(cmdline->argv.items[_PyOS_optind], L"-") != 0)
|
||||
{
|
||||
config->run_filename = _PyMem_RawWcsdup(cmdline->argv[_PyOS_optind]);
|
||||
config->run_filename = _PyMem_RawWcsdup(cmdline->argv.items[_PyOS_optind]);
|
||||
if (config->run_filename == NULL) {
|
||||
return _Py_INIT_NO_MEMORY();
|
||||
}
|
||||
|
@ -1858,12 +1860,9 @@ cmdline_init_env_warnoptions(_PyCmdline *cmdline, const _PyCoreConfig *config)
|
|||
warning != NULL;
|
||||
warning = WCSTOK(NULL, L",", &context))
|
||||
{
|
||||
_PyInitError err = _Py_wstrlist_append(&cmdline->nenv_warnoption,
|
||||
&cmdline->env_warnoptions,
|
||||
warning);
|
||||
if (_Py_INIT_FAILED(err)) {
|
||||
if (_PyWstrList_Append(&cmdline->env_warnoptions, warning) < 0) {
|
||||
PyMem_RawFree(env);
|
||||
return err;
|
||||
return _Py_INIT_NO_MEMORY();
|
||||
}
|
||||
}
|
||||
PyMem_RawFree(env);
|
||||
|
@ -1875,8 +1874,8 @@ static _PyInitError
|
|||
config_init_program(_PyCoreConfig *config, const _PyCmdline *cmdline)
|
||||
{
|
||||
wchar_t *program;
|
||||
if (cmdline->args->argc >= 1 && cmdline->argv != NULL) {
|
||||
program = cmdline->argv[0];
|
||||
if (cmdline->argv.length >= 1) {
|
||||
program = cmdline->argv.items[0];
|
||||
}
|
||||
else {
|
||||
program = L"";
|
||||
|
@ -1890,28 +1889,10 @@ config_init_program(_PyCoreConfig *config, const _PyCmdline *cmdline)
|
|||
}
|
||||
|
||||
|
||||
static _PyInitError
|
||||
config_add_warnings_optlist(_PyCoreConfig *config,
|
||||
int len, wchar_t * const *options)
|
||||
{
|
||||
for (int i = 0; i < len; i++) {
|
||||
_PyInitError err = _Py_wstrlist_append(&config->nwarnoption,
|
||||
&config->warnoptions,
|
||||
options[i]);
|
||||
if (_Py_INIT_FAILED(err)) {
|
||||
return err;
|
||||
}
|
||||
}
|
||||
return _Py_INIT_OK();
|
||||
}
|
||||
|
||||
|
||||
static _PyInitError
|
||||
config_init_warnoptions(_PyCoreConfig *config, const _PyCmdline *cmdline)
|
||||
{
|
||||
_PyInitError err;
|
||||
|
||||
assert(config->nwarnoption == 0);
|
||||
assert(config->warnoptions.length == 0);
|
||||
|
||||
/* The priority order for warnings configuration is (highest precedence
|
||||
* first):
|
||||
|
@ -1929,26 +1910,17 @@ config_init_warnoptions(_PyCoreConfig *config, const _PyCmdline *cmdline)
|
|||
*/
|
||||
|
||||
if (config->preconfig.dev_mode) {
|
||||
err = _Py_wstrlist_append(&config->nwarnoption,
|
||||
&config->warnoptions,
|
||||
L"default");
|
||||
if (_Py_INIT_FAILED(err)) {
|
||||
return err;
|
||||
if (_PyWstrList_Append(&config->warnoptions, L"default")) {
|
||||
return _Py_INIT_NO_MEMORY();
|
||||
}
|
||||
}
|
||||
|
||||
err = config_add_warnings_optlist(config,
|
||||
cmdline->nenv_warnoption,
|
||||
cmdline->env_warnoptions);
|
||||
if (_Py_INIT_FAILED(err)) {
|
||||
return err;
|
||||
if (_PyWstrList_Extend(&config->warnoptions, &cmdline->env_warnoptions) < 0) {
|
||||
return _Py_INIT_NO_MEMORY();
|
||||
}
|
||||
|
||||
err = config_add_warnings_optlist(config,
|
||||
cmdline->nwarnoption,
|
||||
cmdline->warnoptions);
|
||||
if (_Py_INIT_FAILED(err)) {
|
||||
return err;
|
||||
if (_PyWstrList_Extend(&config->warnoptions, &cmdline->warnoptions) < 0) {
|
||||
return _Py_INIT_NO_MEMORY();
|
||||
}
|
||||
|
||||
/* If the bytes_warning_flag isn't set, bytesobject.c and bytearrayobject.c
|
||||
|
@ -1956,18 +1928,15 @@ config_init_warnoptions(_PyCoreConfig *config, const _PyCmdline *cmdline)
|
|||
* case.
|
||||
*/
|
||||
if (config->bytes_warning) {
|
||||
wchar_t *filter;
|
||||
const wchar_t *filter;
|
||||
if (config->bytes_warning> 1) {
|
||||
filter = L"error::BytesWarning";
|
||||
}
|
||||
else {
|
||||
filter = L"default::BytesWarning";
|
||||
}
|
||||
err = _Py_wstrlist_append(&config->nwarnoption,
|
||||
&config->warnoptions,
|
||||
filter);
|
||||
if (_Py_INIT_FAILED(err)) {
|
||||
return err;
|
||||
if (_PyWstrList_Append(&config->warnoptions, filter)) {
|
||||
return _Py_INIT_NO_MEMORY();
|
||||
}
|
||||
}
|
||||
return _Py_INIT_OK();
|
||||
|
@ -1977,23 +1946,24 @@ config_init_warnoptions(_PyCoreConfig *config, const _PyCmdline *cmdline)
|
|||
static _PyInitError
|
||||
config_init_argv(_PyCoreConfig *config, const _PyCmdline *cmdline)
|
||||
{
|
||||
/* Copy argv to be able to modify it (to force -c/-m) */
|
||||
int argc = cmdline->args->argc - _PyOS_optind;
|
||||
wchar_t **argv;
|
||||
_PyWstrList wargv = _PyWstrList_INIT;
|
||||
|
||||
if (argc <= 0 || cmdline->argv == NULL) {
|
||||
/* Copy argv to be able to modify it (to force -c/-m) */
|
||||
if (cmdline->argv.length <= _PyOS_optind) {
|
||||
/* Ensure at least one (empty) argument is seen */
|
||||
static wchar_t *empty_argv[1] = {L""};
|
||||
argc = 1;
|
||||
argv = _Py_wstrlist_copy(1, empty_argv);
|
||||
if (_PyWstrList_Append(&wargv, L"") < 0) {
|
||||
return _Py_INIT_NO_MEMORY();
|
||||
}
|
||||
}
|
||||
else {
|
||||
argv = _Py_wstrlist_copy(argc, &cmdline->argv[_PyOS_optind]);
|
||||
}
|
||||
|
||||
if (argv == NULL) {
|
||||
return _Py_INIT_NO_MEMORY();
|
||||
_PyWstrList slice;
|
||||
slice.length = cmdline->argv.length - _PyOS_optind;
|
||||
slice.items = &cmdline->argv.items[_PyOS_optind];
|
||||
if (_PyWstrList_Copy(&wargv, &slice) < 0) {
|
||||
return _Py_INIT_NO_MEMORY();
|
||||
}
|
||||
}
|
||||
assert(wargv.length >= 1);
|
||||
|
||||
wchar_t *arg0 = NULL;
|
||||
if (config->run_command != NULL) {
|
||||
|
@ -2007,17 +1977,16 @@ config_init_argv(_PyCoreConfig *config, const _PyCmdline *cmdline)
|
|||
if (arg0 != NULL) {
|
||||
arg0 = _PyMem_RawWcsdup(arg0);
|
||||
if (arg0 == NULL) {
|
||||
_Py_wstrlist_clear(argc, argv);
|
||||
_PyWstrList_Clear(&wargv);
|
||||
return _Py_INIT_NO_MEMORY();
|
||||
}
|
||||
|
||||
assert(argc >= 1);
|
||||
PyMem_RawFree(argv[0]);
|
||||
argv[0] = arg0;
|
||||
PyMem_RawFree(wargv.items[0]);
|
||||
wargv.items[0] = arg0;
|
||||
}
|
||||
|
||||
config->argc = argc;
|
||||
config->argv = argv;
|
||||
_PyWstrList_Clear(&config->argv);
|
||||
config->argv = wargv;
|
||||
return _Py_INIT_OK();
|
||||
}
|
||||
|
||||
|
@ -2097,7 +2066,7 @@ config_from_cmdline(_PyCoreConfig *config, _PyCmdline *cmdline,
|
|||
return err;
|
||||
}
|
||||
|
||||
if (_Py_SetArgcArgv(cmdline->args->argc, cmdline->argv) < 0) {
|
||||
if (_Py_SetArgcArgv(cmdline->argv.length, cmdline->argv.items) < 0) {
|
||||
return _Py_INIT_NO_MEMORY();
|
||||
}
|
||||
return _Py_INIT_OK();
|
||||
|
@ -2117,9 +2086,8 @@ _PyCoreConfig_ReadFromArgv(_PyCoreConfig *config, const _PyArgv *args,
|
|||
|
||||
_PyCmdline 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;
|
||||
}
|
||||
|
|
|
@ -37,9 +37,9 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
int _PyOS_opterr = 1; /* generate error messages */
|
||||
int _PyOS_optind = 1; /* index into argv array */
|
||||
wchar_t *_PyOS_optarg = NULL; /* optional argument */
|
||||
int _PyOS_opterr = 1; /* generate error messages */
|
||||
Py_ssize_t _PyOS_optind = 1; /* index into argv array */
|
||||
const wchar_t *_PyOS_optarg = NULL; /* optional argument */
|
||||
|
||||
static wchar_t *opt_ptr = L"";
|
||||
|
||||
|
@ -61,7 +61,7 @@ void _PyOS_ResetGetOpt(void)
|
|||
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 option;
|
||||
|
|
|
@ -154,14 +154,14 @@ _PyPathConfig_ClearGlobal(void)
|
|||
|
||||
|
||||
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 */
|
||||
for (int i=0; i < count; i++) {
|
||||
for (Py_ssize_t i=0; i < list->length; i++) {
|
||||
if (i != 0) {
|
||||
len++;
|
||||
}
|
||||
len += wcslen(list[i]);
|
||||
len += wcslen(list->items[i]);
|
||||
}
|
||||
|
||||
wchar_t *text = PyMem_RawMalloc(len * sizeof(wchar_t));
|
||||
|
@ -169,8 +169,8 @@ wstrlist_join(wchar_t sep, int count, wchar_t **list)
|
|||
return NULL;
|
||||
}
|
||||
wchar_t *str = text;
|
||||
for (int i=0; i < count; i++) {
|
||||
wchar_t *path = list[i];
|
||||
for (Py_ssize_t i=0; i < list->length; i++) {
|
||||
wchar_t *path = list->items[i];
|
||||
if (i != 0) {
|
||||
*str++ = SEP;
|
||||
}
|
||||
|
@ -194,9 +194,7 @@ _PyCoreConfig_SetPathConfig(const _PyCoreConfig *core_config)
|
|||
_PyInitError err;
|
||||
_PyPathConfig path_config = _PyPathConfig_INIT;
|
||||
|
||||
path_config.module_search_path = wstrlist_join(DELIM,
|
||||
core_config->nmodule_search_path,
|
||||
core_config->module_search_paths);
|
||||
path_config.module_search_path = _PyWstrList_Join(&core_config->module_search_paths, DELIM);
|
||||
if (path_config.module_search_path == NULL) {
|
||||
goto no_memory;
|
||||
}
|
||||
|
@ -244,10 +242,9 @@ static _PyInitError
|
|||
core_config_init_module_search_paths(_PyCoreConfig *config,
|
||||
_PyPathConfig *path_config)
|
||||
{
|
||||
assert(config->module_search_paths == NULL);
|
||||
assert(config->nmodule_search_path < 0);
|
||||
assert(!config->use_module_search_paths);
|
||||
|
||||
config->nmodule_search_path = 0;
|
||||
_PyWstrList_Clear(&config->module_search_paths);
|
||||
|
||||
const wchar_t *sys_path = path_config->module_search_path;
|
||||
const wchar_t delim = DELIM;
|
||||
|
@ -266,12 +263,10 @@ core_config_init_module_search_paths(_PyCoreConfig *config,
|
|||
memcpy(path, sys_path, path_len * sizeof(wchar_t));
|
||||
path[path_len] = L'\0';
|
||||
|
||||
_PyInitError err = _Py_wstrlist_append(&config->nmodule_search_path,
|
||||
&config->module_search_paths,
|
||||
path);
|
||||
int res = _PyWstrList_Append(&config->module_search_paths, path);
|
||||
PyMem_RawFree(path);
|
||||
if (_Py_INIT_FAILED(err)) {
|
||||
return err;
|
||||
if (res < 0) {
|
||||
return _Py_INIT_NO_MEMORY();
|
||||
}
|
||||
|
||||
if (*p == '\0') {
|
||||
|
@ -279,6 +274,7 @@ core_config_init_module_search_paths(_PyCoreConfig *config,
|
|||
}
|
||||
sys_path = p + 1;
|
||||
}
|
||||
config->use_module_search_paths = 1;
|
||||
return _Py_INIT_OK();
|
||||
}
|
||||
|
||||
|
@ -294,7 +290,7 @@ _PyCoreConfig_CalculatePathConfig(_PyCoreConfig *config)
|
|||
goto error;
|
||||
}
|
||||
|
||||
if (config->nmodule_search_path < 0) {
|
||||
if (!config->use_module_search_paths) {
|
||||
err = core_config_init_module_search_paths(config, &path_config);
|
||||
if (_Py_INIT_FAILED(err)) {
|
||||
goto error;
|
||||
|
@ -352,7 +348,7 @@ _PyInitError
|
|||
_PyCoreConfig_InitPathConfig(_PyCoreConfig *config)
|
||||
{
|
||||
/* Do we need to calculate the path? */
|
||||
if ((config->nmodule_search_path < 0)
|
||||
if (!config->use_module_search_paths
|
||||
|| (config->executable == NULL)
|
||||
|| (config->prefix == NULL)
|
||||
#ifdef MS_WINDOWS
|
||||
|
@ -567,8 +563,10 @@ Py_GetProgramName(void)
|
|||
|
||||
/* Compute argv[0] which will be prepended to sys.argv */
|
||||
PyObject*
|
||||
_PyPathConfig_ComputeArgv0(int argc, wchar_t **argv)
|
||||
_PyPathConfig_ComputeArgv0(const _PyWstrList *argv)
|
||||
{
|
||||
assert(_PyWstrList_CheckConsistency(argv));
|
||||
|
||||
wchar_t *argv0;
|
||||
wchar_t *p = NULL;
|
||||
Py_ssize_t n = 0;
|
||||
|
@ -585,8 +583,8 @@ _PyPathConfig_ComputeArgv0(int argc, wchar_t **argv)
|
|||
wchar_t fullpath[MAX_PATH];
|
||||
#endif
|
||||
|
||||
argv0 = argv[0];
|
||||
if (argc > 0 && argv0 != NULL) {
|
||||
if (argv->length > 0) {
|
||||
argv0 = argv->items[0];
|
||||
have_module_arg = (wcscmp(argv0, L"-m") == 0);
|
||||
have_script_arg = !have_module_arg && (wcscmp(argv0, L"-c") != 0);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue