blob: 6f063fba740a2bf705bdd6d259044cff6a26bc49 [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{
Guido van Rossumebe3e162007-05-17 18:20:34 +000099 PyObject *mods, *string, *ulo;
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000100 unsigned char ul[256];
101 int n, c;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000102
Guido van Rossumebe3e162007-05-17 18:20:34 +0000103 /* find the string module */
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000104 mods = PyImport_GetModuleDict();
105 if (!mods)
106 return;
107 string = PyDict_GetItemString(mods, "string");
108 if (string)
109 string = PyModule_GetDict(string);
Guido van Rossumebe3e162007-05-17 18:20:34 +0000110 if (!string)
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000111 return;
112
113 /* create uppercase map string */
114 n = 0;
115 for (c = 0; c < 256; c++) {
116 if (isupper(c))
117 ul[n++] = c;
118 }
119 ulo = PyString_FromStringAndSize((const char *)ul, n);
Fredrik Lundh89610a42000-07-08 20:07:24 +0000120 if (!ulo)
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000121 return;
122 if (string)
123 PyDict_SetItemString(string, "uppercase", ulo);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000124 Py_DECREF(ulo);
125
126 /* create lowercase string */
127 n = 0;
128 for (c = 0; c < 256; c++) {
129 if (islower(c))
130 ul[n++] = c;
131 }
132 ulo = PyString_FromStringAndSize((const char *)ul, n);
133 if (!ulo)
134 return;
135 if (string)
136 PyDict_SetItemString(string, "lowercase", ulo);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000137 Py_DECREF(ulo);
138
139 /* create letters string */
140 n = 0;
141 for (c = 0; c < 256; c++) {
142 if (isalpha(c))
143 ul[n++] = c;
144 }
145 ulo = PyString_FromStringAndSize((const char *)ul, n);
146 if (!ulo)
147 return;
148 if (string)
149 PyDict_SetItemString(string, "letters", ulo);
150 Py_DECREF(ulo);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000151}
Martin v. Löwis7c82a3e02001-09-05 17:09:48 +0000152
Guido van Rossum220ecc81997-11-18 21:03:39 +0000153static PyObject*
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000154PyLocale_setlocale(PyObject* self, PyObject* args)
Guido van Rossum220ecc81997-11-18 21:03:39 +0000155{
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000156 int category;
157 char *locale = NULL, *result;
158 PyObject *result_object;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000159
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000160 if (!PyArg_ParseTuple(args, "i|z:setlocale", &category, &locale))
Fredrik Lundh89610a42000-07-08 20:07:24 +0000161 return NULL;
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000162
163 if (locale) {
164 /* set locale */
165 result = setlocale(category, locale);
166 if (!result) {
167 /* operation failed, no setting was changed */
Martin v. Löwis25f90d52003-09-03 04:50:13 +0000168 PyErr_SetString(Error, "unsupported locale setting");
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000169 return NULL;
170 }
171 result_object = PyString_FromString(result);
Mark Hammond9a714752003-07-24 14:15:07 +0000172 if (!result_object)
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000173 return NULL;
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000174 /* record changes to LC_CTYPE */
175 if (category == LC_CTYPE || category == LC_ALL)
176 fixup_ulcase();
177 /* things that got wrong up to here are ignored */
178 PyErr_Clear();
179 } else {
180 /* get locale */
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000181 result = setlocale(category, NULL);
182 if (!result) {
183 PyErr_SetString(Error, "locale query failed");
184 return NULL;
185 }
186 result_object = PyString_FromString(result);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000187 }
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000188 return result_object;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000189}
190
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000191PyDoc_STRVAR(localeconv__doc__,
192"() -> dict. Returns numeric and monetary locale-specific parameters.");
Guido van Rossum220ecc81997-11-18 21:03:39 +0000193
194static PyObject*
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000195PyLocale_localeconv(PyObject* self)
Guido van Rossum220ecc81997-11-18 21:03:39 +0000196{
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000197 PyObject* result;
198 struct lconv *l;
199 PyObject *x;
200
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000201 result = PyDict_New();
Fredrik Lundh89610a42000-07-08 20:07:24 +0000202 if (!result)
203 return NULL;
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000204
205 /* if LC_NUMERIC is different in the C library, use saved value */
206 l = localeconv();
207
208 /* hopefully, the localeconv result survives the C library calls
209 involved herein */
210
211#define RESULT_STRING(s)\
212 x = PyString_FromString(l->s);\
213 if (!x) goto failed;\
214 PyDict_SetItemString(result, #s, x);\
215 Py_XDECREF(x)
216
217#define RESULT_INT(i)\
218 x = PyInt_FromLong(l->i);\
219 if (!x) goto failed;\
220 PyDict_SetItemString(result, #i, x);\
221 Py_XDECREF(x)
Guido van Rossum220ecc81997-11-18 21:03:39 +0000222
223 /* Numeric information */
Martin v. Löwis737ea822004-06-08 18:52:54 +0000224 RESULT_STRING(decimal_point);
225 RESULT_STRING(thousands_sep);
226 x = copy_grouping(l->grouping);
227 if (!x)
228 goto failed;
229 PyDict_SetItemString(result, "grouping", x);
230 Py_XDECREF(x);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000231
232 /* Monetary information */
233 RESULT_STRING(int_curr_symbol);
234 RESULT_STRING(currency_symbol);
235 RESULT_STRING(mon_decimal_point);
236 RESULT_STRING(mon_thousands_sep);
237 x = copy_grouping(l->mon_grouping);
238 if (!x)
239 goto failed;
240 PyDict_SetItemString(result, "mon_grouping", x);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000241 Py_XDECREF(x);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000242 RESULT_STRING(positive_sign);
243 RESULT_STRING(negative_sign);
244 RESULT_INT(int_frac_digits);
245 RESULT_INT(frac_digits);
246 RESULT_INT(p_cs_precedes);
247 RESULT_INT(p_sep_by_space);
248 RESULT_INT(n_cs_precedes);
249 RESULT_INT(n_sep_by_space);
250 RESULT_INT(p_sign_posn);
251 RESULT_INT(n_sign_posn);
252 return result;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000253
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000254 failed:
255 Py_XDECREF(result);
256 Py_XDECREF(x);
257 return NULL;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000258}
259
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000260PyDoc_STRVAR(strcoll__doc__,
261"string,string -> int. Compares two strings according to the locale.");
Guido van Rossum220ecc81997-11-18 21:03:39 +0000262
263static PyObject*
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000264PyLocale_strcoll(PyObject* self, PyObject* args)
Guido van Rossum220ecc81997-11-18 21:03:39 +0000265{
Guido van Rossum8d30cc02007-05-03 17:49:24 +0000266#if !defined(HAVE_WCSCOLL)
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000267 char *s1,*s2;
268
269 if (!PyArg_ParseTuple(args, "ss:strcoll", &s1, &s2))
270 return NULL;
271 return PyInt_FromLong(strcoll(s1, s2));
272#else
273 PyObject *os1, *os2, *result = NULL;
274 wchar_t *ws1 = NULL, *ws2 = NULL;
275 int rel1 = 0, rel2 = 0, len1, len2;
276
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000277 if (!PyArg_UnpackTuple(args, "strcoll", 2, 2, &os1, &os2))
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000278 return NULL;
279 /* If both arguments are byte strings, use strcoll. */
280 if (PyString_Check(os1) && PyString_Check(os2))
281 return PyInt_FromLong(strcoll(PyString_AS_STRING(os1),
282 PyString_AS_STRING(os2)));
283 /* If neither argument is unicode, it's an error. */
284 if (!PyUnicode_Check(os1) && !PyUnicode_Check(os2)) {
285 PyErr_SetString(PyExc_ValueError, "strcoll arguments must be strings");
286 }
287 /* Convert the non-unicode argument to unicode. */
288 if (!PyUnicode_Check(os1)) {
289 os1 = PyUnicode_FromObject(os1);
290 if (!os1)
291 return NULL;
292 rel1 = 1;
293 }
294 if (!PyUnicode_Check(os2)) {
295 os2 = PyUnicode_FromObject(os2);
296 if (!os2) {
297 Py_DECREF(os1);
298 return NULL;
299 }
300 rel2 = 1;
301 }
302 /* Convert the unicode strings to wchar[]. */
303 len1 = PyUnicode_GET_SIZE(os1) + 1;
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000304 ws1 = PyMem_MALLOC(len1 * sizeof(wchar_t));
305 if (!ws1) {
306 PyErr_NoMemory();
307 goto done;
308 }
309 if (PyUnicode_AsWideChar((PyUnicodeObject*)os1, ws1, len1) == -1)
310 goto done;
Marc-André Lemburga9cadcd2004-11-22 13:02:31 +0000311 ws1[len1 - 1] = 0;
312 len2 = PyUnicode_GET_SIZE(os2) + 1;
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000313 ws2 = PyMem_MALLOC(len2 * sizeof(wchar_t));
314 if (!ws2) {
315 PyErr_NoMemory();
316 goto done;
317 }
318 if (PyUnicode_AsWideChar((PyUnicodeObject*)os2, ws2, len2) == -1)
319 goto done;
Marc-André Lemburga9cadcd2004-11-22 13:02:31 +0000320 ws2[len2 - 1] = 0;
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000321 /* Collate the strings. */
322 result = PyInt_FromLong(wcscoll(ws1, ws2));
323 done:
324 /* Deallocate everything. */
325 if (ws1) PyMem_FREE(ws1);
326 if (ws2) PyMem_FREE(ws2);
327 if (rel1) {
328 Py_DECREF(os1);
329 }
330 if (rel2) {
331 Py_DECREF(os2);
332 }
333 return result;
334#endif
Guido van Rossum220ecc81997-11-18 21:03:39 +0000335}
336
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000337
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000338PyDoc_STRVAR(strxfrm__doc__,
339"string -> string. Returns a string that behaves for cmp locale-aware.");
Guido van Rossum220ecc81997-11-18 21:03:39 +0000340
341static PyObject*
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000342PyLocale_strxfrm(PyObject* self, PyObject* args)
Guido van Rossum220ecc81997-11-18 21:03:39 +0000343{
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000344 char *s, *buf;
345 size_t n1, n2;
346 PyObject *result;
347
Fredrik Lundh89610a42000-07-08 20:07:24 +0000348 if (!PyArg_ParseTuple(args, "s:strxfrm", &s))
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000349 return NULL;
350
351 /* assume no change in size, first */
352 n1 = strlen(s) + 1;
353 buf = PyMem_Malloc(n1);
354 if (!buf)
355 return PyErr_NoMemory();
Guido van Rossumd8faa362007-04-27 19:54:29 +0000356 n2 = strxfrm(buf, s, n1) + 1;
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000357 if (n2 > n1) {
358 /* more space needed */
359 buf = PyMem_Realloc(buf, n2);
360 if (!buf)
361 return PyErr_NoMemory();
362 strxfrm(buf, s, n2);
363 }
364 result = PyString_FromString(buf);
365 PyMem_Free(buf);
366 return result;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000367}
368
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000369#if defined(MS_WINDOWS)
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000370static PyObject*
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000371PyLocale_getdefaultlocale(PyObject* self)
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000372{
373 char encoding[100];
374 char locale[100];
375
Tim Peters885d4572001-11-28 20:27:42 +0000376 PyOS_snprintf(encoding, sizeof(encoding), "cp%d", GetACP());
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000377
378 if (GetLocaleInfo(LOCALE_USER_DEFAULT,
379 LOCALE_SISO639LANGNAME,
380 locale, sizeof(locale))) {
Martin v. Löwis18e16552006-02-15 17:27:45 +0000381 Py_ssize_t i = strlen(locale);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000382 locale[i++] = '_';
383 if (GetLocaleInfo(LOCALE_USER_DEFAULT,
384 LOCALE_SISO3166CTRYNAME,
Martin v. Löwis18e16552006-02-15 17:27:45 +0000385 locale+i, (int)(sizeof(locale)-i)))
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000386 return Py_BuildValue("ss", locale, encoding);
387 }
388
389 /* If we end up here, this windows version didn't know about
390 ISO639/ISO3166 names (it's probably Windows 95). Return the
391 Windows language identifier instead (a hexadecimal number) */
392
393 locale[0] = '0';
394 locale[1] = 'x';
395 if (GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_IDEFAULTLANGUAGE,
396 locale+2, sizeof(locale)-2)) {
397 return Py_BuildValue("ss", locale, encoding);
398 }
399
400 /* cannot determine the language code (very unlikely) */
401 Py_INCREF(Py_None);
402 return Py_BuildValue("Os", Py_None, encoding);
403}
404#endif
405
Martin v. Löwis52ea7e92002-11-26 09:05:36 +0000406#if defined(__APPLE__)
Jack Jansen59f072a2004-07-15 13:31:39 +0000407/*
408** Find out what the current script is.
Brett Cannon269ab622004-08-27 05:00:22 +0000409** Donated by Fredrik Lundh.
Jack Jansen59f072a2004-07-15 13:31:39 +0000410*/
411static char *mac_getscript(void)
412{
413 CFStringEncoding enc = CFStringGetSystemEncoding();
414 static CFStringRef name = NULL;
415 /* Return the code name for the encodings for which we have codecs. */
416 switch(enc) {
417 case kCFStringEncodingMacRoman: return "mac-roman";
418 case kCFStringEncodingMacGreek: return "mac-greek";
419 case kCFStringEncodingMacCyrillic: return "mac-cyrillic";
420 case kCFStringEncodingMacTurkish: return "mac-turkish";
421 case kCFStringEncodingMacIcelandic: return "mac-icelandic";
422 /* XXX which one is mac-latin2? */
423 }
424 if (!name) {
Brett Cannon5ce25872005-03-01 03:16:34 +0000425 /* This leaks an object. */
Jack Jansen59f072a2004-07-15 13:31:39 +0000426 name = CFStringConvertEncodingToIANACharSetName(enc);
427 }
428 return (char *)CFStringGetCStringPtr(name, 0);
429}
430
Jack Jansen307d7a42000-07-15 22:31:45 +0000431static PyObject*
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000432PyLocale_getdefaultlocale(PyObject* self)
Jack Jansen307d7a42000-07-15 22:31:45 +0000433{
Jack Jansen59f072a2004-07-15 13:31:39 +0000434 return Py_BuildValue("Os", Py_None, mac_getscript());
Jack Jansen307d7a42000-07-15 22:31:45 +0000435}
436#endif
437
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000438#ifdef HAVE_LANGINFO_H
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000439#define LANGINFO(X) {#X, X}
440struct langinfo_constant{
441 char* name;
442 int value;
443} langinfo_constants[] =
444{
445 /* These constants should exist on any langinfo implementation */
446 LANGINFO(DAY_1),
447 LANGINFO(DAY_2),
448 LANGINFO(DAY_3),
449 LANGINFO(DAY_4),
450 LANGINFO(DAY_5),
451 LANGINFO(DAY_6),
452 LANGINFO(DAY_7),
453
454 LANGINFO(ABDAY_1),
455 LANGINFO(ABDAY_2),
456 LANGINFO(ABDAY_3),
457 LANGINFO(ABDAY_4),
458 LANGINFO(ABDAY_5),
459 LANGINFO(ABDAY_6),
460 LANGINFO(ABDAY_7),
461
462 LANGINFO(MON_1),
463 LANGINFO(MON_2),
464 LANGINFO(MON_3),
465 LANGINFO(MON_4),
466 LANGINFO(MON_5),
467 LANGINFO(MON_6),
468 LANGINFO(MON_7),
469 LANGINFO(MON_8),
470 LANGINFO(MON_9),
471 LANGINFO(MON_10),
472 LANGINFO(MON_11),
473 LANGINFO(MON_12),
474
475 LANGINFO(ABMON_1),
476 LANGINFO(ABMON_2),
477 LANGINFO(ABMON_3),
478 LANGINFO(ABMON_4),
479 LANGINFO(ABMON_5),
480 LANGINFO(ABMON_6),
481 LANGINFO(ABMON_7),
482 LANGINFO(ABMON_8),
483 LANGINFO(ABMON_9),
484 LANGINFO(ABMON_10),
485 LANGINFO(ABMON_11),
486 LANGINFO(ABMON_12),
487
488#ifdef RADIXCHAR
489 /* The following are not available with glibc 2.0 */
490 LANGINFO(RADIXCHAR),
491 LANGINFO(THOUSEP),
492 /* YESSTR and NOSTR are deprecated in glibc, since they are
493 a special case of message translation, which should be rather
494 done using gettext. So we don't expose it to Python in the
495 first place.
496 LANGINFO(YESSTR),
497 LANGINFO(NOSTR),
498 */
499 LANGINFO(CRNCYSTR),
500#endif
501
502 LANGINFO(D_T_FMT),
503 LANGINFO(D_FMT),
504 LANGINFO(T_FMT),
505 LANGINFO(AM_STR),
506 LANGINFO(PM_STR),
507
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000508 /* The following constants are available only with XPG4, but...
509 AIX 3.2. only has CODESET.
510 OpenBSD doesn't have CODESET but has T_FMT_AMPM, and doesn't have
511 a few of the others.
512 Solution: ifdef-test them all. */
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000513#ifdef CODESET
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000514 LANGINFO(CODESET),
Martin v. Löwis496f9e42002-03-27 12:15:57 +0000515#endif
516#ifdef T_FMT_AMPM
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000517 LANGINFO(T_FMT_AMPM),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000518#endif
519#ifdef ERA
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000520 LANGINFO(ERA),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000521#endif
522#ifdef ERA_D_FMT
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000523 LANGINFO(ERA_D_FMT),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000524#endif
525#ifdef ERA_D_T_FMT
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000526 LANGINFO(ERA_D_T_FMT),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000527#endif
528#ifdef ERA_T_FMT
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000529 LANGINFO(ERA_T_FMT),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000530#endif
531#ifdef ALT_DIGITS
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000532 LANGINFO(ALT_DIGITS),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000533#endif
534#ifdef YESEXPR
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000535 LANGINFO(YESEXPR),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000536#endif
537#ifdef NOEXPR
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000538 LANGINFO(NOEXPR),
539#endif
540#ifdef _DATE_FMT
541 /* This is not available in all glibc versions that have CODESET. */
542 LANGINFO(_DATE_FMT),
543#endif
544 {0, 0}
545};
546
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000547PyDoc_STRVAR(nl_langinfo__doc__,
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000548"nl_langinfo(key) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000549"Return the value for the locale information associated with key.");
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000550
551static PyObject*
552PyLocale_nl_langinfo(PyObject* self, PyObject* args)
553{
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000554 int item, i;
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000555 if (!PyArg_ParseTuple(args, "i:nl_langinfo", &item))
556 return NULL;
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000557 /* Check whether this is a supported constant. GNU libc sometimes
558 returns numeric values in the char* return value, which would
559 crash PyString_FromString. */
560 for (i = 0; langinfo_constants[i].name; i++)
Hye-Shik Changc3a87b82004-03-21 19:34:30 +0000561 if (langinfo_constants[i].value == item) {
562 /* Check NULL as a workaround for GNU libc's returning NULL
563 instead of an empty string for nl_langinfo(ERA). */
564 const char *result = nl_langinfo(item);
565 return PyString_FromString(result != NULL ? result : "");
566 }
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000567 PyErr_SetString(PyExc_ValueError, "unsupported langinfo constant");
568 return NULL;
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000569}
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000570#endif /* HAVE_LANGINFO_H */
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000571
572#ifdef HAVE_LIBINTL_H
573
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000574PyDoc_STRVAR(gettext__doc__,
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000575"gettext(msg) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000576"Return translation of msg.");
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000577
578static PyObject*
579PyIntl_gettext(PyObject* self, PyObject *args)
580{
581 char *in;
582 if (!PyArg_ParseTuple(args, "z", &in))
583 return 0;
584 return PyString_FromString(gettext(in));
585}
586
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000587PyDoc_STRVAR(dgettext__doc__,
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000588"dgettext(domain, msg) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000589"Return translation of msg in domain.");
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000590
591static PyObject*
592PyIntl_dgettext(PyObject* self, PyObject *args)
593{
594 char *domain, *in;
595 if (!PyArg_ParseTuple(args, "zz", &domain, &in))
596 return 0;
597 return PyString_FromString(dgettext(domain, in));
598}
599
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000600PyDoc_STRVAR(dcgettext__doc__,
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000601"dcgettext(domain, msg, category) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000602"Return translation of msg in domain and category.");
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000603
604static PyObject*
605PyIntl_dcgettext(PyObject *self, PyObject *args)
606{
607 char *domain, *msgid;
608 int category;
609 if (!PyArg_ParseTuple(args, "zzi", &domain, &msgid, &category))
610 return 0;
611 return PyString_FromString(dcgettext(domain,msgid,category));
612}
613
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000614PyDoc_STRVAR(textdomain__doc__,
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000615"textdomain(domain) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000616"Set the C library's textdmain to domain, returning the new domain.");
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000617
618static PyObject*
619PyIntl_textdomain(PyObject* self, PyObject* args)
620{
621 char *domain;
622 if (!PyArg_ParseTuple(args, "z", &domain))
623 return 0;
624 domain = textdomain(domain);
625 if (!domain) {
626 PyErr_SetFromErrno(PyExc_OSError);
627 return NULL;
628 }
629 return PyString_FromString(domain);
630}
631
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000632PyDoc_STRVAR(bindtextdomain__doc__,
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000633"bindtextdomain(domain, dir) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000634"Bind the C library's domain to dir.");
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000635
636static PyObject*
637PyIntl_bindtextdomain(PyObject* self,PyObject*args)
638{
639 char *domain,*dirname;
640 if (!PyArg_ParseTuple(args, "zz", &domain, &dirname))
641 return 0;
642 dirname = bindtextdomain(domain, dirname);
643 if (!dirname) {
644 PyErr_SetFromErrno(PyExc_OSError);
645 return NULL;
646 }
647 return PyString_FromString(dirname);
648}
649
Gustavo Niemeyer7bd33c52004-07-22 18:44:01 +0000650#ifdef HAVE_BIND_TEXTDOMAIN_CODESET
651PyDoc_STRVAR(bind_textdomain_codeset__doc__,
652"bind_textdomain_codeset(domain, codeset) -> string\n"
653"Bind the C library's domain to codeset.");
654
655static PyObject*
656PyIntl_bind_textdomain_codeset(PyObject* self,PyObject*args)
657{
658 char *domain,*codeset;
659 if (!PyArg_ParseTuple(args, "sz", &domain, &codeset))
660 return NULL;
661 codeset = bind_textdomain_codeset(domain, codeset);
662 if (codeset)
663 return PyString_FromString(codeset);
664 Py_RETURN_NONE;
665}
666#endif
667
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000668#endif
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000669
Guido van Rossum220ecc81997-11-18 21:03:39 +0000670static struct PyMethodDef PyLocale_Methods[] = {
Andrew M. Kuchlinge365fb82000-08-03 02:06:16 +0000671 {"setlocale", (PyCFunction) PyLocale_setlocale,
672 METH_VARARGS, setlocale__doc__},
673 {"localeconv", (PyCFunction) PyLocale_localeconv,
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000674 METH_NOARGS, localeconv__doc__},
Andrew M. Kuchlinge365fb82000-08-03 02:06:16 +0000675 {"strcoll", (PyCFunction) PyLocale_strcoll,
676 METH_VARARGS, strcoll__doc__},
677 {"strxfrm", (PyCFunction) PyLocale_strxfrm,
678 METH_VARARGS, strxfrm__doc__},
Martin v. Löwis52ea7e92002-11-26 09:05:36 +0000679#if defined(MS_WINDOWS) || defined(__APPLE__)
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000680 {"_getdefaultlocale", (PyCFunction) PyLocale_getdefaultlocale, METH_NOARGS},
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000681#endif
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000682#ifdef HAVE_LANGINFO_H
683 {"nl_langinfo", (PyCFunction) PyLocale_nl_langinfo,
684 METH_VARARGS, nl_langinfo__doc__},
685#endif
Martin v. Löwisc6a7d7e2002-05-02 12:16:29 +0000686#ifdef HAVE_LIBINTL_H
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000687 {"gettext",(PyCFunction)PyIntl_gettext,METH_VARARGS,
688 gettext__doc__},
689 {"dgettext",(PyCFunction)PyIntl_dgettext,METH_VARARGS,
690 dgettext__doc__},
691 {"dcgettext",(PyCFunction)PyIntl_dcgettext,METH_VARARGS,
692 dcgettext__doc__},
693 {"textdomain",(PyCFunction)PyIntl_textdomain,METH_VARARGS,
694 textdomain__doc__},
695 {"bindtextdomain",(PyCFunction)PyIntl_bindtextdomain,METH_VARARGS,
696 bindtextdomain__doc__},
Gustavo Niemeyer7bd33c52004-07-22 18:44:01 +0000697#ifdef HAVE_BIND_TEXTDOMAIN_CODESET
698 {"bind_textdomain_codeset",(PyCFunction)PyIntl_bind_textdomain_codeset,
699 METH_VARARGS, bind_textdomain_codeset__doc__},
700#endif
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000701#endif
Guido van Rossum220ecc81997-11-18 21:03:39 +0000702 {NULL, NULL}
703};
704
Mark Hammondfe51c6d2002-08-02 02:27:13 +0000705PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000706init_locale(void)
Guido van Rossum220ecc81997-11-18 21:03:39 +0000707{
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000708 PyObject *m, *d, *x;
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000709#ifdef HAVE_LANGINFO_H
710 int i;
711#endif
Guido van Rossum220ecc81997-11-18 21:03:39 +0000712
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000713 m = Py_InitModule("_locale", PyLocale_Methods);
Neal Norwitz1ac754f2006-01-19 06:09:39 +0000714 if (m == NULL)
715 return;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000716
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000717 d = PyModule_GetDict(m);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000718
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000719 x = PyInt_FromLong(LC_CTYPE);
720 PyDict_SetItemString(d, "LC_CTYPE", x);
721 Py_XDECREF(x);
722
723 x = PyInt_FromLong(LC_TIME);
724 PyDict_SetItemString(d, "LC_TIME", x);
725 Py_XDECREF(x);
726
727 x = PyInt_FromLong(LC_COLLATE);
728 PyDict_SetItemString(d, "LC_COLLATE", x);
729 Py_XDECREF(x);
730
731 x = PyInt_FromLong(LC_MONETARY);
732 PyDict_SetItemString(d, "LC_MONETARY", x);
733 Py_XDECREF(x);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000734
Guido van Rossum8d9c2e31997-12-09 19:35:11 +0000735#ifdef LC_MESSAGES
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000736 x = PyInt_FromLong(LC_MESSAGES);
737 PyDict_SetItemString(d, "LC_MESSAGES", x);
738 Py_XDECREF(x);
Guido van Rossum8d9c2e31997-12-09 19:35:11 +0000739#endif /* LC_MESSAGES */
Guido van Rossum220ecc81997-11-18 21:03:39 +0000740
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000741 x = PyInt_FromLong(LC_NUMERIC);
742 PyDict_SetItemString(d, "LC_NUMERIC", x);
743 Py_XDECREF(x);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000744
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000745 x = PyInt_FromLong(LC_ALL);
746 PyDict_SetItemString(d, "LC_ALL", x);
747 Py_XDECREF(x);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000748
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000749 x = PyInt_FromLong(CHAR_MAX);
750 PyDict_SetItemString(d, "CHAR_MAX", x);
751 Py_XDECREF(x);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000752
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000753 Error = PyErr_NewException("locale.Error", NULL, NULL);
754 PyDict_SetItemString(d, "Error", Error);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000755
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000756 x = PyString_FromString(locale__doc__);
757 PyDict_SetItemString(d, "__doc__", x);
758 Py_XDECREF(x);
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000759
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000760#ifdef HAVE_LANGINFO_H
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000761 for (i = 0; langinfo_constants[i].name; i++) {
762 PyModule_AddIntConstant(m, langinfo_constants[i].name,
763 langinfo_constants[i].value);
764 }
Martin v. Löwisf95dd0a2001-08-15 17:14:33 +0000765#endif
Guido van Rossum220ecc81997-11-18 21:03:39 +0000766}
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000767
768/*
769Local variables:
770c-basic-offset: 4
771indent-tabs-mode: nil
772End:
773*/