blob: e364668d3dd681feae44090a5c77574dba881f84 [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;
Serhiy Storchakaf7eae0a2017-06-28 08:30:06 +0300255 if (wcslen(s) != (size_t)n1) {
256 PyErr_SetString(PyExc_ValueError,
257 "embedded null character");
258 goto exit;
259 }
Martin v. Löwis92fab752008-03-08 10:40:41 +0000260
261 /* assume no change in size, first */
Victor Stinner63649272011-09-29 23:32:06 +0200262 n1 = n1 + 1;
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +0200263 buf = PyMem_New(wchar_t, n1);
Martin v. Löwis92fab752008-03-08 10:40:41 +0000264 if (!buf) {
265 PyErr_NoMemory();
266 goto exit;
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000267 }
Serhiy Storchakabe487a62017-03-06 21:21:41 +0200268 errno = 0;
Martin v. Löwis92fab752008-03-08 10:40:41 +0000269 n2 = wcsxfrm(buf, s, n1);
Benjamin Petersonad4a0cc2017-03-07 22:24:44 -0800270 if (errno && errno != ERANGE) {
Serhiy Storchakabe487a62017-03-06 21:21:41 +0200271 PyErr_SetFromErrno(PyExc_OSError);
272 goto exit;
273 }
Victor Stinner2c5d3cb2011-10-11 22:35:52 +0200274 if (n2 >= (size_t)n1) {
Martin v. Löwis92fab752008-03-08 10:40:41 +0000275 /* more space needed */
Kristjan Valur Jonsson85634d72012-05-31 09:37:31 +0000276 wchar_t * new_buf = PyMem_Realloc(buf, (n2+1)*sizeof(wchar_t));
277 if (!new_buf) {
Martin v. Löwis92fab752008-03-08 10:40:41 +0000278 PyErr_NoMemory();
279 goto exit;
280 }
Kristjan Valur Jonsson85634d72012-05-31 09:37:31 +0000281 buf = new_buf;
Serhiy Storchakabe487a62017-03-06 21:21:41 +0200282 errno = 0;
Martin v. Löwisdb1c3992009-05-23 10:38:26 +0000283 n2 = wcsxfrm(buf, s, n2+1);
Serhiy Storchakabe487a62017-03-06 21:21:41 +0200284 if (errno) {
285 PyErr_SetFromErrno(PyExc_OSError);
286 goto exit;
287 }
Martin v. Löwis92fab752008-03-08 10:40:41 +0000288 }
289 result = PyUnicode_FromWideChar(buf, n2);
Victor Stinner63649272011-09-29 23:32:06 +0200290exit:
Serhiy Storchakabe487a62017-03-06 21:21:41 +0200291 PyMem_Free(buf);
292 PyMem_Free(s);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000293 return result;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000294}
Martin v. Löwis92fab752008-03-08 10:40:41 +0000295#endif
Guido van Rossum220ecc81997-11-18 21:03:39 +0000296
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000297#if defined(MS_WINDOWS)
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000298static PyObject*
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000299PyLocale_getdefaultlocale(PyObject* self)
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000300{
301 char encoding[100];
302 char locale[100];
303
Tim Peters885d4572001-11-28 20:27:42 +0000304 PyOS_snprintf(encoding, sizeof(encoding), "cp%d", GetACP());
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000305
306 if (GetLocaleInfo(LOCALE_USER_DEFAULT,
307 LOCALE_SISO639LANGNAME,
308 locale, sizeof(locale))) {
Martin v. Löwis18e16552006-02-15 17:27:45 +0000309 Py_ssize_t i = strlen(locale);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000310 locale[i++] = '_';
311 if (GetLocaleInfo(LOCALE_USER_DEFAULT,
312 LOCALE_SISO3166CTRYNAME,
Martin v. Löwis18e16552006-02-15 17:27:45 +0000313 locale+i, (int)(sizeof(locale)-i)))
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000314 return Py_BuildValue("ss", locale, encoding);
315 }
316
317 /* If we end up here, this windows version didn't know about
318 ISO639/ISO3166 names (it's probably Windows 95). Return the
319 Windows language identifier instead (a hexadecimal number) */
320
321 locale[0] = '0';
322 locale[1] = 'x';
323 if (GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_IDEFAULTLANGUAGE,
324 locale+2, sizeof(locale)-2)) {
325 return Py_BuildValue("ss", locale, encoding);
326 }
327
328 /* cannot determine the language code (very unlikely) */
329 Py_INCREF(Py_None);
330 return Py_BuildValue("Os", Py_None, encoding);
331}
332#endif
333
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000334#ifdef HAVE_LANGINFO_H
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000335#define LANGINFO(X) {#X, X}
Martin v. Löwis59683e82008-06-13 07:50:45 +0000336static struct langinfo_constant{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000337 char* name;
338 int value;
339} langinfo_constants[] =
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000340{
341 /* These constants should exist on any langinfo implementation */
342 LANGINFO(DAY_1),
343 LANGINFO(DAY_2),
344 LANGINFO(DAY_3),
345 LANGINFO(DAY_4),
346 LANGINFO(DAY_5),
347 LANGINFO(DAY_6),
348 LANGINFO(DAY_7),
349
350 LANGINFO(ABDAY_1),
351 LANGINFO(ABDAY_2),
352 LANGINFO(ABDAY_3),
353 LANGINFO(ABDAY_4),
354 LANGINFO(ABDAY_5),
355 LANGINFO(ABDAY_6),
356 LANGINFO(ABDAY_7),
357
358 LANGINFO(MON_1),
359 LANGINFO(MON_2),
360 LANGINFO(MON_3),
361 LANGINFO(MON_4),
362 LANGINFO(MON_5),
363 LANGINFO(MON_6),
364 LANGINFO(MON_7),
365 LANGINFO(MON_8),
366 LANGINFO(MON_9),
367 LANGINFO(MON_10),
368 LANGINFO(MON_11),
369 LANGINFO(MON_12),
370
371 LANGINFO(ABMON_1),
372 LANGINFO(ABMON_2),
373 LANGINFO(ABMON_3),
374 LANGINFO(ABMON_4),
375 LANGINFO(ABMON_5),
376 LANGINFO(ABMON_6),
377 LANGINFO(ABMON_7),
378 LANGINFO(ABMON_8),
379 LANGINFO(ABMON_9),
380 LANGINFO(ABMON_10),
381 LANGINFO(ABMON_11),
382 LANGINFO(ABMON_12),
383
384#ifdef RADIXCHAR
385 /* The following are not available with glibc 2.0 */
386 LANGINFO(RADIXCHAR),
387 LANGINFO(THOUSEP),
388 /* YESSTR and NOSTR are deprecated in glibc, since they are
389 a special case of message translation, which should be rather
390 done using gettext. So we don't expose it to Python in the
391 first place.
392 LANGINFO(YESSTR),
393 LANGINFO(NOSTR),
394 */
395 LANGINFO(CRNCYSTR),
396#endif
397
398 LANGINFO(D_T_FMT),
399 LANGINFO(D_FMT),
400 LANGINFO(T_FMT),
401 LANGINFO(AM_STR),
402 LANGINFO(PM_STR),
403
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000404 /* The following constants are available only with XPG4, but...
405 AIX 3.2. only has CODESET.
406 OpenBSD doesn't have CODESET but has T_FMT_AMPM, and doesn't have
407 a few of the others.
408 Solution: ifdef-test them all. */
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000409#ifdef CODESET
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000410 LANGINFO(CODESET),
Martin v. Löwis496f9e42002-03-27 12:15:57 +0000411#endif
412#ifdef T_FMT_AMPM
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000413 LANGINFO(T_FMT_AMPM),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000414#endif
415#ifdef ERA
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000416 LANGINFO(ERA),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000417#endif
418#ifdef ERA_D_FMT
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000419 LANGINFO(ERA_D_FMT),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000420#endif
421#ifdef ERA_D_T_FMT
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000422 LANGINFO(ERA_D_T_FMT),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000423#endif
424#ifdef ERA_T_FMT
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000425 LANGINFO(ERA_T_FMT),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000426#endif
427#ifdef ALT_DIGITS
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000428 LANGINFO(ALT_DIGITS),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000429#endif
430#ifdef YESEXPR
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000431 LANGINFO(YESEXPR),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000432#endif
433#ifdef NOEXPR
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000434 LANGINFO(NOEXPR),
435#endif
436#ifdef _DATE_FMT
437 /* This is not available in all glibc versions that have CODESET. */
438 LANGINFO(_DATE_FMT),
439#endif
440 {0, 0}
441};
442
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000443PyDoc_STRVAR(nl_langinfo__doc__,
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000444"nl_langinfo(key) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000445"Return the value for the locale information associated with key.");
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000446
447static PyObject*
448PyLocale_nl_langinfo(PyObject* self, PyObject* args)
449{
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000450 int item, i;
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000451 if (!PyArg_ParseTuple(args, "i:nl_langinfo", &item))
452 return NULL;
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000453 /* Check whether this is a supported constant. GNU libc sometimes
454 returns numeric values in the char* return value, which would
Neal Norwitz7f9d29c2007-08-26 07:21:45 +0000455 crash PyUnicode_FromString. */
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000456 for (i = 0; langinfo_constants[i].name; i++)
Hye-Shik Changc3a87b82004-03-21 19:34:30 +0000457 if (langinfo_constants[i].value == item) {
458 /* Check NULL as a workaround for GNU libc's returning NULL
459 instead of an empty string for nl_langinfo(ERA). */
460 const char *result = nl_langinfo(item);
Neal Norwitz3d7a90d2007-10-27 05:40:06 +0000461 result = result != NULL ? result : "";
Victor Stinnera9c895d2012-02-14 02:33:38 +0100462 return PyUnicode_DecodeLocale(result, NULL);
Hye-Shik Changc3a87b82004-03-21 19:34:30 +0000463 }
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000464 PyErr_SetString(PyExc_ValueError, "unsupported langinfo constant");
465 return NULL;
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000466}
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000467#endif /* HAVE_LANGINFO_H */
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000468
469#ifdef HAVE_LIBINTL_H
470
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000471PyDoc_STRVAR(gettext__doc__,
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000472"gettext(msg) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000473"Return translation of msg.");
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000474
475static PyObject*
476PyIntl_gettext(PyObject* self, PyObject *args)
477{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000478 char *in;
479 if (!PyArg_ParseTuple(args, "s", &in))
480 return 0;
Victor Stinnera9c895d2012-02-14 02:33:38 +0100481 return PyUnicode_DecodeLocale(gettext(in), NULL);
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000482}
483
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000484PyDoc_STRVAR(dgettext__doc__,
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000485"dgettext(domain, msg) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000486"Return translation of msg in domain.");
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000487
488static PyObject*
489PyIntl_dgettext(PyObject* self, PyObject *args)
490{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000491 char *domain, *in;
492 if (!PyArg_ParseTuple(args, "zs", &domain, &in))
493 return 0;
Victor Stinnera9c895d2012-02-14 02:33:38 +0100494 return PyUnicode_DecodeLocale(dgettext(domain, in), NULL);
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000495}
496
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000497PyDoc_STRVAR(dcgettext__doc__,
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000498"dcgettext(domain, msg, category) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000499"Return translation of msg in domain and category.");
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000500
501static PyObject*
502PyIntl_dcgettext(PyObject *self, PyObject *args)
503{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000504 char *domain, *msgid;
505 int category;
506 if (!PyArg_ParseTuple(args, "zsi", &domain, &msgid, &category))
507 return 0;
Victor Stinnera9c895d2012-02-14 02:33:38 +0100508 return PyUnicode_DecodeLocale(dcgettext(domain,msgid,category), NULL);
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000509}
510
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000511PyDoc_STRVAR(textdomain__doc__,
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000512"textdomain(domain) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000513"Set the C library's textdmain to domain, returning the new domain.");
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000514
515static PyObject*
516PyIntl_textdomain(PyObject* self, PyObject* args)
517{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000518 char *domain;
519 if (!PyArg_ParseTuple(args, "z", &domain))
520 return 0;
521 domain = textdomain(domain);
522 if (!domain) {
523 PyErr_SetFromErrno(PyExc_OSError);
524 return NULL;
525 }
Victor Stinnera9c895d2012-02-14 02:33:38 +0100526 return PyUnicode_DecodeLocale(domain, NULL);
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000527}
528
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000529PyDoc_STRVAR(bindtextdomain__doc__,
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000530"bindtextdomain(domain, dir) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000531"Bind the C library's domain to dir.");
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000532
533static PyObject*
534PyIntl_bindtextdomain(PyObject* self,PyObject*args)
535{
Victor Stinner9e19ca42010-06-11 22:09:51 +0000536 char *domain, *dirname, *current_dirname;
537 PyObject *dirname_obj, *dirname_bytes = NULL, *result;
538 if (!PyArg_ParseTuple(args, "sO", &domain, &dirname_obj))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000539 return 0;
540 if (!strlen(domain)) {
541 PyErr_SetString(Error, "domain must be a non-empty string");
542 return 0;
543 }
Victor Stinner9e19ca42010-06-11 22:09:51 +0000544 if (dirname_obj != Py_None) {
545 if (!PyUnicode_FSConverter(dirname_obj, &dirname_bytes))
546 return NULL;
547 dirname = PyBytes_AsString(dirname_bytes);
548 } else {
549 dirname_bytes = NULL;
550 dirname = NULL;
551 }
552 current_dirname = bindtextdomain(domain, dirname);
553 if (current_dirname == NULL) {
554 Py_XDECREF(dirname_bytes);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000555 PyErr_SetFromErrno(PyExc_OSError);
556 return NULL;
557 }
Victor Stinnera9c895d2012-02-14 02:33:38 +0100558 result = PyUnicode_DecodeLocale(current_dirname, NULL);
Victor Stinner9e19ca42010-06-11 22:09:51 +0000559 Py_XDECREF(dirname_bytes);
560 return result;
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000561}
562
Gustavo Niemeyer7bd33c52004-07-22 18:44:01 +0000563#ifdef HAVE_BIND_TEXTDOMAIN_CODESET
564PyDoc_STRVAR(bind_textdomain_codeset__doc__,
565"bind_textdomain_codeset(domain, codeset) -> string\n"
566"Bind the C library's domain to codeset.");
567
568static PyObject*
569PyIntl_bind_textdomain_codeset(PyObject* self,PyObject*args)
570{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000571 char *domain,*codeset;
572 if (!PyArg_ParseTuple(args, "sz", &domain, &codeset))
573 return NULL;
574 codeset = bind_textdomain_codeset(domain, codeset);
575 if (codeset)
Victor Stinnera9c895d2012-02-14 02:33:38 +0100576 return PyUnicode_DecodeLocale(codeset, NULL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000577 Py_RETURN_NONE;
Gustavo Niemeyer7bd33c52004-07-22 18:44:01 +0000578}
579#endif
580
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000581#endif
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000582
Guido van Rossum220ecc81997-11-18 21:03:39 +0000583static struct PyMethodDef PyLocale_Methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000584 {"setlocale", (PyCFunction) PyLocale_setlocale,
Andrew M. Kuchlinge365fb82000-08-03 02:06:16 +0000585 METH_VARARGS, setlocale__doc__},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000586 {"localeconv", (PyCFunction) PyLocale_localeconv,
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000587 METH_NOARGS, localeconv__doc__},
Martin v. Löwis92fab752008-03-08 10:40:41 +0000588#ifdef HAVE_WCSCOLL
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000589 {"strcoll", (PyCFunction) PyLocale_strcoll,
Andrew M. Kuchlinge365fb82000-08-03 02:06:16 +0000590 METH_VARARGS, strcoll__doc__},
Martin v. Löwis92fab752008-03-08 10:40:41 +0000591#endif
592#ifdef HAVE_WCSXFRM
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000593 {"strxfrm", (PyCFunction) PyLocale_strxfrm,
Andrew M. Kuchlinge365fb82000-08-03 02:06:16 +0000594 METH_VARARGS, strxfrm__doc__},
Martin v. Löwis92fab752008-03-08 10:40:41 +0000595#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000596#if defined(MS_WINDOWS)
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000597 {"_getdefaultlocale", (PyCFunction) PyLocale_getdefaultlocale, METH_NOARGS},
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000598#endif
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000599#ifdef HAVE_LANGINFO_H
600 {"nl_langinfo", (PyCFunction) PyLocale_nl_langinfo,
601 METH_VARARGS, nl_langinfo__doc__},
602#endif
Martin v. Löwisc6a7d7e2002-05-02 12:16:29 +0000603#ifdef HAVE_LIBINTL_H
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000604 {"gettext",(PyCFunction)PyIntl_gettext,METH_VARARGS,
605 gettext__doc__},
606 {"dgettext",(PyCFunction)PyIntl_dgettext,METH_VARARGS,
607 dgettext__doc__},
608 {"dcgettext",(PyCFunction)PyIntl_dcgettext,METH_VARARGS,
609 dcgettext__doc__},
610 {"textdomain",(PyCFunction)PyIntl_textdomain,METH_VARARGS,
611 textdomain__doc__},
612 {"bindtextdomain",(PyCFunction)PyIntl_bindtextdomain,METH_VARARGS,
613 bindtextdomain__doc__},
Gustavo Niemeyer7bd33c52004-07-22 18:44:01 +0000614#ifdef HAVE_BIND_TEXTDOMAIN_CODESET
615 {"bind_textdomain_codeset",(PyCFunction)PyIntl_bind_textdomain_codeset,
616 METH_VARARGS, bind_textdomain_codeset__doc__},
617#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000618#endif
Guido van Rossum220ecc81997-11-18 21:03:39 +0000619 {NULL, NULL}
620};
621
Martin v. Löwis1a214512008-06-11 05:26:20 +0000622
623static struct PyModuleDef _localemodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000624 PyModuleDef_HEAD_INIT,
625 "_locale",
626 locale__doc__,
627 -1,
628 PyLocale_Methods,
629 NULL,
630 NULL,
631 NULL,
632 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +0000633};
634
Mark Hammondfe51c6d2002-08-02 02:27:13 +0000635PyMODINIT_FUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +0000636PyInit__locale(void)
Guido van Rossum220ecc81997-11-18 21:03:39 +0000637{
Christian Heimesff4fddd2016-09-09 00:24:12 +0200638 PyObject *m;
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000639#ifdef HAVE_LANGINFO_H
640 int i;
641#endif
Guido van Rossum220ecc81997-11-18 21:03:39 +0000642
Martin v. Löwis1a214512008-06-11 05:26:20 +0000643 m = PyModule_Create(&_localemodule);
Neal Norwitz1ac754f2006-01-19 06:09:39 +0000644 if (m == NULL)
Christian Heimesff4fddd2016-09-09 00:24:12 +0200645 return NULL;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000646
Christian Heimesff4fddd2016-09-09 00:24:12 +0200647 PyModule_AddIntMacro(m, LC_CTYPE);
648 PyModule_AddIntMacro(m, LC_TIME);
649 PyModule_AddIntMacro(m, LC_COLLATE);
650 PyModule_AddIntMacro(m, LC_MONETARY);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000651
Guido van Rossum8d9c2e31997-12-09 19:35:11 +0000652#ifdef LC_MESSAGES
Christian Heimesff4fddd2016-09-09 00:24:12 +0200653 PyModule_AddIntMacro(m, LC_MESSAGES);
Guido van Rossum8d9c2e31997-12-09 19:35:11 +0000654#endif /* LC_MESSAGES */
Guido van Rossum220ecc81997-11-18 21:03:39 +0000655
Christian Heimesff4fddd2016-09-09 00:24:12 +0200656 PyModule_AddIntMacro(m, LC_NUMERIC);
657 PyModule_AddIntMacro(m, LC_ALL);
658 PyModule_AddIntMacro(m, CHAR_MAX);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000659
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000660 Error = PyErr_NewException("locale.Error", NULL, NULL);
Christian Heimesff4fddd2016-09-09 00:24:12 +0200661 if (Error == NULL) {
662 Py_DECREF(m);
663 return NULL;
664 }
665 PyModule_AddObject(m, "Error", Error);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000666
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000667#ifdef HAVE_LANGINFO_H
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000668 for (i = 0; langinfo_constants[i].name; i++) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000669 PyModule_AddIntConstant(m, langinfo_constants[i].name,
670 langinfo_constants[i].value);
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000671 }
Martin v. Löwisf95dd0a2001-08-15 17:14:33 +0000672#endif
Christian Heimesff4fddd2016-09-09 00:24:12 +0200673
674 if (PyErr_Occurred()) {
675 Py_DECREF(m);
676 return NULL;
677 }
Martin v. Löwis1a214512008-06-11 05:26:20 +0000678 return m;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000679}
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000680
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000681/*
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000682Local variables:
683c-basic-offset: 4
684indent-tabs-mode: nil
685End:
686*/