blob: 94d0014bbc09b30b89910b74173821f42b92879b [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
60 if (s[0] == '\0')
61 /* empty string: no grouping at all */
62 return PyList_New(0);
63
64 for (i = 0; s[i] != '\0' && s[i] != CHAR_MAX; i++)
65 ; /* nothing */
66
67 result = PyList_New(i+1);
68 if (!result)
69 return NULL;
70
71 i = -1;
72 do {
73 i++;
74 val = PyInt_FromLong(s[i]);
75 if (!val)
76 break;
77 if (PyList_SetItem(result, i, val)) {
78 Py_DECREF(val);
Fredrik Lundh89610a42000-07-08 20:07:24 +000079 val = NULL;
Fredrik Lundh8f017a02000-07-08 19:57:37 +000080 break;
81 }
82 } while (s[i] != '\0' && s[i] != CHAR_MAX);
83
84 if (!val) {
85 Py_DECREF(result);
86 return NULL;
Guido van Rossum220ecc81997-11-18 21:03:39 +000087 }
Fredrik Lundh8f017a02000-07-08 19:57:37 +000088
89 return result;
Guido van Rossum220ecc81997-11-18 21:03:39 +000090}
91
92static void
Fredrik Lundh8f017a02000-07-08 19:57:37 +000093fixup_ulcase(void)
Guido van Rossum220ecc81997-11-18 21:03:39 +000094{
Fredrik Lundh8f017a02000-07-08 19:57:37 +000095 PyObject *mods, *strop, *string, *ulo;
96 unsigned char ul[256];
97 int n, c;
Guido van Rossum220ecc81997-11-18 21:03:39 +000098
Fredrik Lundh8f017a02000-07-08 19:57:37 +000099 /* find the string and strop modules */
100 mods = PyImport_GetModuleDict();
101 if (!mods)
102 return;
103 string = PyDict_GetItemString(mods, "string");
104 if (string)
105 string = PyModule_GetDict(string);
106 strop=PyDict_GetItemString(mods, "strop");
107 if (strop)
108 strop = PyModule_GetDict(strop);
109 if (!string && !strop)
110 return;
111
112 /* create uppercase map string */
113 n = 0;
114 for (c = 0; c < 256; c++) {
115 if (isupper(c))
116 ul[n++] = c;
117 }
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000118 ulo = PyString_FromStringAndSize((const char *)ul, n);
Fredrik Lundh89610a42000-07-08 20:07:24 +0000119 if (!ulo)
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000120 return;
121 if (string)
122 PyDict_SetItemString(string, "uppercase", ulo);
123 if (strop)
124 PyDict_SetItemString(strop, "uppercase", ulo);
125 Py_DECREF(ulo);
126
127 /* create lowercase string */
128 n = 0;
129 for (c = 0; c < 256; c++) {
130 if (islower(c))
131 ul[n++] = c;
132 }
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000133 ulo = PyString_FromStringAndSize((const char *)ul, n);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000134 if (!ulo)
135 return;
136 if (string)
137 PyDict_SetItemString(string, "lowercase", ulo);
138 if (strop)
139 PyDict_SetItemString(strop, "lowercase", ulo);
140 Py_DECREF(ulo);
141
142 /* create letters string */
143 n = 0;
144 for (c = 0; c < 256; c++) {
145 if (isalpha(c))
146 ul[n++] = c;
147 }
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000148 ulo = PyString_FromStringAndSize((const char *)ul, n);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000149 if (!ulo)
150 return;
151 if (string)
152 PyDict_SetItemString(string, "letters", ulo);
153 Py_DECREF(ulo);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000154}
Martin v. Löwis7c82a3e02001-09-05 17:09:48 +0000155
Guido van Rossum220ecc81997-11-18 21:03:39 +0000156static PyObject*
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000157PyLocale_setlocale(PyObject* self, PyObject* args)
Guido van Rossum220ecc81997-11-18 21:03:39 +0000158{
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000159 int category;
160 char *locale = NULL, *result;
161 PyObject *result_object;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000162
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000163 if (!PyArg_ParseTuple(args, "i|z:setlocale", &category, &locale))
Fredrik Lundh89610a42000-07-08 20:07:24 +0000164 return NULL;
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000165
166 if (locale) {
167 /* set locale */
168 result = setlocale(category, locale);
169 if (!result) {
170 /* operation failed, no setting was changed */
Martin v. Löwis25f90d52003-09-03 04:50:13 +0000171 PyErr_SetString(Error, "unsupported locale setting");
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000172 return NULL;
173 }
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000174 result_object = PyString_FromString(result);
Mark Hammond9a714752003-07-24 14:15:07 +0000175 if (!result_object)
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000176 return NULL;
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000177 /* record changes to LC_CTYPE */
178 if (category == LC_CTYPE || category == LC_ALL)
179 fixup_ulcase();
180 /* things that got wrong up to here are ignored */
181 PyErr_Clear();
182 } else {
183 /* get locale */
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000184 result = setlocale(category, NULL);
185 if (!result) {
186 PyErr_SetString(Error, "locale query failed");
187 return NULL;
188 }
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000189 result_object = PyString_FromString(result);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000190 }
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000191 return result_object;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000192}
193
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000194PyDoc_STRVAR(localeconv__doc__,
195"() -> dict. Returns numeric and monetary locale-specific parameters.");
Guido van Rossum220ecc81997-11-18 21:03:39 +0000196
197static PyObject*
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000198PyLocale_localeconv(PyObject* self)
Guido van Rossum220ecc81997-11-18 21:03:39 +0000199{
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000200 PyObject* result;
201 struct lconv *l;
202 PyObject *x;
203
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000204 result = PyDict_New();
Fredrik Lundh89610a42000-07-08 20:07:24 +0000205 if (!result)
206 return NULL;
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000207
208 /* if LC_NUMERIC is different in the C library, use saved value */
209 l = localeconv();
210
211 /* hopefully, the localeconv result survives the C library calls
212 involved herein */
213
214#define RESULT_STRING(s)\
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000215 x = PyString_FromString(l->s);\
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000216 if (!x) goto failed;\
217 PyDict_SetItemString(result, #s, x);\
218 Py_XDECREF(x)
219
220#define RESULT_INT(i)\
221 x = PyInt_FromLong(l->i);\
222 if (!x) goto failed;\
223 PyDict_SetItemString(result, #i, x);\
224 Py_XDECREF(x)
Guido van Rossum220ecc81997-11-18 21:03:39 +0000225
226 /* Numeric information */
Martin v. Löwis737ea822004-06-08 18:52:54 +0000227 RESULT_STRING(decimal_point);
228 RESULT_STRING(thousands_sep);
229 x = copy_grouping(l->grouping);
230 if (!x)
231 goto failed;
232 PyDict_SetItemString(result, "grouping", x);
233 Py_XDECREF(x);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000234
235 /* Monetary information */
236 RESULT_STRING(int_curr_symbol);
237 RESULT_STRING(currency_symbol);
238 RESULT_STRING(mon_decimal_point);
239 RESULT_STRING(mon_thousands_sep);
240 x = copy_grouping(l->mon_grouping);
241 if (!x)
242 goto failed;
243 PyDict_SetItemString(result, "mon_grouping", x);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000244 Py_XDECREF(x);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000245 RESULT_STRING(positive_sign);
246 RESULT_STRING(negative_sign);
247 RESULT_INT(int_frac_digits);
248 RESULT_INT(frac_digits);
249 RESULT_INT(p_cs_precedes);
250 RESULT_INT(p_sep_by_space);
251 RESULT_INT(n_cs_precedes);
252 RESULT_INT(n_sep_by_space);
253 RESULT_INT(p_sign_posn);
254 RESULT_INT(n_sign_posn);
255 return result;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000256
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000257 failed:
258 Py_XDECREF(result);
259 Py_XDECREF(x);
260 return NULL;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000261}
262
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000263PyDoc_STRVAR(strcoll__doc__,
264"string,string -> int. Compares two strings according to the locale.");
Guido van Rossum220ecc81997-11-18 21:03:39 +0000265
266static PyObject*
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000267PyLocale_strcoll(PyObject* self, PyObject* args)
Guido van Rossum220ecc81997-11-18 21:03:39 +0000268{
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000269#if !defined(HAVE_WCSCOLL) || !defined(Py_USING_UNICODE)
270 char *s1,*s2;
271
272 if (!PyArg_ParseTuple(args, "ss:strcoll", &s1, &s2))
273 return NULL;
274 return PyInt_FromLong(strcoll(s1, s2));
275#else
276 PyObject *os1, *os2, *result = NULL;
277 wchar_t *ws1 = NULL, *ws2 = NULL;
278 int rel1 = 0, rel2 = 0, len1, len2;
279
Georg Brandl96a8c392006-05-29 21:04:52 +0000280 if (!PyArg_UnpackTuple(args, "strcoll", 2, 2, &os1, &os2))
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000281 return NULL;
282 /* If both arguments are byte strings, use strcoll. */
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000283 if (PyString_Check(os1) && PyString_Check(os2))
284 return PyInt_FromLong(strcoll(PyString_AS_STRING(os1),
285 PyString_AS_STRING(os2)));
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000286 /* If neither argument is unicode, it's an error. */
287 if (!PyUnicode_Check(os1) && !PyUnicode_Check(os2)) {
288 PyErr_SetString(PyExc_ValueError, "strcoll arguments must be strings");
289 }
290 /* Convert the non-unicode argument to unicode. */
291 if (!PyUnicode_Check(os1)) {
292 os1 = PyUnicode_FromObject(os1);
293 if (!os1)
294 return NULL;
295 rel1 = 1;
296 }
297 if (!PyUnicode_Check(os2)) {
298 os2 = PyUnicode_FromObject(os2);
299 if (!os2) {
Georg Brandl278fc502008-07-19 12:46:12 +0000300 if (rel1) {
301 Py_DECREF(os1);
302 }
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000303 return NULL;
304 }
305 rel2 = 1;
306 }
307 /* Convert the unicode strings to wchar[]. */
308 len1 = PyUnicode_GET_SIZE(os1) + 1;
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000309 ws1 = PyMem_MALLOC(len1 * sizeof(wchar_t));
310 if (!ws1) {
311 PyErr_NoMemory();
312 goto done;
313 }
314 if (PyUnicode_AsWideChar((PyUnicodeObject*)os1, ws1, len1) == -1)
315 goto done;
Marc-André Lemburga9cadcd2004-11-22 13:02:31 +0000316 ws1[len1 - 1] = 0;
317 len2 = PyUnicode_GET_SIZE(os2) + 1;
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000318 ws2 = PyMem_MALLOC(len2 * sizeof(wchar_t));
319 if (!ws2) {
320 PyErr_NoMemory();
321 goto done;
322 }
323 if (PyUnicode_AsWideChar((PyUnicodeObject*)os2, ws2, len2) == -1)
324 goto done;
Marc-André Lemburga9cadcd2004-11-22 13:02:31 +0000325 ws2[len2 - 1] = 0;
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000326 /* Collate the strings. */
327 result = PyInt_FromLong(wcscoll(ws1, ws2));
328 done:
329 /* Deallocate everything. */
330 if (ws1) PyMem_FREE(ws1);
331 if (ws2) PyMem_FREE(ws2);
332 if (rel1) {
333 Py_DECREF(os1);
334 }
335 if (rel2) {
336 Py_DECREF(os2);
337 }
338 return result;
339#endif
Guido van Rossum220ecc81997-11-18 21:03:39 +0000340}
341
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000342
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000343PyDoc_STRVAR(strxfrm__doc__,
344"string -> string. Returns a string that behaves for cmp locale-aware.");
Guido van Rossum220ecc81997-11-18 21:03:39 +0000345
346static PyObject*
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000347PyLocale_strxfrm(PyObject* self, PyObject* args)
Guido van Rossum220ecc81997-11-18 21:03:39 +0000348{
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000349 char *s, *buf;
350 size_t n1, n2;
351 PyObject *result;
352
Fredrik Lundh89610a42000-07-08 20:07:24 +0000353 if (!PyArg_ParseTuple(args, "s:strxfrm", &s))
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000354 return NULL;
355
356 /* assume no change in size, first */
357 n1 = strlen(s) + 1;
358 buf = PyMem_Malloc(n1);
359 if (!buf)
360 return PyErr_NoMemory();
Matthias Klosee19e0c22007-04-03 04:35:59 +0000361 n2 = strxfrm(buf, s, n1) + 1;
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000362 if (n2 > n1) {
363 /* more space needed */
364 buf = PyMem_Realloc(buf, n2);
365 if (!buf)
366 return PyErr_NoMemory();
367 strxfrm(buf, s, n2);
368 }
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000369 result = PyString_FromString(buf);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000370 PyMem_Free(buf);
371 return result;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000372}
373
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000374#if defined(MS_WINDOWS)
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000375static PyObject*
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000376PyLocale_getdefaultlocale(PyObject* self)
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000377{
378 char encoding[100];
379 char locale[100];
380
Tim Peters885d4572001-11-28 20:27:42 +0000381 PyOS_snprintf(encoding, sizeof(encoding), "cp%d", GetACP());
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000382
383 if (GetLocaleInfo(LOCALE_USER_DEFAULT,
384 LOCALE_SISO639LANGNAME,
385 locale, sizeof(locale))) {
Martin v. Löwis18e16552006-02-15 17:27:45 +0000386 Py_ssize_t i = strlen(locale);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000387 locale[i++] = '_';
388 if (GetLocaleInfo(LOCALE_USER_DEFAULT,
389 LOCALE_SISO3166CTRYNAME,
Martin v. Löwis18e16552006-02-15 17:27:45 +0000390 locale+i, (int)(sizeof(locale)-i)))
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000391 return Py_BuildValue("ss", locale, encoding);
392 }
393
394 /* If we end up here, this windows version didn't know about
395 ISO639/ISO3166 names (it's probably Windows 95). Return the
396 Windows language identifier instead (a hexadecimal number) */
397
398 locale[0] = '0';
399 locale[1] = 'x';
400 if (GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_IDEFAULTLANGUAGE,
401 locale+2, sizeof(locale)-2)) {
402 return Py_BuildValue("ss", locale, encoding);
403 }
404
405 /* cannot determine the language code (very unlikely) */
406 Py_INCREF(Py_None);
407 return Py_BuildValue("Os", Py_None, encoding);
408}
409#endif
410
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000411#ifdef HAVE_LANGINFO_H
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000412#define LANGINFO(X) {#X, X}
Martin v. Löwis111c1802008-06-13 07:47:47 +0000413static struct langinfo_constant{
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000414 char* name;
415 int value;
416} langinfo_constants[] =
417{
418 /* These constants should exist on any langinfo implementation */
419 LANGINFO(DAY_1),
420 LANGINFO(DAY_2),
421 LANGINFO(DAY_3),
422 LANGINFO(DAY_4),
423 LANGINFO(DAY_5),
424 LANGINFO(DAY_6),
425 LANGINFO(DAY_7),
426
427 LANGINFO(ABDAY_1),
428 LANGINFO(ABDAY_2),
429 LANGINFO(ABDAY_3),
430 LANGINFO(ABDAY_4),
431 LANGINFO(ABDAY_5),
432 LANGINFO(ABDAY_6),
433 LANGINFO(ABDAY_7),
434
435 LANGINFO(MON_1),
436 LANGINFO(MON_2),
437 LANGINFO(MON_3),
438 LANGINFO(MON_4),
439 LANGINFO(MON_5),
440 LANGINFO(MON_6),
441 LANGINFO(MON_7),
442 LANGINFO(MON_8),
443 LANGINFO(MON_9),
444 LANGINFO(MON_10),
445 LANGINFO(MON_11),
446 LANGINFO(MON_12),
447
448 LANGINFO(ABMON_1),
449 LANGINFO(ABMON_2),
450 LANGINFO(ABMON_3),
451 LANGINFO(ABMON_4),
452 LANGINFO(ABMON_5),
453 LANGINFO(ABMON_6),
454 LANGINFO(ABMON_7),
455 LANGINFO(ABMON_8),
456 LANGINFO(ABMON_9),
457 LANGINFO(ABMON_10),
458 LANGINFO(ABMON_11),
459 LANGINFO(ABMON_12),
460
461#ifdef RADIXCHAR
462 /* The following are not available with glibc 2.0 */
463 LANGINFO(RADIXCHAR),
464 LANGINFO(THOUSEP),
465 /* YESSTR and NOSTR are deprecated in glibc, since they are
466 a special case of message translation, which should be rather
467 done using gettext. So we don't expose it to Python in the
468 first place.
469 LANGINFO(YESSTR),
470 LANGINFO(NOSTR),
471 */
472 LANGINFO(CRNCYSTR),
473#endif
474
475 LANGINFO(D_T_FMT),
476 LANGINFO(D_FMT),
477 LANGINFO(T_FMT),
478 LANGINFO(AM_STR),
479 LANGINFO(PM_STR),
480
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000481 /* The following constants are available only with XPG4, but...
482 AIX 3.2. only has CODESET.
483 OpenBSD doesn't have CODESET but has T_FMT_AMPM, and doesn't have
484 a few of the others.
485 Solution: ifdef-test them all. */
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000486#ifdef CODESET
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000487 LANGINFO(CODESET),
Martin v. Löwis496f9e42002-03-27 12:15:57 +0000488#endif
489#ifdef T_FMT_AMPM
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000490 LANGINFO(T_FMT_AMPM),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000491#endif
492#ifdef ERA
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000493 LANGINFO(ERA),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000494#endif
495#ifdef ERA_D_FMT
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000496 LANGINFO(ERA_D_FMT),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000497#endif
498#ifdef ERA_D_T_FMT
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000499 LANGINFO(ERA_D_T_FMT),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000500#endif
501#ifdef ERA_T_FMT
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000502 LANGINFO(ERA_T_FMT),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000503#endif
504#ifdef ALT_DIGITS
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000505 LANGINFO(ALT_DIGITS),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000506#endif
507#ifdef YESEXPR
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000508 LANGINFO(YESEXPR),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000509#endif
510#ifdef NOEXPR
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000511 LANGINFO(NOEXPR),
512#endif
513#ifdef _DATE_FMT
514 /* This is not available in all glibc versions that have CODESET. */
515 LANGINFO(_DATE_FMT),
516#endif
517 {0, 0}
518};
519
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000520PyDoc_STRVAR(nl_langinfo__doc__,
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000521"nl_langinfo(key) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000522"Return the value for the locale information associated with key.");
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000523
524static PyObject*
525PyLocale_nl_langinfo(PyObject* self, PyObject* args)
526{
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000527 int item, i;
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000528 if (!PyArg_ParseTuple(args, "i:nl_langinfo", &item))
529 return NULL;
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000530 /* Check whether this is a supported constant. GNU libc sometimes
531 returns numeric values in the char* return value, which would
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000532 crash PyString_FromString. */
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000533 for (i = 0; langinfo_constants[i].name; i++)
Hye-Shik Changc3a87b82004-03-21 19:34:30 +0000534 if (langinfo_constants[i].value == item) {
535 /* Check NULL as a workaround for GNU libc's returning NULL
536 instead of an empty string for nl_langinfo(ERA). */
537 const char *result = nl_langinfo(item);
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000538 return PyString_FromString(result != NULL ? result : "");
Hye-Shik Changc3a87b82004-03-21 19:34:30 +0000539 }
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000540 PyErr_SetString(PyExc_ValueError, "unsupported langinfo constant");
541 return NULL;
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000542}
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000543#endif /* HAVE_LANGINFO_H */
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000544
545#ifdef HAVE_LIBINTL_H
546
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000547PyDoc_STRVAR(gettext__doc__,
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000548"gettext(msg) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000549"Return translation of msg.");
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000550
551static PyObject*
552PyIntl_gettext(PyObject* self, PyObject *args)
553{
554 char *in;
Georg Brandl6b41a8e2008-07-19 12:39:10 +0000555 if (!PyArg_ParseTuple(args, "s", &in))
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000556 return 0;
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000557 return PyString_FromString(gettext(in));
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000558}
559
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000560PyDoc_STRVAR(dgettext__doc__,
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000561"dgettext(domain, msg) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000562"Return translation of msg in domain.");
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000563
564static PyObject*
565PyIntl_dgettext(PyObject* self, PyObject *args)
566{
567 char *domain, *in;
Georg Brandl6b41a8e2008-07-19 12:39:10 +0000568 if (!PyArg_ParseTuple(args, "zs", &domain, &in))
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000569 return 0;
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000570 return PyString_FromString(dgettext(domain, in));
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000571}
572
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000573PyDoc_STRVAR(dcgettext__doc__,
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000574"dcgettext(domain, msg, category) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000575"Return translation of msg in domain and category.");
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000576
577static PyObject*
578PyIntl_dcgettext(PyObject *self, PyObject *args)
579{
580 char *domain, *msgid;
581 int category;
Georg Brandl6b41a8e2008-07-19 12:39:10 +0000582 if (!PyArg_ParseTuple(args, "zsi", &domain, &msgid, &category))
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000583 return 0;
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000584 return PyString_FromString(dcgettext(domain,msgid,category));
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000585}
586
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000587PyDoc_STRVAR(textdomain__doc__,
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000588"textdomain(domain) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000589"Set the C library's textdmain to domain, returning the new domain.");
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000590
591static PyObject*
592PyIntl_textdomain(PyObject* self, PyObject* args)
593{
594 char *domain;
595 if (!PyArg_ParseTuple(args, "z", &domain))
596 return 0;
597 domain = textdomain(domain);
598 if (!domain) {
599 PyErr_SetFromErrno(PyExc_OSError);
600 return NULL;
601 }
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000602 return PyString_FromString(domain);
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000603}
604
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000605PyDoc_STRVAR(bindtextdomain__doc__,
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000606"bindtextdomain(domain, dir) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000607"Bind the C library's domain to dir.");
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000608
609static PyObject*
610PyIntl_bindtextdomain(PyObject* self,PyObject*args)
611{
Georg Brandl6b41a8e2008-07-19 12:39:10 +0000612 char *domain, *dirname;
613 if (!PyArg_ParseTuple(args, "sz", &domain, &dirname))
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000614 return 0;
Georg Brandl6b41a8e2008-07-19 12:39:10 +0000615 if (!strlen(domain)) {
616 PyErr_SetString(Error, "domain must be a non-empty string");
617 return 0;
618 }
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000619 dirname = bindtextdomain(domain, dirname);
620 if (!dirname) {
621 PyErr_SetFromErrno(PyExc_OSError);
622 return NULL;
623 }
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000624 return PyString_FromString(dirname);
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000625}
626
Gustavo Niemeyer7bd33c52004-07-22 18:44:01 +0000627#ifdef HAVE_BIND_TEXTDOMAIN_CODESET
628PyDoc_STRVAR(bind_textdomain_codeset__doc__,
629"bind_textdomain_codeset(domain, codeset) -> string\n"
630"Bind the C library's domain to codeset.");
631
632static PyObject*
633PyIntl_bind_textdomain_codeset(PyObject* self,PyObject*args)
634{
635 char *domain,*codeset;
636 if (!PyArg_ParseTuple(args, "sz", &domain, &codeset))
637 return NULL;
638 codeset = bind_textdomain_codeset(domain, codeset);
639 if (codeset)
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000640 return PyString_FromString(codeset);
Gustavo Niemeyer7bd33c52004-07-22 18:44:01 +0000641 Py_RETURN_NONE;
642}
643#endif
644
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000645#endif
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000646
Guido van Rossum220ecc81997-11-18 21:03:39 +0000647static struct PyMethodDef PyLocale_Methods[] = {
Andrew M. Kuchlinge365fb82000-08-03 02:06:16 +0000648 {"setlocale", (PyCFunction) PyLocale_setlocale,
649 METH_VARARGS, setlocale__doc__},
650 {"localeconv", (PyCFunction) PyLocale_localeconv,
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000651 METH_NOARGS, localeconv__doc__},
Andrew M. Kuchlinge365fb82000-08-03 02:06:16 +0000652 {"strcoll", (PyCFunction) PyLocale_strcoll,
653 METH_VARARGS, strcoll__doc__},
654 {"strxfrm", (PyCFunction) PyLocale_strxfrm,
655 METH_VARARGS, strxfrm__doc__},
Benjamin Petersone021c9c2009-06-07 16:24:48 +0000656#if defined(MS_WINDOWS)
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000657 {"_getdefaultlocale", (PyCFunction) PyLocale_getdefaultlocale, METH_NOARGS},
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000658#endif
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000659#ifdef HAVE_LANGINFO_H
660 {"nl_langinfo", (PyCFunction) PyLocale_nl_langinfo,
661 METH_VARARGS, nl_langinfo__doc__},
662#endif
Martin v. Löwisc6a7d7e2002-05-02 12:16:29 +0000663#ifdef HAVE_LIBINTL_H
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000664 {"gettext",(PyCFunction)PyIntl_gettext,METH_VARARGS,
665 gettext__doc__},
666 {"dgettext",(PyCFunction)PyIntl_dgettext,METH_VARARGS,
667 dgettext__doc__},
668 {"dcgettext",(PyCFunction)PyIntl_dcgettext,METH_VARARGS,
669 dcgettext__doc__},
670 {"textdomain",(PyCFunction)PyIntl_textdomain,METH_VARARGS,
671 textdomain__doc__},
672 {"bindtextdomain",(PyCFunction)PyIntl_bindtextdomain,METH_VARARGS,
673 bindtextdomain__doc__},
Gustavo Niemeyer7bd33c52004-07-22 18:44:01 +0000674#ifdef HAVE_BIND_TEXTDOMAIN_CODESET
675 {"bind_textdomain_codeset",(PyCFunction)PyIntl_bind_textdomain_codeset,
676 METH_VARARGS, bind_textdomain_codeset__doc__},
677#endif
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000678#endif
Guido van Rossum220ecc81997-11-18 21:03:39 +0000679 {NULL, NULL}
680};
681
Mark Hammondfe51c6d2002-08-02 02:27:13 +0000682PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000683init_locale(void)
Guido van Rossum220ecc81997-11-18 21:03:39 +0000684{
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000685 PyObject *m, *d, *x;
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000686#ifdef HAVE_LANGINFO_H
687 int i;
688#endif
Guido van Rossum220ecc81997-11-18 21:03:39 +0000689
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000690 m = Py_InitModule("_locale", PyLocale_Methods);
Neal Norwitz1ac754f2006-01-19 06:09:39 +0000691 if (m == NULL)
692 return;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000693
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000694 d = PyModule_GetDict(m);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000695
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000696 x = PyInt_FromLong(LC_CTYPE);
697 PyDict_SetItemString(d, "LC_CTYPE", x);
698 Py_XDECREF(x);
699
700 x = PyInt_FromLong(LC_TIME);
701 PyDict_SetItemString(d, "LC_TIME", x);
702 Py_XDECREF(x);
703
704 x = PyInt_FromLong(LC_COLLATE);
705 PyDict_SetItemString(d, "LC_COLLATE", x);
706 Py_XDECREF(x);
707
708 x = PyInt_FromLong(LC_MONETARY);
709 PyDict_SetItemString(d, "LC_MONETARY", x);
710 Py_XDECREF(x);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000711
Guido van Rossum8d9c2e31997-12-09 19:35:11 +0000712#ifdef LC_MESSAGES
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000713 x = PyInt_FromLong(LC_MESSAGES);
714 PyDict_SetItemString(d, "LC_MESSAGES", x);
715 Py_XDECREF(x);
Guido van Rossum8d9c2e31997-12-09 19:35:11 +0000716#endif /* LC_MESSAGES */
Guido van Rossum220ecc81997-11-18 21:03:39 +0000717
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000718 x = PyInt_FromLong(LC_NUMERIC);
719 PyDict_SetItemString(d, "LC_NUMERIC", x);
720 Py_XDECREF(x);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000721
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000722 x = PyInt_FromLong(LC_ALL);
723 PyDict_SetItemString(d, "LC_ALL", x);
724 Py_XDECREF(x);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000725
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000726 x = PyInt_FromLong(CHAR_MAX);
727 PyDict_SetItemString(d, "CHAR_MAX", x);
728 Py_XDECREF(x);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000729
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000730 Error = PyErr_NewException("locale.Error", NULL, NULL);
731 PyDict_SetItemString(d, "Error", Error);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000732
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000733 x = PyString_FromString(locale__doc__);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000734 PyDict_SetItemString(d, "__doc__", x);
735 Py_XDECREF(x);
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000736
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000737#ifdef HAVE_LANGINFO_H
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000738 for (i = 0; langinfo_constants[i].name; i++) {
739 PyModule_AddIntConstant(m, langinfo_constants[i].name,
740 langinfo_constants[i].value);
741 }
Martin v. Löwisf95dd0a2001-08-15 17:14:33 +0000742#endif
Guido van Rossum220ecc81997-11-18 21:03:39 +0000743}
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000744
745/*
746Local variables:
747c-basic-offset: 4
748indent-tabs-mode: nil
749End:
750*/