blob: 20c59a4e1ad09230dfbdb29a1ceeffe2fcf315e2 [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 */
Martin v. Löwisa69e1ef2008-03-08 10:54:31 +0000260 buf = PyMem_Realloc(buf, (n2+1)*sizeof(wchar_t));
Martin v. Löwis92fab752008-03-08 10:40:41 +0000261 if (!buf) {
262 PyErr_NoMemory();
263 goto exit;
264 }
Martin v. Löwisdb1c3992009-05-23 10:38:26 +0000265 n2 = wcsxfrm(buf, s, n2+1);
Martin v. Löwis92fab752008-03-08 10:40:41 +0000266 }
267 result = PyUnicode_FromWideChar(buf, n2);
Victor Stinner63649272011-09-29 23:32:06 +0200268exit:
269 if (buf)
270 PyMem_Free(buf);
271 if (s)
272 PyMem_Free(s);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000273 return result;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000274}
Martin v. Löwis92fab752008-03-08 10:40:41 +0000275#endif
Guido van Rossum220ecc81997-11-18 21:03:39 +0000276
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000277#if defined(MS_WINDOWS)
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000278static PyObject*
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000279PyLocale_getdefaultlocale(PyObject* self)
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000280{
281 char encoding[100];
282 char locale[100];
283
Tim Peters885d4572001-11-28 20:27:42 +0000284 PyOS_snprintf(encoding, sizeof(encoding), "cp%d", GetACP());
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000285
286 if (GetLocaleInfo(LOCALE_USER_DEFAULT,
287 LOCALE_SISO639LANGNAME,
288 locale, sizeof(locale))) {
Martin v. Löwis18e16552006-02-15 17:27:45 +0000289 Py_ssize_t i = strlen(locale);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000290 locale[i++] = '_';
291 if (GetLocaleInfo(LOCALE_USER_DEFAULT,
292 LOCALE_SISO3166CTRYNAME,
Martin v. Löwis18e16552006-02-15 17:27:45 +0000293 locale+i, (int)(sizeof(locale)-i)))
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000294 return Py_BuildValue("ss", locale, encoding);
295 }
296
297 /* If we end up here, this windows version didn't know about
298 ISO639/ISO3166 names (it's probably Windows 95). Return the
299 Windows language identifier instead (a hexadecimal number) */
300
301 locale[0] = '0';
302 locale[1] = 'x';
303 if (GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_IDEFAULTLANGUAGE,
304 locale+2, sizeof(locale)-2)) {
305 return Py_BuildValue("ss", locale, encoding);
306 }
307
308 /* cannot determine the language code (very unlikely) */
309 Py_INCREF(Py_None);
310 return Py_BuildValue("Os", Py_None, encoding);
311}
312#endif
313
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000314#ifdef HAVE_LANGINFO_H
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000315#define LANGINFO(X) {#X, X}
Martin v. Löwis59683e82008-06-13 07:50:45 +0000316static struct langinfo_constant{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000317 char* name;
318 int value;
319} langinfo_constants[] =
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000320{
321 /* These constants should exist on any langinfo implementation */
322 LANGINFO(DAY_1),
323 LANGINFO(DAY_2),
324 LANGINFO(DAY_3),
325 LANGINFO(DAY_4),
326 LANGINFO(DAY_5),
327 LANGINFO(DAY_6),
328 LANGINFO(DAY_7),
329
330 LANGINFO(ABDAY_1),
331 LANGINFO(ABDAY_2),
332 LANGINFO(ABDAY_3),
333 LANGINFO(ABDAY_4),
334 LANGINFO(ABDAY_5),
335 LANGINFO(ABDAY_6),
336 LANGINFO(ABDAY_7),
337
338 LANGINFO(MON_1),
339 LANGINFO(MON_2),
340 LANGINFO(MON_3),
341 LANGINFO(MON_4),
342 LANGINFO(MON_5),
343 LANGINFO(MON_6),
344 LANGINFO(MON_7),
345 LANGINFO(MON_8),
346 LANGINFO(MON_9),
347 LANGINFO(MON_10),
348 LANGINFO(MON_11),
349 LANGINFO(MON_12),
350
351 LANGINFO(ABMON_1),
352 LANGINFO(ABMON_2),
353 LANGINFO(ABMON_3),
354 LANGINFO(ABMON_4),
355 LANGINFO(ABMON_5),
356 LANGINFO(ABMON_6),
357 LANGINFO(ABMON_7),
358 LANGINFO(ABMON_8),
359 LANGINFO(ABMON_9),
360 LANGINFO(ABMON_10),
361 LANGINFO(ABMON_11),
362 LANGINFO(ABMON_12),
363
364#ifdef RADIXCHAR
365 /* The following are not available with glibc 2.0 */
366 LANGINFO(RADIXCHAR),
367 LANGINFO(THOUSEP),
368 /* YESSTR and NOSTR are deprecated in glibc, since they are
369 a special case of message translation, which should be rather
370 done using gettext. So we don't expose it to Python in the
371 first place.
372 LANGINFO(YESSTR),
373 LANGINFO(NOSTR),
374 */
375 LANGINFO(CRNCYSTR),
376#endif
377
378 LANGINFO(D_T_FMT),
379 LANGINFO(D_FMT),
380 LANGINFO(T_FMT),
381 LANGINFO(AM_STR),
382 LANGINFO(PM_STR),
383
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000384 /* The following constants are available only with XPG4, but...
385 AIX 3.2. only has CODESET.
386 OpenBSD doesn't have CODESET but has T_FMT_AMPM, and doesn't have
387 a few of the others.
388 Solution: ifdef-test them all. */
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000389#ifdef CODESET
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000390 LANGINFO(CODESET),
Martin v. Löwis496f9e42002-03-27 12:15:57 +0000391#endif
392#ifdef T_FMT_AMPM
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000393 LANGINFO(T_FMT_AMPM),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000394#endif
395#ifdef ERA
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000396 LANGINFO(ERA),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000397#endif
398#ifdef ERA_D_FMT
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000399 LANGINFO(ERA_D_FMT),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000400#endif
401#ifdef ERA_D_T_FMT
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000402 LANGINFO(ERA_D_T_FMT),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000403#endif
404#ifdef ERA_T_FMT
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000405 LANGINFO(ERA_T_FMT),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000406#endif
407#ifdef ALT_DIGITS
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000408 LANGINFO(ALT_DIGITS),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000409#endif
410#ifdef YESEXPR
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000411 LANGINFO(YESEXPR),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000412#endif
413#ifdef NOEXPR
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000414 LANGINFO(NOEXPR),
415#endif
416#ifdef _DATE_FMT
417 /* This is not available in all glibc versions that have CODESET. */
418 LANGINFO(_DATE_FMT),
419#endif
420 {0, 0}
421};
422
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000423PyDoc_STRVAR(nl_langinfo__doc__,
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000424"nl_langinfo(key) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000425"Return the value for the locale information associated with key.");
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000426
427static PyObject*
428PyLocale_nl_langinfo(PyObject* self, PyObject* args)
429{
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000430 int item, i;
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000431 if (!PyArg_ParseTuple(args, "i:nl_langinfo", &item))
432 return NULL;
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000433 /* Check whether this is a supported constant. GNU libc sometimes
434 returns numeric values in the char* return value, which would
Neal Norwitz7f9d29c2007-08-26 07:21:45 +0000435 crash PyUnicode_FromString. */
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000436 for (i = 0; langinfo_constants[i].name; i++)
Hye-Shik Changc3a87b82004-03-21 19:34:30 +0000437 if (langinfo_constants[i].value == item) {
438 /* Check NULL as a workaround for GNU libc's returning NULL
439 instead of an empty string for nl_langinfo(ERA). */
440 const char *result = nl_langinfo(item);
Neal Norwitz3d7a90d2007-10-27 05:40:06 +0000441 result = result != NULL ? result : "";
Victor Stinnera9c895d2012-02-14 02:33:38 +0100442 return PyUnicode_DecodeLocale(result, NULL);
Hye-Shik Changc3a87b82004-03-21 19:34:30 +0000443 }
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000444 PyErr_SetString(PyExc_ValueError, "unsupported langinfo constant");
445 return NULL;
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000446}
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000447#endif /* HAVE_LANGINFO_H */
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000448
449#ifdef HAVE_LIBINTL_H
450
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000451PyDoc_STRVAR(gettext__doc__,
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000452"gettext(msg) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000453"Return translation of msg.");
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000454
455static PyObject*
456PyIntl_gettext(PyObject* self, PyObject *args)
457{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000458 char *in;
459 if (!PyArg_ParseTuple(args, "s", &in))
460 return 0;
Victor Stinnera9c895d2012-02-14 02:33:38 +0100461 return PyUnicode_DecodeLocale(gettext(in), NULL);
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000462}
463
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000464PyDoc_STRVAR(dgettext__doc__,
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000465"dgettext(domain, msg) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000466"Return translation of msg in domain.");
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000467
468static PyObject*
469PyIntl_dgettext(PyObject* self, PyObject *args)
470{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000471 char *domain, *in;
472 if (!PyArg_ParseTuple(args, "zs", &domain, &in))
473 return 0;
Victor Stinnera9c895d2012-02-14 02:33:38 +0100474 return PyUnicode_DecodeLocale(dgettext(domain, in), NULL);
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000475}
476
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000477PyDoc_STRVAR(dcgettext__doc__,
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000478"dcgettext(domain, msg, category) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000479"Return translation of msg in domain and category.");
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000480
481static PyObject*
482PyIntl_dcgettext(PyObject *self, PyObject *args)
483{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000484 char *domain, *msgid;
485 int category;
486 if (!PyArg_ParseTuple(args, "zsi", &domain, &msgid, &category))
487 return 0;
Victor Stinnera9c895d2012-02-14 02:33:38 +0100488 return PyUnicode_DecodeLocale(dcgettext(domain,msgid,category), NULL);
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000489}
490
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000491PyDoc_STRVAR(textdomain__doc__,
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000492"textdomain(domain) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000493"Set the C library's textdmain to domain, returning the new domain.");
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000494
495static PyObject*
496PyIntl_textdomain(PyObject* self, PyObject* args)
497{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000498 char *domain;
499 if (!PyArg_ParseTuple(args, "z", &domain))
500 return 0;
501 domain = textdomain(domain);
502 if (!domain) {
503 PyErr_SetFromErrno(PyExc_OSError);
504 return NULL;
505 }
Victor Stinnera9c895d2012-02-14 02:33:38 +0100506 return PyUnicode_DecodeLocale(domain, NULL);
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000507}
508
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000509PyDoc_STRVAR(bindtextdomain__doc__,
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000510"bindtextdomain(domain, dir) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000511"Bind the C library's domain to dir.");
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000512
513static PyObject*
514PyIntl_bindtextdomain(PyObject* self,PyObject*args)
515{
Victor Stinner9e19ca42010-06-11 22:09:51 +0000516 char *domain, *dirname, *current_dirname;
517 PyObject *dirname_obj, *dirname_bytes = NULL, *result;
518 if (!PyArg_ParseTuple(args, "sO", &domain, &dirname_obj))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000519 return 0;
520 if (!strlen(domain)) {
521 PyErr_SetString(Error, "domain must be a non-empty string");
522 return 0;
523 }
Victor Stinner9e19ca42010-06-11 22:09:51 +0000524 if (dirname_obj != Py_None) {
525 if (!PyUnicode_FSConverter(dirname_obj, &dirname_bytes))
526 return NULL;
527 dirname = PyBytes_AsString(dirname_bytes);
528 } else {
529 dirname_bytes = NULL;
530 dirname = NULL;
531 }
532 current_dirname = bindtextdomain(domain, dirname);
533 if (current_dirname == NULL) {
534 Py_XDECREF(dirname_bytes);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000535 PyErr_SetFromErrno(PyExc_OSError);
536 return NULL;
537 }
Victor Stinnera9c895d2012-02-14 02:33:38 +0100538 result = PyUnicode_DecodeLocale(current_dirname, NULL);
Victor Stinner9e19ca42010-06-11 22:09:51 +0000539 Py_XDECREF(dirname_bytes);
540 return result;
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000541}
542
Gustavo Niemeyer7bd33c52004-07-22 18:44:01 +0000543#ifdef HAVE_BIND_TEXTDOMAIN_CODESET
544PyDoc_STRVAR(bind_textdomain_codeset__doc__,
545"bind_textdomain_codeset(domain, codeset) -> string\n"
546"Bind the C library's domain to codeset.");
547
548static PyObject*
549PyIntl_bind_textdomain_codeset(PyObject* self,PyObject*args)
550{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000551 char *domain,*codeset;
552 if (!PyArg_ParseTuple(args, "sz", &domain, &codeset))
553 return NULL;
554 codeset = bind_textdomain_codeset(domain, codeset);
555 if (codeset)
Victor Stinnera9c895d2012-02-14 02:33:38 +0100556 return PyUnicode_DecodeLocale(codeset, NULL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000557 Py_RETURN_NONE;
Gustavo Niemeyer7bd33c52004-07-22 18:44:01 +0000558}
559#endif
560
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000561#endif
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000562
Guido van Rossum220ecc81997-11-18 21:03:39 +0000563static struct PyMethodDef PyLocale_Methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000564 {"setlocale", (PyCFunction) PyLocale_setlocale,
Andrew M. Kuchlinge365fb82000-08-03 02:06:16 +0000565 METH_VARARGS, setlocale__doc__},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000566 {"localeconv", (PyCFunction) PyLocale_localeconv,
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000567 METH_NOARGS, localeconv__doc__},
Martin v. Löwis92fab752008-03-08 10:40:41 +0000568#ifdef HAVE_WCSCOLL
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000569 {"strcoll", (PyCFunction) PyLocale_strcoll,
Andrew M. Kuchlinge365fb82000-08-03 02:06:16 +0000570 METH_VARARGS, strcoll__doc__},
Martin v. Löwis92fab752008-03-08 10:40:41 +0000571#endif
572#ifdef HAVE_WCSXFRM
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000573 {"strxfrm", (PyCFunction) PyLocale_strxfrm,
Andrew M. Kuchlinge365fb82000-08-03 02:06:16 +0000574 METH_VARARGS, strxfrm__doc__},
Martin v. Löwis92fab752008-03-08 10:40:41 +0000575#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000576#if defined(MS_WINDOWS)
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000577 {"_getdefaultlocale", (PyCFunction) PyLocale_getdefaultlocale, METH_NOARGS},
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000578#endif
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000579#ifdef HAVE_LANGINFO_H
580 {"nl_langinfo", (PyCFunction) PyLocale_nl_langinfo,
581 METH_VARARGS, nl_langinfo__doc__},
582#endif
Martin v. Löwisc6a7d7e2002-05-02 12:16:29 +0000583#ifdef HAVE_LIBINTL_H
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000584 {"gettext",(PyCFunction)PyIntl_gettext,METH_VARARGS,
585 gettext__doc__},
586 {"dgettext",(PyCFunction)PyIntl_dgettext,METH_VARARGS,
587 dgettext__doc__},
588 {"dcgettext",(PyCFunction)PyIntl_dcgettext,METH_VARARGS,
589 dcgettext__doc__},
590 {"textdomain",(PyCFunction)PyIntl_textdomain,METH_VARARGS,
591 textdomain__doc__},
592 {"bindtextdomain",(PyCFunction)PyIntl_bindtextdomain,METH_VARARGS,
593 bindtextdomain__doc__},
Gustavo Niemeyer7bd33c52004-07-22 18:44:01 +0000594#ifdef HAVE_BIND_TEXTDOMAIN_CODESET
595 {"bind_textdomain_codeset",(PyCFunction)PyIntl_bind_textdomain_codeset,
596 METH_VARARGS, bind_textdomain_codeset__doc__},
597#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000598#endif
Guido van Rossum220ecc81997-11-18 21:03:39 +0000599 {NULL, NULL}
600};
601
Martin v. Löwis1a214512008-06-11 05:26:20 +0000602
603static struct PyModuleDef _localemodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000604 PyModuleDef_HEAD_INIT,
605 "_locale",
606 locale__doc__,
607 -1,
608 PyLocale_Methods,
609 NULL,
610 NULL,
611 NULL,
612 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +0000613};
614
Mark Hammondfe51c6d2002-08-02 02:27:13 +0000615PyMODINIT_FUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +0000616PyInit__locale(void)
Guido van Rossum220ecc81997-11-18 21:03:39 +0000617{
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000618 PyObject *m, *d, *x;
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000619#ifdef HAVE_LANGINFO_H
620 int i;
621#endif
Guido van Rossum220ecc81997-11-18 21:03:39 +0000622
Martin v. Löwis1a214512008-06-11 05:26:20 +0000623 m = PyModule_Create(&_localemodule);
Neal Norwitz1ac754f2006-01-19 06:09:39 +0000624 if (m == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000625 return NULL;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000626
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000627 d = PyModule_GetDict(m);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000628
Christian Heimes217cfd12007-12-02 14:31:20 +0000629 x = PyLong_FromLong(LC_CTYPE);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000630 PyDict_SetItemString(d, "LC_CTYPE", x);
631 Py_XDECREF(x);
632
Christian Heimes217cfd12007-12-02 14:31:20 +0000633 x = PyLong_FromLong(LC_TIME);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000634 PyDict_SetItemString(d, "LC_TIME", x);
635 Py_XDECREF(x);
636
Christian Heimes217cfd12007-12-02 14:31:20 +0000637 x = PyLong_FromLong(LC_COLLATE);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000638 PyDict_SetItemString(d, "LC_COLLATE", x);
639 Py_XDECREF(x);
640
Christian Heimes217cfd12007-12-02 14:31:20 +0000641 x = PyLong_FromLong(LC_MONETARY);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000642 PyDict_SetItemString(d, "LC_MONETARY", x);
643 Py_XDECREF(x);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000644
Guido van Rossum8d9c2e31997-12-09 19:35:11 +0000645#ifdef LC_MESSAGES
Christian Heimes217cfd12007-12-02 14:31:20 +0000646 x = PyLong_FromLong(LC_MESSAGES);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000647 PyDict_SetItemString(d, "LC_MESSAGES", x);
648 Py_XDECREF(x);
Guido van Rossum8d9c2e31997-12-09 19:35:11 +0000649#endif /* LC_MESSAGES */
Guido van Rossum220ecc81997-11-18 21:03:39 +0000650
Christian Heimes217cfd12007-12-02 14:31:20 +0000651 x = PyLong_FromLong(LC_NUMERIC);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000652 PyDict_SetItemString(d, "LC_NUMERIC", x);
653 Py_XDECREF(x);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000654
Christian Heimes217cfd12007-12-02 14:31:20 +0000655 x = PyLong_FromLong(LC_ALL);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000656 PyDict_SetItemString(d, "LC_ALL", x);
657 Py_XDECREF(x);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000658
Christian Heimes217cfd12007-12-02 14:31:20 +0000659 x = PyLong_FromLong(CHAR_MAX);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000660 PyDict_SetItemString(d, "CHAR_MAX", x);
661 Py_XDECREF(x);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000662
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000663 Error = PyErr_NewException("locale.Error", NULL, NULL);
664 PyDict_SetItemString(d, "Error", Error);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000665
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000666#ifdef HAVE_LANGINFO_H
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000667 for (i = 0; langinfo_constants[i].name; i++) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000668 PyModule_AddIntConstant(m, langinfo_constants[i].name,
669 langinfo_constants[i].value);
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000670 }
Martin v. Löwisf95dd0a2001-08-15 17:14:33 +0000671#endif
Martin v. Löwis1a214512008-06-11 05:26:20 +0000672 return m;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000673}
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000674
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000675/*
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000676Local variables:
677c-basic-offset: 4
678indent-tabs-mode: nil
679End:
680*/