diff options
Diffstat (limited to 'Modules/main.c')
| -rw-r--r-- | Modules/main.c | 159 |
1 files changed, 124 insertions, 35 deletions
diff --git a/Modules/main.c b/Modules/main.c index 0f7498d610..c6ffb15d9f 100644 --- a/Modules/main.c +++ b/Modules/main.c @@ -1834,6 +1834,17 @@ config_init_utf8_mode(_PyCoreConfig *config) return _Py_INIT_OK(); } +#ifndef MS_WINDOWS + /* The C locale and the POSIX locale enable the UTF-8 Mode (PEP 540) */ + const char *ctype_loc = setlocale(LC_CTYPE, NULL); + if (ctype_loc != NULL + && (strcmp(ctype_loc, "C") == 0 || strcmp(ctype_loc, "POSIX") == 0)) + { + config->utf8_mode = 1; + return _Py_INIT_OK(); + } +#endif + return _Py_INIT_OK(); } @@ -1857,16 +1868,18 @@ config_read_env_vars(_PyCoreConfig *config) const char *env = config_get_env_var("PYTHONCOERCECLOCALE"); if (env) { if (strcmp(env, "0") == 0) { - if (config->coerce_c_locale < 0) { - config->coerce_c_locale = 0; + if (config->_coerce_c_locale < 0) { + config->_coerce_c_locale = 0; } } else if (strcmp(env, "warn") == 0) { - config->coerce_c_locale_warn = 1; + if (config->_coerce_c_locale_warn < 0) { + config->_coerce_c_locale_warn = 1; + } } else { - if (config->coerce_c_locale < 0) { - config->coerce_c_locale = 1; + if (config->_coerce_c_locale < 0) { + config->_coerce_c_locale = 1; } } } @@ -2046,7 +2059,7 @@ pymain_read_conf(_PyMain *pymain, _Py_CommandLineDetails *cmdline) * See the documentation of the PYTHONCOERCECLOCALE setting for more * details. */ - if (config->coerce_c_locale && !locale_coerced) { + if (config->_coerce_c_locale && !locale_coerced) { locale_coerced = 1; _Py_CoerceLegacyLocale(config); encoding_changed = 1; @@ -2073,7 +2086,7 @@ pymain_read_conf(_PyMain *pymain, _Py_CommandLineDetails *cmdline) pymain_read_conf_impl(). Reset Py_IsolatedFlag and Py_NoSiteFlag modified by _PyCoreConfig_Read(). */ int new_utf8_mode = config->utf8_mode; - int new_coerce_c_locale = config->coerce_c_locale; + int new_coerce_c_locale = config->_coerce_c_locale; Py_IgnoreEnvironmentFlag = init_ignore_env; if (_PyCoreConfig_Copy(config, &save_config) < 0) { pymain->err = _Py_INIT_NO_MEMORY(); @@ -2085,7 +2098,7 @@ pymain_read_conf(_PyMain *pymain, _Py_CommandLineDetails *cmdline) cmdline_get_global_config(cmdline); _PyCoreConfig_GetGlobalConfig(config); config->utf8_mode = new_utf8_mode; - config->coerce_c_locale = new_coerce_c_locale; + config->_coerce_c_locale = new_coerce_c_locale; /* The encoding changed: read again the configuration with the new encoding */ @@ -2103,28 +2116,76 @@ done: } -static void -config_init_locale(_PyCoreConfig *config) +static _PyInitError +config_init_coerce_c_locale(_PyCoreConfig *config) { - if (config->coerce_c_locale < 0) { - /* The C locale enables the C locale coercion (PEP 538) */ - if (_Py_LegacyLocaleDetected()) { - config->coerce_c_locale = 1; + const wchar_t *xopt = config_get_xoption(config, L"coerce_c_locale"); + if (xopt) { + wchar_t *sep = wcschr(xopt, L'='); + if (sep) { + xopt = sep + 1; + if (wcscmp(xopt, L"1") == 0) { + if (config->_coerce_c_locale < 0) { + config->_coerce_c_locale = 1; + } + } + else if (wcscmp(xopt, L"0") == 0) { + if (config->_coerce_c_locale < 0) { + config->_coerce_c_locale = 0; + } + } + else if (wcscmp(xopt, L"warn") == 0) { + if (config->_coerce_c_locale_warn < 0) { + config->_coerce_c_locale_warn = 1; + } + } + else { + return _Py_INIT_USER_ERR("invalid -X coerce_c_locale option value"); + } + } + else { + if (config->_coerce_c_locale < 0) { + config->_coerce_c_locale = 1; + } + } + + if (config->_coerce_c_locale_warn < 0) { + config->_coerce_c_locale_warn = 0; } } -#ifndef MS_WINDOWS - if (config->utf8_mode < 0) { - /* The C locale and the POSIX locale enable the UTF-8 Mode (PEP 540) */ - const char *ctype_loc = setlocale(LC_CTYPE, NULL); - if (ctype_loc != NULL - && (strcmp(ctype_loc, "C") == 0 - || strcmp(ctype_loc, "POSIX") == 0)) - { - config->utf8_mode = 1; + const char *env = config_get_env_var("PYTHONCOERCECLOCALE"); + if (env) { + if (strcmp(env, "0") == 0) { + if (config->_coerce_c_locale < 0) { + config->_coerce_c_locale = 0; + } + } + else if (strcmp(env, "warn") == 0) { + if (config->_coerce_c_locale_warn < 0) { + config->_coerce_c_locale_warn = 1; + } + } + else { + if (config->_coerce_c_locale < 0) { + config->_coerce_c_locale = 1; + } + } + + if (config->_coerce_c_locale_warn < 0) { + config->_coerce_c_locale_warn = 0; } } -#endif + + if (config->_coerce_c_locale < 0) { + /* The C locale enables the C locale coercion (PEP 538) */ + if (_Py_LegacyLocaleDetected()) { + config->_coerce_c_locale = 1; + return _Py_INIT_OK(); + } + } + + return _Py_INIT_OK(); } @@ -2284,8 +2345,11 @@ _PyCoreConfig_Read(_PyCoreConfig *config) } } - if (config->utf8_mode < 0 || config->coerce_c_locale < 0) { - config_init_locale(config); + if (config->_coerce_c_locale < 0 || config->_coerce_c_locale_warn < 0) { + err = config_init_coerce_c_locale(config); + if (_Py_INIT_FAILED(err)) { + return err; + } } if (!config->_disable_importlib) { @@ -2317,8 +2381,11 @@ _PyCoreConfig_Read(_PyCoreConfig *config) if (config->tracemalloc < 0) { config->tracemalloc = 0; } - if (config->coerce_c_locale < 0) { - config->coerce_c_locale = 0; + if (config->_coerce_c_locale < 0) { + config->_coerce_c_locale = 0; + } + if (config->_coerce_c_locale_warn < 0) { + config->_coerce_c_locale_warn = 0; } if (config->utf8_mode < 0) { config->utf8_mode = 0; @@ -2327,6 +2394,10 @@ _PyCoreConfig_Read(_PyCoreConfig *config) config->argc = 0; } + assert(config->_coerce_c_locale >= 0); + assert(config->_coerce_c_locale_warn >= 0); + assert(config->ignore_environment >= 0); + return _Py_INIT_OK(); } @@ -2410,8 +2481,8 @@ _PyCoreConfig_Copy(_PyCoreConfig *config, const _PyCoreConfig *config2) COPY_ATTR(dump_refs); COPY_ATTR(malloc_stats); - COPY_ATTR(coerce_c_locale); - COPY_ATTR(coerce_c_locale_warn); + COPY_ATTR(_coerce_c_locale); + COPY_ATTR(_coerce_c_locale_warn); COPY_ATTR(utf8_mode); COPY_STR_ATTR(module_search_path_env); @@ -2638,7 +2709,7 @@ pymain_run_python(_PyMain *pymain) static void -pymain_init(_PyMain *pymain) +pymain_init(_PyMain *pymain, int use_c_locale_coercion) { /* 754 requires that FP exceptions run in "no stop" mode by default, * and until C vendors implement C99's ways to control FP exceptions, @@ -2651,6 +2722,11 @@ pymain_init(_PyMain *pymain) pymain->config._disable_importlib = 0; pymain->config.install_signal_handlers = 1; + if (use_c_locale_coercion) { + /* set to -1 to be able to enable the feature */ + pymain->config._coerce_c_locale = -1; + pymain->config._coerce_c_locale_warn = -1; + } } @@ -2751,9 +2827,9 @@ pymain_cmdline(_PyMain *pymain) static int -pymain_main(_PyMain *pymain) +pymain_main(_PyMain *pymain, int use_c_locale_coercion) { - pymain_init(pymain); + pymain_init(pymain, use_c_locale_coercion); int res = pymain_cmdline(pymain); if (res < 0) { @@ -2802,10 +2878,22 @@ Py_Main(int argc, wchar_t **argv) pymain.argc = argc; pymain.wchar_argv = argv; - return pymain_main(&pymain); + return pymain_main(&pymain, 0); } +#ifdef MS_WINDOWS +int +_Py_WindowsMain(int argc, wchar_t **argv) +{ + _PyMain pymain = _PyMain_INIT; + pymain.use_bytes_argv = 0; + pymain.argc = argc; + pymain.wchar_argv = argv; + + return pymain_main(&pymain, 1); +} +#else int _Py_UnixMain(int argc, char **argv) { @@ -2814,8 +2902,9 @@ _Py_UnixMain(int argc, char **argv) pymain.argc = argc; pymain.bytes_argv = argv; - return pymain_main(&pymain); + return pymain_main(&pymain, 1); } +#endif /* this is gonna seem *real weird*, but if you put some other code between |
