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 #include "clinic/_localemodule.c.h"
57
58 /*[clinic input]
59 module _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 */
66 static PyObject*
copy_grouping(const char * s)67 copy_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
105 Activates/queries locale processing.
106 [clinic start generated code]*/
107
108 static PyObject *
_locale_setlocale_impl(PyObject * module,int category,const char * locale)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
149 static int
locale_is_ascii(const char * str)150 locale_is_ascii(const char *str)
151 {
152 return (strlen(str) == 1 && ((unsigned char)str[0]) <= 127);
153 }
154
155 static int
locale_decode_monetary(PyObject * dict,struct lconv * lc)156 locale_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
225 done:
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
238 Returns numeric and monetary locale-specific parameters.
239 [clinic start generated code]*/
240
241 static PyObject *
_locale_localeconv_impl(PyObject * module)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
352 Compares two strings according to the locale.
353 [clinic start generated code]*/
354
355 static PyObject *
_locale_strcoll_impl(PyObject * module,PyObject * os1,PyObject * os2)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
387 Return a string that can be used as a key for locale-aware comparisons.
388 [clinic start generated code]*/
389
390 static PyObject *
_locale_strxfrm_impl(PyObject * module,PyObject * str)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);
437 exit:
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
451 static PyObject *
_locale__getdefaultlocale_impl(PyObject * module)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}
490 static 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
602 Return the value for the locale information associated with key.
603 [clinic start generated code]*/
604
605 static PyObject *
_locale_nl_langinfo_impl(PyObject * module,int item)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
634 gettext(msg) -> string
635
636 Return translation of msg.
637 [clinic start generated code]*/
638
639 static PyObject *
_locale_gettext_impl(PyObject * module,const char * in)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
653 dgettext(domain, msg) -> string
654
655 Return translation of msg in domain.
656 [clinic start generated code]*/
657
658 static PyObject *
_locale_dgettext_impl(PyObject * module,const char * domain,const char * in)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
673 Return translation of msg in domain and category.
674 [clinic start generated code]*/
675
676 static PyObject *
_locale_dcgettext_impl(PyObject * module,const char * domain,const char * msgid,int category)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
690 Set the C library's textdmain to domain, returning the new domain.
691 [clinic start generated code]*/
692
693 static PyObject *
_locale_textdomain_impl(PyObject * module,const char * domain)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
712 Bind the C library's domain to dir.
713 [clinic start generated code]*/
714
715 static PyObject *
_locale_bindtextdomain_impl(PyObject * module,const char * domain,PyObject * dirname_obj)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
756 Bind the C library's domain to codeset.
757 [clinic start generated code]*/
758
759 static PyObject *
_locale_bind_textdomain_codeset_impl(PyObject * module,const char * domain,const char * codeset)760 _locale_bind_textdomain_codeset_impl(PyObject *module, const char *domain,
761 const char *codeset)
762 /*[clinic end generated code: output=fa452f9c8b1b9e89 input=23fbe3540400f259]*/
763 {
764 codeset = bind_textdomain_codeset(domain, codeset);
765 if (codeset) {
766 return PyUnicode_DecodeLocale(codeset, NULL);
767 }
768 Py_RETURN_NONE;
769 }
770 #endif // HAVE_BIND_TEXTDOMAIN_CODESET
771
772 #endif // HAVE_LIBINTL_H
773
774
775 /*[clinic input]
776 _locale._get_locale_encoding
777
778 Get the current locale encoding.
779 [clinic start generated code]*/
780
781 static PyObject *
_locale__get_locale_encoding_impl(PyObject * module)782 _locale__get_locale_encoding_impl(PyObject *module)
783 /*[clinic end generated code: output=e8e2f6f6f184591a input=513d9961d2f45c76]*/
784 {
785 return _Py_GetLocaleEncodingObject();
786 }
787
788
789 static struct PyMethodDef PyLocale_Methods[] = {
790 _LOCALE_SETLOCALE_METHODDEF
791 _LOCALE_LOCALECONV_METHODDEF
792 #ifdef HAVE_WCSCOLL
793 _LOCALE_STRCOLL_METHODDEF
794 #endif
795 #ifdef HAVE_WCSXFRM
796 _LOCALE_STRXFRM_METHODDEF
797 #endif
798 #if defined(MS_WINDOWS)
799 _LOCALE__GETDEFAULTLOCALE_METHODDEF
800 #endif
801 #ifdef HAVE_LANGINFO_H
802 _LOCALE_NL_LANGINFO_METHODDEF
803 #endif
804 #ifdef HAVE_LIBINTL_H
805 _LOCALE_GETTEXT_METHODDEF
806 _LOCALE_DGETTEXT_METHODDEF
807 _LOCALE_DCGETTEXT_METHODDEF
808 _LOCALE_TEXTDOMAIN_METHODDEF
809 _LOCALE_BINDTEXTDOMAIN_METHODDEF
810 #ifdef HAVE_BIND_TEXTDOMAIN_CODESET
811 _LOCALE_BIND_TEXTDOMAIN_CODESET_METHODDEF
812 #endif
813 #endif
814 _LOCALE__GET_LOCALE_ENCODING_METHODDEF
815 {NULL, NULL}
816 };
817
818 static int
_locale_exec(PyObject * module)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
873 static struct PyModuleDef_Slot _locale_slots[] = {
874 {Py_mod_exec, _locale_exec},
875 {0, NULL}
876 };
877
878 static int
locale_traverse(PyObject * module,visitproc visit,void * arg)879 locale_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
886 static int
locale_clear(PyObject * module)887 locale_clear(PyObject *module)
888 {
889 _locale_state *state = get_locale_state(module);
890 Py_CLEAR(state->Error);
891 return 0;
892 }
893
894 static void
locale_free(PyObject * module)895 locale_free(PyObject *module)
896 {
897 locale_clear(module);
898 }
899
900 static 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
912 PyMODINIT_FUNC
PyInit__locale(void)913 PyInit__locale(void)
914 {
915 return PyModuleDef_Init(&_localemodule);
916 }
917
918 /*
919 Local variables:
920 c-basic-offset: 4
921 indent-tabs-mode: nil
922 End:
923 */
924