blob: 26aed97d8f56d90470c9bd09798bdcf56b08d811 [file] [log] [blame]
Guido van Rossum220ecc81997-11-18 21:03:39 +00001/***********************************************************
Martin v. Löwis25f90d52003-09-03 04:50:13 +00002Copyright (C) 1997, 2002, 2003 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
Martin v. Löwis0e8bd7e2006-06-10 12:23:46 +000019#ifdef HAVE_ERRNO_H
Martin v. Löwisa43190b2006-05-22 09:15:18 +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
Guido van Rossum1ca8bb32001-03-02 06:28:17 +000044#ifdef RISCOS
45char *strdup(const char *);
46#endif
47
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000048PyDoc_STRVAR(locale__doc__, "Support for POSIX locales.");
Guido van Rossum220ecc81997-11-18 21:03:39 +000049
50static PyObject *Error;
51
52/* support functions for formatting floating point numbers */
53
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000054PyDoc_STRVAR(setlocale__doc__,
55"(integer,string=None) -> string. Activates/queries locale processing.");
Guido van Rossum220ecc81997-11-18 21:03:39 +000056
Guido van Rossum220ecc81997-11-18 21:03:39 +000057/* the grouping is terminated by either 0 or CHAR_MAX */
58static PyObject*
Fredrik Lundh8f017a02000-07-08 19:57:37 +000059copy_grouping(char* s)
Guido van Rossum220ecc81997-11-18 21:03:39 +000060{
Fredrik Lundh8f017a02000-07-08 19:57:37 +000061 int i;
62 PyObject *result, *val = NULL;
63
64 if (s[0] == '\0')
65 /* empty string: no grouping at all */
66 return PyList_New(0);
67
68 for (i = 0; s[i] != '\0' && s[i] != CHAR_MAX; i++)
69 ; /* nothing */
70
71 result = PyList_New(i+1);
72 if (!result)
73 return NULL;
74
75 i = -1;
76 do {
77 i++;
78 val = PyInt_FromLong(s[i]);
79 if (!val)
80 break;
81 if (PyList_SetItem(result, i, val)) {
82 Py_DECREF(val);
Fredrik Lundh89610a42000-07-08 20:07:24 +000083 val = NULL;
Fredrik Lundh8f017a02000-07-08 19:57:37 +000084 break;
85 }
86 } while (s[i] != '\0' && s[i] != CHAR_MAX);
87
88 if (!val) {
89 Py_DECREF(result);
90 return NULL;
Guido van Rossum220ecc81997-11-18 21:03:39 +000091 }
Fredrik Lundh8f017a02000-07-08 19:57:37 +000092
93 return result;
Guido van Rossum220ecc81997-11-18 21:03:39 +000094}
95
96static void
Fredrik Lundh8f017a02000-07-08 19:57:37 +000097fixup_ulcase(void)
Guido van Rossum220ecc81997-11-18 21:03:39 +000098{
Fredrik Lundh8f017a02000-07-08 19:57:37 +000099 PyObject *mods, *strop, *string, *ulo;
100 unsigned char ul[256];
101 int n, c;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000102
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000103 /* find the string and strop modules */
104 mods = PyImport_GetModuleDict();
105 if (!mods)
106 return;
107 string = PyDict_GetItemString(mods, "string");
108 if (string)
109 string = PyModule_GetDict(string);
110 strop=PyDict_GetItemString(mods, "strop");
111 if (strop)
112 strop = PyModule_GetDict(strop);
113 if (!string && !strop)
114 return;
115
116 /* create uppercase map string */
117 n = 0;
118 for (c = 0; c < 256; c++) {
119 if (isupper(c))
120 ul[n++] = c;
121 }
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000122 ulo = PyString_FromStringAndSize((const char *)ul, n);
Fredrik Lundh89610a42000-07-08 20:07:24 +0000123 if (!ulo)
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000124 return;
125 if (string)
126 PyDict_SetItemString(string, "uppercase", ulo);
127 if (strop)
128 PyDict_SetItemString(strop, "uppercase", ulo);
129 Py_DECREF(ulo);
130
131 /* create lowercase string */
132 n = 0;
133 for (c = 0; c < 256; c++) {
134 if (islower(c))
135 ul[n++] = c;
136 }
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000137 ulo = PyString_FromStringAndSize((const char *)ul, n);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000138 if (!ulo)
139 return;
140 if (string)
141 PyDict_SetItemString(string, "lowercase", ulo);
142 if (strop)
143 PyDict_SetItemString(strop, "lowercase", ulo);
144 Py_DECREF(ulo);
145
146 /* create letters string */
147 n = 0;
148 for (c = 0; c < 256; c++) {
149 if (isalpha(c))
150 ul[n++] = c;
151 }
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000152 ulo = PyString_FromStringAndSize((const char *)ul, n);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000153 if (!ulo)
154 return;
155 if (string)
156 PyDict_SetItemString(string, "letters", ulo);
157 Py_DECREF(ulo);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000158}
Martin v. Löwis7c82a3e02001-09-05 17:09:48 +0000159
Guido van Rossum220ecc81997-11-18 21:03:39 +0000160static PyObject*
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000161PyLocale_setlocale(PyObject* self, PyObject* args)
Guido van Rossum220ecc81997-11-18 21:03:39 +0000162{
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000163 int category;
164 char *locale = NULL, *result;
165 PyObject *result_object;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000166
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000167 if (!PyArg_ParseTuple(args, "i|z:setlocale", &category, &locale))
Fredrik Lundh89610a42000-07-08 20:07:24 +0000168 return NULL;
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000169
170 if (locale) {
171 /* set locale */
172 result = setlocale(category, locale);
173 if (!result) {
174 /* operation failed, no setting was changed */
Martin v. Löwis25f90d52003-09-03 04:50:13 +0000175 PyErr_SetString(Error, "unsupported locale setting");
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000176 return NULL;
177 }
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000178 result_object = PyString_FromString(result);
Mark Hammond9a714752003-07-24 14:15:07 +0000179 if (!result_object)
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000180 return NULL;
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000181 /* record changes to LC_CTYPE */
182 if (category == LC_CTYPE || category == LC_ALL)
183 fixup_ulcase();
184 /* things that got wrong up to here are ignored */
185 PyErr_Clear();
186 } else {
187 /* get locale */
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000188 result = setlocale(category, NULL);
189 if (!result) {
190 PyErr_SetString(Error, "locale query failed");
191 return NULL;
192 }
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000193 result_object = PyString_FromString(result);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000194 }
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000195 return result_object;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000196}
197
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000198PyDoc_STRVAR(localeconv__doc__,
199"() -> dict. Returns numeric and monetary locale-specific parameters.");
Guido van Rossum220ecc81997-11-18 21:03:39 +0000200
201static PyObject*
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000202PyLocale_localeconv(PyObject* self)
Guido van Rossum220ecc81997-11-18 21:03:39 +0000203{
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000204 PyObject* result;
205 struct lconv *l;
206 PyObject *x;
207
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000208 result = PyDict_New();
Fredrik Lundh89610a42000-07-08 20:07:24 +0000209 if (!result)
210 return NULL;
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000211
212 /* if LC_NUMERIC is different in the C library, use saved value */
213 l = localeconv();
214
215 /* hopefully, the localeconv result survives the C library calls
216 involved herein */
217
218#define RESULT_STRING(s)\
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000219 x = PyString_FromString(l->s);\
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000220 if (!x) goto failed;\
221 PyDict_SetItemString(result, #s, x);\
222 Py_XDECREF(x)
223
224#define RESULT_INT(i)\
225 x = PyInt_FromLong(l->i);\
226 if (!x) goto failed;\
227 PyDict_SetItemString(result, #i, x);\
228 Py_XDECREF(x)
Guido van Rossum220ecc81997-11-18 21:03:39 +0000229
230 /* Numeric information */
Martin v. Löwis737ea822004-06-08 18:52:54 +0000231 RESULT_STRING(decimal_point);
232 RESULT_STRING(thousands_sep);
233 x = copy_grouping(l->grouping);
234 if (!x)
235 goto failed;
236 PyDict_SetItemString(result, "grouping", x);
237 Py_XDECREF(x);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000238
239 /* Monetary information */
240 RESULT_STRING(int_curr_symbol);
241 RESULT_STRING(currency_symbol);
242 RESULT_STRING(mon_decimal_point);
243 RESULT_STRING(mon_thousands_sep);
244 x = copy_grouping(l->mon_grouping);
245 if (!x)
246 goto failed;
247 PyDict_SetItemString(result, "mon_grouping", x);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000248 Py_XDECREF(x);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000249 RESULT_STRING(positive_sign);
250 RESULT_STRING(negative_sign);
251 RESULT_INT(int_frac_digits);
252 RESULT_INT(frac_digits);
253 RESULT_INT(p_cs_precedes);
254 RESULT_INT(p_sep_by_space);
255 RESULT_INT(n_cs_precedes);
256 RESULT_INT(n_sep_by_space);
257 RESULT_INT(p_sign_posn);
258 RESULT_INT(n_sign_posn);
259 return result;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000260
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000261 failed:
262 Py_XDECREF(result);
263 Py_XDECREF(x);
264 return NULL;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000265}
266
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000267PyDoc_STRVAR(strcoll__doc__,
268"string,string -> int. Compares two strings according to the locale.");
Guido van Rossum220ecc81997-11-18 21:03:39 +0000269
270static PyObject*
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000271PyLocale_strcoll(PyObject* self, PyObject* args)
Guido van Rossum220ecc81997-11-18 21:03:39 +0000272{
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000273#if !defined(HAVE_WCSCOLL) || !defined(Py_USING_UNICODE)
274 char *s1,*s2;
275
276 if (!PyArg_ParseTuple(args, "ss:strcoll", &s1, &s2))
277 return NULL;
278 return PyInt_FromLong(strcoll(s1, s2));
279#else
280 PyObject *os1, *os2, *result = NULL;
281 wchar_t *ws1 = NULL, *ws2 = NULL;
282 int rel1 = 0, rel2 = 0, len1, len2;
283
Georg Brandl96a8c392006-05-29 21:04:52 +0000284 if (!PyArg_UnpackTuple(args, "strcoll", 2, 2, &os1, &os2))
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000285 return NULL;
286 /* If both arguments are byte strings, use strcoll. */
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000287 if (PyString_Check(os1) && PyString_Check(os2))
288 return PyInt_FromLong(strcoll(PyString_AS_STRING(os1),
289 PyString_AS_STRING(os2)));
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000290 /* If neither argument is unicode, it's an error. */
291 if (!PyUnicode_Check(os1) && !PyUnicode_Check(os2)) {
292 PyErr_SetString(PyExc_ValueError, "strcoll arguments must be strings");
293 }
294 /* Convert the non-unicode argument to unicode. */
295 if (!PyUnicode_Check(os1)) {
296 os1 = PyUnicode_FromObject(os1);
297 if (!os1)
298 return NULL;
299 rel1 = 1;
300 }
301 if (!PyUnicode_Check(os2)) {
302 os2 = PyUnicode_FromObject(os2);
303 if (!os2) {
Georg Brandl278fc502008-07-19 12:46:12 +0000304 if (rel1) {
305 Py_DECREF(os1);
306 }
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000307 return NULL;
308 }
309 rel2 = 1;
310 }
311 /* Convert the unicode strings to wchar[]. */
312 len1 = PyUnicode_GET_SIZE(os1) + 1;
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000313 ws1 = PyMem_MALLOC(len1 * sizeof(wchar_t));
314 if (!ws1) {
315 PyErr_NoMemory();
316 goto done;
317 }
318 if (PyUnicode_AsWideChar((PyUnicodeObject*)os1, ws1, len1) == -1)
319 goto done;
Marc-André Lemburga9cadcd2004-11-22 13:02:31 +0000320 ws1[len1 - 1] = 0;
321 len2 = PyUnicode_GET_SIZE(os2) + 1;
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000322 ws2 = PyMem_MALLOC(len2 * sizeof(wchar_t));
323 if (!ws2) {
324 PyErr_NoMemory();
325 goto done;
326 }
327 if (PyUnicode_AsWideChar((PyUnicodeObject*)os2, ws2, len2) == -1)
328 goto done;
Marc-André Lemburga9cadcd2004-11-22 13:02:31 +0000329 ws2[len2 - 1] = 0;
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000330 /* Collate the strings. */
331 result = PyInt_FromLong(wcscoll(ws1, ws2));
332 done:
333 /* Deallocate everything. */
334 if (ws1) PyMem_FREE(ws1);
335 if (ws2) PyMem_FREE(ws2);
336 if (rel1) {
337 Py_DECREF(os1);
338 }
339 if (rel2) {
340 Py_DECREF(os2);
341 }
342 return result;
343#endif
Guido van Rossum220ecc81997-11-18 21:03:39 +0000344}
345
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000346
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000347PyDoc_STRVAR(strxfrm__doc__,
348"string -> string. Returns a string that behaves for cmp locale-aware.");
Guido van Rossum220ecc81997-11-18 21:03:39 +0000349
350static PyObject*
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000351PyLocale_strxfrm(PyObject* self, PyObject* args)
Guido van Rossum220ecc81997-11-18 21:03:39 +0000352{
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000353 char *s, *buf;
354 size_t n1, n2;
355 PyObject *result;
356
Fredrik Lundh89610a42000-07-08 20:07:24 +0000357 if (!PyArg_ParseTuple(args, "s:strxfrm", &s))
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000358 return NULL;
359
360 /* assume no change in size, first */
361 n1 = strlen(s) + 1;
362 buf = PyMem_Malloc(n1);
363 if (!buf)
364 return PyErr_NoMemory();
Matthias Klosee19e0c22007-04-03 04:35:59 +0000365 n2 = strxfrm(buf, s, n1) + 1;
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000366 if (n2 > n1) {
367 /* more space needed */
368 buf = PyMem_Realloc(buf, n2);
369 if (!buf)
370 return PyErr_NoMemory();
371 strxfrm(buf, s, n2);
372 }
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000373 result = PyString_FromString(buf);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000374 PyMem_Free(buf);
375 return result;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000376}
377
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000378#if defined(MS_WINDOWS)
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000379static PyObject*
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000380PyLocale_getdefaultlocale(PyObject* self)
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000381{
382 char encoding[100];
383 char locale[100];
384
Tim Peters885d4572001-11-28 20:27:42 +0000385 PyOS_snprintf(encoding, sizeof(encoding), "cp%d", GetACP());
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000386
387 if (GetLocaleInfo(LOCALE_USER_DEFAULT,
388 LOCALE_SISO639LANGNAME,
389 locale, sizeof(locale))) {
Martin v. Löwis18e16552006-02-15 17:27:45 +0000390 Py_ssize_t i = strlen(locale);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000391 locale[i++] = '_';
392 if (GetLocaleInfo(LOCALE_USER_DEFAULT,
393 LOCALE_SISO3166CTRYNAME,
Martin v. Löwis18e16552006-02-15 17:27:45 +0000394 locale+i, (int)(sizeof(locale)-i)))
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000395 return Py_BuildValue("ss", locale, encoding);
396 }
397
398 /* If we end up here, this windows version didn't know about
399 ISO639/ISO3166 names (it's probably Windows 95). Return the
400 Windows language identifier instead (a hexadecimal number) */
401
402 locale[0] = '0';
403 locale[1] = 'x';
404 if (GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_IDEFAULTLANGUAGE,
405 locale+2, sizeof(locale)-2)) {
406 return Py_BuildValue("ss", locale, encoding);
407 }
408
409 /* cannot determine the language code (very unlikely) */
410 Py_INCREF(Py_None);
411 return Py_BuildValue("Os", Py_None, encoding);
412}
413#endif
414
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000415#ifdef HAVE_LANGINFO_H
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000416#define LANGINFO(X) {#X, X}
Martin v. Löwis111c1802008-06-13 07:47:47 +0000417static struct langinfo_constant{
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000418 char* name;
419 int value;
420} langinfo_constants[] =
421{
422 /* These constants should exist on any langinfo implementation */
423 LANGINFO(DAY_1),
424 LANGINFO(DAY_2),
425 LANGINFO(DAY_3),
426 LANGINFO(DAY_4),
427 LANGINFO(DAY_5),
428 LANGINFO(DAY_6),
429 LANGINFO(DAY_7),
430
431 LANGINFO(ABDAY_1),
432 LANGINFO(ABDAY_2),
433 LANGINFO(ABDAY_3),
434 LANGINFO(ABDAY_4),
435 LANGINFO(ABDAY_5),
436 LANGINFO(ABDAY_6),
437 LANGINFO(ABDAY_7),
438
439 LANGINFO(MON_1),
440 LANGINFO(MON_2),
441 LANGINFO(MON_3),
442 LANGINFO(MON_4),
443 LANGINFO(MON_5),
444 LANGINFO(MON_6),
445 LANGINFO(MON_7),
446 LANGINFO(MON_8),
447 LANGINFO(MON_9),
448 LANGINFO(MON_10),
449 LANGINFO(MON_11),
450 LANGINFO(MON_12),
451
452 LANGINFO(ABMON_1),
453 LANGINFO(ABMON_2),
454 LANGINFO(ABMON_3),
455 LANGINFO(ABMON_4),
456 LANGINFO(ABMON_5),
457 LANGINFO(ABMON_6),
458 LANGINFO(ABMON_7),
459 LANGINFO(ABMON_8),
460 LANGINFO(ABMON_9),
461 LANGINFO(ABMON_10),
462 LANGINFO(ABMON_11),
463 LANGINFO(ABMON_12),
464
465#ifdef RADIXCHAR
466 /* The following are not available with glibc 2.0 */
467 LANGINFO(RADIXCHAR),
468 LANGINFO(THOUSEP),
469 /* YESSTR and NOSTR are deprecated in glibc, since they are
470 a special case of message translation, which should be rather
471 done using gettext. So we don't expose it to Python in the
472 first place.
473 LANGINFO(YESSTR),
474 LANGINFO(NOSTR),
475 */
476 LANGINFO(CRNCYSTR),
477#endif
478
479 LANGINFO(D_T_FMT),
480 LANGINFO(D_FMT),
481 LANGINFO(T_FMT),
482 LANGINFO(AM_STR),
483 LANGINFO(PM_STR),
484
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000485 /* The following constants are available only with XPG4, but...
486 AIX 3.2. only has CODESET.
487 OpenBSD doesn't have CODESET but has T_FMT_AMPM, and doesn't have
488 a few of the others.
489 Solution: ifdef-test them all. */
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000490#ifdef CODESET
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000491 LANGINFO(CODESET),
Martin v. Löwis496f9e42002-03-27 12:15:57 +0000492#endif
493#ifdef T_FMT_AMPM
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000494 LANGINFO(T_FMT_AMPM),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000495#endif
496#ifdef ERA
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000497 LANGINFO(ERA),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000498#endif
499#ifdef ERA_D_FMT
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000500 LANGINFO(ERA_D_FMT),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000501#endif
502#ifdef ERA_D_T_FMT
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000503 LANGINFO(ERA_D_T_FMT),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000504#endif
505#ifdef ERA_T_FMT
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000506 LANGINFO(ERA_T_FMT),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000507#endif
508#ifdef ALT_DIGITS
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000509 LANGINFO(ALT_DIGITS),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000510#endif
511#ifdef YESEXPR
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000512 LANGINFO(YESEXPR),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000513#endif
514#ifdef NOEXPR
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000515 LANGINFO(NOEXPR),
516#endif
517#ifdef _DATE_FMT
518 /* This is not available in all glibc versions that have CODESET. */
519 LANGINFO(_DATE_FMT),
520#endif
521 {0, 0}
522};
523
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000524PyDoc_STRVAR(nl_langinfo__doc__,
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000525"nl_langinfo(key) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000526"Return the value for the locale information associated with key.");
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000527
528static PyObject*
529PyLocale_nl_langinfo(PyObject* self, PyObject* args)
530{
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000531 int item, i;
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000532 if (!PyArg_ParseTuple(args, "i:nl_langinfo", &item))
533 return NULL;
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000534 /* Check whether this is a supported constant. GNU libc sometimes
535 returns numeric values in the char* return value, which would
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000536 crash PyString_FromString. */
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000537 for (i = 0; langinfo_constants[i].name; i++)
Hye-Shik Changc3a87b82004-03-21 19:34:30 +0000538 if (langinfo_constants[i].value == item) {
539 /* Check NULL as a workaround for GNU libc's returning NULL
540 instead of an empty string for nl_langinfo(ERA). */
541 const char *result = nl_langinfo(item);
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000542 return PyString_FromString(result != NULL ? result : "");
Hye-Shik Changc3a87b82004-03-21 19:34:30 +0000543 }
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000544 PyErr_SetString(PyExc_ValueError, "unsupported langinfo constant");
545 return NULL;
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000546}
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000547#endif /* HAVE_LANGINFO_H */
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000548
549#ifdef HAVE_LIBINTL_H
550
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000551PyDoc_STRVAR(gettext__doc__,
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000552"gettext(msg) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000553"Return translation of msg.");
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000554
555static PyObject*
556PyIntl_gettext(PyObject* self, PyObject *args)
557{
558 char *in;
Georg Brandl6b41a8e2008-07-19 12:39:10 +0000559 if (!PyArg_ParseTuple(args, "s", &in))
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000560 return 0;
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000561 return PyString_FromString(gettext(in));
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000562}
563
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000564PyDoc_STRVAR(dgettext__doc__,
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000565"dgettext(domain, msg) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000566"Return translation of msg in domain.");
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000567
568static PyObject*
569PyIntl_dgettext(PyObject* self, PyObject *args)
570{
571 char *domain, *in;
Georg Brandl6b41a8e2008-07-19 12:39:10 +0000572 if (!PyArg_ParseTuple(args, "zs", &domain, &in))
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000573 return 0;
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000574 return PyString_FromString(dgettext(domain, in));
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000575}
576
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000577PyDoc_STRVAR(dcgettext__doc__,
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000578"dcgettext(domain, msg, category) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000579"Return translation of msg in domain and category.");
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000580
581static PyObject*
582PyIntl_dcgettext(PyObject *self, PyObject *args)
583{
584 char *domain, *msgid;
585 int category;
Georg Brandl6b41a8e2008-07-19 12:39:10 +0000586 if (!PyArg_ParseTuple(args, "zsi", &domain, &msgid, &category))
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000587 return 0;
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000588 return PyString_FromString(dcgettext(domain,msgid,category));
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000589}
590
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000591PyDoc_STRVAR(textdomain__doc__,
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000592"textdomain(domain) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000593"Set the C library's textdmain to domain, returning the new domain.");
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000594
595static PyObject*
596PyIntl_textdomain(PyObject* self, PyObject* args)
597{
598 char *domain;
599 if (!PyArg_ParseTuple(args, "z", &domain))
600 return 0;
601 domain = textdomain(domain);
602 if (!domain) {
603 PyErr_SetFromErrno(PyExc_OSError);
604 return NULL;
605 }
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000606 return PyString_FromString(domain);
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000607}
608
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000609PyDoc_STRVAR(bindtextdomain__doc__,
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000610"bindtextdomain(domain, dir) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000611"Bind the C library's domain to dir.");
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000612
613static PyObject*
614PyIntl_bindtextdomain(PyObject* self,PyObject*args)
615{
Georg Brandl6b41a8e2008-07-19 12:39:10 +0000616 char *domain, *dirname;
617 if (!PyArg_ParseTuple(args, "sz", &domain, &dirname))
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000618 return 0;
Georg Brandl6b41a8e2008-07-19 12:39:10 +0000619 if (!strlen(domain)) {
620 PyErr_SetString(Error, "domain must be a non-empty string");
621 return 0;
622 }
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000623 dirname = bindtextdomain(domain, dirname);
624 if (!dirname) {
625 PyErr_SetFromErrno(PyExc_OSError);
626 return NULL;
627 }
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000628 return PyString_FromString(dirname);
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000629}
630
Gustavo Niemeyer7bd33c52004-07-22 18:44:01 +0000631#ifdef HAVE_BIND_TEXTDOMAIN_CODESET
632PyDoc_STRVAR(bind_textdomain_codeset__doc__,
633"bind_textdomain_codeset(domain, codeset) -> string\n"
634"Bind the C library's domain to codeset.");
635
636static PyObject*
637PyIntl_bind_textdomain_codeset(PyObject* self,PyObject*args)
638{
639 char *domain,*codeset;
640 if (!PyArg_ParseTuple(args, "sz", &domain, &codeset))
641 return NULL;
642 codeset = bind_textdomain_codeset(domain, codeset);
643 if (codeset)
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000644 return PyString_FromString(codeset);
Gustavo Niemeyer7bd33c52004-07-22 18:44:01 +0000645 Py_RETURN_NONE;
646}
647#endif
648
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000649#endif
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000650
Guido van Rossum220ecc81997-11-18 21:03:39 +0000651static struct PyMethodDef PyLocale_Methods[] = {
Andrew M. Kuchlinge365fb82000-08-03 02:06:16 +0000652 {"setlocale", (PyCFunction) PyLocale_setlocale,
653 METH_VARARGS, setlocale__doc__},
654 {"localeconv", (PyCFunction) PyLocale_localeconv,
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000655 METH_NOARGS, localeconv__doc__},
Andrew M. Kuchlinge365fb82000-08-03 02:06:16 +0000656 {"strcoll", (PyCFunction) PyLocale_strcoll,
657 METH_VARARGS, strcoll__doc__},
658 {"strxfrm", (PyCFunction) PyLocale_strxfrm,
659 METH_VARARGS, strxfrm__doc__},
Benjamin Petersone021c9c2009-06-07 16:24:48 +0000660#if defined(MS_WINDOWS)
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000661 {"_getdefaultlocale", (PyCFunction) PyLocale_getdefaultlocale, METH_NOARGS},
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000662#endif
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000663#ifdef HAVE_LANGINFO_H
664 {"nl_langinfo", (PyCFunction) PyLocale_nl_langinfo,
665 METH_VARARGS, nl_langinfo__doc__},
666#endif
Martin v. Löwisc6a7d7e2002-05-02 12:16:29 +0000667#ifdef HAVE_LIBINTL_H
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000668 {"gettext",(PyCFunction)PyIntl_gettext,METH_VARARGS,
669 gettext__doc__},
670 {"dgettext",(PyCFunction)PyIntl_dgettext,METH_VARARGS,
671 dgettext__doc__},
672 {"dcgettext",(PyCFunction)PyIntl_dcgettext,METH_VARARGS,
673 dcgettext__doc__},
674 {"textdomain",(PyCFunction)PyIntl_textdomain,METH_VARARGS,
675 textdomain__doc__},
676 {"bindtextdomain",(PyCFunction)PyIntl_bindtextdomain,METH_VARARGS,
677 bindtextdomain__doc__},
Gustavo Niemeyer7bd33c52004-07-22 18:44:01 +0000678#ifdef HAVE_BIND_TEXTDOMAIN_CODESET
679 {"bind_textdomain_codeset",(PyCFunction)PyIntl_bind_textdomain_codeset,
680 METH_VARARGS, bind_textdomain_codeset__doc__},
681#endif
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000682#endif
Guido van Rossum220ecc81997-11-18 21:03:39 +0000683 {NULL, NULL}
684};
685
Mark Hammondfe51c6d2002-08-02 02:27:13 +0000686PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000687init_locale(void)
Guido van Rossum220ecc81997-11-18 21:03:39 +0000688{
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000689 PyObject *m, *d, *x;
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000690#ifdef HAVE_LANGINFO_H
691 int i;
692#endif
Guido van Rossum220ecc81997-11-18 21:03:39 +0000693
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000694 m = Py_InitModule("_locale", PyLocale_Methods);
Neal Norwitz1ac754f2006-01-19 06:09:39 +0000695 if (m == NULL)
696 return;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000697
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000698 d = PyModule_GetDict(m);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000699
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000700 x = PyInt_FromLong(LC_CTYPE);
701 PyDict_SetItemString(d, "LC_CTYPE", x);
702 Py_XDECREF(x);
703
704 x = PyInt_FromLong(LC_TIME);
705 PyDict_SetItemString(d, "LC_TIME", x);
706 Py_XDECREF(x);
707
708 x = PyInt_FromLong(LC_COLLATE);
709 PyDict_SetItemString(d, "LC_COLLATE", x);
710 Py_XDECREF(x);
711
712 x = PyInt_FromLong(LC_MONETARY);
713 PyDict_SetItemString(d, "LC_MONETARY", x);
714 Py_XDECREF(x);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000715
Guido van Rossum8d9c2e31997-12-09 19:35:11 +0000716#ifdef LC_MESSAGES
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000717 x = PyInt_FromLong(LC_MESSAGES);
718 PyDict_SetItemString(d, "LC_MESSAGES", x);
719 Py_XDECREF(x);
Guido van Rossum8d9c2e31997-12-09 19:35:11 +0000720#endif /* LC_MESSAGES */
Guido van Rossum220ecc81997-11-18 21:03:39 +0000721
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000722 x = PyInt_FromLong(LC_NUMERIC);
723 PyDict_SetItemString(d, "LC_NUMERIC", x);
724 Py_XDECREF(x);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000725
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000726 x = PyInt_FromLong(LC_ALL);
727 PyDict_SetItemString(d, "LC_ALL", x);
728 Py_XDECREF(x);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000729
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000730 x = PyInt_FromLong(CHAR_MAX);
731 PyDict_SetItemString(d, "CHAR_MAX", x);
732 Py_XDECREF(x);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000733
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000734 Error = PyErr_NewException("locale.Error", NULL, NULL);
735 PyDict_SetItemString(d, "Error", Error);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000736
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000737 x = PyString_FromString(locale__doc__);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000738 PyDict_SetItemString(d, "__doc__", x);
739 Py_XDECREF(x);
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000740
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000741#ifdef HAVE_LANGINFO_H
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000742 for (i = 0; langinfo_constants[i].name; i++) {
743 PyModule_AddIntConstant(m, langinfo_constants[i].name,
744 langinfo_constants[i].value);
745 }
Martin v. Löwisf95dd0a2001-08-15 17:14:33 +0000746#endif
Guido van Rossum220ecc81997-11-18 21:03:39 +0000747}
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000748
749/*
750Local variables:
751c-basic-offset: 4
752indent-tabs-mode: nil
753End:
754*/