blob: 5ed3eaf73d936b327a4a0ee87d58b905d7dce911 [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öwis6238d2b2002-06-30 15:26:10 +000028#if defined(MS_WINDOWS)
Tim Peters7a1f9172002-07-14 22:14:19 +000029#define WIN32_LEAN_AND_MEAN
Fredrik Lundh8f017a02000-07-08 19:57:37 +000030#include <windows.h>
Guido van Rossum239a2181998-04-28 16:08:19 +000031#endif
Guido van Rossum220ecc81997-11-18 21:03:39 +000032
Fredrik Lundh8f017a02000-07-08 19:57:37 +000033#ifdef macintosh
Jack Jansen307d7a42000-07-15 22:31:45 +000034#include "macglue.h"
Fredrik Lundh8f017a02000-07-08 19:57:37 +000035#endif
36
Guido van Rossum1ca8bb32001-03-02 06:28:17 +000037#ifdef RISCOS
38char *strdup(const char *);
39#endif
40
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000041PyDoc_STRVAR(locale__doc__, "Support for POSIX locales.");
Guido van Rossum220ecc81997-11-18 21:03:39 +000042
43static PyObject *Error;
44
45/* support functions for formatting floating point numbers */
46
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000047PyDoc_STRVAR(setlocale__doc__,
48"(integer,string=None) -> string. Activates/queries locale processing.");
Guido van Rossum220ecc81997-11-18 21:03:39 +000049
50/* to record the LC_NUMERIC settings */
Fredrik Lundh8f017a02000-07-08 19:57:37 +000051static PyObject* grouping = NULL;
52static PyObject* thousands_sep = NULL;
53static PyObject* decimal_point = NULL;
Guido van Rossum220ecc81997-11-18 21:03:39 +000054/* if non-null, indicates that LC_NUMERIC is different from "C" */
Fredrik Lundh8f017a02000-07-08 19:57:37 +000055static char* saved_numeric = NULL;
Guido van Rossum220ecc81997-11-18 21:03:39 +000056
57/* the grouping is terminated by either 0 or CHAR_MAX */
58static PyObject*
Fredrik Lundh8f017a02000-07-08 19:57:37 +000059copy_grouping(char* s)
Guido van Rossum220ecc81997-11-18 21:03:39 +000060{
Fredrik Lundh8f017a02000-07-08 19:57:37 +000061 int i;
62 PyObject *result, *val = NULL;
63
64 if (s[0] == '\0')
65 /* empty string: no grouping at all */
66 return PyList_New(0);
67
68 for (i = 0; s[i] != '\0' && s[i] != CHAR_MAX; i++)
69 ; /* nothing */
70
71 result = PyList_New(i+1);
72 if (!result)
73 return NULL;
74
75 i = -1;
76 do {
77 i++;
78 val = PyInt_FromLong(s[i]);
79 if (!val)
80 break;
81 if (PyList_SetItem(result, i, val)) {
82 Py_DECREF(val);
Fredrik Lundh89610a42000-07-08 20:07:24 +000083 val = NULL;
Fredrik Lundh8f017a02000-07-08 19:57:37 +000084 break;
85 }
86 } while (s[i] != '\0' && s[i] != CHAR_MAX);
87
88 if (!val) {
89 Py_DECREF(result);
90 return NULL;
Guido van Rossum220ecc81997-11-18 21:03:39 +000091 }
Fredrik Lundh8f017a02000-07-08 19:57:37 +000092
93 return result;
Guido van Rossum220ecc81997-11-18 21:03:39 +000094}
95
96static void
Fredrik Lundh8f017a02000-07-08 19:57:37 +000097fixup_ulcase(void)
Guido van Rossum220ecc81997-11-18 21:03:39 +000098{
Fredrik Lundh8f017a02000-07-08 19:57:37 +000099 PyObject *mods, *strop, *string, *ulo;
100 unsigned char ul[256];
101 int n, c;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000102
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000103 /* find the string and strop modules */
104 mods = PyImport_GetModuleDict();
105 if (!mods)
106 return;
107 string = PyDict_GetItemString(mods, "string");
108 if (string)
109 string = PyModule_GetDict(string);
110 strop=PyDict_GetItemString(mods, "strop");
111 if (strop)
112 strop = PyModule_GetDict(strop);
113 if (!string && !strop)
114 return;
115
116 /* create uppercase map string */
117 n = 0;
118 for (c = 0; c < 256; c++) {
119 if (isupper(c))
120 ul[n++] = c;
121 }
122 ulo = PyString_FromStringAndSize((const char *)ul, n);
Fredrik Lundh89610a42000-07-08 20:07:24 +0000123 if (!ulo)
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000124 return;
125 if (string)
126 PyDict_SetItemString(string, "uppercase", ulo);
127 if (strop)
128 PyDict_SetItemString(strop, "uppercase", ulo);
129 Py_DECREF(ulo);
130
131 /* create lowercase string */
132 n = 0;
133 for (c = 0; c < 256; c++) {
134 if (islower(c))
135 ul[n++] = c;
136 }
137 ulo = PyString_FromStringAndSize((const char *)ul, n);
138 if (!ulo)
139 return;
140 if (string)
141 PyDict_SetItemString(string, "lowercase", ulo);
142 if (strop)
143 PyDict_SetItemString(strop, "lowercase", ulo);
144 Py_DECREF(ulo);
145
146 /* create letters string */
147 n = 0;
148 for (c = 0; c < 256; c++) {
149 if (isalpha(c))
150 ul[n++] = c;
151 }
152 ulo = PyString_FromStringAndSize((const char *)ul, n);
153 if (!ulo)
154 return;
155 if (string)
156 PyDict_SetItemString(string, "letters", ulo);
157 Py_DECREF(ulo);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000158}
Martin v. Löwis7c82a3e02001-09-05 17:09:48 +0000159
160#if defined(HAVE_LANGINFO_H) && defined(CODESET)
161static int fileencoding_uses_locale = 0;
162#endif
Guido van Rossum220ecc81997-11-18 21:03:39 +0000163
164static 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();
Martin v. Löwis7c82a3e02001-09-05 17:09:48 +0000212#if defined(HAVE_LANGINFO_H) && defined(CODESET)
213 if (Py_FileSystemDefaultEncoding == NULL)
214 fileencoding_uses_locale = 1;
215 if (fileencoding_uses_locale) {
216 char *codeset = nl_langinfo(CODESET);
217 PyObject *enc = NULL;
218 if (*codeset && (enc = PyCodec_Encoder(codeset))) {
219 /* Release previous file encoding */
220 if (Py_FileSystemDefaultEncoding)
Guido van Rossum461591e2001-09-20 19:18:30 +0000221 free((char *)Py_FileSystemDefaultEncoding);
Martin v. Löwis7c82a3e02001-09-05 17:09:48 +0000222 Py_FileSystemDefaultEncoding = strdup(codeset);
223 Py_DECREF(enc);
224 } else
225 PyErr_Clear();
226 }
227#endif
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000228 } else {
229 /* get locale */
230 /* restore LC_NUMERIC first, if appropriate */
231 if (saved_numeric)
232 setlocale(LC_NUMERIC, saved_numeric);
233 result = setlocale(category, NULL);
234 if (!result) {
235 PyErr_SetString(Error, "locale query failed");
236 return NULL;
237 }
238 result_object = PyString_FromString(result);
239 /* restore back to "C" */
240 if (saved_numeric)
241 setlocale(LC_NUMERIC, "C");
Guido van Rossum220ecc81997-11-18 21:03:39 +0000242 }
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000243 return result_object;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000244}
245
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000246PyDoc_STRVAR(localeconv__doc__,
247"() -> dict. Returns numeric and monetary locale-specific parameters.");
Guido van Rossum220ecc81997-11-18 21:03:39 +0000248
249static PyObject*
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000250PyLocale_localeconv(PyObject* self)
Guido van Rossum220ecc81997-11-18 21:03:39 +0000251{
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000252 PyObject* result;
253 struct lconv *l;
254 PyObject *x;
255
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000256 result = PyDict_New();
Fredrik Lundh89610a42000-07-08 20:07:24 +0000257 if (!result)
258 return NULL;
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000259
260 /* if LC_NUMERIC is different in the C library, use saved value */
261 l = localeconv();
262
263 /* hopefully, the localeconv result survives the C library calls
264 involved herein */
265
266#define RESULT_STRING(s)\
267 x = PyString_FromString(l->s);\
268 if (!x) goto failed;\
269 PyDict_SetItemString(result, #s, x);\
270 Py_XDECREF(x)
271
272#define RESULT_INT(i)\
273 x = PyInt_FromLong(l->i);\
274 if (!x) goto failed;\
275 PyDict_SetItemString(result, #i, x);\
276 Py_XDECREF(x)
Guido van Rossum220ecc81997-11-18 21:03:39 +0000277
278 /* Numeric information */
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000279 if (saved_numeric){
280 /* cannot use localeconv results */
281 PyDict_SetItemString(result, "decimal_point", decimal_point);
282 PyDict_SetItemString(result, "grouping", grouping);
283 PyDict_SetItemString(result, "thousands_sep", thousands_sep);
284 } else {
285 RESULT_STRING(decimal_point);
286 RESULT_STRING(thousands_sep);
287 x = copy_grouping(l->grouping);
288 if (!x)
289 goto failed;
290 PyDict_SetItemString(result, "grouping", x);
291 Py_XDECREF(x);
292 }
293
294 /* Monetary information */
295 RESULT_STRING(int_curr_symbol);
296 RESULT_STRING(currency_symbol);
297 RESULT_STRING(mon_decimal_point);
298 RESULT_STRING(mon_thousands_sep);
299 x = copy_grouping(l->mon_grouping);
300 if (!x)
301 goto failed;
302 PyDict_SetItemString(result, "mon_grouping", x);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000303 Py_XDECREF(x);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000304 RESULT_STRING(positive_sign);
305 RESULT_STRING(negative_sign);
306 RESULT_INT(int_frac_digits);
307 RESULT_INT(frac_digits);
308 RESULT_INT(p_cs_precedes);
309 RESULT_INT(p_sep_by_space);
310 RESULT_INT(n_cs_precedes);
311 RESULT_INT(n_sep_by_space);
312 RESULT_INT(p_sign_posn);
313 RESULT_INT(n_sign_posn);
314 return result;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000315
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000316 failed:
317 Py_XDECREF(result);
318 Py_XDECREF(x);
319 return NULL;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000320}
321
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000322PyDoc_STRVAR(strcoll__doc__,
323"string,string -> int. Compares two strings according to the locale.");
Guido van Rossum220ecc81997-11-18 21:03:39 +0000324
325static PyObject*
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000326PyLocale_strcoll(PyObject* self, PyObject* args)
Guido van Rossum220ecc81997-11-18 21:03:39 +0000327{
328 char *s1,*s2;
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000329
330 if (!PyArg_ParseTuple(args, "ss:strcoll", &s1, &s2))
331 return NULL;
332 return PyInt_FromLong(strcoll(s1, s2));
Guido van Rossum220ecc81997-11-18 21:03:39 +0000333}
334
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000335PyDoc_STRVAR(strxfrm__doc__,
336"string -> string. Returns a string that behaves for cmp locale-aware.");
Guido van Rossum220ecc81997-11-18 21:03:39 +0000337
338static PyObject*
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000339PyLocale_strxfrm(PyObject* self, PyObject* args)
Guido van Rossum220ecc81997-11-18 21:03:39 +0000340{
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000341 char *s, *buf;
342 size_t n1, n2;
343 PyObject *result;
344
Fredrik Lundh89610a42000-07-08 20:07:24 +0000345 if (!PyArg_ParseTuple(args, "s:strxfrm", &s))
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000346 return NULL;
347
348 /* assume no change in size, first */
349 n1 = strlen(s) + 1;
350 buf = PyMem_Malloc(n1);
351 if (!buf)
352 return PyErr_NoMemory();
353 n2 = strxfrm(buf, s, n1);
354 if (n2 > n1) {
355 /* more space needed */
356 buf = PyMem_Realloc(buf, n2);
357 if (!buf)
358 return PyErr_NoMemory();
359 strxfrm(buf, s, n2);
360 }
361 result = PyString_FromString(buf);
362 PyMem_Free(buf);
363 return result;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000364}
365
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000366#if defined(MS_WINDOWS)
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000367static PyObject*
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000368PyLocale_getdefaultlocale(PyObject* self)
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000369{
370 char encoding[100];
371 char locale[100];
372
Tim Peters885d4572001-11-28 20:27:42 +0000373 PyOS_snprintf(encoding, sizeof(encoding), "cp%d", GetACP());
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000374
375 if (GetLocaleInfo(LOCALE_USER_DEFAULT,
376 LOCALE_SISO639LANGNAME,
377 locale, sizeof(locale))) {
378 int i = strlen(locale);
379 locale[i++] = '_';
380 if (GetLocaleInfo(LOCALE_USER_DEFAULT,
381 LOCALE_SISO3166CTRYNAME,
382 locale+i, sizeof(locale)-i))
383 return Py_BuildValue("ss", locale, encoding);
384 }
385
386 /* If we end up here, this windows version didn't know about
387 ISO639/ISO3166 names (it's probably Windows 95). Return the
388 Windows language identifier instead (a hexadecimal number) */
389
390 locale[0] = '0';
391 locale[1] = 'x';
392 if (GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_IDEFAULTLANGUAGE,
393 locale+2, sizeof(locale)-2)) {
394 return Py_BuildValue("ss", locale, encoding);
395 }
396
397 /* cannot determine the language code (very unlikely) */
398 Py_INCREF(Py_None);
399 return Py_BuildValue("Os", Py_None, encoding);
400}
401#endif
402
Jack Jansen307d7a42000-07-15 22:31:45 +0000403#if defined(macintosh)
404static PyObject*
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000405PyLocale_getdefaultlocale(PyObject* self)
Jack Jansen307d7a42000-07-15 22:31:45 +0000406{
407 return Py_BuildValue("Os", Py_None, PyMac_getscript());
408}
409#endif
410
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000411#ifdef HAVE_LANGINFO_H
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000412#define LANGINFO(X) {#X, X}
413struct langinfo_constant{
414 char* name;
415 int value;
416} langinfo_constants[] =
417{
418 /* These constants should exist on any langinfo implementation */
419 LANGINFO(DAY_1),
420 LANGINFO(DAY_2),
421 LANGINFO(DAY_3),
422 LANGINFO(DAY_4),
423 LANGINFO(DAY_5),
424 LANGINFO(DAY_6),
425 LANGINFO(DAY_7),
426
427 LANGINFO(ABDAY_1),
428 LANGINFO(ABDAY_2),
429 LANGINFO(ABDAY_3),
430 LANGINFO(ABDAY_4),
431 LANGINFO(ABDAY_5),
432 LANGINFO(ABDAY_6),
433 LANGINFO(ABDAY_7),
434
435 LANGINFO(MON_1),
436 LANGINFO(MON_2),
437 LANGINFO(MON_3),
438 LANGINFO(MON_4),
439 LANGINFO(MON_5),
440 LANGINFO(MON_6),
441 LANGINFO(MON_7),
442 LANGINFO(MON_8),
443 LANGINFO(MON_9),
444 LANGINFO(MON_10),
445 LANGINFO(MON_11),
446 LANGINFO(MON_12),
447
448 LANGINFO(ABMON_1),
449 LANGINFO(ABMON_2),
450 LANGINFO(ABMON_3),
451 LANGINFO(ABMON_4),
452 LANGINFO(ABMON_5),
453 LANGINFO(ABMON_6),
454 LANGINFO(ABMON_7),
455 LANGINFO(ABMON_8),
456 LANGINFO(ABMON_9),
457 LANGINFO(ABMON_10),
458 LANGINFO(ABMON_11),
459 LANGINFO(ABMON_12),
460
461#ifdef RADIXCHAR
462 /* The following are not available with glibc 2.0 */
463 LANGINFO(RADIXCHAR),
464 LANGINFO(THOUSEP),
465 /* YESSTR and NOSTR are deprecated in glibc, since they are
466 a special case of message translation, which should be rather
467 done using gettext. So we don't expose it to Python in the
468 first place.
469 LANGINFO(YESSTR),
470 LANGINFO(NOSTR),
471 */
472 LANGINFO(CRNCYSTR),
473#endif
474
475 LANGINFO(D_T_FMT),
476 LANGINFO(D_FMT),
477 LANGINFO(T_FMT),
478 LANGINFO(AM_STR),
479 LANGINFO(PM_STR),
480
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000481 /* The following constants are available only with XPG4, but...
482 AIX 3.2. only has CODESET.
483 OpenBSD doesn't have CODESET but has T_FMT_AMPM, and doesn't have
484 a few of the others.
485 Solution: ifdef-test them all. */
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000486#ifdef CODESET
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000487 LANGINFO(CODESET),
Martin v. Löwis496f9e42002-03-27 12:15:57 +0000488#endif
489#ifdef T_FMT_AMPM
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000490 LANGINFO(T_FMT_AMPM),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000491#endif
492#ifdef ERA
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000493 LANGINFO(ERA),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000494#endif
495#ifdef ERA_D_FMT
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000496 LANGINFO(ERA_D_FMT),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000497#endif
498#ifdef ERA_D_T_FMT
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000499 LANGINFO(ERA_D_T_FMT),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000500#endif
501#ifdef ERA_T_FMT
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000502 LANGINFO(ERA_T_FMT),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000503#endif
504#ifdef ALT_DIGITS
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000505 LANGINFO(ALT_DIGITS),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000506#endif
507#ifdef YESEXPR
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000508 LANGINFO(YESEXPR),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000509#endif
510#ifdef NOEXPR
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000511 LANGINFO(NOEXPR),
512#endif
513#ifdef _DATE_FMT
514 /* This is not available in all glibc versions that have CODESET. */
515 LANGINFO(_DATE_FMT),
516#endif
517 {0, 0}
518};
519
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000520PyDoc_STRVAR(nl_langinfo__doc__,
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000521"nl_langinfo(key) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000522"Return the value for the locale information associated with key.");
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000523
524static PyObject*
525PyLocale_nl_langinfo(PyObject* self, PyObject* args)
526{
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000527 int item, i;
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000528 if (!PyArg_ParseTuple(args, "i:nl_langinfo", &item))
529 return NULL;
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000530 /* Check whether this is a supported constant. GNU libc sometimes
531 returns numeric values in the char* return value, which would
532 crash PyString_FromString. */
533 for (i = 0; langinfo_constants[i].name; i++)
534 if (langinfo_constants[i].value == item)
535 return PyString_FromString(nl_langinfo(item));
536 PyErr_SetString(PyExc_ValueError, "unsupported langinfo constant");
537 return NULL;
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000538}
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000539#endif /* HAVE_LANGINFO_H */
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000540
541#ifdef HAVE_LIBINTL_H
542
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000543PyDoc_STRVAR(gettext__doc__,
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000544"gettext(msg) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000545"Return translation of msg.");
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000546
547static PyObject*
548PyIntl_gettext(PyObject* self, PyObject *args)
549{
550 char *in;
551 if (!PyArg_ParseTuple(args, "z", &in))
552 return 0;
553 return PyString_FromString(gettext(in));
554}
555
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000556PyDoc_STRVAR(dgettext__doc__,
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000557"dgettext(domain, msg) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000558"Return translation of msg in domain.");
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000559
560static PyObject*
561PyIntl_dgettext(PyObject* self, PyObject *args)
562{
563 char *domain, *in;
564 if (!PyArg_ParseTuple(args, "zz", &domain, &in))
565 return 0;
566 return PyString_FromString(dgettext(domain, in));
567}
568
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000569PyDoc_STRVAR(dcgettext__doc__,
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000570"dcgettext(domain, msg, category) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000571"Return translation of msg in domain and category.");
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000572
573static PyObject*
574PyIntl_dcgettext(PyObject *self, PyObject *args)
575{
576 char *domain, *msgid;
577 int category;
578 if (!PyArg_ParseTuple(args, "zzi", &domain, &msgid, &category))
579 return 0;
580 return PyString_FromString(dcgettext(domain,msgid,category));
581}
582
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000583PyDoc_STRVAR(textdomain__doc__,
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000584"textdomain(domain) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000585"Set the C library's textdmain to domain, returning the new domain.");
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000586
587static PyObject*
588PyIntl_textdomain(PyObject* self, PyObject* args)
589{
590 char *domain;
591 if (!PyArg_ParseTuple(args, "z", &domain))
592 return 0;
593 domain = textdomain(domain);
594 if (!domain) {
595 PyErr_SetFromErrno(PyExc_OSError);
596 return NULL;
597 }
598 return PyString_FromString(domain);
599}
600
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000601PyDoc_STRVAR(bindtextdomain__doc__,
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000602"bindtextdomain(domain, dir) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000603"Bind the C library's domain to dir.");
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000604
605static PyObject*
606PyIntl_bindtextdomain(PyObject* self,PyObject*args)
607{
608 char *domain,*dirname;
609 if (!PyArg_ParseTuple(args, "zz", &domain, &dirname))
610 return 0;
611 dirname = bindtextdomain(domain, dirname);
612 if (!dirname) {
613 PyErr_SetFromErrno(PyExc_OSError);
614 return NULL;
615 }
616 return PyString_FromString(dirname);
617}
618
619#endif
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000620
Guido van Rossum220ecc81997-11-18 21:03:39 +0000621static struct PyMethodDef PyLocale_Methods[] = {
Andrew M. Kuchlinge365fb82000-08-03 02:06:16 +0000622 {"setlocale", (PyCFunction) PyLocale_setlocale,
623 METH_VARARGS, setlocale__doc__},
624 {"localeconv", (PyCFunction) PyLocale_localeconv,
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000625 METH_NOARGS, localeconv__doc__},
Andrew M. Kuchlinge365fb82000-08-03 02:06:16 +0000626 {"strcoll", (PyCFunction) PyLocale_strcoll,
627 METH_VARARGS, strcoll__doc__},
628 {"strxfrm", (PyCFunction) PyLocale_strxfrm,
629 METH_VARARGS, strxfrm__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000630#if defined(MS_WINDOWS) || defined(macintosh)
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000631 {"_getdefaultlocale", (PyCFunction) PyLocale_getdefaultlocale, METH_NOARGS},
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000632#endif
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000633#ifdef HAVE_LANGINFO_H
634 {"nl_langinfo", (PyCFunction) PyLocale_nl_langinfo,
635 METH_VARARGS, nl_langinfo__doc__},
636#endif
Martin v. Löwisc6a7d7e2002-05-02 12:16:29 +0000637#ifdef HAVE_LIBINTL_H
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000638 {"gettext",(PyCFunction)PyIntl_gettext,METH_VARARGS,
639 gettext__doc__},
640 {"dgettext",(PyCFunction)PyIntl_dgettext,METH_VARARGS,
641 dgettext__doc__},
642 {"dcgettext",(PyCFunction)PyIntl_dcgettext,METH_VARARGS,
643 dcgettext__doc__},
644 {"textdomain",(PyCFunction)PyIntl_textdomain,METH_VARARGS,
645 textdomain__doc__},
646 {"bindtextdomain",(PyCFunction)PyIntl_bindtextdomain,METH_VARARGS,
647 bindtextdomain__doc__},
648#endif
Guido van Rossum220ecc81997-11-18 21:03:39 +0000649 {NULL, NULL}
650};
651
Guido van Rossum3886bb61998-12-04 18:50:17 +0000652DL_EXPORT(void)
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000653init_locale(void)
Guido van Rossum220ecc81997-11-18 21:03:39 +0000654{
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000655 PyObject *m, *d, *x;
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000656#ifdef HAVE_LANGINFO_H
657 int i;
658#endif
Guido van Rossum220ecc81997-11-18 21:03:39 +0000659
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000660 m = Py_InitModule("_locale", PyLocale_Methods);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000661
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000662 d = PyModule_GetDict(m);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000663
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000664 x = PyInt_FromLong(LC_CTYPE);
665 PyDict_SetItemString(d, "LC_CTYPE", x);
666 Py_XDECREF(x);
667
668 x = PyInt_FromLong(LC_TIME);
669 PyDict_SetItemString(d, "LC_TIME", x);
670 Py_XDECREF(x);
671
672 x = PyInt_FromLong(LC_COLLATE);
673 PyDict_SetItemString(d, "LC_COLLATE", x);
674 Py_XDECREF(x);
675
676 x = PyInt_FromLong(LC_MONETARY);
677 PyDict_SetItemString(d, "LC_MONETARY", x);
678 Py_XDECREF(x);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000679
Guido van Rossum8d9c2e31997-12-09 19:35:11 +0000680#ifdef LC_MESSAGES
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000681 x = PyInt_FromLong(LC_MESSAGES);
682 PyDict_SetItemString(d, "LC_MESSAGES", x);
683 Py_XDECREF(x);
Guido van Rossum8d9c2e31997-12-09 19:35:11 +0000684#endif /* LC_MESSAGES */
Guido van Rossum220ecc81997-11-18 21:03:39 +0000685
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000686 x = PyInt_FromLong(LC_NUMERIC);
687 PyDict_SetItemString(d, "LC_NUMERIC", x);
688 Py_XDECREF(x);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000689
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000690 x = PyInt_FromLong(LC_ALL);
691 PyDict_SetItemString(d, "LC_ALL", x);
692 Py_XDECREF(x);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000693
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000694 x = PyInt_FromLong(CHAR_MAX);
695 PyDict_SetItemString(d, "CHAR_MAX", x);
696 Py_XDECREF(x);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000697
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000698 Error = PyErr_NewException("locale.Error", NULL, NULL);
699 PyDict_SetItemString(d, "Error", Error);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000700
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000701 x = PyString_FromString(locale__doc__);
702 PyDict_SetItemString(d, "__doc__", x);
703 Py_XDECREF(x);
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000704
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000705#ifdef HAVE_LANGINFO_H
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000706 for (i = 0; langinfo_constants[i].name; i++) {
707 PyModule_AddIntConstant(m, langinfo_constants[i].name,
708 langinfo_constants[i].value);
709 }
Martin v. Löwisf95dd0a2001-08-15 17:14:33 +0000710#endif
Guido van Rossum220ecc81997-11-18 21:03:39 +0000711}