From 74f6568bbd3e70806ea3219e8bacb386ad802ccf Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Fri, 15 Mar 2019 15:08:05 +0100 Subject: 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 --- Include/cpython/coreconfig.h | 42 ++++++++++++++++++++---------------- Include/internal/pycore_coreconfig.h | 37 ++++++++++++++++--------------- Include/internal/pycore_getopt.h | 6 +++--- Include/internal/pycore_pathconfig.h | 2 +- 4 files changed, 46 insertions(+), 41 deletions(-) (limited to 'Include') diff --git a/Include/cpython/coreconfig.h b/Include/cpython/coreconfig.h index 267357676b..bd28c371ce 100644 --- a/Include/cpython/coreconfig.h +++ b/Include/cpython/coreconfig.h @@ -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, \ diff --git a/Include/internal/pycore_coreconfig.h b/Include/internal/pycore_coreconfig.h index 153309de4f..8c5a072e56 100644 --- a/Include/internal/pycore_coreconfig.h +++ b/Include/internal/pycore_coreconfig.h @@ -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); diff --git a/Include/internal/pycore_getopt.h b/Include/internal/pycore_getopt.h index 1d30f5bb99..0d1897c75a 100644 --- a/Include/internal/pycore_getopt.h +++ b/Include/internal/pycore_getopt.h @@ -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 */ diff --git a/Include/internal/pycore_pathconfig.h b/Include/internal/pycore_pathconfig.h index fb6b1d78b3..d0938df541 100644 --- a/Include/internal/pycore_pathconfig.h +++ b/Include/internal/pycore_pathconfig.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, -- cgit v1.2.1