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