blob: c215ef3475fed86b79de9f1fb5b33c4c218734ba [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
Fred Drake68933b92000-08-10 21:41:08 +000012#include "Python.h"
13
Guido van Rossum220ecc81997-11-18 21:03:39 +000014#include <stdio.h>
Guido van Rossum220ecc81997-11-18 21:03:39 +000015#include <locale.h>
16#include <string.h>
Guido van Rossum5cd70f41998-06-19 04:33:30 +000017#include <ctype.h>
Fredrik Lundh8f017a02000-07-08 19:57:37 +000018
Thomas Wouters0e3f5912006-08-11 14:57:12 +000019#ifdef HAVE_ERRNO_H
Thomas Wouters477c8d52006-05-27 19:21:47 +000020#include <errno.h>
21#endif
22
Martin v. Löwis9b75dca2001-08-10 13:58:50 +000023#ifdef HAVE_LANGINFO_H
24#include <langinfo.h>
25#endif
26
Martin v. Löwis2e64c342002-03-27 18:49:02 +000027#ifdef HAVE_LIBINTL_H
28#include <libintl.h>
29#endif
30
Martin v. Löwis9c36c292002-12-21 18:34:06 +000031#ifdef HAVE_WCHAR_H
32#include <wchar.h>
33#endif
34
Jack Jansen7107c1a2003-11-20 13:31:00 +000035#if defined(__APPLE__)
Jack Jansen59f072a2004-07-15 13:31:39 +000036#include <CoreFoundation/CoreFoundation.h>
Jack Jansen7107c1a2003-11-20 13:31:00 +000037#endif
38
Martin v. Löwis6238d2b2002-06-30 15:26:10 +000039#if defined(MS_WINDOWS)
Tim Peters7a1f9172002-07-14 22:14:19 +000040#define WIN32_LEAN_AND_MEAN
Fredrik Lundh8f017a02000-07-08 19:57:37 +000041#include <windows.h>
Guido van Rossum239a2181998-04-28 16:08:19 +000042#endif
Guido van Rossum220ecc81997-11-18 21:03:39 +000043
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000044PyDoc_STRVAR(locale__doc__, "Support for POSIX locales.");
Guido van Rossum220ecc81997-11-18 21:03:39 +000045
46static PyObject *Error;
47
Martin v. Löwis92fab752008-03-08 10:40:41 +000048/* Convert a char* to a Unicode object according to the current locale */
49static PyObject*
50str2uni(const char* s)
51{
Antoine Pitroufff95302008-09-03 18:58:51 +000052#ifdef HAVE_BROKEN_MBSTOWCS
53 size_t needed = strlen(s);
54#else
Martin v. Löwis92fab752008-03-08 10:40:41 +000055 size_t needed = mbstowcs(NULL, s, 0);
Antoine Pitroufff95302008-09-03 18:58:51 +000056#endif
Martin v. Löwis92fab752008-03-08 10:40:41 +000057 size_t res1;
58 wchar_t smallbuf[30];
59 wchar_t *dest;
60 PyObject *res2;
61 if (needed == (size_t)-1) {
62 PyErr_SetString(PyExc_ValueError, "Cannot convert byte to string");
63 return NULL;
64 }
Martin v. Löwis5bacec12008-03-08 13:39:58 +000065 if (needed*sizeof(wchar_t) < sizeof(smallbuf))
Martin v. Löwis92fab752008-03-08 10:40:41 +000066 dest = smallbuf;
67 else {
Martin v. Löwisa69e1ef2008-03-08 10:54:31 +000068 dest = PyMem_Malloc((needed+1)*sizeof(wchar_t));
Martin v. Löwis92fab752008-03-08 10:40:41 +000069 if (!dest)
70 return PyErr_NoMemory();
71 }
72 /* This shouldn't fail now */
73 res1 = mbstowcs(dest, s, needed+1);
Antoine Pitroufff95302008-09-03 18:58:51 +000074#ifdef HAVE_BROKEN_MBSTOWCS
75 assert(res1 != (size_t)-1);
76#else
Martin v. Löwisce7a1122008-03-08 10:59:49 +000077 assert(res1 == needed);
Antoine Pitroufff95302008-09-03 18:58:51 +000078#endif
Martin v. Löwis92fab752008-03-08 10:40:41 +000079 res2 = PyUnicode_FromWideChar(dest, res1);
80 if (dest != smallbuf)
81 PyMem_Free(dest);
82 return res2;
83}
84
Guido van Rossum220ecc81997-11-18 21:03:39 +000085/* support functions for formatting floating point numbers */
86
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000087PyDoc_STRVAR(setlocale__doc__,
88"(integer,string=None) -> string. Activates/queries locale processing.");
Guido van Rossum220ecc81997-11-18 21:03:39 +000089
Guido van Rossum220ecc81997-11-18 21:03:39 +000090/* the grouping is terminated by either 0 or CHAR_MAX */
91static PyObject*
Fredrik Lundh8f017a02000-07-08 19:57:37 +000092copy_grouping(char* s)
Guido van Rossum220ecc81997-11-18 21:03:39 +000093{
Fredrik Lundh8f017a02000-07-08 19:57:37 +000094 int i;
95 PyObject *result, *val = NULL;
96
97 if (s[0] == '\0')
98 /* empty string: no grouping at all */
99 return PyList_New(0);
100
101 for (i = 0; s[i] != '\0' && s[i] != CHAR_MAX; i++)
102 ; /* nothing */
103
104 result = PyList_New(i+1);
105 if (!result)
106 return NULL;
107
108 i = -1;
109 do {
110 i++;
Christian Heimes217cfd12007-12-02 14:31:20 +0000111 val = PyLong_FromLong(s[i]);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000112 if (!val)
113 break;
114 if (PyList_SetItem(result, i, val)) {
115 Py_DECREF(val);
Fredrik Lundh89610a42000-07-08 20:07:24 +0000116 val = NULL;
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000117 break;
118 }
119 } while (s[i] != '\0' && s[i] != CHAR_MAX);
120
121 if (!val) {
122 Py_DECREF(result);
123 return NULL;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000124 }
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000125
126 return result;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000127}
128
Guido van Rossum220ecc81997-11-18 21:03:39 +0000129static PyObject*
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000130PyLocale_setlocale(PyObject* self, PyObject* args)
Guido van Rossum220ecc81997-11-18 21:03:39 +0000131{
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000132 int category;
133 char *locale = NULL, *result;
134 PyObject *result_object;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000135
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000136 if (!PyArg_ParseTuple(args, "i|z:setlocale", &category, &locale))
Fredrik Lundh89610a42000-07-08 20:07:24 +0000137 return NULL;
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000138
139 if (locale) {
140 /* set locale */
141 result = setlocale(category, locale);
142 if (!result) {
143 /* operation failed, no setting was changed */
Martin v. Löwis25f90d52003-09-03 04:50:13 +0000144 PyErr_SetString(Error, "unsupported locale setting");
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000145 return NULL;
146 }
Martin v. Löwis92fab752008-03-08 10:40:41 +0000147 result_object = str2uni(result);
Mark Hammond9a714752003-07-24 14:15:07 +0000148 if (!result_object)
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000149 return NULL;
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000150 } else {
151 /* get locale */
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000152 result = setlocale(category, NULL);
153 if (!result) {
154 PyErr_SetString(Error, "locale query failed");
155 return NULL;
156 }
Martin v. Löwis92fab752008-03-08 10:40:41 +0000157 result_object = str2uni(result);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000158 }
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000159 return result_object;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000160}
161
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000162PyDoc_STRVAR(localeconv__doc__,
163"() -> dict. Returns numeric and monetary locale-specific parameters.");
Guido van Rossum220ecc81997-11-18 21:03:39 +0000164
165static PyObject*
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000166PyLocale_localeconv(PyObject* self)
Guido van Rossum220ecc81997-11-18 21:03:39 +0000167{
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000168 PyObject* result;
169 struct lconv *l;
170 PyObject *x;
171
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000172 result = PyDict_New();
Fredrik Lundh89610a42000-07-08 20:07:24 +0000173 if (!result)
174 return NULL;
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000175
176 /* if LC_NUMERIC is different in the C library, use saved value */
177 l = localeconv();
178
179 /* hopefully, the localeconv result survives the C library calls
180 involved herein */
181
182#define RESULT_STRING(s)\
Martin v. Löwis92fab752008-03-08 10:40:41 +0000183 x = str2uni(l->s); \
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000184 if (!x) goto failed;\
185 PyDict_SetItemString(result, #s, x);\
186 Py_XDECREF(x)
187
188#define RESULT_INT(i)\
Christian Heimes217cfd12007-12-02 14:31:20 +0000189 x = PyLong_FromLong(l->i);\
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000190 if (!x) goto failed;\
191 PyDict_SetItemString(result, #i, x);\
192 Py_XDECREF(x)
Guido van Rossum220ecc81997-11-18 21:03:39 +0000193
194 /* Numeric information */
Martin v. Löwis737ea822004-06-08 18:52:54 +0000195 RESULT_STRING(decimal_point);
196 RESULT_STRING(thousands_sep);
197 x = copy_grouping(l->grouping);
198 if (!x)
199 goto failed;
200 PyDict_SetItemString(result, "grouping", x);
201 Py_XDECREF(x);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000202
203 /* Monetary information */
204 RESULT_STRING(int_curr_symbol);
205 RESULT_STRING(currency_symbol);
206 RESULT_STRING(mon_decimal_point);
207 RESULT_STRING(mon_thousands_sep);
208 x = copy_grouping(l->mon_grouping);
209 if (!x)
210 goto failed;
211 PyDict_SetItemString(result, "mon_grouping", x);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000212 Py_XDECREF(x);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000213 RESULT_STRING(positive_sign);
214 RESULT_STRING(negative_sign);
215 RESULT_INT(int_frac_digits);
216 RESULT_INT(frac_digits);
217 RESULT_INT(p_cs_precedes);
218 RESULT_INT(p_sep_by_space);
219 RESULT_INT(n_cs_precedes);
220 RESULT_INT(n_sep_by_space);
221 RESULT_INT(p_sign_posn);
222 RESULT_INT(n_sign_posn);
223 return result;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000224
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000225 failed:
226 Py_XDECREF(result);
227 Py_XDECREF(x);
228 return NULL;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000229}
230
Martin v. Löwis92fab752008-03-08 10:40:41 +0000231#if defined(HAVE_WCSCOLL)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000232PyDoc_STRVAR(strcoll__doc__,
233"string,string -> int. Compares two strings according to the locale.");
Guido van Rossum220ecc81997-11-18 21:03:39 +0000234
235static PyObject*
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000236PyLocale_strcoll(PyObject* self, PyObject* args)
Guido van Rossum220ecc81997-11-18 21:03:39 +0000237{
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000238 PyObject *os1, *os2, *result = NULL;
239 wchar_t *ws1 = NULL, *ws2 = NULL;
Martin v. Löwis92fab752008-03-08 10:40:41 +0000240 Py_ssize_t len1, len2;
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000241
Martin v. Löwis92fab752008-03-08 10:40:41 +0000242 if (!PyArg_ParseTuple(args, "UU:strcoll", &os1, &os2))
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000243 return NULL;
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000244 /* Convert the unicode strings to wchar[]. */
245 len1 = PyUnicode_GET_SIZE(os1) + 1;
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000246 ws1 = PyMem_MALLOC(len1 * sizeof(wchar_t));
247 if (!ws1) {
248 PyErr_NoMemory();
249 goto done;
250 }
251 if (PyUnicode_AsWideChar((PyUnicodeObject*)os1, ws1, len1) == -1)
252 goto done;
Marc-André Lemburga9cadcd2004-11-22 13:02:31 +0000253 ws1[len1 - 1] = 0;
254 len2 = PyUnicode_GET_SIZE(os2) + 1;
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000255 ws2 = PyMem_MALLOC(len2 * sizeof(wchar_t));
256 if (!ws2) {
257 PyErr_NoMemory();
258 goto done;
259 }
260 if (PyUnicode_AsWideChar((PyUnicodeObject*)os2, ws2, len2) == -1)
261 goto done;
Marc-André Lemburga9cadcd2004-11-22 13:02:31 +0000262 ws2[len2 - 1] = 0;
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000263 /* Collate the strings. */
Christian Heimes217cfd12007-12-02 14:31:20 +0000264 result = PyLong_FromLong(wcscoll(ws1, ws2));
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000265 done:
266 /* Deallocate everything. */
267 if (ws1) PyMem_FREE(ws1);
268 if (ws2) PyMem_FREE(ws2);
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000269 return result;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000270}
Martin v. Löwis92fab752008-03-08 10:40:41 +0000271#endif
Guido van Rossum220ecc81997-11-18 21:03:39 +0000272
Martin v. Löwis92fab752008-03-08 10:40:41 +0000273#ifdef HAVE_WCSXFRM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000274PyDoc_STRVAR(strxfrm__doc__,
Mark Dickinson211c6252009-02-01 10:28:51 +0000275"strxfrm(string) -> string.\n\
276\n\
277Return a string that can be used as a key for locale-aware comparisons.");
Guido van Rossum220ecc81997-11-18 21:03:39 +0000278
279static PyObject*
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000280PyLocale_strxfrm(PyObject* self, PyObject* args)
Guido van Rossum220ecc81997-11-18 21:03:39 +0000281{
Martin v. Löwis92fab752008-03-08 10:40:41 +0000282 Py_UNICODE *s0;
283 Py_ssize_t n0;
284 wchar_t *s, *buf = NULL;
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000285 size_t n1, n2;
Martin v. Löwis92fab752008-03-08 10:40:41 +0000286 PyObject *result = NULL;
287 Py_ssize_t i;
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000288
Martin v. Löwis92fab752008-03-08 10:40:41 +0000289 if (!PyArg_ParseTuple(args, "u#:strxfrm", &s0, &n0))
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000290 return NULL;
291
Martin v. Löwis92fab752008-03-08 10:40:41 +0000292#ifdef HAVE_USABLE_WCHAR_T
293 s = s0;
294#else
Martin v. Löwisa69e1ef2008-03-08 10:54:31 +0000295 s = PyMem_Malloc((n0+1)*sizeof(wchar_t));
Martin v. Löwis92fab752008-03-08 10:40:41 +0000296 if (!s)
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000297 return PyErr_NoMemory();
Martin v. Löwis92fab752008-03-08 10:40:41 +0000298 for (i=0; i<=n0; i++)
299 s[i] = s0[i];
300#endif
301
302 /* assume no change in size, first */
303 n1 = wcslen(s) + 1;
Martin v. Löwisa69e1ef2008-03-08 10:54:31 +0000304 buf = PyMem_Malloc(n1*sizeof(wchar_t));
Martin v. Löwis92fab752008-03-08 10:40:41 +0000305 if (!buf) {
306 PyErr_NoMemory();
307 goto exit;
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000308 }
Martin v. Löwis92fab752008-03-08 10:40:41 +0000309 n2 = wcsxfrm(buf, s, n1);
310 if (n2 >= n1) {
311 /* more space needed */
Martin v. Löwisa69e1ef2008-03-08 10:54:31 +0000312 buf = PyMem_Realloc(buf, (n2+1)*sizeof(wchar_t));
Martin v. Löwis92fab752008-03-08 10:40:41 +0000313 if (!buf) {
314 PyErr_NoMemory();
315 goto exit;
316 }
Martin v. Löwisdb1c3992009-05-23 10:38:26 +0000317 n2 = wcsxfrm(buf, s, n2+1);
Martin v. Löwis92fab752008-03-08 10:40:41 +0000318 }
319 result = PyUnicode_FromWideChar(buf, n2);
320 exit:
321 if (buf) PyMem_Free(buf);
322#ifdef HAVE_USABLE_WCHAR_T
323 PyMem_Free(s);
324#endif
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000325 return result;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000326}
Martin v. Löwis92fab752008-03-08 10:40:41 +0000327#endif
Guido van Rossum220ecc81997-11-18 21:03:39 +0000328
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000329#if defined(MS_WINDOWS)
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000330static PyObject*
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000331PyLocale_getdefaultlocale(PyObject* self)
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000332{
333 char encoding[100];
334 char locale[100];
335
Tim Peters885d4572001-11-28 20:27:42 +0000336 PyOS_snprintf(encoding, sizeof(encoding), "cp%d", GetACP());
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000337
338 if (GetLocaleInfo(LOCALE_USER_DEFAULT,
339 LOCALE_SISO639LANGNAME,
340 locale, sizeof(locale))) {
Martin v. Löwis18e16552006-02-15 17:27:45 +0000341 Py_ssize_t i = strlen(locale);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000342 locale[i++] = '_';
343 if (GetLocaleInfo(LOCALE_USER_DEFAULT,
344 LOCALE_SISO3166CTRYNAME,
Martin v. Löwis18e16552006-02-15 17:27:45 +0000345 locale+i, (int)(sizeof(locale)-i)))
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000346 return Py_BuildValue("ss", locale, encoding);
347 }
348
349 /* If we end up here, this windows version didn't know about
350 ISO639/ISO3166 names (it's probably Windows 95). Return the
351 Windows language identifier instead (a hexadecimal number) */
352
353 locale[0] = '0';
354 locale[1] = 'x';
355 if (GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_IDEFAULTLANGUAGE,
356 locale+2, sizeof(locale)-2)) {
357 return Py_BuildValue("ss", locale, encoding);
358 }
359
360 /* cannot determine the language code (very unlikely) */
361 Py_INCREF(Py_None);
362 return Py_BuildValue("Os", Py_None, encoding);
363}
364#endif
365
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000366#ifdef HAVE_LANGINFO_H
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000367#define LANGINFO(X) {#X, X}
Martin v. Löwis59683e82008-06-13 07:50:45 +0000368static struct langinfo_constant{
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000369 char* name;
370 int value;
371} langinfo_constants[] =
372{
373 /* These constants should exist on any langinfo implementation */
374 LANGINFO(DAY_1),
375 LANGINFO(DAY_2),
376 LANGINFO(DAY_3),
377 LANGINFO(DAY_4),
378 LANGINFO(DAY_5),
379 LANGINFO(DAY_6),
380 LANGINFO(DAY_7),
381
382 LANGINFO(ABDAY_1),
383 LANGINFO(ABDAY_2),
384 LANGINFO(ABDAY_3),
385 LANGINFO(ABDAY_4),
386 LANGINFO(ABDAY_5),
387 LANGINFO(ABDAY_6),
388 LANGINFO(ABDAY_7),
389
390 LANGINFO(MON_1),
391 LANGINFO(MON_2),
392 LANGINFO(MON_3),
393 LANGINFO(MON_4),
394 LANGINFO(MON_5),
395 LANGINFO(MON_6),
396 LANGINFO(MON_7),
397 LANGINFO(MON_8),
398 LANGINFO(MON_9),
399 LANGINFO(MON_10),
400 LANGINFO(MON_11),
401 LANGINFO(MON_12),
402
403 LANGINFO(ABMON_1),
404 LANGINFO(ABMON_2),
405 LANGINFO(ABMON_3),
406 LANGINFO(ABMON_4),
407 LANGINFO(ABMON_5),
408 LANGINFO(ABMON_6),
409 LANGINFO(ABMON_7),
410 LANGINFO(ABMON_8),
411 LANGINFO(ABMON_9),
412 LANGINFO(ABMON_10),
413 LANGINFO(ABMON_11),
414 LANGINFO(ABMON_12),
415
416#ifdef RADIXCHAR
417 /* The following are not available with glibc 2.0 */
418 LANGINFO(RADIXCHAR),
419 LANGINFO(THOUSEP),
420 /* YESSTR and NOSTR are deprecated in glibc, since they are
421 a special case of message translation, which should be rather
422 done using gettext. So we don't expose it to Python in the
423 first place.
424 LANGINFO(YESSTR),
425 LANGINFO(NOSTR),
426 */
427 LANGINFO(CRNCYSTR),
428#endif
429
430 LANGINFO(D_T_FMT),
431 LANGINFO(D_FMT),
432 LANGINFO(T_FMT),
433 LANGINFO(AM_STR),
434 LANGINFO(PM_STR),
435
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000436 /* The following constants are available only with XPG4, but...
437 AIX 3.2. only has CODESET.
438 OpenBSD doesn't have CODESET but has T_FMT_AMPM, and doesn't have
439 a few of the others.
440 Solution: ifdef-test them all. */
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000441#ifdef CODESET
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000442 LANGINFO(CODESET),
Martin v. Löwis496f9e42002-03-27 12:15:57 +0000443#endif
444#ifdef T_FMT_AMPM
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000445 LANGINFO(T_FMT_AMPM),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000446#endif
447#ifdef ERA
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000448 LANGINFO(ERA),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000449#endif
450#ifdef ERA_D_FMT
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000451 LANGINFO(ERA_D_FMT),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000452#endif
453#ifdef ERA_D_T_FMT
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000454 LANGINFO(ERA_D_T_FMT),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000455#endif
456#ifdef ERA_T_FMT
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000457 LANGINFO(ERA_T_FMT),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000458#endif
459#ifdef ALT_DIGITS
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000460 LANGINFO(ALT_DIGITS),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000461#endif
462#ifdef YESEXPR
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000463 LANGINFO(YESEXPR),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000464#endif
465#ifdef NOEXPR
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000466 LANGINFO(NOEXPR),
467#endif
468#ifdef _DATE_FMT
469 /* This is not available in all glibc versions that have CODESET. */
470 LANGINFO(_DATE_FMT),
471#endif
472 {0, 0}
473};
474
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000475PyDoc_STRVAR(nl_langinfo__doc__,
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000476"nl_langinfo(key) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000477"Return the value for the locale information associated with key.");
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000478
479static PyObject*
480PyLocale_nl_langinfo(PyObject* self, PyObject* args)
481{
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000482 int item, i;
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000483 if (!PyArg_ParseTuple(args, "i:nl_langinfo", &item))
484 return NULL;
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000485 /* Check whether this is a supported constant. GNU libc sometimes
486 returns numeric values in the char* return value, which would
Neal Norwitz7f9d29c2007-08-26 07:21:45 +0000487 crash PyUnicode_FromString. */
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000488 for (i = 0; langinfo_constants[i].name; i++)
Hye-Shik Changc3a87b82004-03-21 19:34:30 +0000489 if (langinfo_constants[i].value == item) {
490 /* Check NULL as a workaround for GNU libc's returning NULL
491 instead of an empty string for nl_langinfo(ERA). */
492 const char *result = nl_langinfo(item);
Neal Norwitz3d7a90d2007-10-27 05:40:06 +0000493 result = result != NULL ? result : "";
Martin v. Löwis92fab752008-03-08 10:40:41 +0000494 return str2uni(result);
Hye-Shik Changc3a87b82004-03-21 19:34:30 +0000495 }
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000496 PyErr_SetString(PyExc_ValueError, "unsupported langinfo constant");
497 return NULL;
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000498}
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000499#endif /* HAVE_LANGINFO_H */
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000500
501#ifdef HAVE_LIBINTL_H
502
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000503PyDoc_STRVAR(gettext__doc__,
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000504"gettext(msg) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000505"Return translation of msg.");
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000506
507static PyObject*
508PyIntl_gettext(PyObject* self, PyObject *args)
509{
510 char *in;
Georg Brandl3dbca812008-07-23 16:10:53 +0000511 if (!PyArg_ParseTuple(args, "s", &in))
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000512 return 0;
Martin v. Löwis92fab752008-03-08 10:40:41 +0000513 return str2uni(gettext(in));
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000514}
515
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000516PyDoc_STRVAR(dgettext__doc__,
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000517"dgettext(domain, msg) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000518"Return translation of msg in domain.");
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000519
520static PyObject*
521PyIntl_dgettext(PyObject* self, PyObject *args)
522{
523 char *domain, *in;
Georg Brandl3dbca812008-07-23 16:10:53 +0000524 if (!PyArg_ParseTuple(args, "zs", &domain, &in))
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000525 return 0;
Martin v. Löwis92fab752008-03-08 10:40:41 +0000526 return str2uni(dgettext(domain, in));
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000527}
528
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000529PyDoc_STRVAR(dcgettext__doc__,
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000530"dcgettext(domain, msg, category) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000531"Return translation of msg in domain and category.");
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000532
533static PyObject*
534PyIntl_dcgettext(PyObject *self, PyObject *args)
535{
536 char *domain, *msgid;
537 int category;
Georg Brandl3dbca812008-07-23 16:10:53 +0000538 if (!PyArg_ParseTuple(args, "zsi", &domain, &msgid, &category))
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000539 return 0;
Martin v. Löwis92fab752008-03-08 10:40:41 +0000540 return str2uni(dcgettext(domain,msgid,category));
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000541}
542
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000543PyDoc_STRVAR(textdomain__doc__,
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000544"textdomain(domain) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000545"Set the C library's textdmain to domain, returning the new domain.");
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000546
547static PyObject*
548PyIntl_textdomain(PyObject* self, PyObject* args)
549{
550 char *domain;
551 if (!PyArg_ParseTuple(args, "z", &domain))
552 return 0;
553 domain = textdomain(domain);
554 if (!domain) {
555 PyErr_SetFromErrno(PyExc_OSError);
556 return NULL;
557 }
Martin v. Löwis92fab752008-03-08 10:40:41 +0000558 return str2uni(domain);
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000559}
560
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000561PyDoc_STRVAR(bindtextdomain__doc__,
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000562"bindtextdomain(domain, dir) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000563"Bind the C library's domain to dir.");
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000564
565static PyObject*
566PyIntl_bindtextdomain(PyObject* self,PyObject*args)
567{
Georg Brandl3dbca812008-07-23 16:10:53 +0000568 char *domain, *dirname;
569 if (!PyArg_ParseTuple(args, "sz", &domain, &dirname))
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000570 return 0;
Georg Brandl3dbca812008-07-23 16:10:53 +0000571 if (!strlen(domain)) {
572 PyErr_SetString(Error, "domain must be a non-empty string");
573 return 0;
574 }
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000575 dirname = bindtextdomain(domain, dirname);
576 if (!dirname) {
577 PyErr_SetFromErrno(PyExc_OSError);
578 return NULL;
579 }
Martin v. Löwis92fab752008-03-08 10:40:41 +0000580 return str2uni(dirname);
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000581}
582
Gustavo Niemeyer7bd33c52004-07-22 18:44:01 +0000583#ifdef HAVE_BIND_TEXTDOMAIN_CODESET
584PyDoc_STRVAR(bind_textdomain_codeset__doc__,
585"bind_textdomain_codeset(domain, codeset) -> string\n"
586"Bind the C library's domain to codeset.");
587
588static PyObject*
589PyIntl_bind_textdomain_codeset(PyObject* self,PyObject*args)
590{
591 char *domain,*codeset;
592 if (!PyArg_ParseTuple(args, "sz", &domain, &codeset))
593 return NULL;
594 codeset = bind_textdomain_codeset(domain, codeset);
595 if (codeset)
Martin v. Löwis92fab752008-03-08 10:40:41 +0000596 return str2uni(codeset);
Gustavo Niemeyer7bd33c52004-07-22 18:44:01 +0000597 Py_RETURN_NONE;
598}
599#endif
600
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000601#endif
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000602
Guido van Rossum220ecc81997-11-18 21:03:39 +0000603static struct PyMethodDef PyLocale_Methods[] = {
Andrew M. Kuchlinge365fb82000-08-03 02:06:16 +0000604 {"setlocale", (PyCFunction) PyLocale_setlocale,
605 METH_VARARGS, setlocale__doc__},
606 {"localeconv", (PyCFunction) PyLocale_localeconv,
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000607 METH_NOARGS, localeconv__doc__},
Martin v. Löwis92fab752008-03-08 10:40:41 +0000608#ifdef HAVE_WCSCOLL
Andrew M. Kuchlinge365fb82000-08-03 02:06:16 +0000609 {"strcoll", (PyCFunction) PyLocale_strcoll,
610 METH_VARARGS, strcoll__doc__},
Martin v. Löwis92fab752008-03-08 10:40:41 +0000611#endif
612#ifdef HAVE_WCSXFRM
Andrew M. Kuchlinge365fb82000-08-03 02:06:16 +0000613 {"strxfrm", (PyCFunction) PyLocale_strxfrm,
614 METH_VARARGS, strxfrm__doc__},
Martin v. Löwis92fab752008-03-08 10:40:41 +0000615#endif
Ronald Oussorenfe8a3d62009-06-07 15:29:46 +0000616#if defined(MS_WINDOWS)
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000617 {"_getdefaultlocale", (PyCFunction) PyLocale_getdefaultlocale, METH_NOARGS},
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000618#endif
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000619#ifdef HAVE_LANGINFO_H
620 {"nl_langinfo", (PyCFunction) PyLocale_nl_langinfo,
621 METH_VARARGS, nl_langinfo__doc__},
622#endif
Martin v. Löwisc6a7d7e2002-05-02 12:16:29 +0000623#ifdef HAVE_LIBINTL_H
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000624 {"gettext",(PyCFunction)PyIntl_gettext,METH_VARARGS,
625 gettext__doc__},
626 {"dgettext",(PyCFunction)PyIntl_dgettext,METH_VARARGS,
627 dgettext__doc__},
628 {"dcgettext",(PyCFunction)PyIntl_dcgettext,METH_VARARGS,
629 dcgettext__doc__},
630 {"textdomain",(PyCFunction)PyIntl_textdomain,METH_VARARGS,
631 textdomain__doc__},
632 {"bindtextdomain",(PyCFunction)PyIntl_bindtextdomain,METH_VARARGS,
633 bindtextdomain__doc__},
Gustavo Niemeyer7bd33c52004-07-22 18:44:01 +0000634#ifdef HAVE_BIND_TEXTDOMAIN_CODESET
635 {"bind_textdomain_codeset",(PyCFunction)PyIntl_bind_textdomain_codeset,
636 METH_VARARGS, bind_textdomain_codeset__doc__},
637#endif
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000638#endif
Guido van Rossum220ecc81997-11-18 21:03:39 +0000639 {NULL, NULL}
640};
641
Martin v. Löwis1a214512008-06-11 05:26:20 +0000642
643static struct PyModuleDef _localemodule = {
644 PyModuleDef_HEAD_INIT,
645 "_locale",
646 locale__doc__,
647 -1,
648 PyLocale_Methods,
649 NULL,
650 NULL,
651 NULL,
652 NULL
653};
654
Mark Hammondfe51c6d2002-08-02 02:27:13 +0000655PyMODINIT_FUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +0000656PyInit__locale(void)
Guido van Rossum220ecc81997-11-18 21:03:39 +0000657{
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000658 PyObject *m, *d, *x;
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000659#ifdef HAVE_LANGINFO_H
660 int i;
661#endif
Guido van Rossum220ecc81997-11-18 21:03:39 +0000662
Martin v. Löwis1a214512008-06-11 05:26:20 +0000663 m = PyModule_Create(&_localemodule);
Neal Norwitz1ac754f2006-01-19 06:09:39 +0000664 if (m == NULL)
Martin v. Löwis1a214512008-06-11 05:26:20 +0000665 return NULL;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000666
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000667 d = PyModule_GetDict(m);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000668
Christian Heimes217cfd12007-12-02 14:31:20 +0000669 x = PyLong_FromLong(LC_CTYPE);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000670 PyDict_SetItemString(d, "LC_CTYPE", x);
671 Py_XDECREF(x);
672
Christian Heimes217cfd12007-12-02 14:31:20 +0000673 x = PyLong_FromLong(LC_TIME);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000674 PyDict_SetItemString(d, "LC_TIME", x);
675 Py_XDECREF(x);
676
Christian Heimes217cfd12007-12-02 14:31:20 +0000677 x = PyLong_FromLong(LC_COLLATE);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000678 PyDict_SetItemString(d, "LC_COLLATE", x);
679 Py_XDECREF(x);
680
Christian Heimes217cfd12007-12-02 14:31:20 +0000681 x = PyLong_FromLong(LC_MONETARY);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000682 PyDict_SetItemString(d, "LC_MONETARY", x);
683 Py_XDECREF(x);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000684
Guido van Rossum8d9c2e31997-12-09 19:35:11 +0000685#ifdef LC_MESSAGES
Christian Heimes217cfd12007-12-02 14:31:20 +0000686 x = PyLong_FromLong(LC_MESSAGES);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000687 PyDict_SetItemString(d, "LC_MESSAGES", x);
688 Py_XDECREF(x);
Guido van Rossum8d9c2e31997-12-09 19:35:11 +0000689#endif /* LC_MESSAGES */
Guido van Rossum220ecc81997-11-18 21:03:39 +0000690
Christian Heimes217cfd12007-12-02 14:31:20 +0000691 x = PyLong_FromLong(LC_NUMERIC);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000692 PyDict_SetItemString(d, "LC_NUMERIC", x);
693 Py_XDECREF(x);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000694
Christian Heimes217cfd12007-12-02 14:31:20 +0000695 x = PyLong_FromLong(LC_ALL);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000696 PyDict_SetItemString(d, "LC_ALL", x);
697 Py_XDECREF(x);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000698
Christian Heimes217cfd12007-12-02 14:31:20 +0000699 x = PyLong_FromLong(CHAR_MAX);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000700 PyDict_SetItemString(d, "CHAR_MAX", x);
701 Py_XDECREF(x);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000702
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000703 Error = PyErr_NewException("locale.Error", NULL, NULL);
704 PyDict_SetItemString(d, "Error", Error);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000705
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000706#ifdef HAVE_LANGINFO_H
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000707 for (i = 0; langinfo_constants[i].name; i++) {
708 PyModule_AddIntConstant(m, langinfo_constants[i].name,
709 langinfo_constants[i].value);
710 }
Martin v. Löwisf95dd0a2001-08-15 17:14:33 +0000711#endif
Martin v. Löwis1a214512008-06-11 05:26:20 +0000712 return m;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000713}
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000714
715/*
716Local variables:
717c-basic-offset: 4
718indent-tabs-mode: nil
719End:
720*/