blob: 2d6541dedbbd485e2fed0a87a5b934a89770bfdb [file] [log] [blame]
Guido van Rossum220ecc81997-11-18 21:03:39 +00001/***********************************************************
Martin v. Löwis25f90d52003-09-03 04:50:13 +00002Copyright (C) 1997, 2002, 2003 Martin von Loewis
Guido van Rossum220ecc81997-11-18 21:03:39 +00003
4Permission to use, copy, modify, and distribute this software and its
5documentation for any purpose and without fee is hereby granted,
6provided that the above copyright notice appear in all copies.
7
8This software comes with no warranty. Use at your own risk.
Fredrik Lundh8f017a02000-07-08 19:57:37 +00009
Guido van Rossum220ecc81997-11-18 21:03:39 +000010******************************************************************/
11
Fred Drake68933b92000-08-10 21:41:08 +000012#include "Python.h"
13
Guido van Rossum220ecc81997-11-18 21:03:39 +000014#include <stdio.h>
15#include <errno.h>
16#include <locale.h>
17#include <string.h>
Guido van Rossum5cd70f41998-06-19 04:33:30 +000018#include <ctype.h>
Fredrik Lundh8f017a02000-07-08 19:57:37 +000019
Martin v. Löwis9b75dca2001-08-10 13:58:50 +000020#ifdef HAVE_LANGINFO_H
21#include <langinfo.h>
22#endif
23
Martin v. Löwis2e64c342002-03-27 18:49:02 +000024#ifdef HAVE_LIBINTL_H
25#include <libintl.h>
26#endif
27
Martin v. Löwis9c36c292002-12-21 18:34:06 +000028#ifdef HAVE_WCHAR_H
29#include <wchar.h>
30#endif
31
Jack Jansen7107c1a2003-11-20 13:31:00 +000032#if defined(__APPLE__)
Jack Jansen59f072a2004-07-15 13:31:39 +000033#include <CoreFoundation/CoreFoundation.h>
Jack Jansen7107c1a2003-11-20 13:31:00 +000034#endif
35
Martin v. Löwis6238d2b2002-06-30 15:26:10 +000036#if defined(MS_WINDOWS)
Tim Peters7a1f9172002-07-14 22:14:19 +000037#define WIN32_LEAN_AND_MEAN
Fredrik Lundh8f017a02000-07-08 19:57:37 +000038#include <windows.h>
Guido van Rossum239a2181998-04-28 16:08:19 +000039#endif
Guido van Rossum220ecc81997-11-18 21:03:39 +000040
Guido van Rossum1ca8bb32001-03-02 06:28:17 +000041#ifdef RISCOS
42char *strdup(const char *);
43#endif
44
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000045PyDoc_STRVAR(locale__doc__, "Support for POSIX locales.");
Guido van Rossum220ecc81997-11-18 21:03:39 +000046
47static PyObject *Error;
48
49/* support functions for formatting floating point numbers */
50
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000051PyDoc_STRVAR(setlocale__doc__,
52"(integer,string=None) -> string. Activates/queries locale processing.");
Guido van Rossum220ecc81997-11-18 21:03:39 +000053
Guido van Rossum220ecc81997-11-18 21:03:39 +000054/* the grouping is terminated by either 0 or CHAR_MAX */
55static PyObject*
Fredrik Lundh8f017a02000-07-08 19:57:37 +000056copy_grouping(char* s)
Guido van Rossum220ecc81997-11-18 21:03:39 +000057{
Fredrik Lundh8f017a02000-07-08 19:57:37 +000058 int i;
59 PyObject *result, *val = NULL;
60
61 if (s[0] == '\0')
62 /* empty string: no grouping at all */
63 return PyList_New(0);
64
65 for (i = 0; s[i] != '\0' && s[i] != CHAR_MAX; i++)
66 ; /* nothing */
67
68 result = PyList_New(i+1);
69 if (!result)
70 return NULL;
71
72 i = -1;
73 do {
74 i++;
75 val = PyInt_FromLong(s[i]);
76 if (!val)
77 break;
78 if (PyList_SetItem(result, i, val)) {
79 Py_DECREF(val);
Fredrik Lundh89610a42000-07-08 20:07:24 +000080 val = NULL;
Fredrik Lundh8f017a02000-07-08 19:57:37 +000081 break;
82 }
83 } while (s[i] != '\0' && s[i] != CHAR_MAX);
84
85 if (!val) {
86 Py_DECREF(result);
87 return NULL;
Guido van Rossum220ecc81997-11-18 21:03:39 +000088 }
Fredrik Lundh8f017a02000-07-08 19:57:37 +000089
90 return result;
Guido van Rossum220ecc81997-11-18 21:03:39 +000091}
92
93static void
Fredrik Lundh8f017a02000-07-08 19:57:37 +000094fixup_ulcase(void)
Guido van Rossum220ecc81997-11-18 21:03:39 +000095{
Fredrik Lundh8f017a02000-07-08 19:57:37 +000096 PyObject *mods, *strop, *string, *ulo;
97 unsigned char ul[256];
98 int n, c;
Guido van Rossum220ecc81997-11-18 21:03:39 +000099
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000100 /* find the string and strop modules */
101 mods = PyImport_GetModuleDict();
102 if (!mods)
103 return;
104 string = PyDict_GetItemString(mods, "string");
105 if (string)
106 string = PyModule_GetDict(string);
107 strop=PyDict_GetItemString(mods, "strop");
108 if (strop)
109 strop = PyModule_GetDict(strop);
110 if (!string && !strop)
111 return;
112
113 /* create uppercase map string */
114 n = 0;
115 for (c = 0; c < 256; c++) {
116 if (isupper(c))
117 ul[n++] = c;
118 }
119 ulo = PyString_FromStringAndSize((const char *)ul, n);
Fredrik Lundh89610a42000-07-08 20:07:24 +0000120 if (!ulo)
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000121 return;
122 if (string)
123 PyDict_SetItemString(string, "uppercase", ulo);
124 if (strop)
125 PyDict_SetItemString(strop, "uppercase", ulo);
126 Py_DECREF(ulo);
127
128 /* create lowercase string */
129 n = 0;
130 for (c = 0; c < 256; c++) {
131 if (islower(c))
132 ul[n++] = c;
133 }
134 ulo = PyString_FromStringAndSize((const char *)ul, n);
135 if (!ulo)
136 return;
137 if (string)
138 PyDict_SetItemString(string, "lowercase", ulo);
139 if (strop)
140 PyDict_SetItemString(strop, "lowercase", ulo);
141 Py_DECREF(ulo);
142
143 /* create letters string */
144 n = 0;
145 for (c = 0; c < 256; c++) {
146 if (isalpha(c))
147 ul[n++] = c;
148 }
149 ulo = PyString_FromStringAndSize((const char *)ul, n);
150 if (!ulo)
151 return;
152 if (string)
153 PyDict_SetItemString(string, "letters", ulo);
154 Py_DECREF(ulo);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000155}
Martin v. Löwis7c82a3e02001-09-05 17:09:48 +0000156
Guido van Rossum220ecc81997-11-18 21:03:39 +0000157static PyObject*
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000158PyLocale_setlocale(PyObject* self, PyObject* args)
Guido van Rossum220ecc81997-11-18 21:03:39 +0000159{
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000160 int category;
161 char *locale = NULL, *result;
162 PyObject *result_object;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000163
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000164 if (!PyArg_ParseTuple(args, "i|z:setlocale", &category, &locale))
Fredrik Lundh89610a42000-07-08 20:07:24 +0000165 return NULL;
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000166
167 if (locale) {
168 /* set locale */
169 result = setlocale(category, locale);
170 if (!result) {
171 /* operation failed, no setting was changed */
Martin v. Löwis25f90d52003-09-03 04:50:13 +0000172 PyErr_SetString(Error, "unsupported locale setting");
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000173 return NULL;
174 }
175 result_object = PyString_FromString(result);
Mark Hammond9a714752003-07-24 14:15:07 +0000176 if (!result_object)
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000177 return NULL;
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000178 /* record changes to LC_CTYPE */
179 if (category == LC_CTYPE || category == LC_ALL)
180 fixup_ulcase();
181 /* things that got wrong up to here are ignored */
182 PyErr_Clear();
183 } else {
184 /* get locale */
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000185 result = setlocale(category, NULL);
186 if (!result) {
187 PyErr_SetString(Error, "locale query failed");
188 return NULL;
189 }
190 result_object = PyString_FromString(result);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000191 }
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000192 return result_object;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000193}
194
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000195PyDoc_STRVAR(localeconv__doc__,
196"() -> dict. Returns numeric and monetary locale-specific parameters.");
Guido van Rossum220ecc81997-11-18 21:03:39 +0000197
198static PyObject*
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000199PyLocale_localeconv(PyObject* self)
Guido van Rossum220ecc81997-11-18 21:03:39 +0000200{
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000201 PyObject* result;
202 struct lconv *l;
203 PyObject *x;
204
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000205 result = PyDict_New();
Fredrik Lundh89610a42000-07-08 20:07:24 +0000206 if (!result)
207 return NULL;
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000208
209 /* if LC_NUMERIC is different in the C library, use saved value */
210 l = localeconv();
211
212 /* hopefully, the localeconv result survives the C library calls
213 involved herein */
214
215#define RESULT_STRING(s)\
216 x = PyString_FromString(l->s);\
217 if (!x) goto failed;\
218 PyDict_SetItemString(result, #s, x);\
219 Py_XDECREF(x)
220
221#define RESULT_INT(i)\
222 x = PyInt_FromLong(l->i);\
223 if (!x) goto failed;\
224 PyDict_SetItemString(result, #i, x);\
225 Py_XDECREF(x)
Guido van Rossum220ecc81997-11-18 21:03:39 +0000226
227 /* Numeric information */
Martin v. Löwis737ea822004-06-08 18:52:54 +0000228 RESULT_STRING(decimal_point);
229 RESULT_STRING(thousands_sep);
230 x = copy_grouping(l->grouping);
231 if (!x)
232 goto failed;
233 PyDict_SetItemString(result, "grouping", x);
234 Py_XDECREF(x);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000235
236 /* Monetary information */
237 RESULT_STRING(int_curr_symbol);
238 RESULT_STRING(currency_symbol);
239 RESULT_STRING(mon_decimal_point);
240 RESULT_STRING(mon_thousands_sep);
241 x = copy_grouping(l->mon_grouping);
242 if (!x)
243 goto failed;
244 PyDict_SetItemString(result, "mon_grouping", x);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000245 Py_XDECREF(x);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000246 RESULT_STRING(positive_sign);
247 RESULT_STRING(negative_sign);
248 RESULT_INT(int_frac_digits);
249 RESULT_INT(frac_digits);
250 RESULT_INT(p_cs_precedes);
251 RESULT_INT(p_sep_by_space);
252 RESULT_INT(n_cs_precedes);
253 RESULT_INT(n_sep_by_space);
254 RESULT_INT(p_sign_posn);
255 RESULT_INT(n_sign_posn);
256 return result;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000257
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000258 failed:
259 Py_XDECREF(result);
260 Py_XDECREF(x);
261 return NULL;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000262}
263
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000264PyDoc_STRVAR(strcoll__doc__,
265"string,string -> int. Compares two strings according to the locale.");
Guido van Rossum220ecc81997-11-18 21:03:39 +0000266
267static PyObject*
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000268PyLocale_strcoll(PyObject* self, PyObject* args)
Guido van Rossum220ecc81997-11-18 21:03:39 +0000269{
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000270#if !defined(HAVE_WCSCOLL) || !defined(Py_USING_UNICODE)
271 char *s1,*s2;
272
273 if (!PyArg_ParseTuple(args, "ss:strcoll", &s1, &s2))
274 return NULL;
275 return PyInt_FromLong(strcoll(s1, s2));
276#else
277 PyObject *os1, *os2, *result = NULL;
278 wchar_t *ws1 = NULL, *ws2 = NULL;
279 int rel1 = 0, rel2 = 0, len1, len2;
280
281 if (!PyArg_ParseTuple(args, "OO:strcoll", &os1, &os2))
282 return NULL;
283 /* If both arguments are byte strings, use strcoll. */
284 if (PyString_Check(os1) && PyString_Check(os2))
285 return PyInt_FromLong(strcoll(PyString_AS_STRING(os1),
286 PyString_AS_STRING(os2)));
287 /* If neither argument is unicode, it's an error. */
288 if (!PyUnicode_Check(os1) && !PyUnicode_Check(os2)) {
289 PyErr_SetString(PyExc_ValueError, "strcoll arguments must be strings");
290 }
291 /* Convert the non-unicode argument to unicode. */
292 if (!PyUnicode_Check(os1)) {
293 os1 = PyUnicode_FromObject(os1);
294 if (!os1)
295 return NULL;
296 rel1 = 1;
297 }
298 if (!PyUnicode_Check(os2)) {
299 os2 = PyUnicode_FromObject(os2);
300 if (!os2) {
301 Py_DECREF(os1);
302 return NULL;
303 }
304 rel2 = 1;
305 }
306 /* Convert the unicode strings to wchar[]. */
307 len1 = PyUnicode_GET_SIZE(os1) + 1;
308 len2 = PyUnicode_GET_SIZE(os2) + 1;
309 ws1 = PyMem_MALLOC(len1 * sizeof(wchar_t));
310 if (!ws1) {
311 PyErr_NoMemory();
312 goto done;
313 }
314 if (PyUnicode_AsWideChar((PyUnicodeObject*)os1, ws1, len1) == -1)
315 goto done;
316 ws2 = PyMem_MALLOC(len2 * sizeof(wchar_t));
317 if (!ws2) {
318 PyErr_NoMemory();
319 goto done;
320 }
321 if (PyUnicode_AsWideChar((PyUnicodeObject*)os2, ws2, len2) == -1)
322 goto done;
323 /* Collate the strings. */
324 result = PyInt_FromLong(wcscoll(ws1, ws2));
325 done:
326 /* Deallocate everything. */
327 if (ws1) PyMem_FREE(ws1);
328 if (ws2) PyMem_FREE(ws2);
329 if (rel1) {
330 Py_DECREF(os1);
331 }
332 if (rel2) {
333 Py_DECREF(os2);
334 }
335 return result;
336#endif
Guido van Rossum220ecc81997-11-18 21:03:39 +0000337}
338
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000339
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000340PyDoc_STRVAR(strxfrm__doc__,
341"string -> string. Returns a string that behaves for cmp locale-aware.");
Guido van Rossum220ecc81997-11-18 21:03:39 +0000342
343static PyObject*
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000344PyLocale_strxfrm(PyObject* self, PyObject* args)
Guido van Rossum220ecc81997-11-18 21:03:39 +0000345{
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000346 char *s, *buf;
347 size_t n1, n2;
348 PyObject *result;
349
Fredrik Lundh89610a42000-07-08 20:07:24 +0000350 if (!PyArg_ParseTuple(args, "s:strxfrm", &s))
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000351 return NULL;
352
353 /* assume no change in size, first */
354 n1 = strlen(s) + 1;
355 buf = PyMem_Malloc(n1);
356 if (!buf)
357 return PyErr_NoMemory();
358 n2 = strxfrm(buf, s, n1);
359 if (n2 > n1) {
360 /* more space needed */
361 buf = PyMem_Realloc(buf, n2);
362 if (!buf)
363 return PyErr_NoMemory();
364 strxfrm(buf, s, n2);
365 }
366 result = PyString_FromString(buf);
367 PyMem_Free(buf);
368 return result;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000369}
370
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000371#if defined(MS_WINDOWS)
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000372static PyObject*
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000373PyLocale_getdefaultlocale(PyObject* self)
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000374{
375 char encoding[100];
376 char locale[100];
377
Tim Peters885d4572001-11-28 20:27:42 +0000378 PyOS_snprintf(encoding, sizeof(encoding), "cp%d", GetACP());
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000379
380 if (GetLocaleInfo(LOCALE_USER_DEFAULT,
381 LOCALE_SISO639LANGNAME,
382 locale, sizeof(locale))) {
383 int i = strlen(locale);
384 locale[i++] = '_';
385 if (GetLocaleInfo(LOCALE_USER_DEFAULT,
386 LOCALE_SISO3166CTRYNAME,
387 locale+i, sizeof(locale)-i))
388 return Py_BuildValue("ss", locale, encoding);
389 }
390
391 /* If we end up here, this windows version didn't know about
392 ISO639/ISO3166 names (it's probably Windows 95). Return the
393 Windows language identifier instead (a hexadecimal number) */
394
395 locale[0] = '0';
396 locale[1] = 'x';
397 if (GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_IDEFAULTLANGUAGE,
398 locale+2, sizeof(locale)-2)) {
399 return Py_BuildValue("ss", locale, encoding);
400 }
401
402 /* cannot determine the language code (very unlikely) */
403 Py_INCREF(Py_None);
404 return Py_BuildValue("Os", Py_None, encoding);
405}
406#endif
407
Martin v. Löwis52ea7e92002-11-26 09:05:36 +0000408#if defined(__APPLE__)
Jack Jansen59f072a2004-07-15 13:31:39 +0000409/*
410** Find out what the current script is.
411** Donated by Fredrik Lund.
412*/
413static char *mac_getscript(void)
414{
415 CFStringEncoding enc = CFStringGetSystemEncoding();
416 static CFStringRef name = NULL;
417 /* Return the code name for the encodings for which we have codecs. */
418 switch(enc) {
419 case kCFStringEncodingMacRoman: return "mac-roman";
420 case kCFStringEncodingMacGreek: return "mac-greek";
421 case kCFStringEncodingMacCyrillic: return "mac-cyrillic";
422 case kCFStringEncodingMacTurkish: return "mac-turkish";
423 case kCFStringEncodingMacIcelandic: return "mac-icelandic";
424 /* XXX which one is mac-latin2? */
425 }
426 if (!name) {
427 /* This leaks a an object. */
428 name = CFStringConvertEncodingToIANACharSetName(enc);
429 }
430 return (char *)CFStringGetCStringPtr(name, 0);
431}
432
Jack Jansen307d7a42000-07-15 22:31:45 +0000433static PyObject*
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000434PyLocale_getdefaultlocale(PyObject* self)
Jack Jansen307d7a42000-07-15 22:31:45 +0000435{
Jack Jansen59f072a2004-07-15 13:31:39 +0000436 return Py_BuildValue("Os", Py_None, mac_getscript());
Jack Jansen307d7a42000-07-15 22:31:45 +0000437}
438#endif
439
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000440#ifdef HAVE_LANGINFO_H
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000441#define LANGINFO(X) {#X, X}
442struct langinfo_constant{
443 char* name;
444 int value;
445} langinfo_constants[] =
446{
447 /* These constants should exist on any langinfo implementation */
448 LANGINFO(DAY_1),
449 LANGINFO(DAY_2),
450 LANGINFO(DAY_3),
451 LANGINFO(DAY_4),
452 LANGINFO(DAY_5),
453 LANGINFO(DAY_6),
454 LANGINFO(DAY_7),
455
456 LANGINFO(ABDAY_1),
457 LANGINFO(ABDAY_2),
458 LANGINFO(ABDAY_3),
459 LANGINFO(ABDAY_4),
460 LANGINFO(ABDAY_5),
461 LANGINFO(ABDAY_6),
462 LANGINFO(ABDAY_7),
463
464 LANGINFO(MON_1),
465 LANGINFO(MON_2),
466 LANGINFO(MON_3),
467 LANGINFO(MON_4),
468 LANGINFO(MON_5),
469 LANGINFO(MON_6),
470 LANGINFO(MON_7),
471 LANGINFO(MON_8),
472 LANGINFO(MON_9),
473 LANGINFO(MON_10),
474 LANGINFO(MON_11),
475 LANGINFO(MON_12),
476
477 LANGINFO(ABMON_1),
478 LANGINFO(ABMON_2),
479 LANGINFO(ABMON_3),
480 LANGINFO(ABMON_4),
481 LANGINFO(ABMON_5),
482 LANGINFO(ABMON_6),
483 LANGINFO(ABMON_7),
484 LANGINFO(ABMON_8),
485 LANGINFO(ABMON_9),
486 LANGINFO(ABMON_10),
487 LANGINFO(ABMON_11),
488 LANGINFO(ABMON_12),
489
490#ifdef RADIXCHAR
491 /* The following are not available with glibc 2.0 */
492 LANGINFO(RADIXCHAR),
493 LANGINFO(THOUSEP),
494 /* YESSTR and NOSTR are deprecated in glibc, since they are
495 a special case of message translation, which should be rather
496 done using gettext. So we don't expose it to Python in the
497 first place.
498 LANGINFO(YESSTR),
499 LANGINFO(NOSTR),
500 */
501 LANGINFO(CRNCYSTR),
502#endif
503
504 LANGINFO(D_T_FMT),
505 LANGINFO(D_FMT),
506 LANGINFO(T_FMT),
507 LANGINFO(AM_STR),
508 LANGINFO(PM_STR),
509
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000510 /* The following constants are available only with XPG4, but...
511 AIX 3.2. only has CODESET.
512 OpenBSD doesn't have CODESET but has T_FMT_AMPM, and doesn't have
513 a few of the others.
514 Solution: ifdef-test them all. */
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000515#ifdef CODESET
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000516 LANGINFO(CODESET),
Martin v. Löwis496f9e42002-03-27 12:15:57 +0000517#endif
518#ifdef T_FMT_AMPM
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000519 LANGINFO(T_FMT_AMPM),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000520#endif
521#ifdef ERA
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000522 LANGINFO(ERA),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000523#endif
524#ifdef ERA_D_FMT
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000525 LANGINFO(ERA_D_FMT),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000526#endif
527#ifdef ERA_D_T_FMT
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000528 LANGINFO(ERA_D_T_FMT),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000529#endif
530#ifdef ERA_T_FMT
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000531 LANGINFO(ERA_T_FMT),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000532#endif
533#ifdef ALT_DIGITS
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000534 LANGINFO(ALT_DIGITS),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000535#endif
536#ifdef YESEXPR
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000537 LANGINFO(YESEXPR),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000538#endif
539#ifdef NOEXPR
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000540 LANGINFO(NOEXPR),
541#endif
542#ifdef _DATE_FMT
543 /* This is not available in all glibc versions that have CODESET. */
544 LANGINFO(_DATE_FMT),
545#endif
546 {0, 0}
547};
548
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000549PyDoc_STRVAR(nl_langinfo__doc__,
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000550"nl_langinfo(key) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000551"Return the value for the locale information associated with key.");
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000552
553static PyObject*
554PyLocale_nl_langinfo(PyObject* self, PyObject* args)
555{
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000556 int item, i;
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000557 if (!PyArg_ParseTuple(args, "i:nl_langinfo", &item))
558 return NULL;
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000559 /* Check whether this is a supported constant. GNU libc sometimes
560 returns numeric values in the char* return value, which would
561 crash PyString_FromString. */
562 for (i = 0; langinfo_constants[i].name; i++)
Hye-Shik Changc3a87b82004-03-21 19:34:30 +0000563 if (langinfo_constants[i].value == item) {
564 /* Check NULL as a workaround for GNU libc's returning NULL
565 instead of an empty string for nl_langinfo(ERA). */
566 const char *result = nl_langinfo(item);
567 return PyString_FromString(result != NULL ? result : "");
568 }
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000569 PyErr_SetString(PyExc_ValueError, "unsupported langinfo constant");
570 return NULL;
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000571}
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000572#endif /* HAVE_LANGINFO_H */
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000573
574#ifdef HAVE_LIBINTL_H
575
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000576PyDoc_STRVAR(gettext__doc__,
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000577"gettext(msg) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000578"Return translation of msg.");
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000579
580static PyObject*
581PyIntl_gettext(PyObject* self, PyObject *args)
582{
583 char *in;
584 if (!PyArg_ParseTuple(args, "z", &in))
585 return 0;
586 return PyString_FromString(gettext(in));
587}
588
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000589PyDoc_STRVAR(dgettext__doc__,
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000590"dgettext(domain, msg) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000591"Return translation of msg in domain.");
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000592
593static PyObject*
594PyIntl_dgettext(PyObject* self, PyObject *args)
595{
596 char *domain, *in;
597 if (!PyArg_ParseTuple(args, "zz", &domain, &in))
598 return 0;
599 return PyString_FromString(dgettext(domain, in));
600}
601
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000602PyDoc_STRVAR(dcgettext__doc__,
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000603"dcgettext(domain, msg, category) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000604"Return translation of msg in domain and category.");
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000605
606static PyObject*
607PyIntl_dcgettext(PyObject *self, PyObject *args)
608{
609 char *domain, *msgid;
610 int category;
611 if (!PyArg_ParseTuple(args, "zzi", &domain, &msgid, &category))
612 return 0;
613 return PyString_FromString(dcgettext(domain,msgid,category));
614}
615
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000616PyDoc_STRVAR(textdomain__doc__,
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000617"textdomain(domain) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000618"Set the C library's textdmain to domain, returning the new domain.");
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000619
620static PyObject*
621PyIntl_textdomain(PyObject* self, PyObject* args)
622{
623 char *domain;
624 if (!PyArg_ParseTuple(args, "z", &domain))
625 return 0;
626 domain = textdomain(domain);
627 if (!domain) {
628 PyErr_SetFromErrno(PyExc_OSError);
629 return NULL;
630 }
631 return PyString_FromString(domain);
632}
633
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000634PyDoc_STRVAR(bindtextdomain__doc__,
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000635"bindtextdomain(domain, dir) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000636"Bind the C library's domain to dir.");
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000637
638static PyObject*
639PyIntl_bindtextdomain(PyObject* self,PyObject*args)
640{
641 char *domain,*dirname;
642 if (!PyArg_ParseTuple(args, "zz", &domain, &dirname))
643 return 0;
644 dirname = bindtextdomain(domain, dirname);
645 if (!dirname) {
646 PyErr_SetFromErrno(PyExc_OSError);
647 return NULL;
648 }
649 return PyString_FromString(dirname);
650}
651
Gustavo Niemeyer7bd33c52004-07-22 18:44:01 +0000652#ifdef HAVE_BIND_TEXTDOMAIN_CODESET
653PyDoc_STRVAR(bind_textdomain_codeset__doc__,
654"bind_textdomain_codeset(domain, codeset) -> string\n"
655"Bind the C library's domain to codeset.");
656
657static PyObject*
658PyIntl_bind_textdomain_codeset(PyObject* self,PyObject*args)
659{
660 char *domain,*codeset;
661 if (!PyArg_ParseTuple(args, "sz", &domain, &codeset))
662 return NULL;
663 codeset = bind_textdomain_codeset(domain, codeset);
664 if (codeset)
665 return PyString_FromString(codeset);
666 Py_RETURN_NONE;
667}
668#endif
669
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000670#endif
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000671
Guido van Rossum220ecc81997-11-18 21:03:39 +0000672static struct PyMethodDef PyLocale_Methods[] = {
Andrew M. Kuchlinge365fb82000-08-03 02:06:16 +0000673 {"setlocale", (PyCFunction) PyLocale_setlocale,
674 METH_VARARGS, setlocale__doc__},
675 {"localeconv", (PyCFunction) PyLocale_localeconv,
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000676 METH_NOARGS, localeconv__doc__},
Andrew M. Kuchlinge365fb82000-08-03 02:06:16 +0000677 {"strcoll", (PyCFunction) PyLocale_strcoll,
678 METH_VARARGS, strcoll__doc__},
679 {"strxfrm", (PyCFunction) PyLocale_strxfrm,
680 METH_VARARGS, strxfrm__doc__},
Martin v. Löwis52ea7e92002-11-26 09:05:36 +0000681#if defined(MS_WINDOWS) || defined(__APPLE__)
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000682 {"_getdefaultlocale", (PyCFunction) PyLocale_getdefaultlocale, METH_NOARGS},
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000683#endif
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000684#ifdef HAVE_LANGINFO_H
685 {"nl_langinfo", (PyCFunction) PyLocale_nl_langinfo,
686 METH_VARARGS, nl_langinfo__doc__},
687#endif
Martin v. Löwisc6a7d7e2002-05-02 12:16:29 +0000688#ifdef HAVE_LIBINTL_H
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000689 {"gettext",(PyCFunction)PyIntl_gettext,METH_VARARGS,
690 gettext__doc__},
691 {"dgettext",(PyCFunction)PyIntl_dgettext,METH_VARARGS,
692 dgettext__doc__},
693 {"dcgettext",(PyCFunction)PyIntl_dcgettext,METH_VARARGS,
694 dcgettext__doc__},
695 {"textdomain",(PyCFunction)PyIntl_textdomain,METH_VARARGS,
696 textdomain__doc__},
697 {"bindtextdomain",(PyCFunction)PyIntl_bindtextdomain,METH_VARARGS,
698 bindtextdomain__doc__},
Gustavo Niemeyer7bd33c52004-07-22 18:44:01 +0000699#ifdef HAVE_BIND_TEXTDOMAIN_CODESET
700 {"bind_textdomain_codeset",(PyCFunction)PyIntl_bind_textdomain_codeset,
701 METH_VARARGS, bind_textdomain_codeset__doc__},
702#endif
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000703#endif
Guido van Rossum220ecc81997-11-18 21:03:39 +0000704 {NULL, NULL}
705};
706
Mark Hammondfe51c6d2002-08-02 02:27:13 +0000707PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000708init_locale(void)
Guido van Rossum220ecc81997-11-18 21:03:39 +0000709{
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000710 PyObject *m, *d, *x;
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000711#ifdef HAVE_LANGINFO_H
712 int i;
713#endif
Guido van Rossum220ecc81997-11-18 21:03:39 +0000714
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000715 m = Py_InitModule("_locale", PyLocale_Methods);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000716
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000717 d = PyModule_GetDict(m);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000718
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000719 x = PyInt_FromLong(LC_CTYPE);
720 PyDict_SetItemString(d, "LC_CTYPE", x);
721 Py_XDECREF(x);
722
723 x = PyInt_FromLong(LC_TIME);
724 PyDict_SetItemString(d, "LC_TIME", x);
725 Py_XDECREF(x);
726
727 x = PyInt_FromLong(LC_COLLATE);
728 PyDict_SetItemString(d, "LC_COLLATE", x);
729 Py_XDECREF(x);
730
731 x = PyInt_FromLong(LC_MONETARY);
732 PyDict_SetItemString(d, "LC_MONETARY", x);
733 Py_XDECREF(x);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000734
Guido van Rossum8d9c2e31997-12-09 19:35:11 +0000735#ifdef LC_MESSAGES
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000736 x = PyInt_FromLong(LC_MESSAGES);
737 PyDict_SetItemString(d, "LC_MESSAGES", x);
738 Py_XDECREF(x);
Guido van Rossum8d9c2e31997-12-09 19:35:11 +0000739#endif /* LC_MESSAGES */
Guido van Rossum220ecc81997-11-18 21:03:39 +0000740
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000741 x = PyInt_FromLong(LC_NUMERIC);
742 PyDict_SetItemString(d, "LC_NUMERIC", x);
743 Py_XDECREF(x);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000744
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000745 x = PyInt_FromLong(LC_ALL);
746 PyDict_SetItemString(d, "LC_ALL", x);
747 Py_XDECREF(x);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000748
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000749 x = PyInt_FromLong(CHAR_MAX);
750 PyDict_SetItemString(d, "CHAR_MAX", x);
751 Py_XDECREF(x);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000752
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000753 Error = PyErr_NewException("locale.Error", NULL, NULL);
754 PyDict_SetItemString(d, "Error", Error);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000755
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000756 x = PyString_FromString(locale__doc__);
757 PyDict_SetItemString(d, "__doc__", x);
758 Py_XDECREF(x);
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000759
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000760#ifdef HAVE_LANGINFO_H
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000761 for (i = 0; langinfo_constants[i].name; i++) {
762 PyModule_AddIntConstant(m, langinfo_constants[i].name,
763 langinfo_constants[i].value);
764 }
Martin v. Löwisf95dd0a2001-08-15 17:14:33 +0000765#endif
Guido van Rossum220ecc81997-11-18 21:03:39 +0000766}
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000767
768/*
769Local variables:
770c-basic-offset: 4
771indent-tabs-mode: nil
772End:
773*/