|
|
|
@ -520,34 +520,111 @@ _PyCoreConfig_Clear(_PyCoreConfig *config) |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
int |
|
|
|
/* Copy str into *config_str (duplicate the string) */ |
|
|
|
_PyInitError |
|
|
|
_PyCoreConfig_SetString(char **config_str, const char *str) |
|
|
|
{ |
|
|
|
char *str2; |
|
|
|
if (str != NULL) { |
|
|
|
str2 = _PyMem_RawStrdup(str); |
|
|
|
if (str2 == NULL) { |
|
|
|
return _Py_INIT_NO_MEMORY(); |
|
|
|
} |
|
|
|
} |
|
|
|
else { |
|
|
|
str2 = NULL; |
|
|
|
} |
|
|
|
PyMem_RawFree(*config_str); |
|
|
|
*config_str = str2; |
|
|
|
return _Py_INIT_OK(); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/* Copy str into *config_str (duplicate the string) */ |
|
|
|
_PyInitError |
|
|
|
_PyCoreConfig_SetWideString(wchar_t **config_str, const wchar_t *str) |
|
|
|
{ |
|
|
|
wchar_t *str2; |
|
|
|
if (str != NULL) { |
|
|
|
str2 = _PyMem_RawWcsdup(str); |
|
|
|
if (str2 == NULL) { |
|
|
|
return _Py_INIT_NO_MEMORY(); |
|
|
|
} |
|
|
|
} |
|
|
|
else { |
|
|
|
str2 = NULL; |
|
|
|
} |
|
|
|
PyMem_RawFree(*config_str); |
|
|
|
*config_str = str2; |
|
|
|
return _Py_INIT_OK(); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/* Decode str using Py_DecodeLocale() and set the result into *config_str */ |
|
|
|
static _PyInitError |
|
|
|
_PyCoreConfig_SetWideStringFromStringErr(wchar_t **config_str, const char *str, |
|
|
|
const char *decode_err_msg) |
|
|
|
{ |
|
|
|
wchar_t *str2; |
|
|
|
if (str != NULL) { |
|
|
|
size_t len; |
|
|
|
str2 = Py_DecodeLocale(str, &len); |
|
|
|
if (str2 == NULL) { |
|
|
|
if (len == (size_t)-2) { |
|
|
|
return _Py_INIT_ERR(decode_err_msg); |
|
|
|
} |
|
|
|
else { |
|
|
|
return _Py_INIT_NO_MEMORY(); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
else { |
|
|
|
str2 = NULL; |
|
|
|
} |
|
|
|
PyMem_RawFree(*config_str); |
|
|
|
*config_str = str2; |
|
|
|
return _Py_INIT_OK(); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
_PyInitError |
|
|
|
_PyCoreConfig_SetWideStringFromString(wchar_t **config_str, const char *str) |
|
|
|
{ |
|
|
|
return _PyCoreConfig_SetWideStringFromStringErr( |
|
|
|
config_str, str, "cannot decode string"); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
#define CONFIG_DECODE_LOCALE(config_str, str, NAME) \ |
|
|
|
_PyCoreConfig_SetWideStringFromStringErr(config_str, str, \ |
|
|
|
"cannot decode " NAME) |
|
|
|
|
|
|
|
|
|
|
|
_PyInitError |
|
|
|
_PyCoreConfig_Copy(_PyCoreConfig *config, const _PyCoreConfig *config2) |
|
|
|
{ |
|
|
|
_PyInitError err; |
|
|
|
_PyCoreConfig_Clear(config); |
|
|
|
|
|
|
|
#define COPY_ATTR(ATTR) config->ATTR = config2->ATTR |
|
|
|
#define COPY_STR_ATTR(ATTR) \ |
|
|
|
do { \ |
|
|
|
if (config2->ATTR != NULL) { \ |
|
|
|
config->ATTR = _PyMem_RawStrdup(config2->ATTR); \ |
|
|
|
if (config->ATTR == NULL) { \ |
|
|
|
return -1; \ |
|
|
|
} \ |
|
|
|
err = _PyCoreConfig_SetString(&config->ATTR, config2->ATTR); \ |
|
|
|
if (_Py_INIT_FAILED(err)) { \ |
|
|
|
return err; \ |
|
|
|
} \ |
|
|
|
} while (0) |
|
|
|
#define COPY_WSTR_ATTR(ATTR) \ |
|
|
|
do { \ |
|
|
|
if (config2->ATTR != NULL) { \ |
|
|
|
config->ATTR = _PyMem_RawWcsdup(config2->ATTR); \ |
|
|
|
if (config->ATTR == NULL) { \ |
|
|
|
return -1; \ |
|
|
|
} \ |
|
|
|
err = _PyCoreConfig_SetWideString(&config->ATTR, config2->ATTR); \ |
|
|
|
if (_Py_INIT_FAILED(err)) { \ |
|
|
|
return err; \ |
|
|
|
} \ |
|
|
|
} while (0) |
|
|
|
#define COPY_WSTRLIST(LIST) \ |
|
|
|
do { \ |
|
|
|
if (_PyWstrList_Copy(&config->LIST, &config2->LIST) < 0 ) { \ |
|
|
|
return -1; \ |
|
|
|
return _Py_INIT_NO_MEMORY(); \ |
|
|
|
} \ |
|
|
|
} while (0) |
|
|
|
|
|
|
|
@ -617,7 +694,7 @@ _PyCoreConfig_Copy(_PyCoreConfig *config, const _PyCoreConfig *config2) |
|
|
|
#undef COPY_STR_ATTR |
|
|
|
#undef COPY_WSTR_ATTR |
|
|
|
#undef COPY_WSTRLIST |
|
|
|
return 0; |
|
|
|
return _Py_INIT_OK(); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@ -746,54 +823,44 @@ _PyCoreConfig_GetEnv(const _PyCoreConfig *config, const char *name) |
|
|
|
/* Get a copy of the environment variable as wchar_t*. |
|
|
|
Return 0 on success, but *dest can be NULL. |
|
|
|
Return -1 on memory allocation failure. Return -2 on decoding error. */ |
|
|
|
static int |
|
|
|
static _PyInitError |
|
|
|
_PyCoreConfig_GetEnvDup(const _PyCoreConfig *config, |
|
|
|
wchar_t **dest, |
|
|
|
wchar_t *wname, char *name) |
|
|
|
wchar_t *wname, char *name, |
|
|
|
const char *decode_err_msg) |
|
|
|
{ |
|
|
|
assert(*dest == NULL); |
|
|
|
assert(config->use_environment >= 0); |
|
|
|
|
|
|
|
if (!config->use_environment) { |
|
|
|
*dest = NULL; |
|
|
|
return 0; |
|
|
|
return _Py_INIT_OK(); |
|
|
|
} |
|
|
|
|
|
|
|
#ifdef MS_WINDOWS |
|
|
|
const wchar_t *var = _wgetenv(wname); |
|
|
|
if (!var || var[0] == '\0') { |
|
|
|
*dest = NULL; |
|
|
|
return 0; |
|
|
|
} |
|
|
|
|
|
|
|
wchar_t *copy = _PyMem_RawWcsdup(var); |
|
|
|
if (copy == NULL) { |
|
|
|
return -1; |
|
|
|
return _Py_INIT_OK(); |
|
|
|
} |
|
|
|
|
|
|
|
*dest = copy; |
|
|
|
return _PyCoreConfig_SetWideString(dest, var); |
|
|
|
#else |
|
|
|
const char *var = getenv(name); |
|
|
|
if (!var || var[0] == '\0') { |
|
|
|
*dest = NULL; |
|
|
|
return 0; |
|
|
|
return _Py_INIT_OK(); |
|
|
|
} |
|
|
|
|
|
|
|
size_t len; |
|
|
|
wchar_t *wvar = Py_DecodeLocale(var, &len); |
|
|
|
if (!wvar) { |
|
|
|
if (len == (size_t)-2) { |
|
|
|
return -2; |
|
|
|
} |
|
|
|
else { |
|
|
|
return -1; |
|
|
|
} |
|
|
|
} |
|
|
|
*dest = wvar; |
|
|
|
return _PyCoreConfig_SetWideStringFromStringErr(dest, var, decode_err_msg); |
|
|
|
#endif |
|
|
|
return 0; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
#define CONFIG_GET_ENV_DUP(CONFIG, DEST, WNAME, NAME) \ |
|
|
|
_PyCoreConfig_GetEnvDup(CONFIG, DEST, WNAME, NAME, "cannot decode " NAME) |
|
|
|
|
|
|
|
|
|
|
|
static void |
|
|
|
_PyCoreConfig_GetGlobalConfig(_PyCoreConfig *config) |
|
|
|
{ |
|
|
|
@ -876,6 +943,7 @@ _PyCoreConfig_SetGlobalConfig(const _PyCoreConfig *config) |
|
|
|
static _PyInitError |
|
|
|
config_init_program_name(_PyCoreConfig *config) |
|
|
|
{ |
|
|
|
_PyInitError err; |
|
|
|
assert(config->program_name == NULL); |
|
|
|
|
|
|
|
/* If Py_SetProgramName() was called, use its value */ |
|
|
|
@ -900,13 +968,11 @@ config_init_program_name(_PyCoreConfig *config) |
|
|
|
script. */ |
|
|
|
const char *p = _PyCoreConfig_GetEnv(config, "PYTHONEXECUTABLE"); |
|
|
|
if (p != NULL) { |
|
|
|
size_t len; |
|
|
|
wchar_t* program_name = Py_DecodeLocale(p, &len); |
|
|
|
if (program_name == NULL) { |
|
|
|
return DECODE_LOCALE_ERR("PYTHONEXECUTABLE environment " |
|
|
|
"variable", (Py_ssize_t)len); |
|
|
|
err = CONFIG_DECODE_LOCALE(&config->program_name, p, |
|
|
|
"PYTHONEXECUTABLE environment variable"); |
|
|
|
if (_Py_INIT_FAILED(err)) { |
|
|
|
return err; |
|
|
|
} |
|
|
|
config->program_name = program_name; |
|
|
|
return _Py_INIT_OK(); |
|
|
|
} |
|
|
|
#ifdef WITH_NEXT_FRAMEWORK |
|
|
|
@ -916,13 +982,11 @@ config_init_program_name(_PyCoreConfig *config) |
|
|
|
/* Used by Mac/Tools/pythonw.c to forward |
|
|
|
* the argv0 of the stub executable |
|
|
|
*/ |
|
|
|
size_t len; |
|
|
|
wchar_t* program_name = Py_DecodeLocale(pyvenv_launcher, &len); |
|
|
|
if (program_name == NULL) { |
|
|
|
return DECODE_LOCALE_ERR("__PYVENV_LAUNCHER__ environment " |
|
|
|
"variable", (Py_ssize_t)len); |
|
|
|
err = CONFIG_DECODE_LOCALE(&config->program_name, pyvenv_launcher, |
|
|
|
"__PYVENV_LAUNCHER__ environment variable"); |
|
|
|
if (_Py_INIT_FAILED(err)) { |
|
|
|
return err; |
|
|
|
} |
|
|
|
config->program_name = program_name; |
|
|
|
return _Py_INIT_OK(); |
|
|
|
} |
|
|
|
} |
|
|
|
@ -931,9 +995,10 @@ config_init_program_name(_PyCoreConfig *config) |
|
|
|
|
|
|
|
/* Use argv[0] by default, if available */ |
|
|
|
if (config->program != NULL) { |
|
|
|
config->program_name = _PyMem_RawWcsdup(config->program); |
|
|
|
if (config->program_name == NULL) { |
|
|
|
return _Py_INIT_NO_MEMORY(); |
|
|
|
err = _PyCoreConfig_SetWideString(&config->program_name, |
|
|
|
config->program); |
|
|
|
if (_Py_INIT_FAILED(err)) { |
|
|
|
return err; |
|
|
|
} |
|
|
|
return _Py_INIT_OK(); |
|
|
|
} |
|
|
|
@ -944,9 +1009,9 @@ config_init_program_name(_PyCoreConfig *config) |
|
|
|
#else |
|
|
|
const wchar_t *default_program_name = L"python3"; |
|
|
|
#endif |
|
|
|
config->program_name = _PyMem_RawWcsdup(default_program_name); |
|
|
|
if (config->program_name == NULL) { |
|
|
|
return _Py_INIT_NO_MEMORY(); |
|
|
|
err = _PyCoreConfig_SetWideString(&config->program_name, default_program_name); |
|
|
|
if (_Py_INIT_FAILED(err)) { |
|
|
|
return err; |
|
|
|
} |
|
|
|
return _Py_INIT_OK(); |
|
|
|
} |
|
|
|
@ -959,13 +1024,13 @@ config_init_executable(_PyCoreConfig *config) |
|
|
|
/* If Py_SetProgramFullPath() was called, use its value */ |
|
|
|
const wchar_t *program_full_path = _Py_path_config.program_full_path; |
|
|
|
if (program_full_path != NULL) { |
|
|
|
config->executable = _PyMem_RawWcsdup(program_full_path); |
|
|
|
if (config->executable == NULL) { |
|
|
|
return _Py_INIT_NO_MEMORY(); |
|
|
|
_PyInitError err = _PyCoreConfig_SetWideString(&config->executable, |
|
|
|
program_full_path); |
|
|
|
if (_Py_INIT_FAILED(err)) { |
|
|
|
return err; |
|
|
|
} |
|
|
|
return _Py_INIT_OK(); |
|
|
|
} |
|
|
|
|
|
|
|
return _Py_INIT_OK(); |
|
|
|
} |
|
|
|
|
|
|
|
@ -985,20 +1050,15 @@ config_init_home(_PyCoreConfig *config) |
|
|
|
/* If Py_SetPythonHome() was called, use its value */ |
|
|
|
wchar_t *home = _Py_path_config.home; |
|
|
|
if (home) { |
|
|
|
config->home = _PyMem_RawWcsdup(home); |
|
|
|
if (config->home == NULL) { |
|
|
|
return _Py_INIT_NO_MEMORY(); |
|
|
|
_PyInitError err = _PyCoreConfig_SetWideString(&config->home, home); |
|
|
|
if (_Py_INIT_FAILED(err)) { |
|
|
|
return err; |
|
|
|
} |
|
|
|
return _Py_INIT_OK(); |
|
|
|
} |
|
|
|
|
|
|
|
int res = _PyCoreConfig_GetEnvDup(config, &home, |
|
|
|
L"PYTHONHOME", "PYTHONHOME"); |
|
|
|
if (res < 0) { |
|
|
|
return DECODE_LOCALE_ERR("PYTHONHOME", res); |
|
|
|
} |
|
|
|
config->home = home; |
|
|
|
return _Py_INIT_OK(); |
|
|
|
return CONFIG_GET_ENV_DUP(config, &config->home, |
|
|
|
L"PYTHONHOME", "PYTHONHOME"); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@ -1055,6 +1115,7 @@ config_wstr_to_int(const wchar_t *wstr, int *result) |
|
|
|
static _PyInitError |
|
|
|
config_read_env_vars(_PyCoreConfig *config) |
|
|
|
{ |
|
|
|
_PyInitError err; |
|
|
|
int use_env = config->use_environment; |
|
|
|
|
|
|
|
/* Get environment variables */ |
|
|
|
@ -1094,17 +1155,15 @@ config_read_env_vars(_PyCoreConfig *config) |
|
|
|
} |
|
|
|
|
|
|
|
if (config->module_search_path_env == NULL) { |
|
|
|
wchar_t *path; |
|
|
|
int res = _PyCoreConfig_GetEnvDup(config, &path, |
|
|
|
L"PYTHONPATH", "PYTHONPATH"); |
|
|
|
if (res < 0) { |
|
|
|
return DECODE_LOCALE_ERR("PYTHONPATH", res); |
|
|
|
err = CONFIG_GET_ENV_DUP(config, &config->module_search_path_env, |
|
|
|
L"PYTHONPATH", "PYTHONPATH"); |
|
|
|
if (_Py_INIT_FAILED(err)) { |
|
|
|
return err; |
|
|
|
} |
|
|
|
config->module_search_path_env = path; |
|
|
|
} |
|
|
|
|
|
|
|
if (config->use_hash_seed < 0) { |
|
|
|
_PyInitError err = config_init_hash_seed(config); |
|
|
|
err = config_init_hash_seed(config); |
|
|
|
if (_Py_INIT_FAILED(err)) { |
|
|
|
return err; |
|
|
|
} |
|
|
|
@ -1174,24 +1233,16 @@ config_init_pycache_prefix(_PyCoreConfig *config) |
|
|
|
} |
|
|
|
} |
|
|
|
else { |
|
|
|
// -X pycache_prefix= can cancel the env var |
|
|
|
// PYTHONPYCACHEPREFIX env var ignored |
|
|
|
// if "-X pycache_prefix=" option is used |
|
|
|
config->pycache_prefix = NULL; |
|
|
|
} |
|
|
|
return _Py_INIT_OK(); |
|
|
|
} |
|
|
|
else { |
|
|
|
wchar_t *env; |
|
|
|
int res = _PyCoreConfig_GetEnvDup(config, &env, |
|
|
|
L"PYTHONPYCACHEPREFIX", |
|
|
|
"PYTHONPYCACHEPREFIX"); |
|
|
|
if (res < 0) { |
|
|
|
return DECODE_LOCALE_ERR("PYTHONPYCACHEPREFIX", res); |
|
|
|
} |
|
|
|
|
|
|
|
if (env) { |
|
|
|
config->pycache_prefix = env; |
|
|
|
} |
|
|
|
} |
|
|
|
return _Py_INIT_OK(); |
|
|
|
return CONFIG_GET_ENV_DUP(config, &config->pycache_prefix, |
|
|
|
L"PYTHONPYCACHEPREFIX", |
|
|
|
"PYTHONPYCACHEPREFIX"); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@ -1270,11 +1321,9 @@ config_get_locale_encoding(char **locale_encoding) |
|
|
|
"nl_langinfo(CODESET) failed"); |
|
|
|
} |
|
|
|
#endif |
|
|
|
*locale_encoding = _PyMem_RawStrdup(encoding); |
|
|
|
if (*locale_encoding == NULL) { |
|
|
|
return _Py_INIT_NO_MEMORY(); |
|
|
|
} |
|
|
|
return _Py_INIT_OK(); |
|
|
|
|
|
|
|
assert(*locale_encoding == NULL); |
|
|
|
return _PyCoreConfig_SetString(locale_encoding, encoding); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@ -1282,19 +1331,23 @@ static _PyInitError |
|
|
|
config_init_stdio_encoding(_PyCoreConfig *config, |
|
|
|
const _PyPreConfig *preconfig) |
|
|
|
{ |
|
|
|
_PyInitError err; |
|
|
|
|
|
|
|
/* If Py_SetStandardStreamEncoding() have been called, use these |
|
|
|
parameters. */ |
|
|
|
if (config->stdio_encoding == NULL && _Py_StandardStreamEncoding != NULL) { |
|
|
|
config->stdio_encoding = _PyMem_RawStrdup(_Py_StandardStreamEncoding); |
|
|
|
if (config->stdio_encoding == NULL) { |
|
|
|
return _Py_INIT_NO_MEMORY(); |
|
|
|
err = _PyCoreConfig_SetString(&config->stdio_encoding, |
|
|
|
_Py_StandardStreamEncoding); |
|
|
|
if (_Py_INIT_FAILED(err)) { |
|
|
|
return err; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
if (config->stdio_errors == NULL && _Py_StandardStreamErrors != NULL) { |
|
|
|
config->stdio_errors = _PyMem_RawStrdup(_Py_StandardStreamErrors); |
|
|
|
if (config->stdio_errors == NULL) { |
|
|
|
return _Py_INIT_NO_MEMORY(); |
|
|
|
err = _PyCoreConfig_SetString(&config->stdio_errors, |
|
|
|
_Py_StandardStreamErrors); |
|
|
|
if (_Py_INIT_FAILED(err)) { |
|
|
|
return err; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
@ -1305,27 +1358,30 @@ config_init_stdio_encoding(_PyCoreConfig *config, |
|
|
|
/* PYTHONIOENCODING environment variable */ |
|
|
|
const char *opt = _PyCoreConfig_GetEnv(config, "PYTHONIOENCODING"); |
|
|
|
if (opt) { |
|
|
|
char *pythonioencoding = _PyMem_RawStrdup(opt); |
|
|
|
if (pythonioencoding == NULL) { |
|
|
|
return _Py_INIT_NO_MEMORY(); |
|
|
|
/* _PyCoreConfig_SetString() requires dest to be initialized to NULL */ |
|
|
|
char *pythonioencoding = NULL; |
|
|
|
err = _PyCoreConfig_SetString(&pythonioencoding, opt); |
|
|
|
if (_Py_INIT_FAILED(err)) { |
|
|
|
return err; |
|
|
|
} |
|
|
|
|
|
|
|
char *err = strchr(pythonioencoding, ':'); |
|
|
|
if (err) { |
|
|
|
*err = '\0'; |
|
|
|
err++; |
|
|
|
if (!err[0]) { |
|
|
|
err = NULL; |
|
|
|
char *errors = strchr(pythonioencoding, ':'); |
|
|
|
if (errors) { |
|
|
|
*errors = '\0'; |
|
|
|
errors++; |
|
|
|
if (!errors[0]) { |
|
|
|
errors = NULL; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
/* Does PYTHONIOENCODING contain an encoding? */ |
|
|
|
if (pythonioencoding[0]) { |
|
|
|
if (config->stdio_encoding == NULL) { |
|
|
|
config->stdio_encoding = _PyMem_RawStrdup(pythonioencoding); |
|
|
|
if (config->stdio_encoding == NULL) { |
|
|
|
err = _PyCoreConfig_SetString(&config->stdio_encoding, |
|
|
|
pythonioencoding); |
|
|
|
if (_Py_INIT_FAILED(err)) { |
|
|
|
PyMem_RawFree(pythonioencoding); |
|
|
|
return _Py_INIT_NO_MEMORY(); |
|
|
|
return err; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
@ -1333,16 +1389,16 @@ config_init_stdio_encoding(_PyCoreConfig *config, |
|
|
|
use "strict" error handler by default. |
|
|
|
PYTHONIOENCODING=latin1 behaves as |
|
|
|
PYTHONIOENCODING=latin1:strict. */ |
|
|
|
if (!err) { |
|
|
|
err = "strict"; |
|
|
|
if (!errors) { |
|
|
|
errors = "strict"; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
if (config->stdio_errors == NULL && err != NULL) { |
|
|
|
config->stdio_errors = _PyMem_RawStrdup(err); |
|
|
|
if (config->stdio_errors == NULL) { |
|
|
|
if (config->stdio_errors == NULL && errors != NULL) { |
|
|
|
err = _PyCoreConfig_SetString(&config->stdio_errors, errors); |
|
|
|
if (_Py_INIT_FAILED(err)) { |
|
|
|
PyMem_RawFree(pythonioencoding); |
|
|
|
return _Py_INIT_NO_MEMORY(); |
|
|
|
return err; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
@ -1352,31 +1408,35 @@ config_init_stdio_encoding(_PyCoreConfig *config, |
|
|
|
/* UTF-8 Mode uses UTF-8/surrogateescape */ |
|
|
|
if (preconfig->utf8_mode) { |
|
|
|
if (config->stdio_encoding == NULL) { |
|
|
|
config->stdio_encoding = _PyMem_RawStrdup("utf-8"); |
|
|
|
if (config->stdio_encoding == NULL) { |
|
|
|
return _Py_INIT_NO_MEMORY(); |
|
|
|
err = _PyCoreConfig_SetString(&config->stdio_encoding, |
|
|
|
"utf-8"); |
|
|
|
if (_Py_INIT_FAILED(err)) { |
|
|
|
return err; |
|
|
|
} |
|
|
|
} |
|
|
|
if (config->stdio_errors == NULL) { |
|
|
|
config->stdio_errors = _PyMem_RawStrdup("surrogateescape"); |
|
|
|
if (config->stdio_errors == NULL) { |
|
|
|
return _Py_INIT_NO_MEMORY(); |
|
|
|
err = _PyCoreConfig_SetString(&config->stdio_errors, |
|
|
|
"surrogateescape"); |
|
|
|
if (_Py_INIT_FAILED(err)) { |
|
|
|
return err; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
/* Choose the default error handler based on the current locale. */ |
|
|
|
if (config->stdio_encoding == NULL) { |
|
|
|
_PyInitError err = config_get_locale_encoding(&config->stdio_encoding); |
|
|
|
err = config_get_locale_encoding(&config->stdio_encoding); |
|
|
|
if (_Py_INIT_FAILED(err)) { |
|
|
|
return err; |
|
|
|
} |
|
|
|
} |
|
|
|
if (config->stdio_errors == NULL) { |
|
|
|
const char *errors = config_get_stdio_errors(config); |
|
|
|
config->stdio_errors = _PyMem_RawStrdup(errors); |
|
|
|
if (config->stdio_errors == NULL) { |
|
|
|
return _Py_INIT_NO_MEMORY(); |
|
|
|
assert(errors != NULL); |
|
|
|
|
|
|
|
err = _PyCoreConfig_SetString(&config->stdio_errors, errors); |
|
|
|
if (_Py_INIT_FAILED(err)) { |
|
|
|
return err; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
@ -1387,19 +1447,23 @@ config_init_stdio_encoding(_PyCoreConfig *config, |
|
|
|
static _PyInitError |
|
|
|
config_init_fs_encoding(_PyCoreConfig *config, const _PyPreConfig *preconfig) |
|
|
|
{ |
|
|
|
_PyInitError err; |
|
|
|
|
|
|
|
#ifdef MS_WINDOWS |
|
|
|
if (preconfig->legacy_windows_fs_encoding) { |
|
|
|
/* Legacy Windows filesystem encoding: mbcs/replace */ |
|
|
|
if (config->filesystem_encoding == NULL) { |
|
|
|
config->filesystem_encoding = _PyMem_RawStrdup("mbcs"); |
|
|
|
if (config->filesystem_encoding == NULL) { |
|
|
|
return _Py_INIT_NO_MEMORY(); |
|
|
|
err = _PyCoreConfig_SetString(&config->filesystem_encoding, |
|
|
|
"mbcs"); |
|
|
|
if (_Py_INIT_FAILED(err)) { |
|
|
|
return err; |
|
|
|
} |
|
|
|
} |
|
|
|
if (config->filesystem_errors == NULL) { |
|
|
|
config->filesystem_errors = _PyMem_RawStrdup("replace"); |
|
|
|
if (config->filesystem_errors == NULL) { |
|
|
|
return _Py_INIT_NO_MEMORY(); |
|
|
|
err = _PyCoreConfig_SetString(&config->filesystem_errors, |
|
|
|
"replace"); |
|
|
|
if (_Py_INIT_FAILED(err)) { |
|
|
|
return err; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
@ -1409,51 +1473,54 @@ config_init_fs_encoding(_PyCoreConfig *config, const _PyPreConfig *preconfig) |
|
|
|
Note: UTF-8 Mode takes the same code path and the Legacy Windows FS |
|
|
|
encoding has the priortiy over UTF-8 Mode. */ |
|
|
|
if (config->filesystem_encoding == NULL) { |
|
|
|
config->filesystem_encoding = _PyMem_RawStrdup("utf-8"); |
|
|
|
if (config->filesystem_encoding == NULL) { |
|
|
|
return _Py_INIT_NO_MEMORY(); |
|
|
|
err = _PyCoreConfig_SetString(&config->filesystem_encoding, |
|
|
|
"utf-8"); |
|
|
|
if (_Py_INIT_FAILED(err)) { |
|
|
|
return err; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
if (config->filesystem_errors == NULL) { |
|
|
|
config->filesystem_errors = _PyMem_RawStrdup("surrogatepass"); |
|
|
|
if (config->filesystem_errors == NULL) { |
|
|
|
return _Py_INIT_NO_MEMORY(); |
|
|
|
err = _PyCoreConfig_SetString(&config->filesystem_errors, |
|
|
|
"surrogatepass"); |
|
|
|
if (_Py_INIT_FAILED(err)) { |
|
|
|
return err; |
|
|
|
} |
|
|
|
} |
|
|
|
#else |
|
|
|
if (config->filesystem_encoding == NULL) { |
|
|
|
if (preconfig->utf8_mode) { |
|
|
|
/* UTF-8 Mode use: utf-8/surrogateescape */ |
|
|
|
config->filesystem_encoding = _PyMem_RawStrdup("utf-8"); |
|
|
|
err = _PyCoreConfig_SetString(&config->filesystem_encoding, |
|
|
|
"utf-8"); |
|
|
|
/* errors defaults to surrogateescape above */ |
|
|
|
} |
|
|
|
else if (_Py_GetForceASCII()) { |
|
|
|
config->filesystem_encoding = _PyMem_RawStrdup("ascii"); |
|
|
|
err = _PyCoreConfig_SetString(&config->filesystem_encoding, |
|
|
|
"ascii"); |
|
|
|
} |
|
|
|
else { |
|
|
|
/* macOS and Android use UTF-8, |
|
|
|
other platforms use the locale encoding. */ |
|
|
|
#if defined(__APPLE__) || defined(__ANDROID__) |
|
|
|
config->filesystem_encoding = _PyMem_RawStrdup("utf-8"); |
|
|
|
err = _PyCoreConfig_SetString(&config->filesystem_encoding, |
|
|
|
"utf-8"); |
|
|
|
#else |
|
|
|
_PyInitError err = config_get_locale_encoding(&config->filesystem_encoding); |
|
|
|
if (_Py_INIT_FAILED(err)) { |
|
|
|
return err; |
|
|
|
} |
|
|
|
err = config_get_locale_encoding(&config->filesystem_encoding); |
|
|
|
#endif |
|
|
|
} |
|
|
|
|
|
|
|
if (config->filesystem_encoding == NULL) { |
|
|
|
return _Py_INIT_NO_MEMORY(); |
|
|
|
if (_Py_INIT_FAILED(err)) { |
|
|
|
return err; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
if (config->filesystem_errors == NULL) { |
|
|
|
/* by default, use the "surrogateescape" error handler */ |
|
|
|
config->filesystem_errors = _PyMem_RawStrdup("surrogateescape"); |
|
|
|
if (config->filesystem_errors == NULL) { |
|
|
|
return _Py_INIT_NO_MEMORY(); |
|
|
|
err = _PyCoreConfig_SetString(&config->filesystem_errors, |
|
|
|
"surrogateescape"); |
|
|
|
if (_Py_INIT_FAILED(err)) { |
|
|
|
return err; |
|
|
|
} |
|
|
|
} |
|
|
|
#endif |
|
|
|
@ -1828,13 +1895,16 @@ config_parse_cmdline(_PyCoreConfig *config, _PyPreCmdline *precmdline, |
|
|
|
static _PyInitError |
|
|
|
config_init_env_warnoptions(const _PyCoreConfig *config, _PyWstrList *warnoptions) |
|
|
|
{ |
|
|
|
wchar_t *env; |
|
|
|
int res = _PyCoreConfig_GetEnvDup(config, &env, |
|
|
|
L"PYTHONWARNINGS", "PYTHONWARNINGS"); |
|
|
|
if (res < 0) { |
|
|
|
return DECODE_LOCALE_ERR("PYTHONWARNINGS", res); |
|
|
|
_PyInitError err; |
|
|
|
/* CONFIG_GET_ENV_DUP requires dest to be initialized to NULL */ |
|
|
|
wchar_t *env = NULL; |
|
|
|
err = CONFIG_GET_ENV_DUP(config, &env, |
|
|
|
L"PYTHONWARNINGS", "PYTHONWARNINGS"); |
|
|
|
if (_Py_INIT_FAILED(err)) { |
|
|
|
return err; |
|
|
|
} |
|
|
|
|
|
|
|
/* env var is not set or is empty */ |
|
|
|
if (env == NULL) { |
|
|
|
return _Py_INIT_OK(); |
|
|
|
} |
|
|
|
|