17db96d56Sopenharmony_ci/*********************************************************** 27db96d56Sopenharmony_ciCopyright (C) 1997, 2002, 2003, 2007, 2008 Martin von Loewis 37db96d56Sopenharmony_ci 47db96d56Sopenharmony_ciPermission to use, copy, modify, and distribute this software and its 57db96d56Sopenharmony_cidocumentation for any purpose and without fee is hereby granted, 67db96d56Sopenharmony_ciprovided that the above copyright notice appear in all copies. 77db96d56Sopenharmony_ci 87db96d56Sopenharmony_ciThis software comes with no warranty. Use at your own risk. 97db96d56Sopenharmony_ci 107db96d56Sopenharmony_ci******************************************************************/ 117db96d56Sopenharmony_ci 127db96d56Sopenharmony_ci#define PY_SSIZE_T_CLEAN 137db96d56Sopenharmony_ci#include "Python.h" 147db96d56Sopenharmony_ci#include "pycore_fileutils.h" 157db96d56Sopenharmony_ci 167db96d56Sopenharmony_ci#include <stdio.h> 177db96d56Sopenharmony_ci#include <locale.h> 187db96d56Sopenharmony_ci#include <string.h> 197db96d56Sopenharmony_ci#include <ctype.h> 207db96d56Sopenharmony_ci 217db96d56Sopenharmony_ci#ifdef HAVE_ERRNO_H 227db96d56Sopenharmony_ci#include <errno.h> 237db96d56Sopenharmony_ci#endif 247db96d56Sopenharmony_ci 257db96d56Sopenharmony_ci#ifdef HAVE_LANGINFO_H 267db96d56Sopenharmony_ci#include <langinfo.h> 277db96d56Sopenharmony_ci#endif 287db96d56Sopenharmony_ci 297db96d56Sopenharmony_ci#ifdef HAVE_LIBINTL_H 307db96d56Sopenharmony_ci#include <libintl.h> 317db96d56Sopenharmony_ci#endif 327db96d56Sopenharmony_ci 337db96d56Sopenharmony_ci#ifdef HAVE_WCHAR_H 347db96d56Sopenharmony_ci#include <wchar.h> 357db96d56Sopenharmony_ci#endif 367db96d56Sopenharmony_ci 377db96d56Sopenharmony_ci#if defined(MS_WINDOWS) 387db96d56Sopenharmony_ci#define WIN32_LEAN_AND_MEAN 397db96d56Sopenharmony_ci#include <windows.h> 407db96d56Sopenharmony_ci#endif 417db96d56Sopenharmony_ci 427db96d56Sopenharmony_ciPyDoc_STRVAR(locale__doc__, "Support for POSIX locales."); 437db96d56Sopenharmony_ci 447db96d56Sopenharmony_citypedef struct _locale_state { 457db96d56Sopenharmony_ci PyObject *Error; 467db96d56Sopenharmony_ci} _locale_state; 477db96d56Sopenharmony_ci 487db96d56Sopenharmony_cistatic inline _locale_state* 497db96d56Sopenharmony_ciget_locale_state(PyObject *m) 507db96d56Sopenharmony_ci{ 517db96d56Sopenharmony_ci void *state = PyModule_GetState(m); 527db96d56Sopenharmony_ci assert(state != NULL); 537db96d56Sopenharmony_ci return (_locale_state *)state; 547db96d56Sopenharmony_ci} 557db96d56Sopenharmony_ci 567db96d56Sopenharmony_ci#include "clinic/_localemodule.c.h" 577db96d56Sopenharmony_ci 587db96d56Sopenharmony_ci/*[clinic input] 597db96d56Sopenharmony_cimodule _locale 607db96d56Sopenharmony_ci[clinic start generated code]*/ 617db96d56Sopenharmony_ci/*[clinic end generated code: output=da39a3ee5e6b4b0d input=ed98569b726feada]*/ 627db96d56Sopenharmony_ci 637db96d56Sopenharmony_ci/* support functions for formatting floating point numbers */ 647db96d56Sopenharmony_ci 657db96d56Sopenharmony_ci/* the grouping is terminated by either 0 or CHAR_MAX */ 667db96d56Sopenharmony_cistatic PyObject* 677db96d56Sopenharmony_cicopy_grouping(const char* s) 687db96d56Sopenharmony_ci{ 697db96d56Sopenharmony_ci int i; 707db96d56Sopenharmony_ci PyObject *result, *val = NULL; 717db96d56Sopenharmony_ci 727db96d56Sopenharmony_ci if (s[0] == '\0') { 737db96d56Sopenharmony_ci /* empty string: no grouping at all */ 747db96d56Sopenharmony_ci return PyList_New(0); 757db96d56Sopenharmony_ci } 767db96d56Sopenharmony_ci 777db96d56Sopenharmony_ci for (i = 0; s[i] != '\0' && s[i] != CHAR_MAX; i++) 787db96d56Sopenharmony_ci ; /* nothing */ 797db96d56Sopenharmony_ci 807db96d56Sopenharmony_ci result = PyList_New(i+1); 817db96d56Sopenharmony_ci if (!result) 827db96d56Sopenharmony_ci return NULL; 837db96d56Sopenharmony_ci 847db96d56Sopenharmony_ci i = -1; 857db96d56Sopenharmony_ci do { 867db96d56Sopenharmony_ci i++; 877db96d56Sopenharmony_ci val = PyLong_FromLong(s[i]); 887db96d56Sopenharmony_ci if (val == NULL) { 897db96d56Sopenharmony_ci Py_DECREF(result); 907db96d56Sopenharmony_ci return NULL; 917db96d56Sopenharmony_ci } 927db96d56Sopenharmony_ci PyList_SET_ITEM(result, i, val); 937db96d56Sopenharmony_ci } while (s[i] != '\0' && s[i] != CHAR_MAX); 947db96d56Sopenharmony_ci 957db96d56Sopenharmony_ci return result; 967db96d56Sopenharmony_ci} 977db96d56Sopenharmony_ci 987db96d56Sopenharmony_ci/*[clinic input] 997db96d56Sopenharmony_ci_locale.setlocale 1007db96d56Sopenharmony_ci 1017db96d56Sopenharmony_ci category: int 1027db96d56Sopenharmony_ci locale: str(accept={str, NoneType}) = NULL 1037db96d56Sopenharmony_ci / 1047db96d56Sopenharmony_ci 1057db96d56Sopenharmony_ciActivates/queries locale processing. 1067db96d56Sopenharmony_ci[clinic start generated code]*/ 1077db96d56Sopenharmony_ci 1087db96d56Sopenharmony_cistatic PyObject * 1097db96d56Sopenharmony_ci_locale_setlocale_impl(PyObject *module, int category, const char *locale) 1107db96d56Sopenharmony_ci/*[clinic end generated code: output=a0e777ae5d2ff117 input=dbe18f1d66c57a6a]*/ 1117db96d56Sopenharmony_ci{ 1127db96d56Sopenharmony_ci char *result; 1137db96d56Sopenharmony_ci PyObject *result_object; 1147db96d56Sopenharmony_ci 1157db96d56Sopenharmony_ci#if defined(MS_WINDOWS) 1167db96d56Sopenharmony_ci if (category < LC_MIN || category > LC_MAX) 1177db96d56Sopenharmony_ci { 1187db96d56Sopenharmony_ci PyErr_SetString(get_locale_state(module)->Error, 1197db96d56Sopenharmony_ci "invalid locale category"); 1207db96d56Sopenharmony_ci return NULL; 1217db96d56Sopenharmony_ci } 1227db96d56Sopenharmony_ci#endif 1237db96d56Sopenharmony_ci 1247db96d56Sopenharmony_ci if (locale) { 1257db96d56Sopenharmony_ci /* set locale */ 1267db96d56Sopenharmony_ci result = setlocale(category, locale); 1277db96d56Sopenharmony_ci if (!result) { 1287db96d56Sopenharmony_ci /* operation failed, no setting was changed */ 1297db96d56Sopenharmony_ci PyErr_SetString(get_locale_state(module)->Error, 1307db96d56Sopenharmony_ci "unsupported locale setting"); 1317db96d56Sopenharmony_ci return NULL; 1327db96d56Sopenharmony_ci } 1337db96d56Sopenharmony_ci result_object = PyUnicode_DecodeLocale(result, NULL); 1347db96d56Sopenharmony_ci if (!result_object) 1357db96d56Sopenharmony_ci return NULL; 1367db96d56Sopenharmony_ci } else { 1377db96d56Sopenharmony_ci /* get locale */ 1387db96d56Sopenharmony_ci result = setlocale(category, NULL); 1397db96d56Sopenharmony_ci if (!result) { 1407db96d56Sopenharmony_ci PyErr_SetString(get_locale_state(module)->Error, 1417db96d56Sopenharmony_ci "locale query failed"); 1427db96d56Sopenharmony_ci return NULL; 1437db96d56Sopenharmony_ci } 1447db96d56Sopenharmony_ci result_object = PyUnicode_DecodeLocale(result, NULL); 1457db96d56Sopenharmony_ci } 1467db96d56Sopenharmony_ci return result_object; 1477db96d56Sopenharmony_ci} 1487db96d56Sopenharmony_ci 1497db96d56Sopenharmony_cistatic int 1507db96d56Sopenharmony_cilocale_is_ascii(const char *str) 1517db96d56Sopenharmony_ci{ 1527db96d56Sopenharmony_ci return (strlen(str) == 1 && ((unsigned char)str[0]) <= 127); 1537db96d56Sopenharmony_ci} 1547db96d56Sopenharmony_ci 1557db96d56Sopenharmony_cistatic int 1567db96d56Sopenharmony_cilocale_decode_monetary(PyObject *dict, struct lconv *lc) 1577db96d56Sopenharmony_ci{ 1587db96d56Sopenharmony_ci#ifndef MS_WINDOWS 1597db96d56Sopenharmony_ci int change_locale; 1607db96d56Sopenharmony_ci change_locale = (!locale_is_ascii(lc->int_curr_symbol) 1617db96d56Sopenharmony_ci || !locale_is_ascii(lc->currency_symbol) 1627db96d56Sopenharmony_ci || !locale_is_ascii(lc->mon_decimal_point) 1637db96d56Sopenharmony_ci || !locale_is_ascii(lc->mon_thousands_sep)); 1647db96d56Sopenharmony_ci 1657db96d56Sopenharmony_ci /* Keep a copy of the LC_CTYPE locale */ 1667db96d56Sopenharmony_ci char *oldloc = NULL, *loc = NULL; 1677db96d56Sopenharmony_ci if (change_locale) { 1687db96d56Sopenharmony_ci oldloc = setlocale(LC_CTYPE, NULL); 1697db96d56Sopenharmony_ci if (!oldloc) { 1707db96d56Sopenharmony_ci PyErr_SetString(PyExc_RuntimeWarning, 1717db96d56Sopenharmony_ci "failed to get LC_CTYPE locale"); 1727db96d56Sopenharmony_ci return -1; 1737db96d56Sopenharmony_ci } 1747db96d56Sopenharmony_ci 1757db96d56Sopenharmony_ci oldloc = _PyMem_Strdup(oldloc); 1767db96d56Sopenharmony_ci if (!oldloc) { 1777db96d56Sopenharmony_ci PyErr_NoMemory(); 1787db96d56Sopenharmony_ci return -1; 1797db96d56Sopenharmony_ci } 1807db96d56Sopenharmony_ci 1817db96d56Sopenharmony_ci loc = setlocale(LC_MONETARY, NULL); 1827db96d56Sopenharmony_ci if (loc != NULL && strcmp(loc, oldloc) == 0) { 1837db96d56Sopenharmony_ci loc = NULL; 1847db96d56Sopenharmony_ci } 1857db96d56Sopenharmony_ci 1867db96d56Sopenharmony_ci if (loc != NULL) { 1877db96d56Sopenharmony_ci /* Only set the locale temporarily the LC_CTYPE locale 1887db96d56Sopenharmony_ci to the LC_MONETARY locale if the two locales are different and 1897db96d56Sopenharmony_ci at least one string is non-ASCII. */ 1907db96d56Sopenharmony_ci setlocale(LC_CTYPE, loc); 1917db96d56Sopenharmony_ci } 1927db96d56Sopenharmony_ci } 1937db96d56Sopenharmony_ci 1947db96d56Sopenharmony_ci#define GET_LOCALE_STRING(ATTR) PyUnicode_DecodeLocale(lc->ATTR, NULL) 1957db96d56Sopenharmony_ci#else /* MS_WINDOWS */ 1967db96d56Sopenharmony_ci/* Use _W_* fields of Windows struct lconv */ 1977db96d56Sopenharmony_ci#define GET_LOCALE_STRING(ATTR) PyUnicode_FromWideChar(lc->_W_ ## ATTR, -1) 1987db96d56Sopenharmony_ci#endif /* MS_WINDOWS */ 1997db96d56Sopenharmony_ci 2007db96d56Sopenharmony_ci int res = -1; 2017db96d56Sopenharmony_ci 2027db96d56Sopenharmony_ci#define RESULT_STRING(ATTR) \ 2037db96d56Sopenharmony_ci do { \ 2047db96d56Sopenharmony_ci PyObject *obj; \ 2057db96d56Sopenharmony_ci obj = GET_LOCALE_STRING(ATTR); \ 2067db96d56Sopenharmony_ci if (obj == NULL) { \ 2077db96d56Sopenharmony_ci goto done; \ 2087db96d56Sopenharmony_ci } \ 2097db96d56Sopenharmony_ci if (PyDict_SetItemString(dict, Py_STRINGIFY(ATTR), obj) < 0) { \ 2107db96d56Sopenharmony_ci Py_DECREF(obj); \ 2117db96d56Sopenharmony_ci goto done; \ 2127db96d56Sopenharmony_ci } \ 2137db96d56Sopenharmony_ci Py_DECREF(obj); \ 2147db96d56Sopenharmony_ci } while (0) 2157db96d56Sopenharmony_ci 2167db96d56Sopenharmony_ci RESULT_STRING(int_curr_symbol); 2177db96d56Sopenharmony_ci RESULT_STRING(currency_symbol); 2187db96d56Sopenharmony_ci RESULT_STRING(mon_decimal_point); 2197db96d56Sopenharmony_ci RESULT_STRING(mon_thousands_sep); 2207db96d56Sopenharmony_ci#undef RESULT_STRING 2217db96d56Sopenharmony_ci#undef GET_LOCALE_STRING 2227db96d56Sopenharmony_ci 2237db96d56Sopenharmony_ci res = 0; 2247db96d56Sopenharmony_ci 2257db96d56Sopenharmony_cidone: 2267db96d56Sopenharmony_ci#ifndef MS_WINDOWS 2277db96d56Sopenharmony_ci if (loc != NULL) { 2287db96d56Sopenharmony_ci setlocale(LC_CTYPE, oldloc); 2297db96d56Sopenharmony_ci } 2307db96d56Sopenharmony_ci PyMem_Free(oldloc); 2317db96d56Sopenharmony_ci#endif 2327db96d56Sopenharmony_ci return res; 2337db96d56Sopenharmony_ci} 2347db96d56Sopenharmony_ci 2357db96d56Sopenharmony_ci/*[clinic input] 2367db96d56Sopenharmony_ci_locale.localeconv 2377db96d56Sopenharmony_ci 2387db96d56Sopenharmony_ciReturns numeric and monetary locale-specific parameters. 2397db96d56Sopenharmony_ci[clinic start generated code]*/ 2407db96d56Sopenharmony_ci 2417db96d56Sopenharmony_cistatic PyObject * 2427db96d56Sopenharmony_ci_locale_localeconv_impl(PyObject *module) 2437db96d56Sopenharmony_ci/*[clinic end generated code: output=43a54515e0a2aef5 input=f1132d15accf4444]*/ 2447db96d56Sopenharmony_ci{ 2457db96d56Sopenharmony_ci PyObject* result; 2467db96d56Sopenharmony_ci struct lconv *lc; 2477db96d56Sopenharmony_ci PyObject *x; 2487db96d56Sopenharmony_ci 2497db96d56Sopenharmony_ci result = PyDict_New(); 2507db96d56Sopenharmony_ci if (!result) { 2517db96d56Sopenharmony_ci return NULL; 2527db96d56Sopenharmony_ci } 2537db96d56Sopenharmony_ci 2547db96d56Sopenharmony_ci /* if LC_NUMERIC is different in the C library, use saved value */ 2557db96d56Sopenharmony_ci lc = localeconv(); 2567db96d56Sopenharmony_ci 2577db96d56Sopenharmony_ci /* hopefully, the localeconv result survives the C library calls 2587db96d56Sopenharmony_ci involved herein */ 2597db96d56Sopenharmony_ci 2607db96d56Sopenharmony_ci#define RESULT(key, obj)\ 2617db96d56Sopenharmony_ci do { \ 2627db96d56Sopenharmony_ci if (obj == NULL) \ 2637db96d56Sopenharmony_ci goto failed; \ 2647db96d56Sopenharmony_ci if (PyDict_SetItemString(result, key, obj) < 0) { \ 2657db96d56Sopenharmony_ci Py_DECREF(obj); \ 2667db96d56Sopenharmony_ci goto failed; \ 2677db96d56Sopenharmony_ci } \ 2687db96d56Sopenharmony_ci Py_DECREF(obj); \ 2697db96d56Sopenharmony_ci } while (0) 2707db96d56Sopenharmony_ci 2717db96d56Sopenharmony_ci#ifdef MS_WINDOWS 2727db96d56Sopenharmony_ci/* Use _W_* fields of Windows struct lconv */ 2737db96d56Sopenharmony_ci#define GET_LOCALE_STRING(ATTR) PyUnicode_FromWideChar(lc->_W_ ## ATTR, -1) 2747db96d56Sopenharmony_ci#else 2757db96d56Sopenharmony_ci#define GET_LOCALE_STRING(ATTR) PyUnicode_DecodeLocale(lc->ATTR, NULL) 2767db96d56Sopenharmony_ci#endif 2777db96d56Sopenharmony_ci#define RESULT_STRING(s)\ 2787db96d56Sopenharmony_ci do { \ 2797db96d56Sopenharmony_ci x = GET_LOCALE_STRING(s); \ 2807db96d56Sopenharmony_ci RESULT(#s, x); \ 2817db96d56Sopenharmony_ci } while (0) 2827db96d56Sopenharmony_ci 2837db96d56Sopenharmony_ci#define RESULT_INT(i)\ 2847db96d56Sopenharmony_ci do { \ 2857db96d56Sopenharmony_ci x = PyLong_FromLong(lc->i); \ 2867db96d56Sopenharmony_ci RESULT(#i, x); \ 2877db96d56Sopenharmony_ci } while (0) 2887db96d56Sopenharmony_ci 2897db96d56Sopenharmony_ci /* Monetary information: LC_MONETARY encoding */ 2907db96d56Sopenharmony_ci if (locale_decode_monetary(result, lc) < 0) { 2917db96d56Sopenharmony_ci goto failed; 2927db96d56Sopenharmony_ci } 2937db96d56Sopenharmony_ci x = copy_grouping(lc->mon_grouping); 2947db96d56Sopenharmony_ci RESULT("mon_grouping", x); 2957db96d56Sopenharmony_ci 2967db96d56Sopenharmony_ci RESULT_STRING(positive_sign); 2977db96d56Sopenharmony_ci RESULT_STRING(negative_sign); 2987db96d56Sopenharmony_ci RESULT_INT(int_frac_digits); 2997db96d56Sopenharmony_ci RESULT_INT(frac_digits); 3007db96d56Sopenharmony_ci RESULT_INT(p_cs_precedes); 3017db96d56Sopenharmony_ci RESULT_INT(p_sep_by_space); 3027db96d56Sopenharmony_ci RESULT_INT(n_cs_precedes); 3037db96d56Sopenharmony_ci RESULT_INT(n_sep_by_space); 3047db96d56Sopenharmony_ci RESULT_INT(p_sign_posn); 3057db96d56Sopenharmony_ci RESULT_INT(n_sign_posn); 3067db96d56Sopenharmony_ci 3077db96d56Sopenharmony_ci /* Numeric information: LC_NUMERIC encoding */ 3087db96d56Sopenharmony_ci PyObject *decimal_point = NULL, *thousands_sep = NULL; 3097db96d56Sopenharmony_ci if (_Py_GetLocaleconvNumeric(lc, &decimal_point, &thousands_sep) < 0) { 3107db96d56Sopenharmony_ci Py_XDECREF(decimal_point); 3117db96d56Sopenharmony_ci Py_XDECREF(thousands_sep); 3127db96d56Sopenharmony_ci goto failed; 3137db96d56Sopenharmony_ci } 3147db96d56Sopenharmony_ci 3157db96d56Sopenharmony_ci if (PyDict_SetItemString(result, "decimal_point", decimal_point) < 0) { 3167db96d56Sopenharmony_ci Py_DECREF(decimal_point); 3177db96d56Sopenharmony_ci Py_DECREF(thousands_sep); 3187db96d56Sopenharmony_ci goto failed; 3197db96d56Sopenharmony_ci } 3207db96d56Sopenharmony_ci Py_DECREF(decimal_point); 3217db96d56Sopenharmony_ci 3227db96d56Sopenharmony_ci if (PyDict_SetItemString(result, "thousands_sep", thousands_sep) < 0) { 3237db96d56Sopenharmony_ci Py_DECREF(thousands_sep); 3247db96d56Sopenharmony_ci goto failed; 3257db96d56Sopenharmony_ci } 3267db96d56Sopenharmony_ci Py_DECREF(thousands_sep); 3277db96d56Sopenharmony_ci 3287db96d56Sopenharmony_ci x = copy_grouping(lc->grouping); 3297db96d56Sopenharmony_ci RESULT("grouping", x); 3307db96d56Sopenharmony_ci 3317db96d56Sopenharmony_ci return result; 3327db96d56Sopenharmony_ci 3337db96d56Sopenharmony_ci failed: 3347db96d56Sopenharmony_ci Py_DECREF(result); 3357db96d56Sopenharmony_ci return NULL; 3367db96d56Sopenharmony_ci 3377db96d56Sopenharmony_ci#undef RESULT 3387db96d56Sopenharmony_ci#undef RESULT_STRING 3397db96d56Sopenharmony_ci#undef RESULT_INT 3407db96d56Sopenharmony_ci#undef GET_LOCALE_STRING 3417db96d56Sopenharmony_ci} 3427db96d56Sopenharmony_ci 3437db96d56Sopenharmony_ci#if defined(HAVE_WCSCOLL) 3447db96d56Sopenharmony_ci 3457db96d56Sopenharmony_ci/*[clinic input] 3467db96d56Sopenharmony_ci_locale.strcoll 3477db96d56Sopenharmony_ci 3487db96d56Sopenharmony_ci os1: unicode 3497db96d56Sopenharmony_ci os2: unicode 3507db96d56Sopenharmony_ci / 3517db96d56Sopenharmony_ci 3527db96d56Sopenharmony_ciCompares two strings according to the locale. 3537db96d56Sopenharmony_ci[clinic start generated code]*/ 3547db96d56Sopenharmony_ci 3557db96d56Sopenharmony_cistatic PyObject * 3567db96d56Sopenharmony_ci_locale_strcoll_impl(PyObject *module, PyObject *os1, PyObject *os2) 3577db96d56Sopenharmony_ci/*[clinic end generated code: output=82ddc6d62c76d618 input=693cd02bcbf38dd8]*/ 3587db96d56Sopenharmony_ci{ 3597db96d56Sopenharmony_ci PyObject *result = NULL; 3607db96d56Sopenharmony_ci wchar_t *ws1 = NULL, *ws2 = NULL; 3617db96d56Sopenharmony_ci 3627db96d56Sopenharmony_ci /* Convert the unicode strings to wchar[]. */ 3637db96d56Sopenharmony_ci ws1 = PyUnicode_AsWideCharString(os1, NULL); 3647db96d56Sopenharmony_ci if (ws1 == NULL) 3657db96d56Sopenharmony_ci goto done; 3667db96d56Sopenharmony_ci ws2 = PyUnicode_AsWideCharString(os2, NULL); 3677db96d56Sopenharmony_ci if (ws2 == NULL) 3687db96d56Sopenharmony_ci goto done; 3697db96d56Sopenharmony_ci /* Collate the strings. */ 3707db96d56Sopenharmony_ci result = PyLong_FromLong(wcscoll(ws1, ws2)); 3717db96d56Sopenharmony_ci done: 3727db96d56Sopenharmony_ci /* Deallocate everything. */ 3737db96d56Sopenharmony_ci if (ws1) PyMem_Free(ws1); 3747db96d56Sopenharmony_ci if (ws2) PyMem_Free(ws2); 3757db96d56Sopenharmony_ci return result; 3767db96d56Sopenharmony_ci} 3777db96d56Sopenharmony_ci#endif 3787db96d56Sopenharmony_ci 3797db96d56Sopenharmony_ci#ifdef HAVE_WCSXFRM 3807db96d56Sopenharmony_ci 3817db96d56Sopenharmony_ci/*[clinic input] 3827db96d56Sopenharmony_ci_locale.strxfrm 3837db96d56Sopenharmony_ci 3847db96d56Sopenharmony_ci string as str: unicode 3857db96d56Sopenharmony_ci / 3867db96d56Sopenharmony_ci 3877db96d56Sopenharmony_ciReturn a string that can be used as a key for locale-aware comparisons. 3887db96d56Sopenharmony_ci[clinic start generated code]*/ 3897db96d56Sopenharmony_ci 3907db96d56Sopenharmony_cistatic PyObject * 3917db96d56Sopenharmony_ci_locale_strxfrm_impl(PyObject *module, PyObject *str) 3927db96d56Sopenharmony_ci/*[clinic end generated code: output=3081866ebffc01af input=1378bbe6a88b4780]*/ 3937db96d56Sopenharmony_ci{ 3947db96d56Sopenharmony_ci Py_ssize_t n1; 3957db96d56Sopenharmony_ci wchar_t *s = NULL, *buf = NULL; 3967db96d56Sopenharmony_ci size_t n2; 3977db96d56Sopenharmony_ci PyObject *result = NULL; 3987db96d56Sopenharmony_ci 3997db96d56Sopenharmony_ci s = PyUnicode_AsWideCharString(str, &n1); 4007db96d56Sopenharmony_ci if (s == NULL) 4017db96d56Sopenharmony_ci goto exit; 4027db96d56Sopenharmony_ci if (wcslen(s) != (size_t)n1) { 4037db96d56Sopenharmony_ci PyErr_SetString(PyExc_ValueError, 4047db96d56Sopenharmony_ci "embedded null character"); 4057db96d56Sopenharmony_ci goto exit; 4067db96d56Sopenharmony_ci } 4077db96d56Sopenharmony_ci 4087db96d56Sopenharmony_ci /* assume no change in size, first */ 4097db96d56Sopenharmony_ci n1 = n1 + 1; 4107db96d56Sopenharmony_ci buf = PyMem_New(wchar_t, n1); 4117db96d56Sopenharmony_ci if (!buf) { 4127db96d56Sopenharmony_ci PyErr_NoMemory(); 4137db96d56Sopenharmony_ci goto exit; 4147db96d56Sopenharmony_ci } 4157db96d56Sopenharmony_ci errno = 0; 4167db96d56Sopenharmony_ci n2 = wcsxfrm(buf, s, n1); 4177db96d56Sopenharmony_ci if (errno && errno != ERANGE) { 4187db96d56Sopenharmony_ci PyErr_SetFromErrno(PyExc_OSError); 4197db96d56Sopenharmony_ci goto exit; 4207db96d56Sopenharmony_ci } 4217db96d56Sopenharmony_ci if (n2 >= (size_t)n1) { 4227db96d56Sopenharmony_ci /* more space needed */ 4237db96d56Sopenharmony_ci wchar_t * new_buf = PyMem_Realloc(buf, (n2+1)*sizeof(wchar_t)); 4247db96d56Sopenharmony_ci if (!new_buf) { 4257db96d56Sopenharmony_ci PyErr_NoMemory(); 4267db96d56Sopenharmony_ci goto exit; 4277db96d56Sopenharmony_ci } 4287db96d56Sopenharmony_ci buf = new_buf; 4297db96d56Sopenharmony_ci errno = 0; 4307db96d56Sopenharmony_ci n2 = wcsxfrm(buf, s, n2+1); 4317db96d56Sopenharmony_ci if (errno) { 4327db96d56Sopenharmony_ci PyErr_SetFromErrno(PyExc_OSError); 4337db96d56Sopenharmony_ci goto exit; 4347db96d56Sopenharmony_ci } 4357db96d56Sopenharmony_ci } 4367db96d56Sopenharmony_ci result = PyUnicode_FromWideChar(buf, n2); 4377db96d56Sopenharmony_ciexit: 4387db96d56Sopenharmony_ci PyMem_Free(buf); 4397db96d56Sopenharmony_ci PyMem_Free(s); 4407db96d56Sopenharmony_ci return result; 4417db96d56Sopenharmony_ci} 4427db96d56Sopenharmony_ci#endif 4437db96d56Sopenharmony_ci 4447db96d56Sopenharmony_ci#if defined(MS_WINDOWS) 4457db96d56Sopenharmony_ci 4467db96d56Sopenharmony_ci/*[clinic input] 4477db96d56Sopenharmony_ci_locale._getdefaultlocale 4487db96d56Sopenharmony_ci 4497db96d56Sopenharmony_ci[clinic start generated code]*/ 4507db96d56Sopenharmony_ci 4517db96d56Sopenharmony_cistatic PyObject * 4527db96d56Sopenharmony_ci_locale__getdefaultlocale_impl(PyObject *module) 4537db96d56Sopenharmony_ci/*[clinic end generated code: output=e6254088579534c2 input=003ea41acd17f7c7]*/ 4547db96d56Sopenharmony_ci{ 4557db96d56Sopenharmony_ci char encoding[20]; 4567db96d56Sopenharmony_ci char locale[100]; 4577db96d56Sopenharmony_ci 4587db96d56Sopenharmony_ci PyOS_snprintf(encoding, sizeof(encoding), "cp%u", GetACP()); 4597db96d56Sopenharmony_ci 4607db96d56Sopenharmony_ci if (GetLocaleInfo(LOCALE_USER_DEFAULT, 4617db96d56Sopenharmony_ci LOCALE_SISO639LANGNAME, 4627db96d56Sopenharmony_ci locale, sizeof(locale))) { 4637db96d56Sopenharmony_ci Py_ssize_t i = strlen(locale); 4647db96d56Sopenharmony_ci locale[i++] = '_'; 4657db96d56Sopenharmony_ci if (GetLocaleInfo(LOCALE_USER_DEFAULT, 4667db96d56Sopenharmony_ci LOCALE_SISO3166CTRYNAME, 4677db96d56Sopenharmony_ci locale+i, (int)(sizeof(locale)-i))) 4687db96d56Sopenharmony_ci return Py_BuildValue("ss", locale, encoding); 4697db96d56Sopenharmony_ci } 4707db96d56Sopenharmony_ci 4717db96d56Sopenharmony_ci /* If we end up here, this windows version didn't know about 4727db96d56Sopenharmony_ci ISO639/ISO3166 names (it's probably Windows 95). Return the 4737db96d56Sopenharmony_ci Windows language identifier instead (a hexadecimal number) */ 4747db96d56Sopenharmony_ci 4757db96d56Sopenharmony_ci locale[0] = '0'; 4767db96d56Sopenharmony_ci locale[1] = 'x'; 4777db96d56Sopenharmony_ci if (GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_IDEFAULTLANGUAGE, 4787db96d56Sopenharmony_ci locale+2, sizeof(locale)-2)) { 4797db96d56Sopenharmony_ci return Py_BuildValue("ss", locale, encoding); 4807db96d56Sopenharmony_ci } 4817db96d56Sopenharmony_ci 4827db96d56Sopenharmony_ci /* cannot determine the language code (very unlikely) */ 4837db96d56Sopenharmony_ci Py_INCREF(Py_None); 4847db96d56Sopenharmony_ci return Py_BuildValue("Os", Py_None, encoding); 4857db96d56Sopenharmony_ci} 4867db96d56Sopenharmony_ci#endif 4877db96d56Sopenharmony_ci 4887db96d56Sopenharmony_ci#ifdef HAVE_LANGINFO_H 4897db96d56Sopenharmony_ci#define LANGINFO(X) {#X, X} 4907db96d56Sopenharmony_cistatic struct langinfo_constant{ 4917db96d56Sopenharmony_ci char* name; 4927db96d56Sopenharmony_ci int value; 4937db96d56Sopenharmony_ci} langinfo_constants[] = 4947db96d56Sopenharmony_ci{ 4957db96d56Sopenharmony_ci /* These constants should exist on any langinfo implementation */ 4967db96d56Sopenharmony_ci LANGINFO(DAY_1), 4977db96d56Sopenharmony_ci LANGINFO(DAY_2), 4987db96d56Sopenharmony_ci LANGINFO(DAY_3), 4997db96d56Sopenharmony_ci LANGINFO(DAY_4), 5007db96d56Sopenharmony_ci LANGINFO(DAY_5), 5017db96d56Sopenharmony_ci LANGINFO(DAY_6), 5027db96d56Sopenharmony_ci LANGINFO(DAY_7), 5037db96d56Sopenharmony_ci 5047db96d56Sopenharmony_ci LANGINFO(ABDAY_1), 5057db96d56Sopenharmony_ci LANGINFO(ABDAY_2), 5067db96d56Sopenharmony_ci LANGINFO(ABDAY_3), 5077db96d56Sopenharmony_ci LANGINFO(ABDAY_4), 5087db96d56Sopenharmony_ci LANGINFO(ABDAY_5), 5097db96d56Sopenharmony_ci LANGINFO(ABDAY_6), 5107db96d56Sopenharmony_ci LANGINFO(ABDAY_7), 5117db96d56Sopenharmony_ci 5127db96d56Sopenharmony_ci LANGINFO(MON_1), 5137db96d56Sopenharmony_ci LANGINFO(MON_2), 5147db96d56Sopenharmony_ci LANGINFO(MON_3), 5157db96d56Sopenharmony_ci LANGINFO(MON_4), 5167db96d56Sopenharmony_ci LANGINFO(MON_5), 5177db96d56Sopenharmony_ci LANGINFO(MON_6), 5187db96d56Sopenharmony_ci LANGINFO(MON_7), 5197db96d56Sopenharmony_ci LANGINFO(MON_8), 5207db96d56Sopenharmony_ci LANGINFO(MON_9), 5217db96d56Sopenharmony_ci LANGINFO(MON_10), 5227db96d56Sopenharmony_ci LANGINFO(MON_11), 5237db96d56Sopenharmony_ci LANGINFO(MON_12), 5247db96d56Sopenharmony_ci 5257db96d56Sopenharmony_ci LANGINFO(ABMON_1), 5267db96d56Sopenharmony_ci LANGINFO(ABMON_2), 5277db96d56Sopenharmony_ci LANGINFO(ABMON_3), 5287db96d56Sopenharmony_ci LANGINFO(ABMON_4), 5297db96d56Sopenharmony_ci LANGINFO(ABMON_5), 5307db96d56Sopenharmony_ci LANGINFO(ABMON_6), 5317db96d56Sopenharmony_ci LANGINFO(ABMON_7), 5327db96d56Sopenharmony_ci LANGINFO(ABMON_8), 5337db96d56Sopenharmony_ci LANGINFO(ABMON_9), 5347db96d56Sopenharmony_ci LANGINFO(ABMON_10), 5357db96d56Sopenharmony_ci LANGINFO(ABMON_11), 5367db96d56Sopenharmony_ci LANGINFO(ABMON_12), 5377db96d56Sopenharmony_ci 5387db96d56Sopenharmony_ci#ifdef RADIXCHAR 5397db96d56Sopenharmony_ci /* The following are not available with glibc 2.0 */ 5407db96d56Sopenharmony_ci LANGINFO(RADIXCHAR), 5417db96d56Sopenharmony_ci LANGINFO(THOUSEP), 5427db96d56Sopenharmony_ci /* YESSTR and NOSTR are deprecated in glibc, since they are 5437db96d56Sopenharmony_ci a special case of message translation, which should be rather 5447db96d56Sopenharmony_ci done using gettext. So we don't expose it to Python in the 5457db96d56Sopenharmony_ci first place. 5467db96d56Sopenharmony_ci LANGINFO(YESSTR), 5477db96d56Sopenharmony_ci LANGINFO(NOSTR), 5487db96d56Sopenharmony_ci */ 5497db96d56Sopenharmony_ci LANGINFO(CRNCYSTR), 5507db96d56Sopenharmony_ci#endif 5517db96d56Sopenharmony_ci 5527db96d56Sopenharmony_ci LANGINFO(D_T_FMT), 5537db96d56Sopenharmony_ci LANGINFO(D_FMT), 5547db96d56Sopenharmony_ci LANGINFO(T_FMT), 5557db96d56Sopenharmony_ci LANGINFO(AM_STR), 5567db96d56Sopenharmony_ci LANGINFO(PM_STR), 5577db96d56Sopenharmony_ci 5587db96d56Sopenharmony_ci /* The following constants are available only with XPG4, but... 5597db96d56Sopenharmony_ci OpenBSD doesn't have CODESET but has T_FMT_AMPM, and doesn't have 5607db96d56Sopenharmony_ci a few of the others. 5617db96d56Sopenharmony_ci Solution: ifdef-test them all. */ 5627db96d56Sopenharmony_ci#ifdef CODESET 5637db96d56Sopenharmony_ci LANGINFO(CODESET), 5647db96d56Sopenharmony_ci#endif 5657db96d56Sopenharmony_ci#ifdef T_FMT_AMPM 5667db96d56Sopenharmony_ci LANGINFO(T_FMT_AMPM), 5677db96d56Sopenharmony_ci#endif 5687db96d56Sopenharmony_ci#ifdef ERA 5697db96d56Sopenharmony_ci LANGINFO(ERA), 5707db96d56Sopenharmony_ci#endif 5717db96d56Sopenharmony_ci#ifdef ERA_D_FMT 5727db96d56Sopenharmony_ci LANGINFO(ERA_D_FMT), 5737db96d56Sopenharmony_ci#endif 5747db96d56Sopenharmony_ci#ifdef ERA_D_T_FMT 5757db96d56Sopenharmony_ci LANGINFO(ERA_D_T_FMT), 5767db96d56Sopenharmony_ci#endif 5777db96d56Sopenharmony_ci#ifdef ERA_T_FMT 5787db96d56Sopenharmony_ci LANGINFO(ERA_T_FMT), 5797db96d56Sopenharmony_ci#endif 5807db96d56Sopenharmony_ci#ifdef ALT_DIGITS 5817db96d56Sopenharmony_ci LANGINFO(ALT_DIGITS), 5827db96d56Sopenharmony_ci#endif 5837db96d56Sopenharmony_ci#ifdef YESEXPR 5847db96d56Sopenharmony_ci LANGINFO(YESEXPR), 5857db96d56Sopenharmony_ci#endif 5867db96d56Sopenharmony_ci#ifdef NOEXPR 5877db96d56Sopenharmony_ci LANGINFO(NOEXPR), 5887db96d56Sopenharmony_ci#endif 5897db96d56Sopenharmony_ci#ifdef _DATE_FMT 5907db96d56Sopenharmony_ci /* This is not available in all glibc versions that have CODESET. */ 5917db96d56Sopenharmony_ci LANGINFO(_DATE_FMT), 5927db96d56Sopenharmony_ci#endif 5937db96d56Sopenharmony_ci {0, 0} 5947db96d56Sopenharmony_ci}; 5957db96d56Sopenharmony_ci 5967db96d56Sopenharmony_ci/*[clinic input] 5977db96d56Sopenharmony_ci_locale.nl_langinfo 5987db96d56Sopenharmony_ci 5997db96d56Sopenharmony_ci key as item: int 6007db96d56Sopenharmony_ci / 6017db96d56Sopenharmony_ci 6027db96d56Sopenharmony_ciReturn the value for the locale information associated with key. 6037db96d56Sopenharmony_ci[clinic start generated code]*/ 6047db96d56Sopenharmony_ci 6057db96d56Sopenharmony_cistatic PyObject * 6067db96d56Sopenharmony_ci_locale_nl_langinfo_impl(PyObject *module, int item) 6077db96d56Sopenharmony_ci/*[clinic end generated code: output=6aea457b47e077a3 input=00798143eecfeddc]*/ 6087db96d56Sopenharmony_ci{ 6097db96d56Sopenharmony_ci int i; 6107db96d56Sopenharmony_ci /* Check whether this is a supported constant. GNU libc sometimes 6117db96d56Sopenharmony_ci returns numeric values in the char* return value, which would 6127db96d56Sopenharmony_ci crash PyUnicode_FromString. */ 6137db96d56Sopenharmony_ci for (i = 0; langinfo_constants[i].name; i++) 6147db96d56Sopenharmony_ci if (langinfo_constants[i].value == item) { 6157db96d56Sopenharmony_ci /* Check NULL as a workaround for GNU libc's returning NULL 6167db96d56Sopenharmony_ci instead of an empty string for nl_langinfo(ERA). */ 6177db96d56Sopenharmony_ci const char *result = nl_langinfo(item); 6187db96d56Sopenharmony_ci result = result != NULL ? result : ""; 6197db96d56Sopenharmony_ci return PyUnicode_DecodeLocale(result, NULL); 6207db96d56Sopenharmony_ci } 6217db96d56Sopenharmony_ci PyErr_SetString(PyExc_ValueError, "unsupported langinfo constant"); 6227db96d56Sopenharmony_ci return NULL; 6237db96d56Sopenharmony_ci} 6247db96d56Sopenharmony_ci#endif /* HAVE_LANGINFO_H */ 6257db96d56Sopenharmony_ci 6267db96d56Sopenharmony_ci#ifdef HAVE_LIBINTL_H 6277db96d56Sopenharmony_ci 6287db96d56Sopenharmony_ci/*[clinic input] 6297db96d56Sopenharmony_ci_locale.gettext 6307db96d56Sopenharmony_ci 6317db96d56Sopenharmony_ci msg as in: str 6327db96d56Sopenharmony_ci / 6337db96d56Sopenharmony_ci 6347db96d56Sopenharmony_cigettext(msg) -> string 6357db96d56Sopenharmony_ci 6367db96d56Sopenharmony_ciReturn translation of msg. 6377db96d56Sopenharmony_ci[clinic start generated code]*/ 6387db96d56Sopenharmony_ci 6397db96d56Sopenharmony_cistatic PyObject * 6407db96d56Sopenharmony_ci_locale_gettext_impl(PyObject *module, const char *in) 6417db96d56Sopenharmony_ci/*[clinic end generated code: output=493bb4b38a4704fe input=949fc8efc2bb3bc3]*/ 6427db96d56Sopenharmony_ci{ 6437db96d56Sopenharmony_ci return PyUnicode_DecodeLocale(gettext(in), NULL); 6447db96d56Sopenharmony_ci} 6457db96d56Sopenharmony_ci 6467db96d56Sopenharmony_ci/*[clinic input] 6477db96d56Sopenharmony_ci_locale.dgettext 6487db96d56Sopenharmony_ci 6497db96d56Sopenharmony_ci domain: str(accept={str, NoneType}) 6507db96d56Sopenharmony_ci msg as in: str 6517db96d56Sopenharmony_ci / 6527db96d56Sopenharmony_ci 6537db96d56Sopenharmony_cidgettext(domain, msg) -> string 6547db96d56Sopenharmony_ci 6557db96d56Sopenharmony_ciReturn translation of msg in domain. 6567db96d56Sopenharmony_ci[clinic start generated code]*/ 6577db96d56Sopenharmony_ci 6587db96d56Sopenharmony_cistatic PyObject * 6597db96d56Sopenharmony_ci_locale_dgettext_impl(PyObject *module, const char *domain, const char *in) 6607db96d56Sopenharmony_ci/*[clinic end generated code: output=3c0cd5287b972c8f input=a277388a635109d8]*/ 6617db96d56Sopenharmony_ci{ 6627db96d56Sopenharmony_ci return PyUnicode_DecodeLocale(dgettext(domain, in), NULL); 6637db96d56Sopenharmony_ci} 6647db96d56Sopenharmony_ci 6657db96d56Sopenharmony_ci/*[clinic input] 6667db96d56Sopenharmony_ci_locale.dcgettext 6677db96d56Sopenharmony_ci 6687db96d56Sopenharmony_ci domain: str(accept={str, NoneType}) 6697db96d56Sopenharmony_ci msg as msgid: str 6707db96d56Sopenharmony_ci category: int 6717db96d56Sopenharmony_ci / 6727db96d56Sopenharmony_ci 6737db96d56Sopenharmony_ciReturn translation of msg in domain and category. 6747db96d56Sopenharmony_ci[clinic start generated code]*/ 6757db96d56Sopenharmony_ci 6767db96d56Sopenharmony_cistatic PyObject * 6777db96d56Sopenharmony_ci_locale_dcgettext_impl(PyObject *module, const char *domain, 6787db96d56Sopenharmony_ci const char *msgid, int category) 6797db96d56Sopenharmony_ci/*[clinic end generated code: output=0f4cc4fce0aa283f input=ec5f8fed4336de67]*/ 6807db96d56Sopenharmony_ci{ 6817db96d56Sopenharmony_ci return PyUnicode_DecodeLocale(dcgettext(domain,msgid,category), NULL); 6827db96d56Sopenharmony_ci} 6837db96d56Sopenharmony_ci 6847db96d56Sopenharmony_ci/*[clinic input] 6857db96d56Sopenharmony_ci_locale.textdomain 6867db96d56Sopenharmony_ci 6877db96d56Sopenharmony_ci domain: str(accept={str, NoneType}) 6887db96d56Sopenharmony_ci / 6897db96d56Sopenharmony_ci 6907db96d56Sopenharmony_ciSet the C library's textdmain to domain, returning the new domain. 6917db96d56Sopenharmony_ci[clinic start generated code]*/ 6927db96d56Sopenharmony_ci 6937db96d56Sopenharmony_cistatic PyObject * 6947db96d56Sopenharmony_ci_locale_textdomain_impl(PyObject *module, const char *domain) 6957db96d56Sopenharmony_ci/*[clinic end generated code: output=7992df06aadec313 input=66359716f5eb1d38]*/ 6967db96d56Sopenharmony_ci{ 6977db96d56Sopenharmony_ci domain = textdomain(domain); 6987db96d56Sopenharmony_ci if (!domain) { 6997db96d56Sopenharmony_ci PyErr_SetFromErrno(PyExc_OSError); 7007db96d56Sopenharmony_ci return NULL; 7017db96d56Sopenharmony_ci } 7027db96d56Sopenharmony_ci return PyUnicode_DecodeLocale(domain, NULL); 7037db96d56Sopenharmony_ci} 7047db96d56Sopenharmony_ci 7057db96d56Sopenharmony_ci/*[clinic input] 7067db96d56Sopenharmony_ci_locale.bindtextdomain 7077db96d56Sopenharmony_ci 7087db96d56Sopenharmony_ci domain: str 7097db96d56Sopenharmony_ci dir as dirname_obj: object 7107db96d56Sopenharmony_ci / 7117db96d56Sopenharmony_ci 7127db96d56Sopenharmony_ciBind the C library's domain to dir. 7137db96d56Sopenharmony_ci[clinic start generated code]*/ 7147db96d56Sopenharmony_ci 7157db96d56Sopenharmony_cistatic PyObject * 7167db96d56Sopenharmony_ci_locale_bindtextdomain_impl(PyObject *module, const char *domain, 7177db96d56Sopenharmony_ci PyObject *dirname_obj) 7187db96d56Sopenharmony_ci/*[clinic end generated code: output=6d6f3c7b345d785c input=c0dff085acfe272b]*/ 7197db96d56Sopenharmony_ci{ 7207db96d56Sopenharmony_ci const char *dirname, *current_dirname; 7217db96d56Sopenharmony_ci PyObject *dirname_bytes = NULL, *result; 7227db96d56Sopenharmony_ci 7237db96d56Sopenharmony_ci if (!strlen(domain)) { 7247db96d56Sopenharmony_ci PyErr_SetString(get_locale_state(module)->Error, 7257db96d56Sopenharmony_ci "domain must be a non-empty string"); 7267db96d56Sopenharmony_ci return 0; 7277db96d56Sopenharmony_ci } 7287db96d56Sopenharmony_ci if (dirname_obj != Py_None) { 7297db96d56Sopenharmony_ci if (!PyUnicode_FSConverter(dirname_obj, &dirname_bytes)) 7307db96d56Sopenharmony_ci return NULL; 7317db96d56Sopenharmony_ci dirname = PyBytes_AsString(dirname_bytes); 7327db96d56Sopenharmony_ci } else { 7337db96d56Sopenharmony_ci dirname_bytes = NULL; 7347db96d56Sopenharmony_ci dirname = NULL; 7357db96d56Sopenharmony_ci } 7367db96d56Sopenharmony_ci current_dirname = bindtextdomain(domain, dirname); 7377db96d56Sopenharmony_ci if (current_dirname == NULL) { 7387db96d56Sopenharmony_ci Py_XDECREF(dirname_bytes); 7397db96d56Sopenharmony_ci PyErr_SetFromErrno(PyExc_OSError); 7407db96d56Sopenharmony_ci return NULL; 7417db96d56Sopenharmony_ci } 7427db96d56Sopenharmony_ci result = PyUnicode_DecodeLocale(current_dirname, NULL); 7437db96d56Sopenharmony_ci Py_XDECREF(dirname_bytes); 7447db96d56Sopenharmony_ci return result; 7457db96d56Sopenharmony_ci} 7467db96d56Sopenharmony_ci 7477db96d56Sopenharmony_ci#ifdef HAVE_BIND_TEXTDOMAIN_CODESET 7487db96d56Sopenharmony_ci 7497db96d56Sopenharmony_ci/*[clinic input] 7507db96d56Sopenharmony_ci_locale.bind_textdomain_codeset 7517db96d56Sopenharmony_ci 7527db96d56Sopenharmony_ci domain: str 7537db96d56Sopenharmony_ci codeset: str(accept={str, NoneType}) 7547db96d56Sopenharmony_ci / 7557db96d56Sopenharmony_ci 7567db96d56Sopenharmony_ciBind the C library's domain to codeset. 7577db96d56Sopenharmony_ci[clinic start generated code]*/ 7587db96d56Sopenharmony_ci 7597db96d56Sopenharmony_cistatic PyObject * 7607db96d56Sopenharmony_ci_locale_bind_textdomain_codeset_impl(PyObject *module, const char *domain, 7617db96d56Sopenharmony_ci const char *codeset) 7627db96d56Sopenharmony_ci/*[clinic end generated code: output=fa452f9c8b1b9e89 input=23fbe3540400f259]*/ 7637db96d56Sopenharmony_ci{ 7647db96d56Sopenharmony_ci codeset = bind_textdomain_codeset(domain, codeset); 7657db96d56Sopenharmony_ci if (codeset) { 7667db96d56Sopenharmony_ci return PyUnicode_DecodeLocale(codeset, NULL); 7677db96d56Sopenharmony_ci } 7687db96d56Sopenharmony_ci Py_RETURN_NONE; 7697db96d56Sopenharmony_ci} 7707db96d56Sopenharmony_ci#endif // HAVE_BIND_TEXTDOMAIN_CODESET 7717db96d56Sopenharmony_ci 7727db96d56Sopenharmony_ci#endif // HAVE_LIBINTL_H 7737db96d56Sopenharmony_ci 7747db96d56Sopenharmony_ci 7757db96d56Sopenharmony_ci/*[clinic input] 7767db96d56Sopenharmony_ci_locale.getencoding 7777db96d56Sopenharmony_ci 7787db96d56Sopenharmony_ciGet the current locale encoding. 7797db96d56Sopenharmony_ci[clinic start generated code]*/ 7807db96d56Sopenharmony_ci 7817db96d56Sopenharmony_cistatic PyObject * 7827db96d56Sopenharmony_ci_locale_getencoding_impl(PyObject *module) 7837db96d56Sopenharmony_ci/*[clinic end generated code: output=86b326b971872e46 input=6503d11e5958b360]*/ 7847db96d56Sopenharmony_ci{ 7857db96d56Sopenharmony_ci return _Py_GetLocaleEncodingObject(); 7867db96d56Sopenharmony_ci} 7877db96d56Sopenharmony_ci 7887db96d56Sopenharmony_ci 7897db96d56Sopenharmony_cistatic struct PyMethodDef PyLocale_Methods[] = { 7907db96d56Sopenharmony_ci _LOCALE_SETLOCALE_METHODDEF 7917db96d56Sopenharmony_ci _LOCALE_LOCALECONV_METHODDEF 7927db96d56Sopenharmony_ci#ifdef HAVE_WCSCOLL 7937db96d56Sopenharmony_ci _LOCALE_STRCOLL_METHODDEF 7947db96d56Sopenharmony_ci#endif 7957db96d56Sopenharmony_ci#ifdef HAVE_WCSXFRM 7967db96d56Sopenharmony_ci _LOCALE_STRXFRM_METHODDEF 7977db96d56Sopenharmony_ci#endif 7987db96d56Sopenharmony_ci#if defined(MS_WINDOWS) 7997db96d56Sopenharmony_ci _LOCALE__GETDEFAULTLOCALE_METHODDEF 8007db96d56Sopenharmony_ci#endif 8017db96d56Sopenharmony_ci#ifdef HAVE_LANGINFO_H 8027db96d56Sopenharmony_ci _LOCALE_NL_LANGINFO_METHODDEF 8037db96d56Sopenharmony_ci#endif 8047db96d56Sopenharmony_ci#ifdef HAVE_LIBINTL_H 8057db96d56Sopenharmony_ci _LOCALE_GETTEXT_METHODDEF 8067db96d56Sopenharmony_ci _LOCALE_DGETTEXT_METHODDEF 8077db96d56Sopenharmony_ci _LOCALE_DCGETTEXT_METHODDEF 8087db96d56Sopenharmony_ci _LOCALE_TEXTDOMAIN_METHODDEF 8097db96d56Sopenharmony_ci _LOCALE_BINDTEXTDOMAIN_METHODDEF 8107db96d56Sopenharmony_ci#ifdef HAVE_BIND_TEXTDOMAIN_CODESET 8117db96d56Sopenharmony_ci _LOCALE_BIND_TEXTDOMAIN_CODESET_METHODDEF 8127db96d56Sopenharmony_ci#endif 8137db96d56Sopenharmony_ci#endif 8147db96d56Sopenharmony_ci _LOCALE_GETENCODING_METHODDEF 8157db96d56Sopenharmony_ci {NULL, NULL} 8167db96d56Sopenharmony_ci}; 8177db96d56Sopenharmony_ci 8187db96d56Sopenharmony_cistatic int 8197db96d56Sopenharmony_ci_locale_exec(PyObject *module) 8207db96d56Sopenharmony_ci{ 8217db96d56Sopenharmony_ci#ifdef HAVE_LANGINFO_H 8227db96d56Sopenharmony_ci int i; 8237db96d56Sopenharmony_ci#endif 8247db96d56Sopenharmony_ci#define ADD_INT(module, value) \ 8257db96d56Sopenharmony_ci do { \ 8267db96d56Sopenharmony_ci if (PyModule_AddIntConstant(module, #value, value) < 0) { \ 8277db96d56Sopenharmony_ci return -1; \ 8287db96d56Sopenharmony_ci } \ 8297db96d56Sopenharmony_ci } while (0) 8307db96d56Sopenharmony_ci 8317db96d56Sopenharmony_ci ADD_INT(module, LC_CTYPE); 8327db96d56Sopenharmony_ci ADD_INT(module, LC_TIME); 8337db96d56Sopenharmony_ci ADD_INT(module, LC_COLLATE); 8347db96d56Sopenharmony_ci ADD_INT(module, LC_MONETARY); 8357db96d56Sopenharmony_ci 8367db96d56Sopenharmony_ci#ifdef LC_MESSAGES 8377db96d56Sopenharmony_ci ADD_INT(module, LC_MESSAGES); 8387db96d56Sopenharmony_ci#endif /* LC_MESSAGES */ 8397db96d56Sopenharmony_ci 8407db96d56Sopenharmony_ci ADD_INT(module, LC_NUMERIC); 8417db96d56Sopenharmony_ci ADD_INT(module, LC_ALL); 8427db96d56Sopenharmony_ci ADD_INT(module, CHAR_MAX); 8437db96d56Sopenharmony_ci 8447db96d56Sopenharmony_ci _locale_state *state = get_locale_state(module); 8457db96d56Sopenharmony_ci state->Error = PyErr_NewException("locale.Error", NULL, NULL); 8467db96d56Sopenharmony_ci if (state->Error == NULL) { 8477db96d56Sopenharmony_ci return -1; 8487db96d56Sopenharmony_ci } 8497db96d56Sopenharmony_ci Py_INCREF(get_locale_state(module)->Error); 8507db96d56Sopenharmony_ci if (PyModule_AddObject(module, "Error", get_locale_state(module)->Error) < 0) { 8517db96d56Sopenharmony_ci Py_DECREF(get_locale_state(module)->Error); 8527db96d56Sopenharmony_ci return -1; 8537db96d56Sopenharmony_ci } 8547db96d56Sopenharmony_ci 8557db96d56Sopenharmony_ci#ifdef HAVE_LANGINFO_H 8567db96d56Sopenharmony_ci for (i = 0; langinfo_constants[i].name; i++) { 8577db96d56Sopenharmony_ci if (PyModule_AddIntConstant(module, 8587db96d56Sopenharmony_ci langinfo_constants[i].name, 8597db96d56Sopenharmony_ci langinfo_constants[i].value) < 0) { 8607db96d56Sopenharmony_ci return -1; 8617db96d56Sopenharmony_ci } 8627db96d56Sopenharmony_ci } 8637db96d56Sopenharmony_ci#endif 8647db96d56Sopenharmony_ci 8657db96d56Sopenharmony_ci if (PyErr_Occurred()) { 8667db96d56Sopenharmony_ci return -1; 8677db96d56Sopenharmony_ci } 8687db96d56Sopenharmony_ci return 0; 8697db96d56Sopenharmony_ci 8707db96d56Sopenharmony_ci#undef ADD_INT 8717db96d56Sopenharmony_ci} 8727db96d56Sopenharmony_ci 8737db96d56Sopenharmony_cistatic struct PyModuleDef_Slot _locale_slots[] = { 8747db96d56Sopenharmony_ci {Py_mod_exec, _locale_exec}, 8757db96d56Sopenharmony_ci {0, NULL} 8767db96d56Sopenharmony_ci}; 8777db96d56Sopenharmony_ci 8787db96d56Sopenharmony_cistatic int 8797db96d56Sopenharmony_cilocale_traverse(PyObject *module, visitproc visit, void *arg) 8807db96d56Sopenharmony_ci{ 8817db96d56Sopenharmony_ci _locale_state *state = get_locale_state(module); 8827db96d56Sopenharmony_ci Py_VISIT(state->Error); 8837db96d56Sopenharmony_ci return 0; 8847db96d56Sopenharmony_ci} 8857db96d56Sopenharmony_ci 8867db96d56Sopenharmony_cistatic int 8877db96d56Sopenharmony_cilocale_clear(PyObject *module) 8887db96d56Sopenharmony_ci{ 8897db96d56Sopenharmony_ci _locale_state *state = get_locale_state(module); 8907db96d56Sopenharmony_ci Py_CLEAR(state->Error); 8917db96d56Sopenharmony_ci return 0; 8927db96d56Sopenharmony_ci} 8937db96d56Sopenharmony_ci 8947db96d56Sopenharmony_cistatic void 8957db96d56Sopenharmony_cilocale_free(PyObject *module) 8967db96d56Sopenharmony_ci{ 8977db96d56Sopenharmony_ci locale_clear(module); 8987db96d56Sopenharmony_ci} 8997db96d56Sopenharmony_ci 9007db96d56Sopenharmony_cistatic struct PyModuleDef _localemodule = { 9017db96d56Sopenharmony_ci PyModuleDef_HEAD_INIT, 9027db96d56Sopenharmony_ci "_locale", 9037db96d56Sopenharmony_ci locale__doc__, 9047db96d56Sopenharmony_ci sizeof(_locale_state), 9057db96d56Sopenharmony_ci PyLocale_Methods, 9067db96d56Sopenharmony_ci _locale_slots, 9077db96d56Sopenharmony_ci locale_traverse, 9087db96d56Sopenharmony_ci locale_clear, 9097db96d56Sopenharmony_ci (freefunc)locale_free, 9107db96d56Sopenharmony_ci}; 9117db96d56Sopenharmony_ci 9127db96d56Sopenharmony_ciPyMODINIT_FUNC 9137db96d56Sopenharmony_ciPyInit__locale(void) 9147db96d56Sopenharmony_ci{ 9157db96d56Sopenharmony_ci return PyModuleDef_Init(&_localemodule); 9167db96d56Sopenharmony_ci} 9177db96d56Sopenharmony_ci 9187db96d56Sopenharmony_ci/* 9197db96d56Sopenharmony_ciLocal variables: 9207db96d56Sopenharmony_cic-basic-offset: 4 9217db96d56Sopenharmony_ciindent-tabs-mode: nil 9227db96d56Sopenharmony_ciEnd: 9237db96d56Sopenharmony_ci*/ 924