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 ******************************************************************/
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
45 char *strdup(const char *);
48 PyDoc_STRVAR(locale__doc__
, "Support for POSIX locales.");
50 static PyObject
*Error
;
52 /* support functions for formatting floating point numbers */
54 PyDoc_STRVAR(setlocale__doc__
,
55 "(integer,string=None) -> string. Activates/queries locale processing.");
57 /* the grouping is terminated by either 0 or CHAR_MAX */
59 copy_grouping(char* s
)
62 PyObject
*result
, *val
= NULL
;
65 /* empty string: no grouping at all */
68 for (i
= 0; s
[i
] != '\0' && s
[i
] != CHAR_MAX
; i
++)
71 result
= PyList_New(i
+1);
78 val
= PyInt_FromLong(s
[i
]);
81 if (PyList_SetItem(result
, i
, val
)) {
86 } while (s
[i
] != '\0' && s
[i
] != CHAR_MAX
);
99 PyObject
*mods
, *strop
, *string
, *ulo
;
100 unsigned char ul
[256];
103 /* find the string and strop modules */
104 mods
= PyImport_GetModuleDict();
107 string
= PyDict_GetItemString(mods
, "string");
109 string
= PyModule_GetDict(string
);
110 strop
=PyDict_GetItemString(mods
, "strop");
112 strop
= PyModule_GetDict(strop
);
113 if (!string
&& !strop
)
116 /* create uppercase map string */
118 for (c
= 0; c
< 256; c
++) {
122 ulo
= PyString_FromStringAndSize((const char *)ul
, n
);
126 PyDict_SetItemString(string
, "uppercase", ulo
);
128 PyDict_SetItemString(strop
, "uppercase", ulo
);
131 /* create lowercase string */
133 for (c
= 0; c
< 256; c
++) {
137 ulo
= PyString_FromStringAndSize((const char *)ul
, n
);
141 PyDict_SetItemString(string
, "lowercase", ulo
);
143 PyDict_SetItemString(strop
, "lowercase", ulo
);
146 /* create letters string */
148 for (c
= 0; c
< 256; c
++) {
152 ulo
= PyString_FromStringAndSize((const char *)ul
, n
);
156 PyDict_SetItemString(string
, "letters", ulo
);
161 PyLocale_setlocale(PyObject
* self
, PyObject
* args
)
164 char *locale
= NULL
, *result
;
165 PyObject
*result_object
;
167 if (!PyArg_ParseTuple(args
, "i|z:setlocale", &category
, &locale
))
172 result
= setlocale(category
, locale
);
174 /* operation failed, no setting was changed */
175 PyErr_SetString(Error
, "unsupported locale setting");
178 result_object
= PyString_FromString(result
);
181 /* record changes to LC_CTYPE */
182 if (category
== LC_CTYPE
|| category
== LC_ALL
)
184 /* things that got wrong up to here are ignored */
188 result
= setlocale(category
, NULL
);
190 PyErr_SetString(Error
, "locale query failed");
193 result_object
= PyString_FromString(result
);
195 return result_object
;
198 PyDoc_STRVAR(localeconv__doc__
,
199 "() -> dict. Returns numeric and monetary locale-specific parameters.");
202 PyLocale_localeconv(PyObject
* self
)
208 result
= PyDict_New();
212 /* if LC_NUMERIC is different in the C library, use saved value */
215 /* hopefully, the localeconv result survives the C library calls
218 #define RESULT_STRING(s)\
219 x = PyString_FromString(l->s);\
220 if (!x) goto failed;\
221 PyDict_SetItemString(result, #s, x);\
224 #define RESULT_INT(i)\
225 x = PyInt_FromLong(l->i);\
226 if (!x) goto failed;\
227 PyDict_SetItemString(result, #i, x);\
230 /* Numeric information */
231 RESULT_STRING(decimal_point
);
232 RESULT_STRING(thousands_sep
);
233 x
= copy_grouping(l
->grouping
);
236 PyDict_SetItemString(result
, "grouping", x
);
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
);
247 PyDict_SetItemString(result
, "mon_grouping", x
);
249 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
);
267 PyDoc_STRVAR(strcoll__doc__
,
268 "string,string -> int. Compares two strings according to the locale.");
271 PyLocale_strcoll(PyObject
* self
, PyObject
* args
)
273 #if !defined(HAVE_WCSCOLL) || !defined(Py_USING_UNICODE)
276 if (!PyArg_ParseTuple(args
, "ss:strcoll", &s1
, &s2
))
278 return PyInt_FromLong(strcoll(s1
, s2
));
280 PyObject
*os1
, *os2
, *result
= NULL
;
281 wchar_t *ws1
= NULL
, *ws2
= NULL
;
282 int rel1
= 0, rel2
= 0, len1
, len2
;
284 if (!PyArg_UnpackTuple(args
, "strcoll", 2, 2, &os1
, &os2
))
286 /* If both arguments are byte strings, use strcoll. */
287 if (PyString_Check(os1
) && PyString_Check(os2
))
288 return PyInt_FromLong(strcoll(PyString_AS_STRING(os1
),
289 PyString_AS_STRING(os2
)));
290 /* 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");
294 /* Convert the non-unicode argument to unicode. */
295 if (!PyUnicode_Check(os1
)) {
296 os1
= PyUnicode_FromObject(os1
);
301 if (!PyUnicode_Check(os2
)) {
302 os2
= PyUnicode_FromObject(os2
);
311 /* Convert the unicode strings to wchar[]. */
312 len1
= PyUnicode_GET_SIZE(os1
) + 1;
313 ws1
= PyMem_MALLOC(len1
* sizeof(wchar_t));
318 if (PyUnicode_AsWideChar((PyUnicodeObject
*)os1
, ws1
, len1
) == -1)
321 len2
= PyUnicode_GET_SIZE(os2
) + 1;
322 ws2
= PyMem_MALLOC(len2
* sizeof(wchar_t));
327 if (PyUnicode_AsWideChar((PyUnicodeObject
*)os2
, ws2
, len2
) == -1)
330 /* Collate the strings. */
331 result
= PyInt_FromLong(wcscoll(ws1
, ws2
));
333 /* Deallocate everything. */
334 if (ws1
) PyMem_FREE(ws1
);
335 if (ws2
) PyMem_FREE(ws2
);
347 PyDoc_STRVAR(strxfrm__doc__
,
348 "string -> string. Returns a string that behaves for cmp locale-aware.");
351 PyLocale_strxfrm(PyObject
* self
, PyObject
* args
)
357 if (!PyArg_ParseTuple(args
, "s:strxfrm", &s
))
360 /* assume no change in size, first */
362 buf
= PyMem_Malloc(n1
);
364 return PyErr_NoMemory();
365 n2
= strxfrm(buf
, s
, n1
) + 1;
367 /* more space needed */
368 buf
= PyMem_Realloc(buf
, n2
);
370 return PyErr_NoMemory();
373 result
= PyString_FromString(buf
);
378 #if defined(MS_WINDOWS)
380 PyLocale_getdefaultlocale(PyObject
* self
)
385 PyOS_snprintf(encoding
, sizeof(encoding
), "cp%d", GetACP());
387 if (GetLocaleInfo(LOCALE_USER_DEFAULT
,
388 LOCALE_SISO639LANGNAME
,
389 locale
, sizeof(locale
))) {
390 Py_ssize_t i
= strlen(locale
);
392 if (GetLocaleInfo(LOCALE_USER_DEFAULT
,
393 LOCALE_SISO3166CTRYNAME
,
394 locale
+i
, (int)(sizeof(locale
)-i
)))
395 return Py_BuildValue("ss", locale
, encoding
);
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) */
404 if (GetLocaleInfo(LOCALE_USER_DEFAULT
, LOCALE_IDEFAULTLANGUAGE
,
405 locale
+2, sizeof(locale
)-2)) {
406 return Py_BuildValue("ss", locale
, encoding
);
409 /* cannot determine the language code (very unlikely) */
411 return Py_BuildValue("Os", Py_None
, encoding
);
415 #if defined(__APPLE__)
417 ** Find out what the current script is.
418 ** Donated by Fredrik Lundh.
420 static char *mac_getscript(void)
422 CFStringEncoding enc
= CFStringGetSystemEncoding();
423 static CFStringRef name
= NULL
;
424 /* Return the code name for the encodings for which we have codecs. */
426 case kCFStringEncodingMacRoman
: return "mac-roman";
427 case kCFStringEncodingMacGreek
: return "mac-greek";
428 case kCFStringEncodingMacCyrillic
: return "mac-cyrillic";
429 case kCFStringEncodingMacTurkish
: return "mac-turkish";
430 case kCFStringEncodingMacIcelandic
: return "mac-icelandic";
431 /* XXX which one is mac-latin2? */
434 /* This leaks an object. */
435 name
= CFStringConvertEncodingToIANACharSetName(enc
);
437 return (char *)CFStringGetCStringPtr(name
, 0);
441 PyLocale_getdefaultlocale(PyObject
* self
)
443 return Py_BuildValue("Os", Py_None
, mac_getscript());
447 #ifdef HAVE_LANGINFO_H
448 #define LANGINFO(X) {#X, X}
449 static struct langinfo_constant
{
452 } langinfo_constants
[] =
454 /* These constants should exist on any langinfo implementation */
498 /* The following are not available with glibc 2.0 */
501 /* YESSTR and NOSTR are deprecated in glibc, since they are
502 a special case of message translation, which should be rather
503 done using gettext. So we don't expose it to Python in the
517 /* The following constants are available only with XPG4, but...
518 AIX 3.2. only has CODESET.
519 OpenBSD doesn't have CODESET but has T_FMT_AMPM, and doesn't have
521 Solution: ifdef-test them all. */
526 LANGINFO(T_FMT_AMPM
),
535 LANGINFO(ERA_D_T_FMT
),
541 LANGINFO(ALT_DIGITS
),
550 /* This is not available in all glibc versions that have CODESET. */
556 PyDoc_STRVAR(nl_langinfo__doc__
,
557 "nl_langinfo(key) -> string\n"
558 "Return the value for the locale information associated with key.");
561 PyLocale_nl_langinfo(PyObject
* self
, PyObject
* args
)
564 if (!PyArg_ParseTuple(args
, "i:nl_langinfo", &item
))
566 /* Check whether this is a supported constant. GNU libc sometimes
567 returns numeric values in the char* return value, which would
568 crash PyString_FromString. */
569 for (i
= 0; langinfo_constants
[i
].name
; i
++)
570 if (langinfo_constants
[i
].value
== item
) {
571 /* Check NULL as a workaround for GNU libc's returning NULL
572 instead of an empty string for nl_langinfo(ERA). */
573 const char *result
= nl_langinfo(item
);
574 return PyString_FromString(result
!= NULL
? result
: "");
576 PyErr_SetString(PyExc_ValueError
, "unsupported langinfo constant");
579 #endif /* HAVE_LANGINFO_H */
581 #ifdef HAVE_LIBINTL_H
583 PyDoc_STRVAR(gettext__doc__
,
584 "gettext(msg) -> string\n"
585 "Return translation of msg.");
588 PyIntl_gettext(PyObject
* self
, PyObject
*args
)
591 if (!PyArg_ParseTuple(args
, "s", &in
))
593 return PyString_FromString(gettext(in
));
596 PyDoc_STRVAR(dgettext__doc__
,
597 "dgettext(domain, msg) -> string\n"
598 "Return translation of msg in domain.");
601 PyIntl_dgettext(PyObject
* self
, PyObject
*args
)
604 if (!PyArg_ParseTuple(args
, "zs", &domain
, &in
))
606 return PyString_FromString(dgettext(domain
, in
));
609 PyDoc_STRVAR(dcgettext__doc__
,
610 "dcgettext(domain, msg, category) -> string\n"
611 "Return translation of msg in domain and category.");
614 PyIntl_dcgettext(PyObject
*self
, PyObject
*args
)
616 char *domain
, *msgid
;
618 if (!PyArg_ParseTuple(args
, "zsi", &domain
, &msgid
, &category
))
620 return PyString_FromString(dcgettext(domain
,msgid
,category
));
623 PyDoc_STRVAR(textdomain__doc__
,
624 "textdomain(domain) -> string\n"
625 "Set the C library's textdmain to domain, returning the new domain.");
628 PyIntl_textdomain(PyObject
* self
, PyObject
* args
)
631 if (!PyArg_ParseTuple(args
, "z", &domain
))
633 domain
= textdomain(domain
);
635 PyErr_SetFromErrno(PyExc_OSError
);
638 return PyString_FromString(domain
);
641 PyDoc_STRVAR(bindtextdomain__doc__
,
642 "bindtextdomain(domain, dir) -> string\n"
643 "Bind the C library's domain to dir.");
646 PyIntl_bindtextdomain(PyObject
* self
,PyObject
*args
)
648 char *domain
, *dirname
;
649 if (!PyArg_ParseTuple(args
, "sz", &domain
, &dirname
))
651 if (!strlen(domain
)) {
652 PyErr_SetString(Error
, "domain must be a non-empty string");
655 dirname
= bindtextdomain(domain
, dirname
);
657 PyErr_SetFromErrno(PyExc_OSError
);
660 return PyString_FromString(dirname
);
663 #ifdef HAVE_BIND_TEXTDOMAIN_CODESET
664 PyDoc_STRVAR(bind_textdomain_codeset__doc__
,
665 "bind_textdomain_codeset(domain, codeset) -> string\n"
666 "Bind the C library's domain to codeset.");
669 PyIntl_bind_textdomain_codeset(PyObject
* self
,PyObject
*args
)
671 char *domain
,*codeset
;
672 if (!PyArg_ParseTuple(args
, "sz", &domain
, &codeset
))
674 codeset
= bind_textdomain_codeset(domain
, codeset
);
676 return PyString_FromString(codeset
);
683 static struct PyMethodDef PyLocale_Methods
[] = {
684 {"setlocale", (PyCFunction
) PyLocale_setlocale
,
685 METH_VARARGS
, setlocale__doc__
},
686 {"localeconv", (PyCFunction
) PyLocale_localeconv
,
687 METH_NOARGS
, localeconv__doc__
},
688 {"strcoll", (PyCFunction
) PyLocale_strcoll
,
689 METH_VARARGS
, strcoll__doc__
},
690 {"strxfrm", (PyCFunction
) PyLocale_strxfrm
,
691 METH_VARARGS
, strxfrm__doc__
},
692 #if defined(MS_WINDOWS) || defined(__APPLE__)
693 {"_getdefaultlocale", (PyCFunction
) PyLocale_getdefaultlocale
, METH_NOARGS
},
695 #ifdef HAVE_LANGINFO_H
696 {"nl_langinfo", (PyCFunction
) PyLocale_nl_langinfo
,
697 METH_VARARGS
, nl_langinfo__doc__
},
699 #ifdef HAVE_LIBINTL_H
700 {"gettext",(PyCFunction
)PyIntl_gettext
,METH_VARARGS
,
702 {"dgettext",(PyCFunction
)PyIntl_dgettext
,METH_VARARGS
,
704 {"dcgettext",(PyCFunction
)PyIntl_dcgettext
,METH_VARARGS
,
706 {"textdomain",(PyCFunction
)PyIntl_textdomain
,METH_VARARGS
,
708 {"bindtextdomain",(PyCFunction
)PyIntl_bindtextdomain
,METH_VARARGS
,
709 bindtextdomain__doc__
},
710 #ifdef HAVE_BIND_TEXTDOMAIN_CODESET
711 {"bind_textdomain_codeset",(PyCFunction
)PyIntl_bind_textdomain_codeset
,
712 METH_VARARGS
, bind_textdomain_codeset__doc__
},
722 #ifdef HAVE_LANGINFO_H
726 m
= Py_InitModule("_locale", PyLocale_Methods
);
730 d
= PyModule_GetDict(m
);
732 x
= PyInt_FromLong(LC_CTYPE
);
733 PyDict_SetItemString(d
, "LC_CTYPE", x
);
736 x
= PyInt_FromLong(LC_TIME
);
737 PyDict_SetItemString(d
, "LC_TIME", x
);
740 x
= PyInt_FromLong(LC_COLLATE
);
741 PyDict_SetItemString(d
, "LC_COLLATE", x
);
744 x
= PyInt_FromLong(LC_MONETARY
);
745 PyDict_SetItemString(d
, "LC_MONETARY", x
);
749 x
= PyInt_FromLong(LC_MESSAGES
);
750 PyDict_SetItemString(d
, "LC_MESSAGES", x
);
752 #endif /* LC_MESSAGES */
754 x
= PyInt_FromLong(LC_NUMERIC
);
755 PyDict_SetItemString(d
, "LC_NUMERIC", x
);
758 x
= PyInt_FromLong(LC_ALL
);
759 PyDict_SetItemString(d
, "LC_ALL", x
);
762 x
= PyInt_FromLong(CHAR_MAX
);
763 PyDict_SetItemString(d
, "CHAR_MAX", x
);
766 Error
= PyErr_NewException("locale.Error", NULL
, NULL
);
767 PyDict_SetItemString(d
, "Error", Error
);
769 x
= PyString_FromString(locale__doc__
);
770 PyDict_SetItemString(d
, "__doc__", x
);
773 #ifdef HAVE_LANGINFO_H
774 for (i
= 0; langinfo_constants
[i
].name
; i
++) {
775 PyModule_AddIntConstant(m
, langinfo_constants
[i
].name
,
776 langinfo_constants
[i
].value
);
784 indent-tabs-mode: nil