blob: feb38029008e304e39f69d3f85c85e525cbaf8a6 [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 }
Martin v. Löwis92fab752008-03-08 10:40:41 +0000263 n2 = wcsxfrm(buf, s, n1);
Victor Stinner2c5d3cb2011-10-11 22:35:52 +0200264 if (n2 >= (size_t)n1) {
Martin v. Löwis92fab752008-03-08 10:40:41 +0000265 /* more space needed */
Kristjan Valur Jonsson85634d72012-05-31 09:37:31 +0000266 wchar_t * new_buf = PyMem_Realloc(buf, (n2+1)*sizeof(wchar_t));
267 if (!new_buf) {
Martin v. Löwis92fab752008-03-08 10:40:41 +0000268 PyErr_NoMemory();
269 goto exit;
270 }
Kristjan Valur Jonsson85634d72012-05-31 09:37:31 +0000271 buf = new_buf;
Martin v. Löwisdb1c3992009-05-23 10:38:26 +0000272 n2 = wcsxfrm(buf, s, n2+1);
Martin v. Löwis92fab752008-03-08 10:40:41 +0000273 }
274 result = PyUnicode_FromWideChar(buf, n2);
Victor Stinner63649272011-09-29 23:32:06 +0200275exit:
276 if (buf)
277 PyMem_Free(buf);
278 if (s)
279 PyMem_Free(s);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000280 return result;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000281}
Martin v. Löwis92fab752008-03-08 10:40:41 +0000282#endif
Guido van Rossum220ecc81997-11-18 21:03:39 +0000283
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000284#if defined(MS_WINDOWS)
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000285static PyObject*
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000286PyLocale_getdefaultlocale(PyObject* self)
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000287{
288 char encoding[100];
289 char locale[100];
290
Tim Peters885d4572001-11-28 20:27:42 +0000291 PyOS_snprintf(encoding, sizeof(encoding), "cp%d", GetACP());
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000292
293 if (GetLocaleInfo(LOCALE_USER_DEFAULT,
294 LOCALE_SISO639LANGNAME,
295 locale, sizeof(locale))) {
Martin v. Löwis18e16552006-02-15 17:27:45 +0000296 Py_ssize_t i = strlen(locale);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000297 locale[i++] = '_';
298 if (GetLocaleInfo(LOCALE_USER_DEFAULT,
299 LOCALE_SISO3166CTRYNAME,
Martin v. Löwis18e16552006-02-15 17:27:45 +0000300 locale+i, (int)(sizeof(locale)-i)))
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000301 return Py_BuildValue("ss", locale, encoding);
302 }
303
304 /* If we end up here, this windows version didn't know about
305 ISO639/ISO3166 names (it's probably Windows 95). Return the
306 Windows language identifier instead (a hexadecimal number) */
307
308 locale[0] = '0';
309 locale[1] = 'x';
310 if (GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_IDEFAULTLANGUAGE,
311 locale+2, sizeof(locale)-2)) {
312 return Py_BuildValue("ss", locale, encoding);
313 }
314
315 /* cannot determine the language code (very unlikely) */
316 Py_INCREF(Py_None);
317 return Py_BuildValue("Os", Py_None, encoding);
318}
319#endif
320
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000321#ifdef HAVE_LANGINFO_H
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000322#define LANGINFO(X) {#X, X}
Martin v. Löwis59683e82008-06-13 07:50:45 +0000323static struct langinfo_constant{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000324 char* name;
325 int value;
326} langinfo_constants[] =
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000327{
328 /* These constants should exist on any langinfo implementation */
329 LANGINFO(DAY_1),
330 LANGINFO(DAY_2),
331 LANGINFO(DAY_3),
332 LANGINFO(DAY_4),
333 LANGINFO(DAY_5),
334 LANGINFO(DAY_6),
335 LANGINFO(DAY_7),
336
337 LANGINFO(ABDAY_1),
338 LANGINFO(ABDAY_2),
339 LANGINFO(ABDAY_3),
340 LANGINFO(ABDAY_4),
341 LANGINFO(ABDAY_5),
342 LANGINFO(ABDAY_6),
343 LANGINFO(ABDAY_7),
344
345 LANGINFO(MON_1),
346 LANGINFO(MON_2),
347 LANGINFO(MON_3),
348 LANGINFO(MON_4),
349 LANGINFO(MON_5),
350 LANGINFO(MON_6),
351 LANGINFO(MON_7),
352 LANGINFO(MON_8),
353 LANGINFO(MON_9),
354 LANGINFO(MON_10),
355 LANGINFO(MON_11),
356 LANGINFO(MON_12),
357
358 LANGINFO(ABMON_1),
359 LANGINFO(ABMON_2),
360 LANGINFO(ABMON_3),
361 LANGINFO(ABMON_4),
362 LANGINFO(ABMON_5),
363 LANGINFO(ABMON_6),
364 LANGINFO(ABMON_7),
365 LANGINFO(ABMON_8),
366 LANGINFO(ABMON_9),
367 LANGINFO(ABMON_10),
368 LANGINFO(ABMON_11),
369 LANGINFO(ABMON_12),
370
371#ifdef RADIXCHAR
372 /* The following are not available with glibc 2.0 */
373 LANGINFO(RADIXCHAR),
374 LANGINFO(THOUSEP),
375 /* YESSTR and NOSTR are deprecated in glibc, since they are
376 a special case of message translation, which should be rather
377 done using gettext. So we don't expose it to Python in the
378 first place.
379 LANGINFO(YESSTR),
380 LANGINFO(NOSTR),
381 */
382 LANGINFO(CRNCYSTR),
383#endif
384
385 LANGINFO(D_T_FMT),
386 LANGINFO(D_FMT),
387 LANGINFO(T_FMT),
388 LANGINFO(AM_STR),
389 LANGINFO(PM_STR),
390
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000391 /* The following constants are available only with XPG4, but...
392 AIX 3.2. only has CODESET.
393 OpenBSD doesn't have CODESET but has T_FMT_AMPM, and doesn't have
394 a few of the others.
395 Solution: ifdef-test them all. */
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000396#ifdef CODESET
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000397 LANGINFO(CODESET),
Martin v. Löwis496f9e42002-03-27 12:15:57 +0000398#endif
399#ifdef T_FMT_AMPM
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000400 LANGINFO(T_FMT_AMPM),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000401#endif
402#ifdef ERA
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000403 LANGINFO(ERA),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000404#endif
405#ifdef ERA_D_FMT
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000406 LANGINFO(ERA_D_FMT),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000407#endif
408#ifdef ERA_D_T_FMT
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000409 LANGINFO(ERA_D_T_FMT),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000410#endif
411#ifdef ERA_T_FMT
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000412 LANGINFO(ERA_T_FMT),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000413#endif
414#ifdef ALT_DIGITS
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000415 LANGINFO(ALT_DIGITS),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000416#endif
417#ifdef YESEXPR
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000418 LANGINFO(YESEXPR),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000419#endif
420#ifdef NOEXPR
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000421 LANGINFO(NOEXPR),
422#endif
423#ifdef _DATE_FMT
424 /* This is not available in all glibc versions that have CODESET. */
425 LANGINFO(_DATE_FMT),
426#endif
427 {0, 0}
428};
429
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000430PyDoc_STRVAR(nl_langinfo__doc__,
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000431"nl_langinfo(key) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000432"Return the value for the locale information associated with key.");
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000433
434static PyObject*
435PyLocale_nl_langinfo(PyObject* self, PyObject* args)
436{
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000437 int item, i;
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000438 if (!PyArg_ParseTuple(args, "i:nl_langinfo", &item))
439 return NULL;
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000440 /* Check whether this is a supported constant. GNU libc sometimes
441 returns numeric values in the char* return value, which would
Neal Norwitz7f9d29c2007-08-26 07:21:45 +0000442 crash PyUnicode_FromString. */
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000443 for (i = 0; langinfo_constants[i].name; i++)
Hye-Shik Changc3a87b82004-03-21 19:34:30 +0000444 if (langinfo_constants[i].value == item) {
445 /* Check NULL as a workaround for GNU libc's returning NULL
446 instead of an empty string for nl_langinfo(ERA). */
447 const char *result = nl_langinfo(item);
Neal Norwitz3d7a90d2007-10-27 05:40:06 +0000448 result = result != NULL ? result : "";
Victor Stinnera9c895d2012-02-14 02:33:38 +0100449 return PyUnicode_DecodeLocale(result, NULL);
Hye-Shik Changc3a87b82004-03-21 19:34:30 +0000450 }
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000451 PyErr_SetString(PyExc_ValueError, "unsupported langinfo constant");
452 return NULL;
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000453}
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000454#endif /* HAVE_LANGINFO_H */
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000455
456#ifdef HAVE_LIBINTL_H
457
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000458PyDoc_STRVAR(gettext__doc__,
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000459"gettext(msg) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000460"Return translation of msg.");
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000461
462static PyObject*
463PyIntl_gettext(PyObject* self, PyObject *args)
464{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000465 char *in;
466 if (!PyArg_ParseTuple(args, "s", &in))
467 return 0;
Victor Stinnera9c895d2012-02-14 02:33:38 +0100468 return PyUnicode_DecodeLocale(gettext(in), NULL);
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000469}
470
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000471PyDoc_STRVAR(dgettext__doc__,
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000472"dgettext(domain, msg) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000473"Return translation of msg in domain.");
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000474
475static PyObject*
476PyIntl_dgettext(PyObject* self, PyObject *args)
477{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000478 char *domain, *in;
479 if (!PyArg_ParseTuple(args, "zs", &domain, &in))
480 return 0;
Victor Stinnera9c895d2012-02-14 02:33:38 +0100481 return PyUnicode_DecodeLocale(dgettext(domain, in), NULL);
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000482}
483
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000484PyDoc_STRVAR(dcgettext__doc__,
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000485"dcgettext(domain, msg, category) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000486"Return translation of msg in domain and category.");
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000487
488static PyObject*
489PyIntl_dcgettext(PyObject *self, PyObject *args)
490{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000491 char *domain, *msgid;
492 int category;
493 if (!PyArg_ParseTuple(args, "zsi", &domain, &msgid, &category))
494 return 0;
Victor Stinnera9c895d2012-02-14 02:33:38 +0100495 return PyUnicode_DecodeLocale(dcgettext(domain,msgid,category), NULL);
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000496}
497
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000498PyDoc_STRVAR(textdomain__doc__,
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000499"textdomain(domain) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000500"Set the C library's textdmain to domain, returning the new domain.");
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000501
502static PyObject*
503PyIntl_textdomain(PyObject* self, PyObject* args)
504{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000505 char *domain;
506 if (!PyArg_ParseTuple(args, "z", &domain))
507 return 0;
508 domain = textdomain(domain);
509 if (!domain) {
510 PyErr_SetFromErrno(PyExc_OSError);
511 return NULL;
512 }
Victor Stinnera9c895d2012-02-14 02:33:38 +0100513 return PyUnicode_DecodeLocale(domain, NULL);
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000514}
515
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000516PyDoc_STRVAR(bindtextdomain__doc__,
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000517"bindtextdomain(domain, dir) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000518"Bind the C library's domain to dir.");
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000519
520static PyObject*
521PyIntl_bindtextdomain(PyObject* self,PyObject*args)
522{
Victor Stinner9e19ca42010-06-11 22:09:51 +0000523 char *domain, *dirname, *current_dirname;
524 PyObject *dirname_obj, *dirname_bytes = NULL, *result;
525 if (!PyArg_ParseTuple(args, "sO", &domain, &dirname_obj))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000526 return 0;
527 if (!strlen(domain)) {
528 PyErr_SetString(Error, "domain must be a non-empty string");
529 return 0;
530 }
Victor Stinner9e19ca42010-06-11 22:09:51 +0000531 if (dirname_obj != Py_None) {
532 if (!PyUnicode_FSConverter(dirname_obj, &dirname_bytes))
533 return NULL;
534 dirname = PyBytes_AsString(dirname_bytes);
535 } else {
536 dirname_bytes = NULL;
537 dirname = NULL;
538 }
539 current_dirname = bindtextdomain(domain, dirname);
540 if (current_dirname == NULL) {
541 Py_XDECREF(dirname_bytes);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000542 PyErr_SetFromErrno(PyExc_OSError);
543 return NULL;
544 }
Victor Stinnera9c895d2012-02-14 02:33:38 +0100545 result = PyUnicode_DecodeLocale(current_dirname, NULL);
Victor Stinner9e19ca42010-06-11 22:09:51 +0000546 Py_XDECREF(dirname_bytes);
547 return result;
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000548}
549
Gustavo Niemeyer7bd33c52004-07-22 18:44:01 +0000550#ifdef HAVE_BIND_TEXTDOMAIN_CODESET
551PyDoc_STRVAR(bind_textdomain_codeset__doc__,
552"bind_textdomain_codeset(domain, codeset) -> string\n"
553"Bind the C library's domain to codeset.");
554
555static PyObject*
556PyIntl_bind_textdomain_codeset(PyObject* self,PyObject*args)
557{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000558 char *domain,*codeset;
559 if (!PyArg_ParseTuple(args, "sz", &domain, &codeset))
560 return NULL;
561 codeset = bind_textdomain_codeset(domain, codeset);
562 if (codeset)
Victor Stinnera9c895d2012-02-14 02:33:38 +0100563 return PyUnicode_DecodeLocale(codeset, NULL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000564 Py_RETURN_NONE;
Gustavo Niemeyer7bd33c52004-07-22 18:44:01 +0000565}
566#endif
567
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000568#endif
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000569
Guido van Rossum220ecc81997-11-18 21:03:39 +0000570static struct PyMethodDef PyLocale_Methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000571 {"setlocale", (PyCFunction) PyLocale_setlocale,
Andrew M. Kuchlinge365fb82000-08-03 02:06:16 +0000572 METH_VARARGS, setlocale__doc__},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000573 {"localeconv", (PyCFunction) PyLocale_localeconv,
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000574 METH_NOARGS, localeconv__doc__},
Martin v. Löwis92fab752008-03-08 10:40:41 +0000575#ifdef HAVE_WCSCOLL
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000576 {"strcoll", (PyCFunction) PyLocale_strcoll,
Andrew M. Kuchlinge365fb82000-08-03 02:06:16 +0000577 METH_VARARGS, strcoll__doc__},
Martin v. Löwis92fab752008-03-08 10:40:41 +0000578#endif
579#ifdef HAVE_WCSXFRM
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000580 {"strxfrm", (PyCFunction) PyLocale_strxfrm,
Andrew M. Kuchlinge365fb82000-08-03 02:06:16 +0000581 METH_VARARGS, strxfrm__doc__},
Martin v. Löwis92fab752008-03-08 10:40:41 +0000582#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000583#if defined(MS_WINDOWS)
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000584 {"_getdefaultlocale", (PyCFunction) PyLocale_getdefaultlocale, METH_NOARGS},
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000585#endif
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000586#ifdef HAVE_LANGINFO_H
587 {"nl_langinfo", (PyCFunction) PyLocale_nl_langinfo,
588 METH_VARARGS, nl_langinfo__doc__},
589#endif
Martin v. Löwisc6a7d7e2002-05-02 12:16:29 +0000590#ifdef HAVE_LIBINTL_H
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000591 {"gettext",(PyCFunction)PyIntl_gettext,METH_VARARGS,
592 gettext__doc__},
593 {"dgettext",(PyCFunction)PyIntl_dgettext,METH_VARARGS,
594 dgettext__doc__},
595 {"dcgettext",(PyCFunction)PyIntl_dcgettext,METH_VARARGS,
596 dcgettext__doc__},
597 {"textdomain",(PyCFunction)PyIntl_textdomain,METH_VARARGS,
598 textdomain__doc__},
599 {"bindtextdomain",(PyCFunction)PyIntl_bindtextdomain,METH_VARARGS,
600 bindtextdomain__doc__},
Gustavo Niemeyer7bd33c52004-07-22 18:44:01 +0000601#ifdef HAVE_BIND_TEXTDOMAIN_CODESET
602 {"bind_textdomain_codeset",(PyCFunction)PyIntl_bind_textdomain_codeset,
603 METH_VARARGS, bind_textdomain_codeset__doc__},
604#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000605#endif
Guido van Rossum220ecc81997-11-18 21:03:39 +0000606 {NULL, NULL}
607};
608
Martin v. Löwis1a214512008-06-11 05:26:20 +0000609
610static struct PyModuleDef _localemodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000611 PyModuleDef_HEAD_INIT,
612 "_locale",
613 locale__doc__,
614 -1,
615 PyLocale_Methods,
616 NULL,
617 NULL,
618 NULL,
619 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +0000620};
621
Mark Hammondfe51c6d2002-08-02 02:27:13 +0000622PyMODINIT_FUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +0000623PyInit__locale(void)
Guido van Rossum220ecc81997-11-18 21:03:39 +0000624{
Christian Heimesff4fddd2016-09-09 00:24:12 +0200625 PyObject *m;
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000626#ifdef HAVE_LANGINFO_H
627 int i;
628#endif
Guido van Rossum220ecc81997-11-18 21:03:39 +0000629
Martin v. Löwis1a214512008-06-11 05:26:20 +0000630 m = PyModule_Create(&_localemodule);
Neal Norwitz1ac754f2006-01-19 06:09:39 +0000631 if (m == NULL)
Christian Heimesff4fddd2016-09-09 00:24:12 +0200632 return NULL;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000633
Christian Heimesff4fddd2016-09-09 00:24:12 +0200634 PyModule_AddIntMacro(m, LC_CTYPE);
635 PyModule_AddIntMacro(m, LC_TIME);
636 PyModule_AddIntMacro(m, LC_COLLATE);
637 PyModule_AddIntMacro(m, LC_MONETARY);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000638
Guido van Rossum8d9c2e31997-12-09 19:35:11 +0000639#ifdef LC_MESSAGES
Christian Heimesff4fddd2016-09-09 00:24:12 +0200640 PyModule_AddIntMacro(m, LC_MESSAGES);
Guido van Rossum8d9c2e31997-12-09 19:35:11 +0000641#endif /* LC_MESSAGES */
Guido van Rossum220ecc81997-11-18 21:03:39 +0000642
Christian Heimesff4fddd2016-09-09 00:24:12 +0200643 PyModule_AddIntMacro(m, LC_NUMERIC);
644 PyModule_AddIntMacro(m, LC_ALL);
645 PyModule_AddIntMacro(m, CHAR_MAX);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000646
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000647 Error = PyErr_NewException("locale.Error", NULL, NULL);
Christian Heimesff4fddd2016-09-09 00:24:12 +0200648 if (Error == NULL) {
649 Py_DECREF(m);
650 return NULL;
651 }
652 PyModule_AddObject(m, "Error", Error);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000653
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000654#ifdef HAVE_LANGINFO_H
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000655 for (i = 0; langinfo_constants[i].name; i++) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000656 PyModule_AddIntConstant(m, langinfo_constants[i].name,
657 langinfo_constants[i].value);
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000658 }
Martin v. Löwisf95dd0a2001-08-15 17:14:33 +0000659#endif
Christian Heimesff4fddd2016-09-09 00:24:12 +0200660
661 if (PyErr_Occurred()) {
662 Py_DECREF(m);
663 return NULL;
664 }
Martin v. Löwis1a214512008-06-11 05:26:20 +0000665 return m;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000666}
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000667
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000668/*
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000669Local variables:
670c-basic-offset: 4
671indent-tabs-mode: nil
672End:
673*/