blob: e497a8faeef95646935344bd0a1ed993c7050807 [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
Martin v. Löwis6238d2b2002-06-30 15:26:10 +000035#if defined(MS_WINDOWS)
Tim Peters7a1f9172002-07-14 22:14:19 +000036#define WIN32_LEAN_AND_MEAN
Fredrik Lundh8f017a02000-07-08 19:57:37 +000037#include <windows.h>
Guido van Rossum239a2181998-04-28 16:08:19 +000038#endif
Guido van Rossum220ecc81997-11-18 21:03:39 +000039
Guido van Rossum1ca8bb32001-03-02 06:28:17 +000040#ifdef RISCOS
41char *strdup(const char *);
42#endif
43
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')
Antoine Pitrouc83ea132010-05-09 14:46:46 +000061 /* empty string: no grouping at all */
62 return PyList_New(0);
Fredrik Lundh8f017a02000-07-08 19:57:37 +000063
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
92static void
Fredrik Lundh8f017a02000-07-08 19:57:37 +000093fixup_ulcase(void)
Guido van Rossum220ecc81997-11-18 21:03:39 +000094{
Fredrik Lundh8f017a02000-07-08 19:57:37 +000095 PyObject *mods, *strop, *string, *ulo;
96 unsigned char ul[256];
97 int n, c;
Guido van Rossum220ecc81997-11-18 21:03:39 +000098
Fredrik Lundh8f017a02000-07-08 19:57:37 +000099 /* find the string and strop modules */
100 mods = PyImport_GetModuleDict();
101 if (!mods)
102 return;
103 string = PyDict_GetItemString(mods, "string");
104 if (string)
105 string = PyModule_GetDict(string);
106 strop=PyDict_GetItemString(mods, "strop");
107 if (strop)
108 strop = PyModule_GetDict(strop);
109 if (!string && !strop)
110 return;
111
112 /* create uppercase map string */
113 n = 0;
114 for (c = 0; c < 256; c++) {
115 if (isupper(c))
116 ul[n++] = c;
117 }
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000118 ulo = PyString_FromStringAndSize((const char *)ul, n);
Fredrik Lundh89610a42000-07-08 20:07:24 +0000119 if (!ulo)
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000120 return;
121 if (string)
122 PyDict_SetItemString(string, "uppercase", ulo);
123 if (strop)
124 PyDict_SetItemString(strop, "uppercase", ulo);
125 Py_DECREF(ulo);
126
127 /* create lowercase string */
128 n = 0;
129 for (c = 0; c < 256; c++) {
130 if (islower(c))
131 ul[n++] = c;
132 }
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000133 ulo = PyString_FromStringAndSize((const char *)ul, n);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000134 if (!ulo)
135 return;
136 if (string)
137 PyDict_SetItemString(string, "lowercase", ulo);
138 if (strop)
139 PyDict_SetItemString(strop, "lowercase", ulo);
140 Py_DECREF(ulo);
141
142 /* create letters string */
143 n = 0;
144 for (c = 0; c < 256; c++) {
145 if (isalpha(c))
146 ul[n++] = c;
147 }
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000148 ulo = PyString_FromStringAndSize((const char *)ul, n);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000149 if (!ulo)
150 return;
151 if (string)
152 PyDict_SetItemString(string, "letters", ulo);
153 Py_DECREF(ulo);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000154}
Martin v. Löwis7c82a3e02001-09-05 17:09:48 +0000155
Guido van Rossum220ecc81997-11-18 21:03:39 +0000156static PyObject*
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000157PyLocale_setlocale(PyObject* self, PyObject* args)
Guido van Rossum220ecc81997-11-18 21:03:39 +0000158{
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000159 int category;
160 char *locale = NULL, *result;
161 PyObject *result_object;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000162
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000163 if (!PyArg_ParseTuple(args, "i|z:setlocale", &category, &locale))
Fredrik Lundh89610a42000-07-08 20:07:24 +0000164 return NULL;
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000165
Amaury Forgeot d'Arcd7288712009-12-01 21:51:04 +0000166#if defined(MS_WINDOWS)
167 if (category < LC_MIN || category > LC_MAX)
168 {
169 PyErr_SetString(Error, "invalid locale category");
170 return NULL;
171 }
172#endif
173
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000174 if (locale) {
Benjamin Petersone4668aa2016-09-13 21:48:57 -0700175 /* set locale */
176 result = setlocale(category, locale);
177 if (!result) {
178 /* operation failed, no setting was changed */
179 PyErr_SetString(Error, "unsupported locale setting");
180 return NULL;
181 }
182 result_object = PyString_FromString(result);
183 if (!result_object)
184 return NULL;
185 /* record changes to LC_CTYPE */
186 if (category == LC_CTYPE || category == LC_ALL)
187 fixup_ulcase();
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000188 /* things that got wrong up to here are ignored */
189 PyErr_Clear();
190 } else {
Benjamin Petersone4668aa2016-09-13 21:48:57 -0700191 /* get locale */
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000192 result = setlocale(category, NULL);
193 if (!result) {
194 PyErr_SetString(Error, "locale query failed");
195 return NULL;
196 }
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000197 result_object = PyString_FromString(result);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000198 }
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000199 return result_object;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000200}
201
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000202PyDoc_STRVAR(localeconv__doc__,
203"() -> dict. Returns numeric and monetary locale-specific parameters.");
Guido van Rossum220ecc81997-11-18 21:03:39 +0000204
205static PyObject*
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000206PyLocale_localeconv(PyObject* self)
Guido van Rossum220ecc81997-11-18 21:03:39 +0000207{
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000208 PyObject* result;
209 struct lconv *l;
210 PyObject *x;
211
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000212 result = PyDict_New();
Fredrik Lundh89610a42000-07-08 20:07:24 +0000213 if (!result)
214 return NULL;
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000215
216 /* if LC_NUMERIC is different in the C library, use saved value */
217 l = localeconv();
218
219 /* hopefully, the localeconv result survives the C library calls
220 involved herein */
221
222#define RESULT_STRING(s)\
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000223 x = PyString_FromString(l->s);\
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000224 if (!x) goto failed;\
225 PyDict_SetItemString(result, #s, x);\
226 Py_XDECREF(x)
227
228#define RESULT_INT(i)\
229 x = PyInt_FromLong(l->i);\
230 if (!x) goto failed;\
231 PyDict_SetItemString(result, #i, x);\
232 Py_XDECREF(x)
Guido van Rossum220ecc81997-11-18 21:03:39 +0000233
234 /* Numeric information */
Martin v. Löwis737ea822004-06-08 18:52:54 +0000235 RESULT_STRING(decimal_point);
236 RESULT_STRING(thousands_sep);
237 x = copy_grouping(l->grouping);
238 if (!x)
239 goto failed;
240 PyDict_SetItemString(result, "grouping", x);
241 Py_XDECREF(x);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000242
243 /* Monetary information */
244 RESULT_STRING(int_curr_symbol);
245 RESULT_STRING(currency_symbol);
246 RESULT_STRING(mon_decimal_point);
247 RESULT_STRING(mon_thousands_sep);
248 x = copy_grouping(l->mon_grouping);
249 if (!x)
250 goto failed;
251 PyDict_SetItemString(result, "mon_grouping", x);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000252 Py_XDECREF(x);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000253 RESULT_STRING(positive_sign);
254 RESULT_STRING(negative_sign);
255 RESULT_INT(int_frac_digits);
256 RESULT_INT(frac_digits);
257 RESULT_INT(p_cs_precedes);
258 RESULT_INT(p_sep_by_space);
259 RESULT_INT(n_cs_precedes);
260 RESULT_INT(n_sep_by_space);
261 RESULT_INT(p_sign_posn);
262 RESULT_INT(n_sign_posn);
263 return result;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000264
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000265 failed:
266 Py_XDECREF(result);
267 Py_XDECREF(x);
268 return NULL;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000269}
270
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000271PyDoc_STRVAR(strcoll__doc__,
272"string,string -> int. Compares two strings according to the locale.");
Guido van Rossum220ecc81997-11-18 21:03:39 +0000273
274static PyObject*
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000275PyLocale_strcoll(PyObject* self, PyObject* args)
Guido van Rossum220ecc81997-11-18 21:03:39 +0000276{
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000277#if !defined(HAVE_WCSCOLL) || !defined(Py_USING_UNICODE)
278 char *s1,*s2;
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000279
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000280 if (!PyArg_ParseTuple(args, "ss:strcoll", &s1, &s2))
281 return NULL;
282 return PyInt_FromLong(strcoll(s1, s2));
283#else
284 PyObject *os1, *os2, *result = NULL;
285 wchar_t *ws1 = NULL, *ws2 = NULL;
286 int rel1 = 0, rel2 = 0, len1, len2;
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000287
Georg Brandl96a8c392006-05-29 21:04:52 +0000288 if (!PyArg_UnpackTuple(args, "strcoll", 2, 2, &os1, &os2))
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000289 return NULL;
290 /* If both arguments are byte strings, use strcoll. */
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000291 if (PyString_Check(os1) && PyString_Check(os2))
292 return PyInt_FromLong(strcoll(PyString_AS_STRING(os1),
293 PyString_AS_STRING(os2)));
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000294 /* If neither argument is unicode, it's an error. */
295 if (!PyUnicode_Check(os1) && !PyUnicode_Check(os2)) {
296 PyErr_SetString(PyExc_ValueError, "strcoll arguments must be strings");
297 }
298 /* Convert the non-unicode argument to unicode. */
299 if (!PyUnicode_Check(os1)) {
Benjamin Petersone4668aa2016-09-13 21:48:57 -0700300 os1 = PyUnicode_FromObject(os1);
301 if (!os1)
302 return NULL;
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000303 rel1 = 1;
304 }
305 if (!PyUnicode_Check(os2)) {
306 os2 = PyUnicode_FromObject(os2);
307 if (!os2) {
Georg Brandl278fc502008-07-19 12:46:12 +0000308 if (rel1) {
309 Py_DECREF(os1);
310 }
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000311 return NULL;
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000312 }
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000313 rel2 = 1;
314 }
315 /* Convert the unicode strings to wchar[]. */
316 len1 = PyUnicode_GET_SIZE(os1) + 1;
Serhiy Storchakaa2269d02015-02-16 13:16:07 +0200317 ws1 = PyMem_NEW(wchar_t, len1);
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000318 if (!ws1) {
319 PyErr_NoMemory();
320 goto done;
321 }
322 if (PyUnicode_AsWideChar((PyUnicodeObject*)os1, ws1, len1) == -1)
323 goto done;
Marc-André Lemburga9cadcd2004-11-22 13:02:31 +0000324 ws1[len1 - 1] = 0;
325 len2 = PyUnicode_GET_SIZE(os2) + 1;
Serhiy Storchakaa2269d02015-02-16 13:16:07 +0200326 ws2 = PyMem_NEW(wchar_t, len2);
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000327 if (!ws2) {
328 PyErr_NoMemory();
329 goto done;
330 }
331 if (PyUnicode_AsWideChar((PyUnicodeObject*)os2, ws2, len2) == -1)
332 goto done;
Marc-André Lemburga9cadcd2004-11-22 13:02:31 +0000333 ws2[len2 - 1] = 0;
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000334 /* Collate the strings. */
335 result = PyInt_FromLong(wcscoll(ws1, ws2));
336 done:
337 /* Deallocate everything. */
338 if (ws1) PyMem_FREE(ws1);
339 if (ws2) PyMem_FREE(ws2);
340 if (rel1) {
341 Py_DECREF(os1);
342 }
343 if (rel2) {
344 Py_DECREF(os2);
345 }
346 return result;
347#endif
Guido van Rossum220ecc81997-11-18 21:03:39 +0000348}
349
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000350
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000351PyDoc_STRVAR(strxfrm__doc__,
352"string -> string. Returns a string that behaves for cmp locale-aware.");
Guido van Rossum220ecc81997-11-18 21:03:39 +0000353
354static PyObject*
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000355PyLocale_strxfrm(PyObject* self, PyObject* args)
Guido van Rossum220ecc81997-11-18 21:03:39 +0000356{
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000357 char *s, *buf;
358 size_t n1, n2;
359 PyObject *result;
360
Fredrik Lundh89610a42000-07-08 20:07:24 +0000361 if (!PyArg_ParseTuple(args, "s:strxfrm", &s))
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000362 return NULL;
363
364 /* assume no change in size, first */
365 n1 = strlen(s) + 1;
366 buf = PyMem_Malloc(n1);
367 if (!buf)
368 return PyErr_NoMemory();
Matthias Klosee19e0c22007-04-03 04:35:59 +0000369 n2 = strxfrm(buf, s, n1) + 1;
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000370 if (n2 > n1) {
371 /* more space needed */
372 buf = PyMem_Realloc(buf, n2);
373 if (!buf)
374 return PyErr_NoMemory();
375 strxfrm(buf, s, n2);
376 }
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000377 result = PyString_FromString(buf);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000378 PyMem_Free(buf);
379 return result;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000380}
381
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000382#if defined(MS_WINDOWS)
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000383static PyObject*
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000384PyLocale_getdefaultlocale(PyObject* self)
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000385{
386 char encoding[100];
387 char locale[100];
388
Tim Peters885d4572001-11-28 20:27:42 +0000389 PyOS_snprintf(encoding, sizeof(encoding), "cp%d", GetACP());
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000390
391 if (GetLocaleInfo(LOCALE_USER_DEFAULT,
392 LOCALE_SISO639LANGNAME,
393 locale, sizeof(locale))) {
Martin v. Löwis18e16552006-02-15 17:27:45 +0000394 Py_ssize_t i = strlen(locale);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000395 locale[i++] = '_';
396 if (GetLocaleInfo(LOCALE_USER_DEFAULT,
397 LOCALE_SISO3166CTRYNAME,
Martin v. Löwis18e16552006-02-15 17:27:45 +0000398 locale+i, (int)(sizeof(locale)-i)))
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000399 return Py_BuildValue("ss", locale, encoding);
400 }
401
402 /* If we end up here, this windows version didn't know about
403 ISO639/ISO3166 names (it's probably Windows 95). Return the
404 Windows language identifier instead (a hexadecimal number) */
405
406 locale[0] = '0';
407 locale[1] = 'x';
408 if (GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_IDEFAULTLANGUAGE,
409 locale+2, sizeof(locale)-2)) {
410 return Py_BuildValue("ss", locale, encoding);
411 }
412
413 /* cannot determine the language code (very unlikely) */
414 Py_INCREF(Py_None);
415 return Py_BuildValue("Os", Py_None, encoding);
416}
417#endif
418
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000419#ifdef HAVE_LANGINFO_H
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000420#define LANGINFO(X) {#X, X}
Martin v. Löwis111c1802008-06-13 07:47:47 +0000421static struct langinfo_constant{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000422 char* name;
423 int value;
424} langinfo_constants[] =
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000425{
426 /* These constants should exist on any langinfo implementation */
427 LANGINFO(DAY_1),
428 LANGINFO(DAY_2),
429 LANGINFO(DAY_3),
430 LANGINFO(DAY_4),
431 LANGINFO(DAY_5),
432 LANGINFO(DAY_6),
433 LANGINFO(DAY_7),
434
435 LANGINFO(ABDAY_1),
436 LANGINFO(ABDAY_2),
437 LANGINFO(ABDAY_3),
438 LANGINFO(ABDAY_4),
439 LANGINFO(ABDAY_5),
440 LANGINFO(ABDAY_6),
441 LANGINFO(ABDAY_7),
442
443 LANGINFO(MON_1),
444 LANGINFO(MON_2),
445 LANGINFO(MON_3),
446 LANGINFO(MON_4),
447 LANGINFO(MON_5),
448 LANGINFO(MON_6),
449 LANGINFO(MON_7),
450 LANGINFO(MON_8),
451 LANGINFO(MON_9),
452 LANGINFO(MON_10),
453 LANGINFO(MON_11),
454 LANGINFO(MON_12),
455
456 LANGINFO(ABMON_1),
457 LANGINFO(ABMON_2),
458 LANGINFO(ABMON_3),
459 LANGINFO(ABMON_4),
460 LANGINFO(ABMON_5),
461 LANGINFO(ABMON_6),
462 LANGINFO(ABMON_7),
463 LANGINFO(ABMON_8),
464 LANGINFO(ABMON_9),
465 LANGINFO(ABMON_10),
466 LANGINFO(ABMON_11),
467 LANGINFO(ABMON_12),
468
469#ifdef RADIXCHAR
470 /* The following are not available with glibc 2.0 */
471 LANGINFO(RADIXCHAR),
472 LANGINFO(THOUSEP),
473 /* YESSTR and NOSTR are deprecated in glibc, since they are
474 a special case of message translation, which should be rather
475 done using gettext. So we don't expose it to Python in the
476 first place.
477 LANGINFO(YESSTR),
478 LANGINFO(NOSTR),
479 */
480 LANGINFO(CRNCYSTR),
481#endif
482
483 LANGINFO(D_T_FMT),
484 LANGINFO(D_FMT),
485 LANGINFO(T_FMT),
486 LANGINFO(AM_STR),
487 LANGINFO(PM_STR),
488
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000489 /* The following constants are available only with XPG4, but...
490 AIX 3.2. only has CODESET.
491 OpenBSD doesn't have CODESET but has T_FMT_AMPM, and doesn't have
492 a few of the others.
493 Solution: ifdef-test them all. */
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000494#ifdef CODESET
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000495 LANGINFO(CODESET),
Martin v. Löwis496f9e42002-03-27 12:15:57 +0000496#endif
497#ifdef T_FMT_AMPM
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000498 LANGINFO(T_FMT_AMPM),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000499#endif
500#ifdef ERA
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000501 LANGINFO(ERA),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000502#endif
503#ifdef ERA_D_FMT
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000504 LANGINFO(ERA_D_FMT),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000505#endif
506#ifdef ERA_D_T_FMT
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000507 LANGINFO(ERA_D_T_FMT),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000508#endif
509#ifdef ERA_T_FMT
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000510 LANGINFO(ERA_T_FMT),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000511#endif
512#ifdef ALT_DIGITS
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000513 LANGINFO(ALT_DIGITS),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000514#endif
515#ifdef YESEXPR
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000516 LANGINFO(YESEXPR),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000517#endif
518#ifdef NOEXPR
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000519 LANGINFO(NOEXPR),
520#endif
521#ifdef _DATE_FMT
522 /* This is not available in all glibc versions that have CODESET. */
523 LANGINFO(_DATE_FMT),
524#endif
525 {0, 0}
526};
527
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000528PyDoc_STRVAR(nl_langinfo__doc__,
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000529"nl_langinfo(key) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000530"Return the value for the locale information associated with key.");
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000531
532static PyObject*
533PyLocale_nl_langinfo(PyObject* self, PyObject* args)
534{
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000535 int item, i;
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000536 if (!PyArg_ParseTuple(args, "i:nl_langinfo", &item))
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000537 return NULL;
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000538 /* Check whether this is a supported constant. GNU libc sometimes
539 returns numeric values in the char* return value, which would
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000540 crash PyString_FromString. */
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000541 for (i = 0; langinfo_constants[i].name; i++)
Hye-Shik Changc3a87b82004-03-21 19:34:30 +0000542 if (langinfo_constants[i].value == item) {
543 /* Check NULL as a workaround for GNU libc's returning NULL
544 instead of an empty string for nl_langinfo(ERA). */
545 const char *result = nl_langinfo(item);
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000546 return PyString_FromString(result != NULL ? result : "");
Hye-Shik Changc3a87b82004-03-21 19:34:30 +0000547 }
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000548 PyErr_SetString(PyExc_ValueError, "unsupported langinfo constant");
549 return NULL;
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000550}
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000551#endif /* HAVE_LANGINFO_H */
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000552
553#ifdef HAVE_LIBINTL_H
554
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000555PyDoc_STRVAR(gettext__doc__,
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000556"gettext(msg) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000557"Return translation of msg.");
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000558
559static PyObject*
560PyIntl_gettext(PyObject* self, PyObject *args)
561{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000562 char *in;
563 if (!PyArg_ParseTuple(args, "s", &in))
564 return 0;
565 return PyString_FromString(gettext(in));
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000566}
567
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000568PyDoc_STRVAR(dgettext__doc__,
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000569"dgettext(domain, msg) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000570"Return translation of msg in domain.");
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000571
572static PyObject*
573PyIntl_dgettext(PyObject* self, PyObject *args)
574{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000575 char *domain, *in;
576 if (!PyArg_ParseTuple(args, "zs", &domain, &in))
577 return 0;
578 return PyString_FromString(dgettext(domain, in));
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000579}
580
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000581PyDoc_STRVAR(dcgettext__doc__,
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000582"dcgettext(domain, msg, category) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000583"Return translation of msg in domain and category.");
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000584
585static PyObject*
586PyIntl_dcgettext(PyObject *self, PyObject *args)
587{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000588 char *domain, *msgid;
589 int category;
590 if (!PyArg_ParseTuple(args, "zsi", &domain, &msgid, &category))
591 return 0;
592 return PyString_FromString(dcgettext(domain,msgid,category));
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000593}
594
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000595PyDoc_STRVAR(textdomain__doc__,
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000596"textdomain(domain) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000597"Set the C library's textdmain to domain, returning the new domain.");
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000598
599static PyObject*
600PyIntl_textdomain(PyObject* self, PyObject* args)
601{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000602 char *domain;
603 if (!PyArg_ParseTuple(args, "z", &domain))
604 return 0;
605 domain = textdomain(domain);
606 if (!domain) {
607 PyErr_SetFromErrno(PyExc_OSError);
608 return NULL;
609 }
610 return PyString_FromString(domain);
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000611}
612
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000613PyDoc_STRVAR(bindtextdomain__doc__,
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000614"bindtextdomain(domain, dir) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000615"Bind the C library's domain to dir.");
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000616
617static PyObject*
618PyIntl_bindtextdomain(PyObject* self,PyObject*args)
619{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000620 char *domain, *dirname;
621 if (!PyArg_ParseTuple(args, "sz", &domain, &dirname))
622 return 0;
623 if (!strlen(domain)) {
624 PyErr_SetString(Error, "domain must be a non-empty string");
625 return 0;
626 }
627 dirname = bindtextdomain(domain, dirname);
628 if (!dirname) {
629 PyErr_SetFromErrno(PyExc_OSError);
630 return NULL;
631 }
632 return PyString_FromString(dirname);
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000633}
634
Gustavo Niemeyer7bd33c52004-07-22 18:44:01 +0000635#ifdef HAVE_BIND_TEXTDOMAIN_CODESET
636PyDoc_STRVAR(bind_textdomain_codeset__doc__,
637"bind_textdomain_codeset(domain, codeset) -> string\n"
638"Bind the C library's domain to codeset.");
639
640static PyObject*
641PyIntl_bind_textdomain_codeset(PyObject* self,PyObject*args)
642{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000643 char *domain,*codeset;
644 if (!PyArg_ParseTuple(args, "sz", &domain, &codeset))
645 return NULL;
646 codeset = bind_textdomain_codeset(domain, codeset);
647 if (codeset)
648 return PyString_FromString(codeset);
649 Py_RETURN_NONE;
Gustavo Niemeyer7bd33c52004-07-22 18:44:01 +0000650}
651#endif
652
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000653#endif
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000654
Guido van Rossum220ecc81997-11-18 21:03:39 +0000655static struct PyMethodDef PyLocale_Methods[] = {
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000656 {"setlocale", (PyCFunction) PyLocale_setlocale,
Andrew M. Kuchlinge365fb82000-08-03 02:06:16 +0000657 METH_VARARGS, setlocale__doc__},
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000658 {"localeconv", (PyCFunction) PyLocale_localeconv,
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000659 METH_NOARGS, localeconv__doc__},
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000660 {"strcoll", (PyCFunction) PyLocale_strcoll,
Andrew M. Kuchlinge365fb82000-08-03 02:06:16 +0000661 METH_VARARGS, strcoll__doc__},
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000662 {"strxfrm", (PyCFunction) PyLocale_strxfrm,
Andrew M. Kuchlinge365fb82000-08-03 02:06:16 +0000663 METH_VARARGS, strxfrm__doc__},
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000664#if defined(MS_WINDOWS)
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000665 {"_getdefaultlocale", (PyCFunction) PyLocale_getdefaultlocale, METH_NOARGS},
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000666#endif
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000667#ifdef HAVE_LANGINFO_H
668 {"nl_langinfo", (PyCFunction) PyLocale_nl_langinfo,
669 METH_VARARGS, nl_langinfo__doc__},
670#endif
Martin v. Löwisc6a7d7e2002-05-02 12:16:29 +0000671#ifdef HAVE_LIBINTL_H
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000672 {"gettext",(PyCFunction)PyIntl_gettext,METH_VARARGS,
673 gettext__doc__},
674 {"dgettext",(PyCFunction)PyIntl_dgettext,METH_VARARGS,
675 dgettext__doc__},
676 {"dcgettext",(PyCFunction)PyIntl_dcgettext,METH_VARARGS,
677 dcgettext__doc__},
678 {"textdomain",(PyCFunction)PyIntl_textdomain,METH_VARARGS,
679 textdomain__doc__},
680 {"bindtextdomain",(PyCFunction)PyIntl_bindtextdomain,METH_VARARGS,
681 bindtextdomain__doc__},
Gustavo Niemeyer7bd33c52004-07-22 18:44:01 +0000682#ifdef HAVE_BIND_TEXTDOMAIN_CODESET
683 {"bind_textdomain_codeset",(PyCFunction)PyIntl_bind_textdomain_codeset,
684 METH_VARARGS, bind_textdomain_codeset__doc__},
685#endif
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000686#endif
Guido van Rossum220ecc81997-11-18 21:03:39 +0000687 {NULL, NULL}
688};
689
Mark Hammondfe51c6d2002-08-02 02:27:13 +0000690PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000691init_locale(void)
Guido van Rossum220ecc81997-11-18 21:03:39 +0000692{
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000693 PyObject *m, *d, *x;
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000694#ifdef HAVE_LANGINFO_H
695 int i;
696#endif
Guido van Rossum220ecc81997-11-18 21:03:39 +0000697
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000698 m = Py_InitModule("_locale", PyLocale_Methods);
Neal Norwitz1ac754f2006-01-19 06:09:39 +0000699 if (m == NULL)
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000700 return;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000701
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000702 d = PyModule_GetDict(m);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000703
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000704 x = PyInt_FromLong(LC_CTYPE);
705 PyDict_SetItemString(d, "LC_CTYPE", x);
706 Py_XDECREF(x);
707
708 x = PyInt_FromLong(LC_TIME);
709 PyDict_SetItemString(d, "LC_TIME", x);
710 Py_XDECREF(x);
711
712 x = PyInt_FromLong(LC_COLLATE);
713 PyDict_SetItemString(d, "LC_COLLATE", x);
714 Py_XDECREF(x);
715
716 x = PyInt_FromLong(LC_MONETARY);
717 PyDict_SetItemString(d, "LC_MONETARY", x);
718 Py_XDECREF(x);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000719
Guido van Rossum8d9c2e31997-12-09 19:35:11 +0000720#ifdef LC_MESSAGES
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000721 x = PyInt_FromLong(LC_MESSAGES);
722 PyDict_SetItemString(d, "LC_MESSAGES", x);
723 Py_XDECREF(x);
Guido van Rossum8d9c2e31997-12-09 19:35:11 +0000724#endif /* LC_MESSAGES */
Guido van Rossum220ecc81997-11-18 21:03:39 +0000725
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000726 x = PyInt_FromLong(LC_NUMERIC);
727 PyDict_SetItemString(d, "LC_NUMERIC", 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(LC_ALL);
731 PyDict_SetItemString(d, "LC_ALL", x);
732 Py_XDECREF(x);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000733
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000734 x = PyInt_FromLong(CHAR_MAX);
735 PyDict_SetItemString(d, "CHAR_MAX", x);
736 Py_XDECREF(x);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000737
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000738 Error = PyErr_NewException("locale.Error", NULL, NULL);
739 PyDict_SetItemString(d, "Error", Error);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000740
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000741 x = PyString_FromString(locale__doc__);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000742 PyDict_SetItemString(d, "__doc__", x);
743 Py_XDECREF(x);
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000744
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000745#ifdef HAVE_LANGINFO_H
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000746 for (i = 0; langinfo_constants[i].name; i++) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000747 PyModule_AddIntConstant(m, langinfo_constants[i].name,
748 langinfo_constants[i].value);
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000749 }
Martin v. Löwisf95dd0a2001-08-15 17:14:33 +0000750#endif
Guido van Rossum220ecc81997-11-18 21:03:39 +0000751}
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000752
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000753/*
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000754Local variables:
755c-basic-offset: 4
756indent-tabs-mode: nil
757End:
758*/