blob: 72450def3d6945bbe6178b1d693a1b4871f5d326 [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
Martin v. Löwis92fab752008-03-08 10:40:41 +000045/* Convert a char* to a Unicode object according to the current locale */
46static PyObject*
47str2uni(const char* s)
48{
Antoine Pitroufff95302008-09-03 18:58:51 +000049#ifdef HAVE_BROKEN_MBSTOWCS
50 size_t needed = strlen(s);
51#else
Martin v. Löwis92fab752008-03-08 10:40:41 +000052 size_t needed = mbstowcs(NULL, s, 0);
Antoine Pitroufff95302008-09-03 18:58:51 +000053#endif
Martin v. Löwis92fab752008-03-08 10:40:41 +000054 size_t res1;
55 wchar_t smallbuf[30];
56 wchar_t *dest;
57 PyObject *res2;
58 if (needed == (size_t)-1) {
59 PyErr_SetString(PyExc_ValueError, "Cannot convert byte to string");
60 return NULL;
61 }
Martin v. Löwis5bacec12008-03-08 13:39:58 +000062 if (needed*sizeof(wchar_t) < sizeof(smallbuf))
Martin v. Löwis92fab752008-03-08 10:40:41 +000063 dest = smallbuf;
64 else {
Martin v. Löwisa69e1ef2008-03-08 10:54:31 +000065 dest = PyMem_Malloc((needed+1)*sizeof(wchar_t));
Martin v. Löwis92fab752008-03-08 10:40:41 +000066 if (!dest)
67 return PyErr_NoMemory();
68 }
69 /* This shouldn't fail now */
70 res1 = mbstowcs(dest, s, needed+1);
Antoine Pitroufff95302008-09-03 18:58:51 +000071#ifdef HAVE_BROKEN_MBSTOWCS
72 assert(res1 != (size_t)-1);
73#else
Martin v. Löwisce7a1122008-03-08 10:59:49 +000074 assert(res1 == needed);
Antoine Pitroufff95302008-09-03 18:58:51 +000075#endif
Martin v. Löwis92fab752008-03-08 10:40:41 +000076 res2 = PyUnicode_FromWideChar(dest, res1);
77 if (dest != smallbuf)
78 PyMem_Free(dest);
79 return res2;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000080}
Martin v. Löwis92fab752008-03-08 10:40:41 +000081
Guido van Rossum220ecc81997-11-18 21:03:39 +000082/* support functions for formatting floating point numbers */
83
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000084PyDoc_STRVAR(setlocale__doc__,
85"(integer,string=None) -> string. Activates/queries locale processing.");
Guido van Rossum220ecc81997-11-18 21:03:39 +000086
Guido van Rossum220ecc81997-11-18 21:03:39 +000087/* the grouping is terminated by either 0 or CHAR_MAX */
88static PyObject*
Fredrik Lundh8f017a02000-07-08 19:57:37 +000089copy_grouping(char* s)
Guido van Rossum220ecc81997-11-18 21:03:39 +000090{
Fredrik Lundh8f017a02000-07-08 19:57:37 +000091 int i;
92 PyObject *result, *val = NULL;
93
94 if (s[0] == '\0')
95 /* empty string: no grouping at all */
96 return PyList_New(0);
97
98 for (i = 0; s[i] != '\0' && s[i] != CHAR_MAX; i++)
99 ; /* nothing */
100
101 result = PyList_New(i+1);
102 if (!result)
103 return NULL;
104
105 i = -1;
106 do {
107 i++;
Christian Heimes217cfd12007-12-02 14:31:20 +0000108 val = PyLong_FromLong(s[i]);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000109 if (!val)
110 break;
111 if (PyList_SetItem(result, i, val)) {
112 Py_DECREF(val);
Fredrik Lundh89610a42000-07-08 20:07:24 +0000113 val = NULL;
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000114 break;
115 }
116 } while (s[i] != '\0' && s[i] != CHAR_MAX);
117
118 if (!val) {
119 Py_DECREF(result);
120 return NULL;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000121 }
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000122
123 return result;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000124}
125
Guido van Rossum220ecc81997-11-18 21:03:39 +0000126static PyObject*
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000127PyLocale_setlocale(PyObject* self, PyObject* args)
Guido van Rossum220ecc81997-11-18 21:03:39 +0000128{
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000129 int category;
130 char *locale = NULL, *result;
131 PyObject *result_object;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000132
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000133 if (!PyArg_ParseTuple(args, "i|z:setlocale", &category, &locale))
Fredrik Lundh89610a42000-07-08 20:07:24 +0000134 return NULL;
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000135
Amaury Forgeot d'Arc64f3ca42009-12-01 21:59:18 +0000136#if defined(MS_WINDOWS)
137 if (category < LC_MIN || category > LC_MAX)
138 {
139 PyErr_SetString(Error, "invalid locale category");
140 return NULL;
141 }
142#endif
143
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000144 if (locale) {
145 /* set locale */
146 result = setlocale(category, locale);
147 if (!result) {
148 /* operation failed, no setting was changed */
Martin v. Löwis25f90d52003-09-03 04:50:13 +0000149 PyErr_SetString(Error, "unsupported locale setting");
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000150 return NULL;
151 }
Martin v. Löwis92fab752008-03-08 10:40:41 +0000152 result_object = str2uni(result);
Mark Hammond9a714752003-07-24 14:15:07 +0000153 if (!result_object)
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000154 return NULL;
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000155 } else {
156 /* get locale */
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000157 result = setlocale(category, NULL);
158 if (!result) {
159 PyErr_SetString(Error, "locale query failed");
160 return NULL;
161 }
Martin v. Löwis92fab752008-03-08 10:40:41 +0000162 result_object = str2uni(result);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000163 }
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000164 return result_object;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000165}
166
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000167PyDoc_STRVAR(localeconv__doc__,
168"() -> dict. Returns numeric and monetary locale-specific parameters.");
Guido van Rossum220ecc81997-11-18 21:03:39 +0000169
170static PyObject*
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000171PyLocale_localeconv(PyObject* self)
Guido van Rossum220ecc81997-11-18 21:03:39 +0000172{
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000173 PyObject* result;
174 struct lconv *l;
175 PyObject *x;
176
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000177 result = PyDict_New();
Fredrik Lundh89610a42000-07-08 20:07:24 +0000178 if (!result)
179 return NULL;
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000180
181 /* if LC_NUMERIC is different in the C library, use saved value */
182 l = localeconv();
183
184 /* hopefully, the localeconv result survives the C library calls
185 involved herein */
186
187#define RESULT_STRING(s)\
Martin v. Löwis92fab752008-03-08 10:40:41 +0000188 x = str2uni(l->s); \
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000189 if (!x) goto failed;\
190 PyDict_SetItemString(result, #s, x);\
191 Py_XDECREF(x)
192
193#define RESULT_INT(i)\
Christian Heimes217cfd12007-12-02 14:31:20 +0000194 x = PyLong_FromLong(l->i);\
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000195 if (!x) goto failed;\
196 PyDict_SetItemString(result, #i, x);\
197 Py_XDECREF(x)
Guido van Rossum220ecc81997-11-18 21:03:39 +0000198
199 /* Numeric information */
Martin v. Löwis737ea822004-06-08 18:52:54 +0000200 RESULT_STRING(decimal_point);
201 RESULT_STRING(thousands_sep);
202 x = copy_grouping(l->grouping);
203 if (!x)
204 goto failed;
205 PyDict_SetItemString(result, "grouping", x);
206 Py_XDECREF(x);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000207
208 /* Monetary information */
209 RESULT_STRING(int_curr_symbol);
210 RESULT_STRING(currency_symbol);
211 RESULT_STRING(mon_decimal_point);
212 RESULT_STRING(mon_thousands_sep);
213 x = copy_grouping(l->mon_grouping);
214 if (!x)
215 goto failed;
216 PyDict_SetItemString(result, "mon_grouping", x);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000217 Py_XDECREF(x);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000218 RESULT_STRING(positive_sign);
219 RESULT_STRING(negative_sign);
220 RESULT_INT(int_frac_digits);
221 RESULT_INT(frac_digits);
222 RESULT_INT(p_cs_precedes);
223 RESULT_INT(p_sep_by_space);
224 RESULT_INT(n_cs_precedes);
225 RESULT_INT(n_sep_by_space);
226 RESULT_INT(p_sign_posn);
227 RESULT_INT(n_sign_posn);
228 return result;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000229
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000230 failed:
231 Py_XDECREF(result);
232 Py_XDECREF(x);
233 return NULL;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000234}
235
Martin v. Löwis92fab752008-03-08 10:40:41 +0000236#if defined(HAVE_WCSCOLL)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000237PyDoc_STRVAR(strcoll__doc__,
238"string,string -> int. Compares two strings according to the locale.");
Guido van Rossum220ecc81997-11-18 21:03:39 +0000239
240static PyObject*
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000241PyLocale_strcoll(PyObject* self, PyObject* args)
Guido van Rossum220ecc81997-11-18 21:03:39 +0000242{
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000243 PyObject *os1, *os2, *result = NULL;
244 wchar_t *ws1 = NULL, *ws2 = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000245
Martin v. Löwis92fab752008-03-08 10:40:41 +0000246 if (!PyArg_ParseTuple(args, "UU:strcoll", &os1, &os2))
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000247 return NULL;
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000248 /* Convert the unicode strings to wchar[]. */
Victor Stinnerbeb4135b2010-10-07 01:02:42 +0000249 ws1 = PyUnicode_AsWideCharString(os1, NULL);
Victor Stinner449057f2010-09-29 10:30:43 +0000250 if (ws1 == NULL)
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000251 goto done;
Victor Stinnerbeb4135b2010-10-07 01:02:42 +0000252 ws2 = PyUnicode_AsWideCharString(os2, NULL);
Victor Stinner449057f2010-09-29 10:30:43 +0000253 if (ws2 == NULL)
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000254 goto done;
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000255 /* Collate the strings. */
Christian Heimes217cfd12007-12-02 14:31:20 +0000256 result = PyLong_FromLong(wcscoll(ws1, ws2));
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000257 done:
258 /* Deallocate everything. */
259 if (ws1) PyMem_FREE(ws1);
260 if (ws2) PyMem_FREE(ws2);
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000261 return result;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000262}
Martin v. Löwis92fab752008-03-08 10:40:41 +0000263#endif
Guido van Rossum220ecc81997-11-18 21:03:39 +0000264
Martin v. Löwis92fab752008-03-08 10:40:41 +0000265#ifdef HAVE_WCSXFRM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000266PyDoc_STRVAR(strxfrm__doc__,
Mark Dickinson211c6252009-02-01 10:28:51 +0000267"strxfrm(string) -> string.\n\
268\n\
269Return a string that can be used as a key for locale-aware comparisons.");
Guido van Rossum220ecc81997-11-18 21:03:39 +0000270
271static PyObject*
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000272PyLocale_strxfrm(PyObject* self, PyObject* args)
Guido van Rossum220ecc81997-11-18 21:03:39 +0000273{
Victor Stinner63649272011-09-29 23:32:06 +0200274 PyObject *str;
275 Py_ssize_t n1;
276 wchar_t *s = NULL, *buf = NULL;
277 size_t n2;
Martin v. Löwis92fab752008-03-08 10:40:41 +0000278 PyObject *result = NULL;
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000279
Victor Stinner63649272011-09-29 23:32:06 +0200280 if (!PyArg_ParseTuple(args, "U:strxfrm", &str))
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000281 return NULL;
282
Victor Stinner63649272011-09-29 23:32:06 +0200283 s = PyUnicode_AsWideCharString(str, &n1);
284 if (s == NULL)
285 goto exit;
Martin v. Löwis92fab752008-03-08 10:40:41 +0000286
287 /* assume no change in size, first */
Victor Stinner63649272011-09-29 23:32:06 +0200288 n1 = n1 + 1;
289 buf = PyMem_Malloc(n1 * sizeof(wchar_t));
Martin v. Löwis92fab752008-03-08 10:40:41 +0000290 if (!buf) {
291 PyErr_NoMemory();
292 goto exit;
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000293 }
Martin v. Löwis92fab752008-03-08 10:40:41 +0000294 n2 = wcsxfrm(buf, s, n1);
295 if (n2 >= n1) {
296 /* more space needed */
Martin v. Löwisa69e1ef2008-03-08 10:54:31 +0000297 buf = PyMem_Realloc(buf, (n2+1)*sizeof(wchar_t));
Martin v. Löwis92fab752008-03-08 10:40:41 +0000298 if (!buf) {
299 PyErr_NoMemory();
300 goto exit;
301 }
Martin v. Löwisdb1c3992009-05-23 10:38:26 +0000302 n2 = wcsxfrm(buf, s, n2+1);
Martin v. Löwis92fab752008-03-08 10:40:41 +0000303 }
304 result = PyUnicode_FromWideChar(buf, n2);
Victor Stinner63649272011-09-29 23:32:06 +0200305exit:
306 if (buf)
307 PyMem_Free(buf);
308 if (s)
309 PyMem_Free(s);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000310 return result;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000311}
Martin v. Löwis92fab752008-03-08 10:40:41 +0000312#endif
Guido van Rossum220ecc81997-11-18 21:03:39 +0000313
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000314#if defined(MS_WINDOWS)
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000315static PyObject*
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000316PyLocale_getdefaultlocale(PyObject* self)
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000317{
318 char encoding[100];
319 char locale[100];
320
Tim Peters885d4572001-11-28 20:27:42 +0000321 PyOS_snprintf(encoding, sizeof(encoding), "cp%d", GetACP());
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000322
323 if (GetLocaleInfo(LOCALE_USER_DEFAULT,
324 LOCALE_SISO639LANGNAME,
325 locale, sizeof(locale))) {
Martin v. Löwis18e16552006-02-15 17:27:45 +0000326 Py_ssize_t i = strlen(locale);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000327 locale[i++] = '_';
328 if (GetLocaleInfo(LOCALE_USER_DEFAULT,
329 LOCALE_SISO3166CTRYNAME,
Martin v. Löwis18e16552006-02-15 17:27:45 +0000330 locale+i, (int)(sizeof(locale)-i)))
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000331 return Py_BuildValue("ss", locale, encoding);
332 }
333
334 /* If we end up here, this windows version didn't know about
335 ISO639/ISO3166 names (it's probably Windows 95). Return the
336 Windows language identifier instead (a hexadecimal number) */
337
338 locale[0] = '0';
339 locale[1] = 'x';
340 if (GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_IDEFAULTLANGUAGE,
341 locale+2, sizeof(locale)-2)) {
342 return Py_BuildValue("ss", locale, encoding);
343 }
344
345 /* cannot determine the language code (very unlikely) */
346 Py_INCREF(Py_None);
347 return Py_BuildValue("Os", Py_None, encoding);
348}
349#endif
350
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000351#ifdef HAVE_LANGINFO_H
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000352#define LANGINFO(X) {#X, X}
Martin v. Löwis59683e82008-06-13 07:50:45 +0000353static struct langinfo_constant{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000354 char* name;
355 int value;
356} langinfo_constants[] =
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000357{
358 /* These constants should exist on any langinfo implementation */
359 LANGINFO(DAY_1),
360 LANGINFO(DAY_2),
361 LANGINFO(DAY_3),
362 LANGINFO(DAY_4),
363 LANGINFO(DAY_5),
364 LANGINFO(DAY_6),
365 LANGINFO(DAY_7),
366
367 LANGINFO(ABDAY_1),
368 LANGINFO(ABDAY_2),
369 LANGINFO(ABDAY_3),
370 LANGINFO(ABDAY_4),
371 LANGINFO(ABDAY_5),
372 LANGINFO(ABDAY_6),
373 LANGINFO(ABDAY_7),
374
375 LANGINFO(MON_1),
376 LANGINFO(MON_2),
377 LANGINFO(MON_3),
378 LANGINFO(MON_4),
379 LANGINFO(MON_5),
380 LANGINFO(MON_6),
381 LANGINFO(MON_7),
382 LANGINFO(MON_8),
383 LANGINFO(MON_9),
384 LANGINFO(MON_10),
385 LANGINFO(MON_11),
386 LANGINFO(MON_12),
387
388 LANGINFO(ABMON_1),
389 LANGINFO(ABMON_2),
390 LANGINFO(ABMON_3),
391 LANGINFO(ABMON_4),
392 LANGINFO(ABMON_5),
393 LANGINFO(ABMON_6),
394 LANGINFO(ABMON_7),
395 LANGINFO(ABMON_8),
396 LANGINFO(ABMON_9),
397 LANGINFO(ABMON_10),
398 LANGINFO(ABMON_11),
399 LANGINFO(ABMON_12),
400
401#ifdef RADIXCHAR
402 /* The following are not available with glibc 2.0 */
403 LANGINFO(RADIXCHAR),
404 LANGINFO(THOUSEP),
405 /* YESSTR and NOSTR are deprecated in glibc, since they are
406 a special case of message translation, which should be rather
407 done using gettext. So we don't expose it to Python in the
408 first place.
409 LANGINFO(YESSTR),
410 LANGINFO(NOSTR),
411 */
412 LANGINFO(CRNCYSTR),
413#endif
414
415 LANGINFO(D_T_FMT),
416 LANGINFO(D_FMT),
417 LANGINFO(T_FMT),
418 LANGINFO(AM_STR),
419 LANGINFO(PM_STR),
420
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000421 /* The following constants are available only with XPG4, but...
422 AIX 3.2. only has CODESET.
423 OpenBSD doesn't have CODESET but has T_FMT_AMPM, and doesn't have
424 a few of the others.
425 Solution: ifdef-test them all. */
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000426#ifdef CODESET
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000427 LANGINFO(CODESET),
Martin v. Löwis496f9e42002-03-27 12:15:57 +0000428#endif
429#ifdef T_FMT_AMPM
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000430 LANGINFO(T_FMT_AMPM),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000431#endif
432#ifdef ERA
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000433 LANGINFO(ERA),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000434#endif
435#ifdef ERA_D_FMT
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000436 LANGINFO(ERA_D_FMT),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000437#endif
438#ifdef ERA_D_T_FMT
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000439 LANGINFO(ERA_D_T_FMT),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000440#endif
441#ifdef ERA_T_FMT
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000442 LANGINFO(ERA_T_FMT),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000443#endif
444#ifdef ALT_DIGITS
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000445 LANGINFO(ALT_DIGITS),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000446#endif
447#ifdef YESEXPR
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000448 LANGINFO(YESEXPR),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000449#endif
450#ifdef NOEXPR
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000451 LANGINFO(NOEXPR),
452#endif
453#ifdef _DATE_FMT
454 /* This is not available in all glibc versions that have CODESET. */
455 LANGINFO(_DATE_FMT),
456#endif
457 {0, 0}
458};
459
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000460PyDoc_STRVAR(nl_langinfo__doc__,
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000461"nl_langinfo(key) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000462"Return the value for the locale information associated with key.");
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000463
464static PyObject*
465PyLocale_nl_langinfo(PyObject* self, PyObject* args)
466{
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000467 int item, i;
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000468 if (!PyArg_ParseTuple(args, "i:nl_langinfo", &item))
469 return NULL;
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000470 /* Check whether this is a supported constant. GNU libc sometimes
471 returns numeric values in the char* return value, which would
Neal Norwitz7f9d29c2007-08-26 07:21:45 +0000472 crash PyUnicode_FromString. */
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000473 for (i = 0; langinfo_constants[i].name; i++)
Hye-Shik Changc3a87b82004-03-21 19:34:30 +0000474 if (langinfo_constants[i].value == item) {
475 /* Check NULL as a workaround for GNU libc's returning NULL
476 instead of an empty string for nl_langinfo(ERA). */
477 const char *result = nl_langinfo(item);
Neal Norwitz3d7a90d2007-10-27 05:40:06 +0000478 result = result != NULL ? result : "";
Martin v. Löwis92fab752008-03-08 10:40:41 +0000479 return str2uni(result);
Hye-Shik Changc3a87b82004-03-21 19:34:30 +0000480 }
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000481 PyErr_SetString(PyExc_ValueError, "unsupported langinfo constant");
482 return NULL;
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000483}
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000484#endif /* HAVE_LANGINFO_H */
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000485
486#ifdef HAVE_LIBINTL_H
487
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000488PyDoc_STRVAR(gettext__doc__,
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000489"gettext(msg) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000490"Return translation of msg.");
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000491
492static PyObject*
493PyIntl_gettext(PyObject* self, PyObject *args)
494{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000495 char *in;
496 if (!PyArg_ParseTuple(args, "s", &in))
497 return 0;
498 return str2uni(gettext(in));
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000499}
500
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000501PyDoc_STRVAR(dgettext__doc__,
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000502"dgettext(domain, msg) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000503"Return translation of msg in domain.");
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000504
505static PyObject*
506PyIntl_dgettext(PyObject* self, PyObject *args)
507{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000508 char *domain, *in;
509 if (!PyArg_ParseTuple(args, "zs", &domain, &in))
510 return 0;
511 return str2uni(dgettext(domain, in));
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000512}
513
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000514PyDoc_STRVAR(dcgettext__doc__,
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000515"dcgettext(domain, msg, category) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000516"Return translation of msg in domain and category.");
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000517
518static PyObject*
519PyIntl_dcgettext(PyObject *self, PyObject *args)
520{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000521 char *domain, *msgid;
522 int category;
523 if (!PyArg_ParseTuple(args, "zsi", &domain, &msgid, &category))
524 return 0;
525 return str2uni(dcgettext(domain,msgid,category));
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000526}
527
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000528PyDoc_STRVAR(textdomain__doc__,
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000529"textdomain(domain) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000530"Set the C library's textdmain to domain, returning the new domain.");
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000531
532static PyObject*
533PyIntl_textdomain(PyObject* self, PyObject* args)
534{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000535 char *domain;
536 if (!PyArg_ParseTuple(args, "z", &domain))
537 return 0;
538 domain = textdomain(domain);
539 if (!domain) {
540 PyErr_SetFromErrno(PyExc_OSError);
541 return NULL;
542 }
543 return str2uni(domain);
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000544}
545
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000546PyDoc_STRVAR(bindtextdomain__doc__,
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000547"bindtextdomain(domain, dir) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000548"Bind the C library's domain to dir.");
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000549
550static PyObject*
551PyIntl_bindtextdomain(PyObject* self,PyObject*args)
552{
Victor Stinner9e19ca42010-06-11 22:09:51 +0000553 char *domain, *dirname, *current_dirname;
554 PyObject *dirname_obj, *dirname_bytes = NULL, *result;
555 if (!PyArg_ParseTuple(args, "sO", &domain, &dirname_obj))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000556 return 0;
557 if (!strlen(domain)) {
558 PyErr_SetString(Error, "domain must be a non-empty string");
559 return 0;
560 }
Victor Stinner9e19ca42010-06-11 22:09:51 +0000561 if (dirname_obj != Py_None) {
562 if (!PyUnicode_FSConverter(dirname_obj, &dirname_bytes))
563 return NULL;
564 dirname = PyBytes_AsString(dirname_bytes);
565 } else {
566 dirname_bytes = NULL;
567 dirname = NULL;
568 }
569 current_dirname = bindtextdomain(domain, dirname);
570 if (current_dirname == NULL) {
571 Py_XDECREF(dirname_bytes);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000572 PyErr_SetFromErrno(PyExc_OSError);
573 return NULL;
574 }
Victor Stinner9e19ca42010-06-11 22:09:51 +0000575 result = str2uni(current_dirname);
576 Py_XDECREF(dirname_bytes);
577 return result;
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000578}
579
Gustavo Niemeyer7bd33c52004-07-22 18:44:01 +0000580#ifdef HAVE_BIND_TEXTDOMAIN_CODESET
581PyDoc_STRVAR(bind_textdomain_codeset__doc__,
582"bind_textdomain_codeset(domain, codeset) -> string\n"
583"Bind the C library's domain to codeset.");
584
585static PyObject*
586PyIntl_bind_textdomain_codeset(PyObject* self,PyObject*args)
587{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000588 char *domain,*codeset;
589 if (!PyArg_ParseTuple(args, "sz", &domain, &codeset))
590 return NULL;
591 codeset = bind_textdomain_codeset(domain, codeset);
592 if (codeset)
593 return str2uni(codeset);
594 Py_RETURN_NONE;
Gustavo Niemeyer7bd33c52004-07-22 18:44:01 +0000595}
596#endif
597
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000598#endif
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000599
Guido van Rossum220ecc81997-11-18 21:03:39 +0000600static struct PyMethodDef PyLocale_Methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000601 {"setlocale", (PyCFunction) PyLocale_setlocale,
Andrew M. Kuchlinge365fb82000-08-03 02:06:16 +0000602 METH_VARARGS, setlocale__doc__},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000603 {"localeconv", (PyCFunction) PyLocale_localeconv,
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000604 METH_NOARGS, localeconv__doc__},
Martin v. Löwis92fab752008-03-08 10:40:41 +0000605#ifdef HAVE_WCSCOLL
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000606 {"strcoll", (PyCFunction) PyLocale_strcoll,
Andrew M. Kuchlinge365fb82000-08-03 02:06:16 +0000607 METH_VARARGS, strcoll__doc__},
Martin v. Löwis92fab752008-03-08 10:40:41 +0000608#endif
609#ifdef HAVE_WCSXFRM
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000610 {"strxfrm", (PyCFunction) PyLocale_strxfrm,
Andrew M. Kuchlinge365fb82000-08-03 02:06:16 +0000611 METH_VARARGS, strxfrm__doc__},
Martin v. Löwis92fab752008-03-08 10:40:41 +0000612#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000613#if defined(MS_WINDOWS)
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000614 {"_getdefaultlocale", (PyCFunction) PyLocale_getdefaultlocale, METH_NOARGS},
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000615#endif
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000616#ifdef HAVE_LANGINFO_H
617 {"nl_langinfo", (PyCFunction) PyLocale_nl_langinfo,
618 METH_VARARGS, nl_langinfo__doc__},
619#endif
Martin v. Löwisc6a7d7e2002-05-02 12:16:29 +0000620#ifdef HAVE_LIBINTL_H
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000621 {"gettext",(PyCFunction)PyIntl_gettext,METH_VARARGS,
622 gettext__doc__},
623 {"dgettext",(PyCFunction)PyIntl_dgettext,METH_VARARGS,
624 dgettext__doc__},
625 {"dcgettext",(PyCFunction)PyIntl_dcgettext,METH_VARARGS,
626 dcgettext__doc__},
627 {"textdomain",(PyCFunction)PyIntl_textdomain,METH_VARARGS,
628 textdomain__doc__},
629 {"bindtextdomain",(PyCFunction)PyIntl_bindtextdomain,METH_VARARGS,
630 bindtextdomain__doc__},
Gustavo Niemeyer7bd33c52004-07-22 18:44:01 +0000631#ifdef HAVE_BIND_TEXTDOMAIN_CODESET
632 {"bind_textdomain_codeset",(PyCFunction)PyIntl_bind_textdomain_codeset,
633 METH_VARARGS, bind_textdomain_codeset__doc__},
634#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000635#endif
Guido van Rossum220ecc81997-11-18 21:03:39 +0000636 {NULL, NULL}
637};
638
Martin v. Löwis1a214512008-06-11 05:26:20 +0000639
640static struct PyModuleDef _localemodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000641 PyModuleDef_HEAD_INIT,
642 "_locale",
643 locale__doc__,
644 -1,
645 PyLocale_Methods,
646 NULL,
647 NULL,
648 NULL,
649 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +0000650};
651
Mark Hammondfe51c6d2002-08-02 02:27:13 +0000652PyMODINIT_FUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +0000653PyInit__locale(void)
Guido van Rossum220ecc81997-11-18 21:03:39 +0000654{
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000655 PyObject *m, *d, *x;
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000656#ifdef HAVE_LANGINFO_H
657 int i;
658#endif
Guido van Rossum220ecc81997-11-18 21:03:39 +0000659
Martin v. Löwis1a214512008-06-11 05:26:20 +0000660 m = PyModule_Create(&_localemodule);
Neal Norwitz1ac754f2006-01-19 06:09:39 +0000661 if (m == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000662 return NULL;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000663
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000664 d = PyModule_GetDict(m);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000665
Christian Heimes217cfd12007-12-02 14:31:20 +0000666 x = PyLong_FromLong(LC_CTYPE);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000667 PyDict_SetItemString(d, "LC_CTYPE", x);
668 Py_XDECREF(x);
669
Christian Heimes217cfd12007-12-02 14:31:20 +0000670 x = PyLong_FromLong(LC_TIME);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000671 PyDict_SetItemString(d, "LC_TIME", x);
672 Py_XDECREF(x);
673
Christian Heimes217cfd12007-12-02 14:31:20 +0000674 x = PyLong_FromLong(LC_COLLATE);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000675 PyDict_SetItemString(d, "LC_COLLATE", x);
676 Py_XDECREF(x);
677
Christian Heimes217cfd12007-12-02 14:31:20 +0000678 x = PyLong_FromLong(LC_MONETARY);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000679 PyDict_SetItemString(d, "LC_MONETARY", x);
680 Py_XDECREF(x);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000681
Guido van Rossum8d9c2e31997-12-09 19:35:11 +0000682#ifdef LC_MESSAGES
Christian Heimes217cfd12007-12-02 14:31:20 +0000683 x = PyLong_FromLong(LC_MESSAGES);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000684 PyDict_SetItemString(d, "LC_MESSAGES", x);
685 Py_XDECREF(x);
Guido van Rossum8d9c2e31997-12-09 19:35:11 +0000686#endif /* LC_MESSAGES */
Guido van Rossum220ecc81997-11-18 21:03:39 +0000687
Christian Heimes217cfd12007-12-02 14:31:20 +0000688 x = PyLong_FromLong(LC_NUMERIC);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000689 PyDict_SetItemString(d, "LC_NUMERIC", x);
690 Py_XDECREF(x);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000691
Christian Heimes217cfd12007-12-02 14:31:20 +0000692 x = PyLong_FromLong(LC_ALL);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000693 PyDict_SetItemString(d, "LC_ALL", x);
694 Py_XDECREF(x);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000695
Christian Heimes217cfd12007-12-02 14:31:20 +0000696 x = PyLong_FromLong(CHAR_MAX);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000697 PyDict_SetItemString(d, "CHAR_MAX", x);
698 Py_XDECREF(x);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000699
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000700 Error = PyErr_NewException("locale.Error", NULL, NULL);
701 PyDict_SetItemString(d, "Error", Error);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000702
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000703#ifdef HAVE_LANGINFO_H
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000704 for (i = 0; langinfo_constants[i].name; i++) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000705 PyModule_AddIntConstant(m, langinfo_constants[i].name,
706 langinfo_constants[i].value);
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000707 }
Martin v. Löwisf95dd0a2001-08-15 17:14:33 +0000708#endif
Martin v. Löwis1a214512008-06-11 05:26:20 +0000709 return m;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000710}
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000711
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000712/*
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000713Local variables:
714c-basic-offset: 4
715indent-tabs-mode: nil
716End:
717*/