blob: 0ab79cba6068fa0e19296f1637a7bfe57a99048a [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>
15#include <errno.h>
16#include <locale.h>
17#include <string.h>
Guido van Rossum5cd70f41998-06-19 04:33:30 +000018#include <ctype.h>
Fredrik Lundh8f017a02000-07-08 19:57:37 +000019
Martin v. Löwis9b75dca2001-08-10 13:58:50 +000020#ifdef HAVE_LANGINFO_H
21#include <langinfo.h>
22#endif
23
Martin v. Löwis2e64c342002-03-27 18:49:02 +000024#ifdef HAVE_LIBINTL_H
25#include <libintl.h>
26#endif
27
Martin v. Löwis9c36c292002-12-21 18:34:06 +000028#ifdef HAVE_WCHAR_H
29#include <wchar.h>
30#endif
31
Jack Jansen7107c1a2003-11-20 13:31:00 +000032#if defined(__APPLE__)
33#include "pymactoolbox.h"
34#endif
35
Martin v. Löwis6238d2b2002-06-30 15:26:10 +000036#if defined(MS_WINDOWS)
Tim Peters7a1f9172002-07-14 22:14:19 +000037#define WIN32_LEAN_AND_MEAN
Fredrik Lundh8f017a02000-07-08 19:57:37 +000038#include <windows.h>
Guido van Rossum239a2181998-04-28 16:08:19 +000039#endif
Guido van Rossum220ecc81997-11-18 21:03:39 +000040
Guido van Rossum1ca8bb32001-03-02 06:28:17 +000041#ifdef RISCOS
42char *strdup(const char *);
43#endif
44
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000045PyDoc_STRVAR(locale__doc__, "Support for POSIX locales.");
Guido van Rossum220ecc81997-11-18 21:03:39 +000046
47static PyObject *Error;
48
49/* support functions for formatting floating point numbers */
50
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000051PyDoc_STRVAR(setlocale__doc__,
52"(integer,string=None) -> string. Activates/queries locale processing.");
Guido van Rossum220ecc81997-11-18 21:03:39 +000053
Guido van Rossum220ecc81997-11-18 21:03:39 +000054/* the grouping is terminated by either 0 or CHAR_MAX */
55static PyObject*
Fredrik Lundh8f017a02000-07-08 19:57:37 +000056copy_grouping(char* s)
Guido van Rossum220ecc81997-11-18 21:03:39 +000057{
Fredrik Lundh8f017a02000-07-08 19:57:37 +000058 int i;
59 PyObject *result, *val = NULL;
60
61 if (s[0] == '\0')
62 /* empty string: no grouping at all */
63 return PyList_New(0);
64
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 }
119 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 }
134 ulo = PyString_FromStringAndSize((const char *)ul, n);
135 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 }
149 ulo = PyString_FromStringAndSize((const char *)ul, n);
150 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
167 if (locale) {
168 /* set locale */
169 result = setlocale(category, locale);
170 if (!result) {
171 /* operation failed, no setting was changed */
Martin v. Löwis25f90d52003-09-03 04:50:13 +0000172 PyErr_SetString(Error, "unsupported locale setting");
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000173 return NULL;
174 }
175 result_object = PyString_FromString(result);
Mark Hammond9a714752003-07-24 14:15:07 +0000176 if (!result_object)
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000177 return NULL;
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000178 /* record changes to LC_CTYPE */
179 if (category == LC_CTYPE || category == LC_ALL)
180 fixup_ulcase();
181 /* things that got wrong up to here are ignored */
182 PyErr_Clear();
183 } else {
184 /* get locale */
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000185 result = setlocale(category, NULL);
186 if (!result) {
187 PyErr_SetString(Error, "locale query failed");
188 return NULL;
189 }
190 result_object = PyString_FromString(result);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000191 }
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000192 return result_object;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000193}
194
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000195PyDoc_STRVAR(localeconv__doc__,
196"() -> dict. Returns numeric and monetary locale-specific parameters.");
Guido van Rossum220ecc81997-11-18 21:03:39 +0000197
198static PyObject*
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000199PyLocale_localeconv(PyObject* self)
Guido van Rossum220ecc81997-11-18 21:03:39 +0000200{
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000201 PyObject* result;
202 struct lconv *l;
203 PyObject *x;
204
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000205 result = PyDict_New();
Fredrik Lundh89610a42000-07-08 20:07:24 +0000206 if (!result)
207 return NULL;
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000208
209 /* if LC_NUMERIC is different in the C library, use saved value */
210 l = localeconv();
211
212 /* hopefully, the localeconv result survives the C library calls
213 involved herein */
214
215#define RESULT_STRING(s)\
216 x = PyString_FromString(l->s);\
217 if (!x) goto failed;\
218 PyDict_SetItemString(result, #s, x);\
219 Py_XDECREF(x)
220
221#define RESULT_INT(i)\
222 x = PyInt_FromLong(l->i);\
223 if (!x) goto failed;\
224 PyDict_SetItemString(result, #i, x);\
225 Py_XDECREF(x)
Guido van Rossum220ecc81997-11-18 21:03:39 +0000226
227 /* Numeric information */
Martin v. Löwis737ea822004-06-08 18:52:54 +0000228 RESULT_STRING(decimal_point);
229 RESULT_STRING(thousands_sep);
230 x = copy_grouping(l->grouping);
231 if (!x)
232 goto failed;
233 PyDict_SetItemString(result, "grouping", x);
234 Py_XDECREF(x);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000235
236 /* Monetary information */
237 RESULT_STRING(int_curr_symbol);
238 RESULT_STRING(currency_symbol);
239 RESULT_STRING(mon_decimal_point);
240 RESULT_STRING(mon_thousands_sep);
241 x = copy_grouping(l->mon_grouping);
242 if (!x)
243 goto failed;
244 PyDict_SetItemString(result, "mon_grouping", x);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000245 Py_XDECREF(x);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000246 RESULT_STRING(positive_sign);
247 RESULT_STRING(negative_sign);
248 RESULT_INT(int_frac_digits);
249 RESULT_INT(frac_digits);
250 RESULT_INT(p_cs_precedes);
251 RESULT_INT(p_sep_by_space);
252 RESULT_INT(n_cs_precedes);
253 RESULT_INT(n_sep_by_space);
254 RESULT_INT(p_sign_posn);
255 RESULT_INT(n_sign_posn);
256 return result;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000257
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000258 failed:
259 Py_XDECREF(result);
260 Py_XDECREF(x);
261 return NULL;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000262}
263
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000264PyDoc_STRVAR(strcoll__doc__,
265"string,string -> int. Compares two strings according to the locale.");
Guido van Rossum220ecc81997-11-18 21:03:39 +0000266
267static PyObject*
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000268PyLocale_strcoll(PyObject* self, PyObject* args)
Guido van Rossum220ecc81997-11-18 21:03:39 +0000269{
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000270#if !defined(HAVE_WCSCOLL) || !defined(Py_USING_UNICODE)
271 char *s1,*s2;
272
273 if (!PyArg_ParseTuple(args, "ss:strcoll", &s1, &s2))
274 return NULL;
275 return PyInt_FromLong(strcoll(s1, s2));
276#else
277 PyObject *os1, *os2, *result = NULL;
278 wchar_t *ws1 = NULL, *ws2 = NULL;
279 int rel1 = 0, rel2 = 0, len1, len2;
280
281 if (!PyArg_ParseTuple(args, "OO:strcoll", &os1, &os2))
282 return NULL;
283 /* If both arguments are byte strings, use strcoll. */
284 if (PyString_Check(os1) && PyString_Check(os2))
285 return PyInt_FromLong(strcoll(PyString_AS_STRING(os1),
286 PyString_AS_STRING(os2)));
287 /* If neither argument is unicode, it's an error. */
288 if (!PyUnicode_Check(os1) && !PyUnicode_Check(os2)) {
289 PyErr_SetString(PyExc_ValueError, "strcoll arguments must be strings");
290 }
291 /* Convert the non-unicode argument to unicode. */
292 if (!PyUnicode_Check(os1)) {
293 os1 = PyUnicode_FromObject(os1);
294 if (!os1)
295 return NULL;
296 rel1 = 1;
297 }
298 if (!PyUnicode_Check(os2)) {
299 os2 = PyUnicode_FromObject(os2);
300 if (!os2) {
301 Py_DECREF(os1);
302 return NULL;
303 }
304 rel2 = 1;
305 }
306 /* Convert the unicode strings to wchar[]. */
307 len1 = PyUnicode_GET_SIZE(os1) + 1;
308 len2 = PyUnicode_GET_SIZE(os2) + 1;
309 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;
316 ws2 = PyMem_MALLOC(len2 * sizeof(wchar_t));
317 if (!ws2) {
318 PyErr_NoMemory();
319 goto done;
320 }
321 if (PyUnicode_AsWideChar((PyUnicodeObject*)os2, ws2, len2) == -1)
322 goto done;
323 /* Collate the strings. */
324 result = PyInt_FromLong(wcscoll(ws1, ws2));
325 done:
326 /* Deallocate everything. */
327 if (ws1) PyMem_FREE(ws1);
328 if (ws2) PyMem_FREE(ws2);
329 if (rel1) {
330 Py_DECREF(os1);
331 }
332 if (rel2) {
333 Py_DECREF(os2);
334 }
335 return result;
336#endif
Guido van Rossum220ecc81997-11-18 21:03:39 +0000337}
338
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000339
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000340PyDoc_STRVAR(strxfrm__doc__,
341"string -> string. Returns a string that behaves for cmp locale-aware.");
Guido van Rossum220ecc81997-11-18 21:03:39 +0000342
343static PyObject*
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000344PyLocale_strxfrm(PyObject* self, PyObject* args)
Guido van Rossum220ecc81997-11-18 21:03:39 +0000345{
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000346 char *s, *buf;
347 size_t n1, n2;
348 PyObject *result;
349
Fredrik Lundh89610a42000-07-08 20:07:24 +0000350 if (!PyArg_ParseTuple(args, "s:strxfrm", &s))
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000351 return NULL;
352
353 /* assume no change in size, first */
354 n1 = strlen(s) + 1;
355 buf = PyMem_Malloc(n1);
356 if (!buf)
357 return PyErr_NoMemory();
358 n2 = strxfrm(buf, s, n1);
359 if (n2 > n1) {
360 /* more space needed */
361 buf = PyMem_Realloc(buf, n2);
362 if (!buf)
363 return PyErr_NoMemory();
364 strxfrm(buf, s, n2);
365 }
366 result = PyString_FromString(buf);
367 PyMem_Free(buf);
368 return result;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000369}
370
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000371#if defined(MS_WINDOWS)
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000372static PyObject*
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000373PyLocale_getdefaultlocale(PyObject* self)
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000374{
375 char encoding[100];
376 char locale[100];
377
Tim Peters885d4572001-11-28 20:27:42 +0000378 PyOS_snprintf(encoding, sizeof(encoding), "cp%d", GetACP());
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000379
380 if (GetLocaleInfo(LOCALE_USER_DEFAULT,
381 LOCALE_SISO639LANGNAME,
382 locale, sizeof(locale))) {
383 int i = strlen(locale);
384 locale[i++] = '_';
385 if (GetLocaleInfo(LOCALE_USER_DEFAULT,
386 LOCALE_SISO3166CTRYNAME,
387 locale+i, sizeof(locale)-i))
388 return Py_BuildValue("ss", locale, encoding);
389 }
390
391 /* If we end up here, this windows version didn't know about
392 ISO639/ISO3166 names (it's probably Windows 95). Return the
393 Windows language identifier instead (a hexadecimal number) */
394
395 locale[0] = '0';
396 locale[1] = 'x';
397 if (GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_IDEFAULTLANGUAGE,
398 locale+2, sizeof(locale)-2)) {
399 return Py_BuildValue("ss", locale, encoding);
400 }
401
402 /* cannot determine the language code (very unlikely) */
403 Py_INCREF(Py_None);
404 return Py_BuildValue("Os", Py_None, encoding);
405}
406#endif
407
Martin v. Löwis52ea7e92002-11-26 09:05:36 +0000408#if defined(__APPLE__)
Jack Jansen307d7a42000-07-15 22:31:45 +0000409static PyObject*
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000410PyLocale_getdefaultlocale(PyObject* self)
Jack Jansen307d7a42000-07-15 22:31:45 +0000411{
412 return Py_BuildValue("Os", Py_None, PyMac_getscript());
413}
414#endif
415
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000416#ifdef HAVE_LANGINFO_H
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000417#define LANGINFO(X) {#X, X}
418struct langinfo_constant{
419 char* name;
420 int value;
421} langinfo_constants[] =
422{
423 /* These constants should exist on any langinfo implementation */
424 LANGINFO(DAY_1),
425 LANGINFO(DAY_2),
426 LANGINFO(DAY_3),
427 LANGINFO(DAY_4),
428 LANGINFO(DAY_5),
429 LANGINFO(DAY_6),
430 LANGINFO(DAY_7),
431
432 LANGINFO(ABDAY_1),
433 LANGINFO(ABDAY_2),
434 LANGINFO(ABDAY_3),
435 LANGINFO(ABDAY_4),
436 LANGINFO(ABDAY_5),
437 LANGINFO(ABDAY_6),
438 LANGINFO(ABDAY_7),
439
440 LANGINFO(MON_1),
441 LANGINFO(MON_2),
442 LANGINFO(MON_3),
443 LANGINFO(MON_4),
444 LANGINFO(MON_5),
445 LANGINFO(MON_6),
446 LANGINFO(MON_7),
447 LANGINFO(MON_8),
448 LANGINFO(MON_9),
449 LANGINFO(MON_10),
450 LANGINFO(MON_11),
451 LANGINFO(MON_12),
452
453 LANGINFO(ABMON_1),
454 LANGINFO(ABMON_2),
455 LANGINFO(ABMON_3),
456 LANGINFO(ABMON_4),
457 LANGINFO(ABMON_5),
458 LANGINFO(ABMON_6),
459 LANGINFO(ABMON_7),
460 LANGINFO(ABMON_8),
461 LANGINFO(ABMON_9),
462 LANGINFO(ABMON_10),
463 LANGINFO(ABMON_11),
464 LANGINFO(ABMON_12),
465
466#ifdef RADIXCHAR
467 /* The following are not available with glibc 2.0 */
468 LANGINFO(RADIXCHAR),
469 LANGINFO(THOUSEP),
470 /* YESSTR and NOSTR are deprecated in glibc, since they are
471 a special case of message translation, which should be rather
472 done using gettext. So we don't expose it to Python in the
473 first place.
474 LANGINFO(YESSTR),
475 LANGINFO(NOSTR),
476 */
477 LANGINFO(CRNCYSTR),
478#endif
479
480 LANGINFO(D_T_FMT),
481 LANGINFO(D_FMT),
482 LANGINFO(T_FMT),
483 LANGINFO(AM_STR),
484 LANGINFO(PM_STR),
485
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000486 /* The following constants are available only with XPG4, but...
487 AIX 3.2. only has CODESET.
488 OpenBSD doesn't have CODESET but has T_FMT_AMPM, and doesn't have
489 a few of the others.
490 Solution: ifdef-test them all. */
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000491#ifdef CODESET
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000492 LANGINFO(CODESET),
Martin v. Löwis496f9e42002-03-27 12:15:57 +0000493#endif
494#ifdef T_FMT_AMPM
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000495 LANGINFO(T_FMT_AMPM),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000496#endif
497#ifdef ERA
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000498 LANGINFO(ERA),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000499#endif
500#ifdef ERA_D_FMT
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000501 LANGINFO(ERA_D_FMT),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000502#endif
503#ifdef ERA_D_T_FMT
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000504 LANGINFO(ERA_D_T_FMT),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000505#endif
506#ifdef ERA_T_FMT
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000507 LANGINFO(ERA_T_FMT),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000508#endif
509#ifdef ALT_DIGITS
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000510 LANGINFO(ALT_DIGITS),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000511#endif
512#ifdef YESEXPR
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000513 LANGINFO(YESEXPR),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000514#endif
515#ifdef NOEXPR
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000516 LANGINFO(NOEXPR),
517#endif
518#ifdef _DATE_FMT
519 /* This is not available in all glibc versions that have CODESET. */
520 LANGINFO(_DATE_FMT),
521#endif
522 {0, 0}
523};
524
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000525PyDoc_STRVAR(nl_langinfo__doc__,
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000526"nl_langinfo(key) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000527"Return the value for the locale information associated with key.");
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000528
529static PyObject*
530PyLocale_nl_langinfo(PyObject* self, PyObject* args)
531{
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000532 int item, i;
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000533 if (!PyArg_ParseTuple(args, "i:nl_langinfo", &item))
534 return NULL;
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000535 /* Check whether this is a supported constant. GNU libc sometimes
536 returns numeric values in the char* return value, which would
537 crash PyString_FromString. */
538 for (i = 0; langinfo_constants[i].name; i++)
Hye-Shik Changc3a87b82004-03-21 19:34:30 +0000539 if (langinfo_constants[i].value == item) {
540 /* Check NULL as a workaround for GNU libc's returning NULL
541 instead of an empty string for nl_langinfo(ERA). */
542 const char *result = nl_langinfo(item);
543 return PyString_FromString(result != NULL ? result : "");
544 }
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000545 PyErr_SetString(PyExc_ValueError, "unsupported langinfo constant");
546 return NULL;
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000547}
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000548#endif /* HAVE_LANGINFO_H */
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000549
550#ifdef HAVE_LIBINTL_H
551
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000552PyDoc_STRVAR(gettext__doc__,
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000553"gettext(msg) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000554"Return translation of msg.");
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000555
556static PyObject*
557PyIntl_gettext(PyObject* self, PyObject *args)
558{
559 char *in;
560 if (!PyArg_ParseTuple(args, "z", &in))
561 return 0;
562 return PyString_FromString(gettext(in));
563}
564
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000565PyDoc_STRVAR(dgettext__doc__,
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000566"dgettext(domain, msg) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000567"Return translation of msg in domain.");
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000568
569static PyObject*
570PyIntl_dgettext(PyObject* self, PyObject *args)
571{
572 char *domain, *in;
573 if (!PyArg_ParseTuple(args, "zz", &domain, &in))
574 return 0;
575 return PyString_FromString(dgettext(domain, in));
576}
577
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000578PyDoc_STRVAR(dcgettext__doc__,
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000579"dcgettext(domain, msg, category) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000580"Return translation of msg in domain and category.");
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000581
582static PyObject*
583PyIntl_dcgettext(PyObject *self, PyObject *args)
584{
585 char *domain, *msgid;
586 int category;
587 if (!PyArg_ParseTuple(args, "zzi", &domain, &msgid, &category))
588 return 0;
589 return PyString_FromString(dcgettext(domain,msgid,category));
590}
591
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000592PyDoc_STRVAR(textdomain__doc__,
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000593"textdomain(domain) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000594"Set the C library's textdmain to domain, returning the new domain.");
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000595
596static PyObject*
597PyIntl_textdomain(PyObject* self, PyObject* args)
598{
599 char *domain;
600 if (!PyArg_ParseTuple(args, "z", &domain))
601 return 0;
602 domain = textdomain(domain);
603 if (!domain) {
604 PyErr_SetFromErrno(PyExc_OSError);
605 return NULL;
606 }
607 return PyString_FromString(domain);
608}
609
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000610PyDoc_STRVAR(bindtextdomain__doc__,
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000611"bindtextdomain(domain, dir) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000612"Bind the C library's domain to dir.");
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000613
614static PyObject*
615PyIntl_bindtextdomain(PyObject* self,PyObject*args)
616{
617 char *domain,*dirname;
618 if (!PyArg_ParseTuple(args, "zz", &domain, &dirname))
619 return 0;
620 dirname = bindtextdomain(domain, dirname);
621 if (!dirname) {
622 PyErr_SetFromErrno(PyExc_OSError);
623 return NULL;
624 }
625 return PyString_FromString(dirname);
626}
627
628#endif
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000629
Guido van Rossum220ecc81997-11-18 21:03:39 +0000630static struct PyMethodDef PyLocale_Methods[] = {
Andrew M. Kuchlinge365fb82000-08-03 02:06:16 +0000631 {"setlocale", (PyCFunction) PyLocale_setlocale,
632 METH_VARARGS, setlocale__doc__},
633 {"localeconv", (PyCFunction) PyLocale_localeconv,
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000634 METH_NOARGS, localeconv__doc__},
Andrew M. Kuchlinge365fb82000-08-03 02:06:16 +0000635 {"strcoll", (PyCFunction) PyLocale_strcoll,
636 METH_VARARGS, strcoll__doc__},
637 {"strxfrm", (PyCFunction) PyLocale_strxfrm,
638 METH_VARARGS, strxfrm__doc__},
Martin v. Löwis52ea7e92002-11-26 09:05:36 +0000639#if defined(MS_WINDOWS) || defined(__APPLE__)
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000640 {"_getdefaultlocale", (PyCFunction) PyLocale_getdefaultlocale, METH_NOARGS},
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000641#endif
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000642#ifdef HAVE_LANGINFO_H
643 {"nl_langinfo", (PyCFunction) PyLocale_nl_langinfo,
644 METH_VARARGS, nl_langinfo__doc__},
645#endif
Martin v. Löwisc6a7d7e2002-05-02 12:16:29 +0000646#ifdef HAVE_LIBINTL_H
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000647 {"gettext",(PyCFunction)PyIntl_gettext,METH_VARARGS,
648 gettext__doc__},
649 {"dgettext",(PyCFunction)PyIntl_dgettext,METH_VARARGS,
650 dgettext__doc__},
651 {"dcgettext",(PyCFunction)PyIntl_dcgettext,METH_VARARGS,
652 dcgettext__doc__},
653 {"textdomain",(PyCFunction)PyIntl_textdomain,METH_VARARGS,
654 textdomain__doc__},
655 {"bindtextdomain",(PyCFunction)PyIntl_bindtextdomain,METH_VARARGS,
656 bindtextdomain__doc__},
657#endif
Guido van Rossum220ecc81997-11-18 21:03:39 +0000658 {NULL, NULL}
659};
660
Mark Hammondfe51c6d2002-08-02 02:27:13 +0000661PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000662init_locale(void)
Guido van Rossum220ecc81997-11-18 21:03:39 +0000663{
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000664 PyObject *m, *d, *x;
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000665#ifdef HAVE_LANGINFO_H
666 int i;
667#endif
Guido van Rossum220ecc81997-11-18 21:03:39 +0000668
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000669 m = Py_InitModule("_locale", PyLocale_Methods);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000670
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000671 d = PyModule_GetDict(m);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000672
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000673 x = PyInt_FromLong(LC_CTYPE);
674 PyDict_SetItemString(d, "LC_CTYPE", x);
675 Py_XDECREF(x);
676
677 x = PyInt_FromLong(LC_TIME);
678 PyDict_SetItemString(d, "LC_TIME", x);
679 Py_XDECREF(x);
680
681 x = PyInt_FromLong(LC_COLLATE);
682 PyDict_SetItemString(d, "LC_COLLATE", x);
683 Py_XDECREF(x);
684
685 x = PyInt_FromLong(LC_MONETARY);
686 PyDict_SetItemString(d, "LC_MONETARY", x);
687 Py_XDECREF(x);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000688
Guido van Rossum8d9c2e31997-12-09 19:35:11 +0000689#ifdef LC_MESSAGES
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000690 x = PyInt_FromLong(LC_MESSAGES);
691 PyDict_SetItemString(d, "LC_MESSAGES", x);
692 Py_XDECREF(x);
Guido van Rossum8d9c2e31997-12-09 19:35:11 +0000693#endif /* LC_MESSAGES */
Guido van Rossum220ecc81997-11-18 21:03:39 +0000694
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000695 x = PyInt_FromLong(LC_NUMERIC);
696 PyDict_SetItemString(d, "LC_NUMERIC", x);
697 Py_XDECREF(x);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000698
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000699 x = PyInt_FromLong(LC_ALL);
700 PyDict_SetItemString(d, "LC_ALL", x);
701 Py_XDECREF(x);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000702
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000703 x = PyInt_FromLong(CHAR_MAX);
704 PyDict_SetItemString(d, "CHAR_MAX", x);
705 Py_XDECREF(x);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000706
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000707 Error = PyErr_NewException("locale.Error", NULL, NULL);
708 PyDict_SetItemString(d, "Error", Error);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000709
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000710 x = PyString_FromString(locale__doc__);
711 PyDict_SetItemString(d, "__doc__", x);
712 Py_XDECREF(x);
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000713
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000714#ifdef HAVE_LANGINFO_H
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000715 for (i = 0; langinfo_constants[i].name; i++) {
716 PyModule_AddIntConstant(m, langinfo_constants[i].name,
717 langinfo_constants[i].value);
718 }
Martin v. Löwisf95dd0a2001-08-15 17:14:33 +0000719#endif
Guido van Rossum220ecc81997-11-18 21:03:39 +0000720}
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000721
722/*
723Local variables:
724c-basic-offset: 4
725indent-tabs-mode: nil
726End:
727*/