blob: 7c816ff3e3adfceb1d9cc31c6fbcb66886ea776a [file] [log] [blame]
Guido van Rossum220ecc81997-11-18 21:03:39 +00001/***********************************************************
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +00002Copyright (C) 1997, 2002, 2003, 2007 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
48/* support functions for formatting floating point numbers */
49
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000050PyDoc_STRVAR(setlocale__doc__,
51"(integer,string=None) -> string. Activates/queries locale processing.");
Guido van Rossum220ecc81997-11-18 21:03:39 +000052
Guido van Rossum220ecc81997-11-18 21:03:39 +000053/* the grouping is terminated by either 0 or CHAR_MAX */
54static PyObject*
Fredrik Lundh8f017a02000-07-08 19:57:37 +000055copy_grouping(char* s)
Guido van Rossum220ecc81997-11-18 21:03:39 +000056{
Fredrik Lundh8f017a02000-07-08 19:57:37 +000057 int i;
58 PyObject *result, *val = NULL;
59
60 if (s[0] == '\0')
61 /* empty string: no grouping at all */
62 return PyList_New(0);
63
64 for (i = 0; s[i] != '\0' && s[i] != CHAR_MAX; i++)
65 ; /* nothing */
66
67 result = PyList_New(i+1);
68 if (!result)
69 return NULL;
70
71 i = -1;
72 do {
73 i++;
74 val = PyInt_FromLong(s[i]);
75 if (!val)
76 break;
77 if (PyList_SetItem(result, i, val)) {
78 Py_DECREF(val);
Fredrik Lundh89610a42000-07-08 20:07:24 +000079 val = NULL;
Fredrik Lundh8f017a02000-07-08 19:57:37 +000080 break;
81 }
82 } while (s[i] != '\0' && s[i] != CHAR_MAX);
83
84 if (!val) {
85 Py_DECREF(result);
86 return NULL;
Guido van Rossum220ecc81997-11-18 21:03:39 +000087 }
Fredrik Lundh8f017a02000-07-08 19:57:37 +000088
89 return result;
Guido van Rossum220ecc81997-11-18 21:03:39 +000090}
91
Guido van Rossum220ecc81997-11-18 21:03:39 +000092static PyObject*
Fredrik Lundh8f017a02000-07-08 19:57:37 +000093PyLocale_setlocale(PyObject* self, PyObject* args)
Guido van Rossum220ecc81997-11-18 21:03:39 +000094{
Fredrik Lundh8f017a02000-07-08 19:57:37 +000095 int category;
96 char *locale = NULL, *result;
97 PyObject *result_object;
Guido van Rossum220ecc81997-11-18 21:03:39 +000098
Fredrik Lundh8f017a02000-07-08 19:57:37 +000099 if (!PyArg_ParseTuple(args, "i|z:setlocale", &category, &locale))
Fredrik Lundh89610a42000-07-08 20:07:24 +0000100 return NULL;
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000101
102 if (locale) {
103 /* set locale */
104 result = setlocale(category, locale);
105 if (!result) {
106 /* operation failed, no setting was changed */
Martin v. Löwis25f90d52003-09-03 04:50:13 +0000107 PyErr_SetString(Error, "unsupported locale setting");
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000108 return NULL;
109 }
Neal Norwitz7f9d29c2007-08-26 07:21:45 +0000110 result_object = PyUnicode_FromString(result);
Mark Hammond9a714752003-07-24 14:15:07 +0000111 if (!result_object)
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000112 return NULL;
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000113 } else {
114 /* get locale */
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000115 result = setlocale(category, NULL);
116 if (!result) {
117 PyErr_SetString(Error, "locale query failed");
118 return NULL;
119 }
Neal Norwitz7f9d29c2007-08-26 07:21:45 +0000120 result_object = PyUnicode_FromString(result);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000121 }
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000122 return result_object;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000123}
124
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000125PyDoc_STRVAR(localeconv__doc__,
126"() -> dict. Returns numeric and monetary locale-specific parameters.");
Guido van Rossum220ecc81997-11-18 21:03:39 +0000127
128static PyObject*
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000129PyLocale_localeconv(PyObject* self)
Guido van Rossum220ecc81997-11-18 21:03:39 +0000130{
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000131 PyObject* result;
132 struct lconv *l;
133 PyObject *x;
134
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000135 result = PyDict_New();
Fredrik Lundh89610a42000-07-08 20:07:24 +0000136 if (!result)
137 return NULL;
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000138
139 /* if LC_NUMERIC is different in the C library, use saved value */
140 l = localeconv();
141
142 /* hopefully, the localeconv result survives the C library calls
143 involved herein */
144
145#define RESULT_STRING(s)\
Neal Norwitz7f9d29c2007-08-26 07:21:45 +0000146 x = PyUnicode_FromString(l->s);\
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000147 if (!x) goto failed;\
148 PyDict_SetItemString(result, #s, x);\
149 Py_XDECREF(x)
150
151#define RESULT_INT(i)\
152 x = PyInt_FromLong(l->i);\
153 if (!x) goto failed;\
154 PyDict_SetItemString(result, #i, x);\
155 Py_XDECREF(x)
Guido van Rossum220ecc81997-11-18 21:03:39 +0000156
157 /* Numeric information */
Martin v. Löwis737ea822004-06-08 18:52:54 +0000158 RESULT_STRING(decimal_point);
159 RESULT_STRING(thousands_sep);
160 x = copy_grouping(l->grouping);
161 if (!x)
162 goto failed;
163 PyDict_SetItemString(result, "grouping", x);
164 Py_XDECREF(x);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000165
166 /* Monetary information */
167 RESULT_STRING(int_curr_symbol);
168 RESULT_STRING(currency_symbol);
169 RESULT_STRING(mon_decimal_point);
170 RESULT_STRING(mon_thousands_sep);
171 x = copy_grouping(l->mon_grouping);
172 if (!x)
173 goto failed;
174 PyDict_SetItemString(result, "mon_grouping", x);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000175 Py_XDECREF(x);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000176 RESULT_STRING(positive_sign);
177 RESULT_STRING(negative_sign);
178 RESULT_INT(int_frac_digits);
179 RESULT_INT(frac_digits);
180 RESULT_INT(p_cs_precedes);
181 RESULT_INT(p_sep_by_space);
182 RESULT_INT(n_cs_precedes);
183 RESULT_INT(n_sep_by_space);
184 RESULT_INT(p_sign_posn);
185 RESULT_INT(n_sign_posn);
186 return result;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000187
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000188 failed:
189 Py_XDECREF(result);
190 Py_XDECREF(x);
191 return NULL;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000192}
193
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000194PyDoc_STRVAR(strcoll__doc__,
195"string,string -> int. Compares two strings according to the locale.");
Guido van Rossum220ecc81997-11-18 21:03:39 +0000196
197static PyObject*
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000198PyLocale_strcoll(PyObject* self, PyObject* args)
Guido van Rossum220ecc81997-11-18 21:03:39 +0000199{
Guido van Rossum8d30cc02007-05-03 17:49:24 +0000200#if !defined(HAVE_WCSCOLL)
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000201 char *s1,*s2;
202
203 if (!PyArg_ParseTuple(args, "ss:strcoll", &s1, &s2))
204 return NULL;
205 return PyInt_FromLong(strcoll(s1, s2));
206#else
207 PyObject *os1, *os2, *result = NULL;
208 wchar_t *ws1 = NULL, *ws2 = NULL;
Neal Norwitz7f9d29c2007-08-26 07:21:45 +0000209 int len1, len2;
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000210
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000211 if (!PyArg_UnpackTuple(args, "strcoll", 2, 2, &os1, &os2))
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000212 return NULL;
Neal Norwitz7f9d29c2007-08-26 07:21:45 +0000213 /* Both arguments must be unicode, or it's an error. */
214 if (!PyUnicode_Check(os1) || !PyUnicode_Check(os2)) {
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000215 PyErr_SetString(PyExc_ValueError, "strcoll arguments must be strings");
216 }
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000217 /* Convert the unicode strings to wchar[]. */
218 len1 = PyUnicode_GET_SIZE(os1) + 1;
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000219 ws1 = PyMem_MALLOC(len1 * sizeof(wchar_t));
220 if (!ws1) {
221 PyErr_NoMemory();
222 goto done;
223 }
224 if (PyUnicode_AsWideChar((PyUnicodeObject*)os1, ws1, len1) == -1)
225 goto done;
Marc-André Lemburga9cadcd2004-11-22 13:02:31 +0000226 ws1[len1 - 1] = 0;
227 len2 = PyUnicode_GET_SIZE(os2) + 1;
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000228 ws2 = PyMem_MALLOC(len2 * sizeof(wchar_t));
229 if (!ws2) {
230 PyErr_NoMemory();
231 goto done;
232 }
233 if (PyUnicode_AsWideChar((PyUnicodeObject*)os2, ws2, len2) == -1)
234 goto done;
Marc-André Lemburga9cadcd2004-11-22 13:02:31 +0000235 ws2[len2 - 1] = 0;
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000236 /* Collate the strings. */
237 result = PyInt_FromLong(wcscoll(ws1, ws2));
238 done:
239 /* Deallocate everything. */
240 if (ws1) PyMem_FREE(ws1);
241 if (ws2) PyMem_FREE(ws2);
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000242 return result;
243#endif
Guido van Rossum220ecc81997-11-18 21:03:39 +0000244}
245
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000246
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000247PyDoc_STRVAR(strxfrm__doc__,
248"string -> string. Returns a string that behaves for cmp locale-aware.");
Guido van Rossum220ecc81997-11-18 21:03:39 +0000249
250static PyObject*
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000251PyLocale_strxfrm(PyObject* self, PyObject* args)
Guido van Rossum220ecc81997-11-18 21:03:39 +0000252{
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000253 char *s, *buf;
254 size_t n1, n2;
255 PyObject *result;
256
Fredrik Lundh89610a42000-07-08 20:07:24 +0000257 if (!PyArg_ParseTuple(args, "s:strxfrm", &s))
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000258 return NULL;
259
260 /* assume no change in size, first */
261 n1 = strlen(s) + 1;
262 buf = PyMem_Malloc(n1);
263 if (!buf)
264 return PyErr_NoMemory();
Guido van Rossumd8faa362007-04-27 19:54:29 +0000265 n2 = strxfrm(buf, s, n1) + 1;
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000266 if (n2 > n1) {
267 /* more space needed */
268 buf = PyMem_Realloc(buf, n2);
269 if (!buf)
270 return PyErr_NoMemory();
271 strxfrm(buf, s, n2);
272 }
Neal Norwitz7f9d29c2007-08-26 07:21:45 +0000273 result = PyUnicode_FromString(buf);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000274 PyMem_Free(buf);
275 return result;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000276}
277
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000278#if defined(MS_WINDOWS)
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000279static PyObject*
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000280PyLocale_getdefaultlocale(PyObject* self)
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000281{
282 char encoding[100];
283 char locale[100];
284
Tim Peters885d4572001-11-28 20:27:42 +0000285 PyOS_snprintf(encoding, sizeof(encoding), "cp%d", GetACP());
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000286
287 if (GetLocaleInfo(LOCALE_USER_DEFAULT,
288 LOCALE_SISO639LANGNAME,
289 locale, sizeof(locale))) {
Martin v. Löwis18e16552006-02-15 17:27:45 +0000290 Py_ssize_t i = strlen(locale);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000291 locale[i++] = '_';
292 if (GetLocaleInfo(LOCALE_USER_DEFAULT,
293 LOCALE_SISO3166CTRYNAME,
Martin v. Löwis18e16552006-02-15 17:27:45 +0000294 locale+i, (int)(sizeof(locale)-i)))
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000295 return Py_BuildValue("ss", locale, encoding);
296 }
297
298 /* If we end up here, this windows version didn't know about
299 ISO639/ISO3166 names (it's probably Windows 95). Return the
300 Windows language identifier instead (a hexadecimal number) */
301
302 locale[0] = '0';
303 locale[1] = 'x';
304 if (GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_IDEFAULTLANGUAGE,
305 locale+2, sizeof(locale)-2)) {
306 return Py_BuildValue("ss", locale, encoding);
307 }
308
309 /* cannot determine the language code (very unlikely) */
310 Py_INCREF(Py_None);
311 return Py_BuildValue("Os", Py_None, encoding);
312}
313#endif
314
Martin v. Löwis52ea7e92002-11-26 09:05:36 +0000315#if defined(__APPLE__)
Jack Jansen59f072a2004-07-15 13:31:39 +0000316/*
317** Find out what the current script is.
Brett Cannon269ab622004-08-27 05:00:22 +0000318** Donated by Fredrik Lundh.
Jack Jansen59f072a2004-07-15 13:31:39 +0000319*/
320static char *mac_getscript(void)
321{
322 CFStringEncoding enc = CFStringGetSystemEncoding();
323 static CFStringRef name = NULL;
324 /* Return the code name for the encodings for which we have codecs. */
325 switch(enc) {
326 case kCFStringEncodingMacRoman: return "mac-roman";
327 case kCFStringEncodingMacGreek: return "mac-greek";
328 case kCFStringEncodingMacCyrillic: return "mac-cyrillic";
329 case kCFStringEncodingMacTurkish: return "mac-turkish";
330 case kCFStringEncodingMacIcelandic: return "mac-icelandic";
331 /* XXX which one is mac-latin2? */
332 }
333 if (!name) {
Brett Cannon5ce25872005-03-01 03:16:34 +0000334 /* This leaks an object. */
Jack Jansen59f072a2004-07-15 13:31:39 +0000335 name = CFStringConvertEncodingToIANACharSetName(enc);
336 }
337 return (char *)CFStringGetCStringPtr(name, 0);
338}
339
Jack Jansen307d7a42000-07-15 22:31:45 +0000340static PyObject*
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000341PyLocale_getdefaultlocale(PyObject* self)
Jack Jansen307d7a42000-07-15 22:31:45 +0000342{
Jack Jansen59f072a2004-07-15 13:31:39 +0000343 return Py_BuildValue("Os", Py_None, mac_getscript());
Jack Jansen307d7a42000-07-15 22:31:45 +0000344}
345#endif
346
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000347#ifdef HAVE_LANGINFO_H
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000348#define LANGINFO(X) {#X, X}
349struct langinfo_constant{
350 char* name;
351 int value;
352} langinfo_constants[] =
353{
354 /* These constants should exist on any langinfo implementation */
355 LANGINFO(DAY_1),
356 LANGINFO(DAY_2),
357 LANGINFO(DAY_3),
358 LANGINFO(DAY_4),
359 LANGINFO(DAY_5),
360 LANGINFO(DAY_6),
361 LANGINFO(DAY_7),
362
363 LANGINFO(ABDAY_1),
364 LANGINFO(ABDAY_2),
365 LANGINFO(ABDAY_3),
366 LANGINFO(ABDAY_4),
367 LANGINFO(ABDAY_5),
368 LANGINFO(ABDAY_6),
369 LANGINFO(ABDAY_7),
370
371 LANGINFO(MON_1),
372 LANGINFO(MON_2),
373 LANGINFO(MON_3),
374 LANGINFO(MON_4),
375 LANGINFO(MON_5),
376 LANGINFO(MON_6),
377 LANGINFO(MON_7),
378 LANGINFO(MON_8),
379 LANGINFO(MON_9),
380 LANGINFO(MON_10),
381 LANGINFO(MON_11),
382 LANGINFO(MON_12),
383
384 LANGINFO(ABMON_1),
385 LANGINFO(ABMON_2),
386 LANGINFO(ABMON_3),
387 LANGINFO(ABMON_4),
388 LANGINFO(ABMON_5),
389 LANGINFO(ABMON_6),
390 LANGINFO(ABMON_7),
391 LANGINFO(ABMON_8),
392 LANGINFO(ABMON_9),
393 LANGINFO(ABMON_10),
394 LANGINFO(ABMON_11),
395 LANGINFO(ABMON_12),
396
397#ifdef RADIXCHAR
398 /* The following are not available with glibc 2.0 */
399 LANGINFO(RADIXCHAR),
400 LANGINFO(THOUSEP),
401 /* YESSTR and NOSTR are deprecated in glibc, since they are
402 a special case of message translation, which should be rather
403 done using gettext. So we don't expose it to Python in the
404 first place.
405 LANGINFO(YESSTR),
406 LANGINFO(NOSTR),
407 */
408 LANGINFO(CRNCYSTR),
409#endif
410
411 LANGINFO(D_T_FMT),
412 LANGINFO(D_FMT),
413 LANGINFO(T_FMT),
414 LANGINFO(AM_STR),
415 LANGINFO(PM_STR),
416
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000417 /* The following constants are available only with XPG4, but...
418 AIX 3.2. only has CODESET.
419 OpenBSD doesn't have CODESET but has T_FMT_AMPM, and doesn't have
420 a few of the others.
421 Solution: ifdef-test them all. */
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000422#ifdef CODESET
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000423 LANGINFO(CODESET),
Martin v. Löwis496f9e42002-03-27 12:15:57 +0000424#endif
425#ifdef T_FMT_AMPM
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000426 LANGINFO(T_FMT_AMPM),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000427#endif
428#ifdef ERA
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000429 LANGINFO(ERA),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000430#endif
431#ifdef ERA_D_FMT
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000432 LANGINFO(ERA_D_FMT),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000433#endif
434#ifdef ERA_D_T_FMT
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000435 LANGINFO(ERA_D_T_FMT),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000436#endif
437#ifdef ERA_T_FMT
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000438 LANGINFO(ERA_T_FMT),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000439#endif
440#ifdef ALT_DIGITS
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000441 LANGINFO(ALT_DIGITS),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000442#endif
443#ifdef YESEXPR
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000444 LANGINFO(YESEXPR),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000445#endif
446#ifdef NOEXPR
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000447 LANGINFO(NOEXPR),
448#endif
449#ifdef _DATE_FMT
450 /* This is not available in all glibc versions that have CODESET. */
451 LANGINFO(_DATE_FMT),
452#endif
453 {0, 0}
454};
455
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000456PyDoc_STRVAR(nl_langinfo__doc__,
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000457"nl_langinfo(key) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000458"Return the value for the locale information associated with key.");
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000459
460static PyObject*
461PyLocale_nl_langinfo(PyObject* self, PyObject* args)
462{
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000463 int item, i;
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000464 if (!PyArg_ParseTuple(args, "i:nl_langinfo", &item))
465 return NULL;
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000466 /* Check whether this is a supported constant. GNU libc sometimes
467 returns numeric values in the char* return value, which would
Neal Norwitz7f9d29c2007-08-26 07:21:45 +0000468 crash PyUnicode_FromString. */
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000469 for (i = 0; langinfo_constants[i].name; i++)
Hye-Shik Changc3a87b82004-03-21 19:34:30 +0000470 if (langinfo_constants[i].value == item) {
471 /* Check NULL as a workaround for GNU libc's returning NULL
472 instead of an empty string for nl_langinfo(ERA). */
473 const char *result = nl_langinfo(item);
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +0000474 /* XXX may have to convert this to wcs first. */
475 return PyUnicode_FromString(result != NULL ? result : "");
Hye-Shik Changc3a87b82004-03-21 19:34:30 +0000476 }
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000477 PyErr_SetString(PyExc_ValueError, "unsupported langinfo constant");
478 return NULL;
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000479}
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000480#endif /* HAVE_LANGINFO_H */
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000481
482#ifdef HAVE_LIBINTL_H
483
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000484PyDoc_STRVAR(gettext__doc__,
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000485"gettext(msg) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000486"Return translation of msg.");
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000487
488static PyObject*
489PyIntl_gettext(PyObject* self, PyObject *args)
490{
491 char *in;
492 if (!PyArg_ParseTuple(args, "z", &in))
493 return 0;
Neal Norwitz7f9d29c2007-08-26 07:21:45 +0000494 return PyUnicode_FromString(gettext(in));
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000495}
496
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000497PyDoc_STRVAR(dgettext__doc__,
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000498"dgettext(domain, msg) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000499"Return translation of msg in domain.");
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000500
501static PyObject*
502PyIntl_dgettext(PyObject* self, PyObject *args)
503{
504 char *domain, *in;
505 if (!PyArg_ParseTuple(args, "zz", &domain, &in))
506 return 0;
Neal Norwitz7f9d29c2007-08-26 07:21:45 +0000507 return PyUnicode_FromString(dgettext(domain, in));
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000508}
509
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000510PyDoc_STRVAR(dcgettext__doc__,
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000511"dcgettext(domain, msg, category) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000512"Return translation of msg in domain and category.");
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000513
514static PyObject*
515PyIntl_dcgettext(PyObject *self, PyObject *args)
516{
517 char *domain, *msgid;
518 int category;
519 if (!PyArg_ParseTuple(args, "zzi", &domain, &msgid, &category))
520 return 0;
Neal Norwitz7f9d29c2007-08-26 07:21:45 +0000521 return PyUnicode_FromString(dcgettext(domain,msgid,category));
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000522}
523
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000524PyDoc_STRVAR(textdomain__doc__,
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000525"textdomain(domain) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000526"Set the C library's textdmain to domain, returning the new domain.");
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000527
528static PyObject*
529PyIntl_textdomain(PyObject* self, PyObject* args)
530{
531 char *domain;
532 if (!PyArg_ParseTuple(args, "z", &domain))
533 return 0;
534 domain = textdomain(domain);
535 if (!domain) {
536 PyErr_SetFromErrno(PyExc_OSError);
537 return NULL;
538 }
Neal Norwitz7f9d29c2007-08-26 07:21:45 +0000539 return PyUnicode_FromString(domain);
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000540}
541
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000542PyDoc_STRVAR(bindtextdomain__doc__,
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000543"bindtextdomain(domain, dir) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000544"Bind the C library's domain to dir.");
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000545
546static PyObject*
547PyIntl_bindtextdomain(PyObject* self,PyObject*args)
548{
549 char *domain,*dirname;
550 if (!PyArg_ParseTuple(args, "zz", &domain, &dirname))
551 return 0;
552 dirname = bindtextdomain(domain, dirname);
553 if (!dirname) {
554 PyErr_SetFromErrno(PyExc_OSError);
555 return NULL;
556 }
Neal Norwitz7f9d29c2007-08-26 07:21:45 +0000557 return PyUnicode_FromString(dirname);
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000558}
559
Gustavo Niemeyer7bd33c52004-07-22 18:44:01 +0000560#ifdef HAVE_BIND_TEXTDOMAIN_CODESET
561PyDoc_STRVAR(bind_textdomain_codeset__doc__,
562"bind_textdomain_codeset(domain, codeset) -> string\n"
563"Bind the C library's domain to codeset.");
564
565static PyObject*
566PyIntl_bind_textdomain_codeset(PyObject* self,PyObject*args)
567{
568 char *domain,*codeset;
569 if (!PyArg_ParseTuple(args, "sz", &domain, &codeset))
570 return NULL;
571 codeset = bind_textdomain_codeset(domain, codeset);
572 if (codeset)
Neal Norwitz7f9d29c2007-08-26 07:21:45 +0000573 return PyUnicode_FromString(codeset);
Gustavo Niemeyer7bd33c52004-07-22 18:44:01 +0000574 Py_RETURN_NONE;
575}
576#endif
577
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000578#endif
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000579
Guido van Rossum220ecc81997-11-18 21:03:39 +0000580static struct PyMethodDef PyLocale_Methods[] = {
Andrew M. Kuchlinge365fb82000-08-03 02:06:16 +0000581 {"setlocale", (PyCFunction) PyLocale_setlocale,
582 METH_VARARGS, setlocale__doc__},
583 {"localeconv", (PyCFunction) PyLocale_localeconv,
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000584 METH_NOARGS, localeconv__doc__},
Andrew M. Kuchlinge365fb82000-08-03 02:06:16 +0000585 {"strcoll", (PyCFunction) PyLocale_strcoll,
586 METH_VARARGS, strcoll__doc__},
587 {"strxfrm", (PyCFunction) PyLocale_strxfrm,
588 METH_VARARGS, strxfrm__doc__},
Martin v. Löwis52ea7e92002-11-26 09:05:36 +0000589#if defined(MS_WINDOWS) || defined(__APPLE__)
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000590 {"_getdefaultlocale", (PyCFunction) PyLocale_getdefaultlocale, METH_NOARGS},
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000591#endif
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000592#ifdef HAVE_LANGINFO_H
593 {"nl_langinfo", (PyCFunction) PyLocale_nl_langinfo,
594 METH_VARARGS, nl_langinfo__doc__},
595#endif
Martin v. Löwisc6a7d7e2002-05-02 12:16:29 +0000596#ifdef HAVE_LIBINTL_H
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000597 {"gettext",(PyCFunction)PyIntl_gettext,METH_VARARGS,
598 gettext__doc__},
599 {"dgettext",(PyCFunction)PyIntl_dgettext,METH_VARARGS,
600 dgettext__doc__},
601 {"dcgettext",(PyCFunction)PyIntl_dcgettext,METH_VARARGS,
602 dcgettext__doc__},
603 {"textdomain",(PyCFunction)PyIntl_textdomain,METH_VARARGS,
604 textdomain__doc__},
605 {"bindtextdomain",(PyCFunction)PyIntl_bindtextdomain,METH_VARARGS,
606 bindtextdomain__doc__},
Gustavo Niemeyer7bd33c52004-07-22 18:44:01 +0000607#ifdef HAVE_BIND_TEXTDOMAIN_CODESET
608 {"bind_textdomain_codeset",(PyCFunction)PyIntl_bind_textdomain_codeset,
609 METH_VARARGS, bind_textdomain_codeset__doc__},
610#endif
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000611#endif
Guido van Rossum220ecc81997-11-18 21:03:39 +0000612 {NULL, NULL}
613};
614
Mark Hammondfe51c6d2002-08-02 02:27:13 +0000615PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000616init_locale(void)
Guido van Rossum220ecc81997-11-18 21:03:39 +0000617{
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000618 PyObject *m, *d, *x;
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000619#ifdef HAVE_LANGINFO_H
620 int i;
621#endif
Guido van Rossum220ecc81997-11-18 21:03:39 +0000622
Neal Norwitzf9e115a2007-08-23 18:08:11 +0000623 m = Py_InitModule3("_locale", PyLocale_Methods, locale__doc__);
Neal Norwitz1ac754f2006-01-19 06:09:39 +0000624 if (m == NULL)
625 return;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000626
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000627 d = PyModule_GetDict(m);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000628
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000629 x = PyInt_FromLong(LC_CTYPE);
630 PyDict_SetItemString(d, "LC_CTYPE", x);
631 Py_XDECREF(x);
632
633 x = PyInt_FromLong(LC_TIME);
634 PyDict_SetItemString(d, "LC_TIME", x);
635 Py_XDECREF(x);
636
637 x = PyInt_FromLong(LC_COLLATE);
638 PyDict_SetItemString(d, "LC_COLLATE", x);
639 Py_XDECREF(x);
640
641 x = PyInt_FromLong(LC_MONETARY);
642 PyDict_SetItemString(d, "LC_MONETARY", x);
643 Py_XDECREF(x);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000644
Guido van Rossum8d9c2e31997-12-09 19:35:11 +0000645#ifdef LC_MESSAGES
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000646 x = PyInt_FromLong(LC_MESSAGES);
647 PyDict_SetItemString(d, "LC_MESSAGES", x);
648 Py_XDECREF(x);
Guido van Rossum8d9c2e31997-12-09 19:35:11 +0000649#endif /* LC_MESSAGES */
Guido van Rossum220ecc81997-11-18 21:03:39 +0000650
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000651 x = PyInt_FromLong(LC_NUMERIC);
652 PyDict_SetItemString(d, "LC_NUMERIC", x);
653 Py_XDECREF(x);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000654
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000655 x = PyInt_FromLong(LC_ALL);
656 PyDict_SetItemString(d, "LC_ALL", x);
657 Py_XDECREF(x);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000658
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000659 x = PyInt_FromLong(CHAR_MAX);
660 PyDict_SetItemString(d, "CHAR_MAX", x);
661 Py_XDECREF(x);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000662
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000663 Error = PyErr_NewException("locale.Error", NULL, NULL);
664 PyDict_SetItemString(d, "Error", Error);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000665
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000666#ifdef HAVE_LANGINFO_H
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000667 for (i = 0; langinfo_constants[i].name; i++) {
668 PyModule_AddIntConstant(m, langinfo_constants[i].name,
669 langinfo_constants[i].value);
670 }
Martin v. Löwisf95dd0a2001-08-15 17:14:33 +0000671#endif
Guido van Rossum220ecc81997-11-18 21:03:39 +0000672}
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000673
674/*
675Local variables:
676c-basic-offset: 4
677indent-tabs-mode: nil
678End:
679*/