• 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 #include "Python.h"
13 #include "pycore_fileutils.h"     // _Py_GetLocaleconvNumeric()
14 #include "pycore_pymem.h"         // _PyMem_Strdup()
15 
16 #include <locale.h>               // setlocale()
17 #include <string.h>               // strlen()
18 #ifdef HAVE_ERRNO_H
19 #  include <errno.h>              // errno
20 #endif
21 #ifdef HAVE_LANGINFO_H
22 #  include <langinfo.h>           // nl_langinfo()
23 #endif
24 #ifdef HAVE_LIBINTL_H
25 #  include <libintl.h>
26 #endif
27 #ifdef MS_WINDOWS
28 #  ifndef WIN32_LEAN_AND_MEAN
29 #    define WIN32_LEAN_AND_MEAN
30 #  endif
31 #  include <windows.h>
32 #endif
33 
34 PyDoc_STRVAR(locale__doc__, "Support for POSIX locales.");
35 
36 typedef struct _locale_state {
37     PyObject *Error;
38 } _locale_state;
39 
40 static inline _locale_state*
get_locale_state(PyObject * m)41 get_locale_state(PyObject *m)
42 {
43     void *state = PyModule_GetState(m);
44     assert(state != NULL);
45     return (_locale_state *)state;
46 }
47 
48 #include "clinic/_localemodule.c.h"
49 
50 /*[clinic input]
51 module _locale
52 [clinic start generated code]*/
53 /*[clinic end generated code: output=da39a3ee5e6b4b0d input=ed98569b726feada]*/
54 
55 /* support functions for formatting floating-point numbers */
56 
57 /* the grouping is terminated by either 0 or CHAR_MAX */
58 static PyObject*
copy_grouping(const char * s)59 copy_grouping(const char* s)
60 {
61     int i;
62     PyObject *result, *val = NULL;
63 
64     if (s[0] == '\0') {
65         /* empty string: no grouping at all */
66         return PyList_New(0);
67     }
68 
69     for (i = 0; s[i] != '\0' && s[i] != CHAR_MAX; i++)
70         ; /* nothing */
71 
72     result = PyList_New(i+1);
73     if (!result)
74         return NULL;
75 
76     i = -1;
77     do {
78         i++;
79         val = PyLong_FromLong(s[i]);
80         if (val == NULL) {
81             Py_DECREF(result);
82             return NULL;
83         }
84         PyList_SET_ITEM(result, i, val);
85     } while (s[i] != '\0' && s[i] != CHAR_MAX);
86 
87     return result;
88 }
89 
90 /*[clinic input]
91 _locale.setlocale
92 
93     category: int
94     locale: str(accept={str, NoneType}) = NULL
95     /
96 
97 Activates/queries locale processing.
98 [clinic start generated code]*/
99 
100 static PyObject *
_locale_setlocale_impl(PyObject * module,int category,const char * locale)101 _locale_setlocale_impl(PyObject *module, int category, const char *locale)
102 /*[clinic end generated code: output=a0e777ae5d2ff117 input=dbe18f1d66c57a6a]*/
103 {
104     char *result;
105     PyObject *result_object;
106 
107 #if defined(MS_WINDOWS)
108     if (category < LC_MIN || category > LC_MAX)
109     {
110         PyErr_SetString(get_locale_state(module)->Error,
111                         "invalid locale category");
112         return NULL;
113     }
114 #endif
115 
116     if (locale) {
117         /* set locale */
118         result = setlocale(category, locale);
119         if (!result) {
120             /* operation failed, no setting was changed */
121             PyErr_SetString(get_locale_state(module)->Error,
122                             "unsupported locale setting");
123             return NULL;
124         }
125         result_object = PyUnicode_DecodeLocale(result, NULL);
126         if (!result_object)
127             return NULL;
128     } else {
129         /* get locale */
130         result = setlocale(category, NULL);
131         if (!result) {
132             PyErr_SetString(get_locale_state(module)->Error,
133                             "locale query failed");
134             return NULL;
135         }
136         result_object = PyUnicode_DecodeLocale(result, NULL);
137     }
138     return result_object;
139 }
140 
141 static int
locale_is_ascii(const char * str)142 locale_is_ascii(const char *str)
143 {
144     return (strlen(str) == 1 && ((unsigned char)str[0]) <= 127);
145 }
146 
147 static int
locale_decode_monetary(PyObject * dict,struct lconv * lc)148 locale_decode_monetary(PyObject *dict, struct lconv *lc)
149 {
150 #ifndef MS_WINDOWS
151     int change_locale;
152     change_locale = (!locale_is_ascii(lc->int_curr_symbol)
153                      || !locale_is_ascii(lc->currency_symbol)
154                      || !locale_is_ascii(lc->mon_decimal_point)
155                      || !locale_is_ascii(lc->mon_thousands_sep));
156 
157     /* Keep a copy of the LC_CTYPE locale */
158     char *oldloc = NULL, *loc = NULL;
159     if (change_locale) {
160         oldloc = setlocale(LC_CTYPE, NULL);
161         if (!oldloc) {
162             PyErr_SetString(PyExc_RuntimeWarning,
163                             "failed to get LC_CTYPE locale");
164             return -1;
165         }
166 
167         oldloc = _PyMem_Strdup(oldloc);
168         if (!oldloc) {
169             PyErr_NoMemory();
170             return -1;
171         }
172 
173         loc = setlocale(LC_MONETARY, NULL);
174         if (loc != NULL && strcmp(loc, oldloc) == 0) {
175             loc = NULL;
176         }
177 
178         if (loc != NULL) {
179             /* Only set the locale temporarily the LC_CTYPE locale
180                to the LC_MONETARY locale if the two locales are different and
181                at least one string is non-ASCII. */
182             setlocale(LC_CTYPE, loc);
183         }
184     }
185 
186 #define GET_LOCALE_STRING(ATTR) PyUnicode_DecodeLocale(lc->ATTR, NULL)
187 #else  /* MS_WINDOWS */
188 /* Use _W_* fields of Windows struct lconv */
189 #define GET_LOCALE_STRING(ATTR) PyUnicode_FromWideChar(lc->_W_ ## ATTR, -1)
190 #endif /* MS_WINDOWS */
191 
192     int res = -1;
193 
194 #define RESULT_STRING(ATTR) \
195     do { \
196         PyObject *obj; \
197         obj = GET_LOCALE_STRING(ATTR); \
198         if (obj == NULL) { \
199             goto done; \
200         } \
201         if (PyDict_SetItemString(dict, Py_STRINGIFY(ATTR), obj) < 0) { \
202             Py_DECREF(obj); \
203             goto done; \
204         } \
205         Py_DECREF(obj); \
206     } while (0)
207 
208     RESULT_STRING(int_curr_symbol);
209     RESULT_STRING(currency_symbol);
210     RESULT_STRING(mon_decimal_point);
211     RESULT_STRING(mon_thousands_sep);
212 #undef RESULT_STRING
213 #undef GET_LOCALE_STRING
214 
215     res = 0;
216 
217 done:
218 #ifndef MS_WINDOWS
219     if (loc != NULL) {
220         setlocale(LC_CTYPE, oldloc);
221     }
222     PyMem_Free(oldloc);
223 #endif
224     return res;
225 }
226 
227 /*[clinic input]
228 _locale.localeconv
229 
230 Returns numeric and monetary locale-specific parameters.
231 [clinic start generated code]*/
232 
233 static PyObject *
_locale_localeconv_impl(PyObject * module)234 _locale_localeconv_impl(PyObject *module)
235 /*[clinic end generated code: output=43a54515e0a2aef5 input=f1132d15accf4444]*/
236 {
237     PyObject* result;
238     struct lconv *lc;
239     PyObject *x;
240 
241     result = PyDict_New();
242     if (!result) {
243         return NULL;
244     }
245 
246     /* if LC_NUMERIC is different in the C library, use saved value */
247     lc = localeconv();
248 
249     /* hopefully, the localeconv result survives the C library calls
250        involved herein */
251 
252 #define RESULT(key, obj)\
253     do { \
254         if (obj == NULL) \
255             goto failed; \
256         if (PyDict_SetItemString(result, key, obj) < 0) { \
257             Py_DECREF(obj); \
258             goto failed; \
259         } \
260         Py_DECREF(obj); \
261     } while (0)
262 
263 #ifdef MS_WINDOWS
264 /* Use _W_* fields of Windows struct lconv */
265 #define GET_LOCALE_STRING(ATTR) PyUnicode_FromWideChar(lc->_W_ ## ATTR, -1)
266 #else
267 #define GET_LOCALE_STRING(ATTR) PyUnicode_DecodeLocale(lc->ATTR, NULL)
268 #endif
269 #define RESULT_STRING(s)\
270     do { \
271         x = GET_LOCALE_STRING(s); \
272         RESULT(#s, x); \
273     } while (0)
274 
275 #define RESULT_INT(i)\
276     do { \
277         x = PyLong_FromLong(lc->i); \
278         RESULT(#i, x); \
279     } while (0)
280 
281     /* Monetary information: LC_MONETARY encoding */
282     if (locale_decode_monetary(result, lc) < 0) {
283         goto failed;
284     }
285     x = copy_grouping(lc->mon_grouping);
286     RESULT("mon_grouping", x);
287 
288     RESULT_STRING(positive_sign);
289     RESULT_STRING(negative_sign);
290     RESULT_INT(int_frac_digits);
291     RESULT_INT(frac_digits);
292     RESULT_INT(p_cs_precedes);
293     RESULT_INT(p_sep_by_space);
294     RESULT_INT(n_cs_precedes);
295     RESULT_INT(n_sep_by_space);
296     RESULT_INT(p_sign_posn);
297     RESULT_INT(n_sign_posn);
298 
299     /* Numeric information: LC_NUMERIC encoding */
300     PyObject *decimal_point = NULL, *thousands_sep = NULL;
301     if (_Py_GetLocaleconvNumeric(lc, &decimal_point, &thousands_sep) < 0) {
302         Py_XDECREF(decimal_point);
303         Py_XDECREF(thousands_sep);
304         goto failed;
305     }
306 
307     if (PyDict_SetItemString(result, "decimal_point", decimal_point) < 0) {
308         Py_DECREF(decimal_point);
309         Py_DECREF(thousands_sep);
310         goto failed;
311     }
312     Py_DECREF(decimal_point);
313 
314     if (PyDict_SetItemString(result, "thousands_sep", thousands_sep) < 0) {
315         Py_DECREF(thousands_sep);
316         goto failed;
317     }
318     Py_DECREF(thousands_sep);
319 
320     x = copy_grouping(lc->grouping);
321     RESULT("grouping", x);
322 
323     return result;
324 
325   failed:
326     Py_DECREF(result);
327     return NULL;
328 
329 #undef RESULT
330 #undef RESULT_STRING
331 #undef RESULT_INT
332 #undef GET_LOCALE_STRING
333 }
334 
335 #if defined(HAVE_WCSCOLL)
336 
337 /*[clinic input]
338 _locale.strcoll
339 
340     os1: unicode
341     os2: unicode
342     /
343 
344 Compares two strings according to the locale.
345 [clinic start generated code]*/
346 
347 static PyObject *
_locale_strcoll_impl(PyObject * module,PyObject * os1,PyObject * os2)348 _locale_strcoll_impl(PyObject *module, PyObject *os1, PyObject *os2)
349 /*[clinic end generated code: output=82ddc6d62c76d618 input=693cd02bcbf38dd8]*/
350 {
351     PyObject *result = NULL;
352     wchar_t *ws1 = NULL, *ws2 = NULL;
353 
354     /* Convert the unicode strings to wchar[]. */
355     ws1 = PyUnicode_AsWideCharString(os1, NULL);
356     if (ws1 == NULL)
357         goto done;
358     ws2 = PyUnicode_AsWideCharString(os2, NULL);
359     if (ws2 == NULL)
360         goto done;
361     /* Collate the strings. */
362     result = PyLong_FromLong(wcscoll(ws1, ws2));
363   done:
364     /* Deallocate everything. */
365     if (ws1) PyMem_Free(ws1);
366     if (ws2) PyMem_Free(ws2);
367     return result;
368 }
369 #endif
370 
371 #ifdef HAVE_WCSXFRM
372 
373 /*[clinic input]
374 _locale.strxfrm
375 
376     string as str: unicode
377     /
378 
379 Return a string that can be used as a key for locale-aware comparisons.
380 [clinic start generated code]*/
381 
382 static PyObject *
_locale_strxfrm_impl(PyObject * module,PyObject * str)383 _locale_strxfrm_impl(PyObject *module, PyObject *str)
384 /*[clinic end generated code: output=3081866ebffc01af input=1378bbe6a88b4780]*/
385 {
386     Py_ssize_t n1;
387     wchar_t *s = NULL, *buf = NULL;
388     size_t n2;
389     PyObject *result = NULL;
390 
391     s = PyUnicode_AsWideCharString(str, &n1);
392     if (s == NULL)
393         goto exit;
394     if (wcslen(s) != (size_t)n1) {
395         PyErr_SetString(PyExc_ValueError,
396                         "embedded null character");
397         goto exit;
398     }
399 
400     /* assume no change in size, first */
401     n1 = n1 + 1;
402     buf = PyMem_New(wchar_t, n1);
403     if (!buf) {
404         PyErr_NoMemory();
405         goto exit;
406     }
407     errno = 0;
408     n2 = wcsxfrm(buf, s, n1);
409     if (errno && errno != ERANGE) {
410         PyErr_SetFromErrno(PyExc_OSError);
411         goto exit;
412     }
413     if (n2 >= (size_t)n1) {
414         /* more space needed */
415         wchar_t * new_buf = PyMem_Realloc(buf, (n2+1)*sizeof(wchar_t));
416         if (!new_buf) {
417             PyErr_NoMemory();
418             goto exit;
419         }
420         buf = new_buf;
421         errno = 0;
422         n2 = wcsxfrm(buf, s, n2+1);
423         if (errno) {
424             PyErr_SetFromErrno(PyExc_OSError);
425             goto exit;
426         }
427     }
428     result = PyUnicode_FromWideChar(buf, n2);
429 exit:
430     PyMem_Free(buf);
431     PyMem_Free(s);
432     return result;
433 }
434 #endif
435 
436 #if defined(MS_WINDOWS)
437 
438 /*[clinic input]
439 _locale._getdefaultlocale
440 
441 [clinic start generated code]*/
442 
443 static PyObject *
_locale__getdefaultlocale_impl(PyObject * module)444 _locale__getdefaultlocale_impl(PyObject *module)
445 /*[clinic end generated code: output=e6254088579534c2 input=003ea41acd17f7c7]*/
446 {
447     char encoding[20];
448     char locale[100];
449 
450     PyOS_snprintf(encoding, sizeof(encoding), "cp%u", GetACP());
451 
452     if (GetLocaleInfoA(LOCALE_USER_DEFAULT,
453                       LOCALE_SISO639LANGNAME,
454                       locale, sizeof(locale))) {
455         Py_ssize_t i = strlen(locale);
456         locale[i++] = '_';
457         if (GetLocaleInfoA(LOCALE_USER_DEFAULT,
458                           LOCALE_SISO3166CTRYNAME,
459                           locale+i, (int)(sizeof(locale)-i)))
460             return Py_BuildValue("ss", locale, encoding);
461     }
462 
463     /* If we end up here, this windows version didn't know about
464        ISO639/ISO3166 names (it's probably Windows 95).  Return the
465        Windows language identifier instead (a hexadecimal number) */
466 
467     locale[0] = '0';
468     locale[1] = 'x';
469     if (GetLocaleInfoA(LOCALE_USER_DEFAULT, LOCALE_IDEFAULTLANGUAGE,
470                       locale+2, sizeof(locale)-2)) {
471         return Py_BuildValue("ss", locale, encoding);
472     }
473 
474     /* cannot determine the language code (very unlikely) */
475     Py_INCREF(Py_None);
476     return Py_BuildValue("Os", Py_None, encoding);
477 }
478 #endif
479 
480 #ifdef HAVE_LANGINFO_H
481 #define LANGINFO(X) {#X, X}
482 static struct langinfo_constant{
483     char* name;
484     int value;
485 } langinfo_constants[] =
486 {
487     /* These constants should exist on any langinfo implementation */
488     LANGINFO(DAY_1),
489     LANGINFO(DAY_2),
490     LANGINFO(DAY_3),
491     LANGINFO(DAY_4),
492     LANGINFO(DAY_5),
493     LANGINFO(DAY_6),
494     LANGINFO(DAY_7),
495 
496     LANGINFO(ABDAY_1),
497     LANGINFO(ABDAY_2),
498     LANGINFO(ABDAY_3),
499     LANGINFO(ABDAY_4),
500     LANGINFO(ABDAY_5),
501     LANGINFO(ABDAY_6),
502     LANGINFO(ABDAY_7),
503 
504     LANGINFO(MON_1),
505     LANGINFO(MON_2),
506     LANGINFO(MON_3),
507     LANGINFO(MON_4),
508     LANGINFO(MON_5),
509     LANGINFO(MON_6),
510     LANGINFO(MON_7),
511     LANGINFO(MON_8),
512     LANGINFO(MON_9),
513     LANGINFO(MON_10),
514     LANGINFO(MON_11),
515     LANGINFO(MON_12),
516 
517     LANGINFO(ABMON_1),
518     LANGINFO(ABMON_2),
519     LANGINFO(ABMON_3),
520     LANGINFO(ABMON_4),
521     LANGINFO(ABMON_5),
522     LANGINFO(ABMON_6),
523     LANGINFO(ABMON_7),
524     LANGINFO(ABMON_8),
525     LANGINFO(ABMON_9),
526     LANGINFO(ABMON_10),
527     LANGINFO(ABMON_11),
528     LANGINFO(ABMON_12),
529 
530 #ifdef RADIXCHAR
531     /* The following are not available with glibc 2.0 */
532     LANGINFO(RADIXCHAR),
533     LANGINFO(THOUSEP),
534     /* YESSTR and NOSTR are deprecated in glibc, since they are
535        a special case of message translation, which should be rather
536        done using gettext. So we don't expose it to Python in the
537        first place.
538     LANGINFO(YESSTR),
539     LANGINFO(NOSTR),
540     */
541     LANGINFO(CRNCYSTR),
542 #endif
543 
544     LANGINFO(D_T_FMT),
545     LANGINFO(D_FMT),
546     LANGINFO(T_FMT),
547     LANGINFO(AM_STR),
548     LANGINFO(PM_STR),
549 
550     /* The following constants are available only with XPG4, but...
551        OpenBSD doesn't have CODESET but has T_FMT_AMPM, and doesn't have
552        a few of the others.
553        Solution: ifdef-test them all. */
554 #ifdef CODESET
555     LANGINFO(CODESET),
556 #endif
557 #ifdef T_FMT_AMPM
558     LANGINFO(T_FMT_AMPM),
559 #endif
560 #ifdef ERA
561     LANGINFO(ERA),
562 #endif
563 #ifdef ERA_D_FMT
564     LANGINFO(ERA_D_FMT),
565 #endif
566 #ifdef ERA_D_T_FMT
567     LANGINFO(ERA_D_T_FMT),
568 #endif
569 #ifdef ERA_T_FMT
570     LANGINFO(ERA_T_FMT),
571 #endif
572 #ifdef ALT_DIGITS
573     LANGINFO(ALT_DIGITS),
574 #endif
575 #ifdef YESEXPR
576     LANGINFO(YESEXPR),
577 #endif
578 #ifdef NOEXPR
579     LANGINFO(NOEXPR),
580 #endif
581 #ifdef _DATE_FMT
582     /* This is not available in all glibc versions that have CODESET. */
583     LANGINFO(_DATE_FMT),
584 #endif
585     {0, 0}
586 };
587 
588 #ifdef __GLIBC__
589 #if defined(ALT_DIGITS) || defined(ERA)
590 static PyObject *
decode_strings(const char * result,size_t max_count)591 decode_strings(const char *result, size_t max_count)
592 {
593     /* Convert a sequence of NUL-separated C strings to a Python string
594      * containing semicolon separated items. */
595     size_t i = 0;
596     size_t count = 0;
597     for (; count < max_count && result[i]; count++) {
598         i += strlen(result + i) + 1;
599     }
600     char *buf = PyMem_Malloc(i);
601     if (buf == NULL) {
602         PyErr_NoMemory();
603         return NULL;
604     }
605     memcpy(buf, result, i);
606     /* Replace all NULs with semicolons. */
607     i = 0;
608     while (--count) {
609         i += strlen(buf + i);
610         buf[i++] = ';';
611     }
612     PyObject *pyresult = PyUnicode_DecodeLocale(buf, NULL);
613     PyMem_Free(buf);
614     return pyresult;
615 }
616 #endif
617 #endif
618 
619 /*[clinic input]
620 _locale.nl_langinfo
621 
622     key as item: int
623     /
624 
625 Return the value for the locale information associated with key.
626 [clinic start generated code]*/
627 
628 static PyObject *
_locale_nl_langinfo_impl(PyObject * module,int item)629 _locale_nl_langinfo_impl(PyObject *module, int item)
630 /*[clinic end generated code: output=6aea457b47e077a3 input=00798143eecfeddc]*/
631 {
632     int i;
633     /* Check whether this is a supported constant. GNU libc sometimes
634        returns numeric values in the char* return value, which would
635        crash PyUnicode_FromString.  */
636     for (i = 0; langinfo_constants[i].name; i++)
637         if (langinfo_constants[i].value == item) {
638             /* Check NULL as a workaround for GNU libc's returning NULL
639                instead of an empty string for nl_langinfo(ERA).  */
640             const char *result = nl_langinfo(item);
641             result = result != NULL ? result : "";
642             PyObject *pyresult;
643 #ifdef __GLIBC__
644             /* According to the POSIX specification the result must be
645              * a sequence of semicolon-separated strings.
646              * But in Glibc they are NUL-separated. */
647 #ifdef ALT_DIGITS
648             if (item == ALT_DIGITS && *result) {
649                 pyresult = decode_strings(result, 100);
650             }
651             else
652 #endif
653 #ifdef ERA
654             if (item == ERA && *result) {
655                 pyresult = decode_strings(result, SIZE_MAX);
656             }
657             else
658 #endif
659 #endif
660             {
661                 pyresult = PyUnicode_DecodeLocale(result, NULL);
662             }
663             return pyresult;
664         }
665     PyErr_SetString(PyExc_ValueError, "unsupported langinfo constant");
666     return NULL;
667 }
668 #endif /* HAVE_LANGINFO_H */
669 
670 #ifdef HAVE_LIBINTL_H
671 
672 /*[clinic input]
673 _locale.gettext
674 
675     msg as in: str
676     /
677 
678 gettext(msg) -> string
679 
680 Return translation of msg.
681 [clinic start generated code]*/
682 
683 static PyObject *
_locale_gettext_impl(PyObject * module,const char * in)684 _locale_gettext_impl(PyObject *module, const char *in)
685 /*[clinic end generated code: output=493bb4b38a4704fe input=949fc8efc2bb3bc3]*/
686 {
687     return PyUnicode_DecodeLocale(gettext(in), NULL);
688 }
689 
690 /*[clinic input]
691 _locale.dgettext
692 
693     domain: str(accept={str, NoneType})
694     msg as in: str
695     /
696 
697 dgettext(domain, msg) -> string
698 
699 Return translation of msg in domain.
700 [clinic start generated code]*/
701 
702 static PyObject *
_locale_dgettext_impl(PyObject * module,const char * domain,const char * in)703 _locale_dgettext_impl(PyObject *module, const char *domain, const char *in)
704 /*[clinic end generated code: output=3c0cd5287b972c8f input=a277388a635109d8]*/
705 {
706     return PyUnicode_DecodeLocale(dgettext(domain, in), NULL);
707 }
708 
709 /*[clinic input]
710 _locale.dcgettext
711 
712     domain: str(accept={str, NoneType})
713     msg as msgid: str
714     category: int
715     /
716 
717 Return translation of msg in domain and category.
718 [clinic start generated code]*/
719 
720 static PyObject *
_locale_dcgettext_impl(PyObject * module,const char * domain,const char * msgid,int category)721 _locale_dcgettext_impl(PyObject *module, const char *domain,
722                        const char *msgid, int category)
723 /*[clinic end generated code: output=0f4cc4fce0aa283f input=ec5f8fed4336de67]*/
724 {
725     return PyUnicode_DecodeLocale(dcgettext(domain,msgid,category), NULL);
726 }
727 
728 /*[clinic input]
729 _locale.textdomain
730 
731     domain: str(accept={str, NoneType})
732     /
733 
734 Set the C library's textdmain to domain, returning the new domain.
735 [clinic start generated code]*/
736 
737 static PyObject *
_locale_textdomain_impl(PyObject * module,const char * domain)738 _locale_textdomain_impl(PyObject *module, const char *domain)
739 /*[clinic end generated code: output=7992df06aadec313 input=66359716f5eb1d38]*/
740 {
741     domain = textdomain(domain);
742     if (!domain) {
743         PyErr_SetFromErrno(PyExc_OSError);
744         return NULL;
745     }
746     return PyUnicode_DecodeLocale(domain, NULL);
747 }
748 
749 /*[clinic input]
750 _locale.bindtextdomain
751 
752     domain: str
753     dir as dirname_obj: object
754     /
755 
756 Bind the C library's domain to dir.
757 [clinic start generated code]*/
758 
759 static PyObject *
_locale_bindtextdomain_impl(PyObject * module,const char * domain,PyObject * dirname_obj)760 _locale_bindtextdomain_impl(PyObject *module, const char *domain,
761                             PyObject *dirname_obj)
762 /*[clinic end generated code: output=6d6f3c7b345d785c input=c0dff085acfe272b]*/
763 {
764     const char *dirname, *current_dirname;
765     PyObject *dirname_bytes = NULL, *result;
766 
767     if (!strlen(domain)) {
768         PyErr_SetString(get_locale_state(module)->Error,
769                         "domain must be a non-empty string");
770         return 0;
771     }
772     if (dirname_obj != Py_None) {
773         if (!PyUnicode_FSConverter(dirname_obj, &dirname_bytes))
774             return NULL;
775         dirname = PyBytes_AsString(dirname_bytes);
776     } else {
777         dirname_bytes = NULL;
778         dirname = NULL;
779     }
780     current_dirname = bindtextdomain(domain, dirname);
781     if (current_dirname == NULL) {
782         PyErr_SetFromErrno(PyExc_OSError);
783         Py_XDECREF(dirname_bytes);
784         return NULL;
785     }
786     result = PyUnicode_DecodeLocale(current_dirname, NULL);
787     Py_XDECREF(dirname_bytes);
788     return result;
789 }
790 
791 #ifdef HAVE_BIND_TEXTDOMAIN_CODESET
792 
793 /*[clinic input]
794 _locale.bind_textdomain_codeset
795 
796     domain: str
797     codeset: str(accept={str, NoneType})
798     /
799 
800 Bind the C library's domain to codeset.
801 [clinic start generated code]*/
802 
803 static PyObject *
_locale_bind_textdomain_codeset_impl(PyObject * module,const char * domain,const char * codeset)804 _locale_bind_textdomain_codeset_impl(PyObject *module, const char *domain,
805                                      const char *codeset)
806 /*[clinic end generated code: output=fa452f9c8b1b9e89 input=23fbe3540400f259]*/
807 {
808     codeset = bind_textdomain_codeset(domain, codeset);
809     if (codeset) {
810         return PyUnicode_DecodeLocale(codeset, NULL);
811     }
812     Py_RETURN_NONE;
813 }
814 #endif  // HAVE_BIND_TEXTDOMAIN_CODESET
815 
816 #endif  // HAVE_LIBINTL_H
817 
818 
819 /*[clinic input]
820 _locale.getencoding
821 
822 Get the current locale encoding.
823 [clinic start generated code]*/
824 
825 static PyObject *
_locale_getencoding_impl(PyObject * module)826 _locale_getencoding_impl(PyObject *module)
827 /*[clinic end generated code: output=86b326b971872e46 input=6503d11e5958b360]*/
828 {
829     return _Py_GetLocaleEncodingObject();
830 }
831 
832 
833 static struct PyMethodDef PyLocale_Methods[] = {
834     _LOCALE_SETLOCALE_METHODDEF
835     _LOCALE_LOCALECONV_METHODDEF
836 #ifdef HAVE_WCSCOLL
837     _LOCALE_STRCOLL_METHODDEF
838 #endif
839 #ifdef HAVE_WCSXFRM
840     _LOCALE_STRXFRM_METHODDEF
841 #endif
842 #if defined(MS_WINDOWS)
843     _LOCALE__GETDEFAULTLOCALE_METHODDEF
844 #endif
845 #ifdef HAVE_LANGINFO_H
846     _LOCALE_NL_LANGINFO_METHODDEF
847 #endif
848 #ifdef HAVE_LIBINTL_H
849     _LOCALE_GETTEXT_METHODDEF
850     _LOCALE_DGETTEXT_METHODDEF
851     _LOCALE_DCGETTEXT_METHODDEF
852     _LOCALE_TEXTDOMAIN_METHODDEF
853     _LOCALE_BINDTEXTDOMAIN_METHODDEF
854 #ifdef HAVE_BIND_TEXTDOMAIN_CODESET
855     _LOCALE_BIND_TEXTDOMAIN_CODESET_METHODDEF
856 #endif
857 #endif
858     _LOCALE_GETENCODING_METHODDEF
859   {NULL, NULL}
860 };
861 
862 static int
_locale_exec(PyObject * module)863 _locale_exec(PyObject *module)
864 {
865 #ifdef HAVE_LANGINFO_H
866     int i;
867 #endif
868 #define ADD_INT(module, value)                                    \
869     do {                                                          \
870         if (PyModule_AddIntConstant(module, #value, value) < 0) { \
871             return -1;                                            \
872         }                                                         \
873     } while (0)
874 
875     ADD_INT(module, LC_CTYPE);
876     ADD_INT(module, LC_TIME);
877     ADD_INT(module, LC_COLLATE);
878     ADD_INT(module, LC_MONETARY);
879 
880 #ifdef LC_MESSAGES
881     ADD_INT(module, LC_MESSAGES);
882 #endif /* LC_MESSAGES */
883 
884     ADD_INT(module, LC_NUMERIC);
885     ADD_INT(module, LC_ALL);
886     ADD_INT(module, CHAR_MAX);
887 
888     _locale_state *state = get_locale_state(module);
889     state->Error = PyErr_NewException("locale.Error", NULL, NULL);
890     if (PyModule_AddObjectRef(module, "Error", state->Error) < 0) {
891         return -1;
892     }
893 
894 #ifdef HAVE_LANGINFO_H
895     for (i = 0; langinfo_constants[i].name; i++) {
896         if (PyModule_AddIntConstant(module,
897                                     langinfo_constants[i].name,
898                                     langinfo_constants[i].value) < 0) {
899             return -1;
900         }
901     }
902 #endif
903 
904     if (PyErr_Occurred()) {
905         return -1;
906     }
907     return 0;
908 
909 #undef ADD_INT
910 }
911 
912 static struct PyModuleDef_Slot _locale_slots[] = {
913     {Py_mod_exec, _locale_exec},
914     {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED},
915     {Py_mod_gil, Py_MOD_GIL_NOT_USED},
916     {0, NULL}
917 };
918 
919 static int
locale_traverse(PyObject * module,visitproc visit,void * arg)920 locale_traverse(PyObject *module, visitproc visit, void *arg)
921 {
922     _locale_state *state = get_locale_state(module);
923     Py_VISIT(state->Error);
924     return 0;
925 }
926 
927 static int
locale_clear(PyObject * module)928 locale_clear(PyObject *module)
929 {
930     _locale_state *state = get_locale_state(module);
931     Py_CLEAR(state->Error);
932     return 0;
933 }
934 
935 static void
locale_free(PyObject * module)936 locale_free(PyObject *module)
937 {
938     locale_clear(module);
939 }
940 
941 static struct PyModuleDef _localemodule = {
942     PyModuleDef_HEAD_INIT,
943     "_locale",
944     locale__doc__,
945     sizeof(_locale_state),
946     PyLocale_Methods,
947     _locale_slots,
948     locale_traverse,
949     locale_clear,
950     (freefunc)locale_free,
951 };
952 
953 PyMODINIT_FUNC
PyInit__locale(void)954 PyInit__locale(void)
955 {
956     return PyModuleDef_Init(&_localemodule);
957 }
958 
959 /*
960 Local variables:
961 c-basic-offset: 4
962 indent-tabs-mode: nil
963 End:
964 */
965