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.getencoding
777
778Get the current locale encoding.
779[clinic start generated code]*/
780
781static PyObject *
782_locale_getencoding_impl(PyObject *module)
783/*[clinic end generated code: output=86b326b971872e46 input=6503d11e5958b360]*/
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_GETENCODING_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