blob: 2e353bba00bf35bc038f01a8ffebb1ffcb9e4799 [file] [log] [blame]
Guido van Rossum220ecc81997-11-18 21:03:39 +00001/***********************************************************
Martin v. Löwis92fab752008-03-08 10:40:41 +00002Copyright (C) 1997, 2002, 2003, 2007, 2008 Martin von Loewis
Guido van Rossum220ecc81997-11-18 21:03:39 +00003
4Permission to use, copy, modify, and distribute this software and its
5documentation for any purpose and without fee is hereby granted,
6provided that the above copyright notice appear in all copies.
7
8This software comes with no warranty. Use at your own risk.
Fredrik Lundh8f017a02000-07-08 19:57:37 +00009
Guido van Rossum220ecc81997-11-18 21:03:39 +000010******************************************************************/
11
Antoine Pitrou6a448d42009-10-19 19:43:09 +000012#define PY_SSIZE_T_CLEAN
Fred Drake68933b92000-08-10 21:41:08 +000013#include "Python.h"
Victor Stinner02e6bf72018-11-20 16:20:16 +010014#include "pycore_fileutils.h"
Fred Drake68933b92000-08-10 21:41:08 +000015
Guido van Rossum220ecc81997-11-18 21:03:39 +000016#include <stdio.h>
Guido van Rossum220ecc81997-11-18 21:03:39 +000017#include <locale.h>
18#include <string.h>
Guido van Rossum5cd70f41998-06-19 04:33:30 +000019#include <ctype.h>
Fredrik Lundh8f017a02000-07-08 19:57:37 +000020
Thomas Wouters0e3f5912006-08-11 14:57:12 +000021#ifdef HAVE_ERRNO_H
Thomas Wouters477c8d52006-05-27 19:21:47 +000022#include <errno.h>
23#endif
24
Martin v. Löwis9b75dca2001-08-10 13:58:50 +000025#ifdef HAVE_LANGINFO_H
26#include <langinfo.h>
27#endif
28
Martin v. Löwis2e64c342002-03-27 18:49:02 +000029#ifdef HAVE_LIBINTL_H
30#include <libintl.h>
31#endif
32
Martin v. Löwis9c36c292002-12-21 18:34:06 +000033#ifdef HAVE_WCHAR_H
34#include <wchar.h>
35#endif
36
Martin v. Löwis6238d2b2002-06-30 15:26:10 +000037#if defined(MS_WINDOWS)
Tim Peters7a1f9172002-07-14 22:14:19 +000038#define WIN32_LEAN_AND_MEAN
Fredrik Lundh8f017a02000-07-08 19:57:37 +000039#include <windows.h>
Guido van Rossum239a2181998-04-28 16:08:19 +000040#endif
Guido van Rossum220ecc81997-11-18 21:03:39 +000041
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000042PyDoc_STRVAR(locale__doc__, "Support for POSIX locales.");
Guido van Rossum220ecc81997-11-18 21:03:39 +000043
Hai Shia1581682020-03-12 00:46:06 +080044typedef struct _locale_state {
45 PyObject *Error;
46} _locale_state;
47
48static inline _locale_state*
49get_locale_state(PyObject *m)
50{
51 void *state = PyModule_GetState(m);
52 assert(state != NULL);
53 return (_locale_state *)state;
54}
Guido van Rossum220ecc81997-11-18 21:03:39 +000055
56/* support functions for formatting floating point numbers */
57
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000058PyDoc_STRVAR(setlocale__doc__,
59"(integer,string=None) -> string. Activates/queries locale processing.");
Guido van Rossum220ecc81997-11-18 21:03:39 +000060
Guido van Rossum220ecc81997-11-18 21:03:39 +000061/* the grouping is terminated by either 0 or CHAR_MAX */
62static PyObject*
Serhiy Storchakaef1585e2015-12-25 20:01:53 +020063copy_grouping(const char* s)
Guido van Rossum220ecc81997-11-18 21:03:39 +000064{
Fredrik Lundh8f017a02000-07-08 19:57:37 +000065 int i;
66 PyObject *result, *val = NULL;
67
Martin Panter6d57fe12016-09-17 03:26:16 +000068 if (s[0] == '\0') {
Fredrik Lundh8f017a02000-07-08 19:57:37 +000069 /* empty string: no grouping at all */
70 return PyList_New(0);
Martin Panter6d57fe12016-09-17 03:26:16 +000071 }
Fredrik Lundh8f017a02000-07-08 19:57:37 +000072
73 for (i = 0; s[i] != '\0' && s[i] != CHAR_MAX; i++)
74 ; /* nothing */
75
76 result = PyList_New(i+1);
77 if (!result)
78 return NULL;
79
80 i = -1;
81 do {
82 i++;
Christian Heimes217cfd12007-12-02 14:31:20 +000083 val = PyLong_FromLong(s[i]);
Zackery Spytz99d56b52018-12-08 07:16:55 -070084 if (val == NULL) {
85 Py_DECREF(result);
86 return NULL;
Fredrik Lundh8f017a02000-07-08 19:57:37 +000087 }
Zackery Spytz99d56b52018-12-08 07:16:55 -070088 PyList_SET_ITEM(result, i, val);
Fredrik Lundh8f017a02000-07-08 19:57:37 +000089 } while (s[i] != '\0' && s[i] != CHAR_MAX);
90
Fredrik Lundh8f017a02000-07-08 19:57:37 +000091 return result;
Guido van Rossum220ecc81997-11-18 21:03:39 +000092}
93
Guido van Rossum220ecc81997-11-18 21:03:39 +000094static PyObject*
Fredrik Lundh8f017a02000-07-08 19:57:37 +000095PyLocale_setlocale(PyObject* self, PyObject* args)
Guido van Rossum220ecc81997-11-18 21:03:39 +000096{
Fredrik Lundh8f017a02000-07-08 19:57:37 +000097 int category;
98 char *locale = NULL, *result;
99 PyObject *result_object;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000100
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000101 if (!PyArg_ParseTuple(args, "i|z:setlocale", &category, &locale))
Fredrik Lundh89610a42000-07-08 20:07:24 +0000102 return NULL;
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000103
Amaury Forgeot d'Arc64f3ca42009-12-01 21:59:18 +0000104#if defined(MS_WINDOWS)
105 if (category < LC_MIN || category > LC_MAX)
106 {
Hai Shia1581682020-03-12 00:46:06 +0800107 PyErr_SetString(get_locale_state(self)->Error,
108 "invalid locale category");
Amaury Forgeot d'Arc64f3ca42009-12-01 21:59:18 +0000109 return NULL;
110 }
111#endif
112
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000113 if (locale) {
114 /* set locale */
115 result = setlocale(category, locale);
116 if (!result) {
117 /* operation failed, no setting was changed */
Hai Shia1581682020-03-12 00:46:06 +0800118 PyErr_SetString(get_locale_state(self)->Error,
119 "unsupported locale setting");
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000120 return NULL;
121 }
Victor Stinnera9c895d2012-02-14 02:33:38 +0100122 result_object = PyUnicode_DecodeLocale(result, NULL);
Mark Hammond9a714752003-07-24 14:15:07 +0000123 if (!result_object)
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000124 return NULL;
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000125 } else {
126 /* get locale */
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000127 result = setlocale(category, NULL);
128 if (!result) {
Hai Shia1581682020-03-12 00:46:06 +0800129 PyErr_SetString(get_locale_state(self)->Error,
130 "locale query failed");
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000131 return NULL;
132 }
Victor Stinnera9c895d2012-02-14 02:33:38 +0100133 result_object = PyUnicode_DecodeLocale(result, NULL);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000134 }
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000135 return result_object;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000136}
137
Victor Stinner02e6bf72018-11-20 16:20:16 +0100138static int
139locale_is_ascii(const char *str)
140{
141 return (strlen(str) == 1 && ((unsigned char)str[0]) <= 127);
142}
143
144static int
145locale_decode_monetary(PyObject *dict, struct lconv *lc)
146{
Miss Skeleton (bot)c17ff5c2020-10-20 05:07:14 -0700147#ifndef MS_WINDOWS
Victor Stinner02e6bf72018-11-20 16:20:16 +0100148 int change_locale;
149 change_locale = (!locale_is_ascii(lc->int_curr_symbol)
150 || !locale_is_ascii(lc->currency_symbol)
151 || !locale_is_ascii(lc->mon_decimal_point)
152 || !locale_is_ascii(lc->mon_thousands_sep));
153
154 /* Keep a copy of the LC_CTYPE locale */
155 char *oldloc = NULL, *loc = NULL;
156 if (change_locale) {
157 oldloc = setlocale(LC_CTYPE, NULL);
158 if (!oldloc) {
159 PyErr_SetString(PyExc_RuntimeWarning,
160 "failed to get LC_CTYPE locale");
161 return -1;
162 }
163
164 oldloc = _PyMem_Strdup(oldloc);
165 if (!oldloc) {
166 PyErr_NoMemory();
167 return -1;
168 }
169
170 loc = setlocale(LC_MONETARY, NULL);
171 if (loc != NULL && strcmp(loc, oldloc) == 0) {
172 loc = NULL;
173 }
174
175 if (loc != NULL) {
176 /* Only set the locale temporarily the LC_CTYPE locale
177 to the LC_MONETARY locale if the two locales are different and
178 at least one string is non-ASCII. */
179 setlocale(LC_CTYPE, loc);
180 }
181 }
182
Miss Skeleton (bot)c17ff5c2020-10-20 05:07:14 -0700183#define GET_LOCALE_STRING(ATTR) PyUnicode_DecodeLocale(lc->ATTR, NULL)
184#else /* MS_WINDOWS */
185/* Use _W_* fields of Windows struct lconv */
186#define GET_LOCALE_STRING(ATTR) PyUnicode_FromWideChar(lc->_W_ ## ATTR, -1)
187#endif /* MS_WINDOWS */
188
Victor Stinner02e6bf72018-11-20 16:20:16 +0100189 int res = -1;
190
191#define RESULT_STRING(ATTR) \
192 do { \
193 PyObject *obj; \
Miss Skeleton (bot)c17ff5c2020-10-20 05:07:14 -0700194 obj = GET_LOCALE_STRING(ATTR); \
Victor Stinner02e6bf72018-11-20 16:20:16 +0100195 if (obj == NULL) { \
196 goto done; \
197 } \
198 if (PyDict_SetItemString(dict, Py_STRINGIFY(ATTR), obj) < 0) { \
199 Py_DECREF(obj); \
200 goto done; \
201 } \
202 Py_DECREF(obj); \
203 } while (0)
204
205 RESULT_STRING(int_curr_symbol);
206 RESULT_STRING(currency_symbol);
207 RESULT_STRING(mon_decimal_point);
208 RESULT_STRING(mon_thousands_sep);
209#undef RESULT_STRING
Miss Skeleton (bot)c17ff5c2020-10-20 05:07:14 -0700210#undef GET_LOCALE_STRING
Victor Stinner02e6bf72018-11-20 16:20:16 +0100211
212 res = 0;
213
214done:
Miss Skeleton (bot)c17ff5c2020-10-20 05:07:14 -0700215#ifndef MS_WINDOWS
Victor Stinner02e6bf72018-11-20 16:20:16 +0100216 if (loc != NULL) {
217 setlocale(LC_CTYPE, oldloc);
218 }
219 PyMem_Free(oldloc);
Miss Skeleton (bot)c17ff5c2020-10-20 05:07:14 -0700220#endif
Victor Stinner02e6bf72018-11-20 16:20:16 +0100221 return res;
222}
223
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000224PyDoc_STRVAR(localeconv__doc__,
225"() -> dict. Returns numeric and monetary locale-specific parameters.");
Guido van Rossum220ecc81997-11-18 21:03:39 +0000226
227static PyObject*
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +0530228PyLocale_localeconv(PyObject* self, PyObject *Py_UNUSED(ignored))
Guido van Rossum220ecc81997-11-18 21:03:39 +0000229{
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000230 PyObject* result;
Victor Stinner02e6bf72018-11-20 16:20:16 +0100231 struct lconv *lc;
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000232 PyObject *x;
233
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000234 result = PyDict_New();
Victor Stinnercb064fc2018-01-15 15:58:02 +0100235 if (!result) {
Fredrik Lundh89610a42000-07-08 20:07:24 +0000236 return NULL;
Victor Stinnercb064fc2018-01-15 15:58:02 +0100237 }
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000238
239 /* if LC_NUMERIC is different in the C library, use saved value */
Victor Stinner02e6bf72018-11-20 16:20:16 +0100240 lc = localeconv();
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000241
242 /* hopefully, the localeconv result survives the C library calls
243 involved herein */
244
Victor Stinnerd594f242013-07-17 00:55:57 +0200245#define RESULT(key, obj)\
246 do { \
247 if (obj == NULL) \
248 goto failed; \
Victor Stinnerf38a5c22013-10-29 19:28:20 +0100249 if (PyDict_SetItemString(result, key, obj) < 0) { \
250 Py_DECREF(obj); \
Victor Stinnerd594f242013-07-17 00:55:57 +0200251 goto failed; \
Victor Stinnerf38a5c22013-10-29 19:28:20 +0100252 } \
Victor Stinnerd594f242013-07-17 00:55:57 +0200253 Py_DECREF(obj); \
254 } while (0)
255
Miss Skeleton (bot)c17ff5c2020-10-20 05:07:14 -0700256#ifdef MS_WINDOWS
257/* Use _W_* fields of Windows struct lconv */
258#define GET_LOCALE_STRING(ATTR) PyUnicode_FromWideChar(lc->_W_ ## ATTR, -1)
259#else
260#define GET_LOCALE_STRING(ATTR) PyUnicode_DecodeLocale(lc->ATTR, NULL)
261#endif
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000262#define RESULT_STRING(s)\
Victor Stinnerd594f242013-07-17 00:55:57 +0200263 do { \
Miss Skeleton (bot)c17ff5c2020-10-20 05:07:14 -0700264 x = GET_LOCALE_STRING(s); \
Victor Stinnerd594f242013-07-17 00:55:57 +0200265 RESULT(#s, x); \
266 } while (0)
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000267
268#define RESULT_INT(i)\
Victor Stinnerd594f242013-07-17 00:55:57 +0200269 do { \
Victor Stinner02e6bf72018-11-20 16:20:16 +0100270 x = PyLong_FromLong(lc->i); \
Victor Stinnerd594f242013-07-17 00:55:57 +0200271 RESULT(#i, x); \
272 } while (0)
Guido van Rossum220ecc81997-11-18 21:03:39 +0000273
Victor Stinner02e6bf72018-11-20 16:20:16 +0100274 /* Monetary information: LC_MONETARY encoding */
275 if (locale_decode_monetary(result, lc) < 0) {
276 goto failed;
277 }
278 x = copy_grouping(lc->mon_grouping);
Victor Stinnerd594f242013-07-17 00:55:57 +0200279 RESULT("mon_grouping", x);
280
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000281 RESULT_STRING(positive_sign);
282 RESULT_STRING(negative_sign);
283 RESULT_INT(int_frac_digits);
284 RESULT_INT(frac_digits);
285 RESULT_INT(p_cs_precedes);
286 RESULT_INT(p_sep_by_space);
287 RESULT_INT(n_cs_precedes);
288 RESULT_INT(n_sep_by_space);
289 RESULT_INT(p_sign_posn);
290 RESULT_INT(n_sign_posn);
Victor Stinnercb064fc2018-01-15 15:58:02 +0100291
Victor Stinner02e6bf72018-11-20 16:20:16 +0100292 /* Numeric information: LC_NUMERIC encoding */
Miss Skeleton (bot)c17ff5c2020-10-20 05:07:14 -0700293 PyObject *decimal_point = NULL, *thousands_sep = NULL;
Victor Stinner02e6bf72018-11-20 16:20:16 +0100294 if (_Py_GetLocaleconvNumeric(lc, &decimal_point, &thousands_sep) < 0) {
Miss Skeleton (bot)c17ff5c2020-10-20 05:07:14 -0700295 Py_XDECREF(decimal_point);
296 Py_XDECREF(thousands_sep);
Victor Stinnercb064fc2018-01-15 15:58:02 +0100297 goto failed;
298 }
299
300 if (PyDict_SetItemString(result, "decimal_point", decimal_point) < 0) {
301 Py_DECREF(decimal_point);
302 Py_DECREF(thousands_sep);
303 goto failed;
304 }
305 Py_DECREF(decimal_point);
306
307 if (PyDict_SetItemString(result, "thousands_sep", thousands_sep) < 0) {
308 Py_DECREF(thousands_sep);
309 goto failed;
310 }
311 Py_DECREF(thousands_sep);
312
Victor Stinner02e6bf72018-11-20 16:20:16 +0100313 x = copy_grouping(lc->grouping);
Victor Stinnercb064fc2018-01-15 15:58:02 +0100314 RESULT("grouping", x);
315
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000316 return result;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000317
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000318 failed:
Victor Stinnercb064fc2018-01-15 15:58:02 +0100319 Py_DECREF(result);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000320 return NULL;
Victor Stinner02e6bf72018-11-20 16:20:16 +0100321
322#undef RESULT
323#undef RESULT_STRING
324#undef RESULT_INT
Miss Skeleton (bot)c17ff5c2020-10-20 05:07:14 -0700325#undef GET_LOCALE_STRING
Guido van Rossum220ecc81997-11-18 21:03:39 +0000326}
327
Martin v. Löwis92fab752008-03-08 10:40:41 +0000328#if defined(HAVE_WCSCOLL)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000329PyDoc_STRVAR(strcoll__doc__,
330"string,string -> int. Compares two strings according to the locale.");
Guido van Rossum220ecc81997-11-18 21:03:39 +0000331
332static PyObject*
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000333PyLocale_strcoll(PyObject* self, PyObject* args)
Guido van Rossum220ecc81997-11-18 21:03:39 +0000334{
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000335 PyObject *os1, *os2, *result = NULL;
336 wchar_t *ws1 = NULL, *ws2 = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000337
Martin v. Löwis92fab752008-03-08 10:40:41 +0000338 if (!PyArg_ParseTuple(args, "UU:strcoll", &os1, &os2))
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000339 return NULL;
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000340 /* Convert the unicode strings to wchar[]. */
Victor Stinnerbeb4135b2010-10-07 01:02:42 +0000341 ws1 = PyUnicode_AsWideCharString(os1, NULL);
Victor Stinner449057f2010-09-29 10:30:43 +0000342 if (ws1 == NULL)
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000343 goto done;
Victor Stinnerbeb4135b2010-10-07 01:02:42 +0000344 ws2 = PyUnicode_AsWideCharString(os2, NULL);
Victor Stinner449057f2010-09-29 10:30:43 +0000345 if (ws2 == NULL)
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000346 goto done;
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000347 /* Collate the strings. */
Christian Heimes217cfd12007-12-02 14:31:20 +0000348 result = PyLong_FromLong(wcscoll(ws1, ws2));
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000349 done:
350 /* Deallocate everything. */
351 if (ws1) PyMem_FREE(ws1);
352 if (ws2) PyMem_FREE(ws2);
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000353 return result;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000354}
Martin v. Löwis92fab752008-03-08 10:40:41 +0000355#endif
Guido van Rossum220ecc81997-11-18 21:03:39 +0000356
Martin v. Löwis92fab752008-03-08 10:40:41 +0000357#ifdef HAVE_WCSXFRM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000358PyDoc_STRVAR(strxfrm__doc__,
Mark Dickinson211c6252009-02-01 10:28:51 +0000359"strxfrm(string) -> string.\n\
360\n\
361Return a string that can be used as a key for locale-aware comparisons.");
Guido van Rossum220ecc81997-11-18 21:03:39 +0000362
363static PyObject*
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000364PyLocale_strxfrm(PyObject* self, PyObject* args)
Guido van Rossum220ecc81997-11-18 21:03:39 +0000365{
Victor Stinner63649272011-09-29 23:32:06 +0200366 PyObject *str;
367 Py_ssize_t n1;
368 wchar_t *s = NULL, *buf = NULL;
369 size_t n2;
Martin v. Löwis92fab752008-03-08 10:40:41 +0000370 PyObject *result = NULL;
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000371
Victor Stinner63649272011-09-29 23:32:06 +0200372 if (!PyArg_ParseTuple(args, "U:strxfrm", &str))
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000373 return NULL;
374
Victor Stinner63649272011-09-29 23:32:06 +0200375 s = PyUnicode_AsWideCharString(str, &n1);
376 if (s == NULL)
377 goto exit;
Serhiy Storchakaf7eae0a2017-06-28 08:30:06 +0300378 if (wcslen(s) != (size_t)n1) {
379 PyErr_SetString(PyExc_ValueError,
380 "embedded null character");
381 goto exit;
382 }
Martin v. Löwis92fab752008-03-08 10:40:41 +0000383
384 /* assume no change in size, first */
Victor Stinner63649272011-09-29 23:32:06 +0200385 n1 = n1 + 1;
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +0200386 buf = PyMem_New(wchar_t, n1);
Martin v. Löwis92fab752008-03-08 10:40:41 +0000387 if (!buf) {
388 PyErr_NoMemory();
389 goto exit;
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000390 }
Serhiy Storchakabe487a62017-03-06 21:21:41 +0200391 errno = 0;
Martin v. Löwis92fab752008-03-08 10:40:41 +0000392 n2 = wcsxfrm(buf, s, n1);
Benjamin Petersonad4a0cc2017-03-07 22:24:44 -0800393 if (errno && errno != ERANGE) {
Serhiy Storchakabe487a62017-03-06 21:21:41 +0200394 PyErr_SetFromErrno(PyExc_OSError);
395 goto exit;
396 }
Victor Stinner2c5d3cb2011-10-11 22:35:52 +0200397 if (n2 >= (size_t)n1) {
Martin v. Löwis92fab752008-03-08 10:40:41 +0000398 /* more space needed */
Kristjan Valur Jonsson85634d72012-05-31 09:37:31 +0000399 wchar_t * new_buf = PyMem_Realloc(buf, (n2+1)*sizeof(wchar_t));
400 if (!new_buf) {
Martin v. Löwis92fab752008-03-08 10:40:41 +0000401 PyErr_NoMemory();
402 goto exit;
403 }
Kristjan Valur Jonsson85634d72012-05-31 09:37:31 +0000404 buf = new_buf;
Serhiy Storchakabe487a62017-03-06 21:21:41 +0200405 errno = 0;
Martin v. Löwisdb1c3992009-05-23 10:38:26 +0000406 n2 = wcsxfrm(buf, s, n2+1);
Serhiy Storchakabe487a62017-03-06 21:21:41 +0200407 if (errno) {
408 PyErr_SetFromErrno(PyExc_OSError);
409 goto exit;
410 }
Martin v. Löwis92fab752008-03-08 10:40:41 +0000411 }
412 result = PyUnicode_FromWideChar(buf, n2);
Victor Stinner63649272011-09-29 23:32:06 +0200413exit:
Serhiy Storchakabe487a62017-03-06 21:21:41 +0200414 PyMem_Free(buf);
415 PyMem_Free(s);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000416 return result;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000417}
Martin v. Löwis92fab752008-03-08 10:40:41 +0000418#endif
Guido van Rossum220ecc81997-11-18 21:03:39 +0000419
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000420#if defined(MS_WINDOWS)
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000421static PyObject*
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +0530422PyLocale_getdefaultlocale(PyObject* self, PyObject *Py_UNUSED(ignored))
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000423{
Victor Stinner9e4994d2018-08-28 23:26:33 +0200424 char encoding[20];
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000425 char locale[100];
426
Serhiy Storchakad53fe5f2019-03-13 22:59:55 +0200427 PyOS_snprintf(encoding, sizeof(encoding), "cp%u", GetACP());
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000428
429 if (GetLocaleInfo(LOCALE_USER_DEFAULT,
430 LOCALE_SISO639LANGNAME,
431 locale, sizeof(locale))) {
Martin v. Löwis18e16552006-02-15 17:27:45 +0000432 Py_ssize_t i = strlen(locale);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000433 locale[i++] = '_';
434 if (GetLocaleInfo(LOCALE_USER_DEFAULT,
435 LOCALE_SISO3166CTRYNAME,
Martin v. Löwis18e16552006-02-15 17:27:45 +0000436 locale+i, (int)(sizeof(locale)-i)))
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000437 return Py_BuildValue("ss", locale, encoding);
438 }
439
440 /* If we end up here, this windows version didn't know about
441 ISO639/ISO3166 names (it's probably Windows 95). Return the
442 Windows language identifier instead (a hexadecimal number) */
443
444 locale[0] = '0';
445 locale[1] = 'x';
446 if (GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_IDEFAULTLANGUAGE,
447 locale+2, sizeof(locale)-2)) {
448 return Py_BuildValue("ss", locale, encoding);
449 }
450
451 /* cannot determine the language code (very unlikely) */
452 Py_INCREF(Py_None);
453 return Py_BuildValue("Os", Py_None, encoding);
454}
455#endif
456
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000457#ifdef HAVE_LANGINFO_H
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000458#define LANGINFO(X) {#X, X}
Martin v. Löwis59683e82008-06-13 07:50:45 +0000459static struct langinfo_constant{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000460 char* name;
461 int value;
462} langinfo_constants[] =
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000463{
464 /* These constants should exist on any langinfo implementation */
465 LANGINFO(DAY_1),
466 LANGINFO(DAY_2),
467 LANGINFO(DAY_3),
468 LANGINFO(DAY_4),
469 LANGINFO(DAY_5),
470 LANGINFO(DAY_6),
471 LANGINFO(DAY_7),
472
473 LANGINFO(ABDAY_1),
474 LANGINFO(ABDAY_2),
475 LANGINFO(ABDAY_3),
476 LANGINFO(ABDAY_4),
477 LANGINFO(ABDAY_5),
478 LANGINFO(ABDAY_6),
479 LANGINFO(ABDAY_7),
480
481 LANGINFO(MON_1),
482 LANGINFO(MON_2),
483 LANGINFO(MON_3),
484 LANGINFO(MON_4),
485 LANGINFO(MON_5),
486 LANGINFO(MON_6),
487 LANGINFO(MON_7),
488 LANGINFO(MON_8),
489 LANGINFO(MON_9),
490 LANGINFO(MON_10),
491 LANGINFO(MON_11),
492 LANGINFO(MON_12),
493
494 LANGINFO(ABMON_1),
495 LANGINFO(ABMON_2),
496 LANGINFO(ABMON_3),
497 LANGINFO(ABMON_4),
498 LANGINFO(ABMON_5),
499 LANGINFO(ABMON_6),
500 LANGINFO(ABMON_7),
501 LANGINFO(ABMON_8),
502 LANGINFO(ABMON_9),
503 LANGINFO(ABMON_10),
504 LANGINFO(ABMON_11),
505 LANGINFO(ABMON_12),
506
507#ifdef RADIXCHAR
508 /* The following are not available with glibc 2.0 */
509 LANGINFO(RADIXCHAR),
510 LANGINFO(THOUSEP),
511 /* YESSTR and NOSTR are deprecated in glibc, since they are
512 a special case of message translation, which should be rather
513 done using gettext. So we don't expose it to Python in the
514 first place.
515 LANGINFO(YESSTR),
516 LANGINFO(NOSTR),
517 */
518 LANGINFO(CRNCYSTR),
519#endif
520
521 LANGINFO(D_T_FMT),
522 LANGINFO(D_FMT),
523 LANGINFO(T_FMT),
524 LANGINFO(AM_STR),
525 LANGINFO(PM_STR),
526
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000527 /* The following constants are available only with XPG4, but...
528 AIX 3.2. only has CODESET.
529 OpenBSD doesn't have CODESET but has T_FMT_AMPM, and doesn't have
530 a few of the others.
531 Solution: ifdef-test them all. */
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000532#ifdef CODESET
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000533 LANGINFO(CODESET),
Martin v. Löwis496f9e42002-03-27 12:15:57 +0000534#endif
535#ifdef T_FMT_AMPM
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000536 LANGINFO(T_FMT_AMPM),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000537#endif
538#ifdef ERA
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000539 LANGINFO(ERA),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000540#endif
541#ifdef ERA_D_FMT
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000542 LANGINFO(ERA_D_FMT),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000543#endif
544#ifdef ERA_D_T_FMT
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000545 LANGINFO(ERA_D_T_FMT),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000546#endif
547#ifdef ERA_T_FMT
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000548 LANGINFO(ERA_T_FMT),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000549#endif
550#ifdef ALT_DIGITS
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000551 LANGINFO(ALT_DIGITS),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000552#endif
553#ifdef YESEXPR
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000554 LANGINFO(YESEXPR),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000555#endif
556#ifdef NOEXPR
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000557 LANGINFO(NOEXPR),
558#endif
559#ifdef _DATE_FMT
560 /* This is not available in all glibc versions that have CODESET. */
561 LANGINFO(_DATE_FMT),
562#endif
563 {0, 0}
564};
565
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000566PyDoc_STRVAR(nl_langinfo__doc__,
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000567"nl_langinfo(key) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000568"Return the value for the locale information associated with key.");
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000569
570static PyObject*
571PyLocale_nl_langinfo(PyObject* self, PyObject* args)
572{
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000573 int item, i;
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000574 if (!PyArg_ParseTuple(args, "i:nl_langinfo", &item))
575 return NULL;
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000576 /* Check whether this is a supported constant. GNU libc sometimes
577 returns numeric values in the char* return value, which would
Neal Norwitz7f9d29c2007-08-26 07:21:45 +0000578 crash PyUnicode_FromString. */
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000579 for (i = 0; langinfo_constants[i].name; i++)
Hye-Shik Changc3a87b82004-03-21 19:34:30 +0000580 if (langinfo_constants[i].value == item) {
581 /* Check NULL as a workaround for GNU libc's returning NULL
582 instead of an empty string for nl_langinfo(ERA). */
583 const char *result = nl_langinfo(item);
Neal Norwitz3d7a90d2007-10-27 05:40:06 +0000584 result = result != NULL ? result : "";
Victor Stinnera9c895d2012-02-14 02:33:38 +0100585 return PyUnicode_DecodeLocale(result, NULL);
Hye-Shik Changc3a87b82004-03-21 19:34:30 +0000586 }
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000587 PyErr_SetString(PyExc_ValueError, "unsupported langinfo constant");
588 return NULL;
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000589}
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000590#endif /* HAVE_LANGINFO_H */
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000591
592#ifdef HAVE_LIBINTL_H
593
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000594PyDoc_STRVAR(gettext__doc__,
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000595"gettext(msg) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000596"Return translation of msg.");
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000597
598static PyObject*
599PyIntl_gettext(PyObject* self, PyObject *args)
600{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000601 char *in;
602 if (!PyArg_ParseTuple(args, "s", &in))
603 return 0;
Victor Stinnera9c895d2012-02-14 02:33:38 +0100604 return PyUnicode_DecodeLocale(gettext(in), NULL);
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000605}
606
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000607PyDoc_STRVAR(dgettext__doc__,
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000608"dgettext(domain, msg) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000609"Return translation of msg in domain.");
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000610
611static PyObject*
612PyIntl_dgettext(PyObject* self, PyObject *args)
613{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000614 char *domain, *in;
615 if (!PyArg_ParseTuple(args, "zs", &domain, &in))
616 return 0;
Victor Stinnera9c895d2012-02-14 02:33:38 +0100617 return PyUnicode_DecodeLocale(dgettext(domain, in), NULL);
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000618}
619
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000620PyDoc_STRVAR(dcgettext__doc__,
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000621"dcgettext(domain, msg, category) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000622"Return translation of msg in domain and category.");
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000623
624static PyObject*
625PyIntl_dcgettext(PyObject *self, PyObject *args)
626{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000627 char *domain, *msgid;
628 int category;
629 if (!PyArg_ParseTuple(args, "zsi", &domain, &msgid, &category))
630 return 0;
Victor Stinnera9c895d2012-02-14 02:33:38 +0100631 return PyUnicode_DecodeLocale(dcgettext(domain,msgid,category), NULL);
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000632}
633
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000634PyDoc_STRVAR(textdomain__doc__,
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000635"textdomain(domain) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000636"Set the C library's textdmain to domain, returning the new domain.");
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000637
638static PyObject*
639PyIntl_textdomain(PyObject* self, PyObject* args)
640{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000641 char *domain;
642 if (!PyArg_ParseTuple(args, "z", &domain))
643 return 0;
644 domain = textdomain(domain);
645 if (!domain) {
646 PyErr_SetFromErrno(PyExc_OSError);
647 return NULL;
648 }
Victor Stinnera9c895d2012-02-14 02:33:38 +0100649 return PyUnicode_DecodeLocale(domain, NULL);
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000650}
651
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000652PyDoc_STRVAR(bindtextdomain__doc__,
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000653"bindtextdomain(domain, dir) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000654"Bind the C library's domain to dir.");
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000655
656static PyObject*
Hai Shia1581682020-03-12 00:46:06 +0800657PyIntl_bindtextdomain(PyObject* self, PyObject*args)
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000658{
Serhiy Storchaka8f87eef2020-04-12 14:58:27 +0300659 const char *domain, *dirname, *current_dirname;
Victor Stinner9e19ca42010-06-11 22:09:51 +0000660 PyObject *dirname_obj, *dirname_bytes = NULL, *result;
Hai Shia1581682020-03-12 00:46:06 +0800661
Victor Stinner9e19ca42010-06-11 22:09:51 +0000662 if (!PyArg_ParseTuple(args, "sO", &domain, &dirname_obj))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000663 return 0;
664 if (!strlen(domain)) {
Hai Shia1581682020-03-12 00:46:06 +0800665 PyErr_SetString(get_locale_state(self)->Error,
666 "domain must be a non-empty string");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000667 return 0;
668 }
Victor Stinner9e19ca42010-06-11 22:09:51 +0000669 if (dirname_obj != Py_None) {
670 if (!PyUnicode_FSConverter(dirname_obj, &dirname_bytes))
671 return NULL;
672 dirname = PyBytes_AsString(dirname_bytes);
673 } else {
674 dirname_bytes = NULL;
675 dirname = NULL;
676 }
677 current_dirname = bindtextdomain(domain, dirname);
678 if (current_dirname == NULL) {
679 Py_XDECREF(dirname_bytes);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000680 PyErr_SetFromErrno(PyExc_OSError);
681 return NULL;
682 }
Victor Stinnera9c895d2012-02-14 02:33:38 +0100683 result = PyUnicode_DecodeLocale(current_dirname, NULL);
Victor Stinner9e19ca42010-06-11 22:09:51 +0000684 Py_XDECREF(dirname_bytes);
685 return result;
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000686}
687
Gustavo Niemeyer7bd33c52004-07-22 18:44:01 +0000688#ifdef HAVE_BIND_TEXTDOMAIN_CODESET
689PyDoc_STRVAR(bind_textdomain_codeset__doc__,
690"bind_textdomain_codeset(domain, codeset) -> string\n"
691"Bind the C library's domain to codeset.");
692
693static PyObject*
694PyIntl_bind_textdomain_codeset(PyObject* self,PyObject*args)
695{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000696 char *domain,*codeset;
697 if (!PyArg_ParseTuple(args, "sz", &domain, &codeset))
698 return NULL;
699 codeset = bind_textdomain_codeset(domain, codeset);
Victor Stinner7ed7aea2018-01-15 10:45:49 +0100700 if (codeset) {
Victor Stinnera9c895d2012-02-14 02:33:38 +0100701 return PyUnicode_DecodeLocale(codeset, NULL);
Victor Stinner7ed7aea2018-01-15 10:45:49 +0100702 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000703 Py_RETURN_NONE;
Gustavo Niemeyer7bd33c52004-07-22 18:44:01 +0000704}
705#endif
706
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000707#endif
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000708
Guido van Rossum220ecc81997-11-18 21:03:39 +0000709static struct PyMethodDef PyLocale_Methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000710 {"setlocale", (PyCFunction) PyLocale_setlocale,
Andrew M. Kuchlinge365fb82000-08-03 02:06:16 +0000711 METH_VARARGS, setlocale__doc__},
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +0530712 {"localeconv", PyLocale_localeconv, METH_NOARGS, localeconv__doc__},
Martin v. Löwis92fab752008-03-08 10:40:41 +0000713#ifdef HAVE_WCSCOLL
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000714 {"strcoll", (PyCFunction) PyLocale_strcoll,
Andrew M. Kuchlinge365fb82000-08-03 02:06:16 +0000715 METH_VARARGS, strcoll__doc__},
Martin v. Löwis92fab752008-03-08 10:40:41 +0000716#endif
717#ifdef HAVE_WCSXFRM
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000718 {"strxfrm", (PyCFunction) PyLocale_strxfrm,
Andrew M. Kuchlinge365fb82000-08-03 02:06:16 +0000719 METH_VARARGS, strxfrm__doc__},
Martin v. Löwis92fab752008-03-08 10:40:41 +0000720#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000721#if defined(MS_WINDOWS)
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +0530722 {"_getdefaultlocale", PyLocale_getdefaultlocale, METH_NOARGS},
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000723#endif
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000724#ifdef HAVE_LANGINFO_H
725 {"nl_langinfo", (PyCFunction) PyLocale_nl_langinfo,
726 METH_VARARGS, nl_langinfo__doc__},
727#endif
Martin v. Löwisc6a7d7e2002-05-02 12:16:29 +0000728#ifdef HAVE_LIBINTL_H
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000729 {"gettext",(PyCFunction)PyIntl_gettext,METH_VARARGS,
730 gettext__doc__},
731 {"dgettext",(PyCFunction)PyIntl_dgettext,METH_VARARGS,
732 dgettext__doc__},
733 {"dcgettext",(PyCFunction)PyIntl_dcgettext,METH_VARARGS,
734 dcgettext__doc__},
735 {"textdomain",(PyCFunction)PyIntl_textdomain,METH_VARARGS,
736 textdomain__doc__},
737 {"bindtextdomain",(PyCFunction)PyIntl_bindtextdomain,METH_VARARGS,
738 bindtextdomain__doc__},
Gustavo Niemeyer7bd33c52004-07-22 18:44:01 +0000739#ifdef HAVE_BIND_TEXTDOMAIN_CODESET
740 {"bind_textdomain_codeset",(PyCFunction)PyIntl_bind_textdomain_codeset,
741 METH_VARARGS, bind_textdomain_codeset__doc__},
742#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000743#endif
Guido van Rossum220ecc81997-11-18 21:03:39 +0000744 {NULL, NULL}
745};
746
Hai Shia1581682020-03-12 00:46:06 +0800747static int
Hai Shi7a6f3bc2020-04-03 02:00:47 +0800748_locale_exec(PyObject *module)
Guido van Rossum220ecc81997-11-18 21:03:39 +0000749{
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000750#ifdef HAVE_LANGINFO_H
751 int i;
752#endif
Hai Shi7a6f3bc2020-04-03 02:00:47 +0800753#define ADD_INT(module, value) \
754 do { \
755 if (PyModule_AddIntConstant(module, #value, value) < 0) { \
756 return -1; \
757 } \
758 } while (0)
Guido van Rossum220ecc81997-11-18 21:03:39 +0000759
Hai Shi7a6f3bc2020-04-03 02:00:47 +0800760 ADD_INT(module, LC_CTYPE);
761 ADD_INT(module, LC_TIME);
762 ADD_INT(module, LC_COLLATE);
763 ADD_INT(module, LC_MONETARY);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000764
Guido van Rossum8d9c2e31997-12-09 19:35:11 +0000765#ifdef LC_MESSAGES
Hai Shi7a6f3bc2020-04-03 02:00:47 +0800766 ADD_INT(module, LC_MESSAGES);
Guido van Rossum8d9c2e31997-12-09 19:35:11 +0000767#endif /* LC_MESSAGES */
Guido van Rossum220ecc81997-11-18 21:03:39 +0000768
Hai Shi7a6f3bc2020-04-03 02:00:47 +0800769 ADD_INT(module, LC_NUMERIC);
770 ADD_INT(module, LC_ALL);
771 ADD_INT(module, CHAR_MAX);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000772
Hai Shi7a6f3bc2020-04-03 02:00:47 +0800773 _locale_state *state = get_locale_state(module);
Hai Shia1581682020-03-12 00:46:06 +0800774 state->Error = PyErr_NewException("locale.Error", NULL, NULL);
775 if (state->Error == NULL) {
776 return -1;
Christian Heimesff4fddd2016-09-09 00:24:12 +0200777 }
Hai Shi7a6f3bc2020-04-03 02:00:47 +0800778 Py_INCREF(get_locale_state(module)->Error);
779 if (PyModule_AddObject(module, "Error", get_locale_state(module)->Error) < 0) {
780 Py_DECREF(get_locale_state(module)->Error);
Hai Shia1581682020-03-12 00:46:06 +0800781 return -1;
782 }
Guido van Rossum220ecc81997-11-18 21:03:39 +0000783
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000784#ifdef HAVE_LANGINFO_H
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000785 for (i = 0; langinfo_constants[i].name; i++) {
Hai Shi7a6f3bc2020-04-03 02:00:47 +0800786 if (PyModule_AddIntConstant(module,
787 langinfo_constants[i].name,
788 langinfo_constants[i].value) < 0) {
789 return -1;
790 }
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000791 }
Martin v. Löwisf95dd0a2001-08-15 17:14:33 +0000792#endif
Christian Heimesff4fddd2016-09-09 00:24:12 +0200793
794 if (PyErr_Occurred()) {
Hai Shia1581682020-03-12 00:46:06 +0800795 return -1;
Christian Heimesff4fddd2016-09-09 00:24:12 +0200796 }
Hai Shia1581682020-03-12 00:46:06 +0800797 return 0;
Hai Shi7a6f3bc2020-04-03 02:00:47 +0800798
799#undef ADD_INT
Hai Shia1581682020-03-12 00:46:06 +0800800}
801
802static struct PyModuleDef_Slot _locale_slots[] = {
803 {Py_mod_exec, _locale_exec},
804 {0, NULL}
805};
806
807static int
Hai Shi13397ee2020-03-20 01:11:33 +0800808locale_traverse(PyObject *module, visitproc visit, void *arg)
Hai Shia1581682020-03-12 00:46:06 +0800809{
Hai Shi13397ee2020-03-20 01:11:33 +0800810 _locale_state *state = get_locale_state(module);
Victor Stinner5b1ef202020-03-17 18:09:46 +0100811 Py_VISIT(state->Error);
Hai Shia1581682020-03-12 00:46:06 +0800812 return 0;
813}
814
815static int
Hai Shi13397ee2020-03-20 01:11:33 +0800816locale_clear(PyObject *module)
Hai Shia1581682020-03-12 00:46:06 +0800817{
Hai Shi13397ee2020-03-20 01:11:33 +0800818 _locale_state *state = get_locale_state(module);
Victor Stinner5b1ef202020-03-17 18:09:46 +0100819 Py_CLEAR(state->Error);
Hai Shia1581682020-03-12 00:46:06 +0800820 return 0;
821}
822
823static void
Hai Shi13397ee2020-03-20 01:11:33 +0800824locale_free(PyObject *module)
Hai Shia1581682020-03-12 00:46:06 +0800825{
Hai Shi13397ee2020-03-20 01:11:33 +0800826 locale_clear(module);
Hai Shia1581682020-03-12 00:46:06 +0800827}
828
829static struct PyModuleDef _localemodule = {
830 PyModuleDef_HEAD_INIT,
831 "_locale",
832 locale__doc__,
833 sizeof(_locale_state),
834 PyLocale_Methods,
835 _locale_slots,
836 locale_traverse,
837 locale_clear,
838 (freefunc)locale_free,
839};
840
841PyMODINIT_FUNC
842PyInit__locale(void)
843{
844 return PyModuleDef_Init(&_localemodule);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000845}
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000846
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000847/*
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000848Local variables:
849c-basic-offset: 4
850indent-tabs-mode: nil
851End:
852*/