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 ******************************************************************/
23 #ifdef HAVE_LANGINFO_H
35 #if defined(__APPLE__)
36 #include <CoreFoundation/CoreFoundation.h>
39 #if defined(MS_WINDOWS)
40 #define WIN32_LEAN_AND_MEAN
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 */
50 str2uni(const char* s
)
52 #ifdef HAVE_BROKEN_MBSTOWCS
53 size_t needed
= strlen(s
);
55 size_t needed
= mbstowcs(NULL
, s
, 0);
61 if (needed
== (size_t)-1) {
62 PyErr_SetString(PyExc_ValueError
, "Cannot convert byte to string");
65 if (needed
*sizeof(wchar_t) < sizeof(smallbuf
))
68 dest
= PyMem_Malloc((needed
+1)*sizeof(wchar_t));
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);
77 assert(res1
== needed
);
79 res2
= PyUnicode_FromWideChar(dest
, res1
);
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 */
92 copy_grouping(char* s
)
95 PyObject
*result
, *val
= NULL
;
98 /* empty string: no grouping at all */
101 for (i
= 0; s
[i
] != '\0' && s
[i
] != CHAR_MAX
; i
++)
104 result
= PyList_New(i
+1);
111 val
= PyLong_FromLong(s
[i
]);
114 if (PyList_SetItem(result
, i
, val
)) {
119 } while (s
[i
] != '\0' && s
[i
] != CHAR_MAX
);
130 PyLocale_setlocale(PyObject
* self
, PyObject
* args
)
133 char *locale
= NULL
, *result
;
134 PyObject
*result_object
;
136 if (!PyArg_ParseTuple(args
, "i|z:setlocale", &category
, &locale
))
141 result
= setlocale(category
, locale
);
143 /* operation failed, no setting was changed */
144 PyErr_SetString(Error
, "unsupported locale setting");
147 result_object
= str2uni(result
);
152 result
= setlocale(category
, NULL
);
154 PyErr_SetString(Error
, "locale query failed");
157 result_object
= str2uni(result
);
159 return result_object
;
162 PyDoc_STRVAR(localeconv__doc__
,
163 "() -> dict. Returns numeric and monetary locale-specific parameters.");
166 PyLocale_localeconv(PyObject
* self
)
172 result
= PyDict_New();
176 /* if LC_NUMERIC is different in the C library, use saved value */
179 /* hopefully, the localeconv result survives the C library calls
182 #define RESULT_STRING(s)\
184 if (!x) goto failed;\
185 PyDict_SetItemString(result, #s, x);\
188 #define RESULT_INT(i)\
189 x = PyLong_FromLong(l->i);\
190 if (!x) goto failed;\
191 PyDict_SetItemString(result, #i, x);\
194 /* Numeric information */
195 RESULT_STRING(decimal_point
);
196 RESULT_STRING(thousands_sep
);
197 x
= copy_grouping(l
->grouping
);
200 PyDict_SetItemString(result
, "grouping", 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
);
211 PyDict_SetItemString(result
, "mon_grouping", 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
);
231 #if defined(HAVE_WCSCOLL)
232 PyDoc_STRVAR(strcoll__doc__
,
233 "string,string -> int. Compares two strings according to the locale.");
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
))
244 /* Convert the unicode strings to wchar[]. */
245 len1
= PyUnicode_GET_SIZE(os1
) + 1;
246 ws1
= PyMem_MALLOC(len1
* sizeof(wchar_t));
251 if (PyUnicode_AsWideChar((PyUnicodeObject
*)os1
, ws1
, len1
) == -1)
254 len2
= PyUnicode_GET_SIZE(os2
) + 1;
255 ws2
= PyMem_MALLOC(len2
* sizeof(wchar_t));
260 if (PyUnicode_AsWideChar((PyUnicodeObject
*)os2
, ws2
, len2
) == -1)
263 /* Collate the strings. */
264 result
= PyLong_FromLong(wcscoll(ws1
, ws2
));
266 /* Deallocate everything. */
267 if (ws1
) PyMem_FREE(ws1
);
268 if (ws2
) PyMem_FREE(ws2
);
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.");
280 PyLocale_strxfrm(PyObject
* self
, PyObject
* args
)
284 wchar_t *s
, *buf
= NULL
;
286 PyObject
*result
= NULL
;
289 if (!PyArg_ParseTuple(args
, "u#:strxfrm", &s0
, &n0
))
292 #ifdef HAVE_USABLE_WCHAR_T
295 s
= PyMem_Malloc((n0
+1)*sizeof(wchar_t));
297 return PyErr_NoMemory();
298 for (i
=0; i
<=n0
; i
++)
302 /* assume no change in size, first */
304 buf
= PyMem_Malloc(n1
*sizeof(wchar_t));
309 n2
= wcsxfrm(buf
, s
, n1
);
311 /* more space needed */
312 buf
= PyMem_Realloc(buf
, (n2
+1)*sizeof(wchar_t));
317 n2
= wcsxfrm(buf
, s
, n2
+1);
319 result
= PyUnicode_FromWideChar(buf
, n2
);
321 if (buf
) PyMem_Free(buf
);
322 #ifdef HAVE_USABLE_WCHAR_T
329 #if defined(MS_WINDOWS)
331 PyLocale_getdefaultlocale(PyObject
* self
)
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
);
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) */
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) */
362 return Py_BuildValue("Os", Py_None
, encoding
);
366 #ifdef HAVE_LANGINFO_H
367 #define LANGINFO(X) {#X, X}
368 static struct langinfo_constant
{
371 } langinfo_constants
[] =
373 /* These constants should exist on any langinfo implementation */
417 /* The following are not available with glibc 2.0 */
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
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
440 Solution: ifdef-test them all. */
445 LANGINFO(T_FMT_AMPM
),
454 LANGINFO(ERA_D_T_FMT
),
460 LANGINFO(ALT_DIGITS
),
469 /* This is not available in all glibc versions that have CODESET. */
475 PyDoc_STRVAR(nl_langinfo__doc__
,
476 "nl_langinfo(key) -> string\n"
477 "Return the value for the locale information associated with key.");
480 PyLocale_nl_langinfo(PyObject
* self
, PyObject
* args
)
483 if (!PyArg_ParseTuple(args
, "i:nl_langinfo", &item
))
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");
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.");
508 PyIntl_gettext(PyObject
* self
, PyObject
*args
)
511 if (!PyArg_ParseTuple(args
, "s", &in
))
513 return str2uni(gettext(in
));
516 PyDoc_STRVAR(dgettext__doc__
,
517 "dgettext(domain, msg) -> string\n"
518 "Return translation of msg in domain.");
521 PyIntl_dgettext(PyObject
* self
, PyObject
*args
)
524 if (!PyArg_ParseTuple(args
, "zs", &domain
, &in
))
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.");
534 PyIntl_dcgettext(PyObject
*self
, PyObject
*args
)
536 char *domain
, *msgid
;
538 if (!PyArg_ParseTuple(args
, "zsi", &domain
, &msgid
, &category
))
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.");
548 PyIntl_textdomain(PyObject
* self
, PyObject
* args
)
551 if (!PyArg_ParseTuple(args
, "z", &domain
))
553 domain
= textdomain(domain
);
555 PyErr_SetFromErrno(PyExc_OSError
);
558 return str2uni(domain
);
561 PyDoc_STRVAR(bindtextdomain__doc__
,
562 "bindtextdomain(domain, dir) -> string\n"
563 "Bind the C library's domain to dir.");
566 PyIntl_bindtextdomain(PyObject
* self
,PyObject
*args
)
568 char *domain
, *dirname
;
569 if (!PyArg_ParseTuple(args
, "sz", &domain
, &dirname
))
571 if (!strlen(domain
)) {
572 PyErr_SetString(Error
, "domain must be a non-empty string");
575 dirname
= bindtextdomain(domain
, dirname
);
577 PyErr_SetFromErrno(PyExc_OSError
);
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.");
589 PyIntl_bind_textdomain_codeset(PyObject
* self
,PyObject
*args
)
591 char *domain
,*codeset
;
592 if (!PyArg_ParseTuple(args
, "sz", &domain
, &codeset
))
594 codeset
= bind_textdomain_codeset(domain
, codeset
);
596 return str2uni(codeset
);
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__
},
609 {"strcoll", (PyCFunction
) PyLocale_strcoll
,
610 METH_VARARGS
, strcoll__doc__
},
613 {"strxfrm", (PyCFunction
) PyLocale_strxfrm
,
614 METH_VARARGS
, strxfrm__doc__
},
616 #if defined(MS_WINDOWS)
617 {"_getdefaultlocale", (PyCFunction
) PyLocale_getdefaultlocale
, METH_NOARGS
},
619 #ifdef HAVE_LANGINFO_H
620 {"nl_langinfo", (PyCFunction
) PyLocale_nl_langinfo
,
621 METH_VARARGS
, nl_langinfo__doc__
},
623 #ifdef HAVE_LIBINTL_H
624 {"gettext",(PyCFunction
)PyIntl_gettext
,METH_VARARGS
,
626 {"dgettext",(PyCFunction
)PyIntl_dgettext
,METH_VARARGS
,
628 {"dcgettext",(PyCFunction
)PyIntl_dcgettext
,METH_VARARGS
,
630 {"textdomain",(PyCFunction
)PyIntl_textdomain
,METH_VARARGS
,
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__
},
643 static struct PyModuleDef _localemodule
= {
644 PyModuleDef_HEAD_INIT
,
659 #ifdef HAVE_LANGINFO_H
663 m
= PyModule_Create(&_localemodule
);
667 d
= PyModule_GetDict(m
);
669 x
= PyLong_FromLong(LC_CTYPE
);
670 PyDict_SetItemString(d
, "LC_CTYPE", x
);
673 x
= PyLong_FromLong(LC_TIME
);
674 PyDict_SetItemString(d
, "LC_TIME", x
);
677 x
= PyLong_FromLong(LC_COLLATE
);
678 PyDict_SetItemString(d
, "LC_COLLATE", x
);
681 x
= PyLong_FromLong(LC_MONETARY
);
682 PyDict_SetItemString(d
, "LC_MONETARY", x
);
686 x
= PyLong_FromLong(LC_MESSAGES
);
687 PyDict_SetItemString(d
, "LC_MESSAGES", x
);
689 #endif /* LC_MESSAGES */
691 x
= PyLong_FromLong(LC_NUMERIC
);
692 PyDict_SetItemString(d
, "LC_NUMERIC", x
);
695 x
= PyLong_FromLong(LC_ALL
);
696 PyDict_SetItemString(d
, "LC_ALL", x
);
699 x
= PyLong_FromLong(CHAR_MAX
);
700 PyDict_SetItemString(d
, "CHAR_MAX", 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
);
718 indent-tabs-mode: nil