blob: 0819d0e1924087f1df39d835511cc0bed2c665ed [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{
147 int change_locale;
148 change_locale = (!locale_is_ascii(lc->int_curr_symbol)
149 || !locale_is_ascii(lc->currency_symbol)
150 || !locale_is_ascii(lc->mon_decimal_point)
151 || !locale_is_ascii(lc->mon_thousands_sep));
152
153 /* Keep a copy of the LC_CTYPE locale */
154 char *oldloc = NULL, *loc = NULL;
155 if (change_locale) {
156 oldloc = setlocale(LC_CTYPE, NULL);
157 if (!oldloc) {
158 PyErr_SetString(PyExc_RuntimeWarning,
159 "failed to get LC_CTYPE locale");
160 return -1;
161 }
162
163 oldloc = _PyMem_Strdup(oldloc);
164 if (!oldloc) {
165 PyErr_NoMemory();
166 return -1;
167 }
168
169 loc = setlocale(LC_MONETARY, NULL);
170 if (loc != NULL && strcmp(loc, oldloc) == 0) {
171 loc = NULL;
172 }
173
174 if (loc != NULL) {
175 /* Only set the locale temporarily the LC_CTYPE locale
176 to the LC_MONETARY locale if the two locales are different and
177 at least one string is non-ASCII. */
178 setlocale(LC_CTYPE, loc);
179 }
180 }
181
182 int res = -1;
183
184#define RESULT_STRING(ATTR) \
185 do { \
186 PyObject *obj; \
187 obj = PyUnicode_DecodeLocale(lc->ATTR, NULL); \
188 if (obj == NULL) { \
189 goto done; \
190 } \
191 if (PyDict_SetItemString(dict, Py_STRINGIFY(ATTR), obj) < 0) { \
192 Py_DECREF(obj); \
193 goto done; \
194 } \
195 Py_DECREF(obj); \
196 } while (0)
197
198 RESULT_STRING(int_curr_symbol);
199 RESULT_STRING(currency_symbol);
200 RESULT_STRING(mon_decimal_point);
201 RESULT_STRING(mon_thousands_sep);
202#undef RESULT_STRING
203
204 res = 0;
205
206done:
207 if (loc != NULL) {
208 setlocale(LC_CTYPE, oldloc);
209 }
210 PyMem_Free(oldloc);
211 return res;
212}
213
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000214PyDoc_STRVAR(localeconv__doc__,
215"() -> dict. Returns numeric and monetary locale-specific parameters.");
Guido van Rossum220ecc81997-11-18 21:03:39 +0000216
217static PyObject*
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +0530218PyLocale_localeconv(PyObject* self, PyObject *Py_UNUSED(ignored))
Guido van Rossum220ecc81997-11-18 21:03:39 +0000219{
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000220 PyObject* result;
Victor Stinner02e6bf72018-11-20 16:20:16 +0100221 struct lconv *lc;
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000222 PyObject *x;
223
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000224 result = PyDict_New();
Victor Stinnercb064fc2018-01-15 15:58:02 +0100225 if (!result) {
Fredrik Lundh89610a42000-07-08 20:07:24 +0000226 return NULL;
Victor Stinnercb064fc2018-01-15 15:58:02 +0100227 }
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000228
229 /* if LC_NUMERIC is different in the C library, use saved value */
Victor Stinner02e6bf72018-11-20 16:20:16 +0100230 lc = localeconv();
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000231
232 /* hopefully, the localeconv result survives the C library calls
233 involved herein */
234
Victor Stinnerd594f242013-07-17 00:55:57 +0200235#define RESULT(key, obj)\
236 do { \
237 if (obj == NULL) \
238 goto failed; \
Victor Stinnerf38a5c22013-10-29 19:28:20 +0100239 if (PyDict_SetItemString(result, key, obj) < 0) { \
240 Py_DECREF(obj); \
Victor Stinnerd594f242013-07-17 00:55:57 +0200241 goto failed; \
Victor Stinnerf38a5c22013-10-29 19:28:20 +0100242 } \
Victor Stinnerd594f242013-07-17 00:55:57 +0200243 Py_DECREF(obj); \
244 } while (0)
245
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000246#define RESULT_STRING(s)\
Victor Stinnerd594f242013-07-17 00:55:57 +0200247 do { \
Victor Stinner02e6bf72018-11-20 16:20:16 +0100248 x = PyUnicode_DecodeLocale(lc->s, NULL); \
Victor Stinnerd594f242013-07-17 00:55:57 +0200249 RESULT(#s, x); \
250 } while (0)
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000251
252#define RESULT_INT(i)\
Victor Stinnerd594f242013-07-17 00:55:57 +0200253 do { \
Victor Stinner02e6bf72018-11-20 16:20:16 +0100254 x = PyLong_FromLong(lc->i); \
Victor Stinnerd594f242013-07-17 00:55:57 +0200255 RESULT(#i, x); \
256 } while (0)
Guido van Rossum220ecc81997-11-18 21:03:39 +0000257
Victor Stinner02e6bf72018-11-20 16:20:16 +0100258 /* Monetary information: LC_MONETARY encoding */
259 if (locale_decode_monetary(result, lc) < 0) {
260 goto failed;
261 }
262 x = copy_grouping(lc->mon_grouping);
Victor Stinnerd594f242013-07-17 00:55:57 +0200263 RESULT("mon_grouping", x);
264
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000265 RESULT_STRING(positive_sign);
266 RESULT_STRING(negative_sign);
267 RESULT_INT(int_frac_digits);
268 RESULT_INT(frac_digits);
269 RESULT_INT(p_cs_precedes);
270 RESULT_INT(p_sep_by_space);
271 RESULT_INT(n_cs_precedes);
272 RESULT_INT(n_sep_by_space);
273 RESULT_INT(p_sign_posn);
274 RESULT_INT(n_sign_posn);
Victor Stinnercb064fc2018-01-15 15:58:02 +0100275
Victor Stinner02e6bf72018-11-20 16:20:16 +0100276 /* Numeric information: LC_NUMERIC encoding */
Victor Stinnercb064fc2018-01-15 15:58:02 +0100277 PyObject *decimal_point, *thousands_sep;
Victor Stinner02e6bf72018-11-20 16:20:16 +0100278 if (_Py_GetLocaleconvNumeric(lc, &decimal_point, &thousands_sep) < 0) {
Victor Stinnercb064fc2018-01-15 15:58:02 +0100279 goto failed;
280 }
281
282 if (PyDict_SetItemString(result, "decimal_point", decimal_point) < 0) {
283 Py_DECREF(decimal_point);
284 Py_DECREF(thousands_sep);
285 goto failed;
286 }
287 Py_DECREF(decimal_point);
288
289 if (PyDict_SetItemString(result, "thousands_sep", thousands_sep) < 0) {
290 Py_DECREF(thousands_sep);
291 goto failed;
292 }
293 Py_DECREF(thousands_sep);
294
Victor Stinner02e6bf72018-11-20 16:20:16 +0100295 x = copy_grouping(lc->grouping);
Victor Stinnercb064fc2018-01-15 15:58:02 +0100296 RESULT("grouping", x);
297
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000298 return result;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000299
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000300 failed:
Victor Stinnercb064fc2018-01-15 15:58:02 +0100301 Py_DECREF(result);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000302 return NULL;
Victor Stinner02e6bf72018-11-20 16:20:16 +0100303
304#undef RESULT
305#undef RESULT_STRING
306#undef RESULT_INT
Guido van Rossum220ecc81997-11-18 21:03:39 +0000307}
308
Martin v. Löwis92fab752008-03-08 10:40:41 +0000309#if defined(HAVE_WCSCOLL)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000310PyDoc_STRVAR(strcoll__doc__,
311"string,string -> int. Compares two strings according to the locale.");
Guido van Rossum220ecc81997-11-18 21:03:39 +0000312
313static PyObject*
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000314PyLocale_strcoll(PyObject* self, PyObject* args)
Guido van Rossum220ecc81997-11-18 21:03:39 +0000315{
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000316 PyObject *os1, *os2, *result = NULL;
317 wchar_t *ws1 = NULL, *ws2 = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000318
Martin v. Löwis92fab752008-03-08 10:40:41 +0000319 if (!PyArg_ParseTuple(args, "UU:strcoll", &os1, &os2))
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000320 return NULL;
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000321 /* Convert the unicode strings to wchar[]. */
Victor Stinnerbeb4135b2010-10-07 01:02:42 +0000322 ws1 = PyUnicode_AsWideCharString(os1, NULL);
Victor Stinner449057f2010-09-29 10:30:43 +0000323 if (ws1 == NULL)
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000324 goto done;
Victor Stinnerbeb4135b2010-10-07 01:02:42 +0000325 ws2 = PyUnicode_AsWideCharString(os2, NULL);
Victor Stinner449057f2010-09-29 10:30:43 +0000326 if (ws2 == NULL)
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000327 goto done;
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000328 /* Collate the strings. */
Christian Heimes217cfd12007-12-02 14:31:20 +0000329 result = PyLong_FromLong(wcscoll(ws1, ws2));
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000330 done:
331 /* Deallocate everything. */
332 if (ws1) PyMem_FREE(ws1);
333 if (ws2) PyMem_FREE(ws2);
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000334 return result;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000335}
Martin v. Löwis92fab752008-03-08 10:40:41 +0000336#endif
Guido van Rossum220ecc81997-11-18 21:03:39 +0000337
Martin v. Löwis92fab752008-03-08 10:40:41 +0000338#ifdef HAVE_WCSXFRM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000339PyDoc_STRVAR(strxfrm__doc__,
Mark Dickinson211c6252009-02-01 10:28:51 +0000340"strxfrm(string) -> string.\n\
341\n\
342Return a string that can be used as a key for locale-aware comparisons.");
Guido van Rossum220ecc81997-11-18 21:03:39 +0000343
344static PyObject*
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000345PyLocale_strxfrm(PyObject* self, PyObject* args)
Guido van Rossum220ecc81997-11-18 21:03:39 +0000346{
Victor Stinner63649272011-09-29 23:32:06 +0200347 PyObject *str;
348 Py_ssize_t n1;
349 wchar_t *s = NULL, *buf = NULL;
350 size_t n2;
Martin v. Löwis92fab752008-03-08 10:40:41 +0000351 PyObject *result = NULL;
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000352
Victor Stinner63649272011-09-29 23:32:06 +0200353 if (!PyArg_ParseTuple(args, "U:strxfrm", &str))
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000354 return NULL;
355
Victor Stinner63649272011-09-29 23:32:06 +0200356 s = PyUnicode_AsWideCharString(str, &n1);
357 if (s == NULL)
358 goto exit;
Serhiy Storchakaf7eae0a2017-06-28 08:30:06 +0300359 if (wcslen(s) != (size_t)n1) {
360 PyErr_SetString(PyExc_ValueError,
361 "embedded null character");
362 goto exit;
363 }
Martin v. Löwis92fab752008-03-08 10:40:41 +0000364
365 /* assume no change in size, first */
Victor Stinner63649272011-09-29 23:32:06 +0200366 n1 = n1 + 1;
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +0200367 buf = PyMem_New(wchar_t, n1);
Martin v. Löwis92fab752008-03-08 10:40:41 +0000368 if (!buf) {
369 PyErr_NoMemory();
370 goto exit;
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000371 }
Serhiy Storchakabe487a62017-03-06 21:21:41 +0200372 errno = 0;
Martin v. Löwis92fab752008-03-08 10:40:41 +0000373 n2 = wcsxfrm(buf, s, n1);
Benjamin Petersonad4a0cc2017-03-07 22:24:44 -0800374 if (errno && errno != ERANGE) {
Serhiy Storchakabe487a62017-03-06 21:21:41 +0200375 PyErr_SetFromErrno(PyExc_OSError);
376 goto exit;
377 }
Victor Stinner2c5d3cb2011-10-11 22:35:52 +0200378 if (n2 >= (size_t)n1) {
Martin v. Löwis92fab752008-03-08 10:40:41 +0000379 /* more space needed */
Kristjan Valur Jonsson85634d72012-05-31 09:37:31 +0000380 wchar_t * new_buf = PyMem_Realloc(buf, (n2+1)*sizeof(wchar_t));
381 if (!new_buf) {
Martin v. Löwis92fab752008-03-08 10:40:41 +0000382 PyErr_NoMemory();
383 goto exit;
384 }
Kristjan Valur Jonsson85634d72012-05-31 09:37:31 +0000385 buf = new_buf;
Serhiy Storchakabe487a62017-03-06 21:21:41 +0200386 errno = 0;
Martin v. Löwisdb1c3992009-05-23 10:38:26 +0000387 n2 = wcsxfrm(buf, s, n2+1);
Serhiy Storchakabe487a62017-03-06 21:21:41 +0200388 if (errno) {
389 PyErr_SetFromErrno(PyExc_OSError);
390 goto exit;
391 }
Martin v. Löwis92fab752008-03-08 10:40:41 +0000392 }
393 result = PyUnicode_FromWideChar(buf, n2);
Victor Stinner63649272011-09-29 23:32:06 +0200394exit:
Serhiy Storchakabe487a62017-03-06 21:21:41 +0200395 PyMem_Free(buf);
396 PyMem_Free(s);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000397 return result;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000398}
Martin v. Löwis92fab752008-03-08 10:40:41 +0000399#endif
Guido van Rossum220ecc81997-11-18 21:03:39 +0000400
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000401#if defined(MS_WINDOWS)
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000402static PyObject*
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +0530403PyLocale_getdefaultlocale(PyObject* self, PyObject *Py_UNUSED(ignored))
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000404{
Victor Stinner9e4994d2018-08-28 23:26:33 +0200405 char encoding[20];
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000406 char locale[100];
407
Serhiy Storchakad53fe5f2019-03-13 22:59:55 +0200408 PyOS_snprintf(encoding, sizeof(encoding), "cp%u", GetACP());
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000409
410 if (GetLocaleInfo(LOCALE_USER_DEFAULT,
411 LOCALE_SISO639LANGNAME,
412 locale, sizeof(locale))) {
Martin v. Löwis18e16552006-02-15 17:27:45 +0000413 Py_ssize_t i = strlen(locale);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000414 locale[i++] = '_';
415 if (GetLocaleInfo(LOCALE_USER_DEFAULT,
416 LOCALE_SISO3166CTRYNAME,
Martin v. Löwis18e16552006-02-15 17:27:45 +0000417 locale+i, (int)(sizeof(locale)-i)))
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000418 return Py_BuildValue("ss", locale, encoding);
419 }
420
421 /* If we end up here, this windows version didn't know about
422 ISO639/ISO3166 names (it's probably Windows 95). Return the
423 Windows language identifier instead (a hexadecimal number) */
424
425 locale[0] = '0';
426 locale[1] = 'x';
427 if (GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_IDEFAULTLANGUAGE,
428 locale+2, sizeof(locale)-2)) {
429 return Py_BuildValue("ss", locale, encoding);
430 }
431
432 /* cannot determine the language code (very unlikely) */
433 Py_INCREF(Py_None);
434 return Py_BuildValue("Os", Py_None, encoding);
435}
436#endif
437
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000438#ifdef HAVE_LANGINFO_H
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000439#define LANGINFO(X) {#X, X}
Martin v. Löwis59683e82008-06-13 07:50:45 +0000440static struct langinfo_constant{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000441 char* name;
442 int value;
443} langinfo_constants[] =
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000444{
445 /* These constants should exist on any langinfo implementation */
446 LANGINFO(DAY_1),
447 LANGINFO(DAY_2),
448 LANGINFO(DAY_3),
449 LANGINFO(DAY_4),
450 LANGINFO(DAY_5),
451 LANGINFO(DAY_6),
452 LANGINFO(DAY_7),
453
454 LANGINFO(ABDAY_1),
455 LANGINFO(ABDAY_2),
456 LANGINFO(ABDAY_3),
457 LANGINFO(ABDAY_4),
458 LANGINFO(ABDAY_5),
459 LANGINFO(ABDAY_6),
460 LANGINFO(ABDAY_7),
461
462 LANGINFO(MON_1),
463 LANGINFO(MON_2),
464 LANGINFO(MON_3),
465 LANGINFO(MON_4),
466 LANGINFO(MON_5),
467 LANGINFO(MON_6),
468 LANGINFO(MON_7),
469 LANGINFO(MON_8),
470 LANGINFO(MON_9),
471 LANGINFO(MON_10),
472 LANGINFO(MON_11),
473 LANGINFO(MON_12),
474
475 LANGINFO(ABMON_1),
476 LANGINFO(ABMON_2),
477 LANGINFO(ABMON_3),
478 LANGINFO(ABMON_4),
479 LANGINFO(ABMON_5),
480 LANGINFO(ABMON_6),
481 LANGINFO(ABMON_7),
482 LANGINFO(ABMON_8),
483 LANGINFO(ABMON_9),
484 LANGINFO(ABMON_10),
485 LANGINFO(ABMON_11),
486 LANGINFO(ABMON_12),
487
488#ifdef RADIXCHAR
489 /* The following are not available with glibc 2.0 */
490 LANGINFO(RADIXCHAR),
491 LANGINFO(THOUSEP),
492 /* YESSTR and NOSTR are deprecated in glibc, since they are
493 a special case of message translation, which should be rather
494 done using gettext. So we don't expose it to Python in the
495 first place.
496 LANGINFO(YESSTR),
497 LANGINFO(NOSTR),
498 */
499 LANGINFO(CRNCYSTR),
500#endif
501
502 LANGINFO(D_T_FMT),
503 LANGINFO(D_FMT),
504 LANGINFO(T_FMT),
505 LANGINFO(AM_STR),
506 LANGINFO(PM_STR),
507
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000508 /* The following constants are available only with XPG4, but...
509 AIX 3.2. only has CODESET.
510 OpenBSD doesn't have CODESET but has T_FMT_AMPM, and doesn't have
511 a few of the others.
512 Solution: ifdef-test them all. */
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000513#ifdef CODESET
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000514 LANGINFO(CODESET),
Martin v. Löwis496f9e42002-03-27 12:15:57 +0000515#endif
516#ifdef T_FMT_AMPM
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000517 LANGINFO(T_FMT_AMPM),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000518#endif
519#ifdef ERA
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000520 LANGINFO(ERA),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000521#endif
522#ifdef ERA_D_FMT
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000523 LANGINFO(ERA_D_FMT),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000524#endif
525#ifdef ERA_D_T_FMT
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000526 LANGINFO(ERA_D_T_FMT),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000527#endif
528#ifdef ERA_T_FMT
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000529 LANGINFO(ERA_T_FMT),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000530#endif
531#ifdef ALT_DIGITS
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000532 LANGINFO(ALT_DIGITS),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000533#endif
534#ifdef YESEXPR
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000535 LANGINFO(YESEXPR),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000536#endif
537#ifdef NOEXPR
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000538 LANGINFO(NOEXPR),
539#endif
540#ifdef _DATE_FMT
541 /* This is not available in all glibc versions that have CODESET. */
542 LANGINFO(_DATE_FMT),
543#endif
544 {0, 0}
545};
546
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000547PyDoc_STRVAR(nl_langinfo__doc__,
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000548"nl_langinfo(key) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000549"Return the value for the locale information associated with key.");
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000550
551static PyObject*
552PyLocale_nl_langinfo(PyObject* self, PyObject* args)
553{
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000554 int item, i;
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000555 if (!PyArg_ParseTuple(args, "i:nl_langinfo", &item))
556 return NULL;
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000557 /* Check whether this is a supported constant. GNU libc sometimes
558 returns numeric values in the char* return value, which would
Neal Norwitz7f9d29c2007-08-26 07:21:45 +0000559 crash PyUnicode_FromString. */
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000560 for (i = 0; langinfo_constants[i].name; i++)
Hye-Shik Changc3a87b82004-03-21 19:34:30 +0000561 if (langinfo_constants[i].value == item) {
562 /* Check NULL as a workaround for GNU libc's returning NULL
563 instead of an empty string for nl_langinfo(ERA). */
564 const char *result = nl_langinfo(item);
Neal Norwitz3d7a90d2007-10-27 05:40:06 +0000565 result = result != NULL ? result : "";
Victor Stinnera9c895d2012-02-14 02:33:38 +0100566 return PyUnicode_DecodeLocale(result, NULL);
Hye-Shik Changc3a87b82004-03-21 19:34:30 +0000567 }
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000568 PyErr_SetString(PyExc_ValueError, "unsupported langinfo constant");
569 return NULL;
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000570}
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000571#endif /* HAVE_LANGINFO_H */
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000572
573#ifdef HAVE_LIBINTL_H
574
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000575PyDoc_STRVAR(gettext__doc__,
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000576"gettext(msg) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000577"Return translation of msg.");
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000578
579static PyObject*
580PyIntl_gettext(PyObject* self, PyObject *args)
581{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000582 char *in;
583 if (!PyArg_ParseTuple(args, "s", &in))
584 return 0;
Victor Stinnera9c895d2012-02-14 02:33:38 +0100585 return PyUnicode_DecodeLocale(gettext(in), NULL);
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000586}
587
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000588PyDoc_STRVAR(dgettext__doc__,
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000589"dgettext(domain, msg) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000590"Return translation of msg in domain.");
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000591
592static PyObject*
593PyIntl_dgettext(PyObject* self, PyObject *args)
594{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000595 char *domain, *in;
596 if (!PyArg_ParseTuple(args, "zs", &domain, &in))
597 return 0;
Victor Stinnera9c895d2012-02-14 02:33:38 +0100598 return PyUnicode_DecodeLocale(dgettext(domain, in), NULL);
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000599}
600
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000601PyDoc_STRVAR(dcgettext__doc__,
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000602"dcgettext(domain, msg, category) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000603"Return translation of msg in domain and category.");
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000604
605static PyObject*
606PyIntl_dcgettext(PyObject *self, PyObject *args)
607{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000608 char *domain, *msgid;
609 int category;
610 if (!PyArg_ParseTuple(args, "zsi", &domain, &msgid, &category))
611 return 0;
Victor Stinnera9c895d2012-02-14 02:33:38 +0100612 return PyUnicode_DecodeLocale(dcgettext(domain,msgid,category), NULL);
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000613}
614
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000615PyDoc_STRVAR(textdomain__doc__,
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000616"textdomain(domain) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000617"Set the C library's textdmain to domain, returning the new domain.");
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000618
619static PyObject*
620PyIntl_textdomain(PyObject* self, PyObject* args)
621{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000622 char *domain;
623 if (!PyArg_ParseTuple(args, "z", &domain))
624 return 0;
625 domain = textdomain(domain);
626 if (!domain) {
627 PyErr_SetFromErrno(PyExc_OSError);
628 return NULL;
629 }
Victor Stinnera9c895d2012-02-14 02:33:38 +0100630 return PyUnicode_DecodeLocale(domain, NULL);
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000631}
632
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000633PyDoc_STRVAR(bindtextdomain__doc__,
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000634"bindtextdomain(domain, dir) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000635"Bind the C library's domain to dir.");
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000636
637static PyObject*
Hai Shia1581682020-03-12 00:46:06 +0800638PyIntl_bindtextdomain(PyObject* self, PyObject*args)
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000639{
Serhiy Storchaka8f87eef2020-04-12 14:58:27 +0300640 const char *domain, *dirname, *current_dirname;
Victor Stinner9e19ca42010-06-11 22:09:51 +0000641 PyObject *dirname_obj, *dirname_bytes = NULL, *result;
Hai Shia1581682020-03-12 00:46:06 +0800642
Victor Stinner9e19ca42010-06-11 22:09:51 +0000643 if (!PyArg_ParseTuple(args, "sO", &domain, &dirname_obj))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000644 return 0;
645 if (!strlen(domain)) {
Hai Shia1581682020-03-12 00:46:06 +0800646 PyErr_SetString(get_locale_state(self)->Error,
647 "domain must be a non-empty string");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000648 return 0;
649 }
Victor Stinner9e19ca42010-06-11 22:09:51 +0000650 if (dirname_obj != Py_None) {
651 if (!PyUnicode_FSConverter(dirname_obj, &dirname_bytes))
652 return NULL;
653 dirname = PyBytes_AsString(dirname_bytes);
654 } else {
655 dirname_bytes = NULL;
656 dirname = NULL;
657 }
658 current_dirname = bindtextdomain(domain, dirname);
659 if (current_dirname == NULL) {
660 Py_XDECREF(dirname_bytes);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000661 PyErr_SetFromErrno(PyExc_OSError);
662 return NULL;
663 }
Victor Stinnera9c895d2012-02-14 02:33:38 +0100664 result = PyUnicode_DecodeLocale(current_dirname, NULL);
Victor Stinner9e19ca42010-06-11 22:09:51 +0000665 Py_XDECREF(dirname_bytes);
666 return result;
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000667}
668
Gustavo Niemeyer7bd33c52004-07-22 18:44:01 +0000669#ifdef HAVE_BIND_TEXTDOMAIN_CODESET
670PyDoc_STRVAR(bind_textdomain_codeset__doc__,
671"bind_textdomain_codeset(domain, codeset) -> string\n"
672"Bind the C library's domain to codeset.");
673
674static PyObject*
675PyIntl_bind_textdomain_codeset(PyObject* self,PyObject*args)
676{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000677 char *domain,*codeset;
678 if (!PyArg_ParseTuple(args, "sz", &domain, &codeset))
679 return NULL;
680 codeset = bind_textdomain_codeset(domain, codeset);
Victor Stinner7ed7aea2018-01-15 10:45:49 +0100681 if (codeset) {
Victor Stinnera9c895d2012-02-14 02:33:38 +0100682 return PyUnicode_DecodeLocale(codeset, NULL);
Victor Stinner7ed7aea2018-01-15 10:45:49 +0100683 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000684 Py_RETURN_NONE;
Gustavo Niemeyer7bd33c52004-07-22 18:44:01 +0000685}
686#endif
687
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000688#endif
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000689
Guido van Rossum220ecc81997-11-18 21:03:39 +0000690static struct PyMethodDef PyLocale_Methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000691 {"setlocale", (PyCFunction) PyLocale_setlocale,
Andrew M. Kuchlinge365fb82000-08-03 02:06:16 +0000692 METH_VARARGS, setlocale__doc__},
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +0530693 {"localeconv", PyLocale_localeconv, METH_NOARGS, localeconv__doc__},
Martin v. Löwis92fab752008-03-08 10:40:41 +0000694#ifdef HAVE_WCSCOLL
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000695 {"strcoll", (PyCFunction) PyLocale_strcoll,
Andrew M. Kuchlinge365fb82000-08-03 02:06:16 +0000696 METH_VARARGS, strcoll__doc__},
Martin v. Löwis92fab752008-03-08 10:40:41 +0000697#endif
698#ifdef HAVE_WCSXFRM
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000699 {"strxfrm", (PyCFunction) PyLocale_strxfrm,
Andrew M. Kuchlinge365fb82000-08-03 02:06:16 +0000700 METH_VARARGS, strxfrm__doc__},
Martin v. Löwis92fab752008-03-08 10:40:41 +0000701#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000702#if defined(MS_WINDOWS)
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +0530703 {"_getdefaultlocale", PyLocale_getdefaultlocale, METH_NOARGS},
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000704#endif
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000705#ifdef HAVE_LANGINFO_H
706 {"nl_langinfo", (PyCFunction) PyLocale_nl_langinfo,
707 METH_VARARGS, nl_langinfo__doc__},
708#endif
Martin v. Löwisc6a7d7e2002-05-02 12:16:29 +0000709#ifdef HAVE_LIBINTL_H
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000710 {"gettext",(PyCFunction)PyIntl_gettext,METH_VARARGS,
711 gettext__doc__},
712 {"dgettext",(PyCFunction)PyIntl_dgettext,METH_VARARGS,
713 dgettext__doc__},
714 {"dcgettext",(PyCFunction)PyIntl_dcgettext,METH_VARARGS,
715 dcgettext__doc__},
716 {"textdomain",(PyCFunction)PyIntl_textdomain,METH_VARARGS,
717 textdomain__doc__},
718 {"bindtextdomain",(PyCFunction)PyIntl_bindtextdomain,METH_VARARGS,
719 bindtextdomain__doc__},
Gustavo Niemeyer7bd33c52004-07-22 18:44:01 +0000720#ifdef HAVE_BIND_TEXTDOMAIN_CODESET
721 {"bind_textdomain_codeset",(PyCFunction)PyIntl_bind_textdomain_codeset,
722 METH_VARARGS, bind_textdomain_codeset__doc__},
723#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000724#endif
Guido van Rossum220ecc81997-11-18 21:03:39 +0000725 {NULL, NULL}
726};
727
Hai Shia1581682020-03-12 00:46:06 +0800728static int
Hai Shi7a6f3bc2020-04-03 02:00:47 +0800729_locale_exec(PyObject *module)
Guido van Rossum220ecc81997-11-18 21:03:39 +0000730{
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000731#ifdef HAVE_LANGINFO_H
732 int i;
733#endif
Hai Shi7a6f3bc2020-04-03 02:00:47 +0800734#define ADD_INT(module, value) \
735 do { \
736 if (PyModule_AddIntConstant(module, #value, value) < 0) { \
737 return -1; \
738 } \
739 } while (0)
Guido van Rossum220ecc81997-11-18 21:03:39 +0000740
Hai Shi7a6f3bc2020-04-03 02:00:47 +0800741 ADD_INT(module, LC_CTYPE);
742 ADD_INT(module, LC_TIME);
743 ADD_INT(module, LC_COLLATE);
744 ADD_INT(module, LC_MONETARY);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000745
Guido van Rossum8d9c2e31997-12-09 19:35:11 +0000746#ifdef LC_MESSAGES
Hai Shi7a6f3bc2020-04-03 02:00:47 +0800747 ADD_INT(module, LC_MESSAGES);
Guido van Rossum8d9c2e31997-12-09 19:35:11 +0000748#endif /* LC_MESSAGES */
Guido van Rossum220ecc81997-11-18 21:03:39 +0000749
Hai Shi7a6f3bc2020-04-03 02:00:47 +0800750 ADD_INT(module, LC_NUMERIC);
751 ADD_INT(module, LC_ALL);
752 ADD_INT(module, CHAR_MAX);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000753
Hai Shi7a6f3bc2020-04-03 02:00:47 +0800754 _locale_state *state = get_locale_state(module);
Hai Shia1581682020-03-12 00:46:06 +0800755 state->Error = PyErr_NewException("locale.Error", NULL, NULL);
756 if (state->Error == NULL) {
757 return -1;
Christian Heimesff4fddd2016-09-09 00:24:12 +0200758 }
Hai Shi7a6f3bc2020-04-03 02:00:47 +0800759 Py_INCREF(get_locale_state(module)->Error);
760 if (PyModule_AddObject(module, "Error", get_locale_state(module)->Error) < 0) {
761 Py_DECREF(get_locale_state(module)->Error);
Hai Shia1581682020-03-12 00:46:06 +0800762 return -1;
763 }
Guido van Rossum220ecc81997-11-18 21:03:39 +0000764
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000765#ifdef HAVE_LANGINFO_H
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000766 for (i = 0; langinfo_constants[i].name; i++) {
Hai Shi7a6f3bc2020-04-03 02:00:47 +0800767 if (PyModule_AddIntConstant(module,
768 langinfo_constants[i].name,
769 langinfo_constants[i].value) < 0) {
770 return -1;
771 }
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000772 }
Martin v. Löwisf95dd0a2001-08-15 17:14:33 +0000773#endif
Christian Heimesff4fddd2016-09-09 00:24:12 +0200774
775 if (PyErr_Occurred()) {
Hai Shia1581682020-03-12 00:46:06 +0800776 return -1;
Christian Heimesff4fddd2016-09-09 00:24:12 +0200777 }
Hai Shia1581682020-03-12 00:46:06 +0800778 return 0;
Hai Shi7a6f3bc2020-04-03 02:00:47 +0800779
780#undef ADD_INT
Hai Shia1581682020-03-12 00:46:06 +0800781}
782
783static struct PyModuleDef_Slot _locale_slots[] = {
784 {Py_mod_exec, _locale_exec},
785 {0, NULL}
786};
787
788static int
Hai Shi13397ee2020-03-20 01:11:33 +0800789locale_traverse(PyObject *module, visitproc visit, void *arg)
Hai Shia1581682020-03-12 00:46:06 +0800790{
Hai Shi13397ee2020-03-20 01:11:33 +0800791 _locale_state *state = get_locale_state(module);
Victor Stinner5b1ef202020-03-17 18:09:46 +0100792 Py_VISIT(state->Error);
Hai Shia1581682020-03-12 00:46:06 +0800793 return 0;
794}
795
796static int
Hai Shi13397ee2020-03-20 01:11:33 +0800797locale_clear(PyObject *module)
Hai Shia1581682020-03-12 00:46:06 +0800798{
Hai Shi13397ee2020-03-20 01:11:33 +0800799 _locale_state *state = get_locale_state(module);
Victor Stinner5b1ef202020-03-17 18:09:46 +0100800 Py_CLEAR(state->Error);
Hai Shia1581682020-03-12 00:46:06 +0800801 return 0;
802}
803
804static void
Hai Shi13397ee2020-03-20 01:11:33 +0800805locale_free(PyObject *module)
Hai Shia1581682020-03-12 00:46:06 +0800806{
Hai Shi13397ee2020-03-20 01:11:33 +0800807 locale_clear(module);
Hai Shia1581682020-03-12 00:46:06 +0800808}
809
810static struct PyModuleDef _localemodule = {
811 PyModuleDef_HEAD_INIT,
812 "_locale",
813 locale__doc__,
814 sizeof(_locale_state),
815 PyLocale_Methods,
816 _locale_slots,
817 locale_traverse,
818 locale_clear,
819 (freefunc)locale_free,
820};
821
822PyMODINIT_FUNC
823PyInit__locale(void)
824{
825 return PyModuleDef_Init(&_localemodule);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000826}
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000827
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000828/*
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000829Local variables:
830c-basic-offset: 4
831indent-tabs-mode: nil
832End:
833*/