blob: f45b85e84519bc4a7cb917b3fa35903287d279cc [file] [log] [blame]
Guido van Rossum220ecc81997-11-18 21:03:39 +00001/***********************************************************
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +00002Copyright (C) 1997, 2002, 2003, 2007 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>
Guido van Rossum220ecc81997-11-18 21:03:39 +000015#include <locale.h>
16#include <string.h>
Guido van Rossum5cd70f41998-06-19 04:33:30 +000017#include <ctype.h>
Fredrik Lundh8f017a02000-07-08 19:57:37 +000018
Thomas Wouters0e3f5912006-08-11 14:57:12 +000019#ifdef HAVE_ERRNO_H
Thomas Wouters477c8d52006-05-27 19:21:47 +000020#include <errno.h>
21#endif
22
Martin v. Löwis9b75dca2001-08-10 13:58:50 +000023#ifdef HAVE_LANGINFO_H
24#include <langinfo.h>
25#endif
26
Martin v. Löwis2e64c342002-03-27 18:49:02 +000027#ifdef HAVE_LIBINTL_H
28#include <libintl.h>
29#endif
30
Martin v. Löwis9c36c292002-12-21 18:34:06 +000031#ifdef HAVE_WCHAR_H
32#include <wchar.h>
33#endif
34
Jack Jansen7107c1a2003-11-20 13:31:00 +000035#if defined(__APPLE__)
Jack Jansen59f072a2004-07-15 13:31:39 +000036#include <CoreFoundation/CoreFoundation.h>
Jack Jansen7107c1a2003-11-20 13:31:00 +000037#endif
38
Martin v. Löwis6238d2b2002-06-30 15:26:10 +000039#if defined(MS_WINDOWS)
Tim Peters7a1f9172002-07-14 22:14:19 +000040#define WIN32_LEAN_AND_MEAN
Fredrik Lundh8f017a02000-07-08 19:57:37 +000041#include <windows.h>
Guido van Rossum239a2181998-04-28 16:08:19 +000042#endif
Guido van Rossum220ecc81997-11-18 21:03:39 +000043
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000044PyDoc_STRVAR(locale__doc__, "Support for POSIX locales.");
Guido van Rossum220ecc81997-11-18 21:03:39 +000045
46static PyObject *Error;
47
48/* support functions for formatting floating point numbers */
49
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000050PyDoc_STRVAR(setlocale__doc__,
51"(integer,string=None) -> string. Activates/queries locale processing.");
Guido van Rossum220ecc81997-11-18 21:03:39 +000052
Guido van Rossum220ecc81997-11-18 21:03:39 +000053/* the grouping is terminated by either 0 or CHAR_MAX */
54static PyObject*
Fredrik Lundh8f017a02000-07-08 19:57:37 +000055copy_grouping(char* s)
Guido van Rossum220ecc81997-11-18 21:03:39 +000056{
Fredrik Lundh8f017a02000-07-08 19:57:37 +000057 int i;
58 PyObject *result, *val = NULL;
59
60 if (s[0] == '\0')
61 /* empty string: no grouping at all */
62 return PyList_New(0);
63
64 for (i = 0; s[i] != '\0' && s[i] != CHAR_MAX; i++)
65 ; /* nothing */
66
67 result = PyList_New(i+1);
68 if (!result)
69 return NULL;
70
71 i = -1;
72 do {
73 i++;
74 val = PyInt_FromLong(s[i]);
75 if (!val)
76 break;
77 if (PyList_SetItem(result, i, val)) {
78 Py_DECREF(val);
Fredrik Lundh89610a42000-07-08 20:07:24 +000079 val = NULL;
Fredrik Lundh8f017a02000-07-08 19:57:37 +000080 break;
81 }
82 } while (s[i] != '\0' && s[i] != CHAR_MAX);
83
84 if (!val) {
85 Py_DECREF(result);
86 return NULL;
Guido van Rossum220ecc81997-11-18 21:03:39 +000087 }
Fredrik Lundh8f017a02000-07-08 19:57:37 +000088
89 return result;
Guido van Rossum220ecc81997-11-18 21:03:39 +000090}
91
Guido van Rossum220ecc81997-11-18 21:03:39 +000092static PyObject*
Fredrik Lundh8f017a02000-07-08 19:57:37 +000093PyLocale_setlocale(PyObject* self, PyObject* args)
Guido van Rossum220ecc81997-11-18 21:03:39 +000094{
Fredrik Lundh8f017a02000-07-08 19:57:37 +000095 int category;
96 char *locale = NULL, *result;
97 PyObject *result_object;
Guido van Rossum220ecc81997-11-18 21:03:39 +000098
Fredrik Lundh8f017a02000-07-08 19:57:37 +000099 if (!PyArg_ParseTuple(args, "i|z:setlocale", &category, &locale))
Fredrik Lundh89610a42000-07-08 20:07:24 +0000100 return NULL;
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000101
102 if (locale) {
103 /* set locale */
104 result = setlocale(category, locale);
105 if (!result) {
106 /* operation failed, no setting was changed */
Martin v. Löwis25f90d52003-09-03 04:50:13 +0000107 PyErr_SetString(Error, "unsupported locale setting");
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000108 return NULL;
109 }
110 result_object = PyString_FromString(result);
Mark Hammond9a714752003-07-24 14:15:07 +0000111 if (!result_object)
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000112 return NULL;
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000113 } else {
114 /* get locale */
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000115 result = setlocale(category, NULL);
116 if (!result) {
117 PyErr_SetString(Error, "locale query failed");
118 return NULL;
119 }
120 result_object = PyString_FromString(result);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000121 }
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000122 return result_object;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000123}
124
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000125PyDoc_STRVAR(localeconv__doc__,
126"() -> dict. Returns numeric and monetary locale-specific parameters.");
Guido van Rossum220ecc81997-11-18 21:03:39 +0000127
128static PyObject*
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000129PyLocale_localeconv(PyObject* self)
Guido van Rossum220ecc81997-11-18 21:03:39 +0000130{
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000131 PyObject* result;
132 struct lconv *l;
133 PyObject *x;
134
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000135 result = PyDict_New();
Fredrik Lundh89610a42000-07-08 20:07:24 +0000136 if (!result)
137 return NULL;
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000138
139 /* if LC_NUMERIC is different in the C library, use saved value */
140 l = localeconv();
141
142 /* hopefully, the localeconv result survives the C library calls
143 involved herein */
144
145#define RESULT_STRING(s)\
146 x = PyString_FromString(l->s);\
147 if (!x) goto failed;\
148 PyDict_SetItemString(result, #s, x);\
149 Py_XDECREF(x)
150
151#define RESULT_INT(i)\
152 x = PyInt_FromLong(l->i);\
153 if (!x) goto failed;\
154 PyDict_SetItemString(result, #i, x);\
155 Py_XDECREF(x)
Guido van Rossum220ecc81997-11-18 21:03:39 +0000156
157 /* Numeric information */
Martin v. Löwis737ea822004-06-08 18:52:54 +0000158 RESULT_STRING(decimal_point);
159 RESULT_STRING(thousands_sep);
160 x = copy_grouping(l->grouping);
161 if (!x)
162 goto failed;
163 PyDict_SetItemString(result, "grouping", x);
164 Py_XDECREF(x);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000165
166 /* Monetary information */
167 RESULT_STRING(int_curr_symbol);
168 RESULT_STRING(currency_symbol);
169 RESULT_STRING(mon_decimal_point);
170 RESULT_STRING(mon_thousands_sep);
171 x = copy_grouping(l->mon_grouping);
172 if (!x)
173 goto failed;
174 PyDict_SetItemString(result, "mon_grouping", x);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000175 Py_XDECREF(x);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000176 RESULT_STRING(positive_sign);
177 RESULT_STRING(negative_sign);
178 RESULT_INT(int_frac_digits);
179 RESULT_INT(frac_digits);
180 RESULT_INT(p_cs_precedes);
181 RESULT_INT(p_sep_by_space);
182 RESULT_INT(n_cs_precedes);
183 RESULT_INT(n_sep_by_space);
184 RESULT_INT(p_sign_posn);
185 RESULT_INT(n_sign_posn);
186 return result;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000187
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000188 failed:
189 Py_XDECREF(result);
190 Py_XDECREF(x);
191 return NULL;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000192}
193
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000194PyDoc_STRVAR(strcoll__doc__,
195"string,string -> int. Compares two strings according to the locale.");
Guido van Rossum220ecc81997-11-18 21:03:39 +0000196
197static PyObject*
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000198PyLocale_strcoll(PyObject* self, PyObject* args)
Guido van Rossum220ecc81997-11-18 21:03:39 +0000199{
Guido van Rossum8d30cc02007-05-03 17:49:24 +0000200#if !defined(HAVE_WCSCOLL)
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000201 char *s1,*s2;
202
203 if (!PyArg_ParseTuple(args, "ss:strcoll", &s1, &s2))
204 return NULL;
205 return PyInt_FromLong(strcoll(s1, s2));
206#else
207 PyObject *os1, *os2, *result = NULL;
208 wchar_t *ws1 = NULL, *ws2 = NULL;
209 int rel1 = 0, rel2 = 0, len1, len2;
210
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000211 if (!PyArg_UnpackTuple(args, "strcoll", 2, 2, &os1, &os2))
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000212 return NULL;
213 /* If both arguments are byte strings, use strcoll. */
214 if (PyString_Check(os1) && PyString_Check(os2))
215 return PyInt_FromLong(strcoll(PyString_AS_STRING(os1),
216 PyString_AS_STRING(os2)));
217 /* If neither argument is unicode, it's an error. */
218 if (!PyUnicode_Check(os1) && !PyUnicode_Check(os2)) {
219 PyErr_SetString(PyExc_ValueError, "strcoll arguments must be strings");
220 }
221 /* Convert the non-unicode argument to unicode. */
222 if (!PyUnicode_Check(os1)) {
223 os1 = PyUnicode_FromObject(os1);
224 if (!os1)
225 return NULL;
226 rel1 = 1;
227 }
228 if (!PyUnicode_Check(os2)) {
229 os2 = PyUnicode_FromObject(os2);
230 if (!os2) {
231 Py_DECREF(os1);
232 return NULL;
233 }
234 rel2 = 1;
235 }
236 /* Convert the unicode strings to wchar[]. */
237 len1 = PyUnicode_GET_SIZE(os1) + 1;
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000238 ws1 = PyMem_MALLOC(len1 * sizeof(wchar_t));
239 if (!ws1) {
240 PyErr_NoMemory();
241 goto done;
242 }
243 if (PyUnicode_AsWideChar((PyUnicodeObject*)os1, ws1, len1) == -1)
244 goto done;
Marc-André Lemburga9cadcd2004-11-22 13:02:31 +0000245 ws1[len1 - 1] = 0;
246 len2 = PyUnicode_GET_SIZE(os2) + 1;
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000247 ws2 = PyMem_MALLOC(len2 * sizeof(wchar_t));
248 if (!ws2) {
249 PyErr_NoMemory();
250 goto done;
251 }
252 if (PyUnicode_AsWideChar((PyUnicodeObject*)os2, ws2, len2) == -1)
253 goto done;
Marc-André Lemburga9cadcd2004-11-22 13:02:31 +0000254 ws2[len2 - 1] = 0;
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000255 /* Collate the strings. */
256 result = PyInt_FromLong(wcscoll(ws1, ws2));
257 done:
258 /* Deallocate everything. */
259 if (ws1) PyMem_FREE(ws1);
260 if (ws2) PyMem_FREE(ws2);
261 if (rel1) {
262 Py_DECREF(os1);
263 }
264 if (rel2) {
265 Py_DECREF(os2);
266 }
267 return result;
268#endif
Guido van Rossum220ecc81997-11-18 21:03:39 +0000269}
270
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000271
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000272PyDoc_STRVAR(strxfrm__doc__,
273"string -> string. Returns a string that behaves for cmp locale-aware.");
Guido van Rossum220ecc81997-11-18 21:03:39 +0000274
275static PyObject*
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000276PyLocale_strxfrm(PyObject* self, PyObject* args)
Guido van Rossum220ecc81997-11-18 21:03:39 +0000277{
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000278 char *s, *buf;
279 size_t n1, n2;
280 PyObject *result;
281
Fredrik Lundh89610a42000-07-08 20:07:24 +0000282 if (!PyArg_ParseTuple(args, "s:strxfrm", &s))
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000283 return NULL;
284
285 /* assume no change in size, first */
286 n1 = strlen(s) + 1;
287 buf = PyMem_Malloc(n1);
288 if (!buf)
289 return PyErr_NoMemory();
Guido van Rossumd8faa362007-04-27 19:54:29 +0000290 n2 = strxfrm(buf, s, n1) + 1;
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000291 if (n2 > n1) {
292 /* more space needed */
293 buf = PyMem_Realloc(buf, n2);
294 if (!buf)
295 return PyErr_NoMemory();
296 strxfrm(buf, s, n2);
297 }
298 result = PyString_FromString(buf);
299 PyMem_Free(buf);
300 return result;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000301}
302
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000303#if defined(MS_WINDOWS)
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000304static PyObject*
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000305PyLocale_getdefaultlocale(PyObject* self)
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000306{
307 char encoding[100];
308 char locale[100];
309
Tim Peters885d4572001-11-28 20:27:42 +0000310 PyOS_snprintf(encoding, sizeof(encoding), "cp%d", GetACP());
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000311
312 if (GetLocaleInfo(LOCALE_USER_DEFAULT,
313 LOCALE_SISO639LANGNAME,
314 locale, sizeof(locale))) {
Martin v. Löwis18e16552006-02-15 17:27:45 +0000315 Py_ssize_t i = strlen(locale);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000316 locale[i++] = '_';
317 if (GetLocaleInfo(LOCALE_USER_DEFAULT,
318 LOCALE_SISO3166CTRYNAME,
Martin v. Löwis18e16552006-02-15 17:27:45 +0000319 locale+i, (int)(sizeof(locale)-i)))
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000320 return Py_BuildValue("ss", locale, encoding);
321 }
322
323 /* If we end up here, this windows version didn't know about
324 ISO639/ISO3166 names (it's probably Windows 95). Return the
325 Windows language identifier instead (a hexadecimal number) */
326
327 locale[0] = '0';
328 locale[1] = 'x';
329 if (GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_IDEFAULTLANGUAGE,
330 locale+2, sizeof(locale)-2)) {
331 return Py_BuildValue("ss", locale, encoding);
332 }
333
334 /* cannot determine the language code (very unlikely) */
335 Py_INCREF(Py_None);
336 return Py_BuildValue("Os", Py_None, encoding);
337}
338#endif
339
Martin v. Löwis52ea7e92002-11-26 09:05:36 +0000340#if defined(__APPLE__)
Jack Jansen59f072a2004-07-15 13:31:39 +0000341/*
342** Find out what the current script is.
Brett Cannon269ab622004-08-27 05:00:22 +0000343** Donated by Fredrik Lundh.
Jack Jansen59f072a2004-07-15 13:31:39 +0000344*/
345static char *mac_getscript(void)
346{
347 CFStringEncoding enc = CFStringGetSystemEncoding();
348 static CFStringRef name = NULL;
349 /* Return the code name for the encodings for which we have codecs. */
350 switch(enc) {
351 case kCFStringEncodingMacRoman: return "mac-roman";
352 case kCFStringEncodingMacGreek: return "mac-greek";
353 case kCFStringEncodingMacCyrillic: return "mac-cyrillic";
354 case kCFStringEncodingMacTurkish: return "mac-turkish";
355 case kCFStringEncodingMacIcelandic: return "mac-icelandic";
356 /* XXX which one is mac-latin2? */
357 }
358 if (!name) {
Brett Cannon5ce25872005-03-01 03:16:34 +0000359 /* This leaks an object. */
Jack Jansen59f072a2004-07-15 13:31:39 +0000360 name = CFStringConvertEncodingToIANACharSetName(enc);
361 }
362 return (char *)CFStringGetCStringPtr(name, 0);
363}
364
Jack Jansen307d7a42000-07-15 22:31:45 +0000365static PyObject*
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000366PyLocale_getdefaultlocale(PyObject* self)
Jack Jansen307d7a42000-07-15 22:31:45 +0000367{
Jack Jansen59f072a2004-07-15 13:31:39 +0000368 return Py_BuildValue("Os", Py_None, mac_getscript());
Jack Jansen307d7a42000-07-15 22:31:45 +0000369}
370#endif
371
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000372#ifdef HAVE_LANGINFO_H
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000373#define LANGINFO(X) {#X, X}
374struct langinfo_constant{
375 char* name;
376 int value;
377} langinfo_constants[] =
378{
379 /* These constants should exist on any langinfo implementation */
380 LANGINFO(DAY_1),
381 LANGINFO(DAY_2),
382 LANGINFO(DAY_3),
383 LANGINFO(DAY_4),
384 LANGINFO(DAY_5),
385 LANGINFO(DAY_6),
386 LANGINFO(DAY_7),
387
388 LANGINFO(ABDAY_1),
389 LANGINFO(ABDAY_2),
390 LANGINFO(ABDAY_3),
391 LANGINFO(ABDAY_4),
392 LANGINFO(ABDAY_5),
393 LANGINFO(ABDAY_6),
394 LANGINFO(ABDAY_7),
395
396 LANGINFO(MON_1),
397 LANGINFO(MON_2),
398 LANGINFO(MON_3),
399 LANGINFO(MON_4),
400 LANGINFO(MON_5),
401 LANGINFO(MON_6),
402 LANGINFO(MON_7),
403 LANGINFO(MON_8),
404 LANGINFO(MON_9),
405 LANGINFO(MON_10),
406 LANGINFO(MON_11),
407 LANGINFO(MON_12),
408
409 LANGINFO(ABMON_1),
410 LANGINFO(ABMON_2),
411 LANGINFO(ABMON_3),
412 LANGINFO(ABMON_4),
413 LANGINFO(ABMON_5),
414 LANGINFO(ABMON_6),
415 LANGINFO(ABMON_7),
416 LANGINFO(ABMON_8),
417 LANGINFO(ABMON_9),
418 LANGINFO(ABMON_10),
419 LANGINFO(ABMON_11),
420 LANGINFO(ABMON_12),
421
422#ifdef RADIXCHAR
423 /* The following are not available with glibc 2.0 */
424 LANGINFO(RADIXCHAR),
425 LANGINFO(THOUSEP),
426 /* YESSTR and NOSTR are deprecated in glibc, since they are
427 a special case of message translation, which should be rather
428 done using gettext. So we don't expose it to Python in the
429 first place.
430 LANGINFO(YESSTR),
431 LANGINFO(NOSTR),
432 */
433 LANGINFO(CRNCYSTR),
434#endif
435
436 LANGINFO(D_T_FMT),
437 LANGINFO(D_FMT),
438 LANGINFO(T_FMT),
439 LANGINFO(AM_STR),
440 LANGINFO(PM_STR),
441
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000442 /* The following constants are available only with XPG4, but...
443 AIX 3.2. only has CODESET.
444 OpenBSD doesn't have CODESET but has T_FMT_AMPM, and doesn't have
445 a few of the others.
446 Solution: ifdef-test them all. */
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000447#ifdef CODESET
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000448 LANGINFO(CODESET),
Martin v. Löwis496f9e42002-03-27 12:15:57 +0000449#endif
450#ifdef T_FMT_AMPM
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000451 LANGINFO(T_FMT_AMPM),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000452#endif
453#ifdef ERA
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000454 LANGINFO(ERA),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000455#endif
456#ifdef ERA_D_FMT
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000457 LANGINFO(ERA_D_FMT),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000458#endif
459#ifdef ERA_D_T_FMT
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000460 LANGINFO(ERA_D_T_FMT),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000461#endif
462#ifdef ERA_T_FMT
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000463 LANGINFO(ERA_T_FMT),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000464#endif
465#ifdef ALT_DIGITS
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000466 LANGINFO(ALT_DIGITS),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000467#endif
468#ifdef YESEXPR
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000469 LANGINFO(YESEXPR),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000470#endif
471#ifdef NOEXPR
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000472 LANGINFO(NOEXPR),
473#endif
474#ifdef _DATE_FMT
475 /* This is not available in all glibc versions that have CODESET. */
476 LANGINFO(_DATE_FMT),
477#endif
478 {0, 0}
479};
480
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000481PyDoc_STRVAR(nl_langinfo__doc__,
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000482"nl_langinfo(key) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000483"Return the value for the locale information associated with key.");
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000484
485static PyObject*
486PyLocale_nl_langinfo(PyObject* self, PyObject* args)
487{
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000488 int item, i;
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000489 if (!PyArg_ParseTuple(args, "i:nl_langinfo", &item))
490 return NULL;
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000491 /* Check whether this is a supported constant. GNU libc sometimes
492 returns numeric values in the char* return value, which would
493 crash PyString_FromString. */
494 for (i = 0; langinfo_constants[i].name; i++)
Hye-Shik Changc3a87b82004-03-21 19:34:30 +0000495 if (langinfo_constants[i].value == item) {
496 /* Check NULL as a workaround for GNU libc's returning NULL
497 instead of an empty string for nl_langinfo(ERA). */
498 const char *result = nl_langinfo(item);
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +0000499 /* XXX may have to convert this to wcs first. */
500 return PyUnicode_FromString(result != NULL ? result : "");
Hye-Shik Changc3a87b82004-03-21 19:34:30 +0000501 }
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000502 PyErr_SetString(PyExc_ValueError, "unsupported langinfo constant");
503 return NULL;
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000504}
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000505#endif /* HAVE_LANGINFO_H */
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000506
507#ifdef HAVE_LIBINTL_H
508
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000509PyDoc_STRVAR(gettext__doc__,
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000510"gettext(msg) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000511"Return translation of msg.");
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000512
513static PyObject*
514PyIntl_gettext(PyObject* self, PyObject *args)
515{
516 char *in;
517 if (!PyArg_ParseTuple(args, "z", &in))
518 return 0;
519 return PyString_FromString(gettext(in));
520}
521
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000522PyDoc_STRVAR(dgettext__doc__,
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000523"dgettext(domain, msg) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000524"Return translation of msg in domain.");
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000525
526static PyObject*
527PyIntl_dgettext(PyObject* self, PyObject *args)
528{
529 char *domain, *in;
530 if (!PyArg_ParseTuple(args, "zz", &domain, &in))
531 return 0;
532 return PyString_FromString(dgettext(domain, in));
533}
534
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000535PyDoc_STRVAR(dcgettext__doc__,
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000536"dcgettext(domain, msg, category) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000537"Return translation of msg in domain and category.");
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000538
539static PyObject*
540PyIntl_dcgettext(PyObject *self, PyObject *args)
541{
542 char *domain, *msgid;
543 int category;
544 if (!PyArg_ParseTuple(args, "zzi", &domain, &msgid, &category))
545 return 0;
546 return PyString_FromString(dcgettext(domain,msgid,category));
547}
548
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000549PyDoc_STRVAR(textdomain__doc__,
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000550"textdomain(domain) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000551"Set the C library's textdmain to domain, returning the new domain.");
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000552
553static PyObject*
554PyIntl_textdomain(PyObject* self, PyObject* args)
555{
556 char *domain;
557 if (!PyArg_ParseTuple(args, "z", &domain))
558 return 0;
559 domain = textdomain(domain);
560 if (!domain) {
561 PyErr_SetFromErrno(PyExc_OSError);
562 return NULL;
563 }
564 return PyString_FromString(domain);
565}
566
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000567PyDoc_STRVAR(bindtextdomain__doc__,
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000568"bindtextdomain(domain, dir) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000569"Bind the C library's domain to dir.");
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000570
571static PyObject*
572PyIntl_bindtextdomain(PyObject* self,PyObject*args)
573{
574 char *domain,*dirname;
575 if (!PyArg_ParseTuple(args, "zz", &domain, &dirname))
576 return 0;
577 dirname = bindtextdomain(domain, dirname);
578 if (!dirname) {
579 PyErr_SetFromErrno(PyExc_OSError);
580 return NULL;
581 }
582 return PyString_FromString(dirname);
583}
584
Gustavo Niemeyer7bd33c52004-07-22 18:44:01 +0000585#ifdef HAVE_BIND_TEXTDOMAIN_CODESET
586PyDoc_STRVAR(bind_textdomain_codeset__doc__,
587"bind_textdomain_codeset(domain, codeset) -> string\n"
588"Bind the C library's domain to codeset.");
589
590static PyObject*
591PyIntl_bind_textdomain_codeset(PyObject* self,PyObject*args)
592{
593 char *domain,*codeset;
594 if (!PyArg_ParseTuple(args, "sz", &domain, &codeset))
595 return NULL;
596 codeset = bind_textdomain_codeset(domain, codeset);
597 if (codeset)
598 return PyString_FromString(codeset);
599 Py_RETURN_NONE;
600}
601#endif
602
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000603#endif
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000604
Guido van Rossum220ecc81997-11-18 21:03:39 +0000605static struct PyMethodDef PyLocale_Methods[] = {
Andrew M. Kuchlinge365fb82000-08-03 02:06:16 +0000606 {"setlocale", (PyCFunction) PyLocale_setlocale,
607 METH_VARARGS, setlocale__doc__},
608 {"localeconv", (PyCFunction) PyLocale_localeconv,
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000609 METH_NOARGS, localeconv__doc__},
Andrew M. Kuchlinge365fb82000-08-03 02:06:16 +0000610 {"strcoll", (PyCFunction) PyLocale_strcoll,
611 METH_VARARGS, strcoll__doc__},
612 {"strxfrm", (PyCFunction) PyLocale_strxfrm,
613 METH_VARARGS, strxfrm__doc__},
Martin v. Löwis52ea7e92002-11-26 09:05:36 +0000614#if defined(MS_WINDOWS) || defined(__APPLE__)
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000615 {"_getdefaultlocale", (PyCFunction) PyLocale_getdefaultlocale, METH_NOARGS},
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000616#endif
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000617#ifdef HAVE_LANGINFO_H
618 {"nl_langinfo", (PyCFunction) PyLocale_nl_langinfo,
619 METH_VARARGS, nl_langinfo__doc__},
620#endif
Martin v. Löwisc6a7d7e2002-05-02 12:16:29 +0000621#ifdef HAVE_LIBINTL_H
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000622 {"gettext",(PyCFunction)PyIntl_gettext,METH_VARARGS,
623 gettext__doc__},
624 {"dgettext",(PyCFunction)PyIntl_dgettext,METH_VARARGS,
625 dgettext__doc__},
626 {"dcgettext",(PyCFunction)PyIntl_dcgettext,METH_VARARGS,
627 dcgettext__doc__},
628 {"textdomain",(PyCFunction)PyIntl_textdomain,METH_VARARGS,
629 textdomain__doc__},
630 {"bindtextdomain",(PyCFunction)PyIntl_bindtextdomain,METH_VARARGS,
631 bindtextdomain__doc__},
Gustavo Niemeyer7bd33c52004-07-22 18:44:01 +0000632#ifdef HAVE_BIND_TEXTDOMAIN_CODESET
633 {"bind_textdomain_codeset",(PyCFunction)PyIntl_bind_textdomain_codeset,
634 METH_VARARGS, bind_textdomain_codeset__doc__},
635#endif
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000636#endif
Guido van Rossum220ecc81997-11-18 21:03:39 +0000637 {NULL, NULL}
638};
639
Mark Hammondfe51c6d2002-08-02 02:27:13 +0000640PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000641init_locale(void)
Guido van Rossum220ecc81997-11-18 21:03:39 +0000642{
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000643 PyObject *m, *d, *x;
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000644#ifdef HAVE_LANGINFO_H
645 int i;
646#endif
Guido van Rossum220ecc81997-11-18 21:03:39 +0000647
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000648 m = Py_InitModule("_locale", PyLocale_Methods);
Neal Norwitz1ac754f2006-01-19 06:09:39 +0000649 if (m == NULL)
650 return;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000651
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000652 d = PyModule_GetDict(m);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000653
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000654 x = PyInt_FromLong(LC_CTYPE);
655 PyDict_SetItemString(d, "LC_CTYPE", x);
656 Py_XDECREF(x);
657
658 x = PyInt_FromLong(LC_TIME);
659 PyDict_SetItemString(d, "LC_TIME", x);
660 Py_XDECREF(x);
661
662 x = PyInt_FromLong(LC_COLLATE);
663 PyDict_SetItemString(d, "LC_COLLATE", x);
664 Py_XDECREF(x);
665
666 x = PyInt_FromLong(LC_MONETARY);
667 PyDict_SetItemString(d, "LC_MONETARY", x);
668 Py_XDECREF(x);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000669
Guido van Rossum8d9c2e31997-12-09 19:35:11 +0000670#ifdef LC_MESSAGES
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000671 x = PyInt_FromLong(LC_MESSAGES);
672 PyDict_SetItemString(d, "LC_MESSAGES", x);
673 Py_XDECREF(x);
Guido van Rossum8d9c2e31997-12-09 19:35:11 +0000674#endif /* LC_MESSAGES */
Guido van Rossum220ecc81997-11-18 21:03:39 +0000675
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000676 x = PyInt_FromLong(LC_NUMERIC);
677 PyDict_SetItemString(d, "LC_NUMERIC", x);
678 Py_XDECREF(x);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000679
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000680 x = PyInt_FromLong(LC_ALL);
681 PyDict_SetItemString(d, "LC_ALL", x);
682 Py_XDECREF(x);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000683
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000684 x = PyInt_FromLong(CHAR_MAX);
685 PyDict_SetItemString(d, "CHAR_MAX", x);
686 Py_XDECREF(x);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000687
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000688 Error = PyErr_NewException("locale.Error", NULL, NULL);
689 PyDict_SetItemString(d, "Error", Error);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000690
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000691 x = PyString_FromString(locale__doc__);
692 PyDict_SetItemString(d, "__doc__", x);
693 Py_XDECREF(x);
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000694
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000695#ifdef HAVE_LANGINFO_H
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000696 for (i = 0; langinfo_constants[i].name; i++) {
697 PyModule_AddIntConstant(m, langinfo_constants[i].name,
698 langinfo_constants[i].value);
699 }
Martin v. Löwisf95dd0a2001-08-15 17:14:33 +0000700#endif
Guido van Rossum220ecc81997-11-18 21:03:39 +0000701}
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000702
703/*
704Local variables:
705c-basic-offset: 4
706indent-tabs-mode: nil
707End:
708*/