blob: 06f53460298dd180b6a46a47ee349a329ac360dd [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
Fredrik Lundh8f017a02000-07-08 19:57:37 +000028#if defined(MS_WIN32)
29#define WINDOWS_LEAN_AND_MEAN
30#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
Fredrik Lundh8f017a02000-07-08 19:57:37 +000041static char 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
Fredrik Lundh8f017a02000-07-08 19:57:37 +000047static char setlocale__doc__[] =
Guido van Rossum220ecc81997-11-18 21:03:39 +000048"(integer,string=None) -> string. Activates/queries locale processing."
49;
50
51/* to record the LC_NUMERIC settings */
Fredrik Lundh8f017a02000-07-08 19:57:37 +000052static PyObject* grouping = NULL;
53static PyObject* thousands_sep = NULL;
54static PyObject* decimal_point = NULL;
Guido van Rossum220ecc81997-11-18 21:03:39 +000055/* if non-null, indicates that LC_NUMERIC is different from "C" */
Fredrik Lundh8f017a02000-07-08 19:57:37 +000056static char* saved_numeric = NULL;
Guido van Rossum220ecc81997-11-18 21:03:39 +000057
58/* the grouping is terminated by either 0 or CHAR_MAX */
59static PyObject*
Fredrik Lundh8f017a02000-07-08 19:57:37 +000060copy_grouping(char* s)
Guido van Rossum220ecc81997-11-18 21:03:39 +000061{
Fredrik Lundh8f017a02000-07-08 19:57:37 +000062 int i;
63 PyObject *result, *val = NULL;
64
65 if (s[0] == '\0')
66 /* empty string: no grouping at all */
67 return PyList_New(0);
68
69 for (i = 0; s[i] != '\0' && s[i] != CHAR_MAX; i++)
70 ; /* nothing */
71
72 result = PyList_New(i+1);
73 if (!result)
74 return NULL;
75
76 i = -1;
77 do {
78 i++;
79 val = PyInt_FromLong(s[i]);
80 if (!val)
81 break;
82 if (PyList_SetItem(result, i, val)) {
83 Py_DECREF(val);
Fredrik Lundh89610a42000-07-08 20:07:24 +000084 val = NULL;
Fredrik Lundh8f017a02000-07-08 19:57:37 +000085 break;
86 }
87 } while (s[i] != '\0' && s[i] != CHAR_MAX);
88
89 if (!val) {
90 Py_DECREF(result);
91 return NULL;
Guido van Rossum220ecc81997-11-18 21:03:39 +000092 }
Fredrik Lundh8f017a02000-07-08 19:57:37 +000093
94 return result;
Guido van Rossum220ecc81997-11-18 21:03:39 +000095}
96
97static void
Fredrik Lundh8f017a02000-07-08 19:57:37 +000098fixup_ulcase(void)
Guido van Rossum220ecc81997-11-18 21:03:39 +000099{
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000100 PyObject *mods, *strop, *string, *ulo;
101 unsigned char ul[256];
102 int n, c;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000103
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000104 /* find the string and strop modules */
105 mods = PyImport_GetModuleDict();
106 if (!mods)
107 return;
108 string = PyDict_GetItemString(mods, "string");
109 if (string)
110 string = PyModule_GetDict(string);
111 strop=PyDict_GetItemString(mods, "strop");
112 if (strop)
113 strop = PyModule_GetDict(strop);
114 if (!string && !strop)
115 return;
116
117 /* create uppercase map string */
118 n = 0;
119 for (c = 0; c < 256; c++) {
120 if (isupper(c))
121 ul[n++] = c;
122 }
123 ulo = PyString_FromStringAndSize((const char *)ul, n);
Fredrik Lundh89610a42000-07-08 20:07:24 +0000124 if (!ulo)
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000125 return;
126 if (string)
127 PyDict_SetItemString(string, "uppercase", ulo);
128 if (strop)
129 PyDict_SetItemString(strop, "uppercase", ulo);
130 Py_DECREF(ulo);
131
132 /* create lowercase string */
133 n = 0;
134 for (c = 0; c < 256; c++) {
135 if (islower(c))
136 ul[n++] = c;
137 }
138 ulo = PyString_FromStringAndSize((const char *)ul, n);
139 if (!ulo)
140 return;
141 if (string)
142 PyDict_SetItemString(string, "lowercase", ulo);
143 if (strop)
144 PyDict_SetItemString(strop, "lowercase", ulo);
145 Py_DECREF(ulo);
146
147 /* create letters string */
148 n = 0;
149 for (c = 0; c < 256; c++) {
150 if (isalpha(c))
151 ul[n++] = c;
152 }
153 ulo = PyString_FromStringAndSize((const char *)ul, n);
154 if (!ulo)
155 return;
156 if (string)
157 PyDict_SetItemString(string, "letters", ulo);
158 Py_DECREF(ulo);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000159}
Martin v. Löwis7c82a3e02001-09-05 17:09:48 +0000160
161#if defined(HAVE_LANGINFO_H) && defined(CODESET)
162static int fileencoding_uses_locale = 0;
163#endif
Guido van Rossum220ecc81997-11-18 21:03:39 +0000164
165static PyObject*
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000166PyLocale_setlocale(PyObject* self, PyObject* args)
Guido van Rossum220ecc81997-11-18 21:03:39 +0000167{
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000168 int category;
169 char *locale = NULL, *result;
170 PyObject *result_object;
171 struct lconv *lc;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000172
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000173 if (!PyArg_ParseTuple(args, "i|z:setlocale", &category, &locale))
Fredrik Lundh89610a42000-07-08 20:07:24 +0000174 return NULL;
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000175
176 if (locale) {
177 /* set locale */
178 result = setlocale(category, locale);
179 if (!result) {
180 /* operation failed, no setting was changed */
181 PyErr_SetString(Error, "locale setting not supported");
182 return NULL;
183 }
184 result_object = PyString_FromString(result);
185 if (!result)
186 return NULL;
187 /* record changes to LC_NUMERIC */
188 if (category == LC_NUMERIC || category == LC_ALL) {
189 if (strcmp(locale, "C") == 0 || strcmp(locale, "POSIX") == 0) {
190 /* user just asked for default numeric locale */
191 if (saved_numeric)
192 free(saved_numeric);
193 saved_numeric = NULL;
194 } else {
195 /* remember values */
196 lc = localeconv();
197 Py_XDECREF(grouping);
198 grouping = copy_grouping(lc->grouping);
199 Py_XDECREF(thousands_sep);
200 thousands_sep = PyString_FromString(lc->thousands_sep);
201 Py_XDECREF(decimal_point);
202 decimal_point = PyString_FromString(lc->decimal_point);
203 saved_numeric = strdup(locale);
204 /* restore to "C" */
205 setlocale(LC_NUMERIC, "C");
206 }
207 }
208 /* record changes to LC_CTYPE */
209 if (category == LC_CTYPE || category == LC_ALL)
210 fixup_ulcase();
211 /* things that got wrong up to here are ignored */
212 PyErr_Clear();
Martin v. Löwis7c82a3e02001-09-05 17:09:48 +0000213#if defined(HAVE_LANGINFO_H) && defined(CODESET)
214 if (Py_FileSystemDefaultEncoding == NULL)
215 fileencoding_uses_locale = 1;
216 if (fileencoding_uses_locale) {
217 char *codeset = nl_langinfo(CODESET);
218 PyObject *enc = NULL;
219 if (*codeset && (enc = PyCodec_Encoder(codeset))) {
220 /* Release previous file encoding */
221 if (Py_FileSystemDefaultEncoding)
Guido van Rossum461591e2001-09-20 19:18:30 +0000222 free((char *)Py_FileSystemDefaultEncoding);
Martin v. Löwis7c82a3e02001-09-05 17:09:48 +0000223 Py_FileSystemDefaultEncoding = strdup(codeset);
224 Py_DECREF(enc);
225 } else
226 PyErr_Clear();
227 }
228#endif
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000229 } else {
230 /* get locale */
231 /* restore LC_NUMERIC first, if appropriate */
232 if (saved_numeric)
233 setlocale(LC_NUMERIC, saved_numeric);
234 result = setlocale(category, NULL);
235 if (!result) {
236 PyErr_SetString(Error, "locale query failed");
237 return NULL;
238 }
239 result_object = PyString_FromString(result);
240 /* restore back to "C" */
241 if (saved_numeric)
242 setlocale(LC_NUMERIC, "C");
Guido van Rossum220ecc81997-11-18 21:03:39 +0000243 }
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000244 return result_object;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000245}
246
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000247static char localeconv__doc__[] =
Guido van Rossum220ecc81997-11-18 21:03:39 +0000248"() -> dict. Returns numeric and monetary locale-specific parameters."
249;
250
251static PyObject*
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000252PyLocale_localeconv(PyObject* self)
Guido van Rossum220ecc81997-11-18 21:03:39 +0000253{
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000254 PyObject* result;
255 struct lconv *l;
256 PyObject *x;
257
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000258 result = PyDict_New();
Fredrik Lundh89610a42000-07-08 20:07:24 +0000259 if (!result)
260 return NULL;
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000261
262 /* if LC_NUMERIC is different in the C library, use saved value */
263 l = localeconv();
264
265 /* hopefully, the localeconv result survives the C library calls
266 involved herein */
267
268#define RESULT_STRING(s)\
269 x = PyString_FromString(l->s);\
270 if (!x) goto failed;\
271 PyDict_SetItemString(result, #s, x);\
272 Py_XDECREF(x)
273
274#define RESULT_INT(i)\
275 x = PyInt_FromLong(l->i);\
276 if (!x) goto failed;\
277 PyDict_SetItemString(result, #i, x);\
278 Py_XDECREF(x)
Guido van Rossum220ecc81997-11-18 21:03:39 +0000279
280 /* Numeric information */
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000281 if (saved_numeric){
282 /* cannot use localeconv results */
283 PyDict_SetItemString(result, "decimal_point", decimal_point);
284 PyDict_SetItemString(result, "grouping", grouping);
285 PyDict_SetItemString(result, "thousands_sep", thousands_sep);
286 } else {
287 RESULT_STRING(decimal_point);
288 RESULT_STRING(thousands_sep);
289 x = copy_grouping(l->grouping);
290 if (!x)
291 goto failed;
292 PyDict_SetItemString(result, "grouping", x);
293 Py_XDECREF(x);
294 }
295
296 /* Monetary information */
297 RESULT_STRING(int_curr_symbol);
298 RESULT_STRING(currency_symbol);
299 RESULT_STRING(mon_decimal_point);
300 RESULT_STRING(mon_thousands_sep);
301 x = copy_grouping(l->mon_grouping);
302 if (!x)
303 goto failed;
304 PyDict_SetItemString(result, "mon_grouping", x);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000305 Py_XDECREF(x);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000306 RESULT_STRING(positive_sign);
307 RESULT_STRING(negative_sign);
308 RESULT_INT(int_frac_digits);
309 RESULT_INT(frac_digits);
310 RESULT_INT(p_cs_precedes);
311 RESULT_INT(p_sep_by_space);
312 RESULT_INT(n_cs_precedes);
313 RESULT_INT(n_sep_by_space);
314 RESULT_INT(p_sign_posn);
315 RESULT_INT(n_sign_posn);
316 return result;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000317
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000318 failed:
319 Py_XDECREF(result);
320 Py_XDECREF(x);
321 return NULL;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000322}
323
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000324static char strcoll__doc__[] =
Guido van Rossum220ecc81997-11-18 21:03:39 +0000325"string,string -> int. Compares two strings according to the locale."
326;
327
328static PyObject*
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000329PyLocale_strcoll(PyObject* self, PyObject* args)
Guido van Rossum220ecc81997-11-18 21:03:39 +0000330{
331 char *s1,*s2;
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000332
333 if (!PyArg_ParseTuple(args, "ss:strcoll", &s1, &s2))
334 return NULL;
335 return PyInt_FromLong(strcoll(s1, s2));
Guido van Rossum220ecc81997-11-18 21:03:39 +0000336}
337
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000338static char strxfrm__doc__[] =
Guido van Rossum220ecc81997-11-18 21:03:39 +0000339"string -> string. Returns a string that behaves for cmp locale-aware."
340;
341
342static PyObject*
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000343PyLocale_strxfrm(PyObject* self, PyObject* args)
Guido van Rossum220ecc81997-11-18 21:03:39 +0000344{
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000345 char *s, *buf;
346 size_t n1, n2;
347 PyObject *result;
348
Fredrik Lundh89610a42000-07-08 20:07:24 +0000349 if (!PyArg_ParseTuple(args, "s:strxfrm", &s))
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000350 return NULL;
351
352 /* assume no change in size, first */
353 n1 = strlen(s) + 1;
354 buf = PyMem_Malloc(n1);
355 if (!buf)
356 return PyErr_NoMemory();
357 n2 = strxfrm(buf, s, n1);
358 if (n2 > n1) {
359 /* more space needed */
360 buf = PyMem_Realloc(buf, n2);
361 if (!buf)
362 return PyErr_NoMemory();
363 strxfrm(buf, s, n2);
364 }
365 result = PyString_FromString(buf);
366 PyMem_Free(buf);
367 return result;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000368}
369
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000370#if defined(MS_WIN32)
371static PyObject*
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000372PyLocale_getdefaultlocale(PyObject* self)
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000373{
374 char encoding[100];
375 char locale[100];
376
Tim Peters885d4572001-11-28 20:27:42 +0000377 PyOS_snprintf(encoding, sizeof(encoding), "cp%d", GetACP());
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000378
379 if (GetLocaleInfo(LOCALE_USER_DEFAULT,
380 LOCALE_SISO639LANGNAME,
381 locale, sizeof(locale))) {
382 int i = strlen(locale);
383 locale[i++] = '_';
384 if (GetLocaleInfo(LOCALE_USER_DEFAULT,
385 LOCALE_SISO3166CTRYNAME,
386 locale+i, sizeof(locale)-i))
387 return Py_BuildValue("ss", locale, encoding);
388 }
389
390 /* If we end up here, this windows version didn't know about
391 ISO639/ISO3166 names (it's probably Windows 95). Return the
392 Windows language identifier instead (a hexadecimal number) */
393
394 locale[0] = '0';
395 locale[1] = 'x';
396 if (GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_IDEFAULTLANGUAGE,
397 locale+2, sizeof(locale)-2)) {
398 return Py_BuildValue("ss", locale, encoding);
399 }
400
401 /* cannot determine the language code (very unlikely) */
402 Py_INCREF(Py_None);
403 return Py_BuildValue("Os", Py_None, encoding);
404}
405#endif
406
Jack Jansen307d7a42000-07-15 22:31:45 +0000407#if defined(macintosh)
408static PyObject*
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000409PyLocale_getdefaultlocale(PyObject* self)
Jack Jansen307d7a42000-07-15 22:31:45 +0000410{
411 return Py_BuildValue("Os", Py_None, PyMac_getscript());
412}
413#endif
414
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000415#ifdef HAVE_LANGINFO_H
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000416#define LANGINFO(X) {#X, X}
417struct langinfo_constant{
418 char* name;
419 int value;
420} langinfo_constants[] =
421{
422 /* These constants should exist on any langinfo implementation */
423 LANGINFO(DAY_1),
424 LANGINFO(DAY_2),
425 LANGINFO(DAY_3),
426 LANGINFO(DAY_4),
427 LANGINFO(DAY_5),
428 LANGINFO(DAY_6),
429 LANGINFO(DAY_7),
430
431 LANGINFO(ABDAY_1),
432 LANGINFO(ABDAY_2),
433 LANGINFO(ABDAY_3),
434 LANGINFO(ABDAY_4),
435 LANGINFO(ABDAY_5),
436 LANGINFO(ABDAY_6),
437 LANGINFO(ABDAY_7),
438
439 LANGINFO(MON_1),
440 LANGINFO(MON_2),
441 LANGINFO(MON_3),
442 LANGINFO(MON_4),
443 LANGINFO(MON_5),
444 LANGINFO(MON_6),
445 LANGINFO(MON_7),
446 LANGINFO(MON_8),
447 LANGINFO(MON_9),
448 LANGINFO(MON_10),
449 LANGINFO(MON_11),
450 LANGINFO(MON_12),
451
452 LANGINFO(ABMON_1),
453 LANGINFO(ABMON_2),
454 LANGINFO(ABMON_3),
455 LANGINFO(ABMON_4),
456 LANGINFO(ABMON_5),
457 LANGINFO(ABMON_6),
458 LANGINFO(ABMON_7),
459 LANGINFO(ABMON_8),
460 LANGINFO(ABMON_9),
461 LANGINFO(ABMON_10),
462 LANGINFO(ABMON_11),
463 LANGINFO(ABMON_12),
464
465#ifdef RADIXCHAR
466 /* The following are not available with glibc 2.0 */
467 LANGINFO(RADIXCHAR),
468 LANGINFO(THOUSEP),
469 /* YESSTR and NOSTR are deprecated in glibc, since they are
470 a special case of message translation, which should be rather
471 done using gettext. So we don't expose it to Python in the
472 first place.
473 LANGINFO(YESSTR),
474 LANGINFO(NOSTR),
475 */
476 LANGINFO(CRNCYSTR),
477#endif
478
479 LANGINFO(D_T_FMT),
480 LANGINFO(D_FMT),
481 LANGINFO(T_FMT),
482 LANGINFO(AM_STR),
483 LANGINFO(PM_STR),
484
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000485 /* The following constants are available only with XPG4, but...
486 AIX 3.2. only has CODESET.
487 OpenBSD doesn't have CODESET but has T_FMT_AMPM, and doesn't have
488 a few of the others.
489 Solution: ifdef-test them all. */
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000490#ifdef CODESET
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000491 LANGINFO(CODESET),
Martin v. Löwis496f9e42002-03-27 12:15:57 +0000492#endif
493#ifdef T_FMT_AMPM
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000494 LANGINFO(T_FMT_AMPM),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000495#endif
496#ifdef ERA
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000497 LANGINFO(ERA),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000498#endif
499#ifdef ERA_D_FMT
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000500 LANGINFO(ERA_D_FMT),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000501#endif
502#ifdef ERA_D_T_FMT
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000503 LANGINFO(ERA_D_T_FMT),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000504#endif
505#ifdef ERA_T_FMT
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000506 LANGINFO(ERA_T_FMT),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000507#endif
508#ifdef ALT_DIGITS
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000509 LANGINFO(ALT_DIGITS),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000510#endif
511#ifdef YESEXPR
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000512 LANGINFO(YESEXPR),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000513#endif
514#ifdef NOEXPR
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000515 LANGINFO(NOEXPR),
516#endif
517#ifdef _DATE_FMT
518 /* This is not available in all glibc versions that have CODESET. */
519 LANGINFO(_DATE_FMT),
520#endif
521 {0, 0}
522};
523
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000524static char nl_langinfo__doc__[] =
525"nl_langinfo(key) -> string\n"
526"Return the value for the locale information associated with key."
527;
528
529static PyObject*
530PyLocale_nl_langinfo(PyObject* self, PyObject* args)
531{
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000532 int item, i;
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000533 if (!PyArg_ParseTuple(args, "i:nl_langinfo", &item))
534 return NULL;
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000535 /* Check whether this is a supported constant. GNU libc sometimes
536 returns numeric values in the char* return value, which would
537 crash PyString_FromString. */
538 for (i = 0; langinfo_constants[i].name; i++)
539 if (langinfo_constants[i].value == item)
540 return PyString_FromString(nl_langinfo(item));
541 PyErr_SetString(PyExc_ValueError, "unsupported langinfo constant");
542 return NULL;
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000543}
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000544#endif /* HAVE_LANGINFO_H */
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000545
546#ifdef HAVE_LIBINTL_H
547
548static char gettext__doc__[]=
549"gettext(msg) -> string\n"
550"Return translation of msg.";
551
552static PyObject*
553PyIntl_gettext(PyObject* self, PyObject *args)
554{
555 char *in;
556 if (!PyArg_ParseTuple(args, "z", &in))
557 return 0;
558 return PyString_FromString(gettext(in));
559}
560
561static char dgettext__doc__[]=
562"dgettext(domain, msg) -> string\n"
563"Return translation of msg in domain.";
564
565static PyObject*
566PyIntl_dgettext(PyObject* self, PyObject *args)
567{
568 char *domain, *in;
569 if (!PyArg_ParseTuple(args, "zz", &domain, &in))
570 return 0;
571 return PyString_FromString(dgettext(domain, in));
572}
573
574static char dcgettext__doc__[]=
575"dcgettext(domain, msg, category) -> string\n"
576"Return translation of msg in domain and category.";
577
578static PyObject*
579PyIntl_dcgettext(PyObject *self, PyObject *args)
580{
581 char *domain, *msgid;
582 int category;
583 if (!PyArg_ParseTuple(args, "zzi", &domain, &msgid, &category))
584 return 0;
585 return PyString_FromString(dcgettext(domain,msgid,category));
586}
587
588static char textdomain__doc__[]=
589"textdomain(domain) -> string\n"
590"Set the C library's textdmain to domain, returning the new domain.";
591
592static PyObject*
593PyIntl_textdomain(PyObject* self, PyObject* args)
594{
595 char *domain;
596 if (!PyArg_ParseTuple(args, "z", &domain))
597 return 0;
598 domain = textdomain(domain);
599 if (!domain) {
600 PyErr_SetFromErrno(PyExc_OSError);
601 return NULL;
602 }
603 return PyString_FromString(domain);
604}
605
606static char bindtextdomain__doc__[]=
607"bindtextdomain(domain, dir) -> string\n"
608"Bind the C library's domain to dir.";
609
610static PyObject*
611PyIntl_bindtextdomain(PyObject* self,PyObject*args)
612{
613 char *domain,*dirname;
614 if (!PyArg_ParseTuple(args, "zz", &domain, &dirname))
615 return 0;
616 dirname = bindtextdomain(domain, dirname);
617 if (!dirname) {
618 PyErr_SetFromErrno(PyExc_OSError);
619 return NULL;
620 }
621 return PyString_FromString(dirname);
622}
623
624#endif
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000625
Guido van Rossum220ecc81997-11-18 21:03:39 +0000626static struct PyMethodDef PyLocale_Methods[] = {
Andrew M. Kuchlinge365fb82000-08-03 02:06:16 +0000627 {"setlocale", (PyCFunction) PyLocale_setlocale,
628 METH_VARARGS, setlocale__doc__},
629 {"localeconv", (PyCFunction) PyLocale_localeconv,
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000630 METH_NOARGS, localeconv__doc__},
Andrew M. Kuchlinge365fb82000-08-03 02:06:16 +0000631 {"strcoll", (PyCFunction) PyLocale_strcoll,
632 METH_VARARGS, strcoll__doc__},
633 {"strxfrm", (PyCFunction) PyLocale_strxfrm,
634 METH_VARARGS, strxfrm__doc__},
Jack Jansen307d7a42000-07-15 22:31:45 +0000635#if defined(MS_WIN32) || defined(macintosh)
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000636 {"_getdefaultlocale", (PyCFunction) PyLocale_getdefaultlocale, METH_NOARGS},
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000637#endif
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000638#ifdef HAVE_LANGINFO_H
639 {"nl_langinfo", (PyCFunction) PyLocale_nl_langinfo,
640 METH_VARARGS, nl_langinfo__doc__},
641#endif
Martin v. Löwisc6a7d7e2002-05-02 12:16:29 +0000642#ifdef HAVE_LIBINTL_H
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000643 {"gettext",(PyCFunction)PyIntl_gettext,METH_VARARGS,
644 gettext__doc__},
645 {"dgettext",(PyCFunction)PyIntl_dgettext,METH_VARARGS,
646 dgettext__doc__},
647 {"dcgettext",(PyCFunction)PyIntl_dcgettext,METH_VARARGS,
648 dcgettext__doc__},
649 {"textdomain",(PyCFunction)PyIntl_textdomain,METH_VARARGS,
650 textdomain__doc__},
651 {"bindtextdomain",(PyCFunction)PyIntl_bindtextdomain,METH_VARARGS,
652 bindtextdomain__doc__},
653#endif
Guido van Rossum220ecc81997-11-18 21:03:39 +0000654 {NULL, NULL}
655};
656
Guido van Rossum3886bb61998-12-04 18:50:17 +0000657DL_EXPORT(void)
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000658init_locale(void)
Guido van Rossum220ecc81997-11-18 21:03:39 +0000659{
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000660 PyObject *m, *d, *x;
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000661#ifdef HAVE_LANGINFO_H
662 int i;
663#endif
Guido van Rossum220ecc81997-11-18 21:03:39 +0000664
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000665 m = Py_InitModule("_locale", PyLocale_Methods);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000666
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000667 d = PyModule_GetDict(m);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000668
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000669 x = PyInt_FromLong(LC_CTYPE);
670 PyDict_SetItemString(d, "LC_CTYPE", x);
671 Py_XDECREF(x);
672
673 x = PyInt_FromLong(LC_TIME);
674 PyDict_SetItemString(d, "LC_TIME", x);
675 Py_XDECREF(x);
676
677 x = PyInt_FromLong(LC_COLLATE);
678 PyDict_SetItemString(d, "LC_COLLATE", x);
679 Py_XDECREF(x);
680
681 x = PyInt_FromLong(LC_MONETARY);
682 PyDict_SetItemString(d, "LC_MONETARY", x);
683 Py_XDECREF(x);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000684
Guido van Rossum8d9c2e31997-12-09 19:35:11 +0000685#ifdef LC_MESSAGES
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000686 x = PyInt_FromLong(LC_MESSAGES);
687 PyDict_SetItemString(d, "LC_MESSAGES", x);
688 Py_XDECREF(x);
Guido van Rossum8d9c2e31997-12-09 19:35:11 +0000689#endif /* LC_MESSAGES */
Guido van Rossum220ecc81997-11-18 21:03:39 +0000690
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000691 x = PyInt_FromLong(LC_NUMERIC);
692 PyDict_SetItemString(d, "LC_NUMERIC", x);
693 Py_XDECREF(x);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000694
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000695 x = PyInt_FromLong(LC_ALL);
696 PyDict_SetItemString(d, "LC_ALL", x);
697 Py_XDECREF(x);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000698
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000699 x = PyInt_FromLong(CHAR_MAX);
700 PyDict_SetItemString(d, "CHAR_MAX", x);
701 Py_XDECREF(x);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000702
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000703 Error = PyErr_NewException("locale.Error", NULL, NULL);
704 PyDict_SetItemString(d, "Error", Error);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000705
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000706 x = PyString_FromString(locale__doc__);
707 PyDict_SetItemString(d, "__doc__", x);
708 Py_XDECREF(x);
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000709
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000710#ifdef HAVE_LANGINFO_H
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000711 for (i = 0; langinfo_constants[i].name; i++) {
712 PyModule_AddIntConstant(m, langinfo_constants[i].name,
713 langinfo_constants[i].value);
714 }
Martin v. Löwisf95dd0a2001-08-15 17:14:33 +0000715#endif
Guido van Rossum220ecc81997-11-18 21:03:39 +0000716}