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);
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
#if defined(__APPLE__)
368
** Find out what the current script is.
369
** Donated by Fredrik Lundh.
371
static char *mac_getscript(void)
373
CFStringEncoding enc = CFStringGetSystemEncoding();
374
static CFStringRef name = NULL;
375
/* Return the code name for the encodings for which we have codecs. */
377
case kCFStringEncodingMacRoman: return "mac-roman";
378
case kCFStringEncodingMacGreek: return "mac-greek";
379
case kCFStringEncodingMacCyrillic: return "mac-cyrillic";
380
case kCFStringEncodingMacTurkish: return "mac-turkish";
381
case kCFStringEncodingMacIcelandic: return "mac-icelandic";
382
/* XXX which one is mac-latin2? */
385
/* This leaks an object. */
386
name = CFStringConvertEncodingToIANACharSetName(enc);
388
return (char *)CFStringGetCStringPtr(name, 0);
392
PyLocale_getdefaultlocale(PyObject* self)
394
return Py_BuildValue("Os", Py_None, mac_getscript());
398
#ifdef HAVE_LANGINFO_H
399
#define LANGINFO(X) {#X, X}
400
static struct langinfo_constant{
403
} langinfo_constants[] =
405
/* These constants should exist on any langinfo implementation */
449
/* The following are not available with glibc 2.0 */
452
/* YESSTR and NOSTR are deprecated in glibc, since they are
453
a special case of message translation, which should be rather
454
done using gettext. So we don't expose it to Python in the
468
/* The following constants are available only with XPG4, but...
469
AIX 3.2. only has CODESET.
470
OpenBSD doesn't have CODESET but has T_FMT_AMPM, and doesn't have
472
Solution: ifdef-test them all. */
477
LANGINFO(T_FMT_AMPM),
486
LANGINFO(ERA_D_T_FMT),
492
LANGINFO(ALT_DIGITS),
501
/* This is not available in all glibc versions that have CODESET. */
507
PyDoc_STRVAR(nl_langinfo__doc__,
508
"nl_langinfo(key) -> string\n"
509
"Return the value for the locale information associated with key.");
512
PyLocale_nl_langinfo(PyObject* self, PyObject* args)
515
if (!PyArg_ParseTuple(args, "i:nl_langinfo", &item))
517
/* Check whether this is a supported constant. GNU libc sometimes
518
returns numeric values in the char* return value, which would
519
crash PyUnicode_FromString. */
520
for (i = 0; langinfo_constants[i].name; i++)
521
if (langinfo_constants[i].value == item) {
522
/* Check NULL as a workaround for GNU libc's returning NULL
523
instead of an empty string for nl_langinfo(ERA). */
524
const char *result = nl_langinfo(item);
525
result = result != NULL ? result : "";
526
return str2uni(result);
528
PyErr_SetString(PyExc_ValueError, "unsupported langinfo constant");
531
#endif /* HAVE_LANGINFO_H */
533
#ifdef HAVE_LIBINTL_H
535
PyDoc_STRVAR(gettext__doc__,
536
"gettext(msg) -> string\n"
537
"Return translation of msg.");
540
PyIntl_gettext(PyObject* self, PyObject *args)
543
if (!PyArg_ParseTuple(args, "s", &in))
545
return str2uni(gettext(in));
548
PyDoc_STRVAR(dgettext__doc__,
549
"dgettext(domain, msg) -> string\n"
550
"Return translation of msg in domain.");
553
PyIntl_dgettext(PyObject* self, PyObject *args)
556
if (!PyArg_ParseTuple(args, "zs", &domain, &in))
558
return str2uni(dgettext(domain, in));
561
PyDoc_STRVAR(dcgettext__doc__,
562
"dcgettext(domain, msg, category) -> string\n"
563
"Return translation of msg in domain and category.");
566
PyIntl_dcgettext(PyObject *self, PyObject *args)
568
char *domain, *msgid;
570
if (!PyArg_ParseTuple(args, "zsi", &domain, &msgid, &category))
572
return str2uni(dcgettext(domain,msgid,category));
575
PyDoc_STRVAR(textdomain__doc__,
576
"textdomain(domain) -> string\n"
577
"Set the C library's textdmain to domain, returning the new domain.");
580
PyIntl_textdomain(PyObject* self, PyObject* args)
583
if (!PyArg_ParseTuple(args, "z", &domain))
585
domain = textdomain(domain);
587
PyErr_SetFromErrno(PyExc_OSError);
590
return str2uni(domain);
593
PyDoc_STRVAR(bindtextdomain__doc__,
594
"bindtextdomain(domain, dir) -> string\n"
595
"Bind the C library's domain to dir.");
598
PyIntl_bindtextdomain(PyObject* self,PyObject*args)
600
char *domain, *dirname;
601
if (!PyArg_ParseTuple(args, "sz", &domain, &dirname))
603
if (!strlen(domain)) {
604
PyErr_SetString(Error, "domain must be a non-empty string");
607
dirname = bindtextdomain(domain, dirname);
609
PyErr_SetFromErrno(PyExc_OSError);
612
return str2uni(dirname);
615
#ifdef HAVE_BIND_TEXTDOMAIN_CODESET
616
PyDoc_STRVAR(bind_textdomain_codeset__doc__,
617
"bind_textdomain_codeset(domain, codeset) -> string\n"
618
"Bind the C library's domain to codeset.");
621
PyIntl_bind_textdomain_codeset(PyObject* self,PyObject*args)
623
char *domain,*codeset;
624
if (!PyArg_ParseTuple(args, "sz", &domain, &codeset))
626
codeset = bind_textdomain_codeset(domain, codeset);
628
return str2uni(codeset);
635
static struct PyMethodDef PyLocale_Methods[] = {
636
{"setlocale", (PyCFunction) PyLocale_setlocale,
637
METH_VARARGS, setlocale__doc__},
638
{"localeconv", (PyCFunction) PyLocale_localeconv,
639
METH_NOARGS, localeconv__doc__},
641
{"strcoll", (PyCFunction) PyLocale_strcoll,
642
METH_VARARGS, strcoll__doc__},
645
{"strxfrm", (PyCFunction) PyLocale_strxfrm,
646
METH_VARARGS, strxfrm__doc__},
648
#if defined(MS_WINDOWS) || defined(__APPLE__)
649
{"_getdefaultlocale", (PyCFunction) PyLocale_getdefaultlocale, METH_NOARGS},
651
#ifdef HAVE_LANGINFO_H
652
{"nl_langinfo", (PyCFunction) PyLocale_nl_langinfo,
653
METH_VARARGS, nl_langinfo__doc__},
655
#ifdef HAVE_LIBINTL_H
656
{"gettext",(PyCFunction)PyIntl_gettext,METH_VARARGS,
658
{"dgettext",(PyCFunction)PyIntl_dgettext,METH_VARARGS,
660
{"dcgettext",(PyCFunction)PyIntl_dcgettext,METH_VARARGS,
662
{"textdomain",(PyCFunction)PyIntl_textdomain,METH_VARARGS,
664
{"bindtextdomain",(PyCFunction)PyIntl_bindtextdomain,METH_VARARGS,
665
bindtextdomain__doc__},
666
#ifdef HAVE_BIND_TEXTDOMAIN_CODESET
667
{"bind_textdomain_codeset",(PyCFunction)PyIntl_bind_textdomain_codeset,
668
METH_VARARGS, bind_textdomain_codeset__doc__},
675
static struct PyModuleDef _localemodule = {
676
PyModuleDef_HEAD_INIT,
691
#ifdef HAVE_LANGINFO_H
695
m = PyModule_Create(&_localemodule);
699
d = PyModule_GetDict(m);
701
x = PyLong_FromLong(LC_CTYPE);
702
PyDict_SetItemString(d, "LC_CTYPE", x);
705
x = PyLong_FromLong(LC_TIME);
706
PyDict_SetItemString(d, "LC_TIME", x);
709
x = PyLong_FromLong(LC_COLLATE);
710
PyDict_SetItemString(d, "LC_COLLATE", x);
713
x = PyLong_FromLong(LC_MONETARY);
714
PyDict_SetItemString(d, "LC_MONETARY", x);
718
x = PyLong_FromLong(LC_MESSAGES);
719
PyDict_SetItemString(d, "LC_MESSAGES", x);
721
#endif /* LC_MESSAGES */
723
x = PyLong_FromLong(LC_NUMERIC);
724
PyDict_SetItemString(d, "LC_NUMERIC", x);
727
x = PyLong_FromLong(LC_ALL);
728
PyDict_SetItemString(d, "LC_ALL", x);
731
x = PyLong_FromLong(CHAR_MAX);
732
PyDict_SetItemString(d, "CHAR_MAX", x);
735
Error = PyErr_NewException("locale.Error", NULL, NULL);
736
PyDict_SetItemString(d, "Error", Error);
738
#ifdef HAVE_LANGINFO_H
739
for (i = 0; langinfo_constants[i].name; i++) {
740
PyModule_AddIntConstant(m, langinfo_constants[i].name,
741
langinfo_constants[i].value);
750
indent-tabs-mode: nil