blob: cc688ba1406a9f7195866bc2bbaca11204ad0736 [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
Antoine Pitrou6a448d42009-10-19 19:43:09 +000012#define PY_SSIZE_T_CLEAN
Fred Drake68933b92000-08-10 21:41:08 +000013#include "Python.h"
14
Guido van Rossum220ecc81997-11-18 21:03:39 +000015#include <stdio.h>
Guido van Rossum220ecc81997-11-18 21:03:39 +000016#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
Thomas Wouters0e3f5912006-08-11 14:57:12 +000020#ifdef HAVE_ERRNO_H
Thomas Wouters477c8d52006-05-27 19:21:47 +000021#include <errno.h>
22#endif
23
Martin v. Löwis9b75dca2001-08-10 13:58:50 +000024#ifdef HAVE_LANGINFO_H
25#include <langinfo.h>
26#endif
27
Martin v. Löwis2e64c342002-03-27 18:49:02 +000028#ifdef HAVE_LIBINTL_H
29#include <libintl.h>
30#endif
31
Martin v. Löwis9c36c292002-12-21 18:34:06 +000032#ifdef HAVE_WCHAR_H
33#include <wchar.h>
34#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
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000041PyDoc_STRVAR(locale__doc__, "Support for POSIX locales.");
Guido van Rossum220ecc81997-11-18 21:03:39 +000042
43static PyObject *Error;
44
45/* support functions for formatting floating point numbers */
46
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000047PyDoc_STRVAR(setlocale__doc__,
48"(integer,string=None) -> string. Activates/queries locale processing.");
Guido van Rossum220ecc81997-11-18 21:03:39 +000049
Guido van Rossum220ecc81997-11-18 21:03:39 +000050/* the grouping is terminated by either 0 or CHAR_MAX */
51static PyObject*
Fredrik Lundh8f017a02000-07-08 19:57:37 +000052copy_grouping(char* s)
Guido van Rossum220ecc81997-11-18 21:03:39 +000053{
Fredrik Lundh8f017a02000-07-08 19:57:37 +000054 int i;
55 PyObject *result, *val = NULL;
56
57 if (s[0] == '\0')
58 /* empty string: no grouping at all */
59 return PyList_New(0);
60
61 for (i = 0; s[i] != '\0' && s[i] != CHAR_MAX; i++)
62 ; /* nothing */
63
64 result = PyList_New(i+1);
65 if (!result)
66 return NULL;
67
68 i = -1;
69 do {
70 i++;
Christian Heimes217cfd12007-12-02 14:31:20 +000071 val = PyLong_FromLong(s[i]);
Fredrik Lundh8f017a02000-07-08 19:57:37 +000072 if (!val)
73 break;
74 if (PyList_SetItem(result, i, val)) {
75 Py_DECREF(val);
Fredrik Lundh89610a42000-07-08 20:07:24 +000076 val = NULL;
Fredrik Lundh8f017a02000-07-08 19:57:37 +000077 break;
78 }
79 } while (s[i] != '\0' && s[i] != CHAR_MAX);
80
81 if (!val) {
82 Py_DECREF(result);
83 return NULL;
Guido van Rossum220ecc81997-11-18 21:03:39 +000084 }
Fredrik Lundh8f017a02000-07-08 19:57:37 +000085
86 return result;
Guido van Rossum220ecc81997-11-18 21:03:39 +000087}
88
Guido van Rossum220ecc81997-11-18 21:03:39 +000089static PyObject*
Fredrik Lundh8f017a02000-07-08 19:57:37 +000090PyLocale_setlocale(PyObject* self, PyObject* args)
Guido van Rossum220ecc81997-11-18 21:03:39 +000091{
Fredrik Lundh8f017a02000-07-08 19:57:37 +000092 int category;
93 char *locale = NULL, *result;
94 PyObject *result_object;
Guido van Rossum220ecc81997-11-18 21:03:39 +000095
Fredrik Lundh8f017a02000-07-08 19:57:37 +000096 if (!PyArg_ParseTuple(args, "i|z:setlocale", &category, &locale))
Fredrik Lundh89610a42000-07-08 20:07:24 +000097 return NULL;
Fredrik Lundh8f017a02000-07-08 19:57:37 +000098
Amaury Forgeot d'Arc64f3ca42009-12-01 21:59:18 +000099#if defined(MS_WINDOWS)
100 if (category < LC_MIN || category > LC_MAX)
101 {
102 PyErr_SetString(Error, "invalid locale category");
103 return NULL;
104 }
105#endif
106
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000107 if (locale) {
108 /* set locale */
109 result = setlocale(category, locale);
110 if (!result) {
111 /* operation failed, no setting was changed */
Martin v. Löwis25f90d52003-09-03 04:50:13 +0000112 PyErr_SetString(Error, "unsupported locale setting");
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000113 return NULL;
114 }
Victor Stinnera9c895d2012-02-14 02:33:38 +0100115 result_object = PyUnicode_DecodeLocale(result, NULL);
Mark Hammond9a714752003-07-24 14:15:07 +0000116 if (!result_object)
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000117 return NULL;
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000118 } else {
119 /* get locale */
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000120 result = setlocale(category, NULL);
121 if (!result) {
122 PyErr_SetString(Error, "locale query failed");
123 return NULL;
124 }
Victor Stinnera9c895d2012-02-14 02:33:38 +0100125 result_object = PyUnicode_DecodeLocale(result, NULL);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000126 }
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000127 return result_object;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000128}
129
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000130PyDoc_STRVAR(localeconv__doc__,
131"() -> dict. Returns numeric and monetary locale-specific parameters.");
Guido van Rossum220ecc81997-11-18 21:03:39 +0000132
133static PyObject*
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000134PyLocale_localeconv(PyObject* self)
Guido van Rossum220ecc81997-11-18 21:03:39 +0000135{
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000136 PyObject* result;
137 struct lconv *l;
138 PyObject *x;
139
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000140 result = PyDict_New();
Fredrik Lundh89610a42000-07-08 20:07:24 +0000141 if (!result)
142 return NULL;
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000143
144 /* if LC_NUMERIC is different in the C library, use saved value */
145 l = localeconv();
146
147 /* hopefully, the localeconv result survives the C library calls
148 involved herein */
149
150#define RESULT_STRING(s)\
Victor Stinnera9c895d2012-02-14 02:33:38 +0100151 x = PyUnicode_DecodeLocale(l->s, NULL); \
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000152 if (!x) goto failed;\
153 PyDict_SetItemString(result, #s, x);\
154 Py_XDECREF(x)
155
156#define RESULT_INT(i)\
Christian Heimes217cfd12007-12-02 14:31:20 +0000157 x = PyLong_FromLong(l->i);\
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000158 if (!x) goto failed;\
159 PyDict_SetItemString(result, #i, x);\
160 Py_XDECREF(x)
Guido van Rossum220ecc81997-11-18 21:03:39 +0000161
162 /* Numeric information */
Martin v. Löwis737ea822004-06-08 18:52:54 +0000163 RESULT_STRING(decimal_point);
164 RESULT_STRING(thousands_sep);
165 x = copy_grouping(l->grouping);
166 if (!x)
167 goto failed;
168 PyDict_SetItemString(result, "grouping", x);
169 Py_XDECREF(x);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000170
171 /* Monetary information */
172 RESULT_STRING(int_curr_symbol);
173 RESULT_STRING(currency_symbol);
174 RESULT_STRING(mon_decimal_point);
175 RESULT_STRING(mon_thousands_sep);
176 x = copy_grouping(l->mon_grouping);
177 if (!x)
178 goto failed;
179 PyDict_SetItemString(result, "mon_grouping", x);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000180 Py_XDECREF(x);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000181 RESULT_STRING(positive_sign);
182 RESULT_STRING(negative_sign);
183 RESULT_INT(int_frac_digits);
184 RESULT_INT(frac_digits);
185 RESULT_INT(p_cs_precedes);
186 RESULT_INT(p_sep_by_space);
187 RESULT_INT(n_cs_precedes);
188 RESULT_INT(n_sep_by_space);
189 RESULT_INT(p_sign_posn);
190 RESULT_INT(n_sign_posn);
191 return result;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000192
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000193 failed:
194 Py_XDECREF(result);
195 Py_XDECREF(x);
196 return NULL;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000197}
198
Martin v. Löwis92fab752008-03-08 10:40:41 +0000199#if defined(HAVE_WCSCOLL)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000200PyDoc_STRVAR(strcoll__doc__,
201"string,string -> int. Compares two strings according to the locale.");
Guido van Rossum220ecc81997-11-18 21:03:39 +0000202
203static PyObject*
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000204PyLocale_strcoll(PyObject* self, PyObject* args)
Guido van Rossum220ecc81997-11-18 21:03:39 +0000205{
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000206 PyObject *os1, *os2, *result = NULL;
207 wchar_t *ws1 = NULL, *ws2 = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000208
Martin v. Löwis92fab752008-03-08 10:40:41 +0000209 if (!PyArg_ParseTuple(args, "UU:strcoll", &os1, &os2))
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000210 return NULL;
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000211 /* Convert the unicode strings to wchar[]. */
Victor Stinnerbeb4135b2010-10-07 01:02:42 +0000212 ws1 = PyUnicode_AsWideCharString(os1, NULL);
Victor Stinner449057f2010-09-29 10:30:43 +0000213 if (ws1 == NULL)
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000214 goto done;
Victor Stinnerbeb4135b2010-10-07 01:02:42 +0000215 ws2 = PyUnicode_AsWideCharString(os2, NULL);
Victor Stinner449057f2010-09-29 10:30:43 +0000216 if (ws2 == NULL)
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000217 goto done;
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000218 /* Collate the strings. */
Christian Heimes217cfd12007-12-02 14:31:20 +0000219 result = PyLong_FromLong(wcscoll(ws1, ws2));
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000220 done:
221 /* Deallocate everything. */
222 if (ws1) PyMem_FREE(ws1);
223 if (ws2) PyMem_FREE(ws2);
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000224 return result;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000225}
Martin v. Löwis92fab752008-03-08 10:40:41 +0000226#endif
Guido van Rossum220ecc81997-11-18 21:03:39 +0000227
Martin v. Löwis92fab752008-03-08 10:40:41 +0000228#ifdef HAVE_WCSXFRM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000229PyDoc_STRVAR(strxfrm__doc__,
Mark Dickinson211c6252009-02-01 10:28:51 +0000230"strxfrm(string) -> string.\n\
231\n\
232Return a string that can be used as a key for locale-aware comparisons.");
Guido van Rossum220ecc81997-11-18 21:03:39 +0000233
234static PyObject*
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000235PyLocale_strxfrm(PyObject* self, PyObject* args)
Guido van Rossum220ecc81997-11-18 21:03:39 +0000236{
Victor Stinner63649272011-09-29 23:32:06 +0200237 PyObject *str;
238 Py_ssize_t n1;
239 wchar_t *s = NULL, *buf = NULL;
240 size_t n2;
Martin v. Löwis92fab752008-03-08 10:40:41 +0000241 PyObject *result = NULL;
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000242
Victor Stinner63649272011-09-29 23:32:06 +0200243 if (!PyArg_ParseTuple(args, "U:strxfrm", &str))
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000244 return NULL;
245
Victor Stinner63649272011-09-29 23:32:06 +0200246 s = PyUnicode_AsWideCharString(str, &n1);
247 if (s == NULL)
248 goto exit;
Martin v. Löwis92fab752008-03-08 10:40:41 +0000249
250 /* assume no change in size, first */
Victor Stinner63649272011-09-29 23:32:06 +0200251 n1 = n1 + 1;
252 buf = PyMem_Malloc(n1 * sizeof(wchar_t));
Martin v. Löwis92fab752008-03-08 10:40:41 +0000253 if (!buf) {
254 PyErr_NoMemory();
255 goto exit;
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000256 }
Martin v. Löwis92fab752008-03-08 10:40:41 +0000257 n2 = wcsxfrm(buf, s, n1);
Victor Stinner2c5d3cb2011-10-11 22:35:52 +0200258 if (n2 >= (size_t)n1) {
Martin v. Löwis92fab752008-03-08 10:40:41 +0000259 /* more space needed */
Kristjan Valur Jonsson85634d72012-05-31 09:37:31 +0000260 wchar_t * new_buf = PyMem_Realloc(buf, (n2+1)*sizeof(wchar_t));
261 if (!new_buf) {
Martin v. Löwis92fab752008-03-08 10:40:41 +0000262 PyErr_NoMemory();
263 goto exit;
264 }
Kristjan Valur Jonsson85634d72012-05-31 09:37:31 +0000265 buf = new_buf;
Martin v. Löwisdb1c3992009-05-23 10:38:26 +0000266 n2 = wcsxfrm(buf, s, n2+1);
Martin v. Löwis92fab752008-03-08 10:40:41 +0000267 }
268 result = PyUnicode_FromWideChar(buf, n2);
Victor Stinner63649272011-09-29 23:32:06 +0200269exit:
270 if (buf)
271 PyMem_Free(buf);
272 if (s)
273 PyMem_Free(s);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000274 return result;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000275}
Martin v. Löwis92fab752008-03-08 10:40:41 +0000276#endif
Guido van Rossum220ecc81997-11-18 21:03:39 +0000277
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öwis9b75dca2001-08-10 13:58:50 +0000315#ifdef HAVE_LANGINFO_H
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000316#define LANGINFO(X) {#X, X}
Martin v. Löwis59683e82008-06-13 07:50:45 +0000317static struct langinfo_constant{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000318 char* name;
319 int value;
320} langinfo_constants[] =
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000321{
322 /* These constants should exist on any langinfo implementation */
323 LANGINFO(DAY_1),
324 LANGINFO(DAY_2),
325 LANGINFO(DAY_3),
326 LANGINFO(DAY_4),
327 LANGINFO(DAY_5),
328 LANGINFO(DAY_6),
329 LANGINFO(DAY_7),
330
331 LANGINFO(ABDAY_1),
332 LANGINFO(ABDAY_2),
333 LANGINFO(ABDAY_3),
334 LANGINFO(ABDAY_4),
335 LANGINFO(ABDAY_5),
336 LANGINFO(ABDAY_6),
337 LANGINFO(ABDAY_7),
338
339 LANGINFO(MON_1),
340 LANGINFO(MON_2),
341 LANGINFO(MON_3),
342 LANGINFO(MON_4),
343 LANGINFO(MON_5),
344 LANGINFO(MON_6),
345 LANGINFO(MON_7),
346 LANGINFO(MON_8),
347 LANGINFO(MON_9),
348 LANGINFO(MON_10),
349 LANGINFO(MON_11),
350 LANGINFO(MON_12),
351
352 LANGINFO(ABMON_1),
353 LANGINFO(ABMON_2),
354 LANGINFO(ABMON_3),
355 LANGINFO(ABMON_4),
356 LANGINFO(ABMON_5),
357 LANGINFO(ABMON_6),
358 LANGINFO(ABMON_7),
359 LANGINFO(ABMON_8),
360 LANGINFO(ABMON_9),
361 LANGINFO(ABMON_10),
362 LANGINFO(ABMON_11),
363 LANGINFO(ABMON_12),
364
365#ifdef RADIXCHAR
366 /* The following are not available with glibc 2.0 */
367 LANGINFO(RADIXCHAR),
368 LANGINFO(THOUSEP),
369 /* YESSTR and NOSTR are deprecated in glibc, since they are
370 a special case of message translation, which should be rather
371 done using gettext. So we don't expose it to Python in the
372 first place.
373 LANGINFO(YESSTR),
374 LANGINFO(NOSTR),
375 */
376 LANGINFO(CRNCYSTR),
377#endif
378
379 LANGINFO(D_T_FMT),
380 LANGINFO(D_FMT),
381 LANGINFO(T_FMT),
382 LANGINFO(AM_STR),
383 LANGINFO(PM_STR),
384
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000385 /* The following constants are available only with XPG4, but...
386 AIX 3.2. only has CODESET.
387 OpenBSD doesn't have CODESET but has T_FMT_AMPM, and doesn't have
388 a few of the others.
389 Solution: ifdef-test them all. */
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000390#ifdef CODESET
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000391 LANGINFO(CODESET),
Martin v. Löwis496f9e42002-03-27 12:15:57 +0000392#endif
393#ifdef T_FMT_AMPM
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000394 LANGINFO(T_FMT_AMPM),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000395#endif
396#ifdef ERA
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000397 LANGINFO(ERA),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000398#endif
399#ifdef ERA_D_FMT
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000400 LANGINFO(ERA_D_FMT),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000401#endif
402#ifdef ERA_D_T_FMT
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000403 LANGINFO(ERA_D_T_FMT),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000404#endif
405#ifdef ERA_T_FMT
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000406 LANGINFO(ERA_T_FMT),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000407#endif
408#ifdef ALT_DIGITS
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000409 LANGINFO(ALT_DIGITS),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000410#endif
411#ifdef YESEXPR
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000412 LANGINFO(YESEXPR),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000413#endif
414#ifdef NOEXPR
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000415 LANGINFO(NOEXPR),
416#endif
417#ifdef _DATE_FMT
418 /* This is not available in all glibc versions that have CODESET. */
419 LANGINFO(_DATE_FMT),
420#endif
421 {0, 0}
422};
423
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000424PyDoc_STRVAR(nl_langinfo__doc__,
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000425"nl_langinfo(key) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000426"Return the value for the locale information associated with key.");
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000427
428static PyObject*
429PyLocale_nl_langinfo(PyObject* self, PyObject* args)
430{
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000431 int item, i;
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000432 if (!PyArg_ParseTuple(args, "i:nl_langinfo", &item))
433 return NULL;
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000434 /* Check whether this is a supported constant. GNU libc sometimes
435 returns numeric values in the char* return value, which would
Neal Norwitz7f9d29c2007-08-26 07:21:45 +0000436 crash PyUnicode_FromString. */
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000437 for (i = 0; langinfo_constants[i].name; i++)
Hye-Shik Changc3a87b82004-03-21 19:34:30 +0000438 if (langinfo_constants[i].value == item) {
439 /* Check NULL as a workaround for GNU libc's returning NULL
440 instead of an empty string for nl_langinfo(ERA). */
441 const char *result = nl_langinfo(item);
Neal Norwitz3d7a90d2007-10-27 05:40:06 +0000442 result = result != NULL ? result : "";
Victor Stinnera9c895d2012-02-14 02:33:38 +0100443 return PyUnicode_DecodeLocale(result, NULL);
Hye-Shik Changc3a87b82004-03-21 19:34:30 +0000444 }
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000445 PyErr_SetString(PyExc_ValueError, "unsupported langinfo constant");
446 return NULL;
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000447}
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000448#endif /* HAVE_LANGINFO_H */
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000449
450#ifdef HAVE_LIBINTL_H
451
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000452PyDoc_STRVAR(gettext__doc__,
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000453"gettext(msg) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000454"Return translation of msg.");
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000455
456static PyObject*
457PyIntl_gettext(PyObject* self, PyObject *args)
458{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000459 char *in;
460 if (!PyArg_ParseTuple(args, "s", &in))
461 return 0;
Victor Stinnera9c895d2012-02-14 02:33:38 +0100462 return PyUnicode_DecodeLocale(gettext(in), NULL);
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000463}
464
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000465PyDoc_STRVAR(dgettext__doc__,
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000466"dgettext(domain, msg) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000467"Return translation of msg in domain.");
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000468
469static PyObject*
470PyIntl_dgettext(PyObject* self, PyObject *args)
471{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000472 char *domain, *in;
473 if (!PyArg_ParseTuple(args, "zs", &domain, &in))
474 return 0;
Victor Stinnera9c895d2012-02-14 02:33:38 +0100475 return PyUnicode_DecodeLocale(dgettext(domain, in), NULL);
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000476}
477
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000478PyDoc_STRVAR(dcgettext__doc__,
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000479"dcgettext(domain, msg, category) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000480"Return translation of msg in domain and category.");
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000481
482static PyObject*
483PyIntl_dcgettext(PyObject *self, PyObject *args)
484{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000485 char *domain, *msgid;
486 int category;
487 if (!PyArg_ParseTuple(args, "zsi", &domain, &msgid, &category))
488 return 0;
Victor Stinnera9c895d2012-02-14 02:33:38 +0100489 return PyUnicode_DecodeLocale(dcgettext(domain,msgid,category), NULL);
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000490}
491
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000492PyDoc_STRVAR(textdomain__doc__,
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000493"textdomain(domain) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000494"Set the C library's textdmain to domain, returning the new domain.");
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000495
496static PyObject*
497PyIntl_textdomain(PyObject* self, PyObject* args)
498{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000499 char *domain;
500 if (!PyArg_ParseTuple(args, "z", &domain))
501 return 0;
502 domain = textdomain(domain);
503 if (!domain) {
504 PyErr_SetFromErrno(PyExc_OSError);
505 return NULL;
506 }
Victor Stinnera9c895d2012-02-14 02:33:38 +0100507 return PyUnicode_DecodeLocale(domain, NULL);
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000508}
509
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000510PyDoc_STRVAR(bindtextdomain__doc__,
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000511"bindtextdomain(domain, dir) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000512"Bind the C library's domain to dir.");
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000513
514static PyObject*
515PyIntl_bindtextdomain(PyObject* self,PyObject*args)
516{
Victor Stinner9e19ca42010-06-11 22:09:51 +0000517 char *domain, *dirname, *current_dirname;
518 PyObject *dirname_obj, *dirname_bytes = NULL, *result;
519 if (!PyArg_ParseTuple(args, "sO", &domain, &dirname_obj))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000520 return 0;
521 if (!strlen(domain)) {
522 PyErr_SetString(Error, "domain must be a non-empty string");
523 return 0;
524 }
Victor Stinner9e19ca42010-06-11 22:09:51 +0000525 if (dirname_obj != Py_None) {
526 if (!PyUnicode_FSConverter(dirname_obj, &dirname_bytes))
527 return NULL;
528 dirname = PyBytes_AsString(dirname_bytes);
529 } else {
530 dirname_bytes = NULL;
531 dirname = NULL;
532 }
533 current_dirname = bindtextdomain(domain, dirname);
534 if (current_dirname == NULL) {
535 Py_XDECREF(dirname_bytes);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000536 PyErr_SetFromErrno(PyExc_OSError);
537 return NULL;
538 }
Victor Stinnera9c895d2012-02-14 02:33:38 +0100539 result = PyUnicode_DecodeLocale(current_dirname, NULL);
Victor Stinner9e19ca42010-06-11 22:09:51 +0000540 Py_XDECREF(dirname_bytes);
541 return result;
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000542}
543
Gustavo Niemeyer7bd33c52004-07-22 18:44:01 +0000544#ifdef HAVE_BIND_TEXTDOMAIN_CODESET
545PyDoc_STRVAR(bind_textdomain_codeset__doc__,
546"bind_textdomain_codeset(domain, codeset) -> string\n"
547"Bind the C library's domain to codeset.");
548
549static PyObject*
550PyIntl_bind_textdomain_codeset(PyObject* self,PyObject*args)
551{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000552 char *domain,*codeset;
553 if (!PyArg_ParseTuple(args, "sz", &domain, &codeset))
554 return NULL;
555 codeset = bind_textdomain_codeset(domain, codeset);
556 if (codeset)
Victor Stinnera9c895d2012-02-14 02:33:38 +0100557 return PyUnicode_DecodeLocale(codeset, NULL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000558 Py_RETURN_NONE;
Gustavo Niemeyer7bd33c52004-07-22 18:44:01 +0000559}
560#endif
561
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000562#endif
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000563
Guido van Rossum220ecc81997-11-18 21:03:39 +0000564static struct PyMethodDef PyLocale_Methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000565 {"setlocale", (PyCFunction) PyLocale_setlocale,
Andrew M. Kuchlinge365fb82000-08-03 02:06:16 +0000566 METH_VARARGS, setlocale__doc__},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000567 {"localeconv", (PyCFunction) PyLocale_localeconv,
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000568 METH_NOARGS, localeconv__doc__},
Martin v. Löwis92fab752008-03-08 10:40:41 +0000569#ifdef HAVE_WCSCOLL
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000570 {"strcoll", (PyCFunction) PyLocale_strcoll,
Andrew M. Kuchlinge365fb82000-08-03 02:06:16 +0000571 METH_VARARGS, strcoll__doc__},
Martin v. Löwis92fab752008-03-08 10:40:41 +0000572#endif
573#ifdef HAVE_WCSXFRM
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000574 {"strxfrm", (PyCFunction) PyLocale_strxfrm,
Andrew M. Kuchlinge365fb82000-08-03 02:06:16 +0000575 METH_VARARGS, strxfrm__doc__},
Martin v. Löwis92fab752008-03-08 10:40:41 +0000576#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000577#if defined(MS_WINDOWS)
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000578 {"_getdefaultlocale", (PyCFunction) PyLocale_getdefaultlocale, METH_NOARGS},
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000579#endif
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000580#ifdef HAVE_LANGINFO_H
581 {"nl_langinfo", (PyCFunction) PyLocale_nl_langinfo,
582 METH_VARARGS, nl_langinfo__doc__},
583#endif
Martin v. Löwisc6a7d7e2002-05-02 12:16:29 +0000584#ifdef HAVE_LIBINTL_H
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000585 {"gettext",(PyCFunction)PyIntl_gettext,METH_VARARGS,
586 gettext__doc__},
587 {"dgettext",(PyCFunction)PyIntl_dgettext,METH_VARARGS,
588 dgettext__doc__},
589 {"dcgettext",(PyCFunction)PyIntl_dcgettext,METH_VARARGS,
590 dcgettext__doc__},
591 {"textdomain",(PyCFunction)PyIntl_textdomain,METH_VARARGS,
592 textdomain__doc__},
593 {"bindtextdomain",(PyCFunction)PyIntl_bindtextdomain,METH_VARARGS,
594 bindtextdomain__doc__},
Gustavo Niemeyer7bd33c52004-07-22 18:44:01 +0000595#ifdef HAVE_BIND_TEXTDOMAIN_CODESET
596 {"bind_textdomain_codeset",(PyCFunction)PyIntl_bind_textdomain_codeset,
597 METH_VARARGS, bind_textdomain_codeset__doc__},
598#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000599#endif
Guido van Rossum220ecc81997-11-18 21:03:39 +0000600 {NULL, NULL}
601};
602
Martin v. Löwis1a214512008-06-11 05:26:20 +0000603
604static struct PyModuleDef _localemodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000605 PyModuleDef_HEAD_INIT,
606 "_locale",
607 locale__doc__,
608 -1,
609 PyLocale_Methods,
610 NULL,
611 NULL,
612 NULL,
613 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +0000614};
615
Mark Hammondfe51c6d2002-08-02 02:27:13 +0000616PyMODINIT_FUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +0000617PyInit__locale(void)
Guido van Rossum220ecc81997-11-18 21:03:39 +0000618{
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000619 PyObject *m, *d, *x;
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000620#ifdef HAVE_LANGINFO_H
621 int i;
622#endif
Guido van Rossum220ecc81997-11-18 21:03:39 +0000623
Martin v. Löwis1a214512008-06-11 05:26:20 +0000624 m = PyModule_Create(&_localemodule);
Neal Norwitz1ac754f2006-01-19 06:09:39 +0000625 if (m == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000626 return NULL;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000627
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000628 d = PyModule_GetDict(m);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000629
Christian Heimes217cfd12007-12-02 14:31:20 +0000630 x = PyLong_FromLong(LC_CTYPE);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000631 PyDict_SetItemString(d, "LC_CTYPE", x);
632 Py_XDECREF(x);
633
Christian Heimes217cfd12007-12-02 14:31:20 +0000634 x = PyLong_FromLong(LC_TIME);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000635 PyDict_SetItemString(d, "LC_TIME", x);
636 Py_XDECREF(x);
637
Christian Heimes217cfd12007-12-02 14:31:20 +0000638 x = PyLong_FromLong(LC_COLLATE);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000639 PyDict_SetItemString(d, "LC_COLLATE", x);
640 Py_XDECREF(x);
641
Christian Heimes217cfd12007-12-02 14:31:20 +0000642 x = PyLong_FromLong(LC_MONETARY);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000643 PyDict_SetItemString(d, "LC_MONETARY", x);
644 Py_XDECREF(x);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000645
Guido van Rossum8d9c2e31997-12-09 19:35:11 +0000646#ifdef LC_MESSAGES
Christian Heimes217cfd12007-12-02 14:31:20 +0000647 x = PyLong_FromLong(LC_MESSAGES);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000648 PyDict_SetItemString(d, "LC_MESSAGES", x);
649 Py_XDECREF(x);
Guido van Rossum8d9c2e31997-12-09 19:35:11 +0000650#endif /* LC_MESSAGES */
Guido van Rossum220ecc81997-11-18 21:03:39 +0000651
Christian Heimes217cfd12007-12-02 14:31:20 +0000652 x = PyLong_FromLong(LC_NUMERIC);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000653 PyDict_SetItemString(d, "LC_NUMERIC", x);
654 Py_XDECREF(x);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000655
Christian Heimes217cfd12007-12-02 14:31:20 +0000656 x = PyLong_FromLong(LC_ALL);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000657 PyDict_SetItemString(d, "LC_ALL", x);
658 Py_XDECREF(x);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000659
Christian Heimes217cfd12007-12-02 14:31:20 +0000660 x = PyLong_FromLong(CHAR_MAX);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000661 PyDict_SetItemString(d, "CHAR_MAX", x);
662 Py_XDECREF(x);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000663
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000664 Error = PyErr_NewException("locale.Error", NULL, NULL);
665 PyDict_SetItemString(d, "Error", Error);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000666
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000667#ifdef HAVE_LANGINFO_H
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000668 for (i = 0; langinfo_constants[i].name; i++) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000669 PyModule_AddIntConstant(m, langinfo_constants[i].name,
670 langinfo_constants[i].value);
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000671 }
Martin v. Löwisf95dd0a2001-08-15 17:14:33 +0000672#endif
Martin v. Löwis1a214512008-06-11 05:26:20 +0000673 return m;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000674}
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000675
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000676/*
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000677Local variables:
678c-basic-offset: 4
679indent-tabs-mode: nil
680End:
681*/