1 /***********************************************************
2 Copyright (C) 1997, 2002, 2003, 2007, 2008 Martin von Loewis
3
4 Permission to use, copy, modify, and distribute this software and its
5 documentation for any purpose and without fee is hereby granted,
6 provided that the above copyright notice appear in all copies.
7
8 This 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
42 PyDoc_STRVAR(locale__doc__, "Support for POSIX locales.");
43
44 typedef struct _locale_state {
45 PyObject *Error;
46 } _locale_state;
47
48 static inline _locale_state*
get_locale_state(PyObject * m)49 get_locale_state(PyObject *m)
50 {
51 void *state = PyModule_GetState(m);
52 assert(state != NULL);
53 return (_locale_state *)state;
54 }
55
56 /* support functions for formatting floating point numbers */
57
58 PyDoc_STRVAR(setlocale__doc__,
59 "(integer,string=None) -> string. Activates/queries locale processing.");
60
61 /* the grouping is terminated by either 0 or CHAR_MAX */
62 static PyObject*
copy_grouping(const char * s)63 copy_grouping(const char* s)
64 {
65 int i;
66 PyObject *result, *val = NULL;
67
68 if (s[0] == '\0') {
69 /* empty string: no grouping at all */
70 return PyList_New(0);
71 }
72
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++;
83 val = PyLong_FromLong(s[i]);
84 if (val == NULL) {
85 Py_DECREF(result);
86 return NULL;
87 }
88 PyList_SET_ITEM(result, i, val);
89 } while (s[i] != '\0' && s[i] != CHAR_MAX);
90
91 return result;
92 }
93
94 static PyObject*
PyLocale_setlocale(PyObject * self,PyObject * args)95 PyLocale_setlocale(PyObject* self, PyObject* args)
96 {
97 int category;
98 char *locale = NULL, *result;
99 PyObject *result_object;
100
101 if (!PyArg_ParseTuple(args, "i|z:setlocale", &category, &locale))
102 return NULL;
103
104 #if defined(MS_WINDOWS)
105 if (category < LC_MIN || category > LC_MAX)
106 {
107 PyErr_SetString(get_locale_state(self)->Error,
108 "invalid locale category");
109 return NULL;
110 }
111 #endif
112
113 if (locale) {
114 /* set locale */
115 result = setlocale(category, locale);
116 if (!result) {
117 /* operation failed, no setting was changed */
118 PyErr_SetString(get_locale_state(self)->Error,
119 "unsupported locale setting");
120 return NULL;
121 }
122 result_object = PyUnicode_DecodeLocale(result, NULL);
123 if (!result_object)
124 return NULL;
125 } else {
126 /* get locale */
127 result = setlocale(category, NULL);
128 if (!result) {
129 PyErr_SetString(get_locale_state(self)->Error,
130 "locale query failed");
131 return NULL;
132 }
133 result_object = PyUnicode_DecodeLocale(result, NULL);
134 }
135 return result_object;
136 }
137
138 static int
locale_is_ascii(const char * str)139 locale_is_ascii(const char *str)
140 {
141 return (strlen(str) == 1 && ((unsigned char)str[0]) <= 127);
142 }
143
144 static int
locale_decode_monetary(PyObject * dict,struct lconv * lc)145 locale_decode_monetary(PyObject *dict, struct lconv *lc)
146 {
147 #ifndef MS_WINDOWS
148 int change_locale;
149 change_locale = (!locale_is_ascii(lc->int_curr_symbol)
150 || !locale_is_ascii(lc->currency_symbol)
151 || !locale_is_ascii(lc->mon_decimal_point)
152 || !locale_is_ascii(lc->mon_thousands_sep));
153
154 /* Keep a copy of the LC_CTYPE locale */
155 char *oldloc = NULL, *loc = NULL;
156 if (change_locale) {
157 oldloc = setlocale(LC_CTYPE, NULL);
158 if (!oldloc) {
159 PyErr_SetString(PyExc_RuntimeWarning,
160 "failed to get LC_CTYPE locale");
161 return -1;
162 }
163
164 oldloc = _PyMem_Strdup(oldloc);
165 if (!oldloc) {
166 PyErr_NoMemory();
167 return -1;
168 }
169
170 loc = setlocale(LC_MONETARY, NULL);
171 if (loc != NULL && strcmp(loc, oldloc) == 0) {
172 loc = NULL;
173 }
174
175 if (loc != NULL) {
176 /* Only set the locale temporarily the LC_CTYPE locale
177 to the LC_MONETARY locale if the two locales are different and
178 at least one string is non-ASCII. */
179 setlocale(LC_CTYPE, loc);
180 }
181 }
182
183 #define GET_LOCALE_STRING(ATTR) PyUnicode_DecodeLocale(lc->ATTR, NULL)
184 #else /* MS_WINDOWS */
185 /* Use _W_* fields of Windows struct lconv */
186 #define GET_LOCALE_STRING(ATTR) PyUnicode_FromWideChar(lc->_W_ ## ATTR, -1)
187 #endif /* MS_WINDOWS */
188
189 int res = -1;
190
191 #define RESULT_STRING(ATTR) \
192 do { \
193 PyObject *obj; \
194 obj = GET_LOCALE_STRING(ATTR); \
195 if (obj == NULL) { \
196 goto done; \
197 } \
198 if (PyDict_SetItemString(dict, Py_STRINGIFY(ATTR), obj) < 0) { \
199 Py_DECREF(obj); \
200 goto done; \
201 } \
202 Py_DECREF(obj); \
203 } while (0)
204
205 RESULT_STRING(int_curr_symbol);
206 RESULT_STRING(currency_symbol);
207 RESULT_STRING(mon_decimal_point);
208 RESULT_STRING(mon_thousands_sep);
209 #undef RESULT_STRING
210 #undef GET_LOCALE_STRING
211
212 res = 0;
213
214 done:
215 #ifndef MS_WINDOWS
216 if (loc != NULL) {
217 setlocale(LC_CTYPE, oldloc);
218 }
219 PyMem_Free(oldloc);
220 #endif
221 return res;
222 }
223
224 PyDoc_STRVAR(localeconv__doc__,
225 "() -> dict. Returns numeric and monetary locale-specific parameters.");
226
227 static PyObject*
PyLocale_localeconv(PyObject * self,PyObject * Py_UNUSED (ignored))228 PyLocale_localeconv(PyObject* self, PyObject *Py_UNUSED(ignored))
229 {
230 PyObject* result;
231 struct lconv *lc;
232 PyObject *x;
233
234 result = PyDict_New();
235 if (!result) {
236 return NULL;
237 }
238
239 /* if LC_NUMERIC is different in the C library, use saved value */
240 lc = localeconv();
241
242 /* hopefully, the localeconv result survives the C library calls
243 involved herein */
244
245 #define RESULT(key, obj)\
246 do { \
247 if (obj == NULL) \
248 goto failed; \
249 if (PyDict_SetItemString(result, key, obj) < 0) { \
250 Py_DECREF(obj); \
251 goto failed; \
252 } \
253 Py_DECREF(obj); \
254 } while (0)
255
256 #ifdef MS_WINDOWS
257 /* Use _W_* fields of Windows struct lconv */
258 #define GET_LOCALE_STRING(ATTR) PyUnicode_FromWideChar(lc->_W_ ## ATTR, -1)
259 #else
260 #define GET_LOCALE_STRING(ATTR) PyUnicode_DecodeLocale(lc->ATTR, NULL)
261 #endif
262 #define RESULT_STRING(s)\
263 do { \
264 x = GET_LOCALE_STRING(s); \
265 RESULT(#s, x); \
266 } while (0)
267
268 #define RESULT_INT(i)\
269 do { \
270 x = PyLong_FromLong(lc->i); \
271 RESULT(#i, x); \
272 } while (0)
273
274 /* Monetary information: LC_MONETARY encoding */
275 if (locale_decode_monetary(result, lc) < 0) {
276 goto failed;
277 }
278 x = copy_grouping(lc->mon_grouping);
279 RESULT("mon_grouping", x);
280
281 RESULT_STRING(positive_sign);
282 RESULT_STRING(negative_sign);
283 RESULT_INT(int_frac_digits);
284 RESULT_INT(frac_digits);
285 RESULT_INT(p_cs_precedes);
286 RESULT_INT(p_sep_by_space);
287 RESULT_INT(n_cs_precedes);
288 RESULT_INT(n_sep_by_space);
289 RESULT_INT(p_sign_posn);
290 RESULT_INT(n_sign_posn);
291
292 /* Numeric information: LC_NUMERIC encoding */
293 PyObject *decimal_point = NULL, *thousands_sep = NULL;
294 if (_Py_GetLocaleconvNumeric(lc, &decimal_point, &thousands_sep) < 0) {
295 Py_XDECREF(decimal_point);
296 Py_XDECREF(thousands_sep);
297 goto failed;
298 }
299
300 if (PyDict_SetItemString(result, "decimal_point", decimal_point) < 0) {
301 Py_DECREF(decimal_point);
302 Py_DECREF(thousands_sep);
303 goto failed;
304 }
305 Py_DECREF(decimal_point);
306
307 if (PyDict_SetItemString(result, "thousands_sep", thousands_sep) < 0) {
308 Py_DECREF(thousands_sep);
309 goto failed;
310 }
311 Py_DECREF(thousands_sep);
312
313 x = copy_grouping(lc->grouping);
314 RESULT("grouping", x);
315
316 return result;
317
318 failed:
319 Py_DECREF(result);
320 return NULL;
321
322 #undef RESULT
323 #undef RESULT_STRING
324 #undef RESULT_INT
325 #undef GET_LOCALE_STRING
326 }
327
328 #if defined(HAVE_WCSCOLL)
329 PyDoc_STRVAR(strcoll__doc__,
330 "string,string -> int. Compares two strings according to the locale.");
331
332 static PyObject*
PyLocale_strcoll(PyObject * self,PyObject * args)333 PyLocale_strcoll(PyObject* self, PyObject* args)
334 {
335 PyObject *os1, *os2, *result = NULL;
336 wchar_t *ws1 = NULL, *ws2 = NULL;
337
338 if (!PyArg_ParseTuple(args, "UU:strcoll", &os1, &os2))
339 return NULL;
340 /* Convert the unicode strings to wchar[]. */
341 ws1 = PyUnicode_AsWideCharString(os1, NULL);
342 if (ws1 == NULL)
343 goto done;
344 ws2 = PyUnicode_AsWideCharString(os2, NULL);
345 if (ws2 == NULL)
346 goto done;
347 /* Collate the strings. */
348 result = PyLong_FromLong(wcscoll(ws1, ws2));
349 done:
350 /* Deallocate everything. */
351 if (ws1) PyMem_FREE(ws1);
352 if (ws2) PyMem_FREE(ws2);
353 return result;
354 }
355 #endif
356
357 #ifdef HAVE_WCSXFRM
358 PyDoc_STRVAR(strxfrm__doc__,
359 "strxfrm(string) -> string.\n\
360 \n\
361 Return a string that can be used as a key for locale-aware comparisons.");
362
363 static PyObject*
PyLocale_strxfrm(PyObject * self,PyObject * args)364 PyLocale_strxfrm(PyObject* self, PyObject* args)
365 {
366 PyObject *str;
367 Py_ssize_t n1;
368 wchar_t *s = NULL, *buf = NULL;
369 size_t n2;
370 PyObject *result = NULL;
371
372 if (!PyArg_ParseTuple(args, "U:strxfrm", &str))
373 return NULL;
374
375 s = PyUnicode_AsWideCharString(str, &n1);
376 if (s == NULL)
377 goto exit;
378 if (wcslen(s) != (size_t)n1) {
379 PyErr_SetString(PyExc_ValueError,
380 "embedded null character");
381 goto exit;
382 }
383
384 /* assume no change in size, first */
385 n1 = n1 + 1;
386 buf = PyMem_New(wchar_t, n1);
387 if (!buf) {
388 PyErr_NoMemory();
389 goto exit;
390 }
391 errno = 0;
392 n2 = wcsxfrm(buf, s, n1);
393 if (errno && errno != ERANGE) {
394 PyErr_SetFromErrno(PyExc_OSError);
395 goto exit;
396 }
397 if (n2 >= (size_t)n1) {
398 /* more space needed */
399 wchar_t * new_buf = PyMem_Realloc(buf, (n2+1)*sizeof(wchar_t));
400 if (!new_buf) {
401 PyErr_NoMemory();
402 goto exit;
403 }
404 buf = new_buf;
405 errno = 0;
406 n2 = wcsxfrm(buf, s, n2+1);
407 if (errno) {
408 PyErr_SetFromErrno(PyExc_OSError);
409 goto exit;
410 }
411 }
412 result = PyUnicode_FromWideChar(buf, n2);
413 exit:
414 PyMem_Free(buf);
415 PyMem_Free(s);
416 return result;
417 }
418 #endif
419
420 #if defined(MS_WINDOWS)
421 static PyObject*
PyLocale_getdefaultlocale(PyObject * self,PyObject * Py_UNUSED (ignored))422 PyLocale_getdefaultlocale(PyObject* self, PyObject *Py_UNUSED(ignored))
423 {
424 char encoding[20];
425 char locale[100];
426
427 PyOS_snprintf(encoding, sizeof(encoding), "cp%u", GetACP());
428
429 if (GetLocaleInfo(LOCALE_USER_DEFAULT,
430 LOCALE_SISO639LANGNAME,
431 locale, sizeof(locale))) {
432 Py_ssize_t i = strlen(locale);
433 locale[i++] = '_';
434 if (GetLocaleInfo(LOCALE_USER_DEFAULT,
435 LOCALE_SISO3166CTRYNAME,
436 locale+i, (int)(sizeof(locale)-i)))
437 return Py_BuildValue("ss", locale, encoding);
438 }
439
440 /* If we end up here, this windows version didn't know about
441 ISO639/ISO3166 names (it's probably Windows 95). Return the
442 Windows language identifier instead (a hexadecimal number) */
443
444 locale[0] = '0';
445 locale[1] = 'x';
446 if (GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_IDEFAULTLANGUAGE,
447 locale+2, sizeof(locale)-2)) {
448 return Py_BuildValue("ss", locale, encoding);
449 }
450
451 /* cannot determine the language code (very unlikely) */
452 Py_INCREF(Py_None);
453 return Py_BuildValue("Os", Py_None, encoding);
454 }
455 #endif
456
457 #ifdef HAVE_LANGINFO_H
458 #define LANGINFO(X) {#X, X}
459 static struct langinfo_constant{
460 char* name;
461 int value;
462 } langinfo_constants[] =
463 {
464 /* These constants should exist on any langinfo implementation */
465 LANGINFO(DAY_1),
466 LANGINFO(DAY_2),
467 LANGINFO(DAY_3),
468 LANGINFO(DAY_4),
469 LANGINFO(DAY_5),
470 LANGINFO(DAY_6),
471 LANGINFO(DAY_7),
472
473 LANGINFO(ABDAY_1),
474 LANGINFO(ABDAY_2),
475 LANGINFO(ABDAY_3),
476 LANGINFO(ABDAY_4),
477 LANGINFO(ABDAY_5),
478 LANGINFO(ABDAY_6),
479 LANGINFO(ABDAY_7),
480
481 LANGINFO(MON_1),
482 LANGINFO(MON_2),
483 LANGINFO(MON_3),
484 LANGINFO(MON_4),
485 LANGINFO(MON_5),
486 LANGINFO(MON_6),
487 LANGINFO(MON_7),
488 LANGINFO(MON_8),
489 LANGINFO(MON_9),
490 LANGINFO(MON_10),
491 LANGINFO(MON_11),
492 LANGINFO(MON_12),
493
494 LANGINFO(ABMON_1),
495 LANGINFO(ABMON_2),
496 LANGINFO(ABMON_3),
497 LANGINFO(ABMON_4),
498 LANGINFO(ABMON_5),
499 LANGINFO(ABMON_6),
500 LANGINFO(ABMON_7),
501 LANGINFO(ABMON_8),
502 LANGINFO(ABMON_9),
503 LANGINFO(ABMON_10),
504 LANGINFO(ABMON_11),
505 LANGINFO(ABMON_12),
506
507 #ifdef RADIXCHAR
508 /* The following are not available with glibc 2.0 */
509 LANGINFO(RADIXCHAR),
510 LANGINFO(THOUSEP),
511 /* YESSTR and NOSTR are deprecated in glibc, since they are
512 a special case of message translation, which should be rather
513 done using gettext. So we don't expose it to Python in the
514 first place.
515 LANGINFO(YESSTR),
516 LANGINFO(NOSTR),
517 */
518 LANGINFO(CRNCYSTR),
519 #endif
520
521 LANGINFO(D_T_FMT),
522 LANGINFO(D_FMT),
523 LANGINFO(T_FMT),
524 LANGINFO(AM_STR),
525 LANGINFO(PM_STR),
526
527 /* The following constants are available only with XPG4, but...
528 AIX 3.2. only has CODESET.
529 OpenBSD doesn't have CODESET but has T_FMT_AMPM, and doesn't have
530 a few of the others.
531 Solution: ifdef-test them all. */
532 #ifdef CODESET
533 LANGINFO(CODESET),
534 #endif
535 #ifdef T_FMT_AMPM
536 LANGINFO(T_FMT_AMPM),
537 #endif
538 #ifdef ERA
539 LANGINFO(ERA),
540 #endif
541 #ifdef ERA_D_FMT
542 LANGINFO(ERA_D_FMT),
543 #endif
544 #ifdef ERA_D_T_FMT
545 LANGINFO(ERA_D_T_FMT),
546 #endif
547 #ifdef ERA_T_FMT
548 LANGINFO(ERA_T_FMT),
549 #endif
550 #ifdef ALT_DIGITS
551 LANGINFO(ALT_DIGITS),
552 #endif
553 #ifdef YESEXPR
554 LANGINFO(YESEXPR),
555 #endif
556 #ifdef NOEXPR
557 LANGINFO(NOEXPR),
558 #endif
559 #ifdef _DATE_FMT
560 /* This is not available in all glibc versions that have CODESET. */
561 LANGINFO(_DATE_FMT),
562 #endif
563 {0, 0}
564 };
565
566 PyDoc_STRVAR(nl_langinfo__doc__,
567 "nl_langinfo(key) -> string\n"
568 "Return the value for the locale information associated with key.");
569
570 static PyObject*
PyLocale_nl_langinfo(PyObject * self,PyObject * args)571 PyLocale_nl_langinfo(PyObject* self, PyObject* args)
572 {
573 int item, i;
574 if (!PyArg_ParseTuple(args, "i:nl_langinfo", &item))
575 return NULL;
576 /* Check whether this is a supported constant. GNU libc sometimes
577 returns numeric values in the char* return value, which would
578 crash PyUnicode_FromString. */
579 for (i = 0; langinfo_constants[i].name; i++)
580 if (langinfo_constants[i].value == item) {
581 /* Check NULL as a workaround for GNU libc's returning NULL
582 instead of an empty string for nl_langinfo(ERA). */
583 const char *result = nl_langinfo(item);
584 result = result != NULL ? result : "";
585 return PyUnicode_DecodeLocale(result, NULL);
586 }
587 PyErr_SetString(PyExc_ValueError, "unsupported langinfo constant");
588 return NULL;
589 }
590 #endif /* HAVE_LANGINFO_H */
591
592 #ifdef HAVE_LIBINTL_H
593
594 PyDoc_STRVAR(gettext__doc__,
595 "gettext(msg) -> string\n"
596 "Return translation of msg.");
597
598 static PyObject*
PyIntl_gettext(PyObject * self,PyObject * args)599 PyIntl_gettext(PyObject* self, PyObject *args)
600 {
601 char *in;
602 if (!PyArg_ParseTuple(args, "s", &in))
603 return 0;
604 return PyUnicode_DecodeLocale(gettext(in), NULL);
605 }
606
607 PyDoc_STRVAR(dgettext__doc__,
608 "dgettext(domain, msg) -> string\n"
609 "Return translation of msg in domain.");
610
611 static PyObject*
PyIntl_dgettext(PyObject * self,PyObject * args)612 PyIntl_dgettext(PyObject* self, PyObject *args)
613 {
614 char *domain, *in;
615 if (!PyArg_ParseTuple(args, "zs", &domain, &in))
616 return 0;
617 return PyUnicode_DecodeLocale(dgettext(domain, in), NULL);
618 }
619
620 PyDoc_STRVAR(dcgettext__doc__,
621 "dcgettext(domain, msg, category) -> string\n"
622 "Return translation of msg in domain and category.");
623
624 static PyObject*
PyIntl_dcgettext(PyObject * self,PyObject * args)625 PyIntl_dcgettext(PyObject *self, PyObject *args)
626 {
627 char *domain, *msgid;
628 int category;
629 if (!PyArg_ParseTuple(args, "zsi", &domain, &msgid, &category))
630 return 0;
631 return PyUnicode_DecodeLocale(dcgettext(domain,msgid,category), NULL);
632 }
633
634 PyDoc_STRVAR(textdomain__doc__,
635 "textdomain(domain) -> string\n"
636 "Set the C library's textdmain to domain, returning the new domain.");
637
638 static PyObject*
PyIntl_textdomain(PyObject * self,PyObject * args)639 PyIntl_textdomain(PyObject* self, PyObject* args)
640 {
641 char *domain;
642 if (!PyArg_ParseTuple(args, "z", &domain))
643 return 0;
644 domain = textdomain(domain);
645 if (!domain) {
646 PyErr_SetFromErrno(PyExc_OSError);
647 return NULL;
648 }
649 return PyUnicode_DecodeLocale(domain, NULL);
650 }
651
652 PyDoc_STRVAR(bindtextdomain__doc__,
653 "bindtextdomain(domain, dir) -> string\n"
654 "Bind the C library's domain to dir.");
655
656 static PyObject*
PyIntl_bindtextdomain(PyObject * self,PyObject * args)657 PyIntl_bindtextdomain(PyObject* self, PyObject*args)
658 {
659 const char *domain, *dirname, *current_dirname;
660 PyObject *dirname_obj, *dirname_bytes = NULL, *result;
661
662 if (!PyArg_ParseTuple(args, "sO", &domain, &dirname_obj))
663 return 0;
664 if (!strlen(domain)) {
665 PyErr_SetString(get_locale_state(self)->Error,
666 "domain must be a non-empty string");
667 return 0;
668 }
669 if (dirname_obj != Py_None) {
670 if (!PyUnicode_FSConverter(dirname_obj, &dirname_bytes))
671 return NULL;
672 dirname = PyBytes_AsString(dirname_bytes);
673 } else {
674 dirname_bytes = NULL;
675 dirname = NULL;
676 }
677 current_dirname = bindtextdomain(domain, dirname);
678 if (current_dirname == NULL) {
679 Py_XDECREF(dirname_bytes);
680 PyErr_SetFromErrno(PyExc_OSError);
681 return NULL;
682 }
683 result = PyUnicode_DecodeLocale(current_dirname, NULL);
684 Py_XDECREF(dirname_bytes);
685 return result;
686 }
687
688 #ifdef HAVE_BIND_TEXTDOMAIN_CODESET
689 PyDoc_STRVAR(bind_textdomain_codeset__doc__,
690 "bind_textdomain_codeset(domain, codeset) -> string\n"
691 "Bind the C library's domain to codeset.");
692
693 static PyObject*
PyIntl_bind_textdomain_codeset(PyObject * self,PyObject * args)694 PyIntl_bind_textdomain_codeset(PyObject* self,PyObject*args)
695 {
696 char *domain,*codeset;
697 if (!PyArg_ParseTuple(args, "sz", &domain, &codeset))
698 return NULL;
699 codeset = bind_textdomain_codeset(domain, codeset);
700 if (codeset) {
701 return PyUnicode_DecodeLocale(codeset, NULL);
702 }
703 Py_RETURN_NONE;
704 }
705 #endif
706
707 #endif
708
709 static struct PyMethodDef PyLocale_Methods[] = {
710 {"setlocale", (PyCFunction) PyLocale_setlocale,
711 METH_VARARGS, setlocale__doc__},
712 {"localeconv", PyLocale_localeconv, METH_NOARGS, localeconv__doc__},
713 #ifdef HAVE_WCSCOLL
714 {"strcoll", (PyCFunction) PyLocale_strcoll,
715 METH_VARARGS, strcoll__doc__},
716 #endif
717 #ifdef HAVE_WCSXFRM
718 {"strxfrm", (PyCFunction) PyLocale_strxfrm,
719 METH_VARARGS, strxfrm__doc__},
720 #endif
721 #if defined(MS_WINDOWS)
722 {"_getdefaultlocale", PyLocale_getdefaultlocale, METH_NOARGS},
723 #endif
724 #ifdef HAVE_LANGINFO_H
725 {"nl_langinfo", (PyCFunction) PyLocale_nl_langinfo,
726 METH_VARARGS, nl_langinfo__doc__},
727 #endif
728 #ifdef HAVE_LIBINTL_H
729 {"gettext",(PyCFunction)PyIntl_gettext,METH_VARARGS,
730 gettext__doc__},
731 {"dgettext",(PyCFunction)PyIntl_dgettext,METH_VARARGS,
732 dgettext__doc__},
733 {"dcgettext",(PyCFunction)PyIntl_dcgettext,METH_VARARGS,
734 dcgettext__doc__},
735 {"textdomain",(PyCFunction)PyIntl_textdomain,METH_VARARGS,
736 textdomain__doc__},
737 {"bindtextdomain",(PyCFunction)PyIntl_bindtextdomain,METH_VARARGS,
738 bindtextdomain__doc__},
739 #ifdef HAVE_BIND_TEXTDOMAIN_CODESET
740 {"bind_textdomain_codeset",(PyCFunction)PyIntl_bind_textdomain_codeset,
741 METH_VARARGS, bind_textdomain_codeset__doc__},
742 #endif
743 #endif
744 {NULL, NULL}
745 };
746
747 static int
_locale_exec(PyObject * module)748 _locale_exec(PyObject *module)
749 {
750 #ifdef HAVE_LANGINFO_H
751 int i;
752 #endif
753 #define ADD_INT(module, value) \
754 do { \
755 if (PyModule_AddIntConstant(module, #value, value) < 0) { \
756 return -1; \
757 } \
758 } while (0)
759
760 ADD_INT(module, LC_CTYPE);
761 ADD_INT(module, LC_TIME);
762 ADD_INT(module, LC_COLLATE);
763 ADD_INT(module, LC_MONETARY);
764
765 #ifdef LC_MESSAGES
766 ADD_INT(module, LC_MESSAGES);
767 #endif /* LC_MESSAGES */
768
769 ADD_INT(module, LC_NUMERIC);
770 ADD_INT(module, LC_ALL);
771 ADD_INT(module, CHAR_MAX);
772
773 _locale_state *state = get_locale_state(module);
774 state->Error = PyErr_NewException("locale.Error", NULL, NULL);
775 if (state->Error == NULL) {
776 return -1;
777 }
778 Py_INCREF(get_locale_state(module)->Error);
779 if (PyModule_AddObject(module, "Error", get_locale_state(module)->Error) < 0) {
780 Py_DECREF(get_locale_state(module)->Error);
781 return -1;
782 }
783
784 #ifdef HAVE_LANGINFO_H
785 for (i = 0; langinfo_constants[i].name; i++) {
786 if (PyModule_AddIntConstant(module,
787 langinfo_constants[i].name,
788 langinfo_constants[i].value) < 0) {
789 return -1;
790 }
791 }
792 #endif
793
794 if (PyErr_Occurred()) {
795 return -1;
796 }
797 return 0;
798
799 #undef ADD_INT
800 }
801
802 static struct PyModuleDef_Slot _locale_slots[] = {
803 {Py_mod_exec, _locale_exec},
804 {0, NULL}
805 };
806
807 static int
locale_traverse(PyObject * module,visitproc visit,void * arg)808 locale_traverse(PyObject *module, visitproc visit, void *arg)
809 {
810 _locale_state *state = get_locale_state(module);
811 Py_VISIT(state->Error);
812 return 0;
813 }
814
815 static int
locale_clear(PyObject * module)816 locale_clear(PyObject *module)
817 {
818 _locale_state *state = get_locale_state(module);
819 Py_CLEAR(state->Error);
820 return 0;
821 }
822
823 static void
locale_free(PyObject * module)824 locale_free(PyObject *module)
825 {
826 locale_clear(module);
827 }
828
829 static struct PyModuleDef _localemodule = {
830 PyModuleDef_HEAD_INIT,
831 "_locale",
832 locale__doc__,
833 sizeof(_locale_state),
834 PyLocale_Methods,
835 _locale_slots,
836 locale_traverse,
837 locale_clear,
838 (freefunc)locale_free,
839 };
840
841 PyMODINIT_FUNC
PyInit__locale(void)842 PyInit__locale(void)
843 {
844 return PyModuleDef_Init(&_localemodule);
845 }
846
847 /*
848 Local variables:
849 c-basic-offset: 4
850 indent-tabs-mode: nil
851 End:
852 */
853