blob: f9c48e10f4916a7f4231bac08317ba7a3745f39b [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 }
Neal Norwitz7f9d29c2007-08-26 07:21:45 +0000110 result_object = PyUnicode_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 }
Neal Norwitz7f9d29c2007-08-26 07:21:45 +0000120 result_object = PyUnicode_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)\
Neal Norwitz3d7a90d2007-10-27 05:40:06 +0000146 x = PyUnicode_DecodeUnicodeEscape(l->s, strlen(l->s), "strict");\
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000147 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;
Neal Norwitz7f9d29c2007-08-26 07:21:45 +0000209 int len1, len2;
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000210
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;
Neal Norwitz7f9d29c2007-08-26 07:21:45 +0000213 /* Both arguments must be unicode, or it's an error. */
214 if (!PyUnicode_Check(os1) || !PyUnicode_Check(os2)) {
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000215 PyErr_SetString(PyExc_ValueError, "strcoll arguments must be strings");
216 }
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000217 /* Convert the unicode strings to wchar[]. */
218 len1 = PyUnicode_GET_SIZE(os1) + 1;
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000219 ws1 = PyMem_MALLOC(len1 * sizeof(wchar_t));
220 if (!ws1) {
221 PyErr_NoMemory();
222 goto done;
223 }
224 if (PyUnicode_AsWideChar((PyUnicodeObject*)os1, ws1, len1) == -1)
225 goto done;
Marc-André Lemburga9cadcd2004-11-22 13:02:31 +0000226 ws1[len1 - 1] = 0;
227 len2 = PyUnicode_GET_SIZE(os2) + 1;
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000228 ws2 = PyMem_MALLOC(len2 * sizeof(wchar_t));
229 if (!ws2) {
230 PyErr_NoMemory();
231 goto done;
232 }
233 if (PyUnicode_AsWideChar((PyUnicodeObject*)os2, ws2, len2) == -1)
234 goto done;
Marc-André Lemburga9cadcd2004-11-22 13:02:31 +0000235 ws2[len2 - 1] = 0;
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000236 /* Collate the strings. */
237 result = PyInt_FromLong(wcscoll(ws1, ws2));
238 done:
239 /* Deallocate everything. */
240 if (ws1) PyMem_FREE(ws1);
241 if (ws2) PyMem_FREE(ws2);
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000242 return result;
243#endif
Guido van Rossum220ecc81997-11-18 21:03:39 +0000244}
245
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000246
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000247PyDoc_STRVAR(strxfrm__doc__,
248"string -> string. Returns a string that behaves for cmp locale-aware.");
Guido van Rossum220ecc81997-11-18 21:03:39 +0000249
250static PyObject*
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000251PyLocale_strxfrm(PyObject* self, PyObject* args)
Guido van Rossum220ecc81997-11-18 21:03:39 +0000252{
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000253 char *s, *buf;
254 size_t n1, n2;
255 PyObject *result;
256
Fredrik Lundh89610a42000-07-08 20:07:24 +0000257 if (!PyArg_ParseTuple(args, "s:strxfrm", &s))
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000258 return NULL;
259
260 /* assume no change in size, first */
261 n1 = strlen(s) + 1;
262 buf = PyMem_Malloc(n1);
263 if (!buf)
264 return PyErr_NoMemory();
Guido van Rossumd8faa362007-04-27 19:54:29 +0000265 n2 = strxfrm(buf, s, n1) + 1;
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000266 if (n2 > n1) {
267 /* more space needed */
268 buf = PyMem_Realloc(buf, n2);
269 if (!buf)
270 return PyErr_NoMemory();
271 strxfrm(buf, s, n2);
272 }
Neal Norwitz7f9d29c2007-08-26 07:21:45 +0000273 result = PyUnicode_FromString(buf);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000274 PyMem_Free(buf);
275 return result;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000276}
277
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000278#if defined(MS_WINDOWS)
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000279static PyObject*
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000280PyLocale_getdefaultlocale(PyObject* self)
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000281{
282 char encoding[100];
283 char locale[100];
284
Tim Peters885d4572001-11-28 20:27:42 +0000285 PyOS_snprintf(encoding, sizeof(encoding), "cp%d", GetACP());
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000286
287 if (GetLocaleInfo(LOCALE_USER_DEFAULT,
288 LOCALE_SISO639LANGNAME,
289 locale, sizeof(locale))) {
Martin v. Löwis18e16552006-02-15 17:27:45 +0000290 Py_ssize_t i = strlen(locale);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000291 locale[i++] = '_';
292 if (GetLocaleInfo(LOCALE_USER_DEFAULT,
293 LOCALE_SISO3166CTRYNAME,
Martin v. Löwis18e16552006-02-15 17:27:45 +0000294 locale+i, (int)(sizeof(locale)-i)))
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000295 return Py_BuildValue("ss", locale, encoding);
296 }
297
298 /* If we end up here, this windows version didn't know about
299 ISO639/ISO3166 names (it's probably Windows 95). Return the
300 Windows language identifier instead (a hexadecimal number) */
301
302 locale[0] = '0';
303 locale[1] = 'x';
304 if (GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_IDEFAULTLANGUAGE,
305 locale+2, sizeof(locale)-2)) {
306 return Py_BuildValue("ss", locale, encoding);
307 }
308
309 /* cannot determine the language code (very unlikely) */
310 Py_INCREF(Py_None);
311 return Py_BuildValue("Os", Py_None, encoding);
312}
313#endif
314
Martin v. Löwis52ea7e92002-11-26 09:05:36 +0000315#if defined(__APPLE__)
Jack Jansen59f072a2004-07-15 13:31:39 +0000316/*
317** Find out what the current script is.
Brett Cannon269ab622004-08-27 05:00:22 +0000318** Donated by Fredrik Lundh.
Jack Jansen59f072a2004-07-15 13:31:39 +0000319*/
320static char *mac_getscript(void)
321{
322 CFStringEncoding enc = CFStringGetSystemEncoding();
323 static CFStringRef name = NULL;
324 /* Return the code name for the encodings for which we have codecs. */
325 switch(enc) {
326 case kCFStringEncodingMacRoman: return "mac-roman";
327 case kCFStringEncodingMacGreek: return "mac-greek";
328 case kCFStringEncodingMacCyrillic: return "mac-cyrillic";
329 case kCFStringEncodingMacTurkish: return "mac-turkish";
330 case kCFStringEncodingMacIcelandic: return "mac-icelandic";
331 /* XXX which one is mac-latin2? */
332 }
333 if (!name) {
Brett Cannon5ce25872005-03-01 03:16:34 +0000334 /* This leaks an object. */
Jack Jansen59f072a2004-07-15 13:31:39 +0000335 name = CFStringConvertEncodingToIANACharSetName(enc);
336 }
337 return (char *)CFStringGetCStringPtr(name, 0);
338}
339
Jack Jansen307d7a42000-07-15 22:31:45 +0000340static PyObject*
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000341PyLocale_getdefaultlocale(PyObject* self)
Jack Jansen307d7a42000-07-15 22:31:45 +0000342{
Jack Jansen59f072a2004-07-15 13:31:39 +0000343 return Py_BuildValue("Os", Py_None, mac_getscript());
Jack Jansen307d7a42000-07-15 22:31:45 +0000344}
345#endif
346
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000347#ifdef HAVE_LANGINFO_H
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000348#define LANGINFO(X) {#X, X}
349struct langinfo_constant{
350 char* name;
351 int value;
352} langinfo_constants[] =
353{
354 /* These constants should exist on any langinfo implementation */
355 LANGINFO(DAY_1),
356 LANGINFO(DAY_2),
357 LANGINFO(DAY_3),
358 LANGINFO(DAY_4),
359 LANGINFO(DAY_5),
360 LANGINFO(DAY_6),
361 LANGINFO(DAY_7),
362
363 LANGINFO(ABDAY_1),
364 LANGINFO(ABDAY_2),
365 LANGINFO(ABDAY_3),
366 LANGINFO(ABDAY_4),
367 LANGINFO(ABDAY_5),
368 LANGINFO(ABDAY_6),
369 LANGINFO(ABDAY_7),
370
371 LANGINFO(MON_1),
372 LANGINFO(MON_2),
373 LANGINFO(MON_3),
374 LANGINFO(MON_4),
375 LANGINFO(MON_5),
376 LANGINFO(MON_6),
377 LANGINFO(MON_7),
378 LANGINFO(MON_8),
379 LANGINFO(MON_9),
380 LANGINFO(MON_10),
381 LANGINFO(MON_11),
382 LANGINFO(MON_12),
383
384 LANGINFO(ABMON_1),
385 LANGINFO(ABMON_2),
386 LANGINFO(ABMON_3),
387 LANGINFO(ABMON_4),
388 LANGINFO(ABMON_5),
389 LANGINFO(ABMON_6),
390 LANGINFO(ABMON_7),
391 LANGINFO(ABMON_8),
392 LANGINFO(ABMON_9),
393 LANGINFO(ABMON_10),
394 LANGINFO(ABMON_11),
395 LANGINFO(ABMON_12),
396
397#ifdef RADIXCHAR
398 /* The following are not available with glibc 2.0 */
399 LANGINFO(RADIXCHAR),
400 LANGINFO(THOUSEP),
401 /* YESSTR and NOSTR are deprecated in glibc, since they are
402 a special case of message translation, which should be rather
403 done using gettext. So we don't expose it to Python in the
404 first place.
405 LANGINFO(YESSTR),
406 LANGINFO(NOSTR),
407 */
408 LANGINFO(CRNCYSTR),
409#endif
410
411 LANGINFO(D_T_FMT),
412 LANGINFO(D_FMT),
413 LANGINFO(T_FMT),
414 LANGINFO(AM_STR),
415 LANGINFO(PM_STR),
416
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000417 /* The following constants are available only with XPG4, but...
418 AIX 3.2. only has CODESET.
419 OpenBSD doesn't have CODESET but has T_FMT_AMPM, and doesn't have
420 a few of the others.
421 Solution: ifdef-test them all. */
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000422#ifdef CODESET
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000423 LANGINFO(CODESET),
Martin v. Löwis496f9e42002-03-27 12:15:57 +0000424#endif
425#ifdef T_FMT_AMPM
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000426 LANGINFO(T_FMT_AMPM),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000427#endif
428#ifdef ERA
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000429 LANGINFO(ERA),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000430#endif
431#ifdef ERA_D_FMT
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000432 LANGINFO(ERA_D_FMT),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000433#endif
434#ifdef ERA_D_T_FMT
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000435 LANGINFO(ERA_D_T_FMT),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000436#endif
437#ifdef ERA_T_FMT
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000438 LANGINFO(ERA_T_FMT),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000439#endif
440#ifdef ALT_DIGITS
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000441 LANGINFO(ALT_DIGITS),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000442#endif
443#ifdef YESEXPR
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000444 LANGINFO(YESEXPR),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000445#endif
446#ifdef NOEXPR
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000447 LANGINFO(NOEXPR),
448#endif
449#ifdef _DATE_FMT
450 /* This is not available in all glibc versions that have CODESET. */
451 LANGINFO(_DATE_FMT),
452#endif
453 {0, 0}
454};
455
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000456PyDoc_STRVAR(nl_langinfo__doc__,
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000457"nl_langinfo(key) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000458"Return the value for the locale information associated with key.");
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000459
460static PyObject*
461PyLocale_nl_langinfo(PyObject* self, PyObject* args)
462{
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000463 int item, i;
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000464 if (!PyArg_ParseTuple(args, "i:nl_langinfo", &item))
465 return NULL;
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000466 /* Check whether this is a supported constant. GNU libc sometimes
467 returns numeric values in the char* return value, which would
Neal Norwitz7f9d29c2007-08-26 07:21:45 +0000468 crash PyUnicode_FromString. */
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000469 for (i = 0; langinfo_constants[i].name; i++)
Hye-Shik Changc3a87b82004-03-21 19:34:30 +0000470 if (langinfo_constants[i].value == item) {
471 /* Check NULL as a workaround for GNU libc's returning NULL
472 instead of an empty string for nl_langinfo(ERA). */
473 const char *result = nl_langinfo(item);
Neal Norwitz3d7a90d2007-10-27 05:40:06 +0000474 result = result != NULL ? result : "";
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +0000475 /* XXX may have to convert this to wcs first. */
Neal Norwitz3d7a90d2007-10-27 05:40:06 +0000476 return PyUnicode_DecodeUnicodeEscape(result, strlen(result),
477 "strict");
Hye-Shik Changc3a87b82004-03-21 19:34:30 +0000478 }
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000479 PyErr_SetString(PyExc_ValueError, "unsupported langinfo constant");
480 return NULL;
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000481}
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000482#endif /* HAVE_LANGINFO_H */
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000483
484#ifdef HAVE_LIBINTL_H
485
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000486PyDoc_STRVAR(gettext__doc__,
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000487"gettext(msg) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000488"Return translation of msg.");
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000489
490static PyObject*
491PyIntl_gettext(PyObject* self, PyObject *args)
492{
493 char *in;
494 if (!PyArg_ParseTuple(args, "z", &in))
495 return 0;
Neal Norwitz7f9d29c2007-08-26 07:21:45 +0000496 return PyUnicode_FromString(gettext(in));
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000497}
498
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000499PyDoc_STRVAR(dgettext__doc__,
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000500"dgettext(domain, msg) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000501"Return translation of msg in domain.");
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000502
503static PyObject*
504PyIntl_dgettext(PyObject* self, PyObject *args)
505{
506 char *domain, *in;
507 if (!PyArg_ParseTuple(args, "zz", &domain, &in))
508 return 0;
Neal Norwitz7f9d29c2007-08-26 07:21:45 +0000509 return PyUnicode_FromString(dgettext(domain, in));
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000510}
511
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000512PyDoc_STRVAR(dcgettext__doc__,
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000513"dcgettext(domain, msg, category) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000514"Return translation of msg in domain and category.");
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000515
516static PyObject*
517PyIntl_dcgettext(PyObject *self, PyObject *args)
518{
519 char *domain, *msgid;
520 int category;
521 if (!PyArg_ParseTuple(args, "zzi", &domain, &msgid, &category))
522 return 0;
Neal Norwitz7f9d29c2007-08-26 07:21:45 +0000523 return PyUnicode_FromString(dcgettext(domain,msgid,category));
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000524}
525
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000526PyDoc_STRVAR(textdomain__doc__,
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000527"textdomain(domain) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000528"Set the C library's textdmain to domain, returning the new domain.");
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000529
530static PyObject*
531PyIntl_textdomain(PyObject* self, PyObject* args)
532{
533 char *domain;
534 if (!PyArg_ParseTuple(args, "z", &domain))
535 return 0;
536 domain = textdomain(domain);
537 if (!domain) {
538 PyErr_SetFromErrno(PyExc_OSError);
539 return NULL;
540 }
Neal Norwitz7f9d29c2007-08-26 07:21:45 +0000541 return PyUnicode_FromString(domain);
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000542}
543
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000544PyDoc_STRVAR(bindtextdomain__doc__,
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000545"bindtextdomain(domain, dir) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000546"Bind the C library's domain to dir.");
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000547
548static PyObject*
549PyIntl_bindtextdomain(PyObject* self,PyObject*args)
550{
551 char *domain,*dirname;
552 if (!PyArg_ParseTuple(args, "zz", &domain, &dirname))
553 return 0;
554 dirname = bindtextdomain(domain, dirname);
555 if (!dirname) {
556 PyErr_SetFromErrno(PyExc_OSError);
557 return NULL;
558 }
Neal Norwitz7f9d29c2007-08-26 07:21:45 +0000559 return PyUnicode_FromString(dirname);
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000560}
561
Gustavo Niemeyer7bd33c52004-07-22 18:44:01 +0000562#ifdef HAVE_BIND_TEXTDOMAIN_CODESET
563PyDoc_STRVAR(bind_textdomain_codeset__doc__,
564"bind_textdomain_codeset(domain, codeset) -> string\n"
565"Bind the C library's domain to codeset.");
566
567static PyObject*
568PyIntl_bind_textdomain_codeset(PyObject* self,PyObject*args)
569{
570 char *domain,*codeset;
571 if (!PyArg_ParseTuple(args, "sz", &domain, &codeset))
572 return NULL;
573 codeset = bind_textdomain_codeset(domain, codeset);
574 if (codeset)
Neal Norwitz7f9d29c2007-08-26 07:21:45 +0000575 return PyUnicode_FromString(codeset);
Gustavo Niemeyer7bd33c52004-07-22 18:44:01 +0000576 Py_RETURN_NONE;
577}
578#endif
579
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000580#endif
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000581
Guido van Rossum220ecc81997-11-18 21:03:39 +0000582static struct PyMethodDef PyLocale_Methods[] = {
Andrew M. Kuchlinge365fb82000-08-03 02:06:16 +0000583 {"setlocale", (PyCFunction) PyLocale_setlocale,
584 METH_VARARGS, setlocale__doc__},
585 {"localeconv", (PyCFunction) PyLocale_localeconv,
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000586 METH_NOARGS, localeconv__doc__},
Andrew M. Kuchlinge365fb82000-08-03 02:06:16 +0000587 {"strcoll", (PyCFunction) PyLocale_strcoll,
588 METH_VARARGS, strcoll__doc__},
589 {"strxfrm", (PyCFunction) PyLocale_strxfrm,
590 METH_VARARGS, strxfrm__doc__},
Martin v. Löwis52ea7e92002-11-26 09:05:36 +0000591#if defined(MS_WINDOWS) || defined(__APPLE__)
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000592 {"_getdefaultlocale", (PyCFunction) PyLocale_getdefaultlocale, METH_NOARGS},
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000593#endif
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000594#ifdef HAVE_LANGINFO_H
595 {"nl_langinfo", (PyCFunction) PyLocale_nl_langinfo,
596 METH_VARARGS, nl_langinfo__doc__},
597#endif
Martin v. Löwisc6a7d7e2002-05-02 12:16:29 +0000598#ifdef HAVE_LIBINTL_H
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000599 {"gettext",(PyCFunction)PyIntl_gettext,METH_VARARGS,
600 gettext__doc__},
601 {"dgettext",(PyCFunction)PyIntl_dgettext,METH_VARARGS,
602 dgettext__doc__},
603 {"dcgettext",(PyCFunction)PyIntl_dcgettext,METH_VARARGS,
604 dcgettext__doc__},
605 {"textdomain",(PyCFunction)PyIntl_textdomain,METH_VARARGS,
606 textdomain__doc__},
607 {"bindtextdomain",(PyCFunction)PyIntl_bindtextdomain,METH_VARARGS,
608 bindtextdomain__doc__},
Gustavo Niemeyer7bd33c52004-07-22 18:44:01 +0000609#ifdef HAVE_BIND_TEXTDOMAIN_CODESET
610 {"bind_textdomain_codeset",(PyCFunction)PyIntl_bind_textdomain_codeset,
611 METH_VARARGS, bind_textdomain_codeset__doc__},
612#endif
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000613#endif
Guido van Rossum220ecc81997-11-18 21:03:39 +0000614 {NULL, NULL}
615};
616
Mark Hammondfe51c6d2002-08-02 02:27:13 +0000617PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000618init_locale(void)
Guido van Rossum220ecc81997-11-18 21:03:39 +0000619{
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000620 PyObject *m, *d, *x;
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000621#ifdef HAVE_LANGINFO_H
622 int i;
623#endif
Guido van Rossum220ecc81997-11-18 21:03:39 +0000624
Neal Norwitzf9e115a2007-08-23 18:08:11 +0000625 m = Py_InitModule3("_locale", PyLocale_Methods, locale__doc__);
Neal Norwitz1ac754f2006-01-19 06:09:39 +0000626 if (m == NULL)
627 return;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000628
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000629 d = PyModule_GetDict(m);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000630
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000631 x = PyInt_FromLong(LC_CTYPE);
632 PyDict_SetItemString(d, "LC_CTYPE", x);
633 Py_XDECREF(x);
634
635 x = PyInt_FromLong(LC_TIME);
636 PyDict_SetItemString(d, "LC_TIME", x);
637 Py_XDECREF(x);
638
639 x = PyInt_FromLong(LC_COLLATE);
640 PyDict_SetItemString(d, "LC_COLLATE", x);
641 Py_XDECREF(x);
642
643 x = PyInt_FromLong(LC_MONETARY);
644 PyDict_SetItemString(d, "LC_MONETARY", x);
645 Py_XDECREF(x);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000646
Guido van Rossum8d9c2e31997-12-09 19:35:11 +0000647#ifdef LC_MESSAGES
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000648 x = PyInt_FromLong(LC_MESSAGES);
649 PyDict_SetItemString(d, "LC_MESSAGES", x);
650 Py_XDECREF(x);
Guido van Rossum8d9c2e31997-12-09 19:35:11 +0000651#endif /* LC_MESSAGES */
Guido van Rossum220ecc81997-11-18 21:03:39 +0000652
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000653 x = PyInt_FromLong(LC_NUMERIC);
654 PyDict_SetItemString(d, "LC_NUMERIC", x);
655 Py_XDECREF(x);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000656
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000657 x = PyInt_FromLong(LC_ALL);
658 PyDict_SetItemString(d, "LC_ALL", x);
659 Py_XDECREF(x);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000660
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000661 x = PyInt_FromLong(CHAR_MAX);
662 PyDict_SetItemString(d, "CHAR_MAX", x);
663 Py_XDECREF(x);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000664
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000665 Error = PyErr_NewException("locale.Error", NULL, NULL);
666 PyDict_SetItemString(d, "Error", Error);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000667
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000668#ifdef HAVE_LANGINFO_H
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000669 for (i = 0; langinfo_constants[i].name; i++) {
670 PyModule_AddIntConstant(m, langinfo_constants[i].name,
671 langinfo_constants[i].value);
672 }
Martin v. Löwisf95dd0a2001-08-15 17:14:33 +0000673#endif
Guido van Rossum220ecc81997-11-18 21:03:39 +0000674}
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000675
676/*
677Local variables:
678c-basic-offset: 4
679indent-tabs-mode: nil
680End:
681*/