blob: 2cfda880f2c27e22750b5df1ff09884e9e4cf474 [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
54/* to record the LC_NUMERIC settings */
Fredrik Lundh8f017a02000-07-08 19:57:37 +000055static PyObject* grouping = NULL;
56static PyObject* thousands_sep = NULL;
57static PyObject* decimal_point = NULL;
Guido van Rossum220ecc81997-11-18 21:03:39 +000058/* if non-null, indicates that LC_NUMERIC is different from "C" */
Fredrik Lundh8f017a02000-07-08 19:57:37 +000059static char* saved_numeric = NULL;
Guido van Rossum220ecc81997-11-18 21:03:39 +000060
61/* the grouping is terminated by either 0 or CHAR_MAX */
62static PyObject*
Fredrik Lundh8f017a02000-07-08 19:57:37 +000063copy_grouping(char* s)
Guido van Rossum220ecc81997-11-18 21:03:39 +000064{
Fredrik Lundh8f017a02000-07-08 19:57:37 +000065 int i;
66 PyObject *result, *val = NULL;
67
68 if (s[0] == '\0')
69 /* empty string: no grouping at all */
70 return PyList_New(0);
71
72 for (i = 0; s[i] != '\0' && s[i] != CHAR_MAX; i++)
73 ; /* nothing */
74
75 result = PyList_New(i+1);
76 if (!result)
77 return NULL;
78
79 i = -1;
80 do {
81 i++;
82 val = PyInt_FromLong(s[i]);
83 if (!val)
84 break;
85 if (PyList_SetItem(result, i, val)) {
86 Py_DECREF(val);
Fredrik Lundh89610a42000-07-08 20:07:24 +000087 val = NULL;
Fredrik Lundh8f017a02000-07-08 19:57:37 +000088 break;
89 }
90 } while (s[i] != '\0' && s[i] != CHAR_MAX);
91
92 if (!val) {
93 Py_DECREF(result);
94 return NULL;
Guido van Rossum220ecc81997-11-18 21:03:39 +000095 }
Fredrik Lundh8f017a02000-07-08 19:57:37 +000096
97 return result;
Guido van Rossum220ecc81997-11-18 21:03:39 +000098}
99
100static void
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000101fixup_ulcase(void)
Guido van Rossum220ecc81997-11-18 21:03:39 +0000102{
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000103 PyObject *mods, *strop, *string, *ulo;
104 unsigned char ul[256];
105 int n, c;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000106
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000107 /* find the string and strop modules */
108 mods = PyImport_GetModuleDict();
109 if (!mods)
110 return;
111 string = PyDict_GetItemString(mods, "string");
112 if (string)
113 string = PyModule_GetDict(string);
114 strop=PyDict_GetItemString(mods, "strop");
115 if (strop)
116 strop = PyModule_GetDict(strop);
117 if (!string && !strop)
118 return;
119
120 /* create uppercase map string */
121 n = 0;
122 for (c = 0; c < 256; c++) {
123 if (isupper(c))
124 ul[n++] = c;
125 }
126 ulo = PyString_FromStringAndSize((const char *)ul, n);
Fredrik Lundh89610a42000-07-08 20:07:24 +0000127 if (!ulo)
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000128 return;
129 if (string)
130 PyDict_SetItemString(string, "uppercase", ulo);
131 if (strop)
132 PyDict_SetItemString(strop, "uppercase", ulo);
133 Py_DECREF(ulo);
134
135 /* create lowercase string */
136 n = 0;
137 for (c = 0; c < 256; c++) {
138 if (islower(c))
139 ul[n++] = c;
140 }
141 ulo = PyString_FromStringAndSize((const char *)ul, n);
142 if (!ulo)
143 return;
144 if (string)
145 PyDict_SetItemString(string, "lowercase", ulo);
146 if (strop)
147 PyDict_SetItemString(strop, "lowercase", ulo);
148 Py_DECREF(ulo);
149
150 /* create letters string */
151 n = 0;
152 for (c = 0; c < 256; c++) {
153 if (isalpha(c))
154 ul[n++] = c;
155 }
156 ulo = PyString_FromStringAndSize((const char *)ul, n);
157 if (!ulo)
158 return;
159 if (string)
160 PyDict_SetItemString(string, "letters", ulo);
161 Py_DECREF(ulo);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000162}
Martin v. Löwis7c82a3e02001-09-05 17:09:48 +0000163
Guido van Rossum220ecc81997-11-18 21:03:39 +0000164static PyObject*
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000165PyLocale_setlocale(PyObject* self, PyObject* args)
Guido van Rossum220ecc81997-11-18 21:03:39 +0000166{
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000167 int category;
168 char *locale = NULL, *result;
169 PyObject *result_object;
170 struct lconv *lc;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000171
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000172 if (!PyArg_ParseTuple(args, "i|z:setlocale", &category, &locale))
Fredrik Lundh89610a42000-07-08 20:07:24 +0000173 return NULL;
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000174
175 if (locale) {
176 /* set locale */
177 result = setlocale(category, locale);
178 if (!result) {
179 /* operation failed, no setting was changed */
Martin v. Löwis25f90d52003-09-03 04:50:13 +0000180 PyErr_SetString(Error, "unsupported locale setting");
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000181 return NULL;
182 }
183 result_object = PyString_FromString(result);
Mark Hammond9a714752003-07-24 14:15:07 +0000184 if (!result_object)
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000185 return NULL;
186 /* record changes to LC_NUMERIC */
187 if (category == LC_NUMERIC || category == LC_ALL) {
188 if (strcmp(locale, "C") == 0 || strcmp(locale, "POSIX") == 0) {
189 /* user just asked for default numeric locale */
190 if (saved_numeric)
191 free(saved_numeric);
192 saved_numeric = NULL;
193 } else {
194 /* remember values */
195 lc = localeconv();
196 Py_XDECREF(grouping);
197 grouping = copy_grouping(lc->grouping);
198 Py_XDECREF(thousands_sep);
199 thousands_sep = PyString_FromString(lc->thousands_sep);
200 Py_XDECREF(decimal_point);
201 decimal_point = PyString_FromString(lc->decimal_point);
Mark Hammond9a714752003-07-24 14:15:07 +0000202 if (saved_numeric)
203 free(saved_numeric);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000204 saved_numeric = strdup(locale);
205 /* restore to "C" */
206 setlocale(LC_NUMERIC, "C");
207 }
208 }
209 /* record changes to LC_CTYPE */
210 if (category == LC_CTYPE || category == LC_ALL)
211 fixup_ulcase();
212 /* things that got wrong up to here are ignored */
213 PyErr_Clear();
214 } else {
215 /* get locale */
216 /* restore LC_NUMERIC first, if appropriate */
217 if (saved_numeric)
218 setlocale(LC_NUMERIC, saved_numeric);
219 result = setlocale(category, NULL);
220 if (!result) {
221 PyErr_SetString(Error, "locale query failed");
222 return NULL;
223 }
224 result_object = PyString_FromString(result);
225 /* restore back to "C" */
226 if (saved_numeric)
227 setlocale(LC_NUMERIC, "C");
Guido van Rossum220ecc81997-11-18 21:03:39 +0000228 }
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000229 return result_object;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000230}
231
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000232PyDoc_STRVAR(localeconv__doc__,
233"() -> dict. Returns numeric and monetary locale-specific parameters.");
Guido van Rossum220ecc81997-11-18 21:03:39 +0000234
235static PyObject*
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000236PyLocale_localeconv(PyObject* self)
Guido van Rossum220ecc81997-11-18 21:03:39 +0000237{
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000238 PyObject* result;
239 struct lconv *l;
240 PyObject *x;
241
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000242 result = PyDict_New();
Fredrik Lundh89610a42000-07-08 20:07:24 +0000243 if (!result)
244 return NULL;
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000245
246 /* if LC_NUMERIC is different in the C library, use saved value */
247 l = localeconv();
248
249 /* hopefully, the localeconv result survives the C library calls
250 involved herein */
251
252#define RESULT_STRING(s)\
253 x = PyString_FromString(l->s);\
254 if (!x) goto failed;\
255 PyDict_SetItemString(result, #s, x);\
256 Py_XDECREF(x)
257
258#define RESULT_INT(i)\
259 x = PyInt_FromLong(l->i);\
260 if (!x) goto failed;\
261 PyDict_SetItemString(result, #i, x);\
262 Py_XDECREF(x)
Guido van Rossum220ecc81997-11-18 21:03:39 +0000263
264 /* Numeric information */
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000265 if (saved_numeric){
266 /* cannot use localeconv results */
267 PyDict_SetItemString(result, "decimal_point", decimal_point);
268 PyDict_SetItemString(result, "grouping", grouping);
269 PyDict_SetItemString(result, "thousands_sep", thousands_sep);
270 } else {
271 RESULT_STRING(decimal_point);
272 RESULT_STRING(thousands_sep);
273 x = copy_grouping(l->grouping);
274 if (!x)
275 goto failed;
276 PyDict_SetItemString(result, "grouping", x);
277 Py_XDECREF(x);
278 }
279
280 /* Monetary information */
281 RESULT_STRING(int_curr_symbol);
282 RESULT_STRING(currency_symbol);
283 RESULT_STRING(mon_decimal_point);
284 RESULT_STRING(mon_thousands_sep);
285 x = copy_grouping(l->mon_grouping);
286 if (!x)
287 goto failed;
288 PyDict_SetItemString(result, "mon_grouping", x);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000289 Py_XDECREF(x);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000290 RESULT_STRING(positive_sign);
291 RESULT_STRING(negative_sign);
292 RESULT_INT(int_frac_digits);
293 RESULT_INT(frac_digits);
294 RESULT_INT(p_cs_precedes);
295 RESULT_INT(p_sep_by_space);
296 RESULT_INT(n_cs_precedes);
297 RESULT_INT(n_sep_by_space);
298 RESULT_INT(p_sign_posn);
299 RESULT_INT(n_sign_posn);
300 return result;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000301
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000302 failed:
303 Py_XDECREF(result);
304 Py_XDECREF(x);
305 return NULL;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000306}
307
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000308PyDoc_STRVAR(strcoll__doc__,
309"string,string -> int. Compares two strings according to the locale.");
Guido van Rossum220ecc81997-11-18 21:03:39 +0000310
311static PyObject*
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000312PyLocale_strcoll(PyObject* self, PyObject* args)
Guido van Rossum220ecc81997-11-18 21:03:39 +0000313{
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000314#if !defined(HAVE_WCSCOLL) || !defined(Py_USING_UNICODE)
315 char *s1,*s2;
316
317 if (!PyArg_ParseTuple(args, "ss:strcoll", &s1, &s2))
318 return NULL;
319 return PyInt_FromLong(strcoll(s1, s2));
320#else
321 PyObject *os1, *os2, *result = NULL;
322 wchar_t *ws1 = NULL, *ws2 = NULL;
323 int rel1 = 0, rel2 = 0, len1, len2;
324
325 if (!PyArg_ParseTuple(args, "OO:strcoll", &os1, &os2))
326 return NULL;
327 /* If both arguments are byte strings, use strcoll. */
328 if (PyString_Check(os1) && PyString_Check(os2))
329 return PyInt_FromLong(strcoll(PyString_AS_STRING(os1),
330 PyString_AS_STRING(os2)));
331 /* If neither argument is unicode, it's an error. */
332 if (!PyUnicode_Check(os1) && !PyUnicode_Check(os2)) {
333 PyErr_SetString(PyExc_ValueError, "strcoll arguments must be strings");
334 }
335 /* Convert the non-unicode argument to unicode. */
336 if (!PyUnicode_Check(os1)) {
337 os1 = PyUnicode_FromObject(os1);
338 if (!os1)
339 return NULL;
340 rel1 = 1;
341 }
342 if (!PyUnicode_Check(os2)) {
343 os2 = PyUnicode_FromObject(os2);
344 if (!os2) {
345 Py_DECREF(os1);
346 return NULL;
347 }
348 rel2 = 1;
349 }
350 /* Convert the unicode strings to wchar[]. */
351 len1 = PyUnicode_GET_SIZE(os1) + 1;
352 len2 = PyUnicode_GET_SIZE(os2) + 1;
353 ws1 = PyMem_MALLOC(len1 * sizeof(wchar_t));
354 if (!ws1) {
355 PyErr_NoMemory();
356 goto done;
357 }
358 if (PyUnicode_AsWideChar((PyUnicodeObject*)os1, ws1, len1) == -1)
359 goto done;
360 ws2 = PyMem_MALLOC(len2 * sizeof(wchar_t));
361 if (!ws2) {
362 PyErr_NoMemory();
363 goto done;
364 }
365 if (PyUnicode_AsWideChar((PyUnicodeObject*)os2, ws2, len2) == -1)
366 goto done;
367 /* Collate the strings. */
368 result = PyInt_FromLong(wcscoll(ws1, ws2));
369 done:
370 /* Deallocate everything. */
371 if (ws1) PyMem_FREE(ws1);
372 if (ws2) PyMem_FREE(ws2);
373 if (rel1) {
374 Py_DECREF(os1);
375 }
376 if (rel2) {
377 Py_DECREF(os2);
378 }
379 return result;
380#endif
Guido van Rossum220ecc81997-11-18 21:03:39 +0000381}
382
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000383
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000384PyDoc_STRVAR(strxfrm__doc__,
385"string -> string. Returns a string that behaves for cmp locale-aware.");
Guido van Rossum220ecc81997-11-18 21:03:39 +0000386
387static PyObject*
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000388PyLocale_strxfrm(PyObject* self, PyObject* args)
Guido van Rossum220ecc81997-11-18 21:03:39 +0000389{
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000390 char *s, *buf;
391 size_t n1, n2;
392 PyObject *result;
393
Fredrik Lundh89610a42000-07-08 20:07:24 +0000394 if (!PyArg_ParseTuple(args, "s:strxfrm", &s))
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000395 return NULL;
396
397 /* assume no change in size, first */
398 n1 = strlen(s) + 1;
399 buf = PyMem_Malloc(n1);
400 if (!buf)
401 return PyErr_NoMemory();
402 n2 = strxfrm(buf, s, n1);
403 if (n2 > n1) {
404 /* more space needed */
405 buf = PyMem_Realloc(buf, n2);
406 if (!buf)
407 return PyErr_NoMemory();
408 strxfrm(buf, s, n2);
409 }
410 result = PyString_FromString(buf);
411 PyMem_Free(buf);
412 return result;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000413}
414
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000415#if defined(MS_WINDOWS)
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000416static PyObject*
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000417PyLocale_getdefaultlocale(PyObject* self)
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000418{
419 char encoding[100];
420 char locale[100];
421
Tim Peters885d4572001-11-28 20:27:42 +0000422 PyOS_snprintf(encoding, sizeof(encoding), "cp%d", GetACP());
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000423
424 if (GetLocaleInfo(LOCALE_USER_DEFAULT,
425 LOCALE_SISO639LANGNAME,
426 locale, sizeof(locale))) {
427 int i = strlen(locale);
428 locale[i++] = '_';
429 if (GetLocaleInfo(LOCALE_USER_DEFAULT,
430 LOCALE_SISO3166CTRYNAME,
431 locale+i, sizeof(locale)-i))
432 return Py_BuildValue("ss", locale, encoding);
433 }
434
435 /* If we end up here, this windows version didn't know about
436 ISO639/ISO3166 names (it's probably Windows 95). Return the
437 Windows language identifier instead (a hexadecimal number) */
438
439 locale[0] = '0';
440 locale[1] = 'x';
441 if (GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_IDEFAULTLANGUAGE,
442 locale+2, sizeof(locale)-2)) {
443 return Py_BuildValue("ss", locale, encoding);
444 }
445
446 /* cannot determine the language code (very unlikely) */
447 Py_INCREF(Py_None);
448 return Py_BuildValue("Os", Py_None, encoding);
449}
450#endif
451
Martin v. Löwis52ea7e92002-11-26 09:05:36 +0000452#if defined(__APPLE__)
Jack Jansen307d7a42000-07-15 22:31:45 +0000453static PyObject*
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000454PyLocale_getdefaultlocale(PyObject* self)
Jack Jansen307d7a42000-07-15 22:31:45 +0000455{
456 return Py_BuildValue("Os", Py_None, PyMac_getscript());
457}
458#endif
459
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000460#ifdef HAVE_LANGINFO_H
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000461#define LANGINFO(X) {#X, X}
462struct langinfo_constant{
463 char* name;
464 int value;
465} langinfo_constants[] =
466{
467 /* These constants should exist on any langinfo implementation */
468 LANGINFO(DAY_1),
469 LANGINFO(DAY_2),
470 LANGINFO(DAY_3),
471 LANGINFO(DAY_4),
472 LANGINFO(DAY_5),
473 LANGINFO(DAY_6),
474 LANGINFO(DAY_7),
475
476 LANGINFO(ABDAY_1),
477 LANGINFO(ABDAY_2),
478 LANGINFO(ABDAY_3),
479 LANGINFO(ABDAY_4),
480 LANGINFO(ABDAY_5),
481 LANGINFO(ABDAY_6),
482 LANGINFO(ABDAY_7),
483
484 LANGINFO(MON_1),
485 LANGINFO(MON_2),
486 LANGINFO(MON_3),
487 LANGINFO(MON_4),
488 LANGINFO(MON_5),
489 LANGINFO(MON_6),
490 LANGINFO(MON_7),
491 LANGINFO(MON_8),
492 LANGINFO(MON_9),
493 LANGINFO(MON_10),
494 LANGINFO(MON_11),
495 LANGINFO(MON_12),
496
497 LANGINFO(ABMON_1),
498 LANGINFO(ABMON_2),
499 LANGINFO(ABMON_3),
500 LANGINFO(ABMON_4),
501 LANGINFO(ABMON_5),
502 LANGINFO(ABMON_6),
503 LANGINFO(ABMON_7),
504 LANGINFO(ABMON_8),
505 LANGINFO(ABMON_9),
506 LANGINFO(ABMON_10),
507 LANGINFO(ABMON_11),
508 LANGINFO(ABMON_12),
509
510#ifdef RADIXCHAR
511 /* The following are not available with glibc 2.0 */
512 LANGINFO(RADIXCHAR),
513 LANGINFO(THOUSEP),
514 /* YESSTR and NOSTR are deprecated in glibc, since they are
515 a special case of message translation, which should be rather
516 done using gettext. So we don't expose it to Python in the
517 first place.
518 LANGINFO(YESSTR),
519 LANGINFO(NOSTR),
520 */
521 LANGINFO(CRNCYSTR),
522#endif
523
524 LANGINFO(D_T_FMT),
525 LANGINFO(D_FMT),
526 LANGINFO(T_FMT),
527 LANGINFO(AM_STR),
528 LANGINFO(PM_STR),
529
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000530 /* The following constants are available only with XPG4, but...
531 AIX 3.2. only has CODESET.
532 OpenBSD doesn't have CODESET but has T_FMT_AMPM, and doesn't have
533 a few of the others.
534 Solution: ifdef-test them all. */
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000535#ifdef CODESET
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000536 LANGINFO(CODESET),
Martin v. Löwis496f9e42002-03-27 12:15:57 +0000537#endif
538#ifdef T_FMT_AMPM
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000539 LANGINFO(T_FMT_AMPM),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000540#endif
541#ifdef ERA
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000542 LANGINFO(ERA),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000543#endif
544#ifdef ERA_D_FMT
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000545 LANGINFO(ERA_D_FMT),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000546#endif
547#ifdef ERA_D_T_FMT
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000548 LANGINFO(ERA_D_T_FMT),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000549#endif
550#ifdef ERA_T_FMT
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000551 LANGINFO(ERA_T_FMT),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000552#endif
553#ifdef ALT_DIGITS
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000554 LANGINFO(ALT_DIGITS),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000555#endif
556#ifdef YESEXPR
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000557 LANGINFO(YESEXPR),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000558#endif
559#ifdef NOEXPR
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000560 LANGINFO(NOEXPR),
561#endif
562#ifdef _DATE_FMT
563 /* This is not available in all glibc versions that have CODESET. */
564 LANGINFO(_DATE_FMT),
565#endif
566 {0, 0}
567};
568
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000569PyDoc_STRVAR(nl_langinfo__doc__,
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000570"nl_langinfo(key) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000571"Return the value for the locale information associated with key.");
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000572
573static PyObject*
574PyLocale_nl_langinfo(PyObject* self, PyObject* args)
575{
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000576 int item, i;
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000577 if (!PyArg_ParseTuple(args, "i:nl_langinfo", &item))
578 return NULL;
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000579 /* Check whether this is a supported constant. GNU libc sometimes
580 returns numeric values in the char* return value, which would
581 crash PyString_FromString. */
Martin v. Löwisf5b93732003-09-04 18:24:47 +0000582#ifdef RADIXCHAR
583 if (saved_numeric) {
584 if(item == RADIXCHAR) {
585 Py_INCREF(decimal_point);
586 return decimal_point;
587 }
588 if(item == THOUSEP) {
589 Py_INCREF(thousands_sep);
590 return thousands_sep;
591 }
592 }
593#endif
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000594 for (i = 0; langinfo_constants[i].name; i++)
595 if (langinfo_constants[i].value == item)
596 return PyString_FromString(nl_langinfo(item));
597 PyErr_SetString(PyExc_ValueError, "unsupported langinfo constant");
598 return NULL;
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000599}
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000600#endif /* HAVE_LANGINFO_H */
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000601
602#ifdef HAVE_LIBINTL_H
603
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000604PyDoc_STRVAR(gettext__doc__,
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000605"gettext(msg) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000606"Return translation of msg.");
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000607
608static PyObject*
609PyIntl_gettext(PyObject* self, PyObject *args)
610{
611 char *in;
612 if (!PyArg_ParseTuple(args, "z", &in))
613 return 0;
614 return PyString_FromString(gettext(in));
615}
616
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000617PyDoc_STRVAR(dgettext__doc__,
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000618"dgettext(domain, msg) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000619"Return translation of msg in domain.");
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000620
621static PyObject*
622PyIntl_dgettext(PyObject* self, PyObject *args)
623{
624 char *domain, *in;
625 if (!PyArg_ParseTuple(args, "zz", &domain, &in))
626 return 0;
627 return PyString_FromString(dgettext(domain, in));
628}
629
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000630PyDoc_STRVAR(dcgettext__doc__,
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000631"dcgettext(domain, msg, category) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000632"Return translation of msg in domain and category.");
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000633
634static PyObject*
635PyIntl_dcgettext(PyObject *self, PyObject *args)
636{
637 char *domain, *msgid;
638 int category;
639 if (!PyArg_ParseTuple(args, "zzi", &domain, &msgid, &category))
640 return 0;
641 return PyString_FromString(dcgettext(domain,msgid,category));
642}
643
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000644PyDoc_STRVAR(textdomain__doc__,
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000645"textdomain(domain) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000646"Set the C library's textdmain to domain, returning the new domain.");
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000647
648static PyObject*
649PyIntl_textdomain(PyObject* self, PyObject* args)
650{
651 char *domain;
652 if (!PyArg_ParseTuple(args, "z", &domain))
653 return 0;
654 domain = textdomain(domain);
655 if (!domain) {
656 PyErr_SetFromErrno(PyExc_OSError);
657 return NULL;
658 }
659 return PyString_FromString(domain);
660}
661
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000662PyDoc_STRVAR(bindtextdomain__doc__,
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000663"bindtextdomain(domain, dir) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000664"Bind the C library's domain to dir.");
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000665
666static PyObject*
667PyIntl_bindtextdomain(PyObject* self,PyObject*args)
668{
669 char *domain,*dirname;
670 if (!PyArg_ParseTuple(args, "zz", &domain, &dirname))
671 return 0;
672 dirname = bindtextdomain(domain, dirname);
673 if (!dirname) {
674 PyErr_SetFromErrno(PyExc_OSError);
675 return NULL;
676 }
677 return PyString_FromString(dirname);
678}
679
680#endif
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000681
Guido van Rossum220ecc81997-11-18 21:03:39 +0000682static struct PyMethodDef PyLocale_Methods[] = {
Andrew M. Kuchlinge365fb82000-08-03 02:06:16 +0000683 {"setlocale", (PyCFunction) PyLocale_setlocale,
684 METH_VARARGS, setlocale__doc__},
685 {"localeconv", (PyCFunction) PyLocale_localeconv,
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000686 METH_NOARGS, localeconv__doc__},
Andrew M. Kuchlinge365fb82000-08-03 02:06:16 +0000687 {"strcoll", (PyCFunction) PyLocale_strcoll,
688 METH_VARARGS, strcoll__doc__},
689 {"strxfrm", (PyCFunction) PyLocale_strxfrm,
690 METH_VARARGS, strxfrm__doc__},
Martin v. Löwis52ea7e92002-11-26 09:05:36 +0000691#if defined(MS_WINDOWS) || defined(__APPLE__)
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000692 {"_getdefaultlocale", (PyCFunction) PyLocale_getdefaultlocale, METH_NOARGS},
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000693#endif
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000694#ifdef HAVE_LANGINFO_H
695 {"nl_langinfo", (PyCFunction) PyLocale_nl_langinfo,
696 METH_VARARGS, nl_langinfo__doc__},
697#endif
Martin v. Löwisc6a7d7e2002-05-02 12:16:29 +0000698#ifdef HAVE_LIBINTL_H
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000699 {"gettext",(PyCFunction)PyIntl_gettext,METH_VARARGS,
700 gettext__doc__},
701 {"dgettext",(PyCFunction)PyIntl_dgettext,METH_VARARGS,
702 dgettext__doc__},
703 {"dcgettext",(PyCFunction)PyIntl_dcgettext,METH_VARARGS,
704 dcgettext__doc__},
705 {"textdomain",(PyCFunction)PyIntl_textdomain,METH_VARARGS,
706 textdomain__doc__},
707 {"bindtextdomain",(PyCFunction)PyIntl_bindtextdomain,METH_VARARGS,
708 bindtextdomain__doc__},
709#endif
Guido van Rossum220ecc81997-11-18 21:03:39 +0000710 {NULL, NULL}
711};
712
Mark Hammondfe51c6d2002-08-02 02:27:13 +0000713PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000714init_locale(void)
Guido van Rossum220ecc81997-11-18 21:03:39 +0000715{
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000716 PyObject *m, *d, *x;
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000717#ifdef HAVE_LANGINFO_H
718 int i;
719#endif
Guido van Rossum220ecc81997-11-18 21:03:39 +0000720
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000721 m = Py_InitModule("_locale", PyLocale_Methods);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000722
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000723 d = PyModule_GetDict(m);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000724
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000725 x = PyInt_FromLong(LC_CTYPE);
726 PyDict_SetItemString(d, "LC_CTYPE", x);
727 Py_XDECREF(x);
728
729 x = PyInt_FromLong(LC_TIME);
730 PyDict_SetItemString(d, "LC_TIME", x);
731 Py_XDECREF(x);
732
733 x = PyInt_FromLong(LC_COLLATE);
734 PyDict_SetItemString(d, "LC_COLLATE", x);
735 Py_XDECREF(x);
736
737 x = PyInt_FromLong(LC_MONETARY);
738 PyDict_SetItemString(d, "LC_MONETARY", x);
739 Py_XDECREF(x);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000740
Guido van Rossum8d9c2e31997-12-09 19:35:11 +0000741#ifdef LC_MESSAGES
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000742 x = PyInt_FromLong(LC_MESSAGES);
743 PyDict_SetItemString(d, "LC_MESSAGES", x);
744 Py_XDECREF(x);
Guido van Rossum8d9c2e31997-12-09 19:35:11 +0000745#endif /* LC_MESSAGES */
Guido van Rossum220ecc81997-11-18 21:03:39 +0000746
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000747 x = PyInt_FromLong(LC_NUMERIC);
748 PyDict_SetItemString(d, "LC_NUMERIC", x);
749 Py_XDECREF(x);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000750
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000751 x = PyInt_FromLong(LC_ALL);
752 PyDict_SetItemString(d, "LC_ALL", x);
753 Py_XDECREF(x);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000754
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000755 x = PyInt_FromLong(CHAR_MAX);
756 PyDict_SetItemString(d, "CHAR_MAX", x);
757 Py_XDECREF(x);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000758
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000759 Error = PyErr_NewException("locale.Error", NULL, NULL);
760 PyDict_SetItemString(d, "Error", Error);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000761
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000762 x = PyString_FromString(locale__doc__);
763 PyDict_SetItemString(d, "__doc__", x);
764 Py_XDECREF(x);
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000765
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000766#ifdef HAVE_LANGINFO_H
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000767 for (i = 0; langinfo_constants[i].name; i++) {
768 PyModule_AddIntConstant(m, langinfo_constants[i].name,
769 langinfo_constants[i].value);
770 }
Martin v. Löwisf95dd0a2001-08-15 17:14:33 +0000771#endif
Guido van Rossum220ecc81997-11-18 21:03:39 +0000772}
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000773
774/*
775Local variables:
776c-basic-offset: 4
777indent-tabs-mode: nil
778End:
779*/