blob: 0b657c40813446b0210525ef039e343380473b09 [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{
52 size_t needed = mbstowcs(NULL, s, 0);
53 size_t res1;
54 wchar_t smallbuf[30];
55 wchar_t *dest;
56 PyObject *res2;
57 if (needed == (size_t)-1) {
58 PyErr_SetString(PyExc_ValueError, "Cannot convert byte to string");
59 return NULL;
60 }
61 if (needed < sizeof(smallbuf))
62 dest = smallbuf;
63 else {
Martin v. Löwisa69e1ef2008-03-08 10:54:31 +000064 dest = PyMem_Malloc((needed+1)*sizeof(wchar_t));
Martin v. Löwis92fab752008-03-08 10:40:41 +000065 if (!dest)
66 return PyErr_NoMemory();
67 }
68 /* This shouldn't fail now */
69 res1 = mbstowcs(dest, s, needed+1);
70 assert(res == needed);
71 res2 = PyUnicode_FromWideChar(dest, res1);
72 if (dest != smallbuf)
73 PyMem_Free(dest);
74 return res2;
75}
76
Guido van Rossum220ecc81997-11-18 21:03:39 +000077/* support functions for formatting floating point numbers */
78
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000079PyDoc_STRVAR(setlocale__doc__,
80"(integer,string=None) -> string. Activates/queries locale processing.");
Guido van Rossum220ecc81997-11-18 21:03:39 +000081
Guido van Rossum220ecc81997-11-18 21:03:39 +000082/* the grouping is terminated by either 0 or CHAR_MAX */
83static PyObject*
Fredrik Lundh8f017a02000-07-08 19:57:37 +000084copy_grouping(char* s)
Guido van Rossum220ecc81997-11-18 21:03:39 +000085{
Fredrik Lundh8f017a02000-07-08 19:57:37 +000086 int i;
87 PyObject *result, *val = NULL;
88
89 if (s[0] == '\0')
90 /* empty string: no grouping at all */
91 return PyList_New(0);
92
93 for (i = 0; s[i] != '\0' && s[i] != CHAR_MAX; i++)
94 ; /* nothing */
95
96 result = PyList_New(i+1);
97 if (!result)
98 return NULL;
99
100 i = -1;
101 do {
102 i++;
Christian Heimes217cfd12007-12-02 14:31:20 +0000103 val = PyLong_FromLong(s[i]);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000104 if (!val)
105 break;
106 if (PyList_SetItem(result, i, val)) {
107 Py_DECREF(val);
Fredrik Lundh89610a42000-07-08 20:07:24 +0000108 val = NULL;
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000109 break;
110 }
111 } while (s[i] != '\0' && s[i] != CHAR_MAX);
112
113 if (!val) {
114 Py_DECREF(result);
115 return NULL;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000116 }
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000117
118 return result;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000119}
120
Guido van Rossum220ecc81997-11-18 21:03:39 +0000121static PyObject*
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000122PyLocale_setlocale(PyObject* self, PyObject* args)
Guido van Rossum220ecc81997-11-18 21:03:39 +0000123{
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000124 int category;
125 char *locale = NULL, *result;
126 PyObject *result_object;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000127
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000128 if (!PyArg_ParseTuple(args, "i|z:setlocale", &category, &locale))
Fredrik Lundh89610a42000-07-08 20:07:24 +0000129 return NULL;
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000130
131 if (locale) {
132 /* set locale */
133 result = setlocale(category, locale);
134 if (!result) {
135 /* operation failed, no setting was changed */
Martin v. Löwis25f90d52003-09-03 04:50:13 +0000136 PyErr_SetString(Error, "unsupported locale setting");
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000137 return NULL;
138 }
Martin v. Löwis92fab752008-03-08 10:40:41 +0000139 result_object = str2uni(result);
Mark Hammond9a714752003-07-24 14:15:07 +0000140 if (!result_object)
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000141 return NULL;
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000142 } else {
143 /* get locale */
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000144 result = setlocale(category, NULL);
145 if (!result) {
146 PyErr_SetString(Error, "locale query failed");
147 return NULL;
148 }
Martin v. Löwis92fab752008-03-08 10:40:41 +0000149 result_object = str2uni(result);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000150 }
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000151 return result_object;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000152}
153
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000154PyDoc_STRVAR(localeconv__doc__,
155"() -> dict. Returns numeric and monetary locale-specific parameters.");
Guido van Rossum220ecc81997-11-18 21:03:39 +0000156
157static PyObject*
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000158PyLocale_localeconv(PyObject* self)
Guido van Rossum220ecc81997-11-18 21:03:39 +0000159{
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000160 PyObject* result;
161 struct lconv *l;
162 PyObject *x;
163
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000164 result = PyDict_New();
Fredrik Lundh89610a42000-07-08 20:07:24 +0000165 if (!result)
166 return NULL;
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000167
168 /* if LC_NUMERIC is different in the C library, use saved value */
169 l = localeconv();
170
171 /* hopefully, the localeconv result survives the C library calls
172 involved herein */
173
174#define RESULT_STRING(s)\
Martin v. Löwis92fab752008-03-08 10:40:41 +0000175 x = str2uni(l->s); \
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000176 if (!x) goto failed;\
177 PyDict_SetItemString(result, #s, x);\
178 Py_XDECREF(x)
179
180#define RESULT_INT(i)\
Christian Heimes217cfd12007-12-02 14:31:20 +0000181 x = PyLong_FromLong(l->i);\
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000182 if (!x) goto failed;\
183 PyDict_SetItemString(result, #i, x);\
184 Py_XDECREF(x)
Guido van Rossum220ecc81997-11-18 21:03:39 +0000185
186 /* Numeric information */
Martin v. Löwis737ea822004-06-08 18:52:54 +0000187 RESULT_STRING(decimal_point);
188 RESULT_STRING(thousands_sep);
189 x = copy_grouping(l->grouping);
190 if (!x)
191 goto failed;
192 PyDict_SetItemString(result, "grouping", x);
193 Py_XDECREF(x);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000194
195 /* Monetary information */
196 RESULT_STRING(int_curr_symbol);
197 RESULT_STRING(currency_symbol);
198 RESULT_STRING(mon_decimal_point);
199 RESULT_STRING(mon_thousands_sep);
200 x = copy_grouping(l->mon_grouping);
201 if (!x)
202 goto failed;
203 PyDict_SetItemString(result, "mon_grouping", x);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000204 Py_XDECREF(x);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000205 RESULT_STRING(positive_sign);
206 RESULT_STRING(negative_sign);
207 RESULT_INT(int_frac_digits);
208 RESULT_INT(frac_digits);
209 RESULT_INT(p_cs_precedes);
210 RESULT_INT(p_sep_by_space);
211 RESULT_INT(n_cs_precedes);
212 RESULT_INT(n_sep_by_space);
213 RESULT_INT(p_sign_posn);
214 RESULT_INT(n_sign_posn);
215 return result;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000216
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000217 failed:
218 Py_XDECREF(result);
219 Py_XDECREF(x);
220 return NULL;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000221}
222
Martin v. Löwis92fab752008-03-08 10:40:41 +0000223#if defined(HAVE_WCSCOLL)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000224PyDoc_STRVAR(strcoll__doc__,
225"string,string -> int. Compares two strings according to the locale.");
Guido van Rossum220ecc81997-11-18 21:03:39 +0000226
227static PyObject*
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000228PyLocale_strcoll(PyObject* self, PyObject* args)
Guido van Rossum220ecc81997-11-18 21:03:39 +0000229{
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000230 PyObject *os1, *os2, *result = NULL;
231 wchar_t *ws1 = NULL, *ws2 = NULL;
Martin v. Löwis92fab752008-03-08 10:40:41 +0000232 Py_ssize_t len1, len2;
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000233
Martin v. Löwis92fab752008-03-08 10:40:41 +0000234 if (!PyArg_ParseTuple(args, "UU:strcoll", &os1, &os2))
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000235 return NULL;
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000236 /* Convert the unicode strings to wchar[]. */
237 len1 = PyUnicode_GET_SIZE(os1) + 1;
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000238 ws1 = PyMem_MALLOC(len1 * sizeof(wchar_t));
239 if (!ws1) {
240 PyErr_NoMemory();
241 goto done;
242 }
243 if (PyUnicode_AsWideChar((PyUnicodeObject*)os1, ws1, len1) == -1)
244 goto done;
Marc-André Lemburga9cadcd2004-11-22 13:02:31 +0000245 ws1[len1 - 1] = 0;
246 len2 = PyUnicode_GET_SIZE(os2) + 1;
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000247 ws2 = PyMem_MALLOC(len2 * sizeof(wchar_t));
248 if (!ws2) {
249 PyErr_NoMemory();
250 goto done;
251 }
252 if (PyUnicode_AsWideChar((PyUnicodeObject*)os2, ws2, len2) == -1)
253 goto done;
Marc-André Lemburga9cadcd2004-11-22 13:02:31 +0000254 ws2[len2 - 1] = 0;
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__,
267"string -> string. Returns a string that behaves for cmp locale-aware.");
Guido van Rossum220ecc81997-11-18 21:03:39 +0000268
269static PyObject*
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000270PyLocale_strxfrm(PyObject* self, PyObject* args)
Guido van Rossum220ecc81997-11-18 21:03:39 +0000271{
Martin v. Löwis92fab752008-03-08 10:40:41 +0000272 Py_UNICODE *s0;
273 Py_ssize_t n0;
274 wchar_t *s, *buf = NULL;
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000275 size_t n1, n2;
Martin v. Löwis92fab752008-03-08 10:40:41 +0000276 PyObject *result = NULL;
277 Py_ssize_t i;
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000278
Martin v. Löwis92fab752008-03-08 10:40:41 +0000279 if (!PyArg_ParseTuple(args, "u#:strxfrm", &s0, &n0))
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000280 return NULL;
281
Martin v. Löwis92fab752008-03-08 10:40:41 +0000282#ifdef HAVE_USABLE_WCHAR_T
283 s = s0;
284#else
Martin v. Löwisa69e1ef2008-03-08 10:54:31 +0000285 s = PyMem_Malloc((n0+1)*sizeof(wchar_t));
Martin v. Löwis92fab752008-03-08 10:40:41 +0000286 if (!s)
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000287 return PyErr_NoMemory();
Martin v. Löwis92fab752008-03-08 10:40:41 +0000288 for (i=0; i<=n0; i++)
289 s[i] = s0[i];
290#endif
291
292 /* assume no change in size, first */
293 n1 = wcslen(s) + 1;
Martin v. Löwisa69e1ef2008-03-08 10:54:31 +0000294 buf = PyMem_Malloc(n1*sizeof(wchar_t));
Martin v. Löwis92fab752008-03-08 10:40:41 +0000295 if (!buf) {
296 PyErr_NoMemory();
297 goto exit;
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000298 }
Martin v. Löwis92fab752008-03-08 10:40:41 +0000299 n2 = wcsxfrm(buf, s, n1);
300 if (n2 >= n1) {
301 /* more space needed */
Martin v. Löwisa69e1ef2008-03-08 10:54:31 +0000302 buf = PyMem_Realloc(buf, (n2+1)*sizeof(wchar_t));
Martin v. Löwis92fab752008-03-08 10:40:41 +0000303 if (!buf) {
304 PyErr_NoMemory();
305 goto exit;
306 }
307 n2 = wcsxfrm(buf, s, n2);
308 }
309 result = PyUnicode_FromWideChar(buf, n2);
310 exit:
311 if (buf) PyMem_Free(buf);
312#ifdef HAVE_USABLE_WCHAR_T
313 PyMem_Free(s);
314#endif
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000315 return result;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000316}
Martin v. Löwis92fab752008-03-08 10:40:41 +0000317#endif
Guido van Rossum220ecc81997-11-18 21:03:39 +0000318
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000319#if defined(MS_WINDOWS)
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000320static PyObject*
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000321PyLocale_getdefaultlocale(PyObject* self)
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000322{
323 char encoding[100];
324 char locale[100];
325
Tim Peters885d4572001-11-28 20:27:42 +0000326 PyOS_snprintf(encoding, sizeof(encoding), "cp%d", GetACP());
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000327
328 if (GetLocaleInfo(LOCALE_USER_DEFAULT,
329 LOCALE_SISO639LANGNAME,
330 locale, sizeof(locale))) {
Martin v. Löwis18e16552006-02-15 17:27:45 +0000331 Py_ssize_t i = strlen(locale);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000332 locale[i++] = '_';
333 if (GetLocaleInfo(LOCALE_USER_DEFAULT,
334 LOCALE_SISO3166CTRYNAME,
Martin v. Löwis18e16552006-02-15 17:27:45 +0000335 locale+i, (int)(sizeof(locale)-i)))
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000336 return Py_BuildValue("ss", locale, encoding);
337 }
338
339 /* If we end up here, this windows version didn't know about
340 ISO639/ISO3166 names (it's probably Windows 95). Return the
341 Windows language identifier instead (a hexadecimal number) */
342
343 locale[0] = '0';
344 locale[1] = 'x';
345 if (GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_IDEFAULTLANGUAGE,
346 locale+2, sizeof(locale)-2)) {
347 return Py_BuildValue("ss", locale, encoding);
348 }
349
350 /* cannot determine the language code (very unlikely) */
351 Py_INCREF(Py_None);
352 return Py_BuildValue("Os", Py_None, encoding);
353}
354#endif
355
Martin v. Löwis52ea7e92002-11-26 09:05:36 +0000356#if defined(__APPLE__)
Jack Jansen59f072a2004-07-15 13:31:39 +0000357/*
358** Find out what the current script is.
Brett Cannon269ab622004-08-27 05:00:22 +0000359** Donated by Fredrik Lundh.
Jack Jansen59f072a2004-07-15 13:31:39 +0000360*/
361static char *mac_getscript(void)
362{
363 CFStringEncoding enc = CFStringGetSystemEncoding();
364 static CFStringRef name = NULL;
365 /* Return the code name for the encodings for which we have codecs. */
366 switch(enc) {
367 case kCFStringEncodingMacRoman: return "mac-roman";
368 case kCFStringEncodingMacGreek: return "mac-greek";
369 case kCFStringEncodingMacCyrillic: return "mac-cyrillic";
370 case kCFStringEncodingMacTurkish: return "mac-turkish";
371 case kCFStringEncodingMacIcelandic: return "mac-icelandic";
372 /* XXX which one is mac-latin2? */
373 }
374 if (!name) {
Brett Cannon5ce25872005-03-01 03:16:34 +0000375 /* This leaks an object. */
Jack Jansen59f072a2004-07-15 13:31:39 +0000376 name = CFStringConvertEncodingToIANACharSetName(enc);
377 }
378 return (char *)CFStringGetCStringPtr(name, 0);
379}
380
Jack Jansen307d7a42000-07-15 22:31:45 +0000381static PyObject*
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000382PyLocale_getdefaultlocale(PyObject* self)
Jack Jansen307d7a42000-07-15 22:31:45 +0000383{
Jack Jansen59f072a2004-07-15 13:31:39 +0000384 return Py_BuildValue("Os", Py_None, mac_getscript());
Jack Jansen307d7a42000-07-15 22:31:45 +0000385}
386#endif
387
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000388#ifdef HAVE_LANGINFO_H
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000389#define LANGINFO(X) {#X, X}
390struct langinfo_constant{
391 char* name;
392 int value;
393} langinfo_constants[] =
394{
395 /* These constants should exist on any langinfo implementation */
396 LANGINFO(DAY_1),
397 LANGINFO(DAY_2),
398 LANGINFO(DAY_3),
399 LANGINFO(DAY_4),
400 LANGINFO(DAY_5),
401 LANGINFO(DAY_6),
402 LANGINFO(DAY_7),
403
404 LANGINFO(ABDAY_1),
405 LANGINFO(ABDAY_2),
406 LANGINFO(ABDAY_3),
407 LANGINFO(ABDAY_4),
408 LANGINFO(ABDAY_5),
409 LANGINFO(ABDAY_6),
410 LANGINFO(ABDAY_7),
411
412 LANGINFO(MON_1),
413 LANGINFO(MON_2),
414 LANGINFO(MON_3),
415 LANGINFO(MON_4),
416 LANGINFO(MON_5),
417 LANGINFO(MON_6),
418 LANGINFO(MON_7),
419 LANGINFO(MON_8),
420 LANGINFO(MON_9),
421 LANGINFO(MON_10),
422 LANGINFO(MON_11),
423 LANGINFO(MON_12),
424
425 LANGINFO(ABMON_1),
426 LANGINFO(ABMON_2),
427 LANGINFO(ABMON_3),
428 LANGINFO(ABMON_4),
429 LANGINFO(ABMON_5),
430 LANGINFO(ABMON_6),
431 LANGINFO(ABMON_7),
432 LANGINFO(ABMON_8),
433 LANGINFO(ABMON_9),
434 LANGINFO(ABMON_10),
435 LANGINFO(ABMON_11),
436 LANGINFO(ABMON_12),
437
438#ifdef RADIXCHAR
439 /* The following are not available with glibc 2.0 */
440 LANGINFO(RADIXCHAR),
441 LANGINFO(THOUSEP),
442 /* YESSTR and NOSTR are deprecated in glibc, since they are
443 a special case of message translation, which should be rather
444 done using gettext. So we don't expose it to Python in the
445 first place.
446 LANGINFO(YESSTR),
447 LANGINFO(NOSTR),
448 */
449 LANGINFO(CRNCYSTR),
450#endif
451
452 LANGINFO(D_T_FMT),
453 LANGINFO(D_FMT),
454 LANGINFO(T_FMT),
455 LANGINFO(AM_STR),
456 LANGINFO(PM_STR),
457
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000458 /* The following constants are available only with XPG4, but...
459 AIX 3.2. only has CODESET.
460 OpenBSD doesn't have CODESET but has T_FMT_AMPM, and doesn't have
461 a few of the others.
462 Solution: ifdef-test them all. */
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000463#ifdef CODESET
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000464 LANGINFO(CODESET),
Martin v. Löwis496f9e42002-03-27 12:15:57 +0000465#endif
466#ifdef T_FMT_AMPM
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000467 LANGINFO(T_FMT_AMPM),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000468#endif
469#ifdef ERA
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000470 LANGINFO(ERA),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000471#endif
472#ifdef ERA_D_FMT
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000473 LANGINFO(ERA_D_FMT),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000474#endif
475#ifdef ERA_D_T_FMT
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000476 LANGINFO(ERA_D_T_FMT),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000477#endif
478#ifdef ERA_T_FMT
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000479 LANGINFO(ERA_T_FMT),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000480#endif
481#ifdef ALT_DIGITS
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000482 LANGINFO(ALT_DIGITS),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000483#endif
484#ifdef YESEXPR
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000485 LANGINFO(YESEXPR),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000486#endif
487#ifdef NOEXPR
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000488 LANGINFO(NOEXPR),
489#endif
490#ifdef _DATE_FMT
491 /* This is not available in all glibc versions that have CODESET. */
492 LANGINFO(_DATE_FMT),
493#endif
494 {0, 0}
495};
496
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000497PyDoc_STRVAR(nl_langinfo__doc__,
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000498"nl_langinfo(key) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000499"Return the value for the locale information associated with key.");
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000500
501static PyObject*
502PyLocale_nl_langinfo(PyObject* self, PyObject* args)
503{
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000504 int item, i;
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000505 if (!PyArg_ParseTuple(args, "i:nl_langinfo", &item))
506 return NULL;
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000507 /* Check whether this is a supported constant. GNU libc sometimes
508 returns numeric values in the char* return value, which would
Neal Norwitz7f9d29c2007-08-26 07:21:45 +0000509 crash PyUnicode_FromString. */
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000510 for (i = 0; langinfo_constants[i].name; i++)
Hye-Shik Changc3a87b82004-03-21 19:34:30 +0000511 if (langinfo_constants[i].value == item) {
512 /* Check NULL as a workaround for GNU libc's returning NULL
513 instead of an empty string for nl_langinfo(ERA). */
514 const char *result = nl_langinfo(item);
Neal Norwitz3d7a90d2007-10-27 05:40:06 +0000515 result = result != NULL ? result : "";
Martin v. Löwis92fab752008-03-08 10:40:41 +0000516 return str2uni(result);
Hye-Shik Changc3a87b82004-03-21 19:34:30 +0000517 }
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000518 PyErr_SetString(PyExc_ValueError, "unsupported langinfo constant");
519 return NULL;
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000520}
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000521#endif /* HAVE_LANGINFO_H */
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000522
523#ifdef HAVE_LIBINTL_H
524
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000525PyDoc_STRVAR(gettext__doc__,
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000526"gettext(msg) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000527"Return translation of msg.");
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000528
529static PyObject*
530PyIntl_gettext(PyObject* self, PyObject *args)
531{
532 char *in;
533 if (!PyArg_ParseTuple(args, "z", &in))
534 return 0;
Martin v. Löwis92fab752008-03-08 10:40:41 +0000535 return str2uni(gettext(in));
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000536}
537
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000538PyDoc_STRVAR(dgettext__doc__,
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000539"dgettext(domain, msg) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000540"Return translation of msg in domain.");
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000541
542static PyObject*
543PyIntl_dgettext(PyObject* self, PyObject *args)
544{
545 char *domain, *in;
546 if (!PyArg_ParseTuple(args, "zz", &domain, &in))
547 return 0;
Martin v. Löwis92fab752008-03-08 10:40:41 +0000548 return str2uni(dgettext(domain, in));
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000549}
550
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000551PyDoc_STRVAR(dcgettext__doc__,
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000552"dcgettext(domain, msg, category) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000553"Return translation of msg in domain and category.");
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000554
555static PyObject*
556PyIntl_dcgettext(PyObject *self, PyObject *args)
557{
558 char *domain, *msgid;
559 int category;
560 if (!PyArg_ParseTuple(args, "zzi", &domain, &msgid, &category))
561 return 0;
Martin v. Löwis92fab752008-03-08 10:40:41 +0000562 return str2uni(dcgettext(domain,msgid,category));
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000563}
564
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000565PyDoc_STRVAR(textdomain__doc__,
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000566"textdomain(domain) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000567"Set the C library's textdmain to domain, returning the new domain.");
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000568
569static PyObject*
570PyIntl_textdomain(PyObject* self, PyObject* args)
571{
572 char *domain;
573 if (!PyArg_ParseTuple(args, "z", &domain))
574 return 0;
575 domain = textdomain(domain);
576 if (!domain) {
577 PyErr_SetFromErrno(PyExc_OSError);
578 return NULL;
579 }
Martin v. Löwis92fab752008-03-08 10:40:41 +0000580 return str2uni(domain);
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000581}
582
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000583PyDoc_STRVAR(bindtextdomain__doc__,
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000584"bindtextdomain(domain, dir) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000585"Bind the C library's domain to dir.");
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000586
587static PyObject*
588PyIntl_bindtextdomain(PyObject* self,PyObject*args)
589{
590 char *domain,*dirname;
591 if (!PyArg_ParseTuple(args, "zz", &domain, &dirname))
592 return 0;
593 dirname = bindtextdomain(domain, dirname);
594 if (!dirname) {
595 PyErr_SetFromErrno(PyExc_OSError);
596 return NULL;
597 }
Martin v. Löwis92fab752008-03-08 10:40:41 +0000598 return str2uni(dirname);
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000599}
600
Gustavo Niemeyer7bd33c52004-07-22 18:44:01 +0000601#ifdef HAVE_BIND_TEXTDOMAIN_CODESET
602PyDoc_STRVAR(bind_textdomain_codeset__doc__,
603"bind_textdomain_codeset(domain, codeset) -> string\n"
604"Bind the C library's domain to codeset.");
605
606static PyObject*
607PyIntl_bind_textdomain_codeset(PyObject* self,PyObject*args)
608{
609 char *domain,*codeset;
610 if (!PyArg_ParseTuple(args, "sz", &domain, &codeset))
611 return NULL;
612 codeset = bind_textdomain_codeset(domain, codeset);
613 if (codeset)
Martin v. Löwis92fab752008-03-08 10:40:41 +0000614 return str2uni(codeset);
Gustavo Niemeyer7bd33c52004-07-22 18:44:01 +0000615 Py_RETURN_NONE;
616}
617#endif
618
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000619#endif
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000620
Guido van Rossum220ecc81997-11-18 21:03:39 +0000621static struct PyMethodDef PyLocale_Methods[] = {
Andrew M. Kuchlinge365fb82000-08-03 02:06:16 +0000622 {"setlocale", (PyCFunction) PyLocale_setlocale,
623 METH_VARARGS, setlocale__doc__},
624 {"localeconv", (PyCFunction) PyLocale_localeconv,
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000625 METH_NOARGS, localeconv__doc__},
Martin v. Löwis92fab752008-03-08 10:40:41 +0000626#ifdef HAVE_WCSCOLL
Andrew M. Kuchlinge365fb82000-08-03 02:06:16 +0000627 {"strcoll", (PyCFunction) PyLocale_strcoll,
628 METH_VARARGS, strcoll__doc__},
Martin v. Löwis92fab752008-03-08 10:40:41 +0000629#endif
630#ifdef HAVE_WCSXFRM
Andrew M. Kuchlinge365fb82000-08-03 02:06:16 +0000631 {"strxfrm", (PyCFunction) PyLocale_strxfrm,
632 METH_VARARGS, strxfrm__doc__},
Martin v. Löwis92fab752008-03-08 10:40:41 +0000633#endif
Martin v. Löwis52ea7e92002-11-26 09:05:36 +0000634#if defined(MS_WINDOWS) || defined(__APPLE__)
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000635 {"_getdefaultlocale", (PyCFunction) PyLocale_getdefaultlocale, METH_NOARGS},
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000636#endif
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000637#ifdef HAVE_LANGINFO_H
638 {"nl_langinfo", (PyCFunction) PyLocale_nl_langinfo,
639 METH_VARARGS, nl_langinfo__doc__},
640#endif
Martin v. Löwisc6a7d7e2002-05-02 12:16:29 +0000641#ifdef HAVE_LIBINTL_H
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000642 {"gettext",(PyCFunction)PyIntl_gettext,METH_VARARGS,
643 gettext__doc__},
644 {"dgettext",(PyCFunction)PyIntl_dgettext,METH_VARARGS,
645 dgettext__doc__},
646 {"dcgettext",(PyCFunction)PyIntl_dcgettext,METH_VARARGS,
647 dcgettext__doc__},
648 {"textdomain",(PyCFunction)PyIntl_textdomain,METH_VARARGS,
649 textdomain__doc__},
650 {"bindtextdomain",(PyCFunction)PyIntl_bindtextdomain,METH_VARARGS,
651 bindtextdomain__doc__},
Gustavo Niemeyer7bd33c52004-07-22 18:44:01 +0000652#ifdef HAVE_BIND_TEXTDOMAIN_CODESET
653 {"bind_textdomain_codeset",(PyCFunction)PyIntl_bind_textdomain_codeset,
654 METH_VARARGS, bind_textdomain_codeset__doc__},
655#endif
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000656#endif
Guido van Rossum220ecc81997-11-18 21:03:39 +0000657 {NULL, NULL}
658};
659
Mark Hammondfe51c6d2002-08-02 02:27:13 +0000660PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000661init_locale(void)
Guido van Rossum220ecc81997-11-18 21:03:39 +0000662{
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000663 PyObject *m, *d, *x;
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000664#ifdef HAVE_LANGINFO_H
665 int i;
666#endif
Guido van Rossum220ecc81997-11-18 21:03:39 +0000667
Neal Norwitzf9e115a2007-08-23 18:08:11 +0000668 m = Py_InitModule3("_locale", PyLocale_Methods, locale__doc__);
Neal Norwitz1ac754f2006-01-19 06:09:39 +0000669 if (m == NULL)
670 return;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000671
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000672 d = PyModule_GetDict(m);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000673
Christian Heimes217cfd12007-12-02 14:31:20 +0000674 x = PyLong_FromLong(LC_CTYPE);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000675 PyDict_SetItemString(d, "LC_CTYPE", x);
676 Py_XDECREF(x);
677
Christian Heimes217cfd12007-12-02 14:31:20 +0000678 x = PyLong_FromLong(LC_TIME);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000679 PyDict_SetItemString(d, "LC_TIME", x);
680 Py_XDECREF(x);
681
Christian Heimes217cfd12007-12-02 14:31:20 +0000682 x = PyLong_FromLong(LC_COLLATE);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000683 PyDict_SetItemString(d, "LC_COLLATE", x);
684 Py_XDECREF(x);
685
Christian Heimes217cfd12007-12-02 14:31:20 +0000686 x = PyLong_FromLong(LC_MONETARY);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000687 PyDict_SetItemString(d, "LC_MONETARY", x);
688 Py_XDECREF(x);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000689
Guido van Rossum8d9c2e31997-12-09 19:35:11 +0000690#ifdef LC_MESSAGES
Christian Heimes217cfd12007-12-02 14:31:20 +0000691 x = PyLong_FromLong(LC_MESSAGES);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000692 PyDict_SetItemString(d, "LC_MESSAGES", x);
693 Py_XDECREF(x);
Guido van Rossum8d9c2e31997-12-09 19:35:11 +0000694#endif /* LC_MESSAGES */
Guido van Rossum220ecc81997-11-18 21:03:39 +0000695
Christian Heimes217cfd12007-12-02 14:31:20 +0000696 x = PyLong_FromLong(LC_NUMERIC);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000697 PyDict_SetItemString(d, "LC_NUMERIC", x);
698 Py_XDECREF(x);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000699
Christian Heimes217cfd12007-12-02 14:31:20 +0000700 x = PyLong_FromLong(LC_ALL);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000701 PyDict_SetItemString(d, "LC_ALL", x);
702 Py_XDECREF(x);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000703
Christian Heimes217cfd12007-12-02 14:31:20 +0000704 x = PyLong_FromLong(CHAR_MAX);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000705 PyDict_SetItemString(d, "CHAR_MAX", x);
706 Py_XDECREF(x);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000707
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000708 Error = PyErr_NewException("locale.Error", NULL, NULL);
709 PyDict_SetItemString(d, "Error", Error);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000710
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000711#ifdef HAVE_LANGINFO_H
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000712 for (i = 0; langinfo_constants[i].name; i++) {
713 PyModule_AddIntConstant(m, langinfo_constants[i].name,
714 langinfo_constants[i].value);
715 }
Martin v. Löwisf95dd0a2001-08-15 17:14:33 +0000716#endif
Guido van Rossum220ecc81997-11-18 21:03:39 +0000717}
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000718
719/*
720Local variables:
721c-basic-offset: 4
722indent-tabs-mode: nil
723End:
724*/