blob: 8259180f823850d7f10a0db1adf081aba4c6b02d [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*
Serhiy Storchakaef1585e2015-12-25 20:01:53 +020052copy_grouping(const 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; \
Victor Stinnerf38a5c22013-10-29 19:28:20 +0100154 if (PyDict_SetItemString(result, key, obj) < 0) { \
155 Py_DECREF(obj); \
Victor Stinnerd594f242013-07-17 00:55:57 +0200156 goto failed; \
Victor Stinnerf38a5c22013-10-29 19:28:20 +0100157 } \
Victor Stinnerd594f242013-07-17 00:55:57 +0200158 Py_DECREF(obj); \
159 } while (0)
160
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000161#define RESULT_STRING(s)\
Victor Stinnerd594f242013-07-17 00:55:57 +0200162 do { \
163 x = PyUnicode_DecodeLocale(l->s, NULL); \
164 RESULT(#s, x); \
165 } while (0)
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000166
167#define RESULT_INT(i)\
Victor Stinnerd594f242013-07-17 00:55:57 +0200168 do { \
169 x = PyLong_FromLong(l->i); \
170 RESULT(#i, x); \
171 } while (0)
Guido van Rossum220ecc81997-11-18 21:03:39 +0000172
173 /* Numeric information */
Martin v. Löwis737ea822004-06-08 18:52:54 +0000174 RESULT_STRING(decimal_point);
175 RESULT_STRING(thousands_sep);
176 x = copy_grouping(l->grouping);
Victor Stinnerd594f242013-07-17 00:55:57 +0200177 RESULT("grouping", x);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000178
179 /* Monetary information */
180 RESULT_STRING(int_curr_symbol);
181 RESULT_STRING(currency_symbol);
182 RESULT_STRING(mon_decimal_point);
183 RESULT_STRING(mon_thousands_sep);
184 x = copy_grouping(l->mon_grouping);
Victor Stinnerd594f242013-07-17 00:55:57 +0200185 RESULT("mon_grouping", x);
186
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000187 RESULT_STRING(positive_sign);
188 RESULT_STRING(negative_sign);
189 RESULT_INT(int_frac_digits);
190 RESULT_INT(frac_digits);
191 RESULT_INT(p_cs_precedes);
192 RESULT_INT(p_sep_by_space);
193 RESULT_INT(n_cs_precedes);
194 RESULT_INT(n_sep_by_space);
195 RESULT_INT(p_sign_posn);
196 RESULT_INT(n_sign_posn);
197 return result;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000198
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000199 failed:
200 Py_XDECREF(result);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000201 return NULL;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000202}
203
Martin v. Löwis92fab752008-03-08 10:40:41 +0000204#if defined(HAVE_WCSCOLL)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000205PyDoc_STRVAR(strcoll__doc__,
206"string,string -> int. Compares two strings according to the locale.");
Guido van Rossum220ecc81997-11-18 21:03:39 +0000207
208static PyObject*
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000209PyLocale_strcoll(PyObject* self, PyObject* args)
Guido van Rossum220ecc81997-11-18 21:03:39 +0000210{
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000211 PyObject *os1, *os2, *result = NULL;
212 wchar_t *ws1 = NULL, *ws2 = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000213
Martin v. Löwis92fab752008-03-08 10:40:41 +0000214 if (!PyArg_ParseTuple(args, "UU:strcoll", &os1, &os2))
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000215 return NULL;
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000216 /* Convert the unicode strings to wchar[]. */
Victor Stinnerbeb4135b2010-10-07 01:02:42 +0000217 ws1 = PyUnicode_AsWideCharString(os1, NULL);
Victor Stinner449057f2010-09-29 10:30:43 +0000218 if (ws1 == NULL)
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000219 goto done;
Victor Stinnerbeb4135b2010-10-07 01:02:42 +0000220 ws2 = PyUnicode_AsWideCharString(os2, NULL);
Victor Stinner449057f2010-09-29 10:30:43 +0000221 if (ws2 == NULL)
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000222 goto done;
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000223 /* Collate the strings. */
Christian Heimes217cfd12007-12-02 14:31:20 +0000224 result = PyLong_FromLong(wcscoll(ws1, ws2));
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000225 done:
226 /* Deallocate everything. */
227 if (ws1) PyMem_FREE(ws1);
228 if (ws2) PyMem_FREE(ws2);
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000229 return result;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000230}
Martin v. Löwis92fab752008-03-08 10:40:41 +0000231#endif
Guido van Rossum220ecc81997-11-18 21:03:39 +0000232
Martin v. Löwis92fab752008-03-08 10:40:41 +0000233#ifdef HAVE_WCSXFRM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000234PyDoc_STRVAR(strxfrm__doc__,
Mark Dickinson211c6252009-02-01 10:28:51 +0000235"strxfrm(string) -> string.\n\
236\n\
237Return a string that can be used as a key for locale-aware comparisons.");
Guido van Rossum220ecc81997-11-18 21:03:39 +0000238
239static PyObject*
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000240PyLocale_strxfrm(PyObject* self, PyObject* args)
Guido van Rossum220ecc81997-11-18 21:03:39 +0000241{
Victor Stinner63649272011-09-29 23:32:06 +0200242 PyObject *str;
243 Py_ssize_t n1;
244 wchar_t *s = NULL, *buf = NULL;
245 size_t n2;
Martin v. Löwis92fab752008-03-08 10:40:41 +0000246 PyObject *result = NULL;
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000247
Victor Stinner63649272011-09-29 23:32:06 +0200248 if (!PyArg_ParseTuple(args, "U:strxfrm", &str))
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000249 return NULL;
250
Victor Stinner63649272011-09-29 23:32:06 +0200251 s = PyUnicode_AsWideCharString(str, &n1);
252 if (s == NULL)
253 goto exit;
Martin v. Löwis92fab752008-03-08 10:40:41 +0000254
255 /* assume no change in size, first */
Victor Stinner63649272011-09-29 23:32:06 +0200256 n1 = n1 + 1;
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +0200257 buf = PyMem_New(wchar_t, n1);
Martin v. Löwis92fab752008-03-08 10:40:41 +0000258 if (!buf) {
259 PyErr_NoMemory();
260 goto exit;
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000261 }
Martin v. Löwis92fab752008-03-08 10:40:41 +0000262 n2 = wcsxfrm(buf, s, n1);
Victor Stinner2c5d3cb2011-10-11 22:35:52 +0200263 if (n2 >= (size_t)n1) {
Martin v. Löwis92fab752008-03-08 10:40:41 +0000264 /* more space needed */
Kristjan Valur Jonsson85634d72012-05-31 09:37:31 +0000265 wchar_t * new_buf = PyMem_Realloc(buf, (n2+1)*sizeof(wchar_t));
266 if (!new_buf) {
Martin v. Löwis92fab752008-03-08 10:40:41 +0000267 PyErr_NoMemory();
268 goto exit;
269 }
Kristjan Valur Jonsson85634d72012-05-31 09:37:31 +0000270 buf = new_buf;
Martin v. Löwisdb1c3992009-05-23 10:38:26 +0000271 n2 = wcsxfrm(buf, s, n2+1);
Martin v. Löwis92fab752008-03-08 10:40:41 +0000272 }
273 result = PyUnicode_FromWideChar(buf, n2);
Victor Stinner63649272011-09-29 23:32:06 +0200274exit:
275 if (buf)
276 PyMem_Free(buf);
277 if (s)
278 PyMem_Free(s);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000279 return result;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000280}
Martin v. Löwis92fab752008-03-08 10:40:41 +0000281#endif
Guido van Rossum220ecc81997-11-18 21:03:39 +0000282
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000283#if defined(MS_WINDOWS)
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000284static PyObject*
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000285PyLocale_getdefaultlocale(PyObject* self)
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000286{
287 char encoding[100];
288 char locale[100];
289
Tim Peters885d4572001-11-28 20:27:42 +0000290 PyOS_snprintf(encoding, sizeof(encoding), "cp%d", GetACP());
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000291
292 if (GetLocaleInfo(LOCALE_USER_DEFAULT,
293 LOCALE_SISO639LANGNAME,
294 locale, sizeof(locale))) {
Martin v. Löwis18e16552006-02-15 17:27:45 +0000295 Py_ssize_t i = strlen(locale);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000296 locale[i++] = '_';
297 if (GetLocaleInfo(LOCALE_USER_DEFAULT,
298 LOCALE_SISO3166CTRYNAME,
Martin v. Löwis18e16552006-02-15 17:27:45 +0000299 locale+i, (int)(sizeof(locale)-i)))
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000300 return Py_BuildValue("ss", locale, encoding);
301 }
302
303 /* If we end up here, this windows version didn't know about
304 ISO639/ISO3166 names (it's probably Windows 95). Return the
305 Windows language identifier instead (a hexadecimal number) */
306
307 locale[0] = '0';
308 locale[1] = 'x';
309 if (GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_IDEFAULTLANGUAGE,
310 locale+2, sizeof(locale)-2)) {
311 return Py_BuildValue("ss", locale, encoding);
312 }
313
314 /* cannot determine the language code (very unlikely) */
315 Py_INCREF(Py_None);
316 return Py_BuildValue("Os", Py_None, encoding);
317}
318#endif
319
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000320#ifdef HAVE_LANGINFO_H
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000321#define LANGINFO(X) {#X, X}
Martin v. Löwis59683e82008-06-13 07:50:45 +0000322static struct langinfo_constant{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000323 char* name;
324 int value;
325} langinfo_constants[] =
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000326{
327 /* These constants should exist on any langinfo implementation */
328 LANGINFO(DAY_1),
329 LANGINFO(DAY_2),
330 LANGINFO(DAY_3),
331 LANGINFO(DAY_4),
332 LANGINFO(DAY_5),
333 LANGINFO(DAY_6),
334 LANGINFO(DAY_7),
335
336 LANGINFO(ABDAY_1),
337 LANGINFO(ABDAY_2),
338 LANGINFO(ABDAY_3),
339 LANGINFO(ABDAY_4),
340 LANGINFO(ABDAY_5),
341 LANGINFO(ABDAY_6),
342 LANGINFO(ABDAY_7),
343
344 LANGINFO(MON_1),
345 LANGINFO(MON_2),
346 LANGINFO(MON_3),
347 LANGINFO(MON_4),
348 LANGINFO(MON_5),
349 LANGINFO(MON_6),
350 LANGINFO(MON_7),
351 LANGINFO(MON_8),
352 LANGINFO(MON_9),
353 LANGINFO(MON_10),
354 LANGINFO(MON_11),
355 LANGINFO(MON_12),
356
357 LANGINFO(ABMON_1),
358 LANGINFO(ABMON_2),
359 LANGINFO(ABMON_3),
360 LANGINFO(ABMON_4),
361 LANGINFO(ABMON_5),
362 LANGINFO(ABMON_6),
363 LANGINFO(ABMON_7),
364 LANGINFO(ABMON_8),
365 LANGINFO(ABMON_9),
366 LANGINFO(ABMON_10),
367 LANGINFO(ABMON_11),
368 LANGINFO(ABMON_12),
369
370#ifdef RADIXCHAR
371 /* The following are not available with glibc 2.0 */
372 LANGINFO(RADIXCHAR),
373 LANGINFO(THOUSEP),
374 /* YESSTR and NOSTR are deprecated in glibc, since they are
375 a special case of message translation, which should be rather
376 done using gettext. So we don't expose it to Python in the
377 first place.
378 LANGINFO(YESSTR),
379 LANGINFO(NOSTR),
380 */
381 LANGINFO(CRNCYSTR),
382#endif
383
384 LANGINFO(D_T_FMT),
385 LANGINFO(D_FMT),
386 LANGINFO(T_FMT),
387 LANGINFO(AM_STR),
388 LANGINFO(PM_STR),
389
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000390 /* The following constants are available only with XPG4, but...
391 AIX 3.2. only has CODESET.
392 OpenBSD doesn't have CODESET but has T_FMT_AMPM, and doesn't have
393 a few of the others.
394 Solution: ifdef-test them all. */
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000395#ifdef CODESET
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000396 LANGINFO(CODESET),
Martin v. Löwis496f9e42002-03-27 12:15:57 +0000397#endif
398#ifdef T_FMT_AMPM
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000399 LANGINFO(T_FMT_AMPM),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000400#endif
401#ifdef ERA
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000402 LANGINFO(ERA),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000403#endif
404#ifdef ERA_D_FMT
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000405 LANGINFO(ERA_D_FMT),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000406#endif
407#ifdef ERA_D_T_FMT
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000408 LANGINFO(ERA_D_T_FMT),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000409#endif
410#ifdef ERA_T_FMT
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000411 LANGINFO(ERA_T_FMT),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000412#endif
413#ifdef ALT_DIGITS
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000414 LANGINFO(ALT_DIGITS),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000415#endif
416#ifdef YESEXPR
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000417 LANGINFO(YESEXPR),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000418#endif
419#ifdef NOEXPR
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000420 LANGINFO(NOEXPR),
421#endif
422#ifdef _DATE_FMT
423 /* This is not available in all glibc versions that have CODESET. */
424 LANGINFO(_DATE_FMT),
425#endif
426 {0, 0}
427};
428
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000429PyDoc_STRVAR(nl_langinfo__doc__,
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000430"nl_langinfo(key) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000431"Return the value for the locale information associated with key.");
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000432
433static PyObject*
434PyLocale_nl_langinfo(PyObject* self, PyObject* args)
435{
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000436 int item, i;
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000437 if (!PyArg_ParseTuple(args, "i:nl_langinfo", &item))
438 return NULL;
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000439 /* Check whether this is a supported constant. GNU libc sometimes
440 returns numeric values in the char* return value, which would
Neal Norwitz7f9d29c2007-08-26 07:21:45 +0000441 crash PyUnicode_FromString. */
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000442 for (i = 0; langinfo_constants[i].name; i++)
Hye-Shik Changc3a87b82004-03-21 19:34:30 +0000443 if (langinfo_constants[i].value == item) {
444 /* Check NULL as a workaround for GNU libc's returning NULL
445 instead of an empty string for nl_langinfo(ERA). */
446 const char *result = nl_langinfo(item);
Neal Norwitz3d7a90d2007-10-27 05:40:06 +0000447 result = result != NULL ? result : "";
Victor Stinnera9c895d2012-02-14 02:33:38 +0100448 return PyUnicode_DecodeLocale(result, NULL);
Hye-Shik Changc3a87b82004-03-21 19:34:30 +0000449 }
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000450 PyErr_SetString(PyExc_ValueError, "unsupported langinfo constant");
451 return NULL;
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000452}
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000453#endif /* HAVE_LANGINFO_H */
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000454
455#ifdef HAVE_LIBINTL_H
456
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000457PyDoc_STRVAR(gettext__doc__,
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000458"gettext(msg) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000459"Return translation of msg.");
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000460
461static PyObject*
462PyIntl_gettext(PyObject* self, PyObject *args)
463{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000464 char *in;
465 if (!PyArg_ParseTuple(args, "s", &in))
466 return 0;
Victor Stinnera9c895d2012-02-14 02:33:38 +0100467 return PyUnicode_DecodeLocale(gettext(in), NULL);
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000468}
469
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000470PyDoc_STRVAR(dgettext__doc__,
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000471"dgettext(domain, msg) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000472"Return translation of msg in domain.");
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000473
474static PyObject*
475PyIntl_dgettext(PyObject* self, PyObject *args)
476{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000477 char *domain, *in;
478 if (!PyArg_ParseTuple(args, "zs", &domain, &in))
479 return 0;
Victor Stinnera9c895d2012-02-14 02:33:38 +0100480 return PyUnicode_DecodeLocale(dgettext(domain, in), NULL);
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000481}
482
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000483PyDoc_STRVAR(dcgettext__doc__,
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000484"dcgettext(domain, msg, category) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000485"Return translation of msg in domain and category.");
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000486
487static PyObject*
488PyIntl_dcgettext(PyObject *self, PyObject *args)
489{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000490 char *domain, *msgid;
491 int category;
492 if (!PyArg_ParseTuple(args, "zsi", &domain, &msgid, &category))
493 return 0;
Victor Stinnera9c895d2012-02-14 02:33:38 +0100494 return PyUnicode_DecodeLocale(dcgettext(domain,msgid,category), NULL);
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000495}
496
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000497PyDoc_STRVAR(textdomain__doc__,
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000498"textdomain(domain) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000499"Set the C library's textdmain to domain, returning the new domain.");
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000500
501static PyObject*
502PyIntl_textdomain(PyObject* self, PyObject* args)
503{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000504 char *domain;
505 if (!PyArg_ParseTuple(args, "z", &domain))
506 return 0;
507 domain = textdomain(domain);
508 if (!domain) {
509 PyErr_SetFromErrno(PyExc_OSError);
510 return NULL;
511 }
Victor Stinnera9c895d2012-02-14 02:33:38 +0100512 return PyUnicode_DecodeLocale(domain, NULL);
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000513}
514
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000515PyDoc_STRVAR(bindtextdomain__doc__,
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000516"bindtextdomain(domain, dir) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000517"Bind the C library's domain to dir.");
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000518
519static PyObject*
520PyIntl_bindtextdomain(PyObject* self,PyObject*args)
521{
Victor Stinner9e19ca42010-06-11 22:09:51 +0000522 char *domain, *dirname, *current_dirname;
523 PyObject *dirname_obj, *dirname_bytes = NULL, *result;
524 if (!PyArg_ParseTuple(args, "sO", &domain, &dirname_obj))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000525 return 0;
526 if (!strlen(domain)) {
527 PyErr_SetString(Error, "domain must be a non-empty string");
528 return 0;
529 }
Victor Stinner9e19ca42010-06-11 22:09:51 +0000530 if (dirname_obj != Py_None) {
531 if (!PyUnicode_FSConverter(dirname_obj, &dirname_bytes))
532 return NULL;
533 dirname = PyBytes_AsString(dirname_bytes);
534 } else {
535 dirname_bytes = NULL;
536 dirname = NULL;
537 }
538 current_dirname = bindtextdomain(domain, dirname);
539 if (current_dirname == NULL) {
540 Py_XDECREF(dirname_bytes);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000541 PyErr_SetFromErrno(PyExc_OSError);
542 return NULL;
543 }
Victor Stinnera9c895d2012-02-14 02:33:38 +0100544 result = PyUnicode_DecodeLocale(current_dirname, NULL);
Victor Stinner9e19ca42010-06-11 22:09:51 +0000545 Py_XDECREF(dirname_bytes);
546 return result;
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000547}
548
Gustavo Niemeyer7bd33c52004-07-22 18:44:01 +0000549#ifdef HAVE_BIND_TEXTDOMAIN_CODESET
550PyDoc_STRVAR(bind_textdomain_codeset__doc__,
551"bind_textdomain_codeset(domain, codeset) -> string\n"
552"Bind the C library's domain to codeset.");
553
554static PyObject*
555PyIntl_bind_textdomain_codeset(PyObject* self,PyObject*args)
556{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000557 char *domain,*codeset;
558 if (!PyArg_ParseTuple(args, "sz", &domain, &codeset))
559 return NULL;
560 codeset = bind_textdomain_codeset(domain, codeset);
561 if (codeset)
Victor Stinnera9c895d2012-02-14 02:33:38 +0100562 return PyUnicode_DecodeLocale(codeset, NULL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000563 Py_RETURN_NONE;
Gustavo Niemeyer7bd33c52004-07-22 18:44:01 +0000564}
565#endif
566
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000567#endif
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000568
Guido van Rossum220ecc81997-11-18 21:03:39 +0000569static struct PyMethodDef PyLocale_Methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000570 {"setlocale", (PyCFunction) PyLocale_setlocale,
Andrew M. Kuchlinge365fb82000-08-03 02:06:16 +0000571 METH_VARARGS, setlocale__doc__},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000572 {"localeconv", (PyCFunction) PyLocale_localeconv,
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000573 METH_NOARGS, localeconv__doc__},
Martin v. Löwis92fab752008-03-08 10:40:41 +0000574#ifdef HAVE_WCSCOLL
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000575 {"strcoll", (PyCFunction) PyLocale_strcoll,
Andrew M. Kuchlinge365fb82000-08-03 02:06:16 +0000576 METH_VARARGS, strcoll__doc__},
Martin v. Löwis92fab752008-03-08 10:40:41 +0000577#endif
578#ifdef HAVE_WCSXFRM
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000579 {"strxfrm", (PyCFunction) PyLocale_strxfrm,
Andrew M. Kuchlinge365fb82000-08-03 02:06:16 +0000580 METH_VARARGS, strxfrm__doc__},
Martin v. Löwis92fab752008-03-08 10:40:41 +0000581#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000582#if defined(MS_WINDOWS)
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000583 {"_getdefaultlocale", (PyCFunction) PyLocale_getdefaultlocale, METH_NOARGS},
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000584#endif
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000585#ifdef HAVE_LANGINFO_H
586 {"nl_langinfo", (PyCFunction) PyLocale_nl_langinfo,
587 METH_VARARGS, nl_langinfo__doc__},
588#endif
Martin v. Löwisc6a7d7e2002-05-02 12:16:29 +0000589#ifdef HAVE_LIBINTL_H
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000590 {"gettext",(PyCFunction)PyIntl_gettext,METH_VARARGS,
591 gettext__doc__},
592 {"dgettext",(PyCFunction)PyIntl_dgettext,METH_VARARGS,
593 dgettext__doc__},
594 {"dcgettext",(PyCFunction)PyIntl_dcgettext,METH_VARARGS,
595 dcgettext__doc__},
596 {"textdomain",(PyCFunction)PyIntl_textdomain,METH_VARARGS,
597 textdomain__doc__},
598 {"bindtextdomain",(PyCFunction)PyIntl_bindtextdomain,METH_VARARGS,
599 bindtextdomain__doc__},
Gustavo Niemeyer7bd33c52004-07-22 18:44:01 +0000600#ifdef HAVE_BIND_TEXTDOMAIN_CODESET
601 {"bind_textdomain_codeset",(PyCFunction)PyIntl_bind_textdomain_codeset,
602 METH_VARARGS, bind_textdomain_codeset__doc__},
603#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000604#endif
Guido van Rossum220ecc81997-11-18 21:03:39 +0000605 {NULL, NULL}
606};
607
Martin v. Löwis1a214512008-06-11 05:26:20 +0000608
609static struct PyModuleDef _localemodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000610 PyModuleDef_HEAD_INIT,
611 "_locale",
612 locale__doc__,
613 -1,
614 PyLocale_Methods,
615 NULL,
616 NULL,
617 NULL,
618 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +0000619};
620
Mark Hammondfe51c6d2002-08-02 02:27:13 +0000621PyMODINIT_FUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +0000622PyInit__locale(void)
Guido van Rossum220ecc81997-11-18 21:03:39 +0000623{
Christian Heimesff4fddd2016-09-09 00:24:12 +0200624 PyObject *m;
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000625#ifdef HAVE_LANGINFO_H
626 int i;
627#endif
Guido van Rossum220ecc81997-11-18 21:03:39 +0000628
Martin v. Löwis1a214512008-06-11 05:26:20 +0000629 m = PyModule_Create(&_localemodule);
Neal Norwitz1ac754f2006-01-19 06:09:39 +0000630 if (m == NULL)
Christian Heimesff4fddd2016-09-09 00:24:12 +0200631 return NULL;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000632
Christian Heimesff4fddd2016-09-09 00:24:12 +0200633 PyModule_AddIntMacro(m, LC_CTYPE);
634 PyModule_AddIntMacro(m, LC_TIME);
635 PyModule_AddIntMacro(m, LC_COLLATE);
636 PyModule_AddIntMacro(m, LC_MONETARY);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000637
Guido van Rossum8d9c2e31997-12-09 19:35:11 +0000638#ifdef LC_MESSAGES
Christian Heimesff4fddd2016-09-09 00:24:12 +0200639 PyModule_AddIntMacro(m, LC_MESSAGES);
Guido van Rossum8d9c2e31997-12-09 19:35:11 +0000640#endif /* LC_MESSAGES */
Guido van Rossum220ecc81997-11-18 21:03:39 +0000641
Christian Heimesff4fddd2016-09-09 00:24:12 +0200642 PyModule_AddIntMacro(m, LC_NUMERIC);
643 PyModule_AddIntMacro(m, LC_ALL);
644 PyModule_AddIntMacro(m, CHAR_MAX);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000645
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000646 Error = PyErr_NewException("locale.Error", NULL, NULL);
Christian Heimesff4fddd2016-09-09 00:24:12 +0200647 if (Error == NULL) {
648 Py_DECREF(m);
649 return NULL;
650 }
651 PyModule_AddObject(m, "Error", Error);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000652
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000653#ifdef HAVE_LANGINFO_H
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000654 for (i = 0; langinfo_constants[i].name; i++) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000655 PyModule_AddIntConstant(m, langinfo_constants[i].name,
656 langinfo_constants[i].value);
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000657 }
Martin v. Löwisf95dd0a2001-08-15 17:14:33 +0000658#endif
Christian Heimesff4fddd2016-09-09 00:24:12 +0200659
660 if (PyErr_Occurred()) {
661 Py_DECREF(m);
662 return NULL;
663 }
Martin v. Löwis1a214512008-06-11 05:26:20 +0000664 return m;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000665}
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000666
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000667/*
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000668Local variables:
669c-basic-offset: 4
670indent-tabs-mode: nil
671End:
672*/