blob: 7e2f1a997be68fcb5489e3381b4869ceb0b6c1dc [file] [log] [blame]
Guido van Rossum220ecc81997-11-18 21:03:39 +00001/***********************************************************
Martin v. Löwis25f90d52003-09-03 04:50:13 +00002Copyright (C) 1997, 2002, 2003 Martin von Loewis
Guido van Rossum220ecc81997-11-18 21:03:39 +00003
4Permission to use, copy, modify, and distribute this software and its
5documentation for any purpose and without fee is hereby granted,
6provided that the above copyright notice appear in all copies.
7
8This software comes with no warranty. Use at your own risk.
Fredrik Lundh8f017a02000-07-08 19:57:37 +00009
Guido van Rossum220ecc81997-11-18 21:03:39 +000010******************************************************************/
11
Fred Drake68933b92000-08-10 21:41:08 +000012#include "Python.h"
13
Guido van Rossum220ecc81997-11-18 21:03:39 +000014#include <stdio.h>
Guido van Rossum220ecc81997-11-18 21:03:39 +000015#include <locale.h>
16#include <string.h>
Guido van Rossum5cd70f41998-06-19 04:33:30 +000017#include <ctype.h>
Fredrik Lundh8f017a02000-07-08 19:57:37 +000018
Martin v. Löwis0e8bd7e2006-06-10 12:23:46 +000019#ifdef HAVE_ERRNO_H
Martin v. Löwisa43190b2006-05-22 09:15:18 +000020#include <errno.h>
21#endif
22
Martin v. Löwis9b75dca2001-08-10 13:58:50 +000023#ifdef HAVE_LANGINFO_H
24#include <langinfo.h>
25#endif
26
Martin v. Löwis2e64c342002-03-27 18:49:02 +000027#ifdef HAVE_LIBINTL_H
28#include <libintl.h>
29#endif
30
Martin v. Löwis9c36c292002-12-21 18:34:06 +000031#ifdef HAVE_WCHAR_H
32#include <wchar.h>
33#endif
34
Martin v. Löwis6238d2b2002-06-30 15:26:10 +000035#if defined(MS_WINDOWS)
Tim Peters7a1f9172002-07-14 22:14:19 +000036#define WIN32_LEAN_AND_MEAN
Fredrik Lundh8f017a02000-07-08 19:57:37 +000037#include <windows.h>
Guido van Rossum239a2181998-04-28 16:08:19 +000038#endif
Guido van Rossum220ecc81997-11-18 21:03:39 +000039
Guido van Rossum1ca8bb32001-03-02 06:28:17 +000040#ifdef RISCOS
41char *strdup(const char *);
42#endif
43
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000044PyDoc_STRVAR(locale__doc__, "Support for POSIX locales.");
Guido van Rossum220ecc81997-11-18 21:03:39 +000045
46static PyObject *Error;
47
48/* support functions for formatting floating point numbers */
49
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000050PyDoc_STRVAR(setlocale__doc__,
51"(integer,string=None) -> string. Activates/queries locale processing.");
Guido van Rossum220ecc81997-11-18 21:03:39 +000052
Guido van Rossum220ecc81997-11-18 21:03:39 +000053/* the grouping is terminated by either 0 or CHAR_MAX */
54static PyObject*
Fredrik Lundh8f017a02000-07-08 19:57:37 +000055copy_grouping(char* s)
Guido van Rossum220ecc81997-11-18 21:03:39 +000056{
Fredrik Lundh8f017a02000-07-08 19:57:37 +000057 int i;
58 PyObject *result, *val = NULL;
59
Martin Panterca56dd42016-09-17 07:54:55 +000060 if (s[0] == '\0') {
61 /* empty string: no grouping at all */
62 return PyList_New(0);
63 }
Fredrik Lundh8f017a02000-07-08 19:57:37 +000064
65 for (i = 0; s[i] != '\0' && s[i] != CHAR_MAX; i++)
66 ; /* nothing */
67
68 result = PyList_New(i+1);
69 if (!result)
70 return NULL;
71
72 i = -1;
73 do {
74 i++;
75 val = PyInt_FromLong(s[i]);
76 if (!val)
77 break;
78 if (PyList_SetItem(result, i, val)) {
79 Py_DECREF(val);
Fredrik Lundh89610a42000-07-08 20:07:24 +000080 val = NULL;
Fredrik Lundh8f017a02000-07-08 19:57:37 +000081 break;
82 }
83 } while (s[i] != '\0' && s[i] != CHAR_MAX);
84
85 if (!val) {
86 Py_DECREF(result);
87 return NULL;
Guido van Rossum220ecc81997-11-18 21:03:39 +000088 }
Fredrik Lundh8f017a02000-07-08 19:57:37 +000089
90 return result;
Guido van Rossum220ecc81997-11-18 21:03:39 +000091}
92
93static void
Fredrik Lundh8f017a02000-07-08 19:57:37 +000094fixup_ulcase(void)
Guido van Rossum220ecc81997-11-18 21:03:39 +000095{
Fredrik Lundh8f017a02000-07-08 19:57:37 +000096 PyObject *mods, *strop, *string, *ulo;
97 unsigned char ul[256];
98 int n, c;
Guido van Rossum220ecc81997-11-18 21:03:39 +000099
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000100 /* find the string and strop modules */
101 mods = PyImport_GetModuleDict();
102 if (!mods)
103 return;
104 string = PyDict_GetItemString(mods, "string");
105 if (string)
106 string = PyModule_GetDict(string);
107 strop=PyDict_GetItemString(mods, "strop");
108 if (strop)
109 strop = PyModule_GetDict(strop);
110 if (!string && !strop)
111 return;
112
113 /* create uppercase map string */
114 n = 0;
115 for (c = 0; c < 256; c++) {
116 if (isupper(c))
117 ul[n++] = c;
118 }
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000119 ulo = PyString_FromStringAndSize((const char *)ul, n);
Fredrik Lundh89610a42000-07-08 20:07:24 +0000120 if (!ulo)
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000121 return;
122 if (string)
123 PyDict_SetItemString(string, "uppercase", ulo);
124 if (strop)
125 PyDict_SetItemString(strop, "uppercase", ulo);
126 Py_DECREF(ulo);
127
128 /* create lowercase string */
129 n = 0;
130 for (c = 0; c < 256; c++) {
131 if (islower(c))
132 ul[n++] = c;
133 }
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000134 ulo = PyString_FromStringAndSize((const char *)ul, n);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000135 if (!ulo)
136 return;
137 if (string)
138 PyDict_SetItemString(string, "lowercase", ulo);
139 if (strop)
140 PyDict_SetItemString(strop, "lowercase", ulo);
141 Py_DECREF(ulo);
142
143 /* create letters string */
144 n = 0;
145 for (c = 0; c < 256; c++) {
146 if (isalpha(c))
147 ul[n++] = c;
148 }
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000149 ulo = PyString_FromStringAndSize((const char *)ul, n);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000150 if (!ulo)
151 return;
152 if (string)
153 PyDict_SetItemString(string, "letters", ulo);
154 Py_DECREF(ulo);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000155}
Martin v. Löwis7c82a3e02001-09-05 17:09:48 +0000156
Guido van Rossum220ecc81997-11-18 21:03:39 +0000157static PyObject*
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000158PyLocale_setlocale(PyObject* self, PyObject* args)
Guido van Rossum220ecc81997-11-18 21:03:39 +0000159{
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000160 int category;
161 char *locale = NULL, *result;
162 PyObject *result_object;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000163
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000164 if (!PyArg_ParseTuple(args, "i|z:setlocale", &category, &locale))
Fredrik Lundh89610a42000-07-08 20:07:24 +0000165 return NULL;
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000166
Amaury Forgeot d'Arcd7288712009-12-01 21:51:04 +0000167#if defined(MS_WINDOWS)
168 if (category < LC_MIN || category > LC_MAX)
169 {
170 PyErr_SetString(Error, "invalid locale category");
171 return NULL;
172 }
173#endif
174
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000175 if (locale) {
Benjamin Petersone4668aa2016-09-13 21:48:57 -0700176 /* set locale */
177 result = setlocale(category, locale);
178 if (!result) {
179 /* operation failed, no setting was changed */
180 PyErr_SetString(Error, "unsupported locale setting");
181 return NULL;
182 }
183 result_object = PyString_FromString(result);
184 if (!result_object)
185 return NULL;
186 /* record changes to LC_CTYPE */
187 if (category == LC_CTYPE || category == LC_ALL)
188 fixup_ulcase();
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000189 /* things that got wrong up to here are ignored */
190 PyErr_Clear();
191 } else {
Benjamin Petersone4668aa2016-09-13 21:48:57 -0700192 /* get locale */
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000193 result = setlocale(category, NULL);
194 if (!result) {
195 PyErr_SetString(Error, "locale query failed");
196 return NULL;
197 }
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000198 result_object = PyString_FromString(result);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000199 }
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000200 return result_object;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000201}
202
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000203PyDoc_STRVAR(localeconv__doc__,
204"() -> dict. Returns numeric and monetary locale-specific parameters.");
Guido van Rossum220ecc81997-11-18 21:03:39 +0000205
206static PyObject*
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000207PyLocale_localeconv(PyObject* self)
Guido van Rossum220ecc81997-11-18 21:03:39 +0000208{
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000209 PyObject* result;
210 struct lconv *l;
211 PyObject *x;
212
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000213 result = PyDict_New();
Fredrik Lundh89610a42000-07-08 20:07:24 +0000214 if (!result)
215 return NULL;
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000216
217 /* if LC_NUMERIC is different in the C library, use saved value */
218 l = localeconv();
219
220 /* hopefully, the localeconv result survives the C library calls
221 involved herein */
222
223#define RESULT_STRING(s)\
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000224 x = PyString_FromString(l->s);\
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000225 if (!x) goto failed;\
226 PyDict_SetItemString(result, #s, x);\
227 Py_XDECREF(x)
228
229#define RESULT_INT(i)\
230 x = PyInt_FromLong(l->i);\
231 if (!x) goto failed;\
232 PyDict_SetItemString(result, #i, x);\
233 Py_XDECREF(x)
Guido van Rossum220ecc81997-11-18 21:03:39 +0000234
235 /* Numeric information */
Martin v. Löwis737ea822004-06-08 18:52:54 +0000236 RESULT_STRING(decimal_point);
237 RESULT_STRING(thousands_sep);
238 x = copy_grouping(l->grouping);
239 if (!x)
240 goto failed;
241 PyDict_SetItemString(result, "grouping", x);
242 Py_XDECREF(x);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000243
244 /* Monetary information */
245 RESULT_STRING(int_curr_symbol);
246 RESULT_STRING(currency_symbol);
247 RESULT_STRING(mon_decimal_point);
248 RESULT_STRING(mon_thousands_sep);
249 x = copy_grouping(l->mon_grouping);
250 if (!x)
251 goto failed;
252 PyDict_SetItemString(result, "mon_grouping", x);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000253 Py_XDECREF(x);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000254 RESULT_STRING(positive_sign);
255 RESULT_STRING(negative_sign);
256 RESULT_INT(int_frac_digits);
257 RESULT_INT(frac_digits);
258 RESULT_INT(p_cs_precedes);
259 RESULT_INT(p_sep_by_space);
260 RESULT_INT(n_cs_precedes);
261 RESULT_INT(n_sep_by_space);
262 RESULT_INT(p_sign_posn);
263 RESULT_INT(n_sign_posn);
264 return result;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000265
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000266 failed:
267 Py_XDECREF(result);
268 Py_XDECREF(x);
269 return NULL;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000270}
271
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000272PyDoc_STRVAR(strcoll__doc__,
273"string,string -> int. Compares two strings according to the locale.");
Guido van Rossum220ecc81997-11-18 21:03:39 +0000274
275static PyObject*
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000276PyLocale_strcoll(PyObject* self, PyObject* args)
Guido van Rossum220ecc81997-11-18 21:03:39 +0000277{
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000278#if !defined(HAVE_WCSCOLL) || !defined(Py_USING_UNICODE)
279 char *s1,*s2;
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000280
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000281 if (!PyArg_ParseTuple(args, "ss:strcoll", &s1, &s2))
282 return NULL;
283 return PyInt_FromLong(strcoll(s1, s2));
284#else
285 PyObject *os1, *os2, *result = NULL;
286 wchar_t *ws1 = NULL, *ws2 = NULL;
287 int rel1 = 0, rel2 = 0, len1, len2;
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000288
Georg Brandl96a8c392006-05-29 21:04:52 +0000289 if (!PyArg_UnpackTuple(args, "strcoll", 2, 2, &os1, &os2))
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000290 return NULL;
291 /* If both arguments are byte strings, use strcoll. */
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000292 if (PyString_Check(os1) && PyString_Check(os2))
293 return PyInt_FromLong(strcoll(PyString_AS_STRING(os1),
294 PyString_AS_STRING(os2)));
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000295 /* If neither argument is unicode, it's an error. */
296 if (!PyUnicode_Check(os1) && !PyUnicode_Check(os2)) {
297 PyErr_SetString(PyExc_ValueError, "strcoll arguments must be strings");
298 }
299 /* Convert the non-unicode argument to unicode. */
300 if (!PyUnicode_Check(os1)) {
Benjamin Petersone4668aa2016-09-13 21:48:57 -0700301 os1 = PyUnicode_FromObject(os1);
302 if (!os1)
303 return NULL;
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000304 rel1 = 1;
305 }
306 if (!PyUnicode_Check(os2)) {
307 os2 = PyUnicode_FromObject(os2);
308 if (!os2) {
Georg Brandl278fc502008-07-19 12:46:12 +0000309 if (rel1) {
310 Py_DECREF(os1);
311 }
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000312 return NULL;
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000313 }
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000314 rel2 = 1;
315 }
316 /* Convert the unicode strings to wchar[]. */
317 len1 = PyUnicode_GET_SIZE(os1) + 1;
Serhiy Storchakaa2269d02015-02-16 13:16:07 +0200318 ws1 = PyMem_NEW(wchar_t, len1);
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000319 if (!ws1) {
320 PyErr_NoMemory();
321 goto done;
322 }
323 if (PyUnicode_AsWideChar((PyUnicodeObject*)os1, ws1, len1) == -1)
324 goto done;
Marc-André Lemburga9cadcd2004-11-22 13:02:31 +0000325 ws1[len1 - 1] = 0;
326 len2 = PyUnicode_GET_SIZE(os2) + 1;
Serhiy Storchakaa2269d02015-02-16 13:16:07 +0200327 ws2 = PyMem_NEW(wchar_t, len2);
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000328 if (!ws2) {
329 PyErr_NoMemory();
330 goto done;
331 }
332 if (PyUnicode_AsWideChar((PyUnicodeObject*)os2, ws2, len2) == -1)
333 goto done;
Marc-André Lemburga9cadcd2004-11-22 13:02:31 +0000334 ws2[len2 - 1] = 0;
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000335 /* Collate the strings. */
336 result = PyInt_FromLong(wcscoll(ws1, ws2));
337 done:
338 /* Deallocate everything. */
339 if (ws1) PyMem_FREE(ws1);
340 if (ws2) PyMem_FREE(ws2);
341 if (rel1) {
342 Py_DECREF(os1);
343 }
344 if (rel2) {
345 Py_DECREF(os2);
346 }
347 return result;
348#endif
Guido van Rossum220ecc81997-11-18 21:03:39 +0000349}
350
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000351
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000352PyDoc_STRVAR(strxfrm__doc__,
353"string -> string. Returns a string that behaves for cmp locale-aware.");
Guido van Rossum220ecc81997-11-18 21:03:39 +0000354
355static PyObject*
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000356PyLocale_strxfrm(PyObject* self, PyObject* args)
Guido van Rossum220ecc81997-11-18 21:03:39 +0000357{
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000358 char *s, *buf;
359 size_t n1, n2;
360 PyObject *result;
361
Fredrik Lundh89610a42000-07-08 20:07:24 +0000362 if (!PyArg_ParseTuple(args, "s:strxfrm", &s))
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000363 return NULL;
364
365 /* assume no change in size, first */
366 n1 = strlen(s) + 1;
367 buf = PyMem_Malloc(n1);
368 if (!buf)
369 return PyErr_NoMemory();
Matthias Klosee19e0c22007-04-03 04:35:59 +0000370 n2 = strxfrm(buf, s, n1) + 1;
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000371 if (n2 > n1) {
372 /* more space needed */
373 buf = PyMem_Realloc(buf, n2);
374 if (!buf)
375 return PyErr_NoMemory();
376 strxfrm(buf, s, n2);
377 }
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000378 result = PyString_FromString(buf);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000379 PyMem_Free(buf);
380 return result;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000381}
382
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000383#if defined(MS_WINDOWS)
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000384static PyObject*
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000385PyLocale_getdefaultlocale(PyObject* self)
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000386{
387 char encoding[100];
388 char locale[100];
389
Tim Peters885d4572001-11-28 20:27:42 +0000390 PyOS_snprintf(encoding, sizeof(encoding), "cp%d", GetACP());
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000391
392 if (GetLocaleInfo(LOCALE_USER_DEFAULT,
393 LOCALE_SISO639LANGNAME,
394 locale, sizeof(locale))) {
Martin v. Löwis18e16552006-02-15 17:27:45 +0000395 Py_ssize_t i = strlen(locale);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000396 locale[i++] = '_';
397 if (GetLocaleInfo(LOCALE_USER_DEFAULT,
398 LOCALE_SISO3166CTRYNAME,
Martin v. Löwis18e16552006-02-15 17:27:45 +0000399 locale+i, (int)(sizeof(locale)-i)))
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000400 return Py_BuildValue("ss", locale, encoding);
401 }
402
403 /* If we end up here, this windows version didn't know about
404 ISO639/ISO3166 names (it's probably Windows 95). Return the
405 Windows language identifier instead (a hexadecimal number) */
406
407 locale[0] = '0';
408 locale[1] = 'x';
409 if (GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_IDEFAULTLANGUAGE,
410 locale+2, sizeof(locale)-2)) {
411 return Py_BuildValue("ss", locale, encoding);
412 }
413
414 /* cannot determine the language code (very unlikely) */
415 Py_INCREF(Py_None);
416 return Py_BuildValue("Os", Py_None, encoding);
417}
418#endif
419
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000420#ifdef HAVE_LANGINFO_H
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000421#define LANGINFO(X) {#X, X}
Martin v. Löwis111c1802008-06-13 07:47:47 +0000422static struct langinfo_constant{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000423 char* name;
424 int value;
425} langinfo_constants[] =
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000426{
427 /* These constants should exist on any langinfo implementation */
428 LANGINFO(DAY_1),
429 LANGINFO(DAY_2),
430 LANGINFO(DAY_3),
431 LANGINFO(DAY_4),
432 LANGINFO(DAY_5),
433 LANGINFO(DAY_6),
434 LANGINFO(DAY_7),
435
436 LANGINFO(ABDAY_1),
437 LANGINFO(ABDAY_2),
438 LANGINFO(ABDAY_3),
439 LANGINFO(ABDAY_4),
440 LANGINFO(ABDAY_5),
441 LANGINFO(ABDAY_6),
442 LANGINFO(ABDAY_7),
443
444 LANGINFO(MON_1),
445 LANGINFO(MON_2),
446 LANGINFO(MON_3),
447 LANGINFO(MON_4),
448 LANGINFO(MON_5),
449 LANGINFO(MON_6),
450 LANGINFO(MON_7),
451 LANGINFO(MON_8),
452 LANGINFO(MON_9),
453 LANGINFO(MON_10),
454 LANGINFO(MON_11),
455 LANGINFO(MON_12),
456
457 LANGINFO(ABMON_1),
458 LANGINFO(ABMON_2),
459 LANGINFO(ABMON_3),
460 LANGINFO(ABMON_4),
461 LANGINFO(ABMON_5),
462 LANGINFO(ABMON_6),
463 LANGINFO(ABMON_7),
464 LANGINFO(ABMON_8),
465 LANGINFO(ABMON_9),
466 LANGINFO(ABMON_10),
467 LANGINFO(ABMON_11),
468 LANGINFO(ABMON_12),
469
470#ifdef RADIXCHAR
471 /* The following are not available with glibc 2.0 */
472 LANGINFO(RADIXCHAR),
473 LANGINFO(THOUSEP),
474 /* YESSTR and NOSTR are deprecated in glibc, since they are
475 a special case of message translation, which should be rather
476 done using gettext. So we don't expose it to Python in the
477 first place.
478 LANGINFO(YESSTR),
479 LANGINFO(NOSTR),
480 */
481 LANGINFO(CRNCYSTR),
482#endif
483
484 LANGINFO(D_T_FMT),
485 LANGINFO(D_FMT),
486 LANGINFO(T_FMT),
487 LANGINFO(AM_STR),
488 LANGINFO(PM_STR),
489
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000490 /* The following constants are available only with XPG4, but...
491 AIX 3.2. only has CODESET.
492 OpenBSD doesn't have CODESET but has T_FMT_AMPM, and doesn't have
493 a few of the others.
494 Solution: ifdef-test them all. */
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000495#ifdef CODESET
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000496 LANGINFO(CODESET),
Martin v. Löwis496f9e42002-03-27 12:15:57 +0000497#endif
498#ifdef T_FMT_AMPM
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000499 LANGINFO(T_FMT_AMPM),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000500#endif
501#ifdef ERA
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000502 LANGINFO(ERA),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000503#endif
504#ifdef ERA_D_FMT
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000505 LANGINFO(ERA_D_FMT),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000506#endif
507#ifdef ERA_D_T_FMT
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000508 LANGINFO(ERA_D_T_FMT),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000509#endif
510#ifdef ERA_T_FMT
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000511 LANGINFO(ERA_T_FMT),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000512#endif
513#ifdef ALT_DIGITS
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000514 LANGINFO(ALT_DIGITS),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000515#endif
516#ifdef YESEXPR
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000517 LANGINFO(YESEXPR),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000518#endif
519#ifdef NOEXPR
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000520 LANGINFO(NOEXPR),
521#endif
522#ifdef _DATE_FMT
523 /* This is not available in all glibc versions that have CODESET. */
524 LANGINFO(_DATE_FMT),
525#endif
526 {0, 0}
527};
528
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000529PyDoc_STRVAR(nl_langinfo__doc__,
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000530"nl_langinfo(key) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000531"Return the value for the locale information associated with key.");
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000532
533static PyObject*
534PyLocale_nl_langinfo(PyObject* self, PyObject* args)
535{
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000536 int item, i;
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000537 if (!PyArg_ParseTuple(args, "i:nl_langinfo", &item))
Martin Panterca56dd42016-09-17 07:54:55 +0000538 return NULL;
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000539 /* Check whether this is a supported constant. GNU libc sometimes
540 returns numeric values in the char* return value, which would
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000541 crash PyString_FromString. */
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000542 for (i = 0; langinfo_constants[i].name; i++)
Hye-Shik Changc3a87b82004-03-21 19:34:30 +0000543 if (langinfo_constants[i].value == item) {
544 /* Check NULL as a workaround for GNU libc's returning NULL
545 instead of an empty string for nl_langinfo(ERA). */
546 const char *result = nl_langinfo(item);
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000547 return PyString_FromString(result != NULL ? result : "");
Hye-Shik Changc3a87b82004-03-21 19:34:30 +0000548 }
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000549 PyErr_SetString(PyExc_ValueError, "unsupported langinfo constant");
550 return NULL;
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000551}
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000552#endif /* HAVE_LANGINFO_H */
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000553
554#ifdef HAVE_LIBINTL_H
555
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000556PyDoc_STRVAR(gettext__doc__,
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000557"gettext(msg) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000558"Return translation of msg.");
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000559
560static PyObject*
561PyIntl_gettext(PyObject* self, PyObject *args)
562{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000563 char *in;
564 if (!PyArg_ParseTuple(args, "s", &in))
565 return 0;
566 return PyString_FromString(gettext(in));
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000567}
568
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000569PyDoc_STRVAR(dgettext__doc__,
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000570"dgettext(domain, msg) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000571"Return translation of msg in domain.");
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000572
573static PyObject*
574PyIntl_dgettext(PyObject* self, PyObject *args)
575{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000576 char *domain, *in;
577 if (!PyArg_ParseTuple(args, "zs", &domain, &in))
578 return 0;
579 return PyString_FromString(dgettext(domain, in));
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000580}
581
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000582PyDoc_STRVAR(dcgettext__doc__,
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000583"dcgettext(domain, msg, category) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000584"Return translation of msg in domain and category.");
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000585
586static PyObject*
587PyIntl_dcgettext(PyObject *self, PyObject *args)
588{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000589 char *domain, *msgid;
590 int category;
591 if (!PyArg_ParseTuple(args, "zsi", &domain, &msgid, &category))
592 return 0;
593 return PyString_FromString(dcgettext(domain,msgid,category));
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000594}
595
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000596PyDoc_STRVAR(textdomain__doc__,
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000597"textdomain(domain) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000598"Set the C library's textdmain to domain, returning the new domain.");
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000599
600static PyObject*
601PyIntl_textdomain(PyObject* self, PyObject* args)
602{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000603 char *domain;
604 if (!PyArg_ParseTuple(args, "z", &domain))
605 return 0;
606 domain = textdomain(domain);
607 if (!domain) {
608 PyErr_SetFromErrno(PyExc_OSError);
609 return NULL;
610 }
611 return PyString_FromString(domain);
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000612}
613
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000614PyDoc_STRVAR(bindtextdomain__doc__,
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000615"bindtextdomain(domain, dir) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000616"Bind the C library's domain to dir.");
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000617
618static PyObject*
619PyIntl_bindtextdomain(PyObject* self,PyObject*args)
620{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000621 char *domain, *dirname;
622 if (!PyArg_ParseTuple(args, "sz", &domain, &dirname))
623 return 0;
624 if (!strlen(domain)) {
625 PyErr_SetString(Error, "domain must be a non-empty string");
626 return 0;
627 }
628 dirname = bindtextdomain(domain, dirname);
629 if (!dirname) {
630 PyErr_SetFromErrno(PyExc_OSError);
631 return NULL;
632 }
633 return PyString_FromString(dirname);
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000634}
635
Gustavo Niemeyer7bd33c52004-07-22 18:44:01 +0000636#ifdef HAVE_BIND_TEXTDOMAIN_CODESET
637PyDoc_STRVAR(bind_textdomain_codeset__doc__,
638"bind_textdomain_codeset(domain, codeset) -> string\n"
639"Bind the C library's domain to codeset.");
640
641static PyObject*
642PyIntl_bind_textdomain_codeset(PyObject* self,PyObject*args)
643{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000644 char *domain,*codeset;
645 if (!PyArg_ParseTuple(args, "sz", &domain, &codeset))
646 return NULL;
647 codeset = bind_textdomain_codeset(domain, codeset);
648 if (codeset)
649 return PyString_FromString(codeset);
650 Py_RETURN_NONE;
Gustavo Niemeyer7bd33c52004-07-22 18:44:01 +0000651}
652#endif
653
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000654#endif
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000655
Guido van Rossum220ecc81997-11-18 21:03:39 +0000656static struct PyMethodDef PyLocale_Methods[] = {
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000657 {"setlocale", (PyCFunction) PyLocale_setlocale,
Andrew M. Kuchlinge365fb82000-08-03 02:06:16 +0000658 METH_VARARGS, setlocale__doc__},
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000659 {"localeconv", (PyCFunction) PyLocale_localeconv,
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000660 METH_NOARGS, localeconv__doc__},
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000661 {"strcoll", (PyCFunction) PyLocale_strcoll,
Andrew M. Kuchlinge365fb82000-08-03 02:06:16 +0000662 METH_VARARGS, strcoll__doc__},
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000663 {"strxfrm", (PyCFunction) PyLocale_strxfrm,
Andrew M. Kuchlinge365fb82000-08-03 02:06:16 +0000664 METH_VARARGS, strxfrm__doc__},
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000665#if defined(MS_WINDOWS)
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000666 {"_getdefaultlocale", (PyCFunction) PyLocale_getdefaultlocale, METH_NOARGS},
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000667#endif
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000668#ifdef HAVE_LANGINFO_H
669 {"nl_langinfo", (PyCFunction) PyLocale_nl_langinfo,
670 METH_VARARGS, nl_langinfo__doc__},
671#endif
Martin v. Löwisc6a7d7e2002-05-02 12:16:29 +0000672#ifdef HAVE_LIBINTL_H
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000673 {"gettext",(PyCFunction)PyIntl_gettext,METH_VARARGS,
674 gettext__doc__},
675 {"dgettext",(PyCFunction)PyIntl_dgettext,METH_VARARGS,
676 dgettext__doc__},
677 {"dcgettext",(PyCFunction)PyIntl_dcgettext,METH_VARARGS,
678 dcgettext__doc__},
679 {"textdomain",(PyCFunction)PyIntl_textdomain,METH_VARARGS,
680 textdomain__doc__},
681 {"bindtextdomain",(PyCFunction)PyIntl_bindtextdomain,METH_VARARGS,
682 bindtextdomain__doc__},
Gustavo Niemeyer7bd33c52004-07-22 18:44:01 +0000683#ifdef HAVE_BIND_TEXTDOMAIN_CODESET
684 {"bind_textdomain_codeset",(PyCFunction)PyIntl_bind_textdomain_codeset,
685 METH_VARARGS, bind_textdomain_codeset__doc__},
686#endif
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000687#endif
Guido van Rossum220ecc81997-11-18 21:03:39 +0000688 {NULL, NULL}
689};
690
Mark Hammondfe51c6d2002-08-02 02:27:13 +0000691PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000692init_locale(void)
Guido van Rossum220ecc81997-11-18 21:03:39 +0000693{
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000694 PyObject *m, *d, *x;
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000695#ifdef HAVE_LANGINFO_H
696 int i;
697#endif
Guido van Rossum220ecc81997-11-18 21:03:39 +0000698
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000699 m = Py_InitModule("_locale", PyLocale_Methods);
Neal Norwitz1ac754f2006-01-19 06:09:39 +0000700 if (m == NULL)
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000701 return;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000702
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000703 d = PyModule_GetDict(m);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000704
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000705 x = PyInt_FromLong(LC_CTYPE);
706 PyDict_SetItemString(d, "LC_CTYPE", x);
707 Py_XDECREF(x);
708
709 x = PyInt_FromLong(LC_TIME);
710 PyDict_SetItemString(d, "LC_TIME", x);
711 Py_XDECREF(x);
712
713 x = PyInt_FromLong(LC_COLLATE);
714 PyDict_SetItemString(d, "LC_COLLATE", x);
715 Py_XDECREF(x);
716
717 x = PyInt_FromLong(LC_MONETARY);
718 PyDict_SetItemString(d, "LC_MONETARY", x);
719 Py_XDECREF(x);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000720
Guido van Rossum8d9c2e31997-12-09 19:35:11 +0000721#ifdef LC_MESSAGES
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000722 x = PyInt_FromLong(LC_MESSAGES);
723 PyDict_SetItemString(d, "LC_MESSAGES", x);
724 Py_XDECREF(x);
Guido van Rossum8d9c2e31997-12-09 19:35:11 +0000725#endif /* LC_MESSAGES */
Guido van Rossum220ecc81997-11-18 21:03:39 +0000726
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000727 x = PyInt_FromLong(LC_NUMERIC);
728 PyDict_SetItemString(d, "LC_NUMERIC", x);
729 Py_XDECREF(x);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000730
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000731 x = PyInt_FromLong(LC_ALL);
732 PyDict_SetItemString(d, "LC_ALL", x);
733 Py_XDECREF(x);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000734
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000735 x = PyInt_FromLong(CHAR_MAX);
736 PyDict_SetItemString(d, "CHAR_MAX", x);
737 Py_XDECREF(x);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000738
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000739 Error = PyErr_NewException("locale.Error", NULL, NULL);
740 PyDict_SetItemString(d, "Error", Error);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000741
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000742 x = PyString_FromString(locale__doc__);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000743 PyDict_SetItemString(d, "__doc__", x);
744 Py_XDECREF(x);
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000745
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000746#ifdef HAVE_LANGINFO_H
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000747 for (i = 0; langinfo_constants[i].name; i++) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000748 PyModule_AddIntConstant(m, langinfo_constants[i].name,
749 langinfo_constants[i].value);
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000750 }
Martin v. Löwisf95dd0a2001-08-15 17:14:33 +0000751#endif
Guido van Rossum220ecc81997-11-18 21:03:39 +0000752}
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000753
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000754/*
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000755Local variables:
756c-basic-offset: 4
757indent-tabs-mode: nil
758End:
759*/