blob: 2077be827acf4a7e2ced1de73fcb45c3d884c0a3 [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
164#if defined(HAVE_LANGINFO_H) && defined(CODESET)
165static int fileencoding_uses_locale = 0;
166#endif
Guido van Rossum220ecc81997-11-18 21:03:39 +0000167
168static PyObject*
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000169PyLocale_setlocale(PyObject* self, PyObject* args)
Guido van Rossum220ecc81997-11-18 21:03:39 +0000170{
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000171 int category;
172 char *locale = NULL, *result;
173 PyObject *result_object;
174 struct lconv *lc;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000175
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000176 if (!PyArg_ParseTuple(args, "i|z:setlocale", &category, &locale))
Fredrik Lundh89610a42000-07-08 20:07:24 +0000177 return NULL;
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000178
179 if (locale) {
180 /* set locale */
181 result = setlocale(category, locale);
182 if (!result) {
183 /* operation failed, no setting was changed */
184 PyErr_SetString(Error, "locale setting not supported");
185 return NULL;
186 }
187 result_object = PyString_FromString(result);
188 if (!result)
189 return NULL;
190 /* record changes to LC_NUMERIC */
191 if (category == LC_NUMERIC || category == LC_ALL) {
192 if (strcmp(locale, "C") == 0 || strcmp(locale, "POSIX") == 0) {
193 /* user just asked for default numeric locale */
194 if (saved_numeric)
195 free(saved_numeric);
196 saved_numeric = NULL;
197 } else {
198 /* remember values */
199 lc = localeconv();
200 Py_XDECREF(grouping);
201 grouping = copy_grouping(lc->grouping);
202 Py_XDECREF(thousands_sep);
203 thousands_sep = PyString_FromString(lc->thousands_sep);
204 Py_XDECREF(decimal_point);
205 decimal_point = PyString_FromString(lc->decimal_point);
206 saved_numeric = strdup(locale);
207 /* restore to "C" */
208 setlocale(LC_NUMERIC, "C");
209 }
210 }
211 /* record changes to LC_CTYPE */
212 if (category == LC_CTYPE || category == LC_ALL)
213 fixup_ulcase();
214 /* things that got wrong up to here are ignored */
215 PyErr_Clear();
Martin v. Löwis7c82a3e02001-09-05 17:09:48 +0000216#if defined(HAVE_LANGINFO_H) && defined(CODESET)
217 if (Py_FileSystemDefaultEncoding == NULL)
218 fileencoding_uses_locale = 1;
219 if (fileencoding_uses_locale) {
220 char *codeset = nl_langinfo(CODESET);
221 PyObject *enc = NULL;
222 if (*codeset && (enc = PyCodec_Encoder(codeset))) {
223 /* Release previous file encoding */
224 if (Py_FileSystemDefaultEncoding)
Guido van Rossum461591e2001-09-20 19:18:30 +0000225 free((char *)Py_FileSystemDefaultEncoding);
Martin v. Löwis7c82a3e02001-09-05 17:09:48 +0000226 Py_FileSystemDefaultEncoding = strdup(codeset);
227 Py_DECREF(enc);
228 } else
229 PyErr_Clear();
230 }
231#endif
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000232 } else {
233 /* get locale */
234 /* restore LC_NUMERIC first, if appropriate */
235 if (saved_numeric)
236 setlocale(LC_NUMERIC, saved_numeric);
237 result = setlocale(category, NULL);
238 if (!result) {
239 PyErr_SetString(Error, "locale query failed");
240 return NULL;
241 }
242 result_object = PyString_FromString(result);
243 /* restore back to "C" */
244 if (saved_numeric)
245 setlocale(LC_NUMERIC, "C");
Guido van Rossum220ecc81997-11-18 21:03:39 +0000246 }
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000247 return result_object;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000248}
249
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000250PyDoc_STRVAR(localeconv__doc__,
251"() -> dict. Returns numeric and monetary locale-specific parameters.");
Guido van Rossum220ecc81997-11-18 21:03:39 +0000252
253static PyObject*
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000254PyLocale_localeconv(PyObject* self)
Guido van Rossum220ecc81997-11-18 21:03:39 +0000255{
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000256 PyObject* result;
257 struct lconv *l;
258 PyObject *x;
259
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000260 result = PyDict_New();
Fredrik Lundh89610a42000-07-08 20:07:24 +0000261 if (!result)
262 return NULL;
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000263
264 /* if LC_NUMERIC is different in the C library, use saved value */
265 l = localeconv();
266
267 /* hopefully, the localeconv result survives the C library calls
268 involved herein */
269
270#define RESULT_STRING(s)\
271 x = PyString_FromString(l->s);\
272 if (!x) goto failed;\
273 PyDict_SetItemString(result, #s, x);\
274 Py_XDECREF(x)
275
276#define RESULT_INT(i)\
277 x = PyInt_FromLong(l->i);\
278 if (!x) goto failed;\
279 PyDict_SetItemString(result, #i, x);\
280 Py_XDECREF(x)
Guido van Rossum220ecc81997-11-18 21:03:39 +0000281
282 /* Numeric information */
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000283 if (saved_numeric){
284 /* cannot use localeconv results */
285 PyDict_SetItemString(result, "decimal_point", decimal_point);
286 PyDict_SetItemString(result, "grouping", grouping);
287 PyDict_SetItemString(result, "thousands_sep", thousands_sep);
288 } else {
289 RESULT_STRING(decimal_point);
290 RESULT_STRING(thousands_sep);
291 x = copy_grouping(l->grouping);
292 if (!x)
293 goto failed;
294 PyDict_SetItemString(result, "grouping", x);
295 Py_XDECREF(x);
296 }
297
298 /* Monetary information */
299 RESULT_STRING(int_curr_symbol);
300 RESULT_STRING(currency_symbol);
301 RESULT_STRING(mon_decimal_point);
302 RESULT_STRING(mon_thousands_sep);
303 x = copy_grouping(l->mon_grouping);
304 if (!x)
305 goto failed;
306 PyDict_SetItemString(result, "mon_grouping", x);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000307 Py_XDECREF(x);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000308 RESULT_STRING(positive_sign);
309 RESULT_STRING(negative_sign);
310 RESULT_INT(int_frac_digits);
311 RESULT_INT(frac_digits);
312 RESULT_INT(p_cs_precedes);
313 RESULT_INT(p_sep_by_space);
314 RESULT_INT(n_cs_precedes);
315 RESULT_INT(n_sep_by_space);
316 RESULT_INT(p_sign_posn);
317 RESULT_INT(n_sign_posn);
318 return result;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000319
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000320 failed:
321 Py_XDECREF(result);
322 Py_XDECREF(x);
323 return NULL;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000324}
325
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000326PyDoc_STRVAR(strcoll__doc__,
327"string,string -> int. Compares two strings according to the locale.");
Guido van Rossum220ecc81997-11-18 21:03:39 +0000328
329static PyObject*
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000330PyLocale_strcoll(PyObject* self, PyObject* args)
Guido van Rossum220ecc81997-11-18 21:03:39 +0000331{
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000332#if !defined(HAVE_WCSCOLL) || !defined(Py_USING_UNICODE)
333 char *s1,*s2;
334
335 if (!PyArg_ParseTuple(args, "ss:strcoll", &s1, &s2))
336 return NULL;
337 return PyInt_FromLong(strcoll(s1, s2));
338#else
339 PyObject *os1, *os2, *result = NULL;
340 wchar_t *ws1 = NULL, *ws2 = NULL;
341 int rel1 = 0, rel2 = 0, len1, len2;
342
343 if (!PyArg_ParseTuple(args, "OO:strcoll", &os1, &os2))
344 return NULL;
345 /* If both arguments are byte strings, use strcoll. */
346 if (PyString_Check(os1) && PyString_Check(os2))
347 return PyInt_FromLong(strcoll(PyString_AS_STRING(os1),
348 PyString_AS_STRING(os2)));
349 /* If neither argument is unicode, it's an error. */
350 if (!PyUnicode_Check(os1) && !PyUnicode_Check(os2)) {
351 PyErr_SetString(PyExc_ValueError, "strcoll arguments must be strings");
352 }
353 /* Convert the non-unicode argument to unicode. */
354 if (!PyUnicode_Check(os1)) {
355 os1 = PyUnicode_FromObject(os1);
356 if (!os1)
357 return NULL;
358 rel1 = 1;
359 }
360 if (!PyUnicode_Check(os2)) {
361 os2 = PyUnicode_FromObject(os2);
362 if (!os2) {
363 Py_DECREF(os1);
364 return NULL;
365 }
366 rel2 = 1;
367 }
368 /* Convert the unicode strings to wchar[]. */
369 len1 = PyUnicode_GET_SIZE(os1) + 1;
370 len2 = PyUnicode_GET_SIZE(os2) + 1;
371 ws1 = PyMem_MALLOC(len1 * sizeof(wchar_t));
372 if (!ws1) {
373 PyErr_NoMemory();
374 goto done;
375 }
376 if (PyUnicode_AsWideChar((PyUnicodeObject*)os1, ws1, len1) == -1)
377 goto done;
378 ws2 = PyMem_MALLOC(len2 * sizeof(wchar_t));
379 if (!ws2) {
380 PyErr_NoMemory();
381 goto done;
382 }
383 if (PyUnicode_AsWideChar((PyUnicodeObject*)os2, ws2, len2) == -1)
384 goto done;
385 /* Collate the strings. */
386 result = PyInt_FromLong(wcscoll(ws1, ws2));
387 done:
388 /* Deallocate everything. */
389 if (ws1) PyMem_FREE(ws1);
390 if (ws2) PyMem_FREE(ws2);
391 if (rel1) {
392 Py_DECREF(os1);
393 }
394 if (rel2) {
395 Py_DECREF(os2);
396 }
397 return result;
398#endif
Guido van Rossum220ecc81997-11-18 21:03:39 +0000399}
400
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000401
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000402PyDoc_STRVAR(strxfrm__doc__,
403"string -> string. Returns a string that behaves for cmp locale-aware.");
Guido van Rossum220ecc81997-11-18 21:03:39 +0000404
405static PyObject*
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000406PyLocale_strxfrm(PyObject* self, PyObject* args)
Guido van Rossum220ecc81997-11-18 21:03:39 +0000407{
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000408 char *s, *buf;
409 size_t n1, n2;
410 PyObject *result;
411
Fredrik Lundh89610a42000-07-08 20:07:24 +0000412 if (!PyArg_ParseTuple(args, "s:strxfrm", &s))
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000413 return NULL;
414
415 /* assume no change in size, first */
416 n1 = strlen(s) + 1;
417 buf = PyMem_Malloc(n1);
418 if (!buf)
419 return PyErr_NoMemory();
420 n2 = strxfrm(buf, s, n1);
421 if (n2 > n1) {
422 /* more space needed */
423 buf = PyMem_Realloc(buf, n2);
424 if (!buf)
425 return PyErr_NoMemory();
426 strxfrm(buf, s, n2);
427 }
428 result = PyString_FromString(buf);
429 PyMem_Free(buf);
430 return result;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000431}
432
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000433#if defined(MS_WINDOWS)
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000434static PyObject*
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000435PyLocale_getdefaultlocale(PyObject* self)
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000436{
437 char encoding[100];
438 char locale[100];
439
Tim Peters885d4572001-11-28 20:27:42 +0000440 PyOS_snprintf(encoding, sizeof(encoding), "cp%d", GetACP());
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000441
442 if (GetLocaleInfo(LOCALE_USER_DEFAULT,
443 LOCALE_SISO639LANGNAME,
444 locale, sizeof(locale))) {
445 int i = strlen(locale);
446 locale[i++] = '_';
447 if (GetLocaleInfo(LOCALE_USER_DEFAULT,
448 LOCALE_SISO3166CTRYNAME,
449 locale+i, sizeof(locale)-i))
450 return Py_BuildValue("ss", locale, encoding);
451 }
452
453 /* If we end up here, this windows version didn't know about
454 ISO639/ISO3166 names (it's probably Windows 95). Return the
455 Windows language identifier instead (a hexadecimal number) */
456
457 locale[0] = '0';
458 locale[1] = 'x';
459 if (GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_IDEFAULTLANGUAGE,
460 locale+2, sizeof(locale)-2)) {
461 return Py_BuildValue("ss", locale, encoding);
462 }
463
464 /* cannot determine the language code (very unlikely) */
465 Py_INCREF(Py_None);
466 return Py_BuildValue("Os", Py_None, encoding);
467}
468#endif
469
Martin v. Löwis52ea7e92002-11-26 09:05:36 +0000470#if defined(__APPLE__)
Jack Jansen307d7a42000-07-15 22:31:45 +0000471static PyObject*
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000472PyLocale_getdefaultlocale(PyObject* self)
Jack Jansen307d7a42000-07-15 22:31:45 +0000473{
474 return Py_BuildValue("Os", Py_None, PyMac_getscript());
475}
476#endif
477
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000478#ifdef HAVE_LANGINFO_H
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000479#define LANGINFO(X) {#X, X}
480struct langinfo_constant{
481 char* name;
482 int value;
483} langinfo_constants[] =
484{
485 /* These constants should exist on any langinfo implementation */
486 LANGINFO(DAY_1),
487 LANGINFO(DAY_2),
488 LANGINFO(DAY_3),
489 LANGINFO(DAY_4),
490 LANGINFO(DAY_5),
491 LANGINFO(DAY_6),
492 LANGINFO(DAY_7),
493
494 LANGINFO(ABDAY_1),
495 LANGINFO(ABDAY_2),
496 LANGINFO(ABDAY_3),
497 LANGINFO(ABDAY_4),
498 LANGINFO(ABDAY_5),
499 LANGINFO(ABDAY_6),
500 LANGINFO(ABDAY_7),
501
502 LANGINFO(MON_1),
503 LANGINFO(MON_2),
504 LANGINFO(MON_3),
505 LANGINFO(MON_4),
506 LANGINFO(MON_5),
507 LANGINFO(MON_6),
508 LANGINFO(MON_7),
509 LANGINFO(MON_8),
510 LANGINFO(MON_9),
511 LANGINFO(MON_10),
512 LANGINFO(MON_11),
513 LANGINFO(MON_12),
514
515 LANGINFO(ABMON_1),
516 LANGINFO(ABMON_2),
517 LANGINFO(ABMON_3),
518 LANGINFO(ABMON_4),
519 LANGINFO(ABMON_5),
520 LANGINFO(ABMON_6),
521 LANGINFO(ABMON_7),
522 LANGINFO(ABMON_8),
523 LANGINFO(ABMON_9),
524 LANGINFO(ABMON_10),
525 LANGINFO(ABMON_11),
526 LANGINFO(ABMON_12),
527
528#ifdef RADIXCHAR
529 /* The following are not available with glibc 2.0 */
530 LANGINFO(RADIXCHAR),
531 LANGINFO(THOUSEP),
532 /* YESSTR and NOSTR are deprecated in glibc, since they are
533 a special case of message translation, which should be rather
534 done using gettext. So we don't expose it to Python in the
535 first place.
536 LANGINFO(YESSTR),
537 LANGINFO(NOSTR),
538 */
539 LANGINFO(CRNCYSTR),
540#endif
541
542 LANGINFO(D_T_FMT),
543 LANGINFO(D_FMT),
544 LANGINFO(T_FMT),
545 LANGINFO(AM_STR),
546 LANGINFO(PM_STR),
547
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000548 /* The following constants are available only with XPG4, but...
549 AIX 3.2. only has CODESET.
550 OpenBSD doesn't have CODESET but has T_FMT_AMPM, and doesn't have
551 a few of the others.
552 Solution: ifdef-test them all. */
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000553#ifdef CODESET
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000554 LANGINFO(CODESET),
Martin v. Löwis496f9e42002-03-27 12:15:57 +0000555#endif
556#ifdef T_FMT_AMPM
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000557 LANGINFO(T_FMT_AMPM),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000558#endif
559#ifdef ERA
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000560 LANGINFO(ERA),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000561#endif
562#ifdef ERA_D_FMT
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000563 LANGINFO(ERA_D_FMT),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000564#endif
565#ifdef ERA_D_T_FMT
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000566 LANGINFO(ERA_D_T_FMT),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000567#endif
568#ifdef ERA_T_FMT
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000569 LANGINFO(ERA_T_FMT),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000570#endif
571#ifdef ALT_DIGITS
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000572 LANGINFO(ALT_DIGITS),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000573#endif
574#ifdef YESEXPR
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000575 LANGINFO(YESEXPR),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000576#endif
577#ifdef NOEXPR
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000578 LANGINFO(NOEXPR),
579#endif
580#ifdef _DATE_FMT
581 /* This is not available in all glibc versions that have CODESET. */
582 LANGINFO(_DATE_FMT),
583#endif
584 {0, 0}
585};
586
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000587PyDoc_STRVAR(nl_langinfo__doc__,
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000588"nl_langinfo(key) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000589"Return the value for the locale information associated with key.");
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000590
591static PyObject*
592PyLocale_nl_langinfo(PyObject* self, PyObject* args)
593{
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000594 int item, i;
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000595 if (!PyArg_ParseTuple(args, "i:nl_langinfo", &item))
596 return NULL;
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000597 /* Check whether this is a supported constant. GNU libc sometimes
598 returns numeric values in the char* return value, which would
599 crash PyString_FromString. */
600 for (i = 0; langinfo_constants[i].name; i++)
601 if (langinfo_constants[i].value == item)
602 return PyString_FromString(nl_langinfo(item));
603 PyErr_SetString(PyExc_ValueError, "unsupported langinfo constant");
604 return NULL;
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000605}
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000606#endif /* HAVE_LANGINFO_H */
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000607
608#ifdef HAVE_LIBINTL_H
609
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000610PyDoc_STRVAR(gettext__doc__,
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000611"gettext(msg) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000612"Return translation of msg.");
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000613
614static PyObject*
615PyIntl_gettext(PyObject* self, PyObject *args)
616{
617 char *in;
618 if (!PyArg_ParseTuple(args, "z", &in))
619 return 0;
620 return PyString_FromString(gettext(in));
621}
622
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000623PyDoc_STRVAR(dgettext__doc__,
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000624"dgettext(domain, msg) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000625"Return translation of msg in domain.");
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000626
627static PyObject*
628PyIntl_dgettext(PyObject* self, PyObject *args)
629{
630 char *domain, *in;
631 if (!PyArg_ParseTuple(args, "zz", &domain, &in))
632 return 0;
633 return PyString_FromString(dgettext(domain, in));
634}
635
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000636PyDoc_STRVAR(dcgettext__doc__,
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000637"dcgettext(domain, msg, category) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000638"Return translation of msg in domain and category.");
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000639
640static PyObject*
641PyIntl_dcgettext(PyObject *self, PyObject *args)
642{
643 char *domain, *msgid;
644 int category;
645 if (!PyArg_ParseTuple(args, "zzi", &domain, &msgid, &category))
646 return 0;
647 return PyString_FromString(dcgettext(domain,msgid,category));
648}
649
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000650PyDoc_STRVAR(textdomain__doc__,
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000651"textdomain(domain) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000652"Set the C library's textdmain to domain, returning the new domain.");
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000653
654static PyObject*
655PyIntl_textdomain(PyObject* self, PyObject* args)
656{
657 char *domain;
658 if (!PyArg_ParseTuple(args, "z", &domain))
659 return 0;
660 domain = textdomain(domain);
661 if (!domain) {
662 PyErr_SetFromErrno(PyExc_OSError);
663 return NULL;
664 }
665 return PyString_FromString(domain);
666}
667
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000668PyDoc_STRVAR(bindtextdomain__doc__,
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000669"bindtextdomain(domain, dir) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000670"Bind the C library's domain to dir.");
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000671
672static PyObject*
673PyIntl_bindtextdomain(PyObject* self,PyObject*args)
674{
675 char *domain,*dirname;
676 if (!PyArg_ParseTuple(args, "zz", &domain, &dirname))
677 return 0;
678 dirname = bindtextdomain(domain, dirname);
679 if (!dirname) {
680 PyErr_SetFromErrno(PyExc_OSError);
681 return NULL;
682 }
683 return PyString_FromString(dirname);
684}
685
686#endif
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000687
Guido van Rossum220ecc81997-11-18 21:03:39 +0000688static struct PyMethodDef PyLocale_Methods[] = {
Andrew M. Kuchlinge365fb82000-08-03 02:06:16 +0000689 {"setlocale", (PyCFunction) PyLocale_setlocale,
690 METH_VARARGS, setlocale__doc__},
691 {"localeconv", (PyCFunction) PyLocale_localeconv,
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000692 METH_NOARGS, localeconv__doc__},
Andrew M. Kuchlinge365fb82000-08-03 02:06:16 +0000693 {"strcoll", (PyCFunction) PyLocale_strcoll,
694 METH_VARARGS, strcoll__doc__},
695 {"strxfrm", (PyCFunction) PyLocale_strxfrm,
696 METH_VARARGS, strxfrm__doc__},
Martin v. Löwis52ea7e92002-11-26 09:05:36 +0000697#if defined(MS_WINDOWS) || defined(__APPLE__)
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000698 {"_getdefaultlocale", (PyCFunction) PyLocale_getdefaultlocale, METH_NOARGS},
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000699#endif
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000700#ifdef HAVE_LANGINFO_H
701 {"nl_langinfo", (PyCFunction) PyLocale_nl_langinfo,
702 METH_VARARGS, nl_langinfo__doc__},
703#endif
Martin v. Löwisc6a7d7e2002-05-02 12:16:29 +0000704#ifdef HAVE_LIBINTL_H
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000705 {"gettext",(PyCFunction)PyIntl_gettext,METH_VARARGS,
706 gettext__doc__},
707 {"dgettext",(PyCFunction)PyIntl_dgettext,METH_VARARGS,
708 dgettext__doc__},
709 {"dcgettext",(PyCFunction)PyIntl_dcgettext,METH_VARARGS,
710 dcgettext__doc__},
711 {"textdomain",(PyCFunction)PyIntl_textdomain,METH_VARARGS,
712 textdomain__doc__},
713 {"bindtextdomain",(PyCFunction)PyIntl_bindtextdomain,METH_VARARGS,
714 bindtextdomain__doc__},
715#endif
Guido van Rossum220ecc81997-11-18 21:03:39 +0000716 {NULL, NULL}
717};
718
Mark Hammondfe51c6d2002-08-02 02:27:13 +0000719PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000720init_locale(void)
Guido van Rossum220ecc81997-11-18 21:03:39 +0000721{
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000722 PyObject *m, *d, *x;
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000723#ifdef HAVE_LANGINFO_H
724 int i;
725#endif
Guido van Rossum220ecc81997-11-18 21:03:39 +0000726
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000727 m = Py_InitModule("_locale", PyLocale_Methods);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000728
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000729 d = PyModule_GetDict(m);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000730
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000731 x = PyInt_FromLong(LC_CTYPE);
732 PyDict_SetItemString(d, "LC_CTYPE", x);
733 Py_XDECREF(x);
734
735 x = PyInt_FromLong(LC_TIME);
736 PyDict_SetItemString(d, "LC_TIME", x);
737 Py_XDECREF(x);
738
739 x = PyInt_FromLong(LC_COLLATE);
740 PyDict_SetItemString(d, "LC_COLLATE", x);
741 Py_XDECREF(x);
742
743 x = PyInt_FromLong(LC_MONETARY);
744 PyDict_SetItemString(d, "LC_MONETARY", x);
745 Py_XDECREF(x);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000746
Guido van Rossum8d9c2e31997-12-09 19:35:11 +0000747#ifdef LC_MESSAGES
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000748 x = PyInt_FromLong(LC_MESSAGES);
749 PyDict_SetItemString(d, "LC_MESSAGES", x);
750 Py_XDECREF(x);
Guido van Rossum8d9c2e31997-12-09 19:35:11 +0000751#endif /* LC_MESSAGES */
Guido van Rossum220ecc81997-11-18 21:03:39 +0000752
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000753 x = PyInt_FromLong(LC_NUMERIC);
754 PyDict_SetItemString(d, "LC_NUMERIC", x);
755 Py_XDECREF(x);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000756
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000757 x = PyInt_FromLong(LC_ALL);
758 PyDict_SetItemString(d, "LC_ALL", x);
759 Py_XDECREF(x);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000760
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000761 x = PyInt_FromLong(CHAR_MAX);
762 PyDict_SetItemString(d, "CHAR_MAX", x);
763 Py_XDECREF(x);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000764
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000765 Error = PyErr_NewException("locale.Error", NULL, NULL);
766 PyDict_SetItemString(d, "Error", Error);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000767
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000768 x = PyString_FromString(locale__doc__);
769 PyDict_SetItemString(d, "__doc__", x);
770 Py_XDECREF(x);
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000771
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000772#ifdef HAVE_LANGINFO_H
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000773 for (i = 0; langinfo_constants[i].name; i++) {
774 PyModule_AddIntConstant(m, langinfo_constants[i].name,
775 langinfo_constants[i].value);
776 }
Martin v. Löwisf95dd0a2001-08-15 17:14:33 +0000777#endif
Guido van Rossum220ecc81997-11-18 21:03:39 +0000778}
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000779
780/*
781Local variables:
782c-basic-offset: 4
783indent-tabs-mode: nil
784End:
785*/