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