Branch data Line data Source code
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*
49 : 47128 : get_locale_state(PyObject *m)
50 : : {
51 : 47128 : void *state = PyModule_GetState(m);
52 : : assert(state != NULL);
53 : 47128 : 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*
67 : 1266 : copy_grouping(const char* s)
68 : : {
69 : : int i;
70 : 1266 : PyObject *result, *val = NULL;
71 : :
72 [ + + ]: 1266 : if (s[0] == '\0') {
73 : : /* empty string: no grouping at all */
74 : 768 : return PyList_New(0);
75 : : }
76 : :
77 [ + + + - ]: 1429 : for (i = 0; s[i] != '\0' && s[i] != CHAR_MAX; i++)
78 : : ; /* nothing */
79 : :
80 : 498 : result = PyList_New(i+1);
81 [ - + ]: 498 : if (!result)
82 : 0 : return NULL;
83 : :
84 : 498 : i = -1;
85 : : do {
86 : 1429 : i++;
87 : 1429 : val = PyLong_FromLong(s[i]);
88 [ - + ]: 1429 : if (val == NULL) {
89 : 0 : Py_DECREF(result);
90 : 0 : return NULL;
91 : : }
92 : 1429 : PyList_SET_ITEM(result, i, val);
93 [ + + + - ]: 1429 : } while (s[i] != '\0' && s[i] != CHAR_MAX);
94 : :
95 : 498 : 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 *
109 : 17110 : _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 [ + + ]: 17110 : if (locale) {
125 : : /* set locale */
126 : 839 : result = setlocale(category, locale);
127 [ + + ]: 839 : if (!result) {
128 : : /* operation failed, no setting was changed */
129 : 5 : PyErr_SetString(get_locale_state(module)->Error,
130 : : "unsupported locale setting");
131 : 5 : return NULL;
132 : : }
133 : 834 : result_object = PyUnicode_DecodeLocale(result, NULL);
134 [ - + ]: 834 : if (!result_object)
135 : 0 : return NULL;
136 : : } else {
137 : : /* get locale */
138 : 16271 : result = setlocale(category, NULL);
139 [ + + ]: 16271 : if (!result) {
140 : 1 : PyErr_SetString(get_locale_state(module)->Error,
141 : : "locale query failed");
142 : 1 : return NULL;
143 : : }
144 : 16270 : result_object = PyUnicode_DecodeLocale(result, NULL);
145 : : }
146 : 17104 : return result_object;
147 : : }
148 : :
149 : : static int
150 : 633 : locale_is_ascii(const char *str)
151 : : {
152 [ - + - - ]: 633 : return (strlen(str) == 1 && ((unsigned char)str[0]) <= 127);
153 : : }
154 : :
155 : : static int
156 : 633 : locale_decode_monetary(PyObject *dict, struct lconv *lc)
157 : : {
158 : : #ifndef MS_WINDOWS
159 : : int change_locale;
160 : 633 : change_locale = (!locale_is_ascii(lc->int_curr_symbol)
161 [ # # ]: 0 : || !locale_is_ascii(lc->currency_symbol)
162 [ # # ]: 0 : || !locale_is_ascii(lc->mon_decimal_point)
163 [ - + - - ]: 633 : || !locale_is_ascii(lc->mon_thousands_sep));
164 : :
165 : : /* Keep a copy of the LC_CTYPE locale */
166 : 633 : char *oldloc = NULL, *loc = NULL;
167 [ + - ]: 633 : if (change_locale) {
168 : 633 : oldloc = setlocale(LC_CTYPE, NULL);
169 [ - + ]: 633 : if (!oldloc) {
170 : 0 : PyErr_SetString(PyExc_RuntimeWarning,
171 : : "failed to get LC_CTYPE locale");
172 : 0 : return -1;
173 : : }
174 : :
175 : 633 : oldloc = _PyMem_Strdup(oldloc);
176 [ - + ]: 633 : if (!oldloc) {
177 : : PyErr_NoMemory();
178 : 0 : return -1;
179 : : }
180 : :
181 : 633 : loc = setlocale(LC_MONETARY, NULL);
182 [ + - + + ]: 633 : if (loc != NULL && strcmp(loc, oldloc) == 0) {
183 : 6 : loc = NULL;
184 : : }
185 : :
186 [ + + ]: 633 : 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 : 627 : 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 : 633 : 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 [ - + - + ]: 633 : RESULT_STRING(int_curr_symbol);
217 [ - + - + ]: 633 : RESULT_STRING(currency_symbol);
218 [ - + - + ]: 633 : RESULT_STRING(mon_decimal_point);
219 [ - + - + ]: 633 : RESULT_STRING(mon_thousands_sep);
220 : : #undef RESULT_STRING
221 : : #undef GET_LOCALE_STRING
222 : :
223 : 633 : res = 0;
224 : :
225 : 633 : done:
226 : : #ifndef MS_WINDOWS
227 [ + + ]: 633 : if (loc != NULL) {
228 : 627 : setlocale(LC_CTYPE, oldloc);
229 : : }
230 : 633 : PyMem_Free(oldloc);
231 : : #endif
232 : 633 : 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 *
242 : 633 : _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 : 633 : result = PyDict_New();
250 [ - + ]: 633 : if (!result) {
251 : 0 : return NULL;
252 : : }
253 : :
254 : : /* if LC_NUMERIC is different in the C library, use saved value */
255 : 633 : 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 [ - + ]: 633 : if (locale_decode_monetary(result, lc) < 0) {
291 : 0 : goto failed;
292 : : }
293 : 633 : x = copy_grouping(lc->mon_grouping);
294 [ - + - + ]: 633 : RESULT("mon_grouping", x);
295 : :
296 [ - + - + ]: 633 : RESULT_STRING(positive_sign);
297 [ - + - + ]: 633 : RESULT_STRING(negative_sign);
298 [ - + - + ]: 633 : RESULT_INT(int_frac_digits);
299 [ - + - + ]: 633 : RESULT_INT(frac_digits);
300 [ - + - + ]: 633 : RESULT_INT(p_cs_precedes);
301 [ - + - + ]: 633 : RESULT_INT(p_sep_by_space);
302 [ - + - + ]: 633 : RESULT_INT(n_cs_precedes);
303 [ - + - + ]: 633 : RESULT_INT(n_sep_by_space);
304 [ - + - + ]: 633 : RESULT_INT(p_sign_posn);
305 [ - + - + ]: 633 : RESULT_INT(n_sign_posn);
306 : :
307 : : /* Numeric information: LC_NUMERIC encoding */
308 : 633 : PyObject *decimal_point = NULL, *thousands_sep = NULL;
309 [ - + ]: 633 : if (_Py_GetLocaleconvNumeric(lc, &decimal_point, &thousands_sep) < 0) {
310 : 0 : Py_XDECREF(decimal_point);
311 : 0 : Py_XDECREF(thousands_sep);
312 : 0 : goto failed;
313 : : }
314 : :
315 [ - + ]: 633 : if (PyDict_SetItemString(result, "decimal_point", decimal_point) < 0) {
316 : 0 : Py_DECREF(decimal_point);
317 : 0 : Py_DECREF(thousands_sep);
318 : 0 : goto failed;
319 : : }
320 : 633 : Py_DECREF(decimal_point);
321 : :
322 [ - + ]: 633 : if (PyDict_SetItemString(result, "thousands_sep", thousands_sep) < 0) {
323 : 0 : Py_DECREF(thousands_sep);
324 : 0 : goto failed;
325 : : }
326 : 633 : Py_DECREF(thousands_sep);
327 : :
328 : 633 : x = copy_grouping(lc->grouping);
329 [ - + - + ]: 633 : RESULT("grouping", x);
330 : :
331 : 633 : return result;
332 : :
333 : 0 : failed:
334 : 0 : Py_DECREF(result);
335 : 0 : 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 *
356 : 11 : _locale_strcoll_impl(PyObject *module, PyObject *os1, PyObject *os2)
357 : : /*[clinic end generated code: output=82ddc6d62c76d618 input=693cd02bcbf38dd8]*/
358 : : {
359 : 11 : PyObject *result = NULL;
360 : 11 : wchar_t *ws1 = NULL, *ws2 = NULL;
361 : :
362 : : /* Convert the unicode strings to wchar[]. */
363 : 11 : ws1 = PyUnicode_AsWideCharString(os1, NULL);
364 [ + + ]: 11 : if (ws1 == NULL)
365 : 2 : goto done;
366 : 9 : ws2 = PyUnicode_AsWideCharString(os2, NULL);
367 [ + + ]: 9 : if (ws2 == NULL)
368 : 2 : goto done;
369 : : /* Collate the strings. */
370 : 7 : result = PyLong_FromLong(wcscoll(ws1, ws2));
371 : 11 : done:
372 : : /* Deallocate everything. */
373 [ + + ]: 11 : if (ws1) PyMem_Free(ws1);
374 [ + + ]: 11 : if (ws2) PyMem_Free(ws2);
375 : 11 : 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 *
391 : 8 : _locale_strxfrm_impl(PyObject *module, PyObject *str)
392 : : /*[clinic end generated code: output=3081866ebffc01af input=1378bbe6a88b4780]*/
393 : : {
394 : : Py_ssize_t n1;
395 : 8 : wchar_t *s = NULL, *buf = NULL;
396 : : size_t n2;
397 : 8 : PyObject *result = NULL;
398 : :
399 : 8 : s = PyUnicode_AsWideCharString(str, &n1);
400 [ - + ]: 8 : if (s == NULL)
401 : 0 : goto exit;
402 [ + + ]: 8 : if (wcslen(s) != (size_t)n1) {
403 : 2 : PyErr_SetString(PyExc_ValueError,
404 : : "embedded null character");
405 : 2 : goto exit;
406 : : }
407 : :
408 : : /* assume no change in size, first */
409 : 6 : n1 = n1 + 1;
410 [ + - ]: 6 : buf = PyMem_New(wchar_t, n1);
411 [ - + ]: 6 : if (!buf) {
412 : : PyErr_NoMemory();
413 : 0 : goto exit;
414 : : }
415 : 6 : errno = 0;
416 : 6 : n2 = wcsxfrm(buf, s, n1);
417 [ - + - - ]: 6 : if (errno && errno != ERANGE) {
418 : 0 : PyErr_SetFromErrno(PyExc_OSError);
419 : 0 : goto exit;
420 : : }
421 [ + + ]: 6 : if (n2 >= (size_t)n1) {
422 : : /* more space needed */
423 : 4 : wchar_t * new_buf = PyMem_Realloc(buf, (n2+1)*sizeof(wchar_t));
424 [ - + ]: 4 : if (!new_buf) {
425 : : PyErr_NoMemory();
426 : 0 : goto exit;
427 : : }
428 : 4 : buf = new_buf;
429 : 4 : errno = 0;
430 : 4 : n2 = wcsxfrm(buf, s, n2+1);
431 [ - + ]: 4 : if (errno) {
432 : 0 : PyErr_SetFromErrno(PyExc_OSError);
433 : 0 : goto exit;
434 : : }
435 : : }
436 : 6 : result = PyUnicode_FromWideChar(buf, n2);
437 : 8 : exit:
438 : 8 : PyMem_Free(buf);
439 : 8 : PyMem_Free(s);
440 : 8 : 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 *
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 *
606 : 296 : _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 [ + - ]: 11692 : for (i = 0; langinfo_constants[i].name; i++)
614 [ + + ]: 11692 : 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 : 296 : const char *result = nl_langinfo(item);
618 [ + - ]: 296 : result = result != NULL ? result : "";
619 : 296 : return PyUnicode_DecodeLocale(result, NULL);
620 : : }
621 : 0 : PyErr_SetString(PyExc_ValueError, "unsupported langinfo constant");
622 : 0 : 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 *
640 : 0 : _locale_gettext_impl(PyObject *module, const char *in)
641 : : /*[clinic end generated code: output=493bb4b38a4704fe input=949fc8efc2bb3bc3]*/
642 : : {
643 : 0 : 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 *
659 : 0 : _locale_dgettext_impl(PyObject *module, const char *domain, const char *in)
660 : : /*[clinic end generated code: output=3c0cd5287b972c8f input=a277388a635109d8]*/
661 : : {
662 : 0 : 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 *
677 : 0 : _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 : 0 : 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 *
694 : 0 : _locale_textdomain_impl(PyObject *module, const char *domain)
695 : : /*[clinic end generated code: output=7992df06aadec313 input=66359716f5eb1d38]*/
696 : : {
697 : 0 : domain = textdomain(domain);
698 [ # # ]: 0 : if (!domain) {
699 : 0 : PyErr_SetFromErrno(PyExc_OSError);
700 : 0 : return NULL;
701 : : }
702 : 0 : 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 *
716 : 0 : _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 : 0 : PyObject *dirname_bytes = NULL, *result;
722 : :
723 [ # # ]: 0 : if (!strlen(domain)) {
724 : 0 : PyErr_SetString(get_locale_state(module)->Error,
725 : : "domain must be a non-empty string");
726 : 0 : return 0;
727 : : }
728 [ # # ]: 0 : if (dirname_obj != Py_None) {
729 [ # # ]: 0 : if (!PyUnicode_FSConverter(dirname_obj, &dirname_bytes))
730 : 0 : return NULL;
731 : 0 : dirname = PyBytes_AsString(dirname_bytes);
732 : : } else {
733 : 0 : dirname_bytes = NULL;
734 : 0 : dirname = NULL;
735 : : }
736 : 0 : current_dirname = bindtextdomain(domain, dirname);
737 [ # # ]: 0 : if (current_dirname == NULL) {
738 : 0 : Py_XDECREF(dirname_bytes);
739 : 0 : PyErr_SetFromErrno(PyExc_OSError);
740 : 0 : return NULL;
741 : : }
742 : 0 : result = PyUnicode_DecodeLocale(current_dirname, NULL);
743 : 0 : Py_XDECREF(dirname_bytes);
744 : 0 : 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 *
760 : 0 : _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 : 0 : codeset = bind_textdomain_codeset(domain, codeset);
765 [ # # ]: 0 : if (codeset) {
766 : 0 : return PyUnicode_DecodeLocale(codeset, NULL);
767 : : }
768 : 0 : Py_RETURN_NONE;
769 : : }
770 : : #endif // HAVE_BIND_TEXTDOMAIN_CODESET
771 : :
772 : : #endif // HAVE_LIBINTL_H
773 : :
774 : :
775 : : /*[clinic input]
776 : : _locale.getencoding
777 : :
778 : : Get the current locale encoding.
779 : : [clinic start generated code]*/
780 : :
781 : : static PyObject *
782 : 856 : _locale_getencoding_impl(PyObject *module)
783 : : /*[clinic end generated code: output=86b326b971872e46 input=6503d11e5958b360]*/
784 : : {
785 : 856 : 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_GETENCODING_METHODDEF
815 : : {NULL, NULL}
816 : : };
817 : :
818 : : static int
819 : 1562 : _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 [ - + ]: 1562 : ADD_INT(module, LC_CTYPE);
832 [ - + ]: 1562 : ADD_INT(module, LC_TIME);
833 [ - + ]: 1562 : ADD_INT(module, LC_COLLATE);
834 [ - + ]: 1562 : ADD_INT(module, LC_MONETARY);
835 : :
836 : : #ifdef LC_MESSAGES
837 [ - + ]: 1562 : ADD_INT(module, LC_MESSAGES);
838 : : #endif /* LC_MESSAGES */
839 : :
840 [ - + ]: 1562 : ADD_INT(module, LC_NUMERIC);
841 [ - + ]: 1562 : ADD_INT(module, LC_ALL);
842 [ - + ]: 1562 : ADD_INT(module, CHAR_MAX);
843 : :
844 : 1562 : _locale_state *state = get_locale_state(module);
845 : 1562 : state->Error = PyErr_NewException("locale.Error", NULL, NULL);
846 [ - + ]: 1562 : if (state->Error == NULL) {
847 : 0 : return -1;
848 : : }
849 : 1562 : Py_INCREF(get_locale_state(module)->Error);
850 [ - + ]: 1562 : if (PyModule_AddObject(module, "Error", get_locale_state(module)->Error) < 0) {
851 : 0 : Py_DECREF(get_locale_state(module)->Error);
852 : 0 : return -1;
853 : : }
854 : :
855 : : #ifdef HAVE_LANGINFO_H
856 [ + + ]: 89034 : for (i = 0; langinfo_constants[i].name; i++) {
857 [ - + ]: 87472 : if (PyModule_AddIntConstant(module,
858 : 87472 : langinfo_constants[i].name,
859 : 87472 : langinfo_constants[i].value) < 0) {
860 : 0 : return -1;
861 : : }
862 : : }
863 : : #endif
864 : :
865 [ - + ]: 1562 : if (PyErr_Occurred()) {
866 : 0 : return -1;
867 : : }
868 : 1562 : 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
879 : 39917 : locale_traverse(PyObject *module, visitproc visit, void *arg)
880 : : {
881 : 39917 : _locale_state *state = get_locale_state(module);
882 [ + - - + ]: 39917 : Py_VISIT(state->Error);
883 : 39917 : return 0;
884 : : }
885 : :
886 : : static int
887 : 2519 : locale_clear(PyObject *module)
888 : : {
889 : 2519 : _locale_state *state = get_locale_state(module);
890 [ + + ]: 2519 : Py_CLEAR(state->Error);
891 : 2519 : return 0;
892 : : }
893 : :
894 : : static void
895 : 1562 : locale_free(PyObject *module)
896 : : {
897 : 1562 : locale_clear(module);
898 : 1562 : }
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
913 : 1562 : PyInit__locale(void)
914 : : {
915 : 1562 : return PyModuleDef_Init(&_localemodule);
916 : : }
917 : :
918 : : /*
919 : : Local variables:
920 : : c-basic-offset: 4
921 : : indent-tabs-mode: nil
922 : : End:
923 : : */
|