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