blob: b448be17fe223ddd59ac2c597239894a38898b59 [file] [log] [blame]
Guido van Rossum220ecc81997-11-18 21:03:39 +00001/***********************************************************
Martin v. Löwis25f90d52003-09-03 04:50:13 +00002Copyright (C) 1997, 2002, 2003 Martin von Loewis
Guido van Rossum220ecc81997-11-18 21:03:39 +00003
4Permission to use, copy, modify, and distribute this software and its
5documentation for any purpose and without fee is hereby granted,
6provided that the above copyright notice appear in all copies.
7
8This software comes with no warranty. Use at your own risk.
Fredrik Lundh8f017a02000-07-08 19:57:37 +00009
Guido van Rossum220ecc81997-11-18 21:03:39 +000010******************************************************************/
11
Fred Drake68933b92000-08-10 21:41:08 +000012#include "Python.h"
13
Guido van Rossum220ecc81997-11-18 21:03:39 +000014#include <stdio.h>
Guido van Rossum220ecc81997-11-18 21:03:39 +000015#include <locale.h>
16#include <string.h>
Guido van Rossum5cd70f41998-06-19 04:33:30 +000017#include <ctype.h>
Fredrik Lundh8f017a02000-07-08 19:57:37 +000018
Thomas Wouters0e3f5912006-08-11 14:57:12 +000019#ifdef HAVE_ERRNO_H
Thomas Wouters477c8d52006-05-27 19:21:47 +000020#include <errno.h>
21#endif
22
Martin v. Löwis9b75dca2001-08-10 13:58:50 +000023#ifdef HAVE_LANGINFO_H
24#include <langinfo.h>
25#endif
26
Martin v. Löwis2e64c342002-03-27 18:49:02 +000027#ifdef HAVE_LIBINTL_H
28#include <libintl.h>
29#endif
30
Martin v. Löwis9c36c292002-12-21 18:34:06 +000031#ifdef HAVE_WCHAR_H
32#include <wchar.h>
33#endif
34
Jack Jansen7107c1a2003-11-20 13:31:00 +000035#if defined(__APPLE__)
Jack Jansen59f072a2004-07-15 13:31:39 +000036#include <CoreFoundation/CoreFoundation.h>
Jack Jansen7107c1a2003-11-20 13:31:00 +000037#endif
38
Martin v. Löwis6238d2b2002-06-30 15:26:10 +000039#if defined(MS_WINDOWS)
Tim Peters7a1f9172002-07-14 22:14:19 +000040#define WIN32_LEAN_AND_MEAN
Fredrik Lundh8f017a02000-07-08 19:57:37 +000041#include <windows.h>
Guido van Rossum239a2181998-04-28 16:08:19 +000042#endif
Guido van Rossum220ecc81997-11-18 21:03:39 +000043
Guido van Rossum1ca8bb32001-03-02 06:28:17 +000044#ifdef RISCOS
45char *strdup(const char *);
46#endif
47
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000048PyDoc_STRVAR(locale__doc__, "Support for POSIX locales.");
Guido van Rossum220ecc81997-11-18 21:03:39 +000049
50static PyObject *Error;
51
52/* support functions for formatting floating point numbers */
53
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000054PyDoc_STRVAR(setlocale__doc__,
55"(integer,string=None) -> string. Activates/queries locale processing.");
Guido van Rossum220ecc81997-11-18 21:03:39 +000056
Guido van Rossum220ecc81997-11-18 21:03:39 +000057/* the grouping is terminated by either 0 or CHAR_MAX */
58static PyObject*
Fredrik Lundh8f017a02000-07-08 19:57:37 +000059copy_grouping(char* s)
Guido van Rossum220ecc81997-11-18 21:03:39 +000060{
Fredrik Lundh8f017a02000-07-08 19:57:37 +000061 int i;
62 PyObject *result, *val = NULL;
63
64 if (s[0] == '\0')
65 /* empty string: no grouping at all */
66 return PyList_New(0);
67
68 for (i = 0; s[i] != '\0' && s[i] != CHAR_MAX; i++)
69 ; /* nothing */
70
71 result = PyList_New(i+1);
72 if (!result)
73 return NULL;
74
75 i = -1;
76 do {
77 i++;
78 val = PyInt_FromLong(s[i]);
79 if (!val)
80 break;
81 if (PyList_SetItem(result, i, val)) {
82 Py_DECREF(val);
Fredrik Lundh89610a42000-07-08 20:07:24 +000083 val = NULL;
Fredrik Lundh8f017a02000-07-08 19:57:37 +000084 break;
85 }
86 } while (s[i] != '\0' && s[i] != CHAR_MAX);
87
88 if (!val) {
89 Py_DECREF(result);
90 return NULL;
Guido van Rossum220ecc81997-11-18 21:03:39 +000091 }
Fredrik Lundh8f017a02000-07-08 19:57:37 +000092
93 return result;
Guido van Rossum220ecc81997-11-18 21:03:39 +000094}
95
96static void
Fredrik Lundh8f017a02000-07-08 19:57:37 +000097fixup_ulcase(void)
Guido van Rossum220ecc81997-11-18 21:03:39 +000098{
Fredrik Lundh8f017a02000-07-08 19:57:37 +000099 PyObject *mods, *strop, *string, *ulo;
100 unsigned char ul[256];
101 int n, c;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000102
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000103 /* find the string and strop modules */
104 mods = PyImport_GetModuleDict();
105 if (!mods)
106 return;
107 string = PyDict_GetItemString(mods, "string");
108 if (string)
109 string = PyModule_GetDict(string);
110 strop=PyDict_GetItemString(mods, "strop");
111 if (strop)
112 strop = PyModule_GetDict(strop);
113 if (!string && !strop)
114 return;
115
116 /* create uppercase map string */
117 n = 0;
118 for (c = 0; c < 256; c++) {
119 if (isupper(c))
120 ul[n++] = c;
121 }
122 ulo = PyString_FromStringAndSize((const char *)ul, n);
Fredrik Lundh89610a42000-07-08 20:07:24 +0000123 if (!ulo)
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000124 return;
125 if (string)
126 PyDict_SetItemString(string, "uppercase", ulo);
127 if (strop)
128 PyDict_SetItemString(strop, "uppercase", ulo);
129 Py_DECREF(ulo);
130
131 /* create lowercase string */
132 n = 0;
133 for (c = 0; c < 256; c++) {
134 if (islower(c))
135 ul[n++] = c;
136 }
137 ulo = PyString_FromStringAndSize((const char *)ul, n);
138 if (!ulo)
139 return;
140 if (string)
141 PyDict_SetItemString(string, "lowercase", ulo);
142 if (strop)
143 PyDict_SetItemString(strop, "lowercase", ulo);
144 Py_DECREF(ulo);
145
146 /* create letters string */
147 n = 0;
148 for (c = 0; c < 256; c++) {
149 if (isalpha(c))
150 ul[n++] = c;
151 }
152 ulo = PyString_FromStringAndSize((const char *)ul, n);
153 if (!ulo)
154 return;
155 if (string)
156 PyDict_SetItemString(string, "letters", ulo);
157 Py_DECREF(ulo);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000158}
Martin v. Löwis7c82a3e02001-09-05 17:09:48 +0000159
Guido van Rossum220ecc81997-11-18 21:03:39 +0000160static PyObject*
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000161PyLocale_setlocale(PyObject* self, PyObject* args)
Guido van Rossum220ecc81997-11-18 21:03:39 +0000162{
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000163 int category;
164 char *locale = NULL, *result;
165 PyObject *result_object;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000166
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000167 if (!PyArg_ParseTuple(args, "i|z:setlocale", &category, &locale))
Fredrik Lundh89610a42000-07-08 20:07:24 +0000168 return NULL;
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000169
170 if (locale) {
171 /* set locale */
172 result = setlocale(category, locale);
173 if (!result) {
174 /* operation failed, no setting was changed */
Martin v. Löwis25f90d52003-09-03 04:50:13 +0000175 PyErr_SetString(Error, "unsupported locale setting");
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000176 return NULL;
177 }
178 result_object = PyString_FromString(result);
Mark Hammond9a714752003-07-24 14:15:07 +0000179 if (!result_object)
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000180 return NULL;
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000181 /* record changes to LC_CTYPE */
182 if (category == LC_CTYPE || category == LC_ALL)
183 fixup_ulcase();
184 /* things that got wrong up to here are ignored */
185 PyErr_Clear();
186 } else {
187 /* get locale */
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000188 result = setlocale(category, NULL);
189 if (!result) {
190 PyErr_SetString(Error, "locale query failed");
191 return NULL;
192 }
193 result_object = PyString_FromString(result);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000194 }
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000195 return result_object;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000196}
197
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000198PyDoc_STRVAR(localeconv__doc__,
199"() -> dict. Returns numeric and monetary locale-specific parameters.");
Guido van Rossum220ecc81997-11-18 21:03:39 +0000200
201static PyObject*
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000202PyLocale_localeconv(PyObject* self)
Guido van Rossum220ecc81997-11-18 21:03:39 +0000203{
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000204 PyObject* result;
205 struct lconv *l;
206 PyObject *x;
207
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000208 result = PyDict_New();
Fredrik Lundh89610a42000-07-08 20:07:24 +0000209 if (!result)
210 return NULL;
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000211
212 /* if LC_NUMERIC is different in the C library, use saved value */
213 l = localeconv();
214
215 /* hopefully, the localeconv result survives the C library calls
216 involved herein */
217
218#define RESULT_STRING(s)\
219 x = PyString_FromString(l->s);\
220 if (!x) goto failed;\
221 PyDict_SetItemString(result, #s, x);\
222 Py_XDECREF(x)
223
224#define RESULT_INT(i)\
225 x = PyInt_FromLong(l->i);\
226 if (!x) goto failed;\
227 PyDict_SetItemString(result, #i, x);\
228 Py_XDECREF(x)
Guido van Rossum220ecc81997-11-18 21:03:39 +0000229
230 /* Numeric information */
Martin v. Löwis737ea822004-06-08 18:52:54 +0000231 RESULT_STRING(decimal_point);
232 RESULT_STRING(thousands_sep);
233 x = copy_grouping(l->grouping);
234 if (!x)
235 goto failed;
236 PyDict_SetItemString(result, "grouping", x);
237 Py_XDECREF(x);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000238
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);
245 if (!x)
246 goto failed;
247 PyDict_SetItemString(result, "mon_grouping", x);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000248 Py_XDECREF(x);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000249 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);
259 return result;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000260
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000261 failed:
262 Py_XDECREF(result);
263 Py_XDECREF(x);
264 return NULL;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000265}
266
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000267PyDoc_STRVAR(strcoll__doc__,
268"string,string -> int. Compares two strings according to the locale.");
Guido van Rossum220ecc81997-11-18 21:03:39 +0000269
270static PyObject*
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000271PyLocale_strcoll(PyObject* self, PyObject* args)
Guido van Rossum220ecc81997-11-18 21:03:39 +0000272{
Guido van Rossum8d30cc02007-05-03 17:49:24 +0000273#if !defined(HAVE_WCSCOLL)
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000274 char *s1,*s2;
275
276 if (!PyArg_ParseTuple(args, "ss:strcoll", &s1, &s2))
277 return NULL;
278 return PyInt_FromLong(strcoll(s1, s2));
279#else
280 PyObject *os1, *os2, *result = NULL;
281 wchar_t *ws1 = NULL, *ws2 = NULL;
282 int rel1 = 0, rel2 = 0, len1, len2;
283
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000284 if (!PyArg_UnpackTuple(args, "strcoll", 2, 2, &os1, &os2))
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000285 return NULL;
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");
293 }
294 /* Convert the non-unicode argument to unicode. */
295 if (!PyUnicode_Check(os1)) {
296 os1 = PyUnicode_FromObject(os1);
297 if (!os1)
298 return NULL;
299 rel1 = 1;
300 }
301 if (!PyUnicode_Check(os2)) {
302 os2 = PyUnicode_FromObject(os2);
303 if (!os2) {
304 Py_DECREF(os1);
305 return NULL;
306 }
307 rel2 = 1;
308 }
309 /* Convert the unicode strings to wchar[]. */
310 len1 = PyUnicode_GET_SIZE(os1) + 1;
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000311 ws1 = PyMem_MALLOC(len1 * sizeof(wchar_t));
312 if (!ws1) {
313 PyErr_NoMemory();
314 goto done;
315 }
316 if (PyUnicode_AsWideChar((PyUnicodeObject*)os1, ws1, len1) == -1)
317 goto done;
Marc-André Lemburga9cadcd2004-11-22 13:02:31 +0000318 ws1[len1 - 1] = 0;
319 len2 = PyUnicode_GET_SIZE(os2) + 1;
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000320 ws2 = PyMem_MALLOC(len2 * sizeof(wchar_t));
321 if (!ws2) {
322 PyErr_NoMemory();
323 goto done;
324 }
325 if (PyUnicode_AsWideChar((PyUnicodeObject*)os2, ws2, len2) == -1)
326 goto done;
Marc-André Lemburga9cadcd2004-11-22 13:02:31 +0000327 ws2[len2 - 1] = 0;
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000328 /* Collate the strings. */
329 result = PyInt_FromLong(wcscoll(ws1, ws2));
330 done:
331 /* Deallocate everything. */
332 if (ws1) PyMem_FREE(ws1);
333 if (ws2) PyMem_FREE(ws2);
334 if (rel1) {
335 Py_DECREF(os1);
336 }
337 if (rel2) {
338 Py_DECREF(os2);
339 }
340 return result;
341#endif
Guido van Rossum220ecc81997-11-18 21:03:39 +0000342}
343
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000344
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000345PyDoc_STRVAR(strxfrm__doc__,
346"string -> string. Returns a string that behaves for cmp locale-aware.");
Guido van Rossum220ecc81997-11-18 21:03:39 +0000347
348static PyObject*
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000349PyLocale_strxfrm(PyObject* self, PyObject* args)
Guido van Rossum220ecc81997-11-18 21:03:39 +0000350{
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000351 char *s, *buf;
352 size_t n1, n2;
353 PyObject *result;
354
Fredrik Lundh89610a42000-07-08 20:07:24 +0000355 if (!PyArg_ParseTuple(args, "s:strxfrm", &s))
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000356 return NULL;
357
358 /* assume no change in size, first */
359 n1 = strlen(s) + 1;
360 buf = PyMem_Malloc(n1);
361 if (!buf)
362 return PyErr_NoMemory();
Guido van Rossumd8faa362007-04-27 19:54:29 +0000363 n2 = strxfrm(buf, s, n1) + 1;
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000364 if (n2 > n1) {
365 /* more space needed */
366 buf = PyMem_Realloc(buf, n2);
367 if (!buf)
368 return PyErr_NoMemory();
369 strxfrm(buf, s, n2);
370 }
371 result = PyString_FromString(buf);
372 PyMem_Free(buf);
373 return result;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000374}
375
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000376#if defined(MS_WINDOWS)
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000377static PyObject*
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000378PyLocale_getdefaultlocale(PyObject* self)
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000379{
380 char encoding[100];
381 char locale[100];
382
Tim Peters885d4572001-11-28 20:27:42 +0000383 PyOS_snprintf(encoding, sizeof(encoding), "cp%d", GetACP());
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000384
385 if (GetLocaleInfo(LOCALE_USER_DEFAULT,
386 LOCALE_SISO639LANGNAME,
387 locale, sizeof(locale))) {
Martin v. Löwis18e16552006-02-15 17:27:45 +0000388 Py_ssize_t i = strlen(locale);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000389 locale[i++] = '_';
390 if (GetLocaleInfo(LOCALE_USER_DEFAULT,
391 LOCALE_SISO3166CTRYNAME,
Martin v. Löwis18e16552006-02-15 17:27:45 +0000392 locale+i, (int)(sizeof(locale)-i)))
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000393 return Py_BuildValue("ss", locale, encoding);
394 }
395
396 /* If we end up here, this windows version didn't know about
397 ISO639/ISO3166 names (it's probably Windows 95). Return the
398 Windows language identifier instead (a hexadecimal number) */
399
400 locale[0] = '0';
401 locale[1] = 'x';
402 if (GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_IDEFAULTLANGUAGE,
403 locale+2, sizeof(locale)-2)) {
404 return Py_BuildValue("ss", locale, encoding);
405 }
406
407 /* cannot determine the language code (very unlikely) */
408 Py_INCREF(Py_None);
409 return Py_BuildValue("Os", Py_None, encoding);
410}
411#endif
412
Martin v. Löwis52ea7e92002-11-26 09:05:36 +0000413#if defined(__APPLE__)
Jack Jansen59f072a2004-07-15 13:31:39 +0000414/*
415** Find out what the current script is.
Brett Cannon269ab622004-08-27 05:00:22 +0000416** Donated by Fredrik Lundh.
Jack Jansen59f072a2004-07-15 13:31:39 +0000417*/
418static char *mac_getscript(void)
419{
420 CFStringEncoding enc = CFStringGetSystemEncoding();
421 static CFStringRef name = NULL;
422 /* Return the code name for the encodings for which we have codecs. */
423 switch(enc) {
424 case kCFStringEncodingMacRoman: return "mac-roman";
425 case kCFStringEncodingMacGreek: return "mac-greek";
426 case kCFStringEncodingMacCyrillic: return "mac-cyrillic";
427 case kCFStringEncodingMacTurkish: return "mac-turkish";
428 case kCFStringEncodingMacIcelandic: return "mac-icelandic";
429 /* XXX which one is mac-latin2? */
430 }
431 if (!name) {
Brett Cannon5ce25872005-03-01 03:16:34 +0000432 /* This leaks an object. */
Jack Jansen59f072a2004-07-15 13:31:39 +0000433 name = CFStringConvertEncodingToIANACharSetName(enc);
434 }
435 return (char *)CFStringGetCStringPtr(name, 0);
436}
437
Jack Jansen307d7a42000-07-15 22:31:45 +0000438static PyObject*
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000439PyLocale_getdefaultlocale(PyObject* self)
Jack Jansen307d7a42000-07-15 22:31:45 +0000440{
Jack Jansen59f072a2004-07-15 13:31:39 +0000441 return Py_BuildValue("Os", Py_None, mac_getscript());
Jack Jansen307d7a42000-07-15 22:31:45 +0000442}
443#endif
444
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000445#ifdef HAVE_LANGINFO_H
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000446#define LANGINFO(X) {#X, X}
447struct langinfo_constant{
448 char* name;
449 int value;
450} langinfo_constants[] =
451{
452 /* These constants should exist on any langinfo implementation */
453 LANGINFO(DAY_1),
454 LANGINFO(DAY_2),
455 LANGINFO(DAY_3),
456 LANGINFO(DAY_4),
457 LANGINFO(DAY_5),
458 LANGINFO(DAY_6),
459 LANGINFO(DAY_7),
460
461 LANGINFO(ABDAY_1),
462 LANGINFO(ABDAY_2),
463 LANGINFO(ABDAY_3),
464 LANGINFO(ABDAY_4),
465 LANGINFO(ABDAY_5),
466 LANGINFO(ABDAY_6),
467 LANGINFO(ABDAY_7),
468
469 LANGINFO(MON_1),
470 LANGINFO(MON_2),
471 LANGINFO(MON_3),
472 LANGINFO(MON_4),
473 LANGINFO(MON_5),
474 LANGINFO(MON_6),
475 LANGINFO(MON_7),
476 LANGINFO(MON_8),
477 LANGINFO(MON_9),
478 LANGINFO(MON_10),
479 LANGINFO(MON_11),
480 LANGINFO(MON_12),
481
482 LANGINFO(ABMON_1),
483 LANGINFO(ABMON_2),
484 LANGINFO(ABMON_3),
485 LANGINFO(ABMON_4),
486 LANGINFO(ABMON_5),
487 LANGINFO(ABMON_6),
488 LANGINFO(ABMON_7),
489 LANGINFO(ABMON_8),
490 LANGINFO(ABMON_9),
491 LANGINFO(ABMON_10),
492 LANGINFO(ABMON_11),
493 LANGINFO(ABMON_12),
494
495#ifdef RADIXCHAR
496 /* The following are not available with glibc 2.0 */
497 LANGINFO(RADIXCHAR),
498 LANGINFO(THOUSEP),
499 /* YESSTR and NOSTR are deprecated in glibc, since they are
500 a special case of message translation, which should be rather
501 done using gettext. So we don't expose it to Python in the
502 first place.
503 LANGINFO(YESSTR),
504 LANGINFO(NOSTR),
505 */
506 LANGINFO(CRNCYSTR),
507#endif
508
509 LANGINFO(D_T_FMT),
510 LANGINFO(D_FMT),
511 LANGINFO(T_FMT),
512 LANGINFO(AM_STR),
513 LANGINFO(PM_STR),
514
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000515 /* The following constants are available only with XPG4, but...
516 AIX 3.2. only has CODESET.
517 OpenBSD doesn't have CODESET but has T_FMT_AMPM, and doesn't have
518 a few of the others.
519 Solution: ifdef-test them all. */
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000520#ifdef CODESET
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000521 LANGINFO(CODESET),
Martin v. Löwis496f9e42002-03-27 12:15:57 +0000522#endif
523#ifdef T_FMT_AMPM
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000524 LANGINFO(T_FMT_AMPM),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000525#endif
526#ifdef ERA
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000527 LANGINFO(ERA),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000528#endif
529#ifdef ERA_D_FMT
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000530 LANGINFO(ERA_D_FMT),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000531#endif
532#ifdef ERA_D_T_FMT
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000533 LANGINFO(ERA_D_T_FMT),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000534#endif
535#ifdef ERA_T_FMT
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000536 LANGINFO(ERA_T_FMT),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000537#endif
538#ifdef ALT_DIGITS
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000539 LANGINFO(ALT_DIGITS),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000540#endif
541#ifdef YESEXPR
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000542 LANGINFO(YESEXPR),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000543#endif
544#ifdef NOEXPR
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000545 LANGINFO(NOEXPR),
546#endif
547#ifdef _DATE_FMT
548 /* This is not available in all glibc versions that have CODESET. */
549 LANGINFO(_DATE_FMT),
550#endif
551 {0, 0}
552};
553
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000554PyDoc_STRVAR(nl_langinfo__doc__,
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000555"nl_langinfo(key) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000556"Return the value for the locale information associated with key.");
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000557
558static PyObject*
559PyLocale_nl_langinfo(PyObject* self, PyObject* args)
560{
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000561 int item, i;
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000562 if (!PyArg_ParseTuple(args, "i:nl_langinfo", &item))
563 return NULL;
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000564 /* Check whether this is a supported constant. GNU libc sometimes
565 returns numeric values in the char* return value, which would
566 crash PyString_FromString. */
567 for (i = 0; langinfo_constants[i].name; i++)
Hye-Shik Changc3a87b82004-03-21 19:34:30 +0000568 if (langinfo_constants[i].value == item) {
569 /* Check NULL as a workaround for GNU libc's returning NULL
570 instead of an empty string for nl_langinfo(ERA). */
571 const char *result = nl_langinfo(item);
572 return PyString_FromString(result != NULL ? result : "");
573 }
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000574 PyErr_SetString(PyExc_ValueError, "unsupported langinfo constant");
575 return NULL;
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000576}
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000577#endif /* HAVE_LANGINFO_H */
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000578
579#ifdef HAVE_LIBINTL_H
580
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000581PyDoc_STRVAR(gettext__doc__,
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000582"gettext(msg) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000583"Return translation of msg.");
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000584
585static PyObject*
586PyIntl_gettext(PyObject* self, PyObject *args)
587{
588 char *in;
589 if (!PyArg_ParseTuple(args, "z", &in))
590 return 0;
591 return PyString_FromString(gettext(in));
592}
593
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000594PyDoc_STRVAR(dgettext__doc__,
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000595"dgettext(domain, msg) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000596"Return translation of msg in domain.");
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000597
598static PyObject*
599PyIntl_dgettext(PyObject* self, PyObject *args)
600{
601 char *domain, *in;
602 if (!PyArg_ParseTuple(args, "zz", &domain, &in))
603 return 0;
604 return PyString_FromString(dgettext(domain, in));
605}
606
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000607PyDoc_STRVAR(dcgettext__doc__,
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000608"dcgettext(domain, msg, category) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000609"Return translation of msg in domain and category.");
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000610
611static PyObject*
612PyIntl_dcgettext(PyObject *self, PyObject *args)
613{
614 char *domain, *msgid;
615 int category;
616 if (!PyArg_ParseTuple(args, "zzi", &domain, &msgid, &category))
617 return 0;
618 return PyString_FromString(dcgettext(domain,msgid,category));
619}
620
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000621PyDoc_STRVAR(textdomain__doc__,
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000622"textdomain(domain) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000623"Set the C library's textdmain to domain, returning the new domain.");
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000624
625static PyObject*
626PyIntl_textdomain(PyObject* self, PyObject* args)
627{
628 char *domain;
629 if (!PyArg_ParseTuple(args, "z", &domain))
630 return 0;
631 domain = textdomain(domain);
632 if (!domain) {
633 PyErr_SetFromErrno(PyExc_OSError);
634 return NULL;
635 }
636 return PyString_FromString(domain);
637}
638
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000639PyDoc_STRVAR(bindtextdomain__doc__,
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000640"bindtextdomain(domain, dir) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000641"Bind the C library's domain to dir.");
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000642
643static PyObject*
644PyIntl_bindtextdomain(PyObject* self,PyObject*args)
645{
646 char *domain,*dirname;
647 if (!PyArg_ParseTuple(args, "zz", &domain, &dirname))
648 return 0;
649 dirname = bindtextdomain(domain, dirname);
650 if (!dirname) {
651 PyErr_SetFromErrno(PyExc_OSError);
652 return NULL;
653 }
654 return PyString_FromString(dirname);
655}
656
Gustavo Niemeyer7bd33c52004-07-22 18:44:01 +0000657#ifdef HAVE_BIND_TEXTDOMAIN_CODESET
658PyDoc_STRVAR(bind_textdomain_codeset__doc__,
659"bind_textdomain_codeset(domain, codeset) -> string\n"
660"Bind the C library's domain to codeset.");
661
662static PyObject*
663PyIntl_bind_textdomain_codeset(PyObject* self,PyObject*args)
664{
665 char *domain,*codeset;
666 if (!PyArg_ParseTuple(args, "sz", &domain, &codeset))
667 return NULL;
668 codeset = bind_textdomain_codeset(domain, codeset);
669 if (codeset)
670 return PyString_FromString(codeset);
671 Py_RETURN_NONE;
672}
673#endif
674
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000675#endif
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000676
Guido van Rossum220ecc81997-11-18 21:03:39 +0000677static struct PyMethodDef PyLocale_Methods[] = {
Andrew M. Kuchlinge365fb82000-08-03 02:06:16 +0000678 {"setlocale", (PyCFunction) PyLocale_setlocale,
679 METH_VARARGS, setlocale__doc__},
680 {"localeconv", (PyCFunction) PyLocale_localeconv,
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000681 METH_NOARGS, localeconv__doc__},
Andrew M. Kuchlinge365fb82000-08-03 02:06:16 +0000682 {"strcoll", (PyCFunction) PyLocale_strcoll,
683 METH_VARARGS, strcoll__doc__},
684 {"strxfrm", (PyCFunction) PyLocale_strxfrm,
685 METH_VARARGS, strxfrm__doc__},
Martin v. Löwis52ea7e92002-11-26 09:05:36 +0000686#if defined(MS_WINDOWS) || defined(__APPLE__)
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000687 {"_getdefaultlocale", (PyCFunction) PyLocale_getdefaultlocale, METH_NOARGS},
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000688#endif
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000689#ifdef HAVE_LANGINFO_H
690 {"nl_langinfo", (PyCFunction) PyLocale_nl_langinfo,
691 METH_VARARGS, nl_langinfo__doc__},
692#endif
Martin v. Löwisc6a7d7e2002-05-02 12:16:29 +0000693#ifdef HAVE_LIBINTL_H
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000694 {"gettext",(PyCFunction)PyIntl_gettext,METH_VARARGS,
695 gettext__doc__},
696 {"dgettext",(PyCFunction)PyIntl_dgettext,METH_VARARGS,
697 dgettext__doc__},
698 {"dcgettext",(PyCFunction)PyIntl_dcgettext,METH_VARARGS,
699 dcgettext__doc__},
700 {"textdomain",(PyCFunction)PyIntl_textdomain,METH_VARARGS,
701 textdomain__doc__},
702 {"bindtextdomain",(PyCFunction)PyIntl_bindtextdomain,METH_VARARGS,
703 bindtextdomain__doc__},
Gustavo Niemeyer7bd33c52004-07-22 18:44:01 +0000704#ifdef HAVE_BIND_TEXTDOMAIN_CODESET
705 {"bind_textdomain_codeset",(PyCFunction)PyIntl_bind_textdomain_codeset,
706 METH_VARARGS, bind_textdomain_codeset__doc__},
707#endif
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000708#endif
Guido van Rossum220ecc81997-11-18 21:03:39 +0000709 {NULL, NULL}
710};
711
Mark Hammondfe51c6d2002-08-02 02:27:13 +0000712PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000713init_locale(void)
Guido van Rossum220ecc81997-11-18 21:03:39 +0000714{
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000715 PyObject *m, *d, *x;
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000716#ifdef HAVE_LANGINFO_H
717 int i;
718#endif
Guido van Rossum220ecc81997-11-18 21:03:39 +0000719
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000720 m = Py_InitModule("_locale", PyLocale_Methods);
Neal Norwitz1ac754f2006-01-19 06:09:39 +0000721 if (m == NULL)
722 return;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000723
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000724 d = PyModule_GetDict(m);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000725
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000726 x = PyInt_FromLong(LC_CTYPE);
727 PyDict_SetItemString(d, "LC_CTYPE", x);
728 Py_XDECREF(x);
729
730 x = PyInt_FromLong(LC_TIME);
731 PyDict_SetItemString(d, "LC_TIME", x);
732 Py_XDECREF(x);
733
734 x = PyInt_FromLong(LC_COLLATE);
735 PyDict_SetItemString(d, "LC_COLLATE", x);
736 Py_XDECREF(x);
737
738 x = PyInt_FromLong(LC_MONETARY);
739 PyDict_SetItemString(d, "LC_MONETARY", x);
740 Py_XDECREF(x);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000741
Guido van Rossum8d9c2e31997-12-09 19:35:11 +0000742#ifdef LC_MESSAGES
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000743 x = PyInt_FromLong(LC_MESSAGES);
744 PyDict_SetItemString(d, "LC_MESSAGES", x);
745 Py_XDECREF(x);
Guido van Rossum8d9c2e31997-12-09 19:35:11 +0000746#endif /* LC_MESSAGES */
Guido van Rossum220ecc81997-11-18 21:03:39 +0000747
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000748 x = PyInt_FromLong(LC_NUMERIC);
749 PyDict_SetItemString(d, "LC_NUMERIC", x);
750 Py_XDECREF(x);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000751
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000752 x = PyInt_FromLong(LC_ALL);
753 PyDict_SetItemString(d, "LC_ALL", x);
754 Py_XDECREF(x);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000755
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000756 x = PyInt_FromLong(CHAR_MAX);
757 PyDict_SetItemString(d, "CHAR_MAX", x);
758 Py_XDECREF(x);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000759
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000760 Error = PyErr_NewException("locale.Error", NULL, NULL);
761 PyDict_SetItemString(d, "Error", Error);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000762
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000763 x = PyString_FromString(locale__doc__);
764 PyDict_SetItemString(d, "__doc__", x);
765 Py_XDECREF(x);
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000766
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000767#ifdef HAVE_LANGINFO_H
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000768 for (i = 0; langinfo_constants[i].name; i++) {
769 PyModule_AddIntConstant(m, langinfo_constants[i].name,
770 langinfo_constants[i].value);
771 }
Martin v. Löwisf95dd0a2001-08-15 17:14:33 +0000772#endif
Guido van Rossum220ecc81997-11-18 21:03:39 +0000773}
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000774
775/*
776Local variables:
777c-basic-offset: 4
778indent-tabs-mode: nil
779End:
780*/