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