blob: b196749aecc95b2506e06d67deafac19e1ce803f [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
Victor Stinnerd594f242013-07-17 00:55:57 +0200150#define RESULT(key, obj)\
151 do { \
152 if (obj == NULL) \
153 goto failed; \
154 if (PyDict_SetItemString(result, key, obj) < 0) \
155 goto failed; \
156 Py_DECREF(obj); \
157 } while (0)
158
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000159#define RESULT_STRING(s)\
Victor Stinnerd594f242013-07-17 00:55:57 +0200160 do { \
161 x = PyUnicode_DecodeLocale(l->s, NULL); \
162 RESULT(#s, x); \
163 } while (0)
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000164
165#define RESULT_INT(i)\
Victor Stinnerd594f242013-07-17 00:55:57 +0200166 do { \
167 x = PyLong_FromLong(l->i); \
168 RESULT(#i, x); \
169 } while (0)
Guido van Rossum220ecc81997-11-18 21:03:39 +0000170
171 /* Numeric information */
Martin v. Löwis737ea822004-06-08 18:52:54 +0000172 RESULT_STRING(decimal_point);
173 RESULT_STRING(thousands_sep);
174 x = copy_grouping(l->grouping);
Victor Stinnerd594f242013-07-17 00:55:57 +0200175 RESULT("grouping", x);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000176
177 /* Monetary information */
178 RESULT_STRING(int_curr_symbol);
179 RESULT_STRING(currency_symbol);
180 RESULT_STRING(mon_decimal_point);
181 RESULT_STRING(mon_thousands_sep);
182 x = copy_grouping(l->mon_grouping);
Victor Stinnerd594f242013-07-17 00:55:57 +0200183 RESULT("mon_grouping", x);
184
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000185 RESULT_STRING(positive_sign);
186 RESULT_STRING(negative_sign);
187 RESULT_INT(int_frac_digits);
188 RESULT_INT(frac_digits);
189 RESULT_INT(p_cs_precedes);
190 RESULT_INT(p_sep_by_space);
191 RESULT_INT(n_cs_precedes);
192 RESULT_INT(n_sep_by_space);
193 RESULT_INT(p_sign_posn);
194 RESULT_INT(n_sign_posn);
195 return result;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000196
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000197 failed:
198 Py_XDECREF(result);
199 Py_XDECREF(x);
200 return NULL;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000201}
202
Martin v. Löwis92fab752008-03-08 10:40:41 +0000203#if defined(HAVE_WCSCOLL)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000204PyDoc_STRVAR(strcoll__doc__,
205"string,string -> int. Compares two strings according to the locale.");
Guido van Rossum220ecc81997-11-18 21:03:39 +0000206
207static PyObject*
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000208PyLocale_strcoll(PyObject* self, PyObject* args)
Guido van Rossum220ecc81997-11-18 21:03:39 +0000209{
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000210 PyObject *os1, *os2, *result = NULL;
211 wchar_t *ws1 = NULL, *ws2 = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000212
Martin v. Löwis92fab752008-03-08 10:40:41 +0000213 if (!PyArg_ParseTuple(args, "UU:strcoll", &os1, &os2))
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000214 return NULL;
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000215 /* Convert the unicode strings to wchar[]. */
Victor Stinnerbeb4135b2010-10-07 01:02:42 +0000216 ws1 = PyUnicode_AsWideCharString(os1, NULL);
Victor Stinner449057f2010-09-29 10:30:43 +0000217 if (ws1 == NULL)
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000218 goto done;
Victor Stinnerbeb4135b2010-10-07 01:02:42 +0000219 ws2 = PyUnicode_AsWideCharString(os2, NULL);
Victor Stinner449057f2010-09-29 10:30:43 +0000220 if (ws2 == NULL)
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000221 goto done;
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000222 /* Collate the strings. */
Christian Heimes217cfd12007-12-02 14:31:20 +0000223 result = PyLong_FromLong(wcscoll(ws1, ws2));
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000224 done:
225 /* Deallocate everything. */
226 if (ws1) PyMem_FREE(ws1);
227 if (ws2) PyMem_FREE(ws2);
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000228 return result;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000229}
Martin v. Löwis92fab752008-03-08 10:40:41 +0000230#endif
Guido van Rossum220ecc81997-11-18 21:03:39 +0000231
Martin v. Löwis92fab752008-03-08 10:40:41 +0000232#ifdef HAVE_WCSXFRM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000233PyDoc_STRVAR(strxfrm__doc__,
Mark Dickinson211c6252009-02-01 10:28:51 +0000234"strxfrm(string) -> string.\n\
235\n\
236Return a string that can be used as a key for locale-aware comparisons.");
Guido van Rossum220ecc81997-11-18 21:03:39 +0000237
238static PyObject*
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000239PyLocale_strxfrm(PyObject* self, PyObject* args)
Guido van Rossum220ecc81997-11-18 21:03:39 +0000240{
Victor Stinner63649272011-09-29 23:32:06 +0200241 PyObject *str;
242 Py_ssize_t n1;
243 wchar_t *s = NULL, *buf = NULL;
244 size_t n2;
Martin v. Löwis92fab752008-03-08 10:40:41 +0000245 PyObject *result = NULL;
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000246
Victor Stinner63649272011-09-29 23:32:06 +0200247 if (!PyArg_ParseTuple(args, "U:strxfrm", &str))
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000248 return NULL;
249
Victor Stinner63649272011-09-29 23:32:06 +0200250 s = PyUnicode_AsWideCharString(str, &n1);
251 if (s == NULL)
252 goto exit;
Martin v. Löwis92fab752008-03-08 10:40:41 +0000253
254 /* assume no change in size, first */
Victor Stinner63649272011-09-29 23:32:06 +0200255 n1 = n1 + 1;
256 buf = PyMem_Malloc(n1 * sizeof(wchar_t));
Martin v. Löwis92fab752008-03-08 10:40:41 +0000257 if (!buf) {
258 PyErr_NoMemory();
259 goto exit;
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000260 }
Martin v. Löwis92fab752008-03-08 10:40:41 +0000261 n2 = wcsxfrm(buf, s, n1);
Victor Stinner2c5d3cb2011-10-11 22:35:52 +0200262 if (n2 >= (size_t)n1) {
Martin v. Löwis92fab752008-03-08 10:40:41 +0000263 /* more space needed */
Kristjan Valur Jonsson85634d72012-05-31 09:37:31 +0000264 wchar_t * new_buf = PyMem_Realloc(buf, (n2+1)*sizeof(wchar_t));
265 if (!new_buf) {
Martin v. Löwis92fab752008-03-08 10:40:41 +0000266 PyErr_NoMemory();
267 goto exit;
268 }
Kristjan Valur Jonsson85634d72012-05-31 09:37:31 +0000269 buf = new_buf;
Martin v. Löwisdb1c3992009-05-23 10:38:26 +0000270 n2 = wcsxfrm(buf, s, n2+1);
Martin v. Löwis92fab752008-03-08 10:40:41 +0000271 }
272 result = PyUnicode_FromWideChar(buf, n2);
Victor Stinner63649272011-09-29 23:32:06 +0200273exit:
274 if (buf)
275 PyMem_Free(buf);
276 if (s)
277 PyMem_Free(s);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000278 return result;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000279}
Martin v. Löwis92fab752008-03-08 10:40:41 +0000280#endif
Guido van Rossum220ecc81997-11-18 21:03:39 +0000281
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000282#if defined(MS_WINDOWS)
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000283static PyObject*
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000284PyLocale_getdefaultlocale(PyObject* self)
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000285{
286 char encoding[100];
287 char locale[100];
288
Tim Peters885d4572001-11-28 20:27:42 +0000289 PyOS_snprintf(encoding, sizeof(encoding), "cp%d", GetACP());
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000290
291 if (GetLocaleInfo(LOCALE_USER_DEFAULT,
292 LOCALE_SISO639LANGNAME,
293 locale, sizeof(locale))) {
Martin v. Löwis18e16552006-02-15 17:27:45 +0000294 Py_ssize_t i = strlen(locale);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000295 locale[i++] = '_';
296 if (GetLocaleInfo(LOCALE_USER_DEFAULT,
297 LOCALE_SISO3166CTRYNAME,
Martin v. Löwis18e16552006-02-15 17:27:45 +0000298 locale+i, (int)(sizeof(locale)-i)))
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000299 return Py_BuildValue("ss", locale, encoding);
300 }
301
302 /* If we end up here, this windows version didn't know about
303 ISO639/ISO3166 names (it's probably Windows 95). Return the
304 Windows language identifier instead (a hexadecimal number) */
305
306 locale[0] = '0';
307 locale[1] = 'x';
308 if (GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_IDEFAULTLANGUAGE,
309 locale+2, sizeof(locale)-2)) {
310 return Py_BuildValue("ss", locale, encoding);
311 }
312
313 /* cannot determine the language code (very unlikely) */
314 Py_INCREF(Py_None);
315 return Py_BuildValue("Os", Py_None, encoding);
316}
317#endif
318
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000319#ifdef HAVE_LANGINFO_H
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000320#define LANGINFO(X) {#X, X}
Martin v. Löwis59683e82008-06-13 07:50:45 +0000321static struct langinfo_constant{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000322 char* name;
323 int value;
324} langinfo_constants[] =
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000325{
326 /* These constants should exist on any langinfo implementation */
327 LANGINFO(DAY_1),
328 LANGINFO(DAY_2),
329 LANGINFO(DAY_3),
330 LANGINFO(DAY_4),
331 LANGINFO(DAY_5),
332 LANGINFO(DAY_6),
333 LANGINFO(DAY_7),
334
335 LANGINFO(ABDAY_1),
336 LANGINFO(ABDAY_2),
337 LANGINFO(ABDAY_3),
338 LANGINFO(ABDAY_4),
339 LANGINFO(ABDAY_5),
340 LANGINFO(ABDAY_6),
341 LANGINFO(ABDAY_7),
342
343 LANGINFO(MON_1),
344 LANGINFO(MON_2),
345 LANGINFO(MON_3),
346 LANGINFO(MON_4),
347 LANGINFO(MON_5),
348 LANGINFO(MON_6),
349 LANGINFO(MON_7),
350 LANGINFO(MON_8),
351 LANGINFO(MON_9),
352 LANGINFO(MON_10),
353 LANGINFO(MON_11),
354 LANGINFO(MON_12),
355
356 LANGINFO(ABMON_1),
357 LANGINFO(ABMON_2),
358 LANGINFO(ABMON_3),
359 LANGINFO(ABMON_4),
360 LANGINFO(ABMON_5),
361 LANGINFO(ABMON_6),
362 LANGINFO(ABMON_7),
363 LANGINFO(ABMON_8),
364 LANGINFO(ABMON_9),
365 LANGINFO(ABMON_10),
366 LANGINFO(ABMON_11),
367 LANGINFO(ABMON_12),
368
369#ifdef RADIXCHAR
370 /* The following are not available with glibc 2.0 */
371 LANGINFO(RADIXCHAR),
372 LANGINFO(THOUSEP),
373 /* YESSTR and NOSTR are deprecated in glibc, since they are
374 a special case of message translation, which should be rather
375 done using gettext. So we don't expose it to Python in the
376 first place.
377 LANGINFO(YESSTR),
378 LANGINFO(NOSTR),
379 */
380 LANGINFO(CRNCYSTR),
381#endif
382
383 LANGINFO(D_T_FMT),
384 LANGINFO(D_FMT),
385 LANGINFO(T_FMT),
386 LANGINFO(AM_STR),
387 LANGINFO(PM_STR),
388
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000389 /* The following constants are available only with XPG4, but...
390 AIX 3.2. only has CODESET.
391 OpenBSD doesn't have CODESET but has T_FMT_AMPM, and doesn't have
392 a few of the others.
393 Solution: ifdef-test them all. */
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000394#ifdef CODESET
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000395 LANGINFO(CODESET),
Martin v. Löwis496f9e42002-03-27 12:15:57 +0000396#endif
397#ifdef T_FMT_AMPM
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000398 LANGINFO(T_FMT_AMPM),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000399#endif
400#ifdef ERA
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000401 LANGINFO(ERA),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000402#endif
403#ifdef ERA_D_FMT
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000404 LANGINFO(ERA_D_FMT),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000405#endif
406#ifdef ERA_D_T_FMT
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000407 LANGINFO(ERA_D_T_FMT),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000408#endif
409#ifdef ERA_T_FMT
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000410 LANGINFO(ERA_T_FMT),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000411#endif
412#ifdef ALT_DIGITS
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000413 LANGINFO(ALT_DIGITS),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000414#endif
415#ifdef YESEXPR
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000416 LANGINFO(YESEXPR),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000417#endif
418#ifdef NOEXPR
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000419 LANGINFO(NOEXPR),
420#endif
421#ifdef _DATE_FMT
422 /* This is not available in all glibc versions that have CODESET. */
423 LANGINFO(_DATE_FMT),
424#endif
425 {0, 0}
426};
427
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000428PyDoc_STRVAR(nl_langinfo__doc__,
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000429"nl_langinfo(key) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000430"Return the value for the locale information associated with key.");
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000431
432static PyObject*
433PyLocale_nl_langinfo(PyObject* self, PyObject* args)
434{
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000435 int item, i;
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000436 if (!PyArg_ParseTuple(args, "i:nl_langinfo", &item))
437 return NULL;
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000438 /* Check whether this is a supported constant. GNU libc sometimes
439 returns numeric values in the char* return value, which would
Neal Norwitz7f9d29c2007-08-26 07:21:45 +0000440 crash PyUnicode_FromString. */
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000441 for (i = 0; langinfo_constants[i].name; i++)
Hye-Shik Changc3a87b82004-03-21 19:34:30 +0000442 if (langinfo_constants[i].value == item) {
443 /* Check NULL as a workaround for GNU libc's returning NULL
444 instead of an empty string for nl_langinfo(ERA). */
445 const char *result = nl_langinfo(item);
Neal Norwitz3d7a90d2007-10-27 05:40:06 +0000446 result = result != NULL ? result : "";
Victor Stinnera9c895d2012-02-14 02:33:38 +0100447 return PyUnicode_DecodeLocale(result, NULL);
Hye-Shik Changc3a87b82004-03-21 19:34:30 +0000448 }
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000449 PyErr_SetString(PyExc_ValueError, "unsupported langinfo constant");
450 return NULL;
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000451}
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000452#endif /* HAVE_LANGINFO_H */
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000453
454#ifdef HAVE_LIBINTL_H
455
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000456PyDoc_STRVAR(gettext__doc__,
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000457"gettext(msg) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000458"Return translation of msg.");
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000459
460static PyObject*
461PyIntl_gettext(PyObject* self, PyObject *args)
462{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000463 char *in;
464 if (!PyArg_ParseTuple(args, "s", &in))
465 return 0;
Victor Stinnera9c895d2012-02-14 02:33:38 +0100466 return PyUnicode_DecodeLocale(gettext(in), NULL);
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000467}
468
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000469PyDoc_STRVAR(dgettext__doc__,
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000470"dgettext(domain, msg) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000471"Return translation of msg in domain.");
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000472
473static PyObject*
474PyIntl_dgettext(PyObject* self, PyObject *args)
475{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000476 char *domain, *in;
477 if (!PyArg_ParseTuple(args, "zs", &domain, &in))
478 return 0;
Victor Stinnera9c895d2012-02-14 02:33:38 +0100479 return PyUnicode_DecodeLocale(dgettext(domain, in), NULL);
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000480}
481
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000482PyDoc_STRVAR(dcgettext__doc__,
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000483"dcgettext(domain, msg, category) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000484"Return translation of msg in domain and category.");
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000485
486static PyObject*
487PyIntl_dcgettext(PyObject *self, PyObject *args)
488{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000489 char *domain, *msgid;
490 int category;
491 if (!PyArg_ParseTuple(args, "zsi", &domain, &msgid, &category))
492 return 0;
Victor Stinnera9c895d2012-02-14 02:33:38 +0100493 return PyUnicode_DecodeLocale(dcgettext(domain,msgid,category), NULL);
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000494}
495
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000496PyDoc_STRVAR(textdomain__doc__,
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000497"textdomain(domain) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000498"Set the C library's textdmain to domain, returning the new domain.");
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000499
500static PyObject*
501PyIntl_textdomain(PyObject* self, PyObject* args)
502{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000503 char *domain;
504 if (!PyArg_ParseTuple(args, "z", &domain))
505 return 0;
506 domain = textdomain(domain);
507 if (!domain) {
508 PyErr_SetFromErrno(PyExc_OSError);
509 return NULL;
510 }
Victor Stinnera9c895d2012-02-14 02:33:38 +0100511 return PyUnicode_DecodeLocale(domain, NULL);
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000512}
513
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000514PyDoc_STRVAR(bindtextdomain__doc__,
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000515"bindtextdomain(domain, dir) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000516"Bind the C library's domain to dir.");
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000517
518static PyObject*
519PyIntl_bindtextdomain(PyObject* self,PyObject*args)
520{
Victor Stinner9e19ca42010-06-11 22:09:51 +0000521 char *domain, *dirname, *current_dirname;
522 PyObject *dirname_obj, *dirname_bytes = NULL, *result;
523 if (!PyArg_ParseTuple(args, "sO", &domain, &dirname_obj))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000524 return 0;
525 if (!strlen(domain)) {
526 PyErr_SetString(Error, "domain must be a non-empty string");
527 return 0;
528 }
Victor Stinner9e19ca42010-06-11 22:09:51 +0000529 if (dirname_obj != Py_None) {
530 if (!PyUnicode_FSConverter(dirname_obj, &dirname_bytes))
531 return NULL;
532 dirname = PyBytes_AsString(dirname_bytes);
533 } else {
534 dirname_bytes = NULL;
535 dirname = NULL;
536 }
537 current_dirname = bindtextdomain(domain, dirname);
538 if (current_dirname == NULL) {
539 Py_XDECREF(dirname_bytes);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000540 PyErr_SetFromErrno(PyExc_OSError);
541 return NULL;
542 }
Victor Stinnera9c895d2012-02-14 02:33:38 +0100543 result = PyUnicode_DecodeLocale(current_dirname, NULL);
Victor Stinner9e19ca42010-06-11 22:09:51 +0000544 Py_XDECREF(dirname_bytes);
545 return result;
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000546}
547
Gustavo Niemeyer7bd33c52004-07-22 18:44:01 +0000548#ifdef HAVE_BIND_TEXTDOMAIN_CODESET
549PyDoc_STRVAR(bind_textdomain_codeset__doc__,
550"bind_textdomain_codeset(domain, codeset) -> string\n"
551"Bind the C library's domain to codeset.");
552
553static PyObject*
554PyIntl_bind_textdomain_codeset(PyObject* self,PyObject*args)
555{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000556 char *domain,*codeset;
557 if (!PyArg_ParseTuple(args, "sz", &domain, &codeset))
558 return NULL;
559 codeset = bind_textdomain_codeset(domain, codeset);
560 if (codeset)
Victor Stinnera9c895d2012-02-14 02:33:38 +0100561 return PyUnicode_DecodeLocale(codeset, NULL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000562 Py_RETURN_NONE;
Gustavo Niemeyer7bd33c52004-07-22 18:44:01 +0000563}
564#endif
565
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000566#endif
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000567
Guido van Rossum220ecc81997-11-18 21:03:39 +0000568static struct PyMethodDef PyLocale_Methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000569 {"setlocale", (PyCFunction) PyLocale_setlocale,
Andrew M. Kuchlinge365fb82000-08-03 02:06:16 +0000570 METH_VARARGS, setlocale__doc__},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000571 {"localeconv", (PyCFunction) PyLocale_localeconv,
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000572 METH_NOARGS, localeconv__doc__},
Martin v. Löwis92fab752008-03-08 10:40:41 +0000573#ifdef HAVE_WCSCOLL
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000574 {"strcoll", (PyCFunction) PyLocale_strcoll,
Andrew M. Kuchlinge365fb82000-08-03 02:06:16 +0000575 METH_VARARGS, strcoll__doc__},
Martin v. Löwis92fab752008-03-08 10:40:41 +0000576#endif
577#ifdef HAVE_WCSXFRM
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000578 {"strxfrm", (PyCFunction) PyLocale_strxfrm,
Andrew M. Kuchlinge365fb82000-08-03 02:06:16 +0000579 METH_VARARGS, strxfrm__doc__},
Martin v. Löwis92fab752008-03-08 10:40:41 +0000580#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000581#if defined(MS_WINDOWS)
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000582 {"_getdefaultlocale", (PyCFunction) PyLocale_getdefaultlocale, METH_NOARGS},
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000583#endif
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000584#ifdef HAVE_LANGINFO_H
585 {"nl_langinfo", (PyCFunction) PyLocale_nl_langinfo,
586 METH_VARARGS, nl_langinfo__doc__},
587#endif
Martin v. Löwisc6a7d7e2002-05-02 12:16:29 +0000588#ifdef HAVE_LIBINTL_H
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000589 {"gettext",(PyCFunction)PyIntl_gettext,METH_VARARGS,
590 gettext__doc__},
591 {"dgettext",(PyCFunction)PyIntl_dgettext,METH_VARARGS,
592 dgettext__doc__},
593 {"dcgettext",(PyCFunction)PyIntl_dcgettext,METH_VARARGS,
594 dcgettext__doc__},
595 {"textdomain",(PyCFunction)PyIntl_textdomain,METH_VARARGS,
596 textdomain__doc__},
597 {"bindtextdomain",(PyCFunction)PyIntl_bindtextdomain,METH_VARARGS,
598 bindtextdomain__doc__},
Gustavo Niemeyer7bd33c52004-07-22 18:44:01 +0000599#ifdef HAVE_BIND_TEXTDOMAIN_CODESET
600 {"bind_textdomain_codeset",(PyCFunction)PyIntl_bind_textdomain_codeset,
601 METH_VARARGS, bind_textdomain_codeset__doc__},
602#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000603#endif
Guido van Rossum220ecc81997-11-18 21:03:39 +0000604 {NULL, NULL}
605};
606
Martin v. Löwis1a214512008-06-11 05:26:20 +0000607
608static struct PyModuleDef _localemodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000609 PyModuleDef_HEAD_INIT,
610 "_locale",
611 locale__doc__,
612 -1,
613 PyLocale_Methods,
614 NULL,
615 NULL,
616 NULL,
617 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +0000618};
619
Mark Hammondfe51c6d2002-08-02 02:27:13 +0000620PyMODINIT_FUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +0000621PyInit__locale(void)
Guido van Rossum220ecc81997-11-18 21:03:39 +0000622{
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000623 PyObject *m, *d, *x;
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000624#ifdef HAVE_LANGINFO_H
625 int i;
626#endif
Guido van Rossum220ecc81997-11-18 21:03:39 +0000627
Martin v. Löwis1a214512008-06-11 05:26:20 +0000628 m = PyModule_Create(&_localemodule);
Neal Norwitz1ac754f2006-01-19 06:09:39 +0000629 if (m == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000630 return NULL;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000631
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000632 d = PyModule_GetDict(m);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000633
Christian Heimes217cfd12007-12-02 14:31:20 +0000634 x = PyLong_FromLong(LC_CTYPE);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000635 PyDict_SetItemString(d, "LC_CTYPE", x);
636 Py_XDECREF(x);
637
Christian Heimes217cfd12007-12-02 14:31:20 +0000638 x = PyLong_FromLong(LC_TIME);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000639 PyDict_SetItemString(d, "LC_TIME", x);
640 Py_XDECREF(x);
641
Christian Heimes217cfd12007-12-02 14:31:20 +0000642 x = PyLong_FromLong(LC_COLLATE);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000643 PyDict_SetItemString(d, "LC_COLLATE", x);
644 Py_XDECREF(x);
645
Christian Heimes217cfd12007-12-02 14:31:20 +0000646 x = PyLong_FromLong(LC_MONETARY);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000647 PyDict_SetItemString(d, "LC_MONETARY", x);
648 Py_XDECREF(x);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000649
Guido van Rossum8d9c2e31997-12-09 19:35:11 +0000650#ifdef LC_MESSAGES
Christian Heimes217cfd12007-12-02 14:31:20 +0000651 x = PyLong_FromLong(LC_MESSAGES);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000652 PyDict_SetItemString(d, "LC_MESSAGES", x);
653 Py_XDECREF(x);
Guido van Rossum8d9c2e31997-12-09 19:35:11 +0000654#endif /* LC_MESSAGES */
Guido van Rossum220ecc81997-11-18 21:03:39 +0000655
Christian Heimes217cfd12007-12-02 14:31:20 +0000656 x = PyLong_FromLong(LC_NUMERIC);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000657 PyDict_SetItemString(d, "LC_NUMERIC", 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(LC_ALL);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000661 PyDict_SetItemString(d, "LC_ALL", x);
662 Py_XDECREF(x);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000663
Christian Heimes217cfd12007-12-02 14:31:20 +0000664 x = PyLong_FromLong(CHAR_MAX);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000665 PyDict_SetItemString(d, "CHAR_MAX", x);
666 Py_XDECREF(x);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000667
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000668 Error = PyErr_NewException("locale.Error", NULL, NULL);
669 PyDict_SetItemString(d, "Error", Error);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000670
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000671#ifdef HAVE_LANGINFO_H
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000672 for (i = 0; langinfo_constants[i].name; i++) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000673 PyModule_AddIntConstant(m, langinfo_constants[i].name,
674 langinfo_constants[i].value);
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000675 }
Martin v. Löwisf95dd0a2001-08-15 17:14:33 +0000676#endif
Martin v. Löwis1a214512008-06-11 05:26:20 +0000677 return m;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000678}
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000679
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000680/*
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000681Local variables:
682c-basic-offset: 4
683indent-tabs-mode: nil
684End:
685*/