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