blob: 8bcdb102ae44f987a597fb35c8e56f41ee23cf67 [file] [log] [blame]
Guido van Rossum220ecc81997-11-18 21:03:39 +00001/***********************************************************
Martin v. Löwis92fab752008-03-08 10:40:41 +00002Copyright (C) 1997, 2002, 2003, 2007, 2008 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
Martin v. Löwis6238d2b2002-06-30 15:26:10 +000035#if defined(MS_WINDOWS)
Tim Peters7a1f9172002-07-14 22:14:19 +000036#define WIN32_LEAN_AND_MEAN
Fredrik Lundh8f017a02000-07-08 19:57:37 +000037#include <windows.h>
Guido van Rossum239a2181998-04-28 16:08:19 +000038#endif
Guido van Rossum220ecc81997-11-18 21:03:39 +000039
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000040PyDoc_STRVAR(locale__doc__, "Support for POSIX locales.");
Guido van Rossum220ecc81997-11-18 21:03:39 +000041
42static PyObject *Error;
43
Martin v. Löwis92fab752008-03-08 10:40:41 +000044/* Convert a char* to a Unicode object according to the current locale */
45static PyObject*
46str2uni(const char* s)
47{
Antoine Pitroufff95302008-09-03 18:58:51 +000048#ifdef HAVE_BROKEN_MBSTOWCS
49 size_t needed = strlen(s);
50#else
Martin v. Löwis92fab752008-03-08 10:40:41 +000051 size_t needed = mbstowcs(NULL, s, 0);
Antoine Pitroufff95302008-09-03 18:58:51 +000052#endif
Martin v. Löwis92fab752008-03-08 10:40:41 +000053 size_t res1;
54 wchar_t smallbuf[30];
55 wchar_t *dest;
56 PyObject *res2;
57 if (needed == (size_t)-1) {
58 PyErr_SetString(PyExc_ValueError, "Cannot convert byte to string");
59 return NULL;
60 }
Martin v. Löwis5bacec12008-03-08 13:39:58 +000061 if (needed*sizeof(wchar_t) < sizeof(smallbuf))
Martin v. Löwis92fab752008-03-08 10:40:41 +000062 dest = smallbuf;
63 else {
Martin v. Löwisa69e1ef2008-03-08 10:54:31 +000064 dest = PyMem_Malloc((needed+1)*sizeof(wchar_t));
Martin v. Löwis92fab752008-03-08 10:40:41 +000065 if (!dest)
66 return PyErr_NoMemory();
67 }
68 /* This shouldn't fail now */
69 res1 = mbstowcs(dest, s, needed+1);
Antoine Pitroufff95302008-09-03 18:58:51 +000070#ifdef HAVE_BROKEN_MBSTOWCS
71 assert(res1 != (size_t)-1);
72#else
Martin v. Löwisce7a1122008-03-08 10:59:49 +000073 assert(res1 == needed);
Antoine Pitroufff95302008-09-03 18:58:51 +000074#endif
Martin v. Löwis92fab752008-03-08 10:40:41 +000075 res2 = PyUnicode_FromWideChar(dest, res1);
76 if (dest != smallbuf)
77 PyMem_Free(dest);
78 return res2;
79}
80
Guido van Rossum220ecc81997-11-18 21:03:39 +000081/* support functions for formatting floating point numbers */
82
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000083PyDoc_STRVAR(setlocale__doc__,
84"(integer,string=None) -> string. Activates/queries locale processing.");
Guido van Rossum220ecc81997-11-18 21:03:39 +000085
Guido van Rossum220ecc81997-11-18 21:03:39 +000086/* the grouping is terminated by either 0 or CHAR_MAX */
87static PyObject*
Fredrik Lundh8f017a02000-07-08 19:57:37 +000088copy_grouping(char* s)
Guido van Rossum220ecc81997-11-18 21:03:39 +000089{
Fredrik Lundh8f017a02000-07-08 19:57:37 +000090 int i;
91 PyObject *result, *val = NULL;
92
93 if (s[0] == '\0')
94 /* empty string: no grouping at all */
95 return PyList_New(0);
96
97 for (i = 0; s[i] != '\0' && s[i] != CHAR_MAX; i++)
98 ; /* nothing */
99
100 result = PyList_New(i+1);
101 if (!result)
102 return NULL;
103
104 i = -1;
105 do {
106 i++;
Christian Heimes217cfd12007-12-02 14:31:20 +0000107 val = PyLong_FromLong(s[i]);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000108 if (!val)
109 break;
110 if (PyList_SetItem(result, i, val)) {
111 Py_DECREF(val);
Fredrik Lundh89610a42000-07-08 20:07:24 +0000112 val = NULL;
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000113 break;
114 }
115 } while (s[i] != '\0' && s[i] != CHAR_MAX);
116
117 if (!val) {
118 Py_DECREF(result);
119 return NULL;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000120 }
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000121
122 return result;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000123}
124
Guido van Rossum220ecc81997-11-18 21:03:39 +0000125static PyObject*
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000126PyLocale_setlocale(PyObject* self, PyObject* args)
Guido van Rossum220ecc81997-11-18 21:03:39 +0000127{
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000128 int category;
129 char *locale = NULL, *result;
130 PyObject *result_object;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000131
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000132 if (!PyArg_ParseTuple(args, "i|z:setlocale", &category, &locale))
Fredrik Lundh89610a42000-07-08 20:07:24 +0000133 return NULL;
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000134
135 if (locale) {
136 /* set locale */
137 result = setlocale(category, locale);
138 if (!result) {
139 /* operation failed, no setting was changed */
Martin v. Löwis25f90d52003-09-03 04:50:13 +0000140 PyErr_SetString(Error, "unsupported locale setting");
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000141 return NULL;
142 }
Martin v. Löwis92fab752008-03-08 10:40:41 +0000143 result_object = str2uni(result);
Mark Hammond9a714752003-07-24 14:15:07 +0000144 if (!result_object)
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000145 return NULL;
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000146 } else {
147 /* get locale */
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000148 result = setlocale(category, NULL);
149 if (!result) {
150 PyErr_SetString(Error, "locale query failed");
151 return NULL;
152 }
Martin v. Löwis92fab752008-03-08 10:40:41 +0000153 result_object = str2uni(result);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000154 }
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000155 return result_object;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000156}
157
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000158PyDoc_STRVAR(localeconv__doc__,
159"() -> dict. Returns numeric and monetary locale-specific parameters.");
Guido van Rossum220ecc81997-11-18 21:03:39 +0000160
161static PyObject*
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000162PyLocale_localeconv(PyObject* self)
Guido van Rossum220ecc81997-11-18 21:03:39 +0000163{
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000164 PyObject* result;
165 struct lconv *l;
166 PyObject *x;
167
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000168 result = PyDict_New();
Fredrik Lundh89610a42000-07-08 20:07:24 +0000169 if (!result)
170 return NULL;
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000171
172 /* if LC_NUMERIC is different in the C library, use saved value */
173 l = localeconv();
174
175 /* hopefully, the localeconv result survives the C library calls
176 involved herein */
177
178#define RESULT_STRING(s)\
Martin v. Löwis92fab752008-03-08 10:40:41 +0000179 x = str2uni(l->s); \
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000180 if (!x) goto failed;\
181 PyDict_SetItemString(result, #s, x);\
182 Py_XDECREF(x)
183
184#define RESULT_INT(i)\
Christian Heimes217cfd12007-12-02 14:31:20 +0000185 x = PyLong_FromLong(l->i);\
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000186 if (!x) goto failed;\
187 PyDict_SetItemString(result, #i, x);\
188 Py_XDECREF(x)
Guido van Rossum220ecc81997-11-18 21:03:39 +0000189
190 /* Numeric information */
Martin v. Löwis737ea822004-06-08 18:52:54 +0000191 RESULT_STRING(decimal_point);
192 RESULT_STRING(thousands_sep);
193 x = copy_grouping(l->grouping);
194 if (!x)
195 goto failed;
196 PyDict_SetItemString(result, "grouping", x);
197 Py_XDECREF(x);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000198
199 /* Monetary information */
200 RESULT_STRING(int_curr_symbol);
201 RESULT_STRING(currency_symbol);
202 RESULT_STRING(mon_decimal_point);
203 RESULT_STRING(mon_thousands_sep);
204 x = copy_grouping(l->mon_grouping);
205 if (!x)
206 goto failed;
207 PyDict_SetItemString(result, "mon_grouping", x);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000208 Py_XDECREF(x);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000209 RESULT_STRING(positive_sign);
210 RESULT_STRING(negative_sign);
211 RESULT_INT(int_frac_digits);
212 RESULT_INT(frac_digits);
213 RESULT_INT(p_cs_precedes);
214 RESULT_INT(p_sep_by_space);
215 RESULT_INT(n_cs_precedes);
216 RESULT_INT(n_sep_by_space);
217 RESULT_INT(p_sign_posn);
218 RESULT_INT(n_sign_posn);
219 return result;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000220
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000221 failed:
222 Py_XDECREF(result);
223 Py_XDECREF(x);
224 return NULL;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000225}
226
Martin v. Löwis92fab752008-03-08 10:40:41 +0000227#if defined(HAVE_WCSCOLL)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000228PyDoc_STRVAR(strcoll__doc__,
229"string,string -> int. Compares two strings according to the locale.");
Guido van Rossum220ecc81997-11-18 21:03:39 +0000230
231static PyObject*
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000232PyLocale_strcoll(PyObject* self, PyObject* args)
Guido van Rossum220ecc81997-11-18 21:03:39 +0000233{
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000234 PyObject *os1, *os2, *result = NULL;
235 wchar_t *ws1 = NULL, *ws2 = NULL;
Martin v. Löwis92fab752008-03-08 10:40:41 +0000236 Py_ssize_t len1, len2;
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000237
Martin v. Löwis92fab752008-03-08 10:40:41 +0000238 if (!PyArg_ParseTuple(args, "UU:strcoll", &os1, &os2))
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000239 return NULL;
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000240 /* Convert the unicode strings to wchar[]. */
241 len1 = PyUnicode_GET_SIZE(os1) + 1;
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000242 ws1 = PyMem_MALLOC(len1 * sizeof(wchar_t));
243 if (!ws1) {
244 PyErr_NoMemory();
245 goto done;
246 }
247 if (PyUnicode_AsWideChar((PyUnicodeObject*)os1, ws1, len1) == -1)
248 goto done;
Marc-André Lemburga9cadcd2004-11-22 13:02:31 +0000249 ws1[len1 - 1] = 0;
250 len2 = PyUnicode_GET_SIZE(os2) + 1;
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000251 ws2 = PyMem_MALLOC(len2 * sizeof(wchar_t));
252 if (!ws2) {
253 PyErr_NoMemory();
254 goto done;
255 }
256 if (PyUnicode_AsWideChar((PyUnicodeObject*)os2, ws2, len2) == -1)
257 goto done;
Marc-André Lemburga9cadcd2004-11-22 13:02:31 +0000258 ws2[len2 - 1] = 0;
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000259 /* Collate the strings. */
Christian Heimes217cfd12007-12-02 14:31:20 +0000260 result = PyLong_FromLong(wcscoll(ws1, ws2));
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000261 done:
262 /* Deallocate everything. */
263 if (ws1) PyMem_FREE(ws1);
264 if (ws2) PyMem_FREE(ws2);
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000265 return result;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000266}
Martin v. Löwis92fab752008-03-08 10:40:41 +0000267#endif
Guido van Rossum220ecc81997-11-18 21:03:39 +0000268
Martin v. Löwis92fab752008-03-08 10:40:41 +0000269#ifdef HAVE_WCSXFRM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000270PyDoc_STRVAR(strxfrm__doc__,
Mark Dickinson211c6252009-02-01 10:28:51 +0000271"strxfrm(string) -> string.\n\
272\n\
273Return a string that can be used as a key for locale-aware comparisons.");
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{
Martin v. Löwis92fab752008-03-08 10:40:41 +0000278 Py_UNICODE *s0;
279 Py_ssize_t n0;
280 wchar_t *s, *buf = NULL;
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000281 size_t n1, n2;
Martin v. Löwis92fab752008-03-08 10:40:41 +0000282 PyObject *result = NULL;
283 Py_ssize_t i;
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000284
Martin v. Löwis92fab752008-03-08 10:40:41 +0000285 if (!PyArg_ParseTuple(args, "u#:strxfrm", &s0, &n0))
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000286 return NULL;
287
Martin v. Löwis92fab752008-03-08 10:40:41 +0000288#ifdef HAVE_USABLE_WCHAR_T
289 s = s0;
290#else
Martin v. Löwisa69e1ef2008-03-08 10:54:31 +0000291 s = PyMem_Malloc((n0+1)*sizeof(wchar_t));
Martin v. Löwis92fab752008-03-08 10:40:41 +0000292 if (!s)
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000293 return PyErr_NoMemory();
Martin v. Löwis92fab752008-03-08 10:40:41 +0000294 for (i=0; i<=n0; i++)
295 s[i] = s0[i];
296#endif
297
298 /* assume no change in size, first */
299 n1 = wcslen(s) + 1;
Martin v. Löwisa69e1ef2008-03-08 10:54:31 +0000300 buf = PyMem_Malloc(n1*sizeof(wchar_t));
Martin v. Löwis92fab752008-03-08 10:40:41 +0000301 if (!buf) {
302 PyErr_NoMemory();
303 goto exit;
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000304 }
Martin v. Löwis92fab752008-03-08 10:40:41 +0000305 n2 = wcsxfrm(buf, s, n1);
306 if (n2 >= n1) {
307 /* more space needed */
Martin v. Löwisa69e1ef2008-03-08 10:54:31 +0000308 buf = PyMem_Realloc(buf, (n2+1)*sizeof(wchar_t));
Martin v. Löwis92fab752008-03-08 10:40:41 +0000309 if (!buf) {
310 PyErr_NoMemory();
311 goto exit;
312 }
Martin v. Löwisdb1c3992009-05-23 10:38:26 +0000313 n2 = wcsxfrm(buf, s, n2+1);
Martin v. Löwis92fab752008-03-08 10:40:41 +0000314 }
315 result = PyUnicode_FromWideChar(buf, n2);
316 exit:
317 if (buf) PyMem_Free(buf);
318#ifdef HAVE_USABLE_WCHAR_T
319 PyMem_Free(s);
320#endif
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000321 return result;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000322}
Martin v. Löwis92fab752008-03-08 10:40:41 +0000323#endif
Guido van Rossum220ecc81997-11-18 21:03:39 +0000324
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000325#if defined(MS_WINDOWS)
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000326static PyObject*
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000327PyLocale_getdefaultlocale(PyObject* self)
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000328{
329 char encoding[100];
330 char locale[100];
331
Tim Peters885d4572001-11-28 20:27:42 +0000332 PyOS_snprintf(encoding, sizeof(encoding), "cp%d", GetACP());
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000333
334 if (GetLocaleInfo(LOCALE_USER_DEFAULT,
335 LOCALE_SISO639LANGNAME,
336 locale, sizeof(locale))) {
Martin v. Löwis18e16552006-02-15 17:27:45 +0000337 Py_ssize_t i = strlen(locale);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000338 locale[i++] = '_';
339 if (GetLocaleInfo(LOCALE_USER_DEFAULT,
340 LOCALE_SISO3166CTRYNAME,
Martin v. Löwis18e16552006-02-15 17:27:45 +0000341 locale+i, (int)(sizeof(locale)-i)))
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000342 return Py_BuildValue("ss", locale, encoding);
343 }
344
345 /* If we end up here, this windows version didn't know about
346 ISO639/ISO3166 names (it's probably Windows 95). Return the
347 Windows language identifier instead (a hexadecimal number) */
348
349 locale[0] = '0';
350 locale[1] = 'x';
351 if (GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_IDEFAULTLANGUAGE,
352 locale+2, sizeof(locale)-2)) {
353 return Py_BuildValue("ss", locale, encoding);
354 }
355
356 /* cannot determine the language code (very unlikely) */
357 Py_INCREF(Py_None);
358 return Py_BuildValue("Os", Py_None, encoding);
359}
360#endif
361
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000362#ifdef HAVE_LANGINFO_H
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000363#define LANGINFO(X) {#X, X}
Martin v. Löwis59683e82008-06-13 07:50:45 +0000364static struct langinfo_constant{
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000365 char* name;
366 int value;
367} langinfo_constants[] =
368{
369 /* These constants should exist on any langinfo implementation */
370 LANGINFO(DAY_1),
371 LANGINFO(DAY_2),
372 LANGINFO(DAY_3),
373 LANGINFO(DAY_4),
374 LANGINFO(DAY_5),
375 LANGINFO(DAY_6),
376 LANGINFO(DAY_7),
377
378 LANGINFO(ABDAY_1),
379 LANGINFO(ABDAY_2),
380 LANGINFO(ABDAY_3),
381 LANGINFO(ABDAY_4),
382 LANGINFO(ABDAY_5),
383 LANGINFO(ABDAY_6),
384 LANGINFO(ABDAY_7),
385
386 LANGINFO(MON_1),
387 LANGINFO(MON_2),
388 LANGINFO(MON_3),
389 LANGINFO(MON_4),
390 LANGINFO(MON_5),
391 LANGINFO(MON_6),
392 LANGINFO(MON_7),
393 LANGINFO(MON_8),
394 LANGINFO(MON_9),
395 LANGINFO(MON_10),
396 LANGINFO(MON_11),
397 LANGINFO(MON_12),
398
399 LANGINFO(ABMON_1),
400 LANGINFO(ABMON_2),
401 LANGINFO(ABMON_3),
402 LANGINFO(ABMON_4),
403 LANGINFO(ABMON_5),
404 LANGINFO(ABMON_6),
405 LANGINFO(ABMON_7),
406 LANGINFO(ABMON_8),
407 LANGINFO(ABMON_9),
408 LANGINFO(ABMON_10),
409 LANGINFO(ABMON_11),
410 LANGINFO(ABMON_12),
411
412#ifdef RADIXCHAR
413 /* The following are not available with glibc 2.0 */
414 LANGINFO(RADIXCHAR),
415 LANGINFO(THOUSEP),
416 /* YESSTR and NOSTR are deprecated in glibc, since they are
417 a special case of message translation, which should be rather
418 done using gettext. So we don't expose it to Python in the
419 first place.
420 LANGINFO(YESSTR),
421 LANGINFO(NOSTR),
422 */
423 LANGINFO(CRNCYSTR),
424#endif
425
426 LANGINFO(D_T_FMT),
427 LANGINFO(D_FMT),
428 LANGINFO(T_FMT),
429 LANGINFO(AM_STR),
430 LANGINFO(PM_STR),
431
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000432 /* The following constants are available only with XPG4, but...
433 AIX 3.2. only has CODESET.
434 OpenBSD doesn't have CODESET but has T_FMT_AMPM, and doesn't have
435 a few of the others.
436 Solution: ifdef-test them all. */
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000437#ifdef CODESET
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000438 LANGINFO(CODESET),
Martin v. Löwis496f9e42002-03-27 12:15:57 +0000439#endif
440#ifdef T_FMT_AMPM
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000441 LANGINFO(T_FMT_AMPM),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000442#endif
443#ifdef ERA
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000444 LANGINFO(ERA),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000445#endif
446#ifdef ERA_D_FMT
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000447 LANGINFO(ERA_D_FMT),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000448#endif
449#ifdef ERA_D_T_FMT
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000450 LANGINFO(ERA_D_T_FMT),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000451#endif
452#ifdef ERA_T_FMT
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000453 LANGINFO(ERA_T_FMT),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000454#endif
455#ifdef ALT_DIGITS
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000456 LANGINFO(ALT_DIGITS),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000457#endif
458#ifdef YESEXPR
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000459 LANGINFO(YESEXPR),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000460#endif
461#ifdef NOEXPR
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000462 LANGINFO(NOEXPR),
463#endif
464#ifdef _DATE_FMT
465 /* This is not available in all glibc versions that have CODESET. */
466 LANGINFO(_DATE_FMT),
467#endif
468 {0, 0}
469};
470
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000471PyDoc_STRVAR(nl_langinfo__doc__,
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000472"nl_langinfo(key) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000473"Return the value for the locale information associated with key.");
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000474
475static PyObject*
476PyLocale_nl_langinfo(PyObject* self, PyObject* args)
477{
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000478 int item, i;
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000479 if (!PyArg_ParseTuple(args, "i:nl_langinfo", &item))
480 return NULL;
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000481 /* Check whether this is a supported constant. GNU libc sometimes
482 returns numeric values in the char* return value, which would
Neal Norwitz7f9d29c2007-08-26 07:21:45 +0000483 crash PyUnicode_FromString. */
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000484 for (i = 0; langinfo_constants[i].name; i++)
Hye-Shik Changc3a87b82004-03-21 19:34:30 +0000485 if (langinfo_constants[i].value == item) {
486 /* Check NULL as a workaround for GNU libc's returning NULL
487 instead of an empty string for nl_langinfo(ERA). */
488 const char *result = nl_langinfo(item);
Neal Norwitz3d7a90d2007-10-27 05:40:06 +0000489 result = result != NULL ? result : "";
Martin v. Löwis92fab752008-03-08 10:40:41 +0000490 return str2uni(result);
Hye-Shik Changc3a87b82004-03-21 19:34:30 +0000491 }
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000492 PyErr_SetString(PyExc_ValueError, "unsupported langinfo constant");
493 return NULL;
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000494}
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000495#endif /* HAVE_LANGINFO_H */
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000496
497#ifdef HAVE_LIBINTL_H
498
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000499PyDoc_STRVAR(gettext__doc__,
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000500"gettext(msg) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000501"Return translation of msg.");
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000502
503static PyObject*
504PyIntl_gettext(PyObject* self, PyObject *args)
505{
506 char *in;
Georg Brandl3dbca812008-07-23 16:10:53 +0000507 if (!PyArg_ParseTuple(args, "s", &in))
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000508 return 0;
Martin v. Löwis92fab752008-03-08 10:40:41 +0000509 return str2uni(gettext(in));
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000510}
511
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000512PyDoc_STRVAR(dgettext__doc__,
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000513"dgettext(domain, msg) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000514"Return translation of msg in domain.");
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000515
516static PyObject*
517PyIntl_dgettext(PyObject* self, PyObject *args)
518{
519 char *domain, *in;
Georg Brandl3dbca812008-07-23 16:10:53 +0000520 if (!PyArg_ParseTuple(args, "zs", &domain, &in))
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000521 return 0;
Martin v. Löwis92fab752008-03-08 10:40:41 +0000522 return str2uni(dgettext(domain, in));
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000523}
524
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000525PyDoc_STRVAR(dcgettext__doc__,
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000526"dcgettext(domain, msg, category) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000527"Return translation of msg in domain and category.");
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000528
529static PyObject*
530PyIntl_dcgettext(PyObject *self, PyObject *args)
531{
532 char *domain, *msgid;
533 int category;
Georg Brandl3dbca812008-07-23 16:10:53 +0000534 if (!PyArg_ParseTuple(args, "zsi", &domain, &msgid, &category))
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000535 return 0;
Martin v. Löwis92fab752008-03-08 10:40:41 +0000536 return str2uni(dcgettext(domain,msgid,category));
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000537}
538
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000539PyDoc_STRVAR(textdomain__doc__,
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000540"textdomain(domain) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000541"Set the C library's textdmain to domain, returning the new domain.");
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000542
543static PyObject*
544PyIntl_textdomain(PyObject* self, PyObject* args)
545{
546 char *domain;
547 if (!PyArg_ParseTuple(args, "z", &domain))
548 return 0;
549 domain = textdomain(domain);
550 if (!domain) {
551 PyErr_SetFromErrno(PyExc_OSError);
552 return NULL;
553 }
Martin v. Löwis92fab752008-03-08 10:40:41 +0000554 return str2uni(domain);
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000555}
556
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000557PyDoc_STRVAR(bindtextdomain__doc__,
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000558"bindtextdomain(domain, dir) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000559"Bind the C library's domain to dir.");
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000560
561static PyObject*
562PyIntl_bindtextdomain(PyObject* self,PyObject*args)
563{
Georg Brandl3dbca812008-07-23 16:10:53 +0000564 char *domain, *dirname;
565 if (!PyArg_ParseTuple(args, "sz", &domain, &dirname))
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000566 return 0;
Georg Brandl3dbca812008-07-23 16:10:53 +0000567 if (!strlen(domain)) {
568 PyErr_SetString(Error, "domain must be a non-empty string");
569 return 0;
570 }
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000571 dirname = bindtextdomain(domain, dirname);
572 if (!dirname) {
573 PyErr_SetFromErrno(PyExc_OSError);
574 return NULL;
575 }
Martin v. Löwis92fab752008-03-08 10:40:41 +0000576 return str2uni(dirname);
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000577}
578
Gustavo Niemeyer7bd33c52004-07-22 18:44:01 +0000579#ifdef HAVE_BIND_TEXTDOMAIN_CODESET
580PyDoc_STRVAR(bind_textdomain_codeset__doc__,
581"bind_textdomain_codeset(domain, codeset) -> string\n"
582"Bind the C library's domain to codeset.");
583
584static PyObject*
585PyIntl_bind_textdomain_codeset(PyObject* self,PyObject*args)
586{
587 char *domain,*codeset;
588 if (!PyArg_ParseTuple(args, "sz", &domain, &codeset))
589 return NULL;
590 codeset = bind_textdomain_codeset(domain, codeset);
591 if (codeset)
Martin v. Löwis92fab752008-03-08 10:40:41 +0000592 return str2uni(codeset);
Gustavo Niemeyer7bd33c52004-07-22 18:44:01 +0000593 Py_RETURN_NONE;
594}
595#endif
596
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000597#endif
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000598
Guido van Rossum220ecc81997-11-18 21:03:39 +0000599static struct PyMethodDef PyLocale_Methods[] = {
Andrew M. Kuchlinge365fb82000-08-03 02:06:16 +0000600 {"setlocale", (PyCFunction) PyLocale_setlocale,
601 METH_VARARGS, setlocale__doc__},
602 {"localeconv", (PyCFunction) PyLocale_localeconv,
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000603 METH_NOARGS, localeconv__doc__},
Martin v. Löwis92fab752008-03-08 10:40:41 +0000604#ifdef HAVE_WCSCOLL
Andrew M. Kuchlinge365fb82000-08-03 02:06:16 +0000605 {"strcoll", (PyCFunction) PyLocale_strcoll,
606 METH_VARARGS, strcoll__doc__},
Martin v. Löwis92fab752008-03-08 10:40:41 +0000607#endif
608#ifdef HAVE_WCSXFRM
Andrew M. Kuchlinge365fb82000-08-03 02:06:16 +0000609 {"strxfrm", (PyCFunction) PyLocale_strxfrm,
610 METH_VARARGS, strxfrm__doc__},
Martin v. Löwis92fab752008-03-08 10:40:41 +0000611#endif
Ronald Oussorenfe8a3d62009-06-07 15:29:46 +0000612#if defined(MS_WINDOWS)
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000613 {"_getdefaultlocale", (PyCFunction) PyLocale_getdefaultlocale, METH_NOARGS},
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000614#endif
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000615#ifdef HAVE_LANGINFO_H
616 {"nl_langinfo", (PyCFunction) PyLocale_nl_langinfo,
617 METH_VARARGS, nl_langinfo__doc__},
618#endif
Martin v. Löwisc6a7d7e2002-05-02 12:16:29 +0000619#ifdef HAVE_LIBINTL_H
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000620 {"gettext",(PyCFunction)PyIntl_gettext,METH_VARARGS,
621 gettext__doc__},
622 {"dgettext",(PyCFunction)PyIntl_dgettext,METH_VARARGS,
623 dgettext__doc__},
624 {"dcgettext",(PyCFunction)PyIntl_dcgettext,METH_VARARGS,
625 dcgettext__doc__},
626 {"textdomain",(PyCFunction)PyIntl_textdomain,METH_VARARGS,
627 textdomain__doc__},
628 {"bindtextdomain",(PyCFunction)PyIntl_bindtextdomain,METH_VARARGS,
629 bindtextdomain__doc__},
Gustavo Niemeyer7bd33c52004-07-22 18:44:01 +0000630#ifdef HAVE_BIND_TEXTDOMAIN_CODESET
631 {"bind_textdomain_codeset",(PyCFunction)PyIntl_bind_textdomain_codeset,
632 METH_VARARGS, bind_textdomain_codeset__doc__},
633#endif
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000634#endif
Guido van Rossum220ecc81997-11-18 21:03:39 +0000635 {NULL, NULL}
636};
637
Martin v. Löwis1a214512008-06-11 05:26:20 +0000638
639static struct PyModuleDef _localemodule = {
640 PyModuleDef_HEAD_INIT,
641 "_locale",
642 locale__doc__,
643 -1,
644 PyLocale_Methods,
645 NULL,
646 NULL,
647 NULL,
648 NULL
649};
650
Mark Hammondfe51c6d2002-08-02 02:27:13 +0000651PyMODINIT_FUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +0000652PyInit__locale(void)
Guido van Rossum220ecc81997-11-18 21:03:39 +0000653{
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000654 PyObject *m, *d, *x;
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000655#ifdef HAVE_LANGINFO_H
656 int i;
657#endif
Guido van Rossum220ecc81997-11-18 21:03:39 +0000658
Martin v. Löwis1a214512008-06-11 05:26:20 +0000659 m = PyModule_Create(&_localemodule);
Neal Norwitz1ac754f2006-01-19 06:09:39 +0000660 if (m == NULL)
Martin v. Löwis1a214512008-06-11 05:26:20 +0000661 return NULL;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000662
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000663 d = PyModule_GetDict(m);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000664
Christian Heimes217cfd12007-12-02 14:31:20 +0000665 x = PyLong_FromLong(LC_CTYPE);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000666 PyDict_SetItemString(d, "LC_CTYPE", x);
667 Py_XDECREF(x);
668
Christian Heimes217cfd12007-12-02 14:31:20 +0000669 x = PyLong_FromLong(LC_TIME);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000670 PyDict_SetItemString(d, "LC_TIME", x);
671 Py_XDECREF(x);
672
Christian Heimes217cfd12007-12-02 14:31:20 +0000673 x = PyLong_FromLong(LC_COLLATE);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000674 PyDict_SetItemString(d, "LC_COLLATE", x);
675 Py_XDECREF(x);
676
Christian Heimes217cfd12007-12-02 14:31:20 +0000677 x = PyLong_FromLong(LC_MONETARY);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000678 PyDict_SetItemString(d, "LC_MONETARY", x);
679 Py_XDECREF(x);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000680
Guido van Rossum8d9c2e31997-12-09 19:35:11 +0000681#ifdef LC_MESSAGES
Christian Heimes217cfd12007-12-02 14:31:20 +0000682 x = PyLong_FromLong(LC_MESSAGES);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000683 PyDict_SetItemString(d, "LC_MESSAGES", x);
684 Py_XDECREF(x);
Guido van Rossum8d9c2e31997-12-09 19:35:11 +0000685#endif /* LC_MESSAGES */
Guido van Rossum220ecc81997-11-18 21:03:39 +0000686
Christian Heimes217cfd12007-12-02 14:31:20 +0000687 x = PyLong_FromLong(LC_NUMERIC);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000688 PyDict_SetItemString(d, "LC_NUMERIC", x);
689 Py_XDECREF(x);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000690
Christian Heimes217cfd12007-12-02 14:31:20 +0000691 x = PyLong_FromLong(LC_ALL);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000692 PyDict_SetItemString(d, "LC_ALL", x);
693 Py_XDECREF(x);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000694
Christian Heimes217cfd12007-12-02 14:31:20 +0000695 x = PyLong_FromLong(CHAR_MAX);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000696 PyDict_SetItemString(d, "CHAR_MAX", x);
697 Py_XDECREF(x);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000698
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000699 Error = PyErr_NewException("locale.Error", NULL, NULL);
700 PyDict_SetItemString(d, "Error", Error);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000701
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000702#ifdef HAVE_LANGINFO_H
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000703 for (i = 0; langinfo_constants[i].name; i++) {
704 PyModule_AddIntConstant(m, langinfo_constants[i].name,
705 langinfo_constants[i].value);
706 }
Martin v. Löwisf95dd0a2001-08-15 17:14:33 +0000707#endif
Martin v. Löwis1a214512008-06-11 05:26:20 +0000708 return m;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000709}
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000710
711/*
712Local variables:
713c-basic-offset: 4
714indent-tabs-mode: nil
715End:
716*/