• 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 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