blob: 84e393e173769b89abf0fbf5ad9c82629ff9346b [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 Pitroueda95e92009-10-19 19:47:59 +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 Pitrou7f14f0d2010-05-09 16:14:21 +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'Arcea315ac2009-12-01 22:03:44 +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;
Martin v. Löwis92fab752008-03-08 10:40:41 +0000245 Py_ssize_t len1, len2;
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000246
Martin v. Löwis92fab752008-03-08 10:40:41 +0000247 if (!PyArg_ParseTuple(args, "UU:strcoll", &os1, &os2))
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000248 return NULL;
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000249 /* Convert the unicode strings to wchar[]. */
250 len1 = PyUnicode_GET_SIZE(os1) + 1;
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000251 ws1 = PyMem_MALLOC(len1 * sizeof(wchar_t));
252 if (!ws1) {
253 PyErr_NoMemory();
254 goto done;
255 }
256 if (PyUnicode_AsWideChar((PyUnicodeObject*)os1, ws1, len1) == -1)
257 goto done;
Marc-André Lemburga9cadcd2004-11-22 13:02:31 +0000258 ws1[len1 - 1] = 0;
259 len2 = PyUnicode_GET_SIZE(os2) + 1;
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000260 ws2 = PyMem_MALLOC(len2 * sizeof(wchar_t));
261 if (!ws2) {
262 PyErr_NoMemory();
263 goto done;
264 }
265 if (PyUnicode_AsWideChar((PyUnicodeObject*)os2, ws2, len2) == -1)
266 goto done;
Marc-André Lemburga9cadcd2004-11-22 13:02:31 +0000267 ws2[len2 - 1] = 0;
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000268 /* Collate the strings. */
Christian Heimes217cfd12007-12-02 14:31:20 +0000269 result = PyLong_FromLong(wcscoll(ws1, ws2));
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000270 done:
271 /* Deallocate everything. */
272 if (ws1) PyMem_FREE(ws1);
273 if (ws2) PyMem_FREE(ws2);
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000274 return result;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000275}
Martin v. Löwis92fab752008-03-08 10:40:41 +0000276#endif
Guido van Rossum220ecc81997-11-18 21:03:39 +0000277
Martin v. Löwis92fab752008-03-08 10:40:41 +0000278#ifdef HAVE_WCSXFRM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000279PyDoc_STRVAR(strxfrm__doc__,
Mark Dickinson211c6252009-02-01 10:28:51 +0000280"strxfrm(string) -> string.\n\
281\n\
282Return a string that can be used as a key for locale-aware comparisons.");
Guido van Rossum220ecc81997-11-18 21:03:39 +0000283
284static PyObject*
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000285PyLocale_strxfrm(PyObject* self, PyObject* args)
Guido van Rossum220ecc81997-11-18 21:03:39 +0000286{
Martin v. Löwis92fab752008-03-08 10:40:41 +0000287 Py_UNICODE *s0;
288 Py_ssize_t n0;
289 wchar_t *s, *buf = NULL;
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000290 size_t n1, n2;
Martin v. Löwis92fab752008-03-08 10:40:41 +0000291 PyObject *result = NULL;
Georg Brandl227c4852009-10-27 21:39:08 +0000292#ifndef HAVE_USABLE_WCHAR_T
Martin v. Löwis92fab752008-03-08 10:40:41 +0000293 Py_ssize_t i;
Georg Brandl227c4852009-10-27 21:39:08 +0000294#endif
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000295
Martin v. Löwis92fab752008-03-08 10:40:41 +0000296 if (!PyArg_ParseTuple(args, "u#:strxfrm", &s0, &n0))
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000297 return NULL;
298
Martin v. Löwis92fab752008-03-08 10:40:41 +0000299#ifdef HAVE_USABLE_WCHAR_T
300 s = s0;
301#else
Martin v. Löwisa69e1ef2008-03-08 10:54:31 +0000302 s = PyMem_Malloc((n0+1)*sizeof(wchar_t));
Martin v. Löwis92fab752008-03-08 10:40:41 +0000303 if (!s)
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000304 return PyErr_NoMemory();
Martin v. Löwis92fab752008-03-08 10:40:41 +0000305 for (i=0; i<=n0; i++)
306 s[i] = s0[i];
307#endif
308
309 /* assume no change in size, first */
310 n1 = wcslen(s) + 1;
Martin v. Löwisa69e1ef2008-03-08 10:54:31 +0000311 buf = PyMem_Malloc(n1*sizeof(wchar_t));
Martin v. Löwis92fab752008-03-08 10:40:41 +0000312 if (!buf) {
313 PyErr_NoMemory();
314 goto exit;
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000315 }
Martin v. Löwis92fab752008-03-08 10:40:41 +0000316 n2 = wcsxfrm(buf, s, n1);
317 if (n2 >= n1) {
318 /* more space needed */
Martin v. Löwisa69e1ef2008-03-08 10:54:31 +0000319 buf = PyMem_Realloc(buf, (n2+1)*sizeof(wchar_t));
Martin v. Löwis92fab752008-03-08 10:40:41 +0000320 if (!buf) {
321 PyErr_NoMemory();
322 goto exit;
323 }
Martin v. Löwisdb1c3992009-05-23 10:38:26 +0000324 n2 = wcsxfrm(buf, s, n2+1);
Martin v. Löwis92fab752008-03-08 10:40:41 +0000325 }
326 result = PyUnicode_FromWideChar(buf, n2);
327 exit:
328 if (buf) PyMem_Free(buf);
Antoine Pitroueda95e92009-10-19 19:47:59 +0000329#ifndef HAVE_USABLE_WCHAR_T
Martin v. Löwis92fab752008-03-08 10:40:41 +0000330 PyMem_Free(s);
331#endif
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000332 return result;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000333}
Martin v. Löwis92fab752008-03-08 10:40:41 +0000334#endif
Guido van Rossum220ecc81997-11-18 21:03:39 +0000335
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000336#if defined(MS_WINDOWS)
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000337static PyObject*
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000338PyLocale_getdefaultlocale(PyObject* self)
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000339{
340 char encoding[100];
341 char locale[100];
342
Tim Peters885d4572001-11-28 20:27:42 +0000343 PyOS_snprintf(encoding, sizeof(encoding), "cp%d", GetACP());
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000344
345 if (GetLocaleInfo(LOCALE_USER_DEFAULT,
346 LOCALE_SISO639LANGNAME,
347 locale, sizeof(locale))) {
Martin v. Löwis18e16552006-02-15 17:27:45 +0000348 Py_ssize_t i = strlen(locale);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000349 locale[i++] = '_';
350 if (GetLocaleInfo(LOCALE_USER_DEFAULT,
351 LOCALE_SISO3166CTRYNAME,
Martin v. Löwis18e16552006-02-15 17:27:45 +0000352 locale+i, (int)(sizeof(locale)-i)))
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000353 return Py_BuildValue("ss", locale, encoding);
354 }
355
356 /* If we end up here, this windows version didn't know about
357 ISO639/ISO3166 names (it's probably Windows 95). Return the
358 Windows language identifier instead (a hexadecimal number) */
359
360 locale[0] = '0';
361 locale[1] = 'x';
362 if (GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_IDEFAULTLANGUAGE,
363 locale+2, sizeof(locale)-2)) {
364 return Py_BuildValue("ss", locale, encoding);
365 }
366
367 /* cannot determine the language code (very unlikely) */
368 Py_INCREF(Py_None);
369 return Py_BuildValue("Os", Py_None, encoding);
370}
371#endif
372
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000373#ifdef HAVE_LANGINFO_H
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000374#define LANGINFO(X) {#X, X}
Martin v. Löwis59683e82008-06-13 07:50:45 +0000375static struct langinfo_constant{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000376 char* name;
377 int value;
378} langinfo_constants[] =
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000379{
380 /* These constants should exist on any langinfo implementation */
381 LANGINFO(DAY_1),
382 LANGINFO(DAY_2),
383 LANGINFO(DAY_3),
384 LANGINFO(DAY_4),
385 LANGINFO(DAY_5),
386 LANGINFO(DAY_6),
387 LANGINFO(DAY_7),
388
389 LANGINFO(ABDAY_1),
390 LANGINFO(ABDAY_2),
391 LANGINFO(ABDAY_3),
392 LANGINFO(ABDAY_4),
393 LANGINFO(ABDAY_5),
394 LANGINFO(ABDAY_6),
395 LANGINFO(ABDAY_7),
396
397 LANGINFO(MON_1),
398 LANGINFO(MON_2),
399 LANGINFO(MON_3),
400 LANGINFO(MON_4),
401 LANGINFO(MON_5),
402 LANGINFO(MON_6),
403 LANGINFO(MON_7),
404 LANGINFO(MON_8),
405 LANGINFO(MON_9),
406 LANGINFO(MON_10),
407 LANGINFO(MON_11),
408 LANGINFO(MON_12),
409
410 LANGINFO(ABMON_1),
411 LANGINFO(ABMON_2),
412 LANGINFO(ABMON_3),
413 LANGINFO(ABMON_4),
414 LANGINFO(ABMON_5),
415 LANGINFO(ABMON_6),
416 LANGINFO(ABMON_7),
417 LANGINFO(ABMON_8),
418 LANGINFO(ABMON_9),
419 LANGINFO(ABMON_10),
420 LANGINFO(ABMON_11),
421 LANGINFO(ABMON_12),
422
423#ifdef RADIXCHAR
424 /* The following are not available with glibc 2.0 */
425 LANGINFO(RADIXCHAR),
426 LANGINFO(THOUSEP),
427 /* YESSTR and NOSTR are deprecated in glibc, since they are
428 a special case of message translation, which should be rather
429 done using gettext. So we don't expose it to Python in the
430 first place.
431 LANGINFO(YESSTR),
432 LANGINFO(NOSTR),
433 */
434 LANGINFO(CRNCYSTR),
435#endif
436
437 LANGINFO(D_T_FMT),
438 LANGINFO(D_FMT),
439 LANGINFO(T_FMT),
440 LANGINFO(AM_STR),
441 LANGINFO(PM_STR),
442
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000443 /* The following constants are available only with XPG4, but...
444 AIX 3.2. only has CODESET.
445 OpenBSD doesn't have CODESET but has T_FMT_AMPM, and doesn't have
446 a few of the others.
447 Solution: ifdef-test them all. */
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000448#ifdef CODESET
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000449 LANGINFO(CODESET),
Martin v. Löwis496f9e42002-03-27 12:15:57 +0000450#endif
451#ifdef T_FMT_AMPM
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000452 LANGINFO(T_FMT_AMPM),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000453#endif
454#ifdef ERA
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000455 LANGINFO(ERA),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000456#endif
457#ifdef ERA_D_FMT
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000458 LANGINFO(ERA_D_FMT),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000459#endif
460#ifdef ERA_D_T_FMT
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000461 LANGINFO(ERA_D_T_FMT),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000462#endif
463#ifdef ERA_T_FMT
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000464 LANGINFO(ERA_T_FMT),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000465#endif
466#ifdef ALT_DIGITS
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000467 LANGINFO(ALT_DIGITS),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000468#endif
469#ifdef YESEXPR
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000470 LANGINFO(YESEXPR),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000471#endif
472#ifdef NOEXPR
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000473 LANGINFO(NOEXPR),
474#endif
475#ifdef _DATE_FMT
476 /* This is not available in all glibc versions that have CODESET. */
477 LANGINFO(_DATE_FMT),
478#endif
479 {0, 0}
480};
481
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000482PyDoc_STRVAR(nl_langinfo__doc__,
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000483"nl_langinfo(key) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000484"Return the value for the locale information associated with key.");
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000485
486static PyObject*
487PyLocale_nl_langinfo(PyObject* self, PyObject* args)
488{
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000489 int item, i;
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000490 if (!PyArg_ParseTuple(args, "i:nl_langinfo", &item))
491 return NULL;
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000492 /* Check whether this is a supported constant. GNU libc sometimes
493 returns numeric values in the char* return value, which would
Neal Norwitz7f9d29c2007-08-26 07:21:45 +0000494 crash PyUnicode_FromString. */
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000495 for (i = 0; langinfo_constants[i].name; i++)
Hye-Shik Changc3a87b82004-03-21 19:34:30 +0000496 if (langinfo_constants[i].value == item) {
497 /* Check NULL as a workaround for GNU libc's returning NULL
498 instead of an empty string for nl_langinfo(ERA). */
499 const char *result = nl_langinfo(item);
Neal Norwitz3d7a90d2007-10-27 05:40:06 +0000500 result = result != NULL ? result : "";
Martin v. Löwis92fab752008-03-08 10:40:41 +0000501 return str2uni(result);
Hye-Shik Changc3a87b82004-03-21 19:34:30 +0000502 }
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000503 PyErr_SetString(PyExc_ValueError, "unsupported langinfo constant");
504 return NULL;
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000505}
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000506#endif /* HAVE_LANGINFO_H */
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000507
508#ifdef HAVE_LIBINTL_H
509
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000510PyDoc_STRVAR(gettext__doc__,
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000511"gettext(msg) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000512"Return translation of msg.");
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000513
514static PyObject*
515PyIntl_gettext(PyObject* self, PyObject *args)
516{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000517 char *in;
518 if (!PyArg_ParseTuple(args, "s", &in))
519 return 0;
520 return str2uni(gettext(in));
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000521}
522
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000523PyDoc_STRVAR(dgettext__doc__,
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000524"dgettext(domain, msg) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000525"Return translation of msg in domain.");
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000526
527static PyObject*
528PyIntl_dgettext(PyObject* self, PyObject *args)
529{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000530 char *domain, *in;
531 if (!PyArg_ParseTuple(args, "zs", &domain, &in))
532 return 0;
533 return str2uni(dgettext(domain, in));
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000534}
535
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000536PyDoc_STRVAR(dcgettext__doc__,
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000537"dcgettext(domain, msg, category) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000538"Return translation of msg in domain and category.");
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000539
540static PyObject*
541PyIntl_dcgettext(PyObject *self, PyObject *args)
542{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000543 char *domain, *msgid;
544 int category;
545 if (!PyArg_ParseTuple(args, "zsi", &domain, &msgid, &category))
546 return 0;
547 return str2uni(dcgettext(domain,msgid,category));
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000548}
549
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000550PyDoc_STRVAR(textdomain__doc__,
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000551"textdomain(domain) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000552"Set the C library's textdmain to domain, returning the new domain.");
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000553
554static PyObject*
555PyIntl_textdomain(PyObject* self, PyObject* args)
556{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000557 char *domain;
558 if (!PyArg_ParseTuple(args, "z", &domain))
559 return 0;
560 domain = textdomain(domain);
561 if (!domain) {
562 PyErr_SetFromErrno(PyExc_OSError);
563 return NULL;
564 }
565 return str2uni(domain);
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000566}
567
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000568PyDoc_STRVAR(bindtextdomain__doc__,
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000569"bindtextdomain(domain, dir) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000570"Bind the C library's domain to dir.");
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000571
572static PyObject*
573PyIntl_bindtextdomain(PyObject* self,PyObject*args)
574{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000575 char *domain, *dirname;
576 if (!PyArg_ParseTuple(args, "sz", &domain, &dirname))
577 return 0;
578 if (!strlen(domain)) {
579 PyErr_SetString(Error, "domain must be a non-empty string");
580 return 0;
581 }
582 dirname = bindtextdomain(domain, dirname);
583 if (!dirname) {
584 PyErr_SetFromErrno(PyExc_OSError);
585 return NULL;
586 }
587 return str2uni(dirname);
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000588}
589
Gustavo Niemeyer7bd33c52004-07-22 18:44:01 +0000590#ifdef HAVE_BIND_TEXTDOMAIN_CODESET
591PyDoc_STRVAR(bind_textdomain_codeset__doc__,
592"bind_textdomain_codeset(domain, codeset) -> string\n"
593"Bind the C library's domain to codeset.");
594
595static PyObject*
596PyIntl_bind_textdomain_codeset(PyObject* self,PyObject*args)
597{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000598 char *domain,*codeset;
599 if (!PyArg_ParseTuple(args, "sz", &domain, &codeset))
600 return NULL;
601 codeset = bind_textdomain_codeset(domain, codeset);
602 if (codeset)
603 return str2uni(codeset);
604 Py_RETURN_NONE;
Gustavo Niemeyer7bd33c52004-07-22 18:44:01 +0000605}
606#endif
607
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000608#endif
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000609
Guido van Rossum220ecc81997-11-18 21:03:39 +0000610static struct PyMethodDef PyLocale_Methods[] = {
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000611 {"setlocale", (PyCFunction) PyLocale_setlocale,
Andrew M. Kuchlinge365fb82000-08-03 02:06:16 +0000612 METH_VARARGS, setlocale__doc__},
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000613 {"localeconv", (PyCFunction) PyLocale_localeconv,
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000614 METH_NOARGS, localeconv__doc__},
Martin v. Löwis92fab752008-03-08 10:40:41 +0000615#ifdef HAVE_WCSCOLL
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000616 {"strcoll", (PyCFunction) PyLocale_strcoll,
Andrew M. Kuchlinge365fb82000-08-03 02:06:16 +0000617 METH_VARARGS, strcoll__doc__},
Martin v. Löwis92fab752008-03-08 10:40:41 +0000618#endif
619#ifdef HAVE_WCSXFRM
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000620 {"strxfrm", (PyCFunction) PyLocale_strxfrm,
Andrew M. Kuchlinge365fb82000-08-03 02:06:16 +0000621 METH_VARARGS, strxfrm__doc__},
Martin v. Löwis92fab752008-03-08 10:40:41 +0000622#endif
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000623#if defined(MS_WINDOWS)
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000624 {"_getdefaultlocale", (PyCFunction) PyLocale_getdefaultlocale, METH_NOARGS},
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000625#endif
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000626#ifdef HAVE_LANGINFO_H
627 {"nl_langinfo", (PyCFunction) PyLocale_nl_langinfo,
628 METH_VARARGS, nl_langinfo__doc__},
629#endif
Martin v. Löwisc6a7d7e2002-05-02 12:16:29 +0000630#ifdef HAVE_LIBINTL_H
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000631 {"gettext",(PyCFunction)PyIntl_gettext,METH_VARARGS,
632 gettext__doc__},
633 {"dgettext",(PyCFunction)PyIntl_dgettext,METH_VARARGS,
634 dgettext__doc__},
635 {"dcgettext",(PyCFunction)PyIntl_dcgettext,METH_VARARGS,
636 dcgettext__doc__},
637 {"textdomain",(PyCFunction)PyIntl_textdomain,METH_VARARGS,
638 textdomain__doc__},
639 {"bindtextdomain",(PyCFunction)PyIntl_bindtextdomain,METH_VARARGS,
640 bindtextdomain__doc__},
Gustavo Niemeyer7bd33c52004-07-22 18:44:01 +0000641#ifdef HAVE_BIND_TEXTDOMAIN_CODESET
642 {"bind_textdomain_codeset",(PyCFunction)PyIntl_bind_textdomain_codeset,
643 METH_VARARGS, bind_textdomain_codeset__doc__},
644#endif
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000645#endif
Guido van Rossum220ecc81997-11-18 21:03:39 +0000646 {NULL, NULL}
647};
648
Martin v. Löwis1a214512008-06-11 05:26:20 +0000649
650static struct PyModuleDef _localemodule = {
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000651 PyModuleDef_HEAD_INIT,
652 "_locale",
653 locale__doc__,
654 -1,
655 PyLocale_Methods,
656 NULL,
657 NULL,
658 NULL,
659 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +0000660};
661
Mark Hammondfe51c6d2002-08-02 02:27:13 +0000662PyMODINIT_FUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +0000663PyInit__locale(void)
Guido van Rossum220ecc81997-11-18 21:03:39 +0000664{
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000665 PyObject *m, *d, *x;
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000666#ifdef HAVE_LANGINFO_H
667 int i;
668#endif
Guido van Rossum220ecc81997-11-18 21:03:39 +0000669
Martin v. Löwis1a214512008-06-11 05:26:20 +0000670 m = PyModule_Create(&_localemodule);
Neal Norwitz1ac754f2006-01-19 06:09:39 +0000671 if (m == NULL)
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000672 return NULL;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000673
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000674 d = PyModule_GetDict(m);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000675
Christian Heimes217cfd12007-12-02 14:31:20 +0000676 x = PyLong_FromLong(LC_CTYPE);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000677 PyDict_SetItemString(d, "LC_CTYPE", x);
678 Py_XDECREF(x);
679
Christian Heimes217cfd12007-12-02 14:31:20 +0000680 x = PyLong_FromLong(LC_TIME);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000681 PyDict_SetItemString(d, "LC_TIME", x);
682 Py_XDECREF(x);
683
Christian Heimes217cfd12007-12-02 14:31:20 +0000684 x = PyLong_FromLong(LC_COLLATE);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000685 PyDict_SetItemString(d, "LC_COLLATE", x);
686 Py_XDECREF(x);
687
Christian Heimes217cfd12007-12-02 14:31:20 +0000688 x = PyLong_FromLong(LC_MONETARY);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000689 PyDict_SetItemString(d, "LC_MONETARY", x);
690 Py_XDECREF(x);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000691
Guido van Rossum8d9c2e31997-12-09 19:35:11 +0000692#ifdef LC_MESSAGES
Christian Heimes217cfd12007-12-02 14:31:20 +0000693 x = PyLong_FromLong(LC_MESSAGES);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000694 PyDict_SetItemString(d, "LC_MESSAGES", x);
695 Py_XDECREF(x);
Guido van Rossum8d9c2e31997-12-09 19:35:11 +0000696#endif /* LC_MESSAGES */
Guido van Rossum220ecc81997-11-18 21:03:39 +0000697
Christian Heimes217cfd12007-12-02 14:31:20 +0000698 x = PyLong_FromLong(LC_NUMERIC);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000699 PyDict_SetItemString(d, "LC_NUMERIC", x);
700 Py_XDECREF(x);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000701
Christian Heimes217cfd12007-12-02 14:31:20 +0000702 x = PyLong_FromLong(LC_ALL);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000703 PyDict_SetItemString(d, "LC_ALL", x);
704 Py_XDECREF(x);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000705
Christian Heimes217cfd12007-12-02 14:31:20 +0000706 x = PyLong_FromLong(CHAR_MAX);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000707 PyDict_SetItemString(d, "CHAR_MAX", x);
708 Py_XDECREF(x);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000709
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000710 Error = PyErr_NewException("locale.Error", NULL, NULL);
711 PyDict_SetItemString(d, "Error", Error);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000712
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000713#ifdef HAVE_LANGINFO_H
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000714 for (i = 0; langinfo_constants[i].name; i++) {
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000715 PyModule_AddIntConstant(m, langinfo_constants[i].name,
716 langinfo_constants[i].value);
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000717 }
Martin v. Löwisf95dd0a2001-08-15 17:14:33 +0000718#endif
Martin v. Löwis1a214512008-06-11 05:26:20 +0000719 return m;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000720}
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000721
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000722/*
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000723Local variables:
724c-basic-offset: 4
725indent-tabs-mode: nil
726End:
727*/