1 /***********************************************************
2 Copyright (C) 1997, 2002, 2003 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 ******************************************************************/
20 #ifdef HAVE_LANGINFO_H
32 #if defined(MS_WINDOWS)
33 #define WIN32_LEAN_AND_MEAN
37 #if defined(__APPLE__) || defined(__MWERKS__)
42 char *strdup(const char *);
45 PyDoc_STRVAR(locale__doc__
, "Support for POSIX locales.");
47 static PyObject
*Error
;
49 /* support functions for formatting floating point numbers */
51 PyDoc_STRVAR(setlocale__doc__
,
52 "(integer,string=None) -> string. Activates/queries locale processing.");
54 /* to record the LC_NUMERIC settings */
55 static PyObject
* grouping
= NULL
;
56 static PyObject
* thousands_sep
= NULL
;
57 static PyObject
* decimal_point
= NULL
;
58 /* if non-null, indicates that LC_NUMERIC is different from "C" */
59 static char* saved_numeric
= NULL
;
61 /* the grouping is terminated by either 0 or CHAR_MAX */
63 copy_grouping(char* s
)
66 PyObject
*result
, *val
= NULL
;
69 /* empty string: no grouping at all */
72 for (i
= 0; s
[i
] != '\0' && s
[i
] != CHAR_MAX
; i
++)
75 result
= PyList_New(i
+1);
82 val
= PyInt_FromLong(s
[i
]);
85 if (PyList_SetItem(result
, i
, val
)) {
90 } while (s
[i
] != '\0' && s
[i
] != CHAR_MAX
);
103 PyObject
*mods
, *strop
, *string
, *ulo
;
104 unsigned char ul
[256];
107 /* find the string and strop modules */
108 mods
= PyImport_GetModuleDict();
111 string
= PyDict_GetItemString(mods
, "string");
113 string
= PyModule_GetDict(string
);
114 strop
=PyDict_GetItemString(mods
, "strop");
116 strop
= PyModule_GetDict(strop
);
117 if (!string
&& !strop
)
120 /* create uppercase map string */
122 for (c
= 0; c
< 256; c
++) {
126 ulo
= PyString_FromStringAndSize((const char *)ul
, n
);
130 PyDict_SetItemString(string
, "uppercase", ulo
);
132 PyDict_SetItemString(strop
, "uppercase", ulo
);
135 /* create lowercase string */
137 for (c
= 0; c
< 256; c
++) {
141 ulo
= PyString_FromStringAndSize((const char *)ul
, n
);
145 PyDict_SetItemString(string
, "lowercase", ulo
);
147 PyDict_SetItemString(strop
, "lowercase", ulo
);
150 /* create letters string */
152 for (c
= 0; c
< 256; c
++) {
156 ulo
= PyString_FromStringAndSize((const char *)ul
, n
);
160 PyDict_SetItemString(string
, "letters", ulo
);
165 PyLocale_setlocale(PyObject
* self
, PyObject
* args
)
168 char *locale
= NULL
, *result
;
169 PyObject
*result_object
;
172 if (!PyArg_ParseTuple(args
, "i|z:setlocale", &category
, &locale
))
177 result
= setlocale(category
, locale
);
179 /* operation failed, no setting was changed */
180 PyErr_SetString(Error
, "unsupported locale setting");
183 result_object
= PyString_FromString(result
);
186 /* record changes to LC_NUMERIC */
187 if (category
== LC_NUMERIC
|| category
== LC_ALL
) {
188 if (strcmp(locale
, "C") == 0 || strcmp(locale
, "POSIX") == 0) {
189 /* user just asked for default numeric locale */
192 saved_numeric
= NULL
;
194 /* remember values */
196 Py_XDECREF(grouping
);
197 grouping
= copy_grouping(lc
->grouping
);
198 Py_XDECREF(thousands_sep
);
199 thousands_sep
= PyString_FromString(lc
->thousands_sep
);
200 Py_XDECREF(decimal_point
);
201 decimal_point
= PyString_FromString(lc
->decimal_point
);
204 saved_numeric
= strdup(locale
);
206 setlocale(LC_NUMERIC
, "C");
209 /* record changes to LC_CTYPE */
210 if (category
== LC_CTYPE
|| category
== LC_ALL
)
212 /* things that got wrong up to here are ignored */
216 /* restore LC_NUMERIC first, if appropriate */
218 setlocale(LC_NUMERIC
, saved_numeric
);
219 result
= setlocale(category
, NULL
);
221 PyErr_SetString(Error
, "locale query failed");
224 result_object
= PyString_FromString(result
);
225 /* restore back to "C" */
227 setlocale(LC_NUMERIC
, "C");
229 return result_object
;
232 PyDoc_STRVAR(localeconv__doc__
,
233 "() -> dict. Returns numeric and monetary locale-specific parameters.");
236 PyLocale_localeconv(PyObject
* self
)
242 result
= PyDict_New();
246 /* if LC_NUMERIC is different in the C library, use saved value */
249 /* hopefully, the localeconv result survives the C library calls
252 #define RESULT_STRING(s)\
253 x = PyString_FromString(l->s);\
254 if (!x) goto failed;\
255 PyDict_SetItemString(result, #s, x);\
258 #define RESULT_INT(i)\
259 x = PyInt_FromLong(l->i);\
260 if (!x) goto failed;\
261 PyDict_SetItemString(result, #i, x);\
264 /* Numeric information */
266 /* cannot use localeconv results */
267 PyDict_SetItemString(result
, "decimal_point", decimal_point
);
268 PyDict_SetItemString(result
, "grouping", grouping
);
269 PyDict_SetItemString(result
, "thousands_sep", thousands_sep
);
271 RESULT_STRING(decimal_point
);
272 RESULT_STRING(thousands_sep
);
273 x
= copy_grouping(l
->grouping
);
276 PyDict_SetItemString(result
, "grouping", x
);
280 /* Monetary information */
281 RESULT_STRING(int_curr_symbol
);
282 RESULT_STRING(currency_symbol
);
283 RESULT_STRING(mon_decimal_point
);
284 RESULT_STRING(mon_thousands_sep
);
285 x
= copy_grouping(l
->mon_grouping
);
288 PyDict_SetItemString(result
, "mon_grouping", x
);
290 RESULT_STRING(positive_sign
);
291 RESULT_STRING(negative_sign
);
292 RESULT_INT(int_frac_digits
);
293 RESULT_INT(frac_digits
);
294 RESULT_INT(p_cs_precedes
);
295 RESULT_INT(p_sep_by_space
);
296 RESULT_INT(n_cs_precedes
);
297 RESULT_INT(n_sep_by_space
);
298 RESULT_INT(p_sign_posn
);
299 RESULT_INT(n_sign_posn
);
308 PyDoc_STRVAR(strcoll__doc__
,
309 "string,string -> int. Compares two strings according to the locale.");
312 PyLocale_strcoll(PyObject
* self
, PyObject
* args
)
314 #if !defined(HAVE_WCSCOLL) || !defined(Py_USING_UNICODE)
317 if (!PyArg_ParseTuple(args
, "ss:strcoll", &s1
, &s2
))
319 return PyInt_FromLong(strcoll(s1
, s2
));
321 PyObject
*os1
, *os2
, *result
= NULL
;
322 wchar_t *ws1
= NULL
, *ws2
= NULL
;
323 int rel1
= 0, rel2
= 0, len1
, len2
;
325 if (!PyArg_ParseTuple(args
, "OO:strcoll", &os1
, &os2
))
327 /* If both arguments are byte strings, use strcoll. */
328 if (PyString_Check(os1
) && PyString_Check(os2
))
329 return PyInt_FromLong(strcoll(PyString_AS_STRING(os1
),
330 PyString_AS_STRING(os2
)));
331 /* If neither argument is unicode, it's an error. */
332 if (!PyUnicode_Check(os1
) && !PyUnicode_Check(os2
)) {
333 PyErr_SetString(PyExc_ValueError
, "strcoll arguments must be strings");
335 /* Convert the non-unicode argument to unicode. */
336 if (!PyUnicode_Check(os1
)) {
337 os1
= PyUnicode_FromObject(os1
);
342 if (!PyUnicode_Check(os2
)) {
343 os2
= PyUnicode_FromObject(os2
);
350 /* Convert the unicode strings to wchar[]. */
351 len1
= PyUnicode_GET_SIZE(os1
) + 1;
352 len2
= PyUnicode_GET_SIZE(os2
) + 1;
353 ws1
= PyMem_MALLOC(len1
* sizeof(wchar_t));
358 if (PyUnicode_AsWideChar((PyUnicodeObject
*)os1
, ws1
, len1
) == -1)
360 ws2
= PyMem_MALLOC(len2
* sizeof(wchar_t));
365 if (PyUnicode_AsWideChar((PyUnicodeObject
*)os2
, ws2
, len2
) == -1)
367 /* Collate the strings. */
368 result
= PyInt_FromLong(wcscoll(ws1
, ws2
));
370 /* Deallocate everything. */
371 if (ws1
) PyMem_FREE(ws1
);
372 if (ws2
) PyMem_FREE(ws2
);
384 PyDoc_STRVAR(strxfrm__doc__
,
385 "string -> string. Returns a string that behaves for cmp locale-aware.");
388 PyLocale_strxfrm(PyObject
* self
, PyObject
* args
)
394 if (!PyArg_ParseTuple(args
, "s:strxfrm", &s
))
397 /* assume no change in size, first */
399 buf
= PyMem_Malloc(n1
);
401 return PyErr_NoMemory();
402 n2
= strxfrm(buf
, s
, n1
);
404 /* more space needed */
405 buf
= PyMem_Realloc(buf
, n2
);
407 return PyErr_NoMemory();
410 result
= PyString_FromString(buf
);
415 #if defined(MS_WINDOWS)
417 PyLocale_getdefaultlocale(PyObject
* self
)
422 PyOS_snprintf(encoding
, sizeof(encoding
), "cp%d", GetACP());
424 if (GetLocaleInfo(LOCALE_USER_DEFAULT
,
425 LOCALE_SISO639LANGNAME
,
426 locale
, sizeof(locale
))) {
427 int i
= strlen(locale
);
429 if (GetLocaleInfo(LOCALE_USER_DEFAULT
,
430 LOCALE_SISO3166CTRYNAME
,
431 locale
+i
, sizeof(locale
)-i
))
432 return Py_BuildValue("ss", locale
, encoding
);
435 /* If we end up here, this windows version didn't know about
436 ISO639/ISO3166 names (it's probably Windows 95). Return the
437 Windows language identifier instead (a hexadecimal number) */
441 if (GetLocaleInfo(LOCALE_USER_DEFAULT
, LOCALE_IDEFAULTLANGUAGE
,
442 locale
+2, sizeof(locale
)-2)) {
443 return Py_BuildValue("ss", locale
, encoding
);
446 /* cannot determine the language code (very unlikely) */
448 return Py_BuildValue("Os", Py_None
, encoding
);
452 #if defined(__APPLE__)
454 PyLocale_getdefaultlocale(PyObject
* self
)
456 return Py_BuildValue("Os", Py_None
, PyMac_getscript());
460 #ifdef HAVE_LANGINFO_H
461 #define LANGINFO(X) {#X, X}
462 struct langinfo_constant
{
465 } langinfo_constants
[] =
467 /* These constants should exist on any langinfo implementation */
511 /* The following are not available with glibc 2.0 */
514 /* YESSTR and NOSTR are deprecated in glibc, since they are
515 a special case of message translation, which should be rather
516 done using gettext. So we don't expose it to Python in the
530 /* The following constants are available only with XPG4, but...
531 AIX 3.2. only has CODESET.
532 OpenBSD doesn't have CODESET but has T_FMT_AMPM, and doesn't have
534 Solution: ifdef-test them all. */
539 LANGINFO(T_FMT_AMPM
),
548 LANGINFO(ERA_D_T_FMT
),
554 LANGINFO(ALT_DIGITS
),
563 /* This is not available in all glibc versions that have CODESET. */
569 PyDoc_STRVAR(nl_langinfo__doc__
,
570 "nl_langinfo(key) -> string\n"
571 "Return the value for the locale information associated with key.");
574 PyLocale_nl_langinfo(PyObject
* self
, PyObject
* args
)
577 if (!PyArg_ParseTuple(args
, "i:nl_langinfo", &item
))
579 /* Check whether this is a supported constant. GNU libc sometimes
580 returns numeric values in the char* return value, which would
581 crash PyString_FromString. */
584 if(item
== RADIXCHAR
) {
585 Py_INCREF(decimal_point
);
586 return decimal_point
;
588 if(item
== THOUSEP
) {
589 Py_INCREF(thousands_sep
);
590 return thousands_sep
;
594 for (i
= 0; langinfo_constants
[i
].name
; i
++)
595 if (langinfo_constants
[i
].value
== item
) {
596 /* Check NULL as a workaround for GNU libc's returning NULL
597 instead of an empty string for nl_langinfo(ERA). */
598 const char *result
= nl_langinfo(item
);
599 return PyString_FromString(result
!= NULL
? result
: "");
601 PyErr_SetString(PyExc_ValueError
, "unsupported langinfo constant");
604 #endif /* HAVE_LANGINFO_H */
606 #ifdef HAVE_LIBINTL_H
608 PyDoc_STRVAR(gettext__doc__
,
609 "gettext(msg) -> string\n"
610 "Return translation of msg.");
613 PyIntl_gettext(PyObject
* self
, PyObject
*args
)
616 if (!PyArg_ParseTuple(args
, "z", &in
))
618 return PyString_FromString(gettext(in
));
621 PyDoc_STRVAR(dgettext__doc__
,
622 "dgettext(domain, msg) -> string\n"
623 "Return translation of msg in domain.");
626 PyIntl_dgettext(PyObject
* self
, PyObject
*args
)
629 if (!PyArg_ParseTuple(args
, "zz", &domain
, &in
))
631 return PyString_FromString(dgettext(domain
, in
));
634 PyDoc_STRVAR(dcgettext__doc__
,
635 "dcgettext(domain, msg, category) -> string\n"
636 "Return translation of msg in domain and category.");
639 PyIntl_dcgettext(PyObject
*self
, PyObject
*args
)
641 char *domain
, *msgid
;
643 if (!PyArg_ParseTuple(args
, "zzi", &domain
, &msgid
, &category
))
645 return PyString_FromString(dcgettext(domain
,msgid
,category
));
648 PyDoc_STRVAR(textdomain__doc__
,
649 "textdomain(domain) -> string\n"
650 "Set the C library's textdmain to domain, returning the new domain.");
653 PyIntl_textdomain(PyObject
* self
, PyObject
* args
)
656 if (!PyArg_ParseTuple(args
, "z", &domain
))
658 domain
= textdomain(domain
);
660 PyErr_SetFromErrno(PyExc_OSError
);
663 return PyString_FromString(domain
);
666 PyDoc_STRVAR(bindtextdomain__doc__
,
667 "bindtextdomain(domain, dir) -> string\n"
668 "Bind the C library's domain to dir.");
671 PyIntl_bindtextdomain(PyObject
* self
,PyObject
*args
)
673 char *domain
,*dirname
;
674 if (!PyArg_ParseTuple(args
, "zz", &domain
, &dirname
))
676 dirname
= bindtextdomain(domain
, dirname
);
678 PyErr_SetFromErrno(PyExc_OSError
);
681 return PyString_FromString(dirname
);
686 static struct PyMethodDef PyLocale_Methods
[] = {
687 {"setlocale", (PyCFunction
) PyLocale_setlocale
,
688 METH_VARARGS
, setlocale__doc__
},
689 {"localeconv", (PyCFunction
) PyLocale_localeconv
,
690 METH_NOARGS
, localeconv__doc__
},
691 {"strcoll", (PyCFunction
) PyLocale_strcoll
,
692 METH_VARARGS
, strcoll__doc__
},
693 {"strxfrm", (PyCFunction
) PyLocale_strxfrm
,
694 METH_VARARGS
, strxfrm__doc__
},
695 #if defined(MS_WINDOWS) || defined(__APPLE__)
696 {"_getdefaultlocale", (PyCFunction
) PyLocale_getdefaultlocale
, METH_NOARGS
},
698 #ifdef HAVE_LANGINFO_H
699 {"nl_langinfo", (PyCFunction
) PyLocale_nl_langinfo
,
700 METH_VARARGS
, nl_langinfo__doc__
},
702 #ifdef HAVE_LIBINTL_H
703 {"gettext",(PyCFunction
)PyIntl_gettext
,METH_VARARGS
,
705 {"dgettext",(PyCFunction
)PyIntl_dgettext
,METH_VARARGS
,
707 {"dcgettext",(PyCFunction
)PyIntl_dcgettext
,METH_VARARGS
,
709 {"textdomain",(PyCFunction
)PyIntl_textdomain
,METH_VARARGS
,
711 {"bindtextdomain",(PyCFunction
)PyIntl_bindtextdomain
,METH_VARARGS
,
712 bindtextdomain__doc__
},
721 #ifdef HAVE_LANGINFO_H
725 m
= Py_InitModule("_locale", PyLocale_Methods
);
727 d
= PyModule_GetDict(m
);
729 x
= PyInt_FromLong(LC_CTYPE
);
730 PyDict_SetItemString(d
, "LC_CTYPE", x
);
733 x
= PyInt_FromLong(LC_TIME
);
734 PyDict_SetItemString(d
, "LC_TIME", x
);
737 x
= PyInt_FromLong(LC_COLLATE
);
738 PyDict_SetItemString(d
, "LC_COLLATE", x
);
741 x
= PyInt_FromLong(LC_MONETARY
);
742 PyDict_SetItemString(d
, "LC_MONETARY", x
);
746 x
= PyInt_FromLong(LC_MESSAGES
);
747 PyDict_SetItemString(d
, "LC_MESSAGES", x
);
749 #endif /* LC_MESSAGES */
751 x
= PyInt_FromLong(LC_NUMERIC
);
752 PyDict_SetItemString(d
, "LC_NUMERIC", x
);
755 x
= PyInt_FromLong(LC_ALL
);
756 PyDict_SetItemString(d
, "LC_ALL", x
);
759 x
= PyInt_FromLong(CHAR_MAX
);
760 PyDict_SetItemString(d
, "CHAR_MAX", x
);
763 Error
= PyErr_NewException("locale.Error", NULL
, NULL
);
764 PyDict_SetItemString(d
, "Error", Error
);
766 x
= PyString_FromString(locale__doc__
);
767 PyDict_SetItemString(d
, "__doc__", x
);
770 #ifdef HAVE_LANGINFO_H
771 for (i
= 0; langinfo_constants
[i
].name
; i
++) {
772 PyModule_AddIntConstant(m
, langinfo_constants
[i
].name
,
773 langinfo_constants
[i
].value
);
781 indent-tabs-mode: nil