blob: 840f8385f20668dae899d8326ce59db8be2eb77d [file] [log] [blame]
Guido van Rossum220ecc81997-11-18 21:03:39 +00001/***********************************************************
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +00002Copyright (C) 1997, 2002 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
Martin v. Löwis6238d2b2002-06-30 15:26:10 +000032#if defined(MS_WINDOWS)
Tim Peters7a1f9172002-07-14 22:14:19 +000033#define WIN32_LEAN_AND_MEAN
Fredrik Lundh8f017a02000-07-08 19:57:37 +000034#include <windows.h>
Guido van Rossum239a2181998-04-28 16:08:19 +000035#endif
Guido van Rossum220ecc81997-11-18 21:03:39 +000036
Jack Jansen747c3d32002-12-13 15:20:53 +000037#if defined(__APPLE__) || defined(__MWERKS__)
Jack Jansen307d7a42000-07-15 22:31:45 +000038#include "macglue.h"
Fredrik Lundh8f017a02000-07-08 19:57:37 +000039#endif
40
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 */
180 PyErr_SetString(Error, "locale setting not supported");
181 return NULL;
182 }
183 result_object = PyString_FromString(result);
184 if (!result)
185 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);
202 saved_numeric = strdup(locale);
203 /* restore to "C" */
204 setlocale(LC_NUMERIC, "C");
205 }
206 }
207 /* record changes to LC_CTYPE */
208 if (category == LC_CTYPE || category == LC_ALL)
209 fixup_ulcase();
210 /* things that got wrong up to here are ignored */
211 PyErr_Clear();
212 } else {
213 /* get locale */
214 /* restore LC_NUMERIC first, if appropriate */
215 if (saved_numeric)
216 setlocale(LC_NUMERIC, saved_numeric);
217 result = setlocale(category, NULL);
218 if (!result) {
219 PyErr_SetString(Error, "locale query failed");
220 return NULL;
221 }
222 result_object = PyString_FromString(result);
223 /* restore back to "C" */
224 if (saved_numeric)
225 setlocale(LC_NUMERIC, "C");
Guido van Rossum220ecc81997-11-18 21:03:39 +0000226 }
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000227 return result_object;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000228}
229
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000230PyDoc_STRVAR(localeconv__doc__,
231"() -> dict. Returns numeric and monetary locale-specific parameters.");
Guido van Rossum220ecc81997-11-18 21:03:39 +0000232
233static PyObject*
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000234PyLocale_localeconv(PyObject* self)
Guido van Rossum220ecc81997-11-18 21:03:39 +0000235{
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000236 PyObject* result;
237 struct lconv *l;
238 PyObject *x;
239
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000240 result = PyDict_New();
Fredrik Lundh89610a42000-07-08 20:07:24 +0000241 if (!result)
242 return NULL;
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000243
244 /* if LC_NUMERIC is different in the C library, use saved value */
245 l = localeconv();
246
247 /* hopefully, the localeconv result survives the C library calls
248 involved herein */
249
250#define RESULT_STRING(s)\
251 x = PyString_FromString(l->s);\
252 if (!x) goto failed;\
253 PyDict_SetItemString(result, #s, x);\
254 Py_XDECREF(x)
255
256#define RESULT_INT(i)\
257 x = PyInt_FromLong(l->i);\
258 if (!x) goto failed;\
259 PyDict_SetItemString(result, #i, x);\
260 Py_XDECREF(x)
Guido van Rossum220ecc81997-11-18 21:03:39 +0000261
262 /* Numeric information */
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000263 if (saved_numeric){
264 /* cannot use localeconv results */
265 PyDict_SetItemString(result, "decimal_point", decimal_point);
266 PyDict_SetItemString(result, "grouping", grouping);
267 PyDict_SetItemString(result, "thousands_sep", thousands_sep);
268 } else {
269 RESULT_STRING(decimal_point);
270 RESULT_STRING(thousands_sep);
271 x = copy_grouping(l->grouping);
272 if (!x)
273 goto failed;
274 PyDict_SetItemString(result, "grouping", x);
275 Py_XDECREF(x);
276 }
277
278 /* Monetary information */
279 RESULT_STRING(int_curr_symbol);
280 RESULT_STRING(currency_symbol);
281 RESULT_STRING(mon_decimal_point);
282 RESULT_STRING(mon_thousands_sep);
283 x = copy_grouping(l->mon_grouping);
284 if (!x)
285 goto failed;
286 PyDict_SetItemString(result, "mon_grouping", x);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000287 Py_XDECREF(x);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000288 RESULT_STRING(positive_sign);
289 RESULT_STRING(negative_sign);
290 RESULT_INT(int_frac_digits);
291 RESULT_INT(frac_digits);
292 RESULT_INT(p_cs_precedes);
293 RESULT_INT(p_sep_by_space);
294 RESULT_INT(n_cs_precedes);
295 RESULT_INT(n_sep_by_space);
296 RESULT_INT(p_sign_posn);
297 RESULT_INT(n_sign_posn);
298 return result;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000299
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000300 failed:
301 Py_XDECREF(result);
302 Py_XDECREF(x);
303 return NULL;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000304}
305
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000306PyDoc_STRVAR(strcoll__doc__,
307"string,string -> int. Compares two strings according to the locale.");
Guido van Rossum220ecc81997-11-18 21:03:39 +0000308
309static PyObject*
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000310PyLocale_strcoll(PyObject* self, PyObject* args)
Guido van Rossum220ecc81997-11-18 21:03:39 +0000311{
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000312#if !defined(HAVE_WCSCOLL) || !defined(Py_USING_UNICODE)
313 char *s1,*s2;
314
315 if (!PyArg_ParseTuple(args, "ss:strcoll", &s1, &s2))
316 return NULL;
317 return PyInt_FromLong(strcoll(s1, s2));
318#else
319 PyObject *os1, *os2, *result = NULL;
320 wchar_t *ws1 = NULL, *ws2 = NULL;
321 int rel1 = 0, rel2 = 0, len1, len2;
322
323 if (!PyArg_ParseTuple(args, "OO:strcoll", &os1, &os2))
324 return NULL;
325 /* If both arguments are byte strings, use strcoll. */
326 if (PyString_Check(os1) && PyString_Check(os2))
327 return PyInt_FromLong(strcoll(PyString_AS_STRING(os1),
328 PyString_AS_STRING(os2)));
329 /* If neither argument is unicode, it's an error. */
330 if (!PyUnicode_Check(os1) && !PyUnicode_Check(os2)) {
331 PyErr_SetString(PyExc_ValueError, "strcoll arguments must be strings");
332 }
333 /* Convert the non-unicode argument to unicode. */
334 if (!PyUnicode_Check(os1)) {
335 os1 = PyUnicode_FromObject(os1);
336 if (!os1)
337 return NULL;
338 rel1 = 1;
339 }
340 if (!PyUnicode_Check(os2)) {
341 os2 = PyUnicode_FromObject(os2);
342 if (!os2) {
343 Py_DECREF(os1);
344 return NULL;
345 }
346 rel2 = 1;
347 }
348 /* Convert the unicode strings to wchar[]. */
349 len1 = PyUnicode_GET_SIZE(os1) + 1;
350 len2 = PyUnicode_GET_SIZE(os2) + 1;
351 ws1 = PyMem_MALLOC(len1 * sizeof(wchar_t));
352 if (!ws1) {
353 PyErr_NoMemory();
354 goto done;
355 }
356 if (PyUnicode_AsWideChar((PyUnicodeObject*)os1, ws1, len1) == -1)
357 goto done;
358 ws2 = PyMem_MALLOC(len2 * sizeof(wchar_t));
359 if (!ws2) {
360 PyErr_NoMemory();
361 goto done;
362 }
363 if (PyUnicode_AsWideChar((PyUnicodeObject*)os2, ws2, len2) == -1)
364 goto done;
365 /* Collate the strings. */
366 result = PyInt_FromLong(wcscoll(ws1, ws2));
367 done:
368 /* Deallocate everything. */
369 if (ws1) PyMem_FREE(ws1);
370 if (ws2) PyMem_FREE(ws2);
371 if (rel1) {
372 Py_DECREF(os1);
373 }
374 if (rel2) {
375 Py_DECREF(os2);
376 }
377 return result;
378#endif
Guido van Rossum220ecc81997-11-18 21:03:39 +0000379}
380
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000381
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000382PyDoc_STRVAR(strxfrm__doc__,
383"string -> string. Returns a string that behaves for cmp locale-aware.");
Guido van Rossum220ecc81997-11-18 21:03:39 +0000384
385static PyObject*
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000386PyLocale_strxfrm(PyObject* self, PyObject* args)
Guido van Rossum220ecc81997-11-18 21:03:39 +0000387{
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000388 char *s, *buf;
389 size_t n1, n2;
390 PyObject *result;
391
Fredrik Lundh89610a42000-07-08 20:07:24 +0000392 if (!PyArg_ParseTuple(args, "s:strxfrm", &s))
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000393 return NULL;
394
395 /* assume no change in size, first */
396 n1 = strlen(s) + 1;
397 buf = PyMem_Malloc(n1);
398 if (!buf)
399 return PyErr_NoMemory();
400 n2 = strxfrm(buf, s, n1);
401 if (n2 > n1) {
402 /* more space needed */
403 buf = PyMem_Realloc(buf, n2);
404 if (!buf)
405 return PyErr_NoMemory();
406 strxfrm(buf, s, n2);
407 }
408 result = PyString_FromString(buf);
409 PyMem_Free(buf);
410 return result;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000411}
412
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000413#if defined(MS_WINDOWS)
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000414static PyObject*
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000415PyLocale_getdefaultlocale(PyObject* self)
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000416{
417 char encoding[100];
418 char locale[100];
419
Tim Peters885d4572001-11-28 20:27:42 +0000420 PyOS_snprintf(encoding, sizeof(encoding), "cp%d", GetACP());
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000421
422 if (GetLocaleInfo(LOCALE_USER_DEFAULT,
423 LOCALE_SISO639LANGNAME,
424 locale, sizeof(locale))) {
425 int i = strlen(locale);
426 locale[i++] = '_';
427 if (GetLocaleInfo(LOCALE_USER_DEFAULT,
428 LOCALE_SISO3166CTRYNAME,
429 locale+i, sizeof(locale)-i))
430 return Py_BuildValue("ss", locale, encoding);
431 }
432
433 /* If we end up here, this windows version didn't know about
434 ISO639/ISO3166 names (it's probably Windows 95). Return the
435 Windows language identifier instead (a hexadecimal number) */
436
437 locale[0] = '0';
438 locale[1] = 'x';
439 if (GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_IDEFAULTLANGUAGE,
440 locale+2, sizeof(locale)-2)) {
441 return Py_BuildValue("ss", locale, encoding);
442 }
443
444 /* cannot determine the language code (very unlikely) */
445 Py_INCREF(Py_None);
446 return Py_BuildValue("Os", Py_None, encoding);
447}
448#endif
449
Martin v. Löwis52ea7e92002-11-26 09:05:36 +0000450#if defined(__APPLE__)
Jack Jansen307d7a42000-07-15 22:31:45 +0000451static PyObject*
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000452PyLocale_getdefaultlocale(PyObject* self)
Jack Jansen307d7a42000-07-15 22:31:45 +0000453{
454 return Py_BuildValue("Os", Py_None, PyMac_getscript());
455}
456#endif
457
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000458#ifdef HAVE_LANGINFO_H
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000459#define LANGINFO(X) {#X, X}
460struct langinfo_constant{
461 char* name;
462 int value;
463} langinfo_constants[] =
464{
465 /* These constants should exist on any langinfo implementation */
466 LANGINFO(DAY_1),
467 LANGINFO(DAY_2),
468 LANGINFO(DAY_3),
469 LANGINFO(DAY_4),
470 LANGINFO(DAY_5),
471 LANGINFO(DAY_6),
472 LANGINFO(DAY_7),
473
474 LANGINFO(ABDAY_1),
475 LANGINFO(ABDAY_2),
476 LANGINFO(ABDAY_3),
477 LANGINFO(ABDAY_4),
478 LANGINFO(ABDAY_5),
479 LANGINFO(ABDAY_6),
480 LANGINFO(ABDAY_7),
481
482 LANGINFO(MON_1),
483 LANGINFO(MON_2),
484 LANGINFO(MON_3),
485 LANGINFO(MON_4),
486 LANGINFO(MON_5),
487 LANGINFO(MON_6),
488 LANGINFO(MON_7),
489 LANGINFO(MON_8),
490 LANGINFO(MON_9),
491 LANGINFO(MON_10),
492 LANGINFO(MON_11),
493 LANGINFO(MON_12),
494
495 LANGINFO(ABMON_1),
496 LANGINFO(ABMON_2),
497 LANGINFO(ABMON_3),
498 LANGINFO(ABMON_4),
499 LANGINFO(ABMON_5),
500 LANGINFO(ABMON_6),
501 LANGINFO(ABMON_7),
502 LANGINFO(ABMON_8),
503 LANGINFO(ABMON_9),
504 LANGINFO(ABMON_10),
505 LANGINFO(ABMON_11),
506 LANGINFO(ABMON_12),
507
508#ifdef RADIXCHAR
509 /* The following are not available with glibc 2.0 */
510 LANGINFO(RADIXCHAR),
511 LANGINFO(THOUSEP),
512 /* YESSTR and NOSTR are deprecated in glibc, since they are
513 a special case of message translation, which should be rather
514 done using gettext. So we don't expose it to Python in the
515 first place.
516 LANGINFO(YESSTR),
517 LANGINFO(NOSTR),
518 */
519 LANGINFO(CRNCYSTR),
520#endif
521
522 LANGINFO(D_T_FMT),
523 LANGINFO(D_FMT),
524 LANGINFO(T_FMT),
525 LANGINFO(AM_STR),
526 LANGINFO(PM_STR),
527
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000528 /* The following constants are available only with XPG4, but...
529 AIX 3.2. only has CODESET.
530 OpenBSD doesn't have CODESET but has T_FMT_AMPM, and doesn't have
531 a few of the others.
532 Solution: ifdef-test them all. */
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000533#ifdef CODESET
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000534 LANGINFO(CODESET),
Martin v. Löwis496f9e42002-03-27 12:15:57 +0000535#endif
536#ifdef T_FMT_AMPM
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000537 LANGINFO(T_FMT_AMPM),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000538#endif
539#ifdef ERA
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000540 LANGINFO(ERA),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000541#endif
542#ifdef ERA_D_FMT
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000543 LANGINFO(ERA_D_FMT),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000544#endif
545#ifdef ERA_D_T_FMT
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000546 LANGINFO(ERA_D_T_FMT),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000547#endif
548#ifdef ERA_T_FMT
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000549 LANGINFO(ERA_T_FMT),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000550#endif
551#ifdef ALT_DIGITS
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000552 LANGINFO(ALT_DIGITS),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000553#endif
554#ifdef YESEXPR
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000555 LANGINFO(YESEXPR),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000556#endif
557#ifdef NOEXPR
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000558 LANGINFO(NOEXPR),
559#endif
560#ifdef _DATE_FMT
561 /* This is not available in all glibc versions that have CODESET. */
562 LANGINFO(_DATE_FMT),
563#endif
564 {0, 0}
565};
566
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000567PyDoc_STRVAR(nl_langinfo__doc__,
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000568"nl_langinfo(key) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000569"Return the value for the locale information associated with key.");
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000570
571static PyObject*
572PyLocale_nl_langinfo(PyObject* self, PyObject* args)
573{
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000574 int item, i;
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000575 if (!PyArg_ParseTuple(args, "i:nl_langinfo", &item))
576 return NULL;
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000577 /* Check whether this is a supported constant. GNU libc sometimes
578 returns numeric values in the char* return value, which would
579 crash PyString_FromString. */
580 for (i = 0; langinfo_constants[i].name; i++)
581 if (langinfo_constants[i].value == item)
582 return PyString_FromString(nl_langinfo(item));
583 PyErr_SetString(PyExc_ValueError, "unsupported langinfo constant");
584 return NULL;
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000585}
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000586#endif /* HAVE_LANGINFO_H */
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000587
588#ifdef HAVE_LIBINTL_H
589
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000590PyDoc_STRVAR(gettext__doc__,
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000591"gettext(msg) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000592"Return translation of msg.");
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000593
594static PyObject*
595PyIntl_gettext(PyObject* self, PyObject *args)
596{
597 char *in;
598 if (!PyArg_ParseTuple(args, "z", &in))
599 return 0;
600 return PyString_FromString(gettext(in));
601}
602
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000603PyDoc_STRVAR(dgettext__doc__,
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000604"dgettext(domain, msg) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000605"Return translation of msg in domain.");
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000606
607static PyObject*
608PyIntl_dgettext(PyObject* self, PyObject *args)
609{
610 char *domain, *in;
611 if (!PyArg_ParseTuple(args, "zz", &domain, &in))
612 return 0;
613 return PyString_FromString(dgettext(domain, in));
614}
615
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000616PyDoc_STRVAR(dcgettext__doc__,
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000617"dcgettext(domain, msg, category) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000618"Return translation of msg in domain and category.");
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000619
620static PyObject*
621PyIntl_dcgettext(PyObject *self, PyObject *args)
622{
623 char *domain, *msgid;
624 int category;
625 if (!PyArg_ParseTuple(args, "zzi", &domain, &msgid, &category))
626 return 0;
627 return PyString_FromString(dcgettext(domain,msgid,category));
628}
629
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000630PyDoc_STRVAR(textdomain__doc__,
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000631"textdomain(domain) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000632"Set the C library's textdmain to domain, returning the new domain.");
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000633
634static PyObject*
635PyIntl_textdomain(PyObject* self, PyObject* args)
636{
637 char *domain;
638 if (!PyArg_ParseTuple(args, "z", &domain))
639 return 0;
640 domain = textdomain(domain);
641 if (!domain) {
642 PyErr_SetFromErrno(PyExc_OSError);
643 return NULL;
644 }
645 return PyString_FromString(domain);
646}
647
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000648PyDoc_STRVAR(bindtextdomain__doc__,
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000649"bindtextdomain(domain, dir) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000650"Bind the C library's domain to dir.");
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000651
652static PyObject*
653PyIntl_bindtextdomain(PyObject* self,PyObject*args)
654{
655 char *domain,*dirname;
656 if (!PyArg_ParseTuple(args, "zz", &domain, &dirname))
657 return 0;
658 dirname = bindtextdomain(domain, dirname);
659 if (!dirname) {
660 PyErr_SetFromErrno(PyExc_OSError);
661 return NULL;
662 }
663 return PyString_FromString(dirname);
664}
665
666#endif
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000667
Guido van Rossum220ecc81997-11-18 21:03:39 +0000668static struct PyMethodDef PyLocale_Methods[] = {
Andrew M. Kuchlinge365fb82000-08-03 02:06:16 +0000669 {"setlocale", (PyCFunction) PyLocale_setlocale,
670 METH_VARARGS, setlocale__doc__},
671 {"localeconv", (PyCFunction) PyLocale_localeconv,
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000672 METH_NOARGS, localeconv__doc__},
Andrew M. Kuchlinge365fb82000-08-03 02:06:16 +0000673 {"strcoll", (PyCFunction) PyLocale_strcoll,
674 METH_VARARGS, strcoll__doc__},
675 {"strxfrm", (PyCFunction) PyLocale_strxfrm,
676 METH_VARARGS, strxfrm__doc__},
Martin v. Löwis52ea7e92002-11-26 09:05:36 +0000677#if defined(MS_WINDOWS) || defined(__APPLE__)
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000678 {"_getdefaultlocale", (PyCFunction) PyLocale_getdefaultlocale, METH_NOARGS},
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000679#endif
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000680#ifdef HAVE_LANGINFO_H
681 {"nl_langinfo", (PyCFunction) PyLocale_nl_langinfo,
682 METH_VARARGS, nl_langinfo__doc__},
683#endif
Martin v. Löwisc6a7d7e2002-05-02 12:16:29 +0000684#ifdef HAVE_LIBINTL_H
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000685 {"gettext",(PyCFunction)PyIntl_gettext,METH_VARARGS,
686 gettext__doc__},
687 {"dgettext",(PyCFunction)PyIntl_dgettext,METH_VARARGS,
688 dgettext__doc__},
689 {"dcgettext",(PyCFunction)PyIntl_dcgettext,METH_VARARGS,
690 dcgettext__doc__},
691 {"textdomain",(PyCFunction)PyIntl_textdomain,METH_VARARGS,
692 textdomain__doc__},
693 {"bindtextdomain",(PyCFunction)PyIntl_bindtextdomain,METH_VARARGS,
694 bindtextdomain__doc__},
695#endif
Guido van Rossum220ecc81997-11-18 21:03:39 +0000696 {NULL, NULL}
697};
698
Mark Hammondfe51c6d2002-08-02 02:27:13 +0000699PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000700init_locale(void)
Guido van Rossum220ecc81997-11-18 21:03:39 +0000701{
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000702 PyObject *m, *d, *x;
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000703#ifdef HAVE_LANGINFO_H
704 int i;
705#endif
Guido van Rossum220ecc81997-11-18 21:03:39 +0000706
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000707 m = Py_InitModule("_locale", PyLocale_Methods);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000708
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000709 d = PyModule_GetDict(m);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000710
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000711 x = PyInt_FromLong(LC_CTYPE);
712 PyDict_SetItemString(d, "LC_CTYPE", x);
713 Py_XDECREF(x);
714
715 x = PyInt_FromLong(LC_TIME);
716 PyDict_SetItemString(d, "LC_TIME", x);
717 Py_XDECREF(x);
718
719 x = PyInt_FromLong(LC_COLLATE);
720 PyDict_SetItemString(d, "LC_COLLATE", x);
721 Py_XDECREF(x);
722
723 x = PyInt_FromLong(LC_MONETARY);
724 PyDict_SetItemString(d, "LC_MONETARY", x);
725 Py_XDECREF(x);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000726
Guido van Rossum8d9c2e31997-12-09 19:35:11 +0000727#ifdef LC_MESSAGES
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000728 x = PyInt_FromLong(LC_MESSAGES);
729 PyDict_SetItemString(d, "LC_MESSAGES", x);
730 Py_XDECREF(x);
Guido van Rossum8d9c2e31997-12-09 19:35:11 +0000731#endif /* LC_MESSAGES */
Guido van Rossum220ecc81997-11-18 21:03:39 +0000732
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000733 x = PyInt_FromLong(LC_NUMERIC);
734 PyDict_SetItemString(d, "LC_NUMERIC", x);
735 Py_XDECREF(x);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000736
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000737 x = PyInt_FromLong(LC_ALL);
738 PyDict_SetItemString(d, "LC_ALL", x);
739 Py_XDECREF(x);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000740
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000741 x = PyInt_FromLong(CHAR_MAX);
742 PyDict_SetItemString(d, "CHAR_MAX", x);
743 Py_XDECREF(x);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000744
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000745 Error = PyErr_NewException("locale.Error", NULL, NULL);
746 PyDict_SetItemString(d, "Error", Error);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000747
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000748 x = PyString_FromString(locale__doc__);
749 PyDict_SetItemString(d, "__doc__", x);
750 Py_XDECREF(x);
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000751
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000752#ifdef HAVE_LANGINFO_H
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000753 for (i = 0; langinfo_constants[i].name; i++) {
754 PyModule_AddIntConstant(m, langinfo_constants[i].name,
755 langinfo_constants[i].value);
756 }
Martin v. Löwisf95dd0a2001-08-15 17:14:33 +0000757#endif
Guido van Rossum220ecc81997-11-18 21:03:39 +0000758}
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000759
760/*
761Local variables:
762c-basic-offset: 4
763indent-tabs-mode: nil
764End:
765*/