blob: e3d1e7f49e16c435758d0c592aafe71ade503b48 [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;
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000308 ws1 = PyMem_MALLOC(len1 * sizeof(wchar_t));
309 if (!ws1) {
310 PyErr_NoMemory();
311 goto done;
312 }
313 if (PyUnicode_AsWideChar((PyUnicodeObject*)os1, ws1, len1) == -1)
314 goto done;
Marc-André Lemburga9cadcd2004-11-22 13:02:31 +0000315 ws1[len1 - 1] = 0;
316 len2 = PyUnicode_GET_SIZE(os2) + 1;
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000317 ws2 = PyMem_MALLOC(len2 * sizeof(wchar_t));
318 if (!ws2) {
319 PyErr_NoMemory();
320 goto done;
321 }
322 if (PyUnicode_AsWideChar((PyUnicodeObject*)os2, ws2, len2) == -1)
323 goto done;
Marc-André Lemburga9cadcd2004-11-22 13:02:31 +0000324 ws2[len2 - 1] = 0;
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000325 /* Collate the strings. */
326 result = PyInt_FromLong(wcscoll(ws1, ws2));
327 done:
328 /* Deallocate everything. */
329 if (ws1) PyMem_FREE(ws1);
330 if (ws2) PyMem_FREE(ws2);
331 if (rel1) {
332 Py_DECREF(os1);
333 }
334 if (rel2) {
335 Py_DECREF(os2);
336 }
337 return result;
338#endif
Guido van Rossum220ecc81997-11-18 21:03:39 +0000339}
340
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000341
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000342PyDoc_STRVAR(strxfrm__doc__,
343"string -> string. Returns a string that behaves for cmp locale-aware.");
Guido van Rossum220ecc81997-11-18 21:03:39 +0000344
345static PyObject*
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000346PyLocale_strxfrm(PyObject* self, PyObject* args)
Guido van Rossum220ecc81997-11-18 21:03:39 +0000347{
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000348 char *s, *buf;
349 size_t n1, n2;
350 PyObject *result;
351
Fredrik Lundh89610a42000-07-08 20:07:24 +0000352 if (!PyArg_ParseTuple(args, "s:strxfrm", &s))
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000353 return NULL;
354
355 /* assume no change in size, first */
356 n1 = strlen(s) + 1;
357 buf = PyMem_Malloc(n1);
358 if (!buf)
359 return PyErr_NoMemory();
360 n2 = strxfrm(buf, s, n1);
361 if (n2 > n1) {
362 /* more space needed */
363 buf = PyMem_Realloc(buf, n2);
364 if (!buf)
365 return PyErr_NoMemory();
366 strxfrm(buf, s, n2);
367 }
368 result = PyString_FromString(buf);
369 PyMem_Free(buf);
370 return result;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000371}
372
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000373#if defined(MS_WINDOWS)
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000374static PyObject*
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000375PyLocale_getdefaultlocale(PyObject* self)
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000376{
377 char encoding[100];
378 char locale[100];
379
Tim Peters885d4572001-11-28 20:27:42 +0000380 PyOS_snprintf(encoding, sizeof(encoding), "cp%d", GetACP());
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000381
382 if (GetLocaleInfo(LOCALE_USER_DEFAULT,
383 LOCALE_SISO639LANGNAME,
384 locale, sizeof(locale))) {
Martin v. Löwis18e16552006-02-15 17:27:45 +0000385 Py_ssize_t i = strlen(locale);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000386 locale[i++] = '_';
387 if (GetLocaleInfo(LOCALE_USER_DEFAULT,
388 LOCALE_SISO3166CTRYNAME,
Martin v. Löwis18e16552006-02-15 17:27:45 +0000389 locale+i, (int)(sizeof(locale)-i)))
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000390 return Py_BuildValue("ss", locale, encoding);
391 }
392
393 /* If we end up here, this windows version didn't know about
394 ISO639/ISO3166 names (it's probably Windows 95). Return the
395 Windows language identifier instead (a hexadecimal number) */
396
397 locale[0] = '0';
398 locale[1] = 'x';
399 if (GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_IDEFAULTLANGUAGE,
400 locale+2, sizeof(locale)-2)) {
401 return Py_BuildValue("ss", locale, encoding);
402 }
403
404 /* cannot determine the language code (very unlikely) */
405 Py_INCREF(Py_None);
406 return Py_BuildValue("Os", Py_None, encoding);
407}
408#endif
409
Martin v. Löwis52ea7e92002-11-26 09:05:36 +0000410#if defined(__APPLE__)
Jack Jansen59f072a2004-07-15 13:31:39 +0000411/*
412** Find out what the current script is.
Brett Cannon269ab622004-08-27 05:00:22 +0000413** Donated by Fredrik Lundh.
Jack Jansen59f072a2004-07-15 13:31:39 +0000414*/
415static char *mac_getscript(void)
416{
417 CFStringEncoding enc = CFStringGetSystemEncoding();
418 static CFStringRef name = NULL;
419 /* Return the code name for the encodings for which we have codecs. */
420 switch(enc) {
421 case kCFStringEncodingMacRoman: return "mac-roman";
422 case kCFStringEncodingMacGreek: return "mac-greek";
423 case kCFStringEncodingMacCyrillic: return "mac-cyrillic";
424 case kCFStringEncodingMacTurkish: return "mac-turkish";
425 case kCFStringEncodingMacIcelandic: return "mac-icelandic";
426 /* XXX which one is mac-latin2? */
427 }
428 if (!name) {
Brett Cannon5ce25872005-03-01 03:16:34 +0000429 /* This leaks an object. */
Jack Jansen59f072a2004-07-15 13:31:39 +0000430 name = CFStringConvertEncodingToIANACharSetName(enc);
431 }
432 return (char *)CFStringGetCStringPtr(name, 0);
433}
434
Jack Jansen307d7a42000-07-15 22:31:45 +0000435static PyObject*
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000436PyLocale_getdefaultlocale(PyObject* self)
Jack Jansen307d7a42000-07-15 22:31:45 +0000437{
Jack Jansen59f072a2004-07-15 13:31:39 +0000438 return Py_BuildValue("Os", Py_None, mac_getscript());
Jack Jansen307d7a42000-07-15 22:31:45 +0000439}
440#endif
441
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000442#ifdef HAVE_LANGINFO_H
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000443#define LANGINFO(X) {#X, X}
444struct langinfo_constant{
445 char* name;
446 int value;
447} langinfo_constants[] =
448{
449 /* These constants should exist on any langinfo implementation */
450 LANGINFO(DAY_1),
451 LANGINFO(DAY_2),
452 LANGINFO(DAY_3),
453 LANGINFO(DAY_4),
454 LANGINFO(DAY_5),
455 LANGINFO(DAY_6),
456 LANGINFO(DAY_7),
457
458 LANGINFO(ABDAY_1),
459 LANGINFO(ABDAY_2),
460 LANGINFO(ABDAY_3),
461 LANGINFO(ABDAY_4),
462 LANGINFO(ABDAY_5),
463 LANGINFO(ABDAY_6),
464 LANGINFO(ABDAY_7),
465
466 LANGINFO(MON_1),
467 LANGINFO(MON_2),
468 LANGINFO(MON_3),
469 LANGINFO(MON_4),
470 LANGINFO(MON_5),
471 LANGINFO(MON_6),
472 LANGINFO(MON_7),
473 LANGINFO(MON_8),
474 LANGINFO(MON_9),
475 LANGINFO(MON_10),
476 LANGINFO(MON_11),
477 LANGINFO(MON_12),
478
479 LANGINFO(ABMON_1),
480 LANGINFO(ABMON_2),
481 LANGINFO(ABMON_3),
482 LANGINFO(ABMON_4),
483 LANGINFO(ABMON_5),
484 LANGINFO(ABMON_6),
485 LANGINFO(ABMON_7),
486 LANGINFO(ABMON_8),
487 LANGINFO(ABMON_9),
488 LANGINFO(ABMON_10),
489 LANGINFO(ABMON_11),
490 LANGINFO(ABMON_12),
491
492#ifdef RADIXCHAR
493 /* The following are not available with glibc 2.0 */
494 LANGINFO(RADIXCHAR),
495 LANGINFO(THOUSEP),
496 /* YESSTR and NOSTR are deprecated in glibc, since they are
497 a special case of message translation, which should be rather
498 done using gettext. So we don't expose it to Python in the
499 first place.
500 LANGINFO(YESSTR),
501 LANGINFO(NOSTR),
502 */
503 LANGINFO(CRNCYSTR),
504#endif
505
506 LANGINFO(D_T_FMT),
507 LANGINFO(D_FMT),
508 LANGINFO(T_FMT),
509 LANGINFO(AM_STR),
510 LANGINFO(PM_STR),
511
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000512 /* The following constants are available only with XPG4, but...
513 AIX 3.2. only has CODESET.
514 OpenBSD doesn't have CODESET but has T_FMT_AMPM, and doesn't have
515 a few of the others.
516 Solution: ifdef-test them all. */
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000517#ifdef CODESET
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000518 LANGINFO(CODESET),
Martin v. Löwis496f9e42002-03-27 12:15:57 +0000519#endif
520#ifdef T_FMT_AMPM
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000521 LANGINFO(T_FMT_AMPM),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000522#endif
523#ifdef ERA
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000524 LANGINFO(ERA),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000525#endif
526#ifdef ERA_D_FMT
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000527 LANGINFO(ERA_D_FMT),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000528#endif
529#ifdef ERA_D_T_FMT
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000530 LANGINFO(ERA_D_T_FMT),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000531#endif
532#ifdef ERA_T_FMT
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000533 LANGINFO(ERA_T_FMT),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000534#endif
535#ifdef ALT_DIGITS
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000536 LANGINFO(ALT_DIGITS),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000537#endif
538#ifdef YESEXPR
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000539 LANGINFO(YESEXPR),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000540#endif
541#ifdef NOEXPR
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000542 LANGINFO(NOEXPR),
543#endif
544#ifdef _DATE_FMT
545 /* This is not available in all glibc versions that have CODESET. */
546 LANGINFO(_DATE_FMT),
547#endif
548 {0, 0}
549};
550
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000551PyDoc_STRVAR(nl_langinfo__doc__,
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000552"nl_langinfo(key) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000553"Return the value for the locale information associated with key.");
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000554
555static PyObject*
556PyLocale_nl_langinfo(PyObject* self, PyObject* args)
557{
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000558 int item, i;
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000559 if (!PyArg_ParseTuple(args, "i:nl_langinfo", &item))
560 return NULL;
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000561 /* Check whether this is a supported constant. GNU libc sometimes
562 returns numeric values in the char* return value, which would
563 crash PyString_FromString. */
564 for (i = 0; langinfo_constants[i].name; i++)
Hye-Shik Changc3a87b82004-03-21 19:34:30 +0000565 if (langinfo_constants[i].value == item) {
566 /* Check NULL as a workaround for GNU libc's returning NULL
567 instead of an empty string for nl_langinfo(ERA). */
568 const char *result = nl_langinfo(item);
569 return PyString_FromString(result != NULL ? result : "");
570 }
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000571 PyErr_SetString(PyExc_ValueError, "unsupported langinfo constant");
572 return NULL;
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000573}
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000574#endif /* HAVE_LANGINFO_H */
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000575
576#ifdef HAVE_LIBINTL_H
577
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000578PyDoc_STRVAR(gettext__doc__,
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000579"gettext(msg) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000580"Return translation of msg.");
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000581
582static PyObject*
583PyIntl_gettext(PyObject* self, PyObject *args)
584{
585 char *in;
586 if (!PyArg_ParseTuple(args, "z", &in))
587 return 0;
588 return PyString_FromString(gettext(in));
589}
590
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000591PyDoc_STRVAR(dgettext__doc__,
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000592"dgettext(domain, msg) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000593"Return translation of msg in domain.");
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000594
595static PyObject*
596PyIntl_dgettext(PyObject* self, PyObject *args)
597{
598 char *domain, *in;
599 if (!PyArg_ParseTuple(args, "zz", &domain, &in))
600 return 0;
601 return PyString_FromString(dgettext(domain, in));
602}
603
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000604PyDoc_STRVAR(dcgettext__doc__,
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000605"dcgettext(domain, msg, category) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000606"Return translation of msg in domain and category.");
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000607
608static PyObject*
609PyIntl_dcgettext(PyObject *self, PyObject *args)
610{
611 char *domain, *msgid;
612 int category;
613 if (!PyArg_ParseTuple(args, "zzi", &domain, &msgid, &category))
614 return 0;
615 return PyString_FromString(dcgettext(domain,msgid,category));
616}
617
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000618PyDoc_STRVAR(textdomain__doc__,
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000619"textdomain(domain) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000620"Set the C library's textdmain to domain, returning the new domain.");
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000621
622static PyObject*
623PyIntl_textdomain(PyObject* self, PyObject* args)
624{
625 char *domain;
626 if (!PyArg_ParseTuple(args, "z", &domain))
627 return 0;
628 domain = textdomain(domain);
629 if (!domain) {
630 PyErr_SetFromErrno(PyExc_OSError);
631 return NULL;
632 }
633 return PyString_FromString(domain);
634}
635
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000636PyDoc_STRVAR(bindtextdomain__doc__,
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000637"bindtextdomain(domain, dir) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000638"Bind the C library's domain to dir.");
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000639
640static PyObject*
641PyIntl_bindtextdomain(PyObject* self,PyObject*args)
642{
643 char *domain,*dirname;
644 if (!PyArg_ParseTuple(args, "zz", &domain, &dirname))
645 return 0;
646 dirname = bindtextdomain(domain, dirname);
647 if (!dirname) {
648 PyErr_SetFromErrno(PyExc_OSError);
649 return NULL;
650 }
651 return PyString_FromString(dirname);
652}
653
Gustavo Niemeyer7bd33c52004-07-22 18:44:01 +0000654#ifdef HAVE_BIND_TEXTDOMAIN_CODESET
655PyDoc_STRVAR(bind_textdomain_codeset__doc__,
656"bind_textdomain_codeset(domain, codeset) -> string\n"
657"Bind the C library's domain to codeset.");
658
659static PyObject*
660PyIntl_bind_textdomain_codeset(PyObject* self,PyObject*args)
661{
662 char *domain,*codeset;
663 if (!PyArg_ParseTuple(args, "sz", &domain, &codeset))
664 return NULL;
665 codeset = bind_textdomain_codeset(domain, codeset);
666 if (codeset)
667 return PyString_FromString(codeset);
668 Py_RETURN_NONE;
669}
670#endif
671
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000672#endif
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000673
Guido van Rossum220ecc81997-11-18 21:03:39 +0000674static struct PyMethodDef PyLocale_Methods[] = {
Andrew M. Kuchlinge365fb82000-08-03 02:06:16 +0000675 {"setlocale", (PyCFunction) PyLocale_setlocale,
676 METH_VARARGS, setlocale__doc__},
677 {"localeconv", (PyCFunction) PyLocale_localeconv,
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000678 METH_NOARGS, localeconv__doc__},
Andrew M. Kuchlinge365fb82000-08-03 02:06:16 +0000679 {"strcoll", (PyCFunction) PyLocale_strcoll,
680 METH_VARARGS, strcoll__doc__},
681 {"strxfrm", (PyCFunction) PyLocale_strxfrm,
682 METH_VARARGS, strxfrm__doc__},
Martin v. Löwis52ea7e92002-11-26 09:05:36 +0000683#if defined(MS_WINDOWS) || defined(__APPLE__)
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000684 {"_getdefaultlocale", (PyCFunction) PyLocale_getdefaultlocale, METH_NOARGS},
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000685#endif
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000686#ifdef HAVE_LANGINFO_H
687 {"nl_langinfo", (PyCFunction) PyLocale_nl_langinfo,
688 METH_VARARGS, nl_langinfo__doc__},
689#endif
Martin v. Löwisc6a7d7e2002-05-02 12:16:29 +0000690#ifdef HAVE_LIBINTL_H
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000691 {"gettext",(PyCFunction)PyIntl_gettext,METH_VARARGS,
692 gettext__doc__},
693 {"dgettext",(PyCFunction)PyIntl_dgettext,METH_VARARGS,
694 dgettext__doc__},
695 {"dcgettext",(PyCFunction)PyIntl_dcgettext,METH_VARARGS,
696 dcgettext__doc__},
697 {"textdomain",(PyCFunction)PyIntl_textdomain,METH_VARARGS,
698 textdomain__doc__},
699 {"bindtextdomain",(PyCFunction)PyIntl_bindtextdomain,METH_VARARGS,
700 bindtextdomain__doc__},
Gustavo Niemeyer7bd33c52004-07-22 18:44:01 +0000701#ifdef HAVE_BIND_TEXTDOMAIN_CODESET
702 {"bind_textdomain_codeset",(PyCFunction)PyIntl_bind_textdomain_codeset,
703 METH_VARARGS, bind_textdomain_codeset__doc__},
704#endif
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000705#endif
Guido van Rossum220ecc81997-11-18 21:03:39 +0000706 {NULL, NULL}
707};
708
Mark Hammondfe51c6d2002-08-02 02:27:13 +0000709PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000710init_locale(void)
Guido van Rossum220ecc81997-11-18 21:03:39 +0000711{
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000712 PyObject *m, *d, *x;
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000713#ifdef HAVE_LANGINFO_H
714 int i;
715#endif
Guido van Rossum220ecc81997-11-18 21:03:39 +0000716
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000717 m = Py_InitModule("_locale", PyLocale_Methods);
Neal Norwitz1ac754f2006-01-19 06:09:39 +0000718 if (m == NULL)
719 return;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000720
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000721 d = PyModule_GetDict(m);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000722
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000723 x = PyInt_FromLong(LC_CTYPE);
724 PyDict_SetItemString(d, "LC_CTYPE", x);
725 Py_XDECREF(x);
726
727 x = PyInt_FromLong(LC_TIME);
728 PyDict_SetItemString(d, "LC_TIME", x);
729 Py_XDECREF(x);
730
731 x = PyInt_FromLong(LC_COLLATE);
732 PyDict_SetItemString(d, "LC_COLLATE", x);
733 Py_XDECREF(x);
734
735 x = PyInt_FromLong(LC_MONETARY);
736 PyDict_SetItemString(d, "LC_MONETARY", x);
737 Py_XDECREF(x);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000738
Guido van Rossum8d9c2e31997-12-09 19:35:11 +0000739#ifdef LC_MESSAGES
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000740 x = PyInt_FromLong(LC_MESSAGES);
741 PyDict_SetItemString(d, "LC_MESSAGES", x);
742 Py_XDECREF(x);
Guido van Rossum8d9c2e31997-12-09 19:35:11 +0000743#endif /* LC_MESSAGES */
Guido van Rossum220ecc81997-11-18 21:03:39 +0000744
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000745 x = PyInt_FromLong(LC_NUMERIC);
746 PyDict_SetItemString(d, "LC_NUMERIC", 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(LC_ALL);
750 PyDict_SetItemString(d, "LC_ALL", x);
751 Py_XDECREF(x);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000752
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000753 x = PyInt_FromLong(CHAR_MAX);
754 PyDict_SetItemString(d, "CHAR_MAX", x);
755 Py_XDECREF(x);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000756
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000757 Error = PyErr_NewException("locale.Error", NULL, NULL);
758 PyDict_SetItemString(d, "Error", Error);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000759
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000760 x = PyString_FromString(locale__doc__);
761 PyDict_SetItemString(d, "__doc__", x);
762 Py_XDECREF(x);
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000763
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000764#ifdef HAVE_LANGINFO_H
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000765 for (i = 0; langinfo_constants[i].name; i++) {
766 PyModule_AddIntConstant(m, langinfo_constants[i].name,
767 langinfo_constants[i].value);
768 }
Martin v. Löwisf95dd0a2001-08-15 17:14:33 +0000769#endif
Guido van Rossum220ecc81997-11-18 21:03:39 +0000770}
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000771
772/*
773Local variables:
774c-basic-offset: 4
775indent-tabs-mode: nil
776End:
777*/