Blocked revisions 73580-73582 via svnmerge
[python/dscho.git] / Modules / _localemodule.c
blobc215ef3475fed86b79de9f1fb5b33c4c218734ba
1 /***********************************************************
2 Copyright (C) 1997, 2002, 2003, 2007, 2008 Martin von Loewis
4 Permission to use, copy, modify, and distribute this software and its
5 documentation for any purpose and without fee is hereby granted,
6 provided that the above copyright notice appear in all copies.
8 This software comes with no warranty. Use at your own risk.
10 ******************************************************************/
12 #include "Python.h"
14 #include <stdio.h>
15 #include <locale.h>
16 #include <string.h>
17 #include <ctype.h>
19 #ifdef HAVE_ERRNO_H
20 #include <errno.h>
21 #endif
23 #ifdef HAVE_LANGINFO_H
24 #include <langinfo.h>
25 #endif
27 #ifdef HAVE_LIBINTL_H
28 #include <libintl.h>
29 #endif
31 #ifdef HAVE_WCHAR_H
32 #include <wchar.h>
33 #endif
35 #if defined(__APPLE__)
36 #include <CoreFoundation/CoreFoundation.h>
37 #endif
39 #if defined(MS_WINDOWS)
40 #define WIN32_LEAN_AND_MEAN
41 #include <windows.h>
42 #endif
44 PyDoc_STRVAR(locale__doc__, "Support for POSIX locales.");
46 static PyObject *Error;
48 /* Convert a char* to a Unicode object according to the current locale */
49 static PyObject*
50 str2uni(const char* s)
52 #ifdef HAVE_BROKEN_MBSTOWCS
53 size_t needed = strlen(s);
54 #else
55 size_t needed = mbstowcs(NULL, s, 0);
56 #endif
57 size_t res1;
58 wchar_t smallbuf[30];
59 wchar_t *dest;
60 PyObject *res2;
61 if (needed == (size_t)-1) {
62 PyErr_SetString(PyExc_ValueError, "Cannot convert byte to string");
63 return NULL;
65 if (needed*sizeof(wchar_t) < sizeof(smallbuf))
66 dest = smallbuf;
67 else {
68 dest = PyMem_Malloc((needed+1)*sizeof(wchar_t));
69 if (!dest)
70 return PyErr_NoMemory();
72 /* This shouldn't fail now */
73 res1 = mbstowcs(dest, s, needed+1);
74 #ifdef HAVE_BROKEN_MBSTOWCS
75 assert(res1 != (size_t)-1);
76 #else
77 assert(res1 == needed);
78 #endif
79 res2 = PyUnicode_FromWideChar(dest, res1);
80 if (dest != smallbuf)
81 PyMem_Free(dest);
82 return res2;
85 /* support functions for formatting floating point numbers */
87 PyDoc_STRVAR(setlocale__doc__,
88 "(integer,string=None) -> string. Activates/queries locale processing.");
90 /* the grouping is terminated by either 0 or CHAR_MAX */
91 static PyObject*
92 copy_grouping(char* s)
94 int i;
95 PyObject *result, *val = NULL;
97 if (s[0] == '\0')
98 /* empty string: no grouping at all */
99 return PyList_New(0);
101 for (i = 0; s[i] != '\0' && s[i] != CHAR_MAX; i++)
102 ; /* nothing */
104 result = PyList_New(i+1);
105 if (!result)
106 return NULL;
108 i = -1;
109 do {
110 i++;
111 val = PyLong_FromLong(s[i]);
112 if (!val)
113 break;
114 if (PyList_SetItem(result, i, val)) {
115 Py_DECREF(val);
116 val = NULL;
117 break;
119 } while (s[i] != '\0' && s[i] != CHAR_MAX);
121 if (!val) {
122 Py_DECREF(result);
123 return NULL;
126 return result;
129 static PyObject*
130 PyLocale_setlocale(PyObject* self, PyObject* args)
132 int category;
133 char *locale = NULL, *result;
134 PyObject *result_object;
136 if (!PyArg_ParseTuple(args, "i|z:setlocale", &category, &locale))
137 return NULL;
139 if (locale) {
140 /* set locale */
141 result = setlocale(category, locale);
142 if (!result) {
143 /* operation failed, no setting was changed */
144 PyErr_SetString(Error, "unsupported locale setting");
145 return NULL;
147 result_object = str2uni(result);
148 if (!result_object)
149 return NULL;
150 } else {
151 /* get locale */
152 result = setlocale(category, NULL);
153 if (!result) {
154 PyErr_SetString(Error, "locale query failed");
155 return NULL;
157 result_object = str2uni(result);
159 return result_object;
162 PyDoc_STRVAR(localeconv__doc__,
163 "() -> dict. Returns numeric and monetary locale-specific parameters.");
165 static PyObject*
166 PyLocale_localeconv(PyObject* self)
168 PyObject* result;
169 struct lconv *l;
170 PyObject *x;
172 result = PyDict_New();
173 if (!result)
174 return NULL;
176 /* if LC_NUMERIC is different in the C library, use saved value */
177 l = localeconv();
179 /* hopefully, the localeconv result survives the C library calls
180 involved herein */
182 #define RESULT_STRING(s)\
183 x = str2uni(l->s); \
184 if (!x) goto failed;\
185 PyDict_SetItemString(result, #s, x);\
186 Py_XDECREF(x)
188 #define RESULT_INT(i)\
189 x = PyLong_FromLong(l->i);\
190 if (!x) goto failed;\
191 PyDict_SetItemString(result, #i, x);\
192 Py_XDECREF(x)
194 /* Numeric information */
195 RESULT_STRING(decimal_point);
196 RESULT_STRING(thousands_sep);
197 x = copy_grouping(l->grouping);
198 if (!x)
199 goto failed;
200 PyDict_SetItemString(result, "grouping", x);
201 Py_XDECREF(x);
203 /* Monetary information */
204 RESULT_STRING(int_curr_symbol);
205 RESULT_STRING(currency_symbol);
206 RESULT_STRING(mon_decimal_point);
207 RESULT_STRING(mon_thousands_sep);
208 x = copy_grouping(l->mon_grouping);
209 if (!x)
210 goto failed;
211 PyDict_SetItemString(result, "mon_grouping", x);
212 Py_XDECREF(x);
213 RESULT_STRING(positive_sign);
214 RESULT_STRING(negative_sign);
215 RESULT_INT(int_frac_digits);
216 RESULT_INT(frac_digits);
217 RESULT_INT(p_cs_precedes);
218 RESULT_INT(p_sep_by_space);
219 RESULT_INT(n_cs_precedes);
220 RESULT_INT(n_sep_by_space);
221 RESULT_INT(p_sign_posn);
222 RESULT_INT(n_sign_posn);
223 return result;
225 failed:
226 Py_XDECREF(result);
227 Py_XDECREF(x);
228 return NULL;
231 #if defined(HAVE_WCSCOLL)
232 PyDoc_STRVAR(strcoll__doc__,
233 "string,string -> int. Compares two strings according to the locale.");
235 static PyObject*
236 PyLocale_strcoll(PyObject* self, PyObject* args)
238 PyObject *os1, *os2, *result = NULL;
239 wchar_t *ws1 = NULL, *ws2 = NULL;
240 Py_ssize_t len1, len2;
242 if (!PyArg_ParseTuple(args, "UU:strcoll", &os1, &os2))
243 return NULL;
244 /* Convert the unicode strings to wchar[]. */
245 len1 = PyUnicode_GET_SIZE(os1) + 1;
246 ws1 = PyMem_MALLOC(len1 * sizeof(wchar_t));
247 if (!ws1) {
248 PyErr_NoMemory();
249 goto done;
251 if (PyUnicode_AsWideChar((PyUnicodeObject*)os1, ws1, len1) == -1)
252 goto done;
253 ws1[len1 - 1] = 0;
254 len2 = PyUnicode_GET_SIZE(os2) + 1;
255 ws2 = PyMem_MALLOC(len2 * sizeof(wchar_t));
256 if (!ws2) {
257 PyErr_NoMemory();
258 goto done;
260 if (PyUnicode_AsWideChar((PyUnicodeObject*)os2, ws2, len2) == -1)
261 goto done;
262 ws2[len2 - 1] = 0;
263 /* Collate the strings. */
264 result = PyLong_FromLong(wcscoll(ws1, ws2));
265 done:
266 /* Deallocate everything. */
267 if (ws1) PyMem_FREE(ws1);
268 if (ws2) PyMem_FREE(ws2);
269 return result;
271 #endif
273 #ifdef HAVE_WCSXFRM
274 PyDoc_STRVAR(strxfrm__doc__,
275 "strxfrm(string) -> string.\n\
277 Return a string that can be used as a key for locale-aware comparisons.");
279 static PyObject*
280 PyLocale_strxfrm(PyObject* self, PyObject* args)
282 Py_UNICODE *s0;
283 Py_ssize_t n0;
284 wchar_t *s, *buf = NULL;
285 size_t n1, n2;
286 PyObject *result = NULL;
287 Py_ssize_t i;
289 if (!PyArg_ParseTuple(args, "u#:strxfrm", &s0, &n0))
290 return NULL;
292 #ifdef HAVE_USABLE_WCHAR_T
293 s = s0;
294 #else
295 s = PyMem_Malloc((n0+1)*sizeof(wchar_t));
296 if (!s)
297 return PyErr_NoMemory();
298 for (i=0; i<=n0; i++)
299 s[i] = s0[i];
300 #endif
302 /* assume no change in size, first */
303 n1 = wcslen(s) + 1;
304 buf = PyMem_Malloc(n1*sizeof(wchar_t));
305 if (!buf) {
306 PyErr_NoMemory();
307 goto exit;
309 n2 = wcsxfrm(buf, s, n1);
310 if (n2 >= n1) {
311 /* more space needed */
312 buf = PyMem_Realloc(buf, (n2+1)*sizeof(wchar_t));
313 if (!buf) {
314 PyErr_NoMemory();
315 goto exit;
317 n2 = wcsxfrm(buf, s, n2+1);
319 result = PyUnicode_FromWideChar(buf, n2);
320 exit:
321 if (buf) PyMem_Free(buf);
322 #ifdef HAVE_USABLE_WCHAR_T
323 PyMem_Free(s);
324 #endif
325 return result;
327 #endif
329 #if defined(MS_WINDOWS)
330 static PyObject*
331 PyLocale_getdefaultlocale(PyObject* self)
333 char encoding[100];
334 char locale[100];
336 PyOS_snprintf(encoding, sizeof(encoding), "cp%d", GetACP());
338 if (GetLocaleInfo(LOCALE_USER_DEFAULT,
339 LOCALE_SISO639LANGNAME,
340 locale, sizeof(locale))) {
341 Py_ssize_t i = strlen(locale);
342 locale[i++] = '_';
343 if (GetLocaleInfo(LOCALE_USER_DEFAULT,
344 LOCALE_SISO3166CTRYNAME,
345 locale+i, (int)(sizeof(locale)-i)))
346 return Py_BuildValue("ss", locale, encoding);
349 /* If we end up here, this windows version didn't know about
350 ISO639/ISO3166 names (it's probably Windows 95). Return the
351 Windows language identifier instead (a hexadecimal number) */
353 locale[0] = '0';
354 locale[1] = 'x';
355 if (GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_IDEFAULTLANGUAGE,
356 locale+2, sizeof(locale)-2)) {
357 return Py_BuildValue("ss", locale, encoding);
360 /* cannot determine the language code (very unlikely) */
361 Py_INCREF(Py_None);
362 return Py_BuildValue("Os", Py_None, encoding);
364 #endif
366 #ifdef HAVE_LANGINFO_H
367 #define LANGINFO(X) {#X, X}
368 static struct langinfo_constant{
369 char* name;
370 int value;
371 } langinfo_constants[] =
373 /* These constants should exist on any langinfo implementation */
374 LANGINFO(DAY_1),
375 LANGINFO(DAY_2),
376 LANGINFO(DAY_3),
377 LANGINFO(DAY_4),
378 LANGINFO(DAY_5),
379 LANGINFO(DAY_6),
380 LANGINFO(DAY_7),
382 LANGINFO(ABDAY_1),
383 LANGINFO(ABDAY_2),
384 LANGINFO(ABDAY_3),
385 LANGINFO(ABDAY_4),
386 LANGINFO(ABDAY_5),
387 LANGINFO(ABDAY_6),
388 LANGINFO(ABDAY_7),
390 LANGINFO(MON_1),
391 LANGINFO(MON_2),
392 LANGINFO(MON_3),
393 LANGINFO(MON_4),
394 LANGINFO(MON_5),
395 LANGINFO(MON_6),
396 LANGINFO(MON_7),
397 LANGINFO(MON_8),
398 LANGINFO(MON_9),
399 LANGINFO(MON_10),
400 LANGINFO(MON_11),
401 LANGINFO(MON_12),
403 LANGINFO(ABMON_1),
404 LANGINFO(ABMON_2),
405 LANGINFO(ABMON_3),
406 LANGINFO(ABMON_4),
407 LANGINFO(ABMON_5),
408 LANGINFO(ABMON_6),
409 LANGINFO(ABMON_7),
410 LANGINFO(ABMON_8),
411 LANGINFO(ABMON_9),
412 LANGINFO(ABMON_10),
413 LANGINFO(ABMON_11),
414 LANGINFO(ABMON_12),
416 #ifdef RADIXCHAR
417 /* The following are not available with glibc 2.0 */
418 LANGINFO(RADIXCHAR),
419 LANGINFO(THOUSEP),
420 /* YESSTR and NOSTR are deprecated in glibc, since they are
421 a special case of message translation, which should be rather
422 done using gettext. So we don't expose it to Python in the
423 first place.
424 LANGINFO(YESSTR),
425 LANGINFO(NOSTR),
427 LANGINFO(CRNCYSTR),
428 #endif
430 LANGINFO(D_T_FMT),
431 LANGINFO(D_FMT),
432 LANGINFO(T_FMT),
433 LANGINFO(AM_STR),
434 LANGINFO(PM_STR),
436 /* The following constants are available only with XPG4, but...
437 AIX 3.2. only has CODESET.
438 OpenBSD doesn't have CODESET but has T_FMT_AMPM, and doesn't have
439 a few of the others.
440 Solution: ifdef-test them all. */
441 #ifdef CODESET
442 LANGINFO(CODESET),
443 #endif
444 #ifdef T_FMT_AMPM
445 LANGINFO(T_FMT_AMPM),
446 #endif
447 #ifdef ERA
448 LANGINFO(ERA),
449 #endif
450 #ifdef ERA_D_FMT
451 LANGINFO(ERA_D_FMT),
452 #endif
453 #ifdef ERA_D_T_FMT
454 LANGINFO(ERA_D_T_FMT),
455 #endif
456 #ifdef ERA_T_FMT
457 LANGINFO(ERA_T_FMT),
458 #endif
459 #ifdef ALT_DIGITS
460 LANGINFO(ALT_DIGITS),
461 #endif
462 #ifdef YESEXPR
463 LANGINFO(YESEXPR),
464 #endif
465 #ifdef NOEXPR
466 LANGINFO(NOEXPR),
467 #endif
468 #ifdef _DATE_FMT
469 /* This is not available in all glibc versions that have CODESET. */
470 LANGINFO(_DATE_FMT),
471 #endif
472 {0, 0}
475 PyDoc_STRVAR(nl_langinfo__doc__,
476 "nl_langinfo(key) -> string\n"
477 "Return the value for the locale information associated with key.");
479 static PyObject*
480 PyLocale_nl_langinfo(PyObject* self, PyObject* args)
482 int item, i;
483 if (!PyArg_ParseTuple(args, "i:nl_langinfo", &item))
484 return NULL;
485 /* Check whether this is a supported constant. GNU libc sometimes
486 returns numeric values in the char* return value, which would
487 crash PyUnicode_FromString. */
488 for (i = 0; langinfo_constants[i].name; i++)
489 if (langinfo_constants[i].value == item) {
490 /* Check NULL as a workaround for GNU libc's returning NULL
491 instead of an empty string for nl_langinfo(ERA). */
492 const char *result = nl_langinfo(item);
493 result = result != NULL ? result : "";
494 return str2uni(result);
496 PyErr_SetString(PyExc_ValueError, "unsupported langinfo constant");
497 return NULL;
499 #endif /* HAVE_LANGINFO_H */
501 #ifdef HAVE_LIBINTL_H
503 PyDoc_STRVAR(gettext__doc__,
504 "gettext(msg) -> string\n"
505 "Return translation of msg.");
507 static PyObject*
508 PyIntl_gettext(PyObject* self, PyObject *args)
510 char *in;
511 if (!PyArg_ParseTuple(args, "s", &in))
512 return 0;
513 return str2uni(gettext(in));
516 PyDoc_STRVAR(dgettext__doc__,
517 "dgettext(domain, msg) -> string\n"
518 "Return translation of msg in domain.");
520 static PyObject*
521 PyIntl_dgettext(PyObject* self, PyObject *args)
523 char *domain, *in;
524 if (!PyArg_ParseTuple(args, "zs", &domain, &in))
525 return 0;
526 return str2uni(dgettext(domain, in));
529 PyDoc_STRVAR(dcgettext__doc__,
530 "dcgettext(domain, msg, category) -> string\n"
531 "Return translation of msg in domain and category.");
533 static PyObject*
534 PyIntl_dcgettext(PyObject *self, PyObject *args)
536 char *domain, *msgid;
537 int category;
538 if (!PyArg_ParseTuple(args, "zsi", &domain, &msgid, &category))
539 return 0;
540 return str2uni(dcgettext(domain,msgid,category));
543 PyDoc_STRVAR(textdomain__doc__,
544 "textdomain(domain) -> string\n"
545 "Set the C library's textdmain to domain, returning the new domain.");
547 static PyObject*
548 PyIntl_textdomain(PyObject* self, PyObject* args)
550 char *domain;
551 if (!PyArg_ParseTuple(args, "z", &domain))
552 return 0;
553 domain = textdomain(domain);
554 if (!domain) {
555 PyErr_SetFromErrno(PyExc_OSError);
556 return NULL;
558 return str2uni(domain);
561 PyDoc_STRVAR(bindtextdomain__doc__,
562 "bindtextdomain(domain, dir) -> string\n"
563 "Bind the C library's domain to dir.");
565 static PyObject*
566 PyIntl_bindtextdomain(PyObject* self,PyObject*args)
568 char *domain, *dirname;
569 if (!PyArg_ParseTuple(args, "sz", &domain, &dirname))
570 return 0;
571 if (!strlen(domain)) {
572 PyErr_SetString(Error, "domain must be a non-empty string");
573 return 0;
575 dirname = bindtextdomain(domain, dirname);
576 if (!dirname) {
577 PyErr_SetFromErrno(PyExc_OSError);
578 return NULL;
580 return str2uni(dirname);
583 #ifdef HAVE_BIND_TEXTDOMAIN_CODESET
584 PyDoc_STRVAR(bind_textdomain_codeset__doc__,
585 "bind_textdomain_codeset(domain, codeset) -> string\n"
586 "Bind the C library's domain to codeset.");
588 static PyObject*
589 PyIntl_bind_textdomain_codeset(PyObject* self,PyObject*args)
591 char *domain,*codeset;
592 if (!PyArg_ParseTuple(args, "sz", &domain, &codeset))
593 return NULL;
594 codeset = bind_textdomain_codeset(domain, codeset);
595 if (codeset)
596 return str2uni(codeset);
597 Py_RETURN_NONE;
599 #endif
601 #endif
603 static struct PyMethodDef PyLocale_Methods[] = {
604 {"setlocale", (PyCFunction) PyLocale_setlocale,
605 METH_VARARGS, setlocale__doc__},
606 {"localeconv", (PyCFunction) PyLocale_localeconv,
607 METH_NOARGS, localeconv__doc__},
608 #ifdef HAVE_WCSCOLL
609 {"strcoll", (PyCFunction) PyLocale_strcoll,
610 METH_VARARGS, strcoll__doc__},
611 #endif
612 #ifdef HAVE_WCSXFRM
613 {"strxfrm", (PyCFunction) PyLocale_strxfrm,
614 METH_VARARGS, strxfrm__doc__},
615 #endif
616 #if defined(MS_WINDOWS)
617 {"_getdefaultlocale", (PyCFunction) PyLocale_getdefaultlocale, METH_NOARGS},
618 #endif
619 #ifdef HAVE_LANGINFO_H
620 {"nl_langinfo", (PyCFunction) PyLocale_nl_langinfo,
621 METH_VARARGS, nl_langinfo__doc__},
622 #endif
623 #ifdef HAVE_LIBINTL_H
624 {"gettext",(PyCFunction)PyIntl_gettext,METH_VARARGS,
625 gettext__doc__},
626 {"dgettext",(PyCFunction)PyIntl_dgettext,METH_VARARGS,
627 dgettext__doc__},
628 {"dcgettext",(PyCFunction)PyIntl_dcgettext,METH_VARARGS,
629 dcgettext__doc__},
630 {"textdomain",(PyCFunction)PyIntl_textdomain,METH_VARARGS,
631 textdomain__doc__},
632 {"bindtextdomain",(PyCFunction)PyIntl_bindtextdomain,METH_VARARGS,
633 bindtextdomain__doc__},
634 #ifdef HAVE_BIND_TEXTDOMAIN_CODESET
635 {"bind_textdomain_codeset",(PyCFunction)PyIntl_bind_textdomain_codeset,
636 METH_VARARGS, bind_textdomain_codeset__doc__},
637 #endif
638 #endif
639 {NULL, NULL}
643 static struct PyModuleDef _localemodule = {
644 PyModuleDef_HEAD_INIT,
645 "_locale",
646 locale__doc__,
648 PyLocale_Methods,
649 NULL,
650 NULL,
651 NULL,
652 NULL
655 PyMODINIT_FUNC
656 PyInit__locale(void)
658 PyObject *m, *d, *x;
659 #ifdef HAVE_LANGINFO_H
660 int i;
661 #endif
663 m = PyModule_Create(&_localemodule);
664 if (m == NULL)
665 return NULL;
667 d = PyModule_GetDict(m);
669 x = PyLong_FromLong(LC_CTYPE);
670 PyDict_SetItemString(d, "LC_CTYPE", x);
671 Py_XDECREF(x);
673 x = PyLong_FromLong(LC_TIME);
674 PyDict_SetItemString(d, "LC_TIME", x);
675 Py_XDECREF(x);
677 x = PyLong_FromLong(LC_COLLATE);
678 PyDict_SetItemString(d, "LC_COLLATE", x);
679 Py_XDECREF(x);
681 x = PyLong_FromLong(LC_MONETARY);
682 PyDict_SetItemString(d, "LC_MONETARY", x);
683 Py_XDECREF(x);
685 #ifdef LC_MESSAGES
686 x = PyLong_FromLong(LC_MESSAGES);
687 PyDict_SetItemString(d, "LC_MESSAGES", x);
688 Py_XDECREF(x);
689 #endif /* LC_MESSAGES */
691 x = PyLong_FromLong(LC_NUMERIC);
692 PyDict_SetItemString(d, "LC_NUMERIC", x);
693 Py_XDECREF(x);
695 x = PyLong_FromLong(LC_ALL);
696 PyDict_SetItemString(d, "LC_ALL", x);
697 Py_XDECREF(x);
699 x = PyLong_FromLong(CHAR_MAX);
700 PyDict_SetItemString(d, "CHAR_MAX", x);
701 Py_XDECREF(x);
703 Error = PyErr_NewException("locale.Error", NULL, NULL);
704 PyDict_SetItemString(d, "Error", Error);
706 #ifdef HAVE_LANGINFO_H
707 for (i = 0; langinfo_constants[i].name; i++) {
708 PyModule_AddIntConstant(m, langinfo_constants[i].name,
709 langinfo_constants[i].value);
711 #endif
712 return m;
716 Local variables:
717 c-basic-offset: 4
718 indent-tabs-mode: nil
719 End: