1/***********************************************************
2Copyright (C) 1997, 2002, 2003, 2007, 2008 Martin von Loewis
3
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.
9
10******************************************************************/
11
12#define PY_SSIZE_T_CLEAN
13#include "Python.h"
14#include "pycore_fileutils.h"
15
16#include <stdio.h>
17#include <locale.h>
18#include <string.h>
19#include <ctype.h>
20
21#ifdef HAVE_ERRNO_H
22#include <errno.h>
23#endif
24
25#ifdef HAVE_LANGINFO_H
26#include <langinfo.h>
27#endif
28
29#ifdef HAVE_LIBINTL_H
30#include <libintl.h>
31#endif
32
33#ifdef HAVE_WCHAR_H
34#include <wchar.h>
35#endif
36
37#if defined(MS_WINDOWS)
38#define WIN32_LEAN_AND_MEAN
39#include <windows.h>
40#endif
41
42PyDoc_STRVAR(locale__doc__, "Support for POSIX locales.");
43
44typedef 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}
55
56#include "clinic/_localemodule.c.h"
57
58/*[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 */
64
65/* the grouping is terminated by either 0 or CHAR_MAX */
66static PyObject*
67copy_grouping(const char* s)
68{
69 int i;
70 PyObject *result, *val = NULL;
71
72 if (s[0] == '\0') {
73 /* empty string: no grouping at all */
74 return PyList_New(0);
75 }
76
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++;
87 val = PyLong_FromLong(s[i]);
88 if (val == NULL) {
89 Py_DECREF(result);
90 return NULL;
91 }
92 PyList_SET_ITEM(result, i, val);
93 } while (s[i] != '\0' && s[i] != CHAR_MAX);
94
95 return result;
96}
97
98/*[clinic input]
99_locale.setlocale
100
101 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;
114
115#if defined(MS_WINDOWS)
116 if (category < LC_MIN || category > LC_MAX)
117 {
118 PyErr_SetString(get_locale_state(module)->Error,
119 "invalid locale category");
120 return NULL;
121 }
122#endif
123
124 if (locale) {
125 /* set locale */
126 result = setlocale(category, locale);
127 if (!result) {
128 /* operation failed, no setting was changed */
129 PyErr_SetString(get_locale_state(module)->Error,
130 "unsupported locale setting");
131 return NULL;
132 }
133 result_object = PyUnicode_DecodeLocale(result, NULL);
134 if (!result_object)
135 return NULL;
136 } else {
137 /* get locale */
138 result = setlocale(category, NULL);
139 if (!result) {
140 PyErr_SetString(get_locale_state(module)->Error,
141 "locale query failed");
142 return NULL;
143 }
144 result_object = PyUnicode_DecodeLocale(result, NULL);
145 }
146 return result_object;
147}
148
149static 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#ifndef MS_WINDOWS
159 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
194#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
200 int res = -1;
201
202#define RESULT_STRING(ATTR) \
203 do { \
204 PyObject *obj; \
205 obj = GET_LOCALE_STRING(ATTR); \
206 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
221#undef GET_LOCALE_STRING
222
223 res = 0;
224
225done:
226#ifndef MS_WINDOWS
227 if (loc != NULL) {
228 setlocale(LC_CTYPE, oldloc);
229 }
230 PyMem_Free(oldloc);
231#endif
232 return res;
233}
234
235/*[clinic input]
236_locale.localeconv
237
238Returns 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]*/
244{
245 PyObject* result;
246 struct lconv *lc;
247 PyObject *x;
248
249 result = PyDict_New();
250 if (!result) {
251 return NULL;
252 }
253
254 /* if LC_NUMERIC is different in the C library, use saved value */
255 lc = localeconv();
256
257 /* hopefully, the localeconv result survives the C library calls
258 involved herein */
259
260#define RESULT(key, obj)\
261 do { \
262 if (obj == NULL) \
263 goto failed; \
264 if (PyDict_SetItemString(result, key, obj) < 0) { \
265 Py_DECREF(obj); \
266 goto failed; \
267 } \
268 Py_DECREF(obj); \
269 } while (0)
270
271#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
277#define RESULT_STRING(s)\
278 do { \
279 x = GET_LOCALE_STRING(s); \
280 RESULT(#s, x); \
281 } while (0)
282
283#define RESULT_INT(i)\
284 do { \
285 x = PyLong_FromLong(lc->i); \
286 RESULT(#i, x); \
287 } while (0)
288
289 /* Monetary information: LC_MONETARY encoding */
290 if (locale_decode_monetary(result, lc) < 0) {
291 goto failed;
292 }
293 x = copy_grouping(lc->mon_grouping);
294 RESULT("mon_grouping", x);
295
296 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);
306
307 /* Numeric information: LC_NUMERIC encoding */
308 PyObject *decimal_point = NULL, *thousands_sep = NULL;
309 if (_Py_GetLocaleconvNumeric(lc, &decimal_point, &thousands_sep) < 0) {
310 Py_XDECREF(decimal_point);
311 Py_XDECREF(thousands_sep);
312 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
328 x = copy_grouping(lc->grouping);
329 RESULT("grouping", x);
330
331 return result;
332
333 failed:
334 Py_DECREF(result);
335 return NULL;
336
337#undef RESULT
338#undef RESULT_STRING
339#undef RESULT_INT
340#undef GET_LOCALE_STRING
341}
342
343#if defined(HAVE_WCSCOLL)
344
345/*[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]*/
358{
359 PyObject *result = NULL;
360 wchar_t *ws1 = NULL, *ws2 = NULL;
361
362 /* Convert the unicode strings to wchar[]. */
363 ws1 = PyUnicode_AsWideCharString(os1, NULL);
364 if (ws1 == NULL)
365 goto done;
366 ws2 = PyUnicode_AsWideCharString(os2, NULL);
367 if (ws2 == NULL)
368 goto done;
369 /* Collate the strings. */
370 result = PyLong_FromLong(wcscoll(ws1, ws2));
371 done:
372 /* Deallocate everything. */
373 if (ws1) PyMem_Free(ws1);
374 if (ws2) PyMem_Free(ws2);
375 return result;
376}
377#endif
378
379#ifdef HAVE_WCSXFRM
380
381/*[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]*/
393{
394 Py_ssize_t n1;
395 wchar_t *s = NULL, *buf = NULL;
396 size_t n2;
397 PyObject *result = NULL;
398
399 s = PyUnicode_AsWideCharString(str, &n1);
400 if (s == NULL)
401 goto exit;
402 if (wcslen(s) != (size_t)n1) {
403 PyErr_SetString(PyExc_ValueError,
404 "embedded null character");
405 goto exit;
406 }
407
408 /* assume no change in size, first */
409 n1 = n1 + 1;
410 buf = PyMem_New(wchar_t, n1);
411 if (!buf) {
412 PyErr_NoMemory();
413 goto exit;
414 }
415 errno = 0;
416 n2 = wcsxfrm(buf, s, n1);
417 if (errno && errno != ERANGE) {
418 PyErr_SetFromErrno(PyExc_OSError);
419 goto exit;
420 }
421 if (n2 >= (size_t)n1) {
422 /* more space needed */
423 wchar_t * new_buf = PyMem_Realloc(buf, (n2+1)*sizeof(wchar_t));
424 if (!new_buf) {
425 PyErr_NoMemory();
426 goto exit;
427 }
428 buf = new_buf;
429 errno = 0;
430 n2 = wcsxfrm(buf, s, n2+1);
431 if (errno) {
432 PyErr_SetFromErrno(PyExc_OSError);
433 goto exit;
434 }
435 }
436 result = PyUnicode_FromWideChar(buf, n2);
437exit:
438 PyMem_Free(buf);
439 PyMem_Free(s);
440 return result;
441}
442#endif
443
444#if defined(MS_WINDOWS)
445
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]*/
454{
455 char encoding[20];
456 char locale[100];
457
458 PyOS_snprintf(encoding, sizeof(encoding), "cp%u", GetACP());
459
460 if (GetLocaleInfo(LOCALE_USER_DEFAULT,
461 LOCALE_SISO639LANGNAME,
462 locale, sizeof(locale))) {
463 Py_ssize_t i = strlen(locale);
464 locale[i++] = '_';
465 if (GetLocaleInfo(LOCALE_USER_DEFAULT,
466 LOCALE_SISO3166CTRYNAME,
467 locale+i, (int)(sizeof(locale)-i)))
468 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
488#ifdef HAVE_LANGINFO_H
489#define LANGINFO(X) {#X, X}
490static struct langinfo_constant{
491 char* name;
492 int value;
493} langinfo_constants[] =
494{
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
558 /* The following constants are available only with XPG4, but...
559 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. */
562#ifdef CODESET
563 LANGINFO(CODESET),
564#endif
565#ifdef T_FMT_AMPM
566 LANGINFO(T_FMT_AMPM),
567#endif
568#ifdef ERA
569 LANGINFO(ERA),
570#endif
571#ifdef ERA_D_FMT
572 LANGINFO(ERA_D_FMT),
573#endif
574#ifdef ERA_D_T_FMT
575 LANGINFO(ERA_D_T_FMT),
576#endif
577#ifdef ERA_T_FMT
578 LANGINFO(ERA_T_FMT),
579#endif
580#ifdef ALT_DIGITS
581 LANGINFO(ALT_DIGITS),
582#endif
583#ifdef YESEXPR
584 LANGINFO(YESEXPR),
585#endif
586#ifdef NOEXPR
587 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
596/*[clinic input]
597_locale.nl_langinfo
598
599 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]*/
608{
609 int i;
610 /* Check whether this is a supported constant. GNU libc sometimes
611 returns numeric values in the char* return value, which would
612 crash PyUnicode_FromString. */
613 for (i = 0; langinfo_constants[i].name; i++)
614 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);
618 result = result != NULL ? result : "";
619 return PyUnicode_DecodeLocale(result, NULL);
620 }
621 PyErr_SetString(PyExc_ValueError, "unsupported langinfo constant");
622 return NULL;
623}
624#endif /* HAVE_LANGINFO_H */
625
626#ifdef HAVE_LIBINTL_H
627
628/*[clinic input]
629_locale.gettext
630
631 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]*/
642{
643 return PyUnicode_DecodeLocale(gettext(in), NULL);
644}
645
646/*[clinic input]
647_locale.dgettext
648
649 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]*/
661{
662 return PyUnicode_DecodeLocale(dgettext(domain, in), NULL);
663}
664
665/*[clinic input]
666_locale.dcgettext
667
668 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]*/
680{
681 return PyUnicode_DecodeLocale(dcgettext(domain,msgid,category), NULL);
682}
683
684/*[clinic input]
685_locale.textdomain
686
687 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]*/
696{
697 domain = textdomain(domain);
698 if (!domain) {
699 PyErr_SetFromErrno(PyExc_OSError);
700 return NULL;
701 }
702 return PyUnicode_DecodeLocale(domain, NULL);
703}
704
705/*[clinic input]
706_locale.bindtextdomain
707
708 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]*/
719{
720 const char *dirname, *current_dirname;
721 PyObject *dirname_bytes = NULL, *result;
722
723 if (!strlen(domain)) {
724 PyErr_SetString(get_locale_state(module)->Error,
725 "domain must be a non-empty string");
726 return 0;
727 }
728 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);
739 PyErr_SetFromErrno(PyExc_OSError);
740 return NULL;
741 }
742 result = PyUnicode_DecodeLocale(current_dirname, NULL);
743 Py_XDECREF(dirname_bytes);
744 return result;
745}
746
747#ifdef HAVE_BIND_TEXTDOMAIN_CODESET
748
749/*[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]*/
763{
764 codeset = bind_textdomain_codeset(domain, codeset);
765 if (codeset) {
766 return PyUnicode_DecodeLocale(codeset, NULL);
767 }
768 Py_RETURN_NONE;
769}
770#endif // HAVE_BIND_TEXTDOMAIN_CODESET
771
772#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{
785 return _Py_GetLocaleEncodingObject();
786}
787
788
789static struct PyMethodDef PyLocale_Methods[] = {
790 _LOCALE_SETLOCALE_METHODDEF
791 _LOCALE_LOCALECONV_METHODDEF
792#ifdef HAVE_WCSCOLL
793 _LOCALE_STRCOLL_METHODDEF
794#endif
795#ifdef HAVE_WCSXFRM
796 _LOCALE_STRXFRM_METHODDEF
797#endif
798#if defined(MS_WINDOWS)
799 _LOCALE__GETDEFAULTLOCALE_METHODDEF
800#endif
801#ifdef HAVE_LANGINFO_H
802 _LOCALE_NL_LANGINFO_METHODDEF
803#endif
804#ifdef HAVE_LIBINTL_H
805 _LOCALE_GETTEXT_METHODDEF
806 _LOCALE_DGETTEXT_METHODDEF
807 _LOCALE_DCGETTEXT_METHODDEF
808 _LOCALE_TEXTDOMAIN_METHODDEF
809 _LOCALE_BINDTEXTDOMAIN_METHODDEF
810#ifdef HAVE_BIND_TEXTDOMAIN_CODESET
811 _LOCALE_BIND_TEXTDOMAIN_CODESET_METHODDEF
812#endif
813#endif
814 _LOCALE__GET_LOCALE_ENCODING_METHODDEF
815 {NULL, NULL}
816};
817
818static int
819_locale_exec(PyObject *module)
820{
821#ifdef HAVE_LANGINFO_H
822 int i;
823#endif
824#define ADD_INT(module, value) \
825 do { \
826 if (PyModule_AddIntConstant(module, #value, value) < 0) { \
827 return -1; \
828 } \
829 } while (0)
830
831 ADD_INT(module, LC_CTYPE);
832 ADD_INT(module, LC_TIME);
833 ADD_INT(module, LC_COLLATE);
834 ADD_INT(module, LC_MONETARY);
835
836#ifdef LC_MESSAGES
837 ADD_INT(module, LC_MESSAGES);
838#endif /* LC_MESSAGES */
839
840 ADD_INT(module, LC_NUMERIC);
841 ADD_INT(module, LC_ALL);
842 ADD_INT(module, CHAR_MAX);
843
844 _locale_state *state = get_locale_state(module);
845 state->Error = PyErr_NewException("locale.Error", NULL, NULL);
846 if (state->Error == NULL) {
847 return -1;
848 }
849 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);
852 return -1;
853 }
854
855#ifdef HAVE_LANGINFO_H
856 for (i = 0; langinfo_constants[i].name; i++) {
857 if (PyModule_AddIntConstant(module,
858 langinfo_constants[i].name,
859 langinfo_constants[i].value) < 0) {
860 return -1;
861 }
862 }
863#endif
864
865 if (PyErr_Occurred()) {
866 return -1;
867 }
868 return 0;
869
870#undef ADD_INT
871}
872
873static struct PyModuleDef_Slot _locale_slots[] = {
874 {Py_mod_exec, _locale_exec},
875 {0, NULL}
876};
877
878static int
879locale_traverse(PyObject *module, visitproc visit, void *arg)
880{
881 _locale_state *state = get_locale_state(module);
882 Py_VISIT(state->Error);
883 return 0;
884}
885
886static int
887locale_clear(PyObject *module)
888{
889 _locale_state *state = get_locale_state(module);
890 Py_CLEAR(state->Error);
891 return 0;
892}
893
894static void
895locale_free(PyObject *module)
896{
897 locale_clear(module);
898}
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);
916}
917
918/*
919Local variables:
920c-basic-offset: 4
921indent-tabs-mode: nil
922End:
923*/
924