blob: 0fe2e08b41f9f6d683dc9a816918deb8f06ecd02 [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
Zackery Spytzbbceef62020-07-15 03:07:34 -060056#include "clinic/_localemodule.c.h"
Guido van Rossum220ecc81997-11-18 21:03:39 +000057
Zackery Spytzbbceef62020-07-15 03:07:34 -060058/*[clinic input]
59module _locale
60[clinic start generated code]*/
61/*[clinic end generated code: output=da39a3ee5e6b4b0d input=ed98569b726feada]*/
62
63/* support functions for formatting floating point numbers */
Guido van Rossum220ecc81997-11-18 21:03:39 +000064
Guido van Rossum220ecc81997-11-18 21:03:39 +000065/* the grouping is terminated by either 0 or CHAR_MAX */
66static PyObject*
Serhiy Storchakaef1585e2015-12-25 20:01:53 +020067copy_grouping(const char* s)
Guido van Rossum220ecc81997-11-18 21:03:39 +000068{
Fredrik Lundh8f017a02000-07-08 19:57:37 +000069 int i;
70 PyObject *result, *val = NULL;
71
Martin Panter6d57fe12016-09-17 03:26:16 +000072 if (s[0] == '\0') {
Fredrik Lundh8f017a02000-07-08 19:57:37 +000073 /* empty string: no grouping at all */
74 return PyList_New(0);
Martin Panter6d57fe12016-09-17 03:26:16 +000075 }
Fredrik Lundh8f017a02000-07-08 19:57:37 +000076
77 for (i = 0; s[i] != '\0' && s[i] != CHAR_MAX; i++)
78 ; /* nothing */
79
80 result = PyList_New(i+1);
81 if (!result)
82 return NULL;
83
84 i = -1;
85 do {
86 i++;
Christian Heimes217cfd12007-12-02 14:31:20 +000087 val = PyLong_FromLong(s[i]);
Zackery Spytz99d56b52018-12-08 07:16:55 -070088 if (val == NULL) {
89 Py_DECREF(result);
90 return NULL;
Fredrik Lundh8f017a02000-07-08 19:57:37 +000091 }
Zackery Spytz99d56b52018-12-08 07:16:55 -070092 PyList_SET_ITEM(result, i, val);
Fredrik Lundh8f017a02000-07-08 19:57:37 +000093 } while (s[i] != '\0' && s[i] != CHAR_MAX);
94
Fredrik Lundh8f017a02000-07-08 19:57:37 +000095 return result;
Guido van Rossum220ecc81997-11-18 21:03:39 +000096}
97
Zackery Spytzbbceef62020-07-15 03:07:34 -060098/*[clinic input]
99_locale.setlocale
Guido van Rossum220ecc81997-11-18 21:03:39 +0000100
Zackery Spytzbbceef62020-07-15 03:07:34 -0600101 category: int
102 locale: str(accept={str, NoneType}) = NULL
103 /
104
105Activates/queries locale processing.
106[clinic start generated code]*/
107
108static PyObject *
109_locale_setlocale_impl(PyObject *module, int category, const char *locale)
110/*[clinic end generated code: output=a0e777ae5d2ff117 input=dbe18f1d66c57a6a]*/
111{
112 char *result;
113 PyObject *result_object;
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000114
Amaury Forgeot d'Arc64f3ca42009-12-01 21:59:18 +0000115#if defined(MS_WINDOWS)
116 if (category < LC_MIN || category > LC_MAX)
117 {
Zackery Spytzbbceef62020-07-15 03:07:34 -0600118 PyErr_SetString(get_locale_state(module)->Error,
Hai Shia1581682020-03-12 00:46:06 +0800119 "invalid locale category");
Amaury Forgeot d'Arc64f3ca42009-12-01 21:59:18 +0000120 return NULL;
121 }
122#endif
123
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000124 if (locale) {
125 /* set locale */
126 result = setlocale(category, locale);
127 if (!result) {
128 /* operation failed, no setting was changed */
Zackery Spytzbbceef62020-07-15 03:07:34 -0600129 PyErr_SetString(get_locale_state(module)->Error,
Hai Shia1581682020-03-12 00:46:06 +0800130 "unsupported locale setting");
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);
Mark Hammond9a714752003-07-24 14:15:07 +0000134 if (!result_object)
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000135 return NULL;
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000136 } else {
137 /* get locale */
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000138 result = setlocale(category, NULL);
139 if (!result) {
Zackery Spytzbbceef62020-07-15 03:07:34 -0600140 PyErr_SetString(get_locale_state(module)->Error,
Hai Shia1581682020-03-12 00:46:06 +0800141 "locale query failed");
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000142 return NULL;
143 }
Victor Stinnera9c895d2012-02-14 02:33:38 +0100144 result_object = PyUnicode_DecodeLocale(result, NULL);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000145 }
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000146 return result_object;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000147}
148
Victor Stinner02e6bf72018-11-20 16:20:16 +0100149static int
150locale_is_ascii(const char *str)
151{
152 return (strlen(str) == 1 && ((unsigned char)str[0]) <= 127);
153}
154
155static int
156locale_decode_monetary(PyObject *dict, struct lconv *lc)
157{
158 int change_locale;
159 change_locale = (!locale_is_ascii(lc->int_curr_symbol)
160 || !locale_is_ascii(lc->currency_symbol)
161 || !locale_is_ascii(lc->mon_decimal_point)
162 || !locale_is_ascii(lc->mon_thousands_sep));
163
164 /* Keep a copy of the LC_CTYPE locale */
165 char *oldloc = NULL, *loc = NULL;
166 if (change_locale) {
167 oldloc = setlocale(LC_CTYPE, NULL);
168 if (!oldloc) {
169 PyErr_SetString(PyExc_RuntimeWarning,
170 "failed to get LC_CTYPE locale");
171 return -1;
172 }
173
174 oldloc = _PyMem_Strdup(oldloc);
175 if (!oldloc) {
176 PyErr_NoMemory();
177 return -1;
178 }
179
180 loc = setlocale(LC_MONETARY, NULL);
181 if (loc != NULL && strcmp(loc, oldloc) == 0) {
182 loc = NULL;
183 }
184
185 if (loc != NULL) {
186 /* Only set the locale temporarily the LC_CTYPE locale
187 to the LC_MONETARY locale if the two locales are different and
188 at least one string is non-ASCII. */
189 setlocale(LC_CTYPE, loc);
190 }
191 }
192
193 int res = -1;
194
195#define RESULT_STRING(ATTR) \
196 do { \
197 PyObject *obj; \
198 obj = PyUnicode_DecodeLocale(lc->ATTR, NULL); \
199 if (obj == NULL) { \
200 goto done; \
201 } \
202 if (PyDict_SetItemString(dict, Py_STRINGIFY(ATTR), obj) < 0) { \
203 Py_DECREF(obj); \
204 goto done; \
205 } \
206 Py_DECREF(obj); \
207 } while (0)
208
209 RESULT_STRING(int_curr_symbol);
210 RESULT_STRING(currency_symbol);
211 RESULT_STRING(mon_decimal_point);
212 RESULT_STRING(mon_thousands_sep);
213#undef RESULT_STRING
214
215 res = 0;
216
217done:
218 if (loc != NULL) {
219 setlocale(LC_CTYPE, oldloc);
220 }
221 PyMem_Free(oldloc);
222 return res;
223}
224
Zackery Spytzbbceef62020-07-15 03:07:34 -0600225/*[clinic input]
226_locale.localeconv
Guido van Rossum220ecc81997-11-18 21:03:39 +0000227
Zackery Spytzbbceef62020-07-15 03:07:34 -0600228Returns numeric and monetary locale-specific parameters.
229[clinic start generated code]*/
230
231static PyObject *
232_locale_localeconv_impl(PyObject *module)
233/*[clinic end generated code: output=43a54515e0a2aef5 input=f1132d15accf4444]*/
Guido van Rossum220ecc81997-11-18 21:03:39 +0000234{
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000235 PyObject* result;
Victor Stinner02e6bf72018-11-20 16:20:16 +0100236 struct lconv *lc;
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000237 PyObject *x;
238
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000239 result = PyDict_New();
Victor Stinnercb064fc2018-01-15 15:58:02 +0100240 if (!result) {
Fredrik Lundh89610a42000-07-08 20:07:24 +0000241 return NULL;
Victor Stinnercb064fc2018-01-15 15:58:02 +0100242 }
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000243
244 /* if LC_NUMERIC is different in the C library, use saved value */
Victor Stinner02e6bf72018-11-20 16:20:16 +0100245 lc = localeconv();
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000246
247 /* hopefully, the localeconv result survives the C library calls
248 involved herein */
249
Victor Stinnerd594f242013-07-17 00:55:57 +0200250#define RESULT(key, obj)\
251 do { \
252 if (obj == NULL) \
253 goto failed; \
Victor Stinnerf38a5c22013-10-29 19:28:20 +0100254 if (PyDict_SetItemString(result, key, obj) < 0) { \
255 Py_DECREF(obj); \
Victor Stinnerd594f242013-07-17 00:55:57 +0200256 goto failed; \
Victor Stinnerf38a5c22013-10-29 19:28:20 +0100257 } \
Victor Stinnerd594f242013-07-17 00:55:57 +0200258 Py_DECREF(obj); \
259 } while (0)
260
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000261#define RESULT_STRING(s)\
Victor Stinnerd594f242013-07-17 00:55:57 +0200262 do { \
Victor Stinner02e6bf72018-11-20 16:20:16 +0100263 x = PyUnicode_DecodeLocale(lc->s, NULL); \
Victor Stinnerd594f242013-07-17 00:55:57 +0200264 RESULT(#s, x); \
265 } while (0)
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000266
267#define RESULT_INT(i)\
Victor Stinnerd594f242013-07-17 00:55:57 +0200268 do { \
Victor Stinner02e6bf72018-11-20 16:20:16 +0100269 x = PyLong_FromLong(lc->i); \
Victor Stinnerd594f242013-07-17 00:55:57 +0200270 RESULT(#i, x); \
271 } while (0)
Guido van Rossum220ecc81997-11-18 21:03:39 +0000272
Victor Stinner02e6bf72018-11-20 16:20:16 +0100273 /* Monetary information: LC_MONETARY encoding */
274 if (locale_decode_monetary(result, lc) < 0) {
275 goto failed;
276 }
277 x = copy_grouping(lc->mon_grouping);
Victor Stinnerd594f242013-07-17 00:55:57 +0200278 RESULT("mon_grouping", x);
279
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000280 RESULT_STRING(positive_sign);
281 RESULT_STRING(negative_sign);
282 RESULT_INT(int_frac_digits);
283 RESULT_INT(frac_digits);
284 RESULT_INT(p_cs_precedes);
285 RESULT_INT(p_sep_by_space);
286 RESULT_INT(n_cs_precedes);
287 RESULT_INT(n_sep_by_space);
288 RESULT_INT(p_sign_posn);
289 RESULT_INT(n_sign_posn);
Victor Stinnercb064fc2018-01-15 15:58:02 +0100290
Victor Stinner02e6bf72018-11-20 16:20:16 +0100291 /* Numeric information: LC_NUMERIC encoding */
Victor Stinnercb064fc2018-01-15 15:58:02 +0100292 PyObject *decimal_point, *thousands_sep;
Victor Stinner02e6bf72018-11-20 16:20:16 +0100293 if (_Py_GetLocaleconvNumeric(lc, &decimal_point, &thousands_sep) < 0) {
Victor Stinnercb064fc2018-01-15 15:58:02 +0100294 goto failed;
295 }
296
297 if (PyDict_SetItemString(result, "decimal_point", decimal_point) < 0) {
298 Py_DECREF(decimal_point);
299 Py_DECREF(thousands_sep);
300 goto failed;
301 }
302 Py_DECREF(decimal_point);
303
304 if (PyDict_SetItemString(result, "thousands_sep", thousands_sep) < 0) {
305 Py_DECREF(thousands_sep);
306 goto failed;
307 }
308 Py_DECREF(thousands_sep);
309
Victor Stinner02e6bf72018-11-20 16:20:16 +0100310 x = copy_grouping(lc->grouping);
Victor Stinnercb064fc2018-01-15 15:58:02 +0100311 RESULT("grouping", x);
312
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000313 return result;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000314
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000315 failed:
Victor Stinnercb064fc2018-01-15 15:58:02 +0100316 Py_DECREF(result);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000317 return NULL;
Victor Stinner02e6bf72018-11-20 16:20:16 +0100318
319#undef RESULT
320#undef RESULT_STRING
321#undef RESULT_INT
Guido van Rossum220ecc81997-11-18 21:03:39 +0000322}
323
Martin v. Löwis92fab752008-03-08 10:40:41 +0000324#if defined(HAVE_WCSCOLL)
Guido van Rossum220ecc81997-11-18 21:03:39 +0000325
Zackery Spytzbbceef62020-07-15 03:07:34 -0600326/*[clinic input]
327_locale.strcoll
328
329 os1: unicode
330 os2: unicode
331 /
332
333Compares two strings according to the locale.
334[clinic start generated code]*/
335
336static PyObject *
337_locale_strcoll_impl(PyObject *module, PyObject *os1, PyObject *os2)
338/*[clinic end generated code: output=82ddc6d62c76d618 input=693cd02bcbf38dd8]*/
Guido van Rossum220ecc81997-11-18 21:03:39 +0000339{
Zackery Spytzbbceef62020-07-15 03:07:34 -0600340 PyObject *result = NULL;
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000341 wchar_t *ws1 = NULL, *ws2 = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000342
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000343 /* Convert the unicode strings to wchar[]. */
Victor Stinnerbeb4135b2010-10-07 01:02:42 +0000344 ws1 = PyUnicode_AsWideCharString(os1, NULL);
Victor Stinner449057f2010-09-29 10:30:43 +0000345 if (ws1 == NULL)
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000346 goto done;
Victor Stinnerbeb4135b2010-10-07 01:02:42 +0000347 ws2 = PyUnicode_AsWideCharString(os2, NULL);
Victor Stinner449057f2010-09-29 10:30:43 +0000348 if (ws2 == NULL)
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000349 goto done;
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000350 /* Collate the strings. */
Christian Heimes217cfd12007-12-02 14:31:20 +0000351 result = PyLong_FromLong(wcscoll(ws1, ws2));
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000352 done:
353 /* Deallocate everything. */
354 if (ws1) PyMem_FREE(ws1);
355 if (ws2) PyMem_FREE(ws2);
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000356 return result;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000357}
Martin v. Löwis92fab752008-03-08 10:40:41 +0000358#endif
Guido van Rossum220ecc81997-11-18 21:03:39 +0000359
Martin v. Löwis92fab752008-03-08 10:40:41 +0000360#ifdef HAVE_WCSXFRM
Guido van Rossum220ecc81997-11-18 21:03:39 +0000361
Zackery Spytzbbceef62020-07-15 03:07:34 -0600362/*[clinic input]
363_locale.strxfrm
364
365 string as str: unicode
366 /
367
368Return a string that can be used as a key for locale-aware comparisons.
369[clinic start generated code]*/
370
371static PyObject *
372_locale_strxfrm_impl(PyObject *module, PyObject *str)
373/*[clinic end generated code: output=3081866ebffc01af input=1378bbe6a88b4780]*/
Guido van Rossum220ecc81997-11-18 21:03:39 +0000374{
Victor Stinner63649272011-09-29 23:32:06 +0200375 Py_ssize_t n1;
376 wchar_t *s = NULL, *buf = NULL;
377 size_t n2;
Martin v. Löwis92fab752008-03-08 10:40:41 +0000378 PyObject *result = NULL;
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000379
Victor Stinner63649272011-09-29 23:32:06 +0200380 s = PyUnicode_AsWideCharString(str, &n1);
381 if (s == NULL)
382 goto exit;
Serhiy Storchakaf7eae0a2017-06-28 08:30:06 +0300383 if (wcslen(s) != (size_t)n1) {
384 PyErr_SetString(PyExc_ValueError,
385 "embedded null character");
386 goto exit;
387 }
Martin v. Löwis92fab752008-03-08 10:40:41 +0000388
389 /* assume no change in size, first */
Victor Stinner63649272011-09-29 23:32:06 +0200390 n1 = n1 + 1;
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +0200391 buf = PyMem_New(wchar_t, n1);
Martin v. Löwis92fab752008-03-08 10:40:41 +0000392 if (!buf) {
393 PyErr_NoMemory();
394 goto exit;
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000395 }
Serhiy Storchakabe487a62017-03-06 21:21:41 +0200396 errno = 0;
Martin v. Löwis92fab752008-03-08 10:40:41 +0000397 n2 = wcsxfrm(buf, s, n1);
Benjamin Petersonad4a0cc2017-03-07 22:24:44 -0800398 if (errno && errno != ERANGE) {
Serhiy Storchakabe487a62017-03-06 21:21:41 +0200399 PyErr_SetFromErrno(PyExc_OSError);
400 goto exit;
401 }
Victor Stinner2c5d3cb2011-10-11 22:35:52 +0200402 if (n2 >= (size_t)n1) {
Martin v. Löwis92fab752008-03-08 10:40:41 +0000403 /* more space needed */
Kristjan Valur Jonsson85634d72012-05-31 09:37:31 +0000404 wchar_t * new_buf = PyMem_Realloc(buf, (n2+1)*sizeof(wchar_t));
405 if (!new_buf) {
Martin v. Löwis92fab752008-03-08 10:40:41 +0000406 PyErr_NoMemory();
407 goto exit;
408 }
Kristjan Valur Jonsson85634d72012-05-31 09:37:31 +0000409 buf = new_buf;
Serhiy Storchakabe487a62017-03-06 21:21:41 +0200410 errno = 0;
Martin v. Löwisdb1c3992009-05-23 10:38:26 +0000411 n2 = wcsxfrm(buf, s, n2+1);
Serhiy Storchakabe487a62017-03-06 21:21:41 +0200412 if (errno) {
413 PyErr_SetFromErrno(PyExc_OSError);
414 goto exit;
415 }
Martin v. Löwis92fab752008-03-08 10:40:41 +0000416 }
417 result = PyUnicode_FromWideChar(buf, n2);
Victor Stinner63649272011-09-29 23:32:06 +0200418exit:
Serhiy Storchakabe487a62017-03-06 21:21:41 +0200419 PyMem_Free(buf);
420 PyMem_Free(s);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000421 return result;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000422}
Martin v. Löwis92fab752008-03-08 10:40:41 +0000423#endif
Guido van Rossum220ecc81997-11-18 21:03:39 +0000424
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000425#if defined(MS_WINDOWS)
Zackery Spytzbbceef62020-07-15 03:07:34 -0600426
427/*[clinic input]
428_locale._getdefaultlocale
429
430[clinic start generated code]*/
431
432static PyObject *
433_locale__getdefaultlocale_impl(PyObject *module)
434/*[clinic end generated code: output=e6254088579534c2 input=003ea41acd17f7c7]*/
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000435{
Victor Stinner9e4994d2018-08-28 23:26:33 +0200436 char encoding[20];
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000437 char locale[100];
438
Serhiy Storchakad53fe5f2019-03-13 22:59:55 +0200439 PyOS_snprintf(encoding, sizeof(encoding), "cp%u", GetACP());
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000440
441 if (GetLocaleInfo(LOCALE_USER_DEFAULT,
442 LOCALE_SISO639LANGNAME,
443 locale, sizeof(locale))) {
Martin v. Löwis18e16552006-02-15 17:27:45 +0000444 Py_ssize_t i = strlen(locale);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000445 locale[i++] = '_';
446 if (GetLocaleInfo(LOCALE_USER_DEFAULT,
447 LOCALE_SISO3166CTRYNAME,
Martin v. Löwis18e16552006-02-15 17:27:45 +0000448 locale+i, (int)(sizeof(locale)-i)))
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000449 return Py_BuildValue("ss", locale, encoding);
450 }
451
452 /* If we end up here, this windows version didn't know about
453 ISO639/ISO3166 names (it's probably Windows 95). Return the
454 Windows language identifier instead (a hexadecimal number) */
455
456 locale[0] = '0';
457 locale[1] = 'x';
458 if (GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_IDEFAULTLANGUAGE,
459 locale+2, sizeof(locale)-2)) {
460 return Py_BuildValue("ss", locale, encoding);
461 }
462
463 /* cannot determine the language code (very unlikely) */
464 Py_INCREF(Py_None);
465 return Py_BuildValue("Os", Py_None, encoding);
466}
467#endif
468
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000469#ifdef HAVE_LANGINFO_H
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000470#define LANGINFO(X) {#X, X}
Martin v. Löwis59683e82008-06-13 07:50:45 +0000471static struct langinfo_constant{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000472 char* name;
473 int value;
474} langinfo_constants[] =
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000475{
476 /* These constants should exist on any langinfo implementation */
477 LANGINFO(DAY_1),
478 LANGINFO(DAY_2),
479 LANGINFO(DAY_3),
480 LANGINFO(DAY_4),
481 LANGINFO(DAY_5),
482 LANGINFO(DAY_6),
483 LANGINFO(DAY_7),
484
485 LANGINFO(ABDAY_1),
486 LANGINFO(ABDAY_2),
487 LANGINFO(ABDAY_3),
488 LANGINFO(ABDAY_4),
489 LANGINFO(ABDAY_5),
490 LANGINFO(ABDAY_6),
491 LANGINFO(ABDAY_7),
492
493 LANGINFO(MON_1),
494 LANGINFO(MON_2),
495 LANGINFO(MON_3),
496 LANGINFO(MON_4),
497 LANGINFO(MON_5),
498 LANGINFO(MON_6),
499 LANGINFO(MON_7),
500 LANGINFO(MON_8),
501 LANGINFO(MON_9),
502 LANGINFO(MON_10),
503 LANGINFO(MON_11),
504 LANGINFO(MON_12),
505
506 LANGINFO(ABMON_1),
507 LANGINFO(ABMON_2),
508 LANGINFO(ABMON_3),
509 LANGINFO(ABMON_4),
510 LANGINFO(ABMON_5),
511 LANGINFO(ABMON_6),
512 LANGINFO(ABMON_7),
513 LANGINFO(ABMON_8),
514 LANGINFO(ABMON_9),
515 LANGINFO(ABMON_10),
516 LANGINFO(ABMON_11),
517 LANGINFO(ABMON_12),
518
519#ifdef RADIXCHAR
520 /* The following are not available with glibc 2.0 */
521 LANGINFO(RADIXCHAR),
522 LANGINFO(THOUSEP),
523 /* YESSTR and NOSTR are deprecated in glibc, since they are
524 a special case of message translation, which should be rather
525 done using gettext. So we don't expose it to Python in the
526 first place.
527 LANGINFO(YESSTR),
528 LANGINFO(NOSTR),
529 */
530 LANGINFO(CRNCYSTR),
531#endif
532
533 LANGINFO(D_T_FMT),
534 LANGINFO(D_FMT),
535 LANGINFO(T_FMT),
536 LANGINFO(AM_STR),
537 LANGINFO(PM_STR),
538
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000539 /* The following constants are available only with XPG4, but...
540 AIX 3.2. only has CODESET.
541 OpenBSD doesn't have CODESET but has T_FMT_AMPM, and doesn't have
542 a few of the others.
543 Solution: ifdef-test them all. */
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000544#ifdef CODESET
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000545 LANGINFO(CODESET),
Martin v. Löwis496f9e42002-03-27 12:15:57 +0000546#endif
547#ifdef T_FMT_AMPM
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000548 LANGINFO(T_FMT_AMPM),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000549#endif
550#ifdef ERA
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000551 LANGINFO(ERA),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000552#endif
553#ifdef ERA_D_FMT
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000554 LANGINFO(ERA_D_FMT),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000555#endif
556#ifdef ERA_D_T_FMT
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000557 LANGINFO(ERA_D_T_FMT),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000558#endif
559#ifdef ERA_T_FMT
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000560 LANGINFO(ERA_T_FMT),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000561#endif
562#ifdef ALT_DIGITS
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000563 LANGINFO(ALT_DIGITS),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000564#endif
565#ifdef YESEXPR
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000566 LANGINFO(YESEXPR),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000567#endif
568#ifdef NOEXPR
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000569 LANGINFO(NOEXPR),
570#endif
571#ifdef _DATE_FMT
572 /* This is not available in all glibc versions that have CODESET. */
573 LANGINFO(_DATE_FMT),
574#endif
575 {0, 0}
576};
577
Zackery Spytzbbceef62020-07-15 03:07:34 -0600578/*[clinic input]
579_locale.nl_langinfo
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000580
Zackery Spytzbbceef62020-07-15 03:07:34 -0600581 key as item: int
582 /
583
584Return the value for the locale information associated with key.
585[clinic start generated code]*/
586
587static PyObject *
588_locale_nl_langinfo_impl(PyObject *module, int item)
589/*[clinic end generated code: output=6aea457b47e077a3 input=00798143eecfeddc]*/
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000590{
Zackery Spytzbbceef62020-07-15 03:07:34 -0600591 int i;
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000592 /* Check whether this is a supported constant. GNU libc sometimes
593 returns numeric values in the char* return value, which would
Neal Norwitz7f9d29c2007-08-26 07:21:45 +0000594 crash PyUnicode_FromString. */
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000595 for (i = 0; langinfo_constants[i].name; i++)
Hye-Shik Changc3a87b82004-03-21 19:34:30 +0000596 if (langinfo_constants[i].value == item) {
597 /* Check NULL as a workaround for GNU libc's returning NULL
598 instead of an empty string for nl_langinfo(ERA). */
599 const char *result = nl_langinfo(item);
Neal Norwitz3d7a90d2007-10-27 05:40:06 +0000600 result = result != NULL ? result : "";
Victor Stinnera9c895d2012-02-14 02:33:38 +0100601 return PyUnicode_DecodeLocale(result, NULL);
Hye-Shik Changc3a87b82004-03-21 19:34:30 +0000602 }
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000603 PyErr_SetString(PyExc_ValueError, "unsupported langinfo constant");
604 return NULL;
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000605}
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000606#endif /* HAVE_LANGINFO_H */
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000607
608#ifdef HAVE_LIBINTL_H
609
Zackery Spytzbbceef62020-07-15 03:07:34 -0600610/*[clinic input]
611_locale.gettext
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000612
Zackery Spytzbbceef62020-07-15 03:07:34 -0600613 msg as in: str
614 /
615
616gettext(msg) -> string
617
618Return translation of msg.
619[clinic start generated code]*/
620
621static PyObject *
622_locale_gettext_impl(PyObject *module, const char *in)
623/*[clinic end generated code: output=493bb4b38a4704fe input=949fc8efc2bb3bc3]*/
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000624{
Victor Stinnera9c895d2012-02-14 02:33:38 +0100625 return PyUnicode_DecodeLocale(gettext(in), NULL);
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000626}
627
Zackery Spytzbbceef62020-07-15 03:07:34 -0600628/*[clinic input]
629_locale.dgettext
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000630
Zackery Spytzbbceef62020-07-15 03:07:34 -0600631 domain: str(accept={str, NoneType})
632 msg as in: str
633 /
634
635dgettext(domain, msg) -> string
636
637Return translation of msg in domain.
638[clinic start generated code]*/
639
640static PyObject *
641_locale_dgettext_impl(PyObject *module, const char *domain, const char *in)
642/*[clinic end generated code: output=3c0cd5287b972c8f input=a277388a635109d8]*/
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000643{
Victor Stinnera9c895d2012-02-14 02:33:38 +0100644 return PyUnicode_DecodeLocale(dgettext(domain, in), NULL);
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000645}
646
Zackery Spytzbbceef62020-07-15 03:07:34 -0600647/*[clinic input]
648_locale.dcgettext
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000649
Zackery Spytzbbceef62020-07-15 03:07:34 -0600650 domain: str(accept={str, NoneType})
651 msg as msgid: str
652 category: int
653 /
654
655Return translation of msg in domain and category.
656[clinic start generated code]*/
657
658static PyObject *
659_locale_dcgettext_impl(PyObject *module, const char *domain,
660 const char *msgid, int category)
661/*[clinic end generated code: output=0f4cc4fce0aa283f input=ec5f8fed4336de67]*/
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000662{
Victor Stinnera9c895d2012-02-14 02:33:38 +0100663 return PyUnicode_DecodeLocale(dcgettext(domain,msgid,category), NULL);
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000664}
665
Zackery Spytzbbceef62020-07-15 03:07:34 -0600666/*[clinic input]
667_locale.textdomain
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000668
Zackery Spytzbbceef62020-07-15 03:07:34 -0600669 domain: str(accept={str, NoneType})
670 /
671
672Set the C library's textdmain to domain, returning the new domain.
673[clinic start generated code]*/
674
675static PyObject *
676_locale_textdomain_impl(PyObject *module, const char *domain)
677/*[clinic end generated code: output=7992df06aadec313 input=66359716f5eb1d38]*/
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000678{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000679 domain = textdomain(domain);
680 if (!domain) {
681 PyErr_SetFromErrno(PyExc_OSError);
682 return NULL;
683 }
Victor Stinnera9c895d2012-02-14 02:33:38 +0100684 return PyUnicode_DecodeLocale(domain, NULL);
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000685}
686
Zackery Spytzbbceef62020-07-15 03:07:34 -0600687/*[clinic input]
688_locale.bindtextdomain
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000689
Zackery Spytzbbceef62020-07-15 03:07:34 -0600690 domain: str
691 dir as dirname_obj: object
692 /
693
694Bind the C library's domain to dir.
695[clinic start generated code]*/
696
697static PyObject *
698_locale_bindtextdomain_impl(PyObject *module, const char *domain,
699 PyObject *dirname_obj)
700/*[clinic end generated code: output=6d6f3c7b345d785c input=c0dff085acfe272b]*/
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000701{
Zackery Spytzbbceef62020-07-15 03:07:34 -0600702 const char *dirname, *current_dirname;
703 PyObject *dirname_bytes = NULL, *result;
Hai Shia1581682020-03-12 00:46:06 +0800704
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000705 if (!strlen(domain)) {
Zackery Spytzbbceef62020-07-15 03:07:34 -0600706 PyErr_SetString(get_locale_state(module)->Error,
Hai Shia1581682020-03-12 00:46:06 +0800707 "domain must be a non-empty string");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000708 return 0;
709 }
Victor Stinner9e19ca42010-06-11 22:09:51 +0000710 if (dirname_obj != Py_None) {
711 if (!PyUnicode_FSConverter(dirname_obj, &dirname_bytes))
712 return NULL;
713 dirname = PyBytes_AsString(dirname_bytes);
714 } else {
715 dirname_bytes = NULL;
716 dirname = NULL;
717 }
718 current_dirname = bindtextdomain(domain, dirname);
719 if (current_dirname == NULL) {
720 Py_XDECREF(dirname_bytes);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000721 PyErr_SetFromErrno(PyExc_OSError);
722 return NULL;
723 }
Victor Stinnera9c895d2012-02-14 02:33:38 +0100724 result = PyUnicode_DecodeLocale(current_dirname, NULL);
Victor Stinner9e19ca42010-06-11 22:09:51 +0000725 Py_XDECREF(dirname_bytes);
726 return result;
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000727}
728
Gustavo Niemeyer7bd33c52004-07-22 18:44:01 +0000729#ifdef HAVE_BIND_TEXTDOMAIN_CODESET
Gustavo Niemeyer7bd33c52004-07-22 18:44:01 +0000730
Zackery Spytzbbceef62020-07-15 03:07:34 -0600731/*[clinic input]
732_locale.bind_textdomain_codeset
733
734 domain: str
735 codeset: str(accept={str, NoneType})
736 /
737
738Bind the C library's domain to codeset.
739[clinic start generated code]*/
740
741static PyObject *
742_locale_bind_textdomain_codeset_impl(PyObject *module, const char *domain,
743 const char *codeset)
744/*[clinic end generated code: output=fa452f9c8b1b9e89 input=23fbe3540400f259]*/
Gustavo Niemeyer7bd33c52004-07-22 18:44:01 +0000745{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000746 codeset = bind_textdomain_codeset(domain, codeset);
Victor Stinner7ed7aea2018-01-15 10:45:49 +0100747 if (codeset) {
Victor Stinnera9c895d2012-02-14 02:33:38 +0100748 return PyUnicode_DecodeLocale(codeset, NULL);
Victor Stinner7ed7aea2018-01-15 10:45:49 +0100749 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000750 Py_RETURN_NONE;
Gustavo Niemeyer7bd33c52004-07-22 18:44:01 +0000751}
752#endif
753
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000754#endif
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000755
Guido van Rossum220ecc81997-11-18 21:03:39 +0000756static struct PyMethodDef PyLocale_Methods[] = {
Zackery Spytzbbceef62020-07-15 03:07:34 -0600757 _LOCALE_SETLOCALE_METHODDEF
758 _LOCALE_LOCALECONV_METHODDEF
Martin v. Löwis92fab752008-03-08 10:40:41 +0000759#ifdef HAVE_WCSCOLL
Zackery Spytzbbceef62020-07-15 03:07:34 -0600760 _LOCALE_STRCOLL_METHODDEF
Martin v. Löwis92fab752008-03-08 10:40:41 +0000761#endif
762#ifdef HAVE_WCSXFRM
Zackery Spytzbbceef62020-07-15 03:07:34 -0600763 _LOCALE_STRXFRM_METHODDEF
Martin v. Löwis92fab752008-03-08 10:40:41 +0000764#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000765#if defined(MS_WINDOWS)
Zackery Spytzbbceef62020-07-15 03:07:34 -0600766 _LOCALE__GETDEFAULTLOCALE_METHODDEF
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000767#endif
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000768#ifdef HAVE_LANGINFO_H
Zackery Spytzbbceef62020-07-15 03:07:34 -0600769 _LOCALE_NL_LANGINFO_METHODDEF
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000770#endif
Martin v. Löwisc6a7d7e2002-05-02 12:16:29 +0000771#ifdef HAVE_LIBINTL_H
Zackery Spytzbbceef62020-07-15 03:07:34 -0600772 _LOCALE_GETTEXT_METHODDEF
773 _LOCALE_DGETTEXT_METHODDEF
774 _LOCALE_DCGETTEXT_METHODDEF
775 _LOCALE_TEXTDOMAIN_METHODDEF
776 _LOCALE_BINDTEXTDOMAIN_METHODDEF
Gustavo Niemeyer7bd33c52004-07-22 18:44:01 +0000777#ifdef HAVE_BIND_TEXTDOMAIN_CODESET
Zackery Spytzbbceef62020-07-15 03:07:34 -0600778 _LOCALE_BIND_TEXTDOMAIN_CODESET_METHODDEF
Gustavo Niemeyer7bd33c52004-07-22 18:44:01 +0000779#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000780#endif
Guido van Rossum220ecc81997-11-18 21:03:39 +0000781 {NULL, NULL}
782};
783
Hai Shia1581682020-03-12 00:46:06 +0800784static int
Hai Shi7a6f3bc2020-04-03 02:00:47 +0800785_locale_exec(PyObject *module)
Guido van Rossum220ecc81997-11-18 21:03:39 +0000786{
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000787#ifdef HAVE_LANGINFO_H
788 int i;
789#endif
Hai Shi7a6f3bc2020-04-03 02:00:47 +0800790#define ADD_INT(module, value) \
791 do { \
792 if (PyModule_AddIntConstant(module, #value, value) < 0) { \
793 return -1; \
794 } \
795 } while (0)
Guido van Rossum220ecc81997-11-18 21:03:39 +0000796
Hai Shi7a6f3bc2020-04-03 02:00:47 +0800797 ADD_INT(module, LC_CTYPE);
798 ADD_INT(module, LC_TIME);
799 ADD_INT(module, LC_COLLATE);
800 ADD_INT(module, LC_MONETARY);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000801
Guido van Rossum8d9c2e31997-12-09 19:35:11 +0000802#ifdef LC_MESSAGES
Hai Shi7a6f3bc2020-04-03 02:00:47 +0800803 ADD_INT(module, LC_MESSAGES);
Guido van Rossum8d9c2e31997-12-09 19:35:11 +0000804#endif /* LC_MESSAGES */
Guido van Rossum220ecc81997-11-18 21:03:39 +0000805
Hai Shi7a6f3bc2020-04-03 02:00:47 +0800806 ADD_INT(module, LC_NUMERIC);
807 ADD_INT(module, LC_ALL);
808 ADD_INT(module, CHAR_MAX);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000809
Hai Shi7a6f3bc2020-04-03 02:00:47 +0800810 _locale_state *state = get_locale_state(module);
Hai Shia1581682020-03-12 00:46:06 +0800811 state->Error = PyErr_NewException("locale.Error", NULL, NULL);
812 if (state->Error == NULL) {
813 return -1;
Christian Heimesff4fddd2016-09-09 00:24:12 +0200814 }
Hai Shi7a6f3bc2020-04-03 02:00:47 +0800815 Py_INCREF(get_locale_state(module)->Error);
816 if (PyModule_AddObject(module, "Error", get_locale_state(module)->Error) < 0) {
817 Py_DECREF(get_locale_state(module)->Error);
Hai Shia1581682020-03-12 00:46:06 +0800818 return -1;
819 }
Guido van Rossum220ecc81997-11-18 21:03:39 +0000820
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000821#ifdef HAVE_LANGINFO_H
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000822 for (i = 0; langinfo_constants[i].name; i++) {
Hai Shi7a6f3bc2020-04-03 02:00:47 +0800823 if (PyModule_AddIntConstant(module,
824 langinfo_constants[i].name,
825 langinfo_constants[i].value) < 0) {
826 return -1;
827 }
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000828 }
Martin v. Löwisf95dd0a2001-08-15 17:14:33 +0000829#endif
Christian Heimesff4fddd2016-09-09 00:24:12 +0200830
831 if (PyErr_Occurred()) {
Hai Shia1581682020-03-12 00:46:06 +0800832 return -1;
Christian Heimesff4fddd2016-09-09 00:24:12 +0200833 }
Hai Shia1581682020-03-12 00:46:06 +0800834 return 0;
Hai Shi7a6f3bc2020-04-03 02:00:47 +0800835
836#undef ADD_INT
Hai Shia1581682020-03-12 00:46:06 +0800837}
838
839static struct PyModuleDef_Slot _locale_slots[] = {
840 {Py_mod_exec, _locale_exec},
841 {0, NULL}
842};
843
844static int
Hai Shi13397ee2020-03-20 01:11:33 +0800845locale_traverse(PyObject *module, visitproc visit, void *arg)
Hai Shia1581682020-03-12 00:46:06 +0800846{
Hai Shi13397ee2020-03-20 01:11:33 +0800847 _locale_state *state = get_locale_state(module);
Victor Stinner5b1ef202020-03-17 18:09:46 +0100848 Py_VISIT(state->Error);
Hai Shia1581682020-03-12 00:46:06 +0800849 return 0;
850}
851
852static int
Hai Shi13397ee2020-03-20 01:11:33 +0800853locale_clear(PyObject *module)
Hai Shia1581682020-03-12 00:46:06 +0800854{
Hai Shi13397ee2020-03-20 01:11:33 +0800855 _locale_state *state = get_locale_state(module);
Victor Stinner5b1ef202020-03-17 18:09:46 +0100856 Py_CLEAR(state->Error);
Hai Shia1581682020-03-12 00:46:06 +0800857 return 0;
858}
859
860static void
Hai Shi13397ee2020-03-20 01:11:33 +0800861locale_free(PyObject *module)
Hai Shia1581682020-03-12 00:46:06 +0800862{
Hai Shi13397ee2020-03-20 01:11:33 +0800863 locale_clear(module);
Hai Shia1581682020-03-12 00:46:06 +0800864}
865
866static struct PyModuleDef _localemodule = {
867 PyModuleDef_HEAD_INIT,
868 "_locale",
869 locale__doc__,
870 sizeof(_locale_state),
871 PyLocale_Methods,
872 _locale_slots,
873 locale_traverse,
874 locale_clear,
875 (freefunc)locale_free,
876};
877
878PyMODINIT_FUNC
879PyInit__locale(void)
880{
881 return PyModuleDef_Init(&_localemodule);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000882}
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000883
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000884/*
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000885Local variables:
886c-basic-offset: 4
887indent-tabs-mode: nil
888End:
889*/