blob: 564f5598edcc6690f16ed12ac4b34d932c8b0067 [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{
TIGirardif2312032020-10-20 08:39:52 -0300158#ifndef MS_WINDOWS
Victor Stinner02e6bf72018-11-20 16:20:16 +0100159 int change_locale;
160 change_locale = (!locale_is_ascii(lc->int_curr_symbol)
161 || !locale_is_ascii(lc->currency_symbol)
162 || !locale_is_ascii(lc->mon_decimal_point)
163 || !locale_is_ascii(lc->mon_thousands_sep));
164
165 /* Keep a copy of the LC_CTYPE locale */
166 char *oldloc = NULL, *loc = NULL;
167 if (change_locale) {
168 oldloc = setlocale(LC_CTYPE, NULL);
169 if (!oldloc) {
170 PyErr_SetString(PyExc_RuntimeWarning,
171 "failed to get LC_CTYPE locale");
172 return -1;
173 }
174
175 oldloc = _PyMem_Strdup(oldloc);
176 if (!oldloc) {
177 PyErr_NoMemory();
178 return -1;
179 }
180
181 loc = setlocale(LC_MONETARY, NULL);
182 if (loc != NULL && strcmp(loc, oldloc) == 0) {
183 loc = NULL;
184 }
185
186 if (loc != NULL) {
187 /* Only set the locale temporarily the LC_CTYPE locale
188 to the LC_MONETARY locale if the two locales are different and
189 at least one string is non-ASCII. */
190 setlocale(LC_CTYPE, loc);
191 }
192 }
193
TIGirardif2312032020-10-20 08:39:52 -0300194#define GET_LOCALE_STRING(ATTR) PyUnicode_DecodeLocale(lc->ATTR, NULL)
195#else /* MS_WINDOWS */
196/* Use _W_* fields of Windows struct lconv */
197#define GET_LOCALE_STRING(ATTR) PyUnicode_FromWideChar(lc->_W_ ## ATTR, -1)
198#endif /* MS_WINDOWS */
199
Victor Stinner02e6bf72018-11-20 16:20:16 +0100200 int res = -1;
201
202#define RESULT_STRING(ATTR) \
203 do { \
204 PyObject *obj; \
TIGirardif2312032020-10-20 08:39:52 -0300205 obj = GET_LOCALE_STRING(ATTR); \
Victor Stinner02e6bf72018-11-20 16:20:16 +0100206 if (obj == NULL) { \
207 goto done; \
208 } \
209 if (PyDict_SetItemString(dict, Py_STRINGIFY(ATTR), obj) < 0) { \
210 Py_DECREF(obj); \
211 goto done; \
212 } \
213 Py_DECREF(obj); \
214 } while (0)
215
216 RESULT_STRING(int_curr_symbol);
217 RESULT_STRING(currency_symbol);
218 RESULT_STRING(mon_decimal_point);
219 RESULT_STRING(mon_thousands_sep);
220#undef RESULT_STRING
TIGirardif2312032020-10-20 08:39:52 -0300221#undef GET_LOCALE_STRING
Victor Stinner02e6bf72018-11-20 16:20:16 +0100222
223 res = 0;
224
225done:
TIGirardif2312032020-10-20 08:39:52 -0300226#ifndef MS_WINDOWS
Victor Stinner02e6bf72018-11-20 16:20:16 +0100227 if (loc != NULL) {
228 setlocale(LC_CTYPE, oldloc);
229 }
230 PyMem_Free(oldloc);
TIGirardif2312032020-10-20 08:39:52 -0300231#endif
Victor Stinner02e6bf72018-11-20 16:20:16 +0100232 return res;
233}
234
Zackery Spytzbbceef62020-07-15 03:07:34 -0600235/*[clinic input]
236_locale.localeconv
Guido van Rossum220ecc81997-11-18 21:03:39 +0000237
Zackery Spytzbbceef62020-07-15 03:07:34 -0600238Returns numeric and monetary locale-specific parameters.
239[clinic start generated code]*/
240
241static PyObject *
242_locale_localeconv_impl(PyObject *module)
243/*[clinic end generated code: output=43a54515e0a2aef5 input=f1132d15accf4444]*/
Guido van Rossum220ecc81997-11-18 21:03:39 +0000244{
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000245 PyObject* result;
Victor Stinner02e6bf72018-11-20 16:20:16 +0100246 struct lconv *lc;
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000247 PyObject *x;
248
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000249 result = PyDict_New();
Victor Stinnercb064fc2018-01-15 15:58:02 +0100250 if (!result) {
Fredrik Lundh89610a42000-07-08 20:07:24 +0000251 return NULL;
Victor Stinnercb064fc2018-01-15 15:58:02 +0100252 }
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000253
254 /* if LC_NUMERIC is different in the C library, use saved value */
Victor Stinner02e6bf72018-11-20 16:20:16 +0100255 lc = localeconv();
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000256
257 /* hopefully, the localeconv result survives the C library calls
258 involved herein */
259
Victor Stinnerd594f242013-07-17 00:55:57 +0200260#define RESULT(key, obj)\
261 do { \
262 if (obj == NULL) \
263 goto failed; \
Victor Stinnerf38a5c22013-10-29 19:28:20 +0100264 if (PyDict_SetItemString(result, key, obj) < 0) { \
265 Py_DECREF(obj); \
Victor Stinnerd594f242013-07-17 00:55:57 +0200266 goto failed; \
Victor Stinnerf38a5c22013-10-29 19:28:20 +0100267 } \
Victor Stinnerd594f242013-07-17 00:55:57 +0200268 Py_DECREF(obj); \
269 } while (0)
270
TIGirardif2312032020-10-20 08:39:52 -0300271#ifdef MS_WINDOWS
272/* Use _W_* fields of Windows struct lconv */
273#define GET_LOCALE_STRING(ATTR) PyUnicode_FromWideChar(lc->_W_ ## ATTR, -1)
274#else
275#define GET_LOCALE_STRING(ATTR) PyUnicode_DecodeLocale(lc->ATTR, NULL)
276#endif
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000277#define RESULT_STRING(s)\
Victor Stinnerd594f242013-07-17 00:55:57 +0200278 do { \
TIGirardif2312032020-10-20 08:39:52 -0300279 x = GET_LOCALE_STRING(s); \
Victor Stinnerd594f242013-07-17 00:55:57 +0200280 RESULT(#s, x); \
281 } while (0)
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000282
283#define RESULT_INT(i)\
Victor Stinnerd594f242013-07-17 00:55:57 +0200284 do { \
Victor Stinner02e6bf72018-11-20 16:20:16 +0100285 x = PyLong_FromLong(lc->i); \
Victor Stinnerd594f242013-07-17 00:55:57 +0200286 RESULT(#i, x); \
287 } while (0)
Guido van Rossum220ecc81997-11-18 21:03:39 +0000288
Victor Stinner02e6bf72018-11-20 16:20:16 +0100289 /* Monetary information: LC_MONETARY encoding */
290 if (locale_decode_monetary(result, lc) < 0) {
291 goto failed;
292 }
293 x = copy_grouping(lc->mon_grouping);
Victor Stinnerd594f242013-07-17 00:55:57 +0200294 RESULT("mon_grouping", x);
295
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000296 RESULT_STRING(positive_sign);
297 RESULT_STRING(negative_sign);
298 RESULT_INT(int_frac_digits);
299 RESULT_INT(frac_digits);
300 RESULT_INT(p_cs_precedes);
301 RESULT_INT(p_sep_by_space);
302 RESULT_INT(n_cs_precedes);
303 RESULT_INT(n_sep_by_space);
304 RESULT_INT(p_sign_posn);
305 RESULT_INT(n_sign_posn);
Victor Stinnercb064fc2018-01-15 15:58:02 +0100306
Victor Stinner02e6bf72018-11-20 16:20:16 +0100307 /* Numeric information: LC_NUMERIC encoding */
TIGirardif2312032020-10-20 08:39:52 -0300308 PyObject *decimal_point = NULL, *thousands_sep = NULL;
Victor Stinner02e6bf72018-11-20 16:20:16 +0100309 if (_Py_GetLocaleconvNumeric(lc, &decimal_point, &thousands_sep) < 0) {
TIGirardif2312032020-10-20 08:39:52 -0300310 Py_XDECREF(decimal_point);
311 Py_XDECREF(thousands_sep);
Victor Stinnercb064fc2018-01-15 15:58:02 +0100312 goto failed;
313 }
314
315 if (PyDict_SetItemString(result, "decimal_point", decimal_point) < 0) {
316 Py_DECREF(decimal_point);
317 Py_DECREF(thousands_sep);
318 goto failed;
319 }
320 Py_DECREF(decimal_point);
321
322 if (PyDict_SetItemString(result, "thousands_sep", thousands_sep) < 0) {
323 Py_DECREF(thousands_sep);
324 goto failed;
325 }
326 Py_DECREF(thousands_sep);
327
Victor Stinner02e6bf72018-11-20 16:20:16 +0100328 x = copy_grouping(lc->grouping);
Victor Stinnercb064fc2018-01-15 15:58:02 +0100329 RESULT("grouping", x);
330
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000331 return result;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000332
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000333 failed:
Victor Stinnercb064fc2018-01-15 15:58:02 +0100334 Py_DECREF(result);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000335 return NULL;
Victor Stinner02e6bf72018-11-20 16:20:16 +0100336
337#undef RESULT
338#undef RESULT_STRING
339#undef RESULT_INT
TIGirardif2312032020-10-20 08:39:52 -0300340#undef GET_LOCALE_STRING
Guido van Rossum220ecc81997-11-18 21:03:39 +0000341}
342
Martin v. Löwis92fab752008-03-08 10:40:41 +0000343#if defined(HAVE_WCSCOLL)
Guido van Rossum220ecc81997-11-18 21:03:39 +0000344
Zackery Spytzbbceef62020-07-15 03:07:34 -0600345/*[clinic input]
346_locale.strcoll
347
348 os1: unicode
349 os2: unicode
350 /
351
352Compares two strings according to the locale.
353[clinic start generated code]*/
354
355static PyObject *
356_locale_strcoll_impl(PyObject *module, PyObject *os1, PyObject *os2)
357/*[clinic end generated code: output=82ddc6d62c76d618 input=693cd02bcbf38dd8]*/
Guido van Rossum220ecc81997-11-18 21:03:39 +0000358{
Zackery Spytzbbceef62020-07-15 03:07:34 -0600359 PyObject *result = NULL;
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000360 wchar_t *ws1 = NULL, *ws2 = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000361
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000362 /* Convert the unicode strings to wchar[]. */
Victor Stinnerbeb4135b2010-10-07 01:02:42 +0000363 ws1 = PyUnicode_AsWideCharString(os1, NULL);
Victor Stinner449057f2010-09-29 10:30:43 +0000364 if (ws1 == NULL)
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000365 goto done;
Victor Stinnerbeb4135b2010-10-07 01:02:42 +0000366 ws2 = PyUnicode_AsWideCharString(os2, NULL);
Victor Stinner449057f2010-09-29 10:30:43 +0000367 if (ws2 == NULL)
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000368 goto done;
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000369 /* Collate the strings. */
Christian Heimes217cfd12007-12-02 14:31:20 +0000370 result = PyLong_FromLong(wcscoll(ws1, ws2));
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000371 done:
372 /* Deallocate everything. */
Victor Stinner00d7abd2020-12-01 09:56:42 +0100373 if (ws1) PyMem_Free(ws1);
374 if (ws2) PyMem_Free(ws2);
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000375 return result;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000376}
Martin v. Löwis92fab752008-03-08 10:40:41 +0000377#endif
Guido van Rossum220ecc81997-11-18 21:03:39 +0000378
Martin v. Löwis92fab752008-03-08 10:40:41 +0000379#ifdef HAVE_WCSXFRM
Guido van Rossum220ecc81997-11-18 21:03:39 +0000380
Zackery Spytzbbceef62020-07-15 03:07:34 -0600381/*[clinic input]
382_locale.strxfrm
383
384 string as str: unicode
385 /
386
387Return a string that can be used as a key for locale-aware comparisons.
388[clinic start generated code]*/
389
390static PyObject *
391_locale_strxfrm_impl(PyObject *module, PyObject *str)
392/*[clinic end generated code: output=3081866ebffc01af input=1378bbe6a88b4780]*/
Guido van Rossum220ecc81997-11-18 21:03:39 +0000393{
Victor Stinner63649272011-09-29 23:32:06 +0200394 Py_ssize_t n1;
395 wchar_t *s = NULL, *buf = NULL;
396 size_t n2;
Martin v. Löwis92fab752008-03-08 10:40:41 +0000397 PyObject *result = NULL;
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000398
Victor Stinner63649272011-09-29 23:32:06 +0200399 s = PyUnicode_AsWideCharString(str, &n1);
400 if (s == NULL)
401 goto exit;
Serhiy Storchakaf7eae0a2017-06-28 08:30:06 +0300402 if (wcslen(s) != (size_t)n1) {
403 PyErr_SetString(PyExc_ValueError,
404 "embedded null character");
405 goto exit;
406 }
Martin v. Löwis92fab752008-03-08 10:40:41 +0000407
408 /* assume no change in size, first */
Victor Stinner63649272011-09-29 23:32:06 +0200409 n1 = n1 + 1;
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +0200410 buf = PyMem_New(wchar_t, n1);
Martin v. Löwis92fab752008-03-08 10:40:41 +0000411 if (!buf) {
412 PyErr_NoMemory();
413 goto exit;
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000414 }
Serhiy Storchakabe487a62017-03-06 21:21:41 +0200415 errno = 0;
Martin v. Löwis92fab752008-03-08 10:40:41 +0000416 n2 = wcsxfrm(buf, s, n1);
Benjamin Petersonad4a0cc2017-03-07 22:24:44 -0800417 if (errno && errno != ERANGE) {
Serhiy Storchakabe487a62017-03-06 21:21:41 +0200418 PyErr_SetFromErrno(PyExc_OSError);
419 goto exit;
420 }
Victor Stinner2c5d3cb2011-10-11 22:35:52 +0200421 if (n2 >= (size_t)n1) {
Martin v. Löwis92fab752008-03-08 10:40:41 +0000422 /* more space needed */
Kristjan Valur Jonsson85634d72012-05-31 09:37:31 +0000423 wchar_t * new_buf = PyMem_Realloc(buf, (n2+1)*sizeof(wchar_t));
424 if (!new_buf) {
Martin v. Löwis92fab752008-03-08 10:40:41 +0000425 PyErr_NoMemory();
426 goto exit;
427 }
Kristjan Valur Jonsson85634d72012-05-31 09:37:31 +0000428 buf = new_buf;
Serhiy Storchakabe487a62017-03-06 21:21:41 +0200429 errno = 0;
Martin v. Löwisdb1c3992009-05-23 10:38:26 +0000430 n2 = wcsxfrm(buf, s, n2+1);
Serhiy Storchakabe487a62017-03-06 21:21:41 +0200431 if (errno) {
432 PyErr_SetFromErrno(PyExc_OSError);
433 goto exit;
434 }
Martin v. Löwis92fab752008-03-08 10:40:41 +0000435 }
436 result = PyUnicode_FromWideChar(buf, n2);
Victor Stinner63649272011-09-29 23:32:06 +0200437exit:
Serhiy Storchakabe487a62017-03-06 21:21:41 +0200438 PyMem_Free(buf);
439 PyMem_Free(s);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000440 return result;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000441}
Martin v. Löwis92fab752008-03-08 10:40:41 +0000442#endif
Guido van Rossum220ecc81997-11-18 21:03:39 +0000443
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000444#if defined(MS_WINDOWS)
Zackery Spytzbbceef62020-07-15 03:07:34 -0600445
446/*[clinic input]
447_locale._getdefaultlocale
448
449[clinic start generated code]*/
450
451static PyObject *
452_locale__getdefaultlocale_impl(PyObject *module)
453/*[clinic end generated code: output=e6254088579534c2 input=003ea41acd17f7c7]*/
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000454{
Victor Stinner9e4994d2018-08-28 23:26:33 +0200455 char encoding[20];
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000456 char locale[100];
457
Serhiy Storchakad53fe5f2019-03-13 22:59:55 +0200458 PyOS_snprintf(encoding, sizeof(encoding), "cp%u", GetACP());
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000459
460 if (GetLocaleInfo(LOCALE_USER_DEFAULT,
461 LOCALE_SISO639LANGNAME,
462 locale, sizeof(locale))) {
Martin v. Löwis18e16552006-02-15 17:27:45 +0000463 Py_ssize_t i = strlen(locale);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000464 locale[i++] = '_';
465 if (GetLocaleInfo(LOCALE_USER_DEFAULT,
466 LOCALE_SISO3166CTRYNAME,
Martin v. Löwis18e16552006-02-15 17:27:45 +0000467 locale+i, (int)(sizeof(locale)-i)))
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000468 return Py_BuildValue("ss", locale, encoding);
469 }
470
471 /* If we end up here, this windows version didn't know about
472 ISO639/ISO3166 names (it's probably Windows 95). Return the
473 Windows language identifier instead (a hexadecimal number) */
474
475 locale[0] = '0';
476 locale[1] = 'x';
477 if (GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_IDEFAULTLANGUAGE,
478 locale+2, sizeof(locale)-2)) {
479 return Py_BuildValue("ss", locale, encoding);
480 }
481
482 /* cannot determine the language code (very unlikely) */
483 Py_INCREF(Py_None);
484 return Py_BuildValue("Os", Py_None, encoding);
485}
486#endif
487
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000488#ifdef HAVE_LANGINFO_H
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000489#define LANGINFO(X) {#X, X}
Martin v. Löwis59683e82008-06-13 07:50:45 +0000490static struct langinfo_constant{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000491 char* name;
492 int value;
493} langinfo_constants[] =
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000494{
495 /* These constants should exist on any langinfo implementation */
496 LANGINFO(DAY_1),
497 LANGINFO(DAY_2),
498 LANGINFO(DAY_3),
499 LANGINFO(DAY_4),
500 LANGINFO(DAY_5),
501 LANGINFO(DAY_6),
502 LANGINFO(DAY_7),
503
504 LANGINFO(ABDAY_1),
505 LANGINFO(ABDAY_2),
506 LANGINFO(ABDAY_3),
507 LANGINFO(ABDAY_4),
508 LANGINFO(ABDAY_5),
509 LANGINFO(ABDAY_6),
510 LANGINFO(ABDAY_7),
511
512 LANGINFO(MON_1),
513 LANGINFO(MON_2),
514 LANGINFO(MON_3),
515 LANGINFO(MON_4),
516 LANGINFO(MON_5),
517 LANGINFO(MON_6),
518 LANGINFO(MON_7),
519 LANGINFO(MON_8),
520 LANGINFO(MON_9),
521 LANGINFO(MON_10),
522 LANGINFO(MON_11),
523 LANGINFO(MON_12),
524
525 LANGINFO(ABMON_1),
526 LANGINFO(ABMON_2),
527 LANGINFO(ABMON_3),
528 LANGINFO(ABMON_4),
529 LANGINFO(ABMON_5),
530 LANGINFO(ABMON_6),
531 LANGINFO(ABMON_7),
532 LANGINFO(ABMON_8),
533 LANGINFO(ABMON_9),
534 LANGINFO(ABMON_10),
535 LANGINFO(ABMON_11),
536 LANGINFO(ABMON_12),
537
538#ifdef RADIXCHAR
539 /* The following are not available with glibc 2.0 */
540 LANGINFO(RADIXCHAR),
541 LANGINFO(THOUSEP),
542 /* YESSTR and NOSTR are deprecated in glibc, since they are
543 a special case of message translation, which should be rather
544 done using gettext. So we don't expose it to Python in the
545 first place.
546 LANGINFO(YESSTR),
547 LANGINFO(NOSTR),
548 */
549 LANGINFO(CRNCYSTR),
550#endif
551
552 LANGINFO(D_T_FMT),
553 LANGINFO(D_FMT),
554 LANGINFO(T_FMT),
555 LANGINFO(AM_STR),
556 LANGINFO(PM_STR),
557
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000558 /* The following constants are available only with XPG4, but...
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000559 OpenBSD doesn't have CODESET but has T_FMT_AMPM, and doesn't have
560 a few of the others.
561 Solution: ifdef-test them all. */
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000562#ifdef CODESET
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000563 LANGINFO(CODESET),
Martin v. Löwis496f9e42002-03-27 12:15:57 +0000564#endif
565#ifdef T_FMT_AMPM
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000566 LANGINFO(T_FMT_AMPM),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000567#endif
568#ifdef ERA
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000569 LANGINFO(ERA),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000570#endif
571#ifdef ERA_D_FMT
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000572 LANGINFO(ERA_D_FMT),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000573#endif
574#ifdef ERA_D_T_FMT
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000575 LANGINFO(ERA_D_T_FMT),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000576#endif
577#ifdef ERA_T_FMT
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000578 LANGINFO(ERA_T_FMT),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000579#endif
580#ifdef ALT_DIGITS
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000581 LANGINFO(ALT_DIGITS),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000582#endif
583#ifdef YESEXPR
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000584 LANGINFO(YESEXPR),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000585#endif
586#ifdef NOEXPR
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000587 LANGINFO(NOEXPR),
588#endif
589#ifdef _DATE_FMT
590 /* This is not available in all glibc versions that have CODESET. */
591 LANGINFO(_DATE_FMT),
592#endif
593 {0, 0}
594};
595
Zackery Spytzbbceef62020-07-15 03:07:34 -0600596/*[clinic input]
597_locale.nl_langinfo
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000598
Zackery Spytzbbceef62020-07-15 03:07:34 -0600599 key as item: int
600 /
601
602Return the value for the locale information associated with key.
603[clinic start generated code]*/
604
605static PyObject *
606_locale_nl_langinfo_impl(PyObject *module, int item)
607/*[clinic end generated code: output=6aea457b47e077a3 input=00798143eecfeddc]*/
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000608{
Zackery Spytzbbceef62020-07-15 03:07:34 -0600609 int i;
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000610 /* Check whether this is a supported constant. GNU libc sometimes
611 returns numeric values in the char* return value, which would
Neal Norwitz7f9d29c2007-08-26 07:21:45 +0000612 crash PyUnicode_FromString. */
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000613 for (i = 0; langinfo_constants[i].name; i++)
Hye-Shik Changc3a87b82004-03-21 19:34:30 +0000614 if (langinfo_constants[i].value == item) {
615 /* Check NULL as a workaround for GNU libc's returning NULL
616 instead of an empty string for nl_langinfo(ERA). */
617 const char *result = nl_langinfo(item);
Neal Norwitz3d7a90d2007-10-27 05:40:06 +0000618 result = result != NULL ? result : "";
Victor Stinnera9c895d2012-02-14 02:33:38 +0100619 return PyUnicode_DecodeLocale(result, NULL);
Hye-Shik Changc3a87b82004-03-21 19:34:30 +0000620 }
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000621 PyErr_SetString(PyExc_ValueError, "unsupported langinfo constant");
622 return NULL;
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000623}
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000624#endif /* HAVE_LANGINFO_H */
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000625
626#ifdef HAVE_LIBINTL_H
627
Zackery Spytzbbceef62020-07-15 03:07:34 -0600628/*[clinic input]
629_locale.gettext
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000630
Zackery Spytzbbceef62020-07-15 03:07:34 -0600631 msg as in: str
632 /
633
634gettext(msg) -> string
635
636Return translation of msg.
637[clinic start generated code]*/
638
639static PyObject *
640_locale_gettext_impl(PyObject *module, const char *in)
641/*[clinic end generated code: output=493bb4b38a4704fe input=949fc8efc2bb3bc3]*/
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000642{
Victor Stinnera9c895d2012-02-14 02:33:38 +0100643 return PyUnicode_DecodeLocale(gettext(in), NULL);
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000644}
645
Zackery Spytzbbceef62020-07-15 03:07:34 -0600646/*[clinic input]
647_locale.dgettext
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000648
Zackery Spytzbbceef62020-07-15 03:07:34 -0600649 domain: str(accept={str, NoneType})
650 msg as in: str
651 /
652
653dgettext(domain, msg) -> string
654
655Return translation of msg in domain.
656[clinic start generated code]*/
657
658static PyObject *
659_locale_dgettext_impl(PyObject *module, const char *domain, const char *in)
660/*[clinic end generated code: output=3c0cd5287b972c8f input=a277388a635109d8]*/
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000661{
Victor Stinnera9c895d2012-02-14 02:33:38 +0100662 return PyUnicode_DecodeLocale(dgettext(domain, in), NULL);
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000663}
664
Zackery Spytzbbceef62020-07-15 03:07:34 -0600665/*[clinic input]
666_locale.dcgettext
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000667
Zackery Spytzbbceef62020-07-15 03:07:34 -0600668 domain: str(accept={str, NoneType})
669 msg as msgid: str
670 category: int
671 /
672
673Return translation of msg in domain and category.
674[clinic start generated code]*/
675
676static PyObject *
677_locale_dcgettext_impl(PyObject *module, const char *domain,
678 const char *msgid, int category)
679/*[clinic end generated code: output=0f4cc4fce0aa283f input=ec5f8fed4336de67]*/
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000680{
Victor Stinnera9c895d2012-02-14 02:33:38 +0100681 return PyUnicode_DecodeLocale(dcgettext(domain,msgid,category), NULL);
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000682}
683
Zackery Spytzbbceef62020-07-15 03:07:34 -0600684/*[clinic input]
685_locale.textdomain
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000686
Zackery Spytzbbceef62020-07-15 03:07:34 -0600687 domain: str(accept={str, NoneType})
688 /
689
690Set the C library's textdmain to domain, returning the new domain.
691[clinic start generated code]*/
692
693static PyObject *
694_locale_textdomain_impl(PyObject *module, const char *domain)
695/*[clinic end generated code: output=7992df06aadec313 input=66359716f5eb1d38]*/
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000696{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000697 domain = textdomain(domain);
698 if (!domain) {
699 PyErr_SetFromErrno(PyExc_OSError);
700 return NULL;
701 }
Victor Stinnera9c895d2012-02-14 02:33:38 +0100702 return PyUnicode_DecodeLocale(domain, NULL);
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000703}
704
Zackery Spytzbbceef62020-07-15 03:07:34 -0600705/*[clinic input]
706_locale.bindtextdomain
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000707
Zackery Spytzbbceef62020-07-15 03:07:34 -0600708 domain: str
709 dir as dirname_obj: object
710 /
711
712Bind the C library's domain to dir.
713[clinic start generated code]*/
714
715static PyObject *
716_locale_bindtextdomain_impl(PyObject *module, const char *domain,
717 PyObject *dirname_obj)
718/*[clinic end generated code: output=6d6f3c7b345d785c input=c0dff085acfe272b]*/
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000719{
Zackery Spytzbbceef62020-07-15 03:07:34 -0600720 const char *dirname, *current_dirname;
721 PyObject *dirname_bytes = NULL, *result;
Hai Shia1581682020-03-12 00:46:06 +0800722
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000723 if (!strlen(domain)) {
Zackery Spytzbbceef62020-07-15 03:07:34 -0600724 PyErr_SetString(get_locale_state(module)->Error,
Hai Shia1581682020-03-12 00:46:06 +0800725 "domain must be a non-empty string");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000726 return 0;
727 }
Victor Stinner9e19ca42010-06-11 22:09:51 +0000728 if (dirname_obj != Py_None) {
729 if (!PyUnicode_FSConverter(dirname_obj, &dirname_bytes))
730 return NULL;
731 dirname = PyBytes_AsString(dirname_bytes);
732 } else {
733 dirname_bytes = NULL;
734 dirname = NULL;
735 }
736 current_dirname = bindtextdomain(domain, dirname);
737 if (current_dirname == NULL) {
738 Py_XDECREF(dirname_bytes);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000739 PyErr_SetFromErrno(PyExc_OSError);
740 return NULL;
741 }
Victor Stinnera9c895d2012-02-14 02:33:38 +0100742 result = PyUnicode_DecodeLocale(current_dirname, NULL);
Victor Stinner9e19ca42010-06-11 22:09:51 +0000743 Py_XDECREF(dirname_bytes);
744 return result;
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000745}
746
Gustavo Niemeyer7bd33c52004-07-22 18:44:01 +0000747#ifdef HAVE_BIND_TEXTDOMAIN_CODESET
Gustavo Niemeyer7bd33c52004-07-22 18:44:01 +0000748
Zackery Spytzbbceef62020-07-15 03:07:34 -0600749/*[clinic input]
750_locale.bind_textdomain_codeset
751
752 domain: str
753 codeset: str(accept={str, NoneType})
754 /
755
756Bind the C library's domain to codeset.
757[clinic start generated code]*/
758
759static PyObject *
760_locale_bind_textdomain_codeset_impl(PyObject *module, const char *domain,
761 const char *codeset)
762/*[clinic end generated code: output=fa452f9c8b1b9e89 input=23fbe3540400f259]*/
Gustavo Niemeyer7bd33c52004-07-22 18:44:01 +0000763{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000764 codeset = bind_textdomain_codeset(domain, codeset);
Victor Stinner7ed7aea2018-01-15 10:45:49 +0100765 if (codeset) {
Victor Stinnera9c895d2012-02-14 02:33:38 +0100766 return PyUnicode_DecodeLocale(codeset, NULL);
Victor Stinner7ed7aea2018-01-15 10:45:49 +0100767 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000768 Py_RETURN_NONE;
Gustavo Niemeyer7bd33c52004-07-22 18:44:01 +0000769}
Victor Stinnerb62bdf72020-10-31 01:32:11 +0100770#endif // HAVE_BIND_TEXTDOMAIN_CODESET
Gustavo Niemeyer7bd33c52004-07-22 18:44:01 +0000771
Victor Stinnerb62bdf72020-10-31 01:32:11 +0100772#endif // HAVE_LIBINTL_H
773
774
775/*[clinic input]
776_locale._get_locale_encoding
777
778Get the current locale encoding.
779[clinic start generated code]*/
780
781static PyObject *
782_locale__get_locale_encoding_impl(PyObject *module)
783/*[clinic end generated code: output=e8e2f6f6f184591a input=513d9961d2f45c76]*/
784{
Victor Stinner82458b62020-11-01 20:59:35 +0100785 return _Py_GetLocaleEncodingObject();
Victor Stinnerb62bdf72020-10-31 01:32:11 +0100786}
787
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000788
Guido van Rossum220ecc81997-11-18 21:03:39 +0000789static struct PyMethodDef PyLocale_Methods[] = {
Zackery Spytzbbceef62020-07-15 03:07:34 -0600790 _LOCALE_SETLOCALE_METHODDEF
791 _LOCALE_LOCALECONV_METHODDEF
Martin v. Löwis92fab752008-03-08 10:40:41 +0000792#ifdef HAVE_WCSCOLL
Zackery Spytzbbceef62020-07-15 03:07:34 -0600793 _LOCALE_STRCOLL_METHODDEF
Martin v. Löwis92fab752008-03-08 10:40:41 +0000794#endif
795#ifdef HAVE_WCSXFRM
Zackery Spytzbbceef62020-07-15 03:07:34 -0600796 _LOCALE_STRXFRM_METHODDEF
Martin v. Löwis92fab752008-03-08 10:40:41 +0000797#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000798#if defined(MS_WINDOWS)
Zackery Spytzbbceef62020-07-15 03:07:34 -0600799 _LOCALE__GETDEFAULTLOCALE_METHODDEF
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000800#endif
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000801#ifdef HAVE_LANGINFO_H
Zackery Spytzbbceef62020-07-15 03:07:34 -0600802 _LOCALE_NL_LANGINFO_METHODDEF
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000803#endif
Martin v. Löwisc6a7d7e2002-05-02 12:16:29 +0000804#ifdef HAVE_LIBINTL_H
Zackery Spytzbbceef62020-07-15 03:07:34 -0600805 _LOCALE_GETTEXT_METHODDEF
806 _LOCALE_DGETTEXT_METHODDEF
807 _LOCALE_DCGETTEXT_METHODDEF
808 _LOCALE_TEXTDOMAIN_METHODDEF
809 _LOCALE_BINDTEXTDOMAIN_METHODDEF
Gustavo Niemeyer7bd33c52004-07-22 18:44:01 +0000810#ifdef HAVE_BIND_TEXTDOMAIN_CODESET
Zackery Spytzbbceef62020-07-15 03:07:34 -0600811 _LOCALE_BIND_TEXTDOMAIN_CODESET_METHODDEF
Gustavo Niemeyer7bd33c52004-07-22 18:44:01 +0000812#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000813#endif
Victor Stinnerb62bdf72020-10-31 01:32:11 +0100814 _LOCALE__GET_LOCALE_ENCODING_METHODDEF
Guido van Rossum220ecc81997-11-18 21:03:39 +0000815 {NULL, NULL}
816};
817
Hai Shia1581682020-03-12 00:46:06 +0800818static int
Hai Shi7a6f3bc2020-04-03 02:00:47 +0800819_locale_exec(PyObject *module)
Guido van Rossum220ecc81997-11-18 21:03:39 +0000820{
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000821#ifdef HAVE_LANGINFO_H
822 int i;
823#endif
Hai Shi7a6f3bc2020-04-03 02:00:47 +0800824#define ADD_INT(module, value) \
825 do { \
826 if (PyModule_AddIntConstant(module, #value, value) < 0) { \
827 return -1; \
828 } \
829 } while (0)
Guido van Rossum220ecc81997-11-18 21:03:39 +0000830
Hai Shi7a6f3bc2020-04-03 02:00:47 +0800831 ADD_INT(module, LC_CTYPE);
832 ADD_INT(module, LC_TIME);
833 ADD_INT(module, LC_COLLATE);
834 ADD_INT(module, LC_MONETARY);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000835
Guido van Rossum8d9c2e31997-12-09 19:35:11 +0000836#ifdef LC_MESSAGES
Hai Shi7a6f3bc2020-04-03 02:00:47 +0800837 ADD_INT(module, LC_MESSAGES);
Guido van Rossum8d9c2e31997-12-09 19:35:11 +0000838#endif /* LC_MESSAGES */
Guido van Rossum220ecc81997-11-18 21:03:39 +0000839
Hai Shi7a6f3bc2020-04-03 02:00:47 +0800840 ADD_INT(module, LC_NUMERIC);
841 ADD_INT(module, LC_ALL);
842 ADD_INT(module, CHAR_MAX);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000843
Hai Shi7a6f3bc2020-04-03 02:00:47 +0800844 _locale_state *state = get_locale_state(module);
Hai Shia1581682020-03-12 00:46:06 +0800845 state->Error = PyErr_NewException("locale.Error", NULL, NULL);
846 if (state->Error == NULL) {
847 return -1;
Christian Heimesff4fddd2016-09-09 00:24:12 +0200848 }
Hai Shi7a6f3bc2020-04-03 02:00:47 +0800849 Py_INCREF(get_locale_state(module)->Error);
850 if (PyModule_AddObject(module, "Error", get_locale_state(module)->Error) < 0) {
851 Py_DECREF(get_locale_state(module)->Error);
Hai Shia1581682020-03-12 00:46:06 +0800852 return -1;
853 }
Guido van Rossum220ecc81997-11-18 21:03:39 +0000854
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000855#ifdef HAVE_LANGINFO_H
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000856 for (i = 0; langinfo_constants[i].name; i++) {
Hai Shi7a6f3bc2020-04-03 02:00:47 +0800857 if (PyModule_AddIntConstant(module,
858 langinfo_constants[i].name,
859 langinfo_constants[i].value) < 0) {
860 return -1;
861 }
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000862 }
Martin v. Löwisf95dd0a2001-08-15 17:14:33 +0000863#endif
Christian Heimesff4fddd2016-09-09 00:24:12 +0200864
865 if (PyErr_Occurred()) {
Hai Shia1581682020-03-12 00:46:06 +0800866 return -1;
Christian Heimesff4fddd2016-09-09 00:24:12 +0200867 }
Hai Shia1581682020-03-12 00:46:06 +0800868 return 0;
Hai Shi7a6f3bc2020-04-03 02:00:47 +0800869
870#undef ADD_INT
Hai Shia1581682020-03-12 00:46:06 +0800871}
872
873static struct PyModuleDef_Slot _locale_slots[] = {
874 {Py_mod_exec, _locale_exec},
875 {0, NULL}
876};
877
878static int
Hai Shi13397ee2020-03-20 01:11:33 +0800879locale_traverse(PyObject *module, visitproc visit, void *arg)
Hai Shia1581682020-03-12 00:46:06 +0800880{
Hai Shi13397ee2020-03-20 01:11:33 +0800881 _locale_state *state = get_locale_state(module);
Victor Stinner5b1ef202020-03-17 18:09:46 +0100882 Py_VISIT(state->Error);
Hai Shia1581682020-03-12 00:46:06 +0800883 return 0;
884}
885
886static int
Hai Shi13397ee2020-03-20 01:11:33 +0800887locale_clear(PyObject *module)
Hai Shia1581682020-03-12 00:46:06 +0800888{
Hai Shi13397ee2020-03-20 01:11:33 +0800889 _locale_state *state = get_locale_state(module);
Victor Stinner5b1ef202020-03-17 18:09:46 +0100890 Py_CLEAR(state->Error);
Hai Shia1581682020-03-12 00:46:06 +0800891 return 0;
892}
893
894static void
Hai Shi13397ee2020-03-20 01:11:33 +0800895locale_free(PyObject *module)
Hai Shia1581682020-03-12 00:46:06 +0800896{
Hai Shi13397ee2020-03-20 01:11:33 +0800897 locale_clear(module);
Hai Shia1581682020-03-12 00:46:06 +0800898}
899
900static struct PyModuleDef _localemodule = {
901 PyModuleDef_HEAD_INIT,
902 "_locale",
903 locale__doc__,
904 sizeof(_locale_state),
905 PyLocale_Methods,
906 _locale_slots,
907 locale_traverse,
908 locale_clear,
909 (freefunc)locale_free,
910};
911
912PyMODINIT_FUNC
913PyInit__locale(void)
914{
915 return PyModuleDef_Init(&_localemodule);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000916}
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000917
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000918/*
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000919Local variables:
920c-basic-offset: 4
921indent-tabs-mode: nil
922End:
923*/