blob: ecd673e4a7dbad91ea143ec4f187c3abedbbbfd3 [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
Martin Panter6d57fe12016-09-17 03:26:16 +000057 if (s[0] == '\0') {
Fredrik Lundh8f017a02000-07-08 19:57:37 +000058 /* empty string: no grouping at all */
59 return PyList_New(0);
Martin Panter6d57fe12016-09-17 03:26:16 +000060 }
Fredrik Lundh8f017a02000-07-08 19:57:37 +000061
62 for (i = 0; s[i] != '\0' && s[i] != CHAR_MAX; i++)
63 ; /* nothing */
64
65 result = PyList_New(i+1);
66 if (!result)
67 return NULL;
68
69 i = -1;
70 do {
71 i++;
Christian Heimes217cfd12007-12-02 14:31:20 +000072 val = PyLong_FromLong(s[i]);
Fredrik Lundh8f017a02000-07-08 19:57:37 +000073 if (!val)
74 break;
75 if (PyList_SetItem(result, i, val)) {
76 Py_DECREF(val);
Fredrik Lundh89610a42000-07-08 20:07:24 +000077 val = NULL;
Fredrik Lundh8f017a02000-07-08 19:57:37 +000078 break;
79 }
80 } while (s[i] != '\0' && s[i] != CHAR_MAX);
81
82 if (!val) {
83 Py_DECREF(result);
84 return NULL;
Guido van Rossum220ecc81997-11-18 21:03:39 +000085 }
Fredrik Lundh8f017a02000-07-08 19:57:37 +000086
87 return result;
Guido van Rossum220ecc81997-11-18 21:03:39 +000088}
89
Guido van Rossum220ecc81997-11-18 21:03:39 +000090static PyObject*
Fredrik Lundh8f017a02000-07-08 19:57:37 +000091PyLocale_setlocale(PyObject* self, PyObject* args)
Guido van Rossum220ecc81997-11-18 21:03:39 +000092{
Fredrik Lundh8f017a02000-07-08 19:57:37 +000093 int category;
94 char *locale = NULL, *result;
95 PyObject *result_object;
Guido van Rossum220ecc81997-11-18 21:03:39 +000096
Fredrik Lundh8f017a02000-07-08 19:57:37 +000097 if (!PyArg_ParseTuple(args, "i|z:setlocale", &category, &locale))
Fredrik Lundh89610a42000-07-08 20:07:24 +000098 return NULL;
Fredrik Lundh8f017a02000-07-08 19:57:37 +000099
Amaury Forgeot d'Arc64f3ca42009-12-01 21:59:18 +0000100#if defined(MS_WINDOWS)
101 if (category < LC_MIN || category > LC_MAX)
102 {
103 PyErr_SetString(Error, "invalid locale category");
104 return NULL;
105 }
106#endif
107
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000108 if (locale) {
109 /* set locale */
110 result = setlocale(category, locale);
111 if (!result) {
112 /* operation failed, no setting was changed */
Martin v. Löwis25f90d52003-09-03 04:50:13 +0000113 PyErr_SetString(Error, "unsupported locale setting");
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000114 return NULL;
115 }
Victor Stinnera9c895d2012-02-14 02:33:38 +0100116 result_object = PyUnicode_DecodeLocale(result, NULL);
Mark Hammond9a714752003-07-24 14:15:07 +0000117 if (!result_object)
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000118 return NULL;
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000119 } else {
120 /* get locale */
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000121 result = setlocale(category, NULL);
122 if (!result) {
123 PyErr_SetString(Error, "locale query failed");
124 return NULL;
125 }
Victor Stinnera9c895d2012-02-14 02:33:38 +0100126 result_object = PyUnicode_DecodeLocale(result, NULL);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000127 }
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000128 return result_object;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000129}
130
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000131PyDoc_STRVAR(localeconv__doc__,
132"() -> dict. Returns numeric and monetary locale-specific parameters.");
Guido van Rossum220ecc81997-11-18 21:03:39 +0000133
134static PyObject*
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000135PyLocale_localeconv(PyObject* self)
Guido van Rossum220ecc81997-11-18 21:03:39 +0000136{
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000137 PyObject* result;
138 struct lconv *l;
139 PyObject *x;
140
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000141 result = PyDict_New();
Fredrik Lundh89610a42000-07-08 20:07:24 +0000142 if (!result)
143 return NULL;
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000144
145 /* if LC_NUMERIC is different in the C library, use saved value */
146 l = localeconv();
147
148 /* hopefully, the localeconv result survives the C library calls
149 involved herein */
150
Victor Stinnerd594f242013-07-17 00:55:57 +0200151#define RESULT(key, obj)\
152 do { \
153 if (obj == NULL) \
154 goto failed; \
Victor Stinnerf38a5c22013-10-29 19:28:20 +0100155 if (PyDict_SetItemString(result, key, obj) < 0) { \
156 Py_DECREF(obj); \
Victor Stinnerd594f242013-07-17 00:55:57 +0200157 goto failed; \
Victor Stinnerf38a5c22013-10-29 19:28:20 +0100158 } \
Victor Stinnerd594f242013-07-17 00:55:57 +0200159 Py_DECREF(obj); \
160 } while (0)
161
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000162#define RESULT_STRING(s)\
Victor Stinnerd594f242013-07-17 00:55:57 +0200163 do { \
164 x = PyUnicode_DecodeLocale(l->s, NULL); \
165 RESULT(#s, x); \
166 } while (0)
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000167
168#define RESULT_INT(i)\
Victor Stinnerd594f242013-07-17 00:55:57 +0200169 do { \
170 x = PyLong_FromLong(l->i); \
171 RESULT(#i, x); \
172 } while (0)
Guido van Rossum220ecc81997-11-18 21:03:39 +0000173
174 /* Numeric information */
Martin v. Löwis737ea822004-06-08 18:52:54 +0000175 RESULT_STRING(decimal_point);
176 RESULT_STRING(thousands_sep);
177 x = copy_grouping(l->grouping);
Victor Stinnerd594f242013-07-17 00:55:57 +0200178 RESULT("grouping", x);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000179
180 /* Monetary information */
181 RESULT_STRING(int_curr_symbol);
182 RESULT_STRING(currency_symbol);
183 RESULT_STRING(mon_decimal_point);
184 RESULT_STRING(mon_thousands_sep);
185 x = copy_grouping(l->mon_grouping);
Victor Stinnerd594f242013-07-17 00:55:57 +0200186 RESULT("mon_grouping", x);
187
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000188 RESULT_STRING(positive_sign);
189 RESULT_STRING(negative_sign);
190 RESULT_INT(int_frac_digits);
191 RESULT_INT(frac_digits);
192 RESULT_INT(p_cs_precedes);
193 RESULT_INT(p_sep_by_space);
194 RESULT_INT(n_cs_precedes);
195 RESULT_INT(n_sep_by_space);
196 RESULT_INT(p_sign_posn);
197 RESULT_INT(n_sign_posn);
198 return result;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000199
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000200 failed:
201 Py_XDECREF(result);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000202 return NULL;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000203}
204
Martin v. Löwis92fab752008-03-08 10:40:41 +0000205#if defined(HAVE_WCSCOLL)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000206PyDoc_STRVAR(strcoll__doc__,
207"string,string -> int. Compares two strings according to the locale.");
Guido van Rossum220ecc81997-11-18 21:03:39 +0000208
209static PyObject*
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000210PyLocale_strcoll(PyObject* self, PyObject* args)
Guido van Rossum220ecc81997-11-18 21:03:39 +0000211{
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000212 PyObject *os1, *os2, *result = NULL;
213 wchar_t *ws1 = NULL, *ws2 = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000214
Martin v. Löwis92fab752008-03-08 10:40:41 +0000215 if (!PyArg_ParseTuple(args, "UU:strcoll", &os1, &os2))
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000216 return NULL;
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000217 /* Convert the unicode strings to wchar[]. */
Victor Stinnerbeb4135b2010-10-07 01:02:42 +0000218 ws1 = PyUnicode_AsWideCharString(os1, NULL);
Victor Stinner449057f2010-09-29 10:30:43 +0000219 if (ws1 == NULL)
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000220 goto done;
Victor Stinnerbeb4135b2010-10-07 01:02:42 +0000221 ws2 = PyUnicode_AsWideCharString(os2, NULL);
Victor Stinner449057f2010-09-29 10:30:43 +0000222 if (ws2 == NULL)
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000223 goto done;
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000224 /* Collate the strings. */
Christian Heimes217cfd12007-12-02 14:31:20 +0000225 result = PyLong_FromLong(wcscoll(ws1, ws2));
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000226 done:
227 /* Deallocate everything. */
228 if (ws1) PyMem_FREE(ws1);
229 if (ws2) PyMem_FREE(ws2);
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000230 return result;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000231}
Martin v. Löwis92fab752008-03-08 10:40:41 +0000232#endif
Guido van Rossum220ecc81997-11-18 21:03:39 +0000233
Martin v. Löwis92fab752008-03-08 10:40:41 +0000234#ifdef HAVE_WCSXFRM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000235PyDoc_STRVAR(strxfrm__doc__,
Mark Dickinson211c6252009-02-01 10:28:51 +0000236"strxfrm(string) -> string.\n\
237\n\
238Return a string that can be used as a key for locale-aware comparisons.");
Guido van Rossum220ecc81997-11-18 21:03:39 +0000239
240static PyObject*
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000241PyLocale_strxfrm(PyObject* self, PyObject* args)
Guido van Rossum220ecc81997-11-18 21:03:39 +0000242{
Victor Stinner63649272011-09-29 23:32:06 +0200243 PyObject *str;
244 Py_ssize_t n1;
245 wchar_t *s = NULL, *buf = NULL;
246 size_t n2;
Martin v. Löwis92fab752008-03-08 10:40:41 +0000247 PyObject *result = NULL;
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000248
Victor Stinner63649272011-09-29 23:32:06 +0200249 if (!PyArg_ParseTuple(args, "U:strxfrm", &str))
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000250 return NULL;
251
Victor Stinner63649272011-09-29 23:32:06 +0200252 s = PyUnicode_AsWideCharString(str, &n1);
253 if (s == NULL)
254 goto exit;
Martin v. Löwis92fab752008-03-08 10:40:41 +0000255
256 /* assume no change in size, first */
Victor Stinner63649272011-09-29 23:32:06 +0200257 n1 = n1 + 1;
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +0200258 buf = PyMem_New(wchar_t, n1);
Martin v. Löwis92fab752008-03-08 10:40:41 +0000259 if (!buf) {
260 PyErr_NoMemory();
261 goto exit;
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000262 }
Serhiy Storchakabe487a62017-03-06 21:21:41 +0200263 errno = 0;
Martin v. Löwis92fab752008-03-08 10:40:41 +0000264 n2 = wcsxfrm(buf, s, n1);
Benjamin Petersonad4a0cc2017-03-07 22:24:44 -0800265 if (errno && errno != ERANGE) {
Serhiy Storchakabe487a62017-03-06 21:21:41 +0200266 PyErr_SetFromErrno(PyExc_OSError);
267 goto exit;
268 }
Victor Stinner2c5d3cb2011-10-11 22:35:52 +0200269 if (n2 >= (size_t)n1) {
Martin v. Löwis92fab752008-03-08 10:40:41 +0000270 /* more space needed */
Kristjan Valur Jonsson85634d72012-05-31 09:37:31 +0000271 wchar_t * new_buf = PyMem_Realloc(buf, (n2+1)*sizeof(wchar_t));
272 if (!new_buf) {
Martin v. Löwis92fab752008-03-08 10:40:41 +0000273 PyErr_NoMemory();
274 goto exit;
275 }
Kristjan Valur Jonsson85634d72012-05-31 09:37:31 +0000276 buf = new_buf;
Serhiy Storchakabe487a62017-03-06 21:21:41 +0200277 errno = 0;
Martin v. Löwisdb1c3992009-05-23 10:38:26 +0000278 n2 = wcsxfrm(buf, s, n2+1);
Serhiy Storchakabe487a62017-03-06 21:21:41 +0200279 if (errno) {
280 PyErr_SetFromErrno(PyExc_OSError);
281 goto exit;
282 }
Martin v. Löwis92fab752008-03-08 10:40:41 +0000283 }
284 result = PyUnicode_FromWideChar(buf, n2);
Victor Stinner63649272011-09-29 23:32:06 +0200285exit:
Serhiy Storchakabe487a62017-03-06 21:21:41 +0200286 PyMem_Free(buf);
287 PyMem_Free(s);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000288 return result;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000289}
Martin v. Löwis92fab752008-03-08 10:40:41 +0000290#endif
Guido van Rossum220ecc81997-11-18 21:03:39 +0000291
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000292#if defined(MS_WINDOWS)
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000293static PyObject*
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000294PyLocale_getdefaultlocale(PyObject* self)
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000295{
296 char encoding[100];
297 char locale[100];
298
Tim Peters885d4572001-11-28 20:27:42 +0000299 PyOS_snprintf(encoding, sizeof(encoding), "cp%d", GetACP());
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000300
301 if (GetLocaleInfo(LOCALE_USER_DEFAULT,
302 LOCALE_SISO639LANGNAME,
303 locale, sizeof(locale))) {
Martin v. Löwis18e16552006-02-15 17:27:45 +0000304 Py_ssize_t i = strlen(locale);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000305 locale[i++] = '_';
306 if (GetLocaleInfo(LOCALE_USER_DEFAULT,
307 LOCALE_SISO3166CTRYNAME,
Martin v. Löwis18e16552006-02-15 17:27:45 +0000308 locale+i, (int)(sizeof(locale)-i)))
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000309 return Py_BuildValue("ss", locale, encoding);
310 }
311
312 /* If we end up here, this windows version didn't know about
313 ISO639/ISO3166 names (it's probably Windows 95). Return the
314 Windows language identifier instead (a hexadecimal number) */
315
316 locale[0] = '0';
317 locale[1] = 'x';
318 if (GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_IDEFAULTLANGUAGE,
319 locale+2, sizeof(locale)-2)) {
320 return Py_BuildValue("ss", locale, encoding);
321 }
322
323 /* cannot determine the language code (very unlikely) */
324 Py_INCREF(Py_None);
325 return Py_BuildValue("Os", Py_None, encoding);
326}
327#endif
328
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000329#ifdef HAVE_LANGINFO_H
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000330#define LANGINFO(X) {#X, X}
Martin v. Löwis59683e82008-06-13 07:50:45 +0000331static struct langinfo_constant{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000332 char* name;
333 int value;
334} langinfo_constants[] =
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000335{
336 /* These constants should exist on any langinfo implementation */
337 LANGINFO(DAY_1),
338 LANGINFO(DAY_2),
339 LANGINFO(DAY_3),
340 LANGINFO(DAY_4),
341 LANGINFO(DAY_5),
342 LANGINFO(DAY_6),
343 LANGINFO(DAY_7),
344
345 LANGINFO(ABDAY_1),
346 LANGINFO(ABDAY_2),
347 LANGINFO(ABDAY_3),
348 LANGINFO(ABDAY_4),
349 LANGINFO(ABDAY_5),
350 LANGINFO(ABDAY_6),
351 LANGINFO(ABDAY_7),
352
353 LANGINFO(MON_1),
354 LANGINFO(MON_2),
355 LANGINFO(MON_3),
356 LANGINFO(MON_4),
357 LANGINFO(MON_5),
358 LANGINFO(MON_6),
359 LANGINFO(MON_7),
360 LANGINFO(MON_8),
361 LANGINFO(MON_9),
362 LANGINFO(MON_10),
363 LANGINFO(MON_11),
364 LANGINFO(MON_12),
365
366 LANGINFO(ABMON_1),
367 LANGINFO(ABMON_2),
368 LANGINFO(ABMON_3),
369 LANGINFO(ABMON_4),
370 LANGINFO(ABMON_5),
371 LANGINFO(ABMON_6),
372 LANGINFO(ABMON_7),
373 LANGINFO(ABMON_8),
374 LANGINFO(ABMON_9),
375 LANGINFO(ABMON_10),
376 LANGINFO(ABMON_11),
377 LANGINFO(ABMON_12),
378
379#ifdef RADIXCHAR
380 /* The following are not available with glibc 2.0 */
381 LANGINFO(RADIXCHAR),
382 LANGINFO(THOUSEP),
383 /* YESSTR and NOSTR are deprecated in glibc, since they are
384 a special case of message translation, which should be rather
385 done using gettext. So we don't expose it to Python in the
386 first place.
387 LANGINFO(YESSTR),
388 LANGINFO(NOSTR),
389 */
390 LANGINFO(CRNCYSTR),
391#endif
392
393 LANGINFO(D_T_FMT),
394 LANGINFO(D_FMT),
395 LANGINFO(T_FMT),
396 LANGINFO(AM_STR),
397 LANGINFO(PM_STR),
398
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000399 /* The following constants are available only with XPG4, but...
400 AIX 3.2. only has CODESET.
401 OpenBSD doesn't have CODESET but has T_FMT_AMPM, and doesn't have
402 a few of the others.
403 Solution: ifdef-test them all. */
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000404#ifdef CODESET
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000405 LANGINFO(CODESET),
Martin v. Löwis496f9e42002-03-27 12:15:57 +0000406#endif
407#ifdef T_FMT_AMPM
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000408 LANGINFO(T_FMT_AMPM),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000409#endif
410#ifdef ERA
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000411 LANGINFO(ERA),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000412#endif
413#ifdef ERA_D_FMT
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000414 LANGINFO(ERA_D_FMT),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000415#endif
416#ifdef ERA_D_T_FMT
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000417 LANGINFO(ERA_D_T_FMT),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000418#endif
419#ifdef ERA_T_FMT
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000420 LANGINFO(ERA_T_FMT),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000421#endif
422#ifdef ALT_DIGITS
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000423 LANGINFO(ALT_DIGITS),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000424#endif
425#ifdef YESEXPR
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000426 LANGINFO(YESEXPR),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000427#endif
428#ifdef NOEXPR
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000429 LANGINFO(NOEXPR),
430#endif
431#ifdef _DATE_FMT
432 /* This is not available in all glibc versions that have CODESET. */
433 LANGINFO(_DATE_FMT),
434#endif
435 {0, 0}
436};
437
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000438PyDoc_STRVAR(nl_langinfo__doc__,
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000439"nl_langinfo(key) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000440"Return the value for the locale information associated with key.");
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000441
442static PyObject*
443PyLocale_nl_langinfo(PyObject* self, PyObject* args)
444{
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000445 int item, i;
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000446 if (!PyArg_ParseTuple(args, "i:nl_langinfo", &item))
447 return NULL;
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000448 /* Check whether this is a supported constant. GNU libc sometimes
449 returns numeric values in the char* return value, which would
Neal Norwitz7f9d29c2007-08-26 07:21:45 +0000450 crash PyUnicode_FromString. */
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000451 for (i = 0; langinfo_constants[i].name; i++)
Hye-Shik Changc3a87b82004-03-21 19:34:30 +0000452 if (langinfo_constants[i].value == item) {
453 /* Check NULL as a workaround for GNU libc's returning NULL
454 instead of an empty string for nl_langinfo(ERA). */
455 const char *result = nl_langinfo(item);
Neal Norwitz3d7a90d2007-10-27 05:40:06 +0000456 result = result != NULL ? result : "";
Victor Stinnera9c895d2012-02-14 02:33:38 +0100457 return PyUnicode_DecodeLocale(result, NULL);
Hye-Shik Changc3a87b82004-03-21 19:34:30 +0000458 }
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000459 PyErr_SetString(PyExc_ValueError, "unsupported langinfo constant");
460 return NULL;
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000461}
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000462#endif /* HAVE_LANGINFO_H */
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000463
464#ifdef HAVE_LIBINTL_H
465
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000466PyDoc_STRVAR(gettext__doc__,
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000467"gettext(msg) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000468"Return translation of msg.");
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000469
470static PyObject*
471PyIntl_gettext(PyObject* self, PyObject *args)
472{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000473 char *in;
474 if (!PyArg_ParseTuple(args, "s", &in))
475 return 0;
Victor Stinnera9c895d2012-02-14 02:33:38 +0100476 return PyUnicode_DecodeLocale(gettext(in), NULL);
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000477}
478
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000479PyDoc_STRVAR(dgettext__doc__,
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000480"dgettext(domain, msg) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000481"Return translation of msg in domain.");
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000482
483static PyObject*
484PyIntl_dgettext(PyObject* self, PyObject *args)
485{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000486 char *domain, *in;
487 if (!PyArg_ParseTuple(args, "zs", &domain, &in))
488 return 0;
Victor Stinnera9c895d2012-02-14 02:33:38 +0100489 return PyUnicode_DecodeLocale(dgettext(domain, in), NULL);
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000490}
491
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000492PyDoc_STRVAR(dcgettext__doc__,
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000493"dcgettext(domain, msg, category) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000494"Return translation of msg in domain and category.");
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000495
496static PyObject*
497PyIntl_dcgettext(PyObject *self, PyObject *args)
498{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000499 char *domain, *msgid;
500 int category;
501 if (!PyArg_ParseTuple(args, "zsi", &domain, &msgid, &category))
502 return 0;
Victor Stinnera9c895d2012-02-14 02:33:38 +0100503 return PyUnicode_DecodeLocale(dcgettext(domain,msgid,category), NULL);
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000504}
505
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000506PyDoc_STRVAR(textdomain__doc__,
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000507"textdomain(domain) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000508"Set the C library's textdmain to domain, returning the new domain.");
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000509
510static PyObject*
511PyIntl_textdomain(PyObject* self, PyObject* args)
512{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000513 char *domain;
514 if (!PyArg_ParseTuple(args, "z", &domain))
515 return 0;
516 domain = textdomain(domain);
517 if (!domain) {
518 PyErr_SetFromErrno(PyExc_OSError);
519 return NULL;
520 }
Victor Stinnera9c895d2012-02-14 02:33:38 +0100521 return PyUnicode_DecodeLocale(domain, NULL);
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000522}
523
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000524PyDoc_STRVAR(bindtextdomain__doc__,
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000525"bindtextdomain(domain, dir) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000526"Bind the C library's domain to dir.");
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000527
528static PyObject*
529PyIntl_bindtextdomain(PyObject* self,PyObject*args)
530{
Victor Stinner9e19ca42010-06-11 22:09:51 +0000531 char *domain, *dirname, *current_dirname;
532 PyObject *dirname_obj, *dirname_bytes = NULL, *result;
533 if (!PyArg_ParseTuple(args, "sO", &domain, &dirname_obj))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000534 return 0;
535 if (!strlen(domain)) {
536 PyErr_SetString(Error, "domain must be a non-empty string");
537 return 0;
538 }
Victor Stinner9e19ca42010-06-11 22:09:51 +0000539 if (dirname_obj != Py_None) {
540 if (!PyUnicode_FSConverter(dirname_obj, &dirname_bytes))
541 return NULL;
542 dirname = PyBytes_AsString(dirname_bytes);
543 } else {
544 dirname_bytes = NULL;
545 dirname = NULL;
546 }
547 current_dirname = bindtextdomain(domain, dirname);
548 if (current_dirname == NULL) {
549 Py_XDECREF(dirname_bytes);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000550 PyErr_SetFromErrno(PyExc_OSError);
551 return NULL;
552 }
Victor Stinnera9c895d2012-02-14 02:33:38 +0100553 result = PyUnicode_DecodeLocale(current_dirname, NULL);
Victor Stinner9e19ca42010-06-11 22:09:51 +0000554 Py_XDECREF(dirname_bytes);
555 return result;
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000556}
557
Gustavo Niemeyer7bd33c52004-07-22 18:44:01 +0000558#ifdef HAVE_BIND_TEXTDOMAIN_CODESET
559PyDoc_STRVAR(bind_textdomain_codeset__doc__,
560"bind_textdomain_codeset(domain, codeset) -> string\n"
561"Bind the C library's domain to codeset.");
562
563static PyObject*
564PyIntl_bind_textdomain_codeset(PyObject* self,PyObject*args)
565{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000566 char *domain,*codeset;
567 if (!PyArg_ParseTuple(args, "sz", &domain, &codeset))
568 return NULL;
569 codeset = bind_textdomain_codeset(domain, codeset);
570 if (codeset)
Victor Stinnera9c895d2012-02-14 02:33:38 +0100571 return PyUnicode_DecodeLocale(codeset, NULL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000572 Py_RETURN_NONE;
Gustavo Niemeyer7bd33c52004-07-22 18:44:01 +0000573}
574#endif
575
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000576#endif
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000577
Guido van Rossum220ecc81997-11-18 21:03:39 +0000578static struct PyMethodDef PyLocale_Methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000579 {"setlocale", (PyCFunction) PyLocale_setlocale,
Andrew M. Kuchlinge365fb82000-08-03 02:06:16 +0000580 METH_VARARGS, setlocale__doc__},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000581 {"localeconv", (PyCFunction) PyLocale_localeconv,
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000582 METH_NOARGS, localeconv__doc__},
Martin v. Löwis92fab752008-03-08 10:40:41 +0000583#ifdef HAVE_WCSCOLL
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000584 {"strcoll", (PyCFunction) PyLocale_strcoll,
Andrew M. Kuchlinge365fb82000-08-03 02:06:16 +0000585 METH_VARARGS, strcoll__doc__},
Martin v. Löwis92fab752008-03-08 10:40:41 +0000586#endif
587#ifdef HAVE_WCSXFRM
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000588 {"strxfrm", (PyCFunction) PyLocale_strxfrm,
Andrew M. Kuchlinge365fb82000-08-03 02:06:16 +0000589 METH_VARARGS, strxfrm__doc__},
Martin v. Löwis92fab752008-03-08 10:40:41 +0000590#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000591#if defined(MS_WINDOWS)
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000592 {"_getdefaultlocale", (PyCFunction) PyLocale_getdefaultlocale, METH_NOARGS},
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000593#endif
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000594#ifdef HAVE_LANGINFO_H
595 {"nl_langinfo", (PyCFunction) PyLocale_nl_langinfo,
596 METH_VARARGS, nl_langinfo__doc__},
597#endif
Martin v. Löwisc6a7d7e2002-05-02 12:16:29 +0000598#ifdef HAVE_LIBINTL_H
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000599 {"gettext",(PyCFunction)PyIntl_gettext,METH_VARARGS,
600 gettext__doc__},
601 {"dgettext",(PyCFunction)PyIntl_dgettext,METH_VARARGS,
602 dgettext__doc__},
603 {"dcgettext",(PyCFunction)PyIntl_dcgettext,METH_VARARGS,
604 dcgettext__doc__},
605 {"textdomain",(PyCFunction)PyIntl_textdomain,METH_VARARGS,
606 textdomain__doc__},
607 {"bindtextdomain",(PyCFunction)PyIntl_bindtextdomain,METH_VARARGS,
608 bindtextdomain__doc__},
Gustavo Niemeyer7bd33c52004-07-22 18:44:01 +0000609#ifdef HAVE_BIND_TEXTDOMAIN_CODESET
610 {"bind_textdomain_codeset",(PyCFunction)PyIntl_bind_textdomain_codeset,
611 METH_VARARGS, bind_textdomain_codeset__doc__},
612#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000613#endif
Guido van Rossum220ecc81997-11-18 21:03:39 +0000614 {NULL, NULL}
615};
616
Martin v. Löwis1a214512008-06-11 05:26:20 +0000617
618static struct PyModuleDef _localemodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000619 PyModuleDef_HEAD_INIT,
620 "_locale",
621 locale__doc__,
622 -1,
623 PyLocale_Methods,
624 NULL,
625 NULL,
626 NULL,
627 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +0000628};
629
Mark Hammondfe51c6d2002-08-02 02:27:13 +0000630PyMODINIT_FUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +0000631PyInit__locale(void)
Guido van Rossum220ecc81997-11-18 21:03:39 +0000632{
Christian Heimesff4fddd2016-09-09 00:24:12 +0200633 PyObject *m;
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000634#ifdef HAVE_LANGINFO_H
635 int i;
636#endif
Guido van Rossum220ecc81997-11-18 21:03:39 +0000637
Martin v. Löwis1a214512008-06-11 05:26:20 +0000638 m = PyModule_Create(&_localemodule);
Neal Norwitz1ac754f2006-01-19 06:09:39 +0000639 if (m == NULL)
Christian Heimesff4fddd2016-09-09 00:24:12 +0200640 return NULL;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000641
Christian Heimesff4fddd2016-09-09 00:24:12 +0200642 PyModule_AddIntMacro(m, LC_CTYPE);
643 PyModule_AddIntMacro(m, LC_TIME);
644 PyModule_AddIntMacro(m, LC_COLLATE);
645 PyModule_AddIntMacro(m, LC_MONETARY);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000646
Guido van Rossum8d9c2e31997-12-09 19:35:11 +0000647#ifdef LC_MESSAGES
Christian Heimesff4fddd2016-09-09 00:24:12 +0200648 PyModule_AddIntMacro(m, LC_MESSAGES);
Guido van Rossum8d9c2e31997-12-09 19:35:11 +0000649#endif /* LC_MESSAGES */
Guido van Rossum220ecc81997-11-18 21:03:39 +0000650
Christian Heimesff4fddd2016-09-09 00:24:12 +0200651 PyModule_AddIntMacro(m, LC_NUMERIC);
652 PyModule_AddIntMacro(m, LC_ALL);
653 PyModule_AddIntMacro(m, CHAR_MAX);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000654
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000655 Error = PyErr_NewException("locale.Error", NULL, NULL);
Christian Heimesff4fddd2016-09-09 00:24:12 +0200656 if (Error == NULL) {
657 Py_DECREF(m);
658 return NULL;
659 }
660 PyModule_AddObject(m, "Error", Error);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000661
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000662#ifdef HAVE_LANGINFO_H
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000663 for (i = 0; langinfo_constants[i].name; i++) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000664 PyModule_AddIntConstant(m, langinfo_constants[i].name,
665 langinfo_constants[i].value);
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000666 }
Martin v. Löwisf95dd0a2001-08-15 17:14:33 +0000667#endif
Christian Heimesff4fddd2016-09-09 00:24:12 +0200668
669 if (PyErr_Occurred()) {
670 Py_DECREF(m);
671 return NULL;
672 }
Martin v. Löwis1a214512008-06-11 05:26:20 +0000673 return m;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000674}
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000675
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000676/*
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000677Local variables:
678c-basic-offset: 4
679indent-tabs-mode: nil
680End:
681*/