blob: fb2837e1730f51ecfb33a18324e36edd961e6219 [file] [log] [blame]
Guido van Rossum220ecc81997-11-18 21:03:39 +00001/***********************************************************
Martin v. Löwis92fab752008-03-08 10:40:41 +00002Copyright (C) 1997, 2002, 2003, 2007, 2008 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
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000044PyDoc_STRVAR(locale__doc__, "Support for POSIX locales.");
Guido van Rossum220ecc81997-11-18 21:03:39 +000045
46static PyObject *Error;
47
Martin v. Löwis92fab752008-03-08 10:40:41 +000048/* Convert a char* to a Unicode object according to the current locale */
49static PyObject*
50str2uni(const char* s)
51{
Antoine Pitroufff95302008-09-03 18:58:51 +000052#ifdef HAVE_BROKEN_MBSTOWCS
53 size_t needed = strlen(s);
54#else
Martin v. Löwis92fab752008-03-08 10:40:41 +000055 size_t needed = mbstowcs(NULL, s, 0);
Antoine Pitroufff95302008-09-03 18:58:51 +000056#endif
Martin v. Löwis92fab752008-03-08 10:40:41 +000057 size_t res1;
58 wchar_t smallbuf[30];
59 wchar_t *dest;
60 PyObject *res2;
61 if (needed == (size_t)-1) {
62 PyErr_SetString(PyExc_ValueError, "Cannot convert byte to string");
63 return NULL;
64 }
Martin v. Löwis5bacec12008-03-08 13:39:58 +000065 if (needed*sizeof(wchar_t) < sizeof(smallbuf))
Martin v. Löwis92fab752008-03-08 10:40:41 +000066 dest = smallbuf;
67 else {
Martin v. Löwisa69e1ef2008-03-08 10:54:31 +000068 dest = PyMem_Malloc((needed+1)*sizeof(wchar_t));
Martin v. Löwis92fab752008-03-08 10:40:41 +000069 if (!dest)
70 return PyErr_NoMemory();
71 }
72 /* This shouldn't fail now */
73 res1 = mbstowcs(dest, s, needed+1);
Antoine Pitroufff95302008-09-03 18:58:51 +000074#ifdef HAVE_BROKEN_MBSTOWCS
75 assert(res1 != (size_t)-1);
76#else
Martin v. Löwisce7a1122008-03-08 10:59:49 +000077 assert(res1 == needed);
Antoine Pitroufff95302008-09-03 18:58:51 +000078#endif
Martin v. Löwis92fab752008-03-08 10:40:41 +000079 res2 = PyUnicode_FromWideChar(dest, res1);
80 if (dest != smallbuf)
81 PyMem_Free(dest);
82 return res2;
83}
84
Guido van Rossum220ecc81997-11-18 21:03:39 +000085/* support functions for formatting floating point numbers */
86
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000087PyDoc_STRVAR(setlocale__doc__,
88"(integer,string=None) -> string. Activates/queries locale processing.");
Guido van Rossum220ecc81997-11-18 21:03:39 +000089
Guido van Rossum220ecc81997-11-18 21:03:39 +000090/* the grouping is terminated by either 0 or CHAR_MAX */
91static PyObject*
Fredrik Lundh8f017a02000-07-08 19:57:37 +000092copy_grouping(char* s)
Guido van Rossum220ecc81997-11-18 21:03:39 +000093{
Fredrik Lundh8f017a02000-07-08 19:57:37 +000094 int i;
95 PyObject *result, *val = NULL;
96
97 if (s[0] == '\0')
98 /* empty string: no grouping at all */
99 return PyList_New(0);
100
101 for (i = 0; s[i] != '\0' && s[i] != CHAR_MAX; i++)
102 ; /* nothing */
103
104 result = PyList_New(i+1);
105 if (!result)
106 return NULL;
107
108 i = -1;
109 do {
110 i++;
Christian Heimes217cfd12007-12-02 14:31:20 +0000111 val = PyLong_FromLong(s[i]);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000112 if (!val)
113 break;
114 if (PyList_SetItem(result, i, val)) {
115 Py_DECREF(val);
Fredrik Lundh89610a42000-07-08 20:07:24 +0000116 val = NULL;
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000117 break;
118 }
119 } while (s[i] != '\0' && s[i] != CHAR_MAX);
120
121 if (!val) {
122 Py_DECREF(result);
123 return NULL;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000124 }
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000125
126 return result;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000127}
128
Guido van Rossum220ecc81997-11-18 21:03:39 +0000129static PyObject*
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000130PyLocale_setlocale(PyObject* self, PyObject* args)
Guido van Rossum220ecc81997-11-18 21:03:39 +0000131{
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000132 int category;
133 char *locale = NULL, *result;
134 PyObject *result_object;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000135
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000136 if (!PyArg_ParseTuple(args, "i|z:setlocale", &category, &locale))
Fredrik Lundh89610a42000-07-08 20:07:24 +0000137 return NULL;
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000138
139 if (locale) {
140 /* set locale */
141 result = setlocale(category, locale);
142 if (!result) {
143 /* operation failed, no setting was changed */
Martin v. Löwis25f90d52003-09-03 04:50:13 +0000144 PyErr_SetString(Error, "unsupported locale setting");
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000145 return NULL;
146 }
Martin v. Löwis92fab752008-03-08 10:40:41 +0000147 result_object = str2uni(result);
Mark Hammond9a714752003-07-24 14:15:07 +0000148 if (!result_object)
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000149 return NULL;
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000150 } else {
151 /* get locale */
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000152 result = setlocale(category, NULL);
153 if (!result) {
154 PyErr_SetString(Error, "locale query failed");
155 return NULL;
156 }
Martin v. Löwis92fab752008-03-08 10:40:41 +0000157 result_object = str2uni(result);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000158 }
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000159 return result_object;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000160}
161
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000162PyDoc_STRVAR(localeconv__doc__,
163"() -> dict. Returns numeric and monetary locale-specific parameters.");
Guido van Rossum220ecc81997-11-18 21:03:39 +0000164
165static PyObject*
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000166PyLocale_localeconv(PyObject* self)
Guido van Rossum220ecc81997-11-18 21:03:39 +0000167{
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000168 PyObject* result;
169 struct lconv *l;
170 PyObject *x;
171
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000172 result = PyDict_New();
Fredrik Lundh89610a42000-07-08 20:07:24 +0000173 if (!result)
174 return NULL;
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000175
176 /* if LC_NUMERIC is different in the C library, use saved value */
177 l = localeconv();
178
179 /* hopefully, the localeconv result survives the C library calls
180 involved herein */
181
182#define RESULT_STRING(s)\
Martin v. Löwis92fab752008-03-08 10:40:41 +0000183 x = str2uni(l->s); \
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000184 if (!x) goto failed;\
185 PyDict_SetItemString(result, #s, x);\
186 Py_XDECREF(x)
187
188#define RESULT_INT(i)\
Christian Heimes217cfd12007-12-02 14:31:20 +0000189 x = PyLong_FromLong(l->i);\
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000190 if (!x) goto failed;\
191 PyDict_SetItemString(result, #i, x);\
192 Py_XDECREF(x)
Guido van Rossum220ecc81997-11-18 21:03:39 +0000193
194 /* Numeric information */
Martin v. Löwis737ea822004-06-08 18:52:54 +0000195 RESULT_STRING(decimal_point);
196 RESULT_STRING(thousands_sep);
197 x = copy_grouping(l->grouping);
198 if (!x)
199 goto failed;
200 PyDict_SetItemString(result, "grouping", x);
201 Py_XDECREF(x);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000202
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);
209 if (!x)
210 goto failed;
211 PyDict_SetItemString(result, "mon_grouping", x);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000212 Py_XDECREF(x);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000213 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);
223 return result;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000224
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000225 failed:
226 Py_XDECREF(result);
227 Py_XDECREF(x);
228 return NULL;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000229}
230
Martin v. Löwis92fab752008-03-08 10:40:41 +0000231#if defined(HAVE_WCSCOLL)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000232PyDoc_STRVAR(strcoll__doc__,
233"string,string -> int. Compares two strings according to the locale.");
Guido van Rossum220ecc81997-11-18 21:03:39 +0000234
235static PyObject*
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000236PyLocale_strcoll(PyObject* self, PyObject* args)
Guido van Rossum220ecc81997-11-18 21:03:39 +0000237{
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000238 PyObject *os1, *os2, *result = NULL;
239 wchar_t *ws1 = NULL, *ws2 = NULL;
Martin v. Löwis92fab752008-03-08 10:40:41 +0000240 Py_ssize_t len1, len2;
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000241
Martin v. Löwis92fab752008-03-08 10:40:41 +0000242 if (!PyArg_ParseTuple(args, "UU:strcoll", &os1, &os2))
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000243 return NULL;
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000244 /* Convert the unicode strings to wchar[]. */
245 len1 = PyUnicode_GET_SIZE(os1) + 1;
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000246 ws1 = PyMem_MALLOC(len1 * sizeof(wchar_t));
247 if (!ws1) {
248 PyErr_NoMemory();
249 goto done;
250 }
251 if (PyUnicode_AsWideChar((PyUnicodeObject*)os1, ws1, len1) == -1)
252 goto done;
Marc-André Lemburga9cadcd2004-11-22 13:02:31 +0000253 ws1[len1 - 1] = 0;
254 len2 = PyUnicode_GET_SIZE(os2) + 1;
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000255 ws2 = PyMem_MALLOC(len2 * sizeof(wchar_t));
256 if (!ws2) {
257 PyErr_NoMemory();
258 goto done;
259 }
260 if (PyUnicode_AsWideChar((PyUnicodeObject*)os2, ws2, len2) == -1)
261 goto done;
Marc-André Lemburga9cadcd2004-11-22 13:02:31 +0000262 ws2[len2 - 1] = 0;
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000263 /* Collate the strings. */
Christian Heimes217cfd12007-12-02 14:31:20 +0000264 result = PyLong_FromLong(wcscoll(ws1, ws2));
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000265 done:
266 /* Deallocate everything. */
267 if (ws1) PyMem_FREE(ws1);
268 if (ws2) PyMem_FREE(ws2);
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000269 return result;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000270}
Martin v. Löwis92fab752008-03-08 10:40:41 +0000271#endif
Guido van Rossum220ecc81997-11-18 21:03:39 +0000272
Martin v. Löwis92fab752008-03-08 10:40:41 +0000273#ifdef HAVE_WCSXFRM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000274PyDoc_STRVAR(strxfrm__doc__,
275"string -> string. Returns a string that behaves for cmp locale-aware.");
Guido van Rossum220ecc81997-11-18 21:03:39 +0000276
277static PyObject*
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000278PyLocale_strxfrm(PyObject* self, PyObject* args)
Guido van Rossum220ecc81997-11-18 21:03:39 +0000279{
Martin v. Löwis92fab752008-03-08 10:40:41 +0000280 Py_UNICODE *s0;
281 Py_ssize_t n0;
282 wchar_t *s, *buf = NULL;
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000283 size_t n1, n2;
Martin v. Löwis92fab752008-03-08 10:40:41 +0000284 PyObject *result = NULL;
285 Py_ssize_t i;
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000286
Martin v. Löwis92fab752008-03-08 10:40:41 +0000287 if (!PyArg_ParseTuple(args, "u#:strxfrm", &s0, &n0))
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000288 return NULL;
289
Martin v. Löwis92fab752008-03-08 10:40:41 +0000290#ifdef HAVE_USABLE_WCHAR_T
291 s = s0;
292#else
Martin v. Löwisa69e1ef2008-03-08 10:54:31 +0000293 s = PyMem_Malloc((n0+1)*sizeof(wchar_t));
Martin v. Löwis92fab752008-03-08 10:40:41 +0000294 if (!s)
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000295 return PyErr_NoMemory();
Martin v. Löwis92fab752008-03-08 10:40:41 +0000296 for (i=0; i<=n0; i++)
297 s[i] = s0[i];
298#endif
299
300 /* assume no change in size, first */
301 n1 = wcslen(s) + 1;
Martin v. Löwisa69e1ef2008-03-08 10:54:31 +0000302 buf = PyMem_Malloc(n1*sizeof(wchar_t));
Martin v. Löwis92fab752008-03-08 10:40:41 +0000303 if (!buf) {
304 PyErr_NoMemory();
305 goto exit;
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000306 }
Martin v. Löwis92fab752008-03-08 10:40:41 +0000307 n2 = wcsxfrm(buf, s, n1);
308 if (n2 >= n1) {
309 /* more space needed */
Martin v. Löwisa69e1ef2008-03-08 10:54:31 +0000310 buf = PyMem_Realloc(buf, (n2+1)*sizeof(wchar_t));
Martin v. Löwis92fab752008-03-08 10:40:41 +0000311 if (!buf) {
312 PyErr_NoMemory();
313 goto exit;
314 }
315 n2 = wcsxfrm(buf, s, n2);
316 }
317 result = PyUnicode_FromWideChar(buf, n2);
318 exit:
319 if (buf) PyMem_Free(buf);
320#ifdef HAVE_USABLE_WCHAR_T
321 PyMem_Free(s);
322#endif
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000323 return result;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000324}
Martin v. Löwis92fab752008-03-08 10:40:41 +0000325#endif
Guido van Rossum220ecc81997-11-18 21:03:39 +0000326
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000327#if defined(MS_WINDOWS)
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000328static PyObject*
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000329PyLocale_getdefaultlocale(PyObject* self)
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000330{
331 char encoding[100];
332 char locale[100];
333
Tim Peters885d4572001-11-28 20:27:42 +0000334 PyOS_snprintf(encoding, sizeof(encoding), "cp%d", GetACP());
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000335
336 if (GetLocaleInfo(LOCALE_USER_DEFAULT,
337 LOCALE_SISO639LANGNAME,
338 locale, sizeof(locale))) {
Martin v. Löwis18e16552006-02-15 17:27:45 +0000339 Py_ssize_t i = strlen(locale);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000340 locale[i++] = '_';
341 if (GetLocaleInfo(LOCALE_USER_DEFAULT,
342 LOCALE_SISO3166CTRYNAME,
Martin v. Löwis18e16552006-02-15 17:27:45 +0000343 locale+i, (int)(sizeof(locale)-i)))
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000344 return Py_BuildValue("ss", locale, encoding);
345 }
346
347 /* If we end up here, this windows version didn't know about
348 ISO639/ISO3166 names (it's probably Windows 95). Return the
349 Windows language identifier instead (a hexadecimal number) */
350
351 locale[0] = '0';
352 locale[1] = 'x';
353 if (GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_IDEFAULTLANGUAGE,
354 locale+2, sizeof(locale)-2)) {
355 return Py_BuildValue("ss", locale, encoding);
356 }
357
358 /* cannot determine the language code (very unlikely) */
359 Py_INCREF(Py_None);
360 return Py_BuildValue("Os", Py_None, encoding);
361}
362#endif
363
Martin v. Löwis52ea7e92002-11-26 09:05:36 +0000364#if defined(__APPLE__)
Jack Jansen59f072a2004-07-15 13:31:39 +0000365/*
366** Find out what the current script is.
Brett Cannon269ab622004-08-27 05:00:22 +0000367** Donated by Fredrik Lundh.
Jack Jansen59f072a2004-07-15 13:31:39 +0000368*/
369static char *mac_getscript(void)
370{
371 CFStringEncoding enc = CFStringGetSystemEncoding();
372 static CFStringRef name = NULL;
373 /* Return the code name for the encodings for which we have codecs. */
374 switch(enc) {
375 case kCFStringEncodingMacRoman: return "mac-roman";
376 case kCFStringEncodingMacGreek: return "mac-greek";
377 case kCFStringEncodingMacCyrillic: return "mac-cyrillic";
378 case kCFStringEncodingMacTurkish: return "mac-turkish";
379 case kCFStringEncodingMacIcelandic: return "mac-icelandic";
380 /* XXX which one is mac-latin2? */
381 }
382 if (!name) {
Brett Cannon5ce25872005-03-01 03:16:34 +0000383 /* This leaks an object. */
Jack Jansen59f072a2004-07-15 13:31:39 +0000384 name = CFStringConvertEncodingToIANACharSetName(enc);
385 }
386 return (char *)CFStringGetCStringPtr(name, 0);
387}
388
Jack Jansen307d7a42000-07-15 22:31:45 +0000389static PyObject*
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000390PyLocale_getdefaultlocale(PyObject* self)
Jack Jansen307d7a42000-07-15 22:31:45 +0000391{
Jack Jansen59f072a2004-07-15 13:31:39 +0000392 return Py_BuildValue("Os", Py_None, mac_getscript());
Jack Jansen307d7a42000-07-15 22:31:45 +0000393}
394#endif
395
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000396#ifdef HAVE_LANGINFO_H
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000397#define LANGINFO(X) {#X, X}
Martin v. Löwis59683e82008-06-13 07:50:45 +0000398static struct langinfo_constant{
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000399 char* name;
400 int value;
401} langinfo_constants[] =
402{
403 /* These constants should exist on any langinfo implementation */
404 LANGINFO(DAY_1),
405 LANGINFO(DAY_2),
406 LANGINFO(DAY_3),
407 LANGINFO(DAY_4),
408 LANGINFO(DAY_5),
409 LANGINFO(DAY_6),
410 LANGINFO(DAY_7),
411
412 LANGINFO(ABDAY_1),
413 LANGINFO(ABDAY_2),
414 LANGINFO(ABDAY_3),
415 LANGINFO(ABDAY_4),
416 LANGINFO(ABDAY_5),
417 LANGINFO(ABDAY_6),
418 LANGINFO(ABDAY_7),
419
420 LANGINFO(MON_1),
421 LANGINFO(MON_2),
422 LANGINFO(MON_3),
423 LANGINFO(MON_4),
424 LANGINFO(MON_5),
425 LANGINFO(MON_6),
426 LANGINFO(MON_7),
427 LANGINFO(MON_8),
428 LANGINFO(MON_9),
429 LANGINFO(MON_10),
430 LANGINFO(MON_11),
431 LANGINFO(MON_12),
432
433 LANGINFO(ABMON_1),
434 LANGINFO(ABMON_2),
435 LANGINFO(ABMON_3),
436 LANGINFO(ABMON_4),
437 LANGINFO(ABMON_5),
438 LANGINFO(ABMON_6),
439 LANGINFO(ABMON_7),
440 LANGINFO(ABMON_8),
441 LANGINFO(ABMON_9),
442 LANGINFO(ABMON_10),
443 LANGINFO(ABMON_11),
444 LANGINFO(ABMON_12),
445
446#ifdef RADIXCHAR
447 /* The following are not available with glibc 2.0 */
448 LANGINFO(RADIXCHAR),
449 LANGINFO(THOUSEP),
450 /* YESSTR and NOSTR are deprecated in glibc, since they are
451 a special case of message translation, which should be rather
452 done using gettext. So we don't expose it to Python in the
453 first place.
454 LANGINFO(YESSTR),
455 LANGINFO(NOSTR),
456 */
457 LANGINFO(CRNCYSTR),
458#endif
459
460 LANGINFO(D_T_FMT),
461 LANGINFO(D_FMT),
462 LANGINFO(T_FMT),
463 LANGINFO(AM_STR),
464 LANGINFO(PM_STR),
465
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000466 /* The following constants are available only with XPG4, but...
467 AIX 3.2. only has CODESET.
468 OpenBSD doesn't have CODESET but has T_FMT_AMPM, and doesn't have
469 a few of the others.
470 Solution: ifdef-test them all. */
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000471#ifdef CODESET
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000472 LANGINFO(CODESET),
Martin v. Löwis496f9e42002-03-27 12:15:57 +0000473#endif
474#ifdef T_FMT_AMPM
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000475 LANGINFO(T_FMT_AMPM),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000476#endif
477#ifdef ERA
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000478 LANGINFO(ERA),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000479#endif
480#ifdef ERA_D_FMT
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000481 LANGINFO(ERA_D_FMT),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000482#endif
483#ifdef ERA_D_T_FMT
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000484 LANGINFO(ERA_D_T_FMT),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000485#endif
486#ifdef ERA_T_FMT
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000487 LANGINFO(ERA_T_FMT),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000488#endif
489#ifdef ALT_DIGITS
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000490 LANGINFO(ALT_DIGITS),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000491#endif
492#ifdef YESEXPR
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000493 LANGINFO(YESEXPR),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000494#endif
495#ifdef NOEXPR
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000496 LANGINFO(NOEXPR),
497#endif
498#ifdef _DATE_FMT
499 /* This is not available in all glibc versions that have CODESET. */
500 LANGINFO(_DATE_FMT),
501#endif
502 {0, 0}
503};
504
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000505PyDoc_STRVAR(nl_langinfo__doc__,
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000506"nl_langinfo(key) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000507"Return the value for the locale information associated with key.");
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000508
509static PyObject*
510PyLocale_nl_langinfo(PyObject* self, PyObject* args)
511{
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000512 int item, i;
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000513 if (!PyArg_ParseTuple(args, "i:nl_langinfo", &item))
514 return NULL;
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000515 /* Check whether this is a supported constant. GNU libc sometimes
516 returns numeric values in the char* return value, which would
Neal Norwitz7f9d29c2007-08-26 07:21:45 +0000517 crash PyUnicode_FromString. */
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000518 for (i = 0; langinfo_constants[i].name; i++)
Hye-Shik Changc3a87b82004-03-21 19:34:30 +0000519 if (langinfo_constants[i].value == item) {
520 /* Check NULL as a workaround for GNU libc's returning NULL
521 instead of an empty string for nl_langinfo(ERA). */
522 const char *result = nl_langinfo(item);
Neal Norwitz3d7a90d2007-10-27 05:40:06 +0000523 result = result != NULL ? result : "";
Martin v. Löwis92fab752008-03-08 10:40:41 +0000524 return str2uni(result);
Hye-Shik Changc3a87b82004-03-21 19:34:30 +0000525 }
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000526 PyErr_SetString(PyExc_ValueError, "unsupported langinfo constant");
527 return NULL;
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000528}
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000529#endif /* HAVE_LANGINFO_H */
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000530
531#ifdef HAVE_LIBINTL_H
532
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000533PyDoc_STRVAR(gettext__doc__,
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000534"gettext(msg) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000535"Return translation of msg.");
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000536
537static PyObject*
538PyIntl_gettext(PyObject* self, PyObject *args)
539{
540 char *in;
Georg Brandl3dbca812008-07-23 16:10:53 +0000541 if (!PyArg_ParseTuple(args, "s", &in))
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000542 return 0;
Martin v. Löwis92fab752008-03-08 10:40:41 +0000543 return str2uni(gettext(in));
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000544}
545
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000546PyDoc_STRVAR(dgettext__doc__,
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000547"dgettext(domain, msg) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000548"Return translation of msg in domain.");
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000549
550static PyObject*
551PyIntl_dgettext(PyObject* self, PyObject *args)
552{
553 char *domain, *in;
Georg Brandl3dbca812008-07-23 16:10:53 +0000554 if (!PyArg_ParseTuple(args, "zs", &domain, &in))
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000555 return 0;
Martin v. Löwis92fab752008-03-08 10:40:41 +0000556 return str2uni(dgettext(domain, in));
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000557}
558
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000559PyDoc_STRVAR(dcgettext__doc__,
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000560"dcgettext(domain, msg, category) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000561"Return translation of msg in domain and category.");
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000562
563static PyObject*
564PyIntl_dcgettext(PyObject *self, PyObject *args)
565{
566 char *domain, *msgid;
567 int category;
Georg Brandl3dbca812008-07-23 16:10:53 +0000568 if (!PyArg_ParseTuple(args, "zsi", &domain, &msgid, &category))
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000569 return 0;
Martin v. Löwis92fab752008-03-08 10:40:41 +0000570 return str2uni(dcgettext(domain,msgid,category));
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000571}
572
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000573PyDoc_STRVAR(textdomain__doc__,
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000574"textdomain(domain) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000575"Set the C library's textdmain to domain, returning the new domain.");
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000576
577static PyObject*
578PyIntl_textdomain(PyObject* self, PyObject* args)
579{
580 char *domain;
581 if (!PyArg_ParseTuple(args, "z", &domain))
582 return 0;
583 domain = textdomain(domain);
584 if (!domain) {
585 PyErr_SetFromErrno(PyExc_OSError);
586 return NULL;
587 }
Martin v. Löwis92fab752008-03-08 10:40:41 +0000588 return str2uni(domain);
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000589}
590
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000591PyDoc_STRVAR(bindtextdomain__doc__,
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000592"bindtextdomain(domain, dir) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000593"Bind the C library's domain to dir.");
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000594
595static PyObject*
596PyIntl_bindtextdomain(PyObject* self,PyObject*args)
597{
Georg Brandl3dbca812008-07-23 16:10:53 +0000598 char *domain, *dirname;
599 if (!PyArg_ParseTuple(args, "sz", &domain, &dirname))
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000600 return 0;
Georg Brandl3dbca812008-07-23 16:10:53 +0000601 if (!strlen(domain)) {
602 PyErr_SetString(Error, "domain must be a non-empty string");
603 return 0;
604 }
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000605 dirname = bindtextdomain(domain, dirname);
606 if (!dirname) {
607 PyErr_SetFromErrno(PyExc_OSError);
608 return NULL;
609 }
Martin v. Löwis92fab752008-03-08 10:40:41 +0000610 return str2uni(dirname);
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000611}
612
Gustavo Niemeyer7bd33c52004-07-22 18:44:01 +0000613#ifdef HAVE_BIND_TEXTDOMAIN_CODESET
614PyDoc_STRVAR(bind_textdomain_codeset__doc__,
615"bind_textdomain_codeset(domain, codeset) -> string\n"
616"Bind the C library's domain to codeset.");
617
618static PyObject*
619PyIntl_bind_textdomain_codeset(PyObject* self,PyObject*args)
620{
621 char *domain,*codeset;
622 if (!PyArg_ParseTuple(args, "sz", &domain, &codeset))
623 return NULL;
624 codeset = bind_textdomain_codeset(domain, codeset);
625 if (codeset)
Martin v. Löwis92fab752008-03-08 10:40:41 +0000626 return str2uni(codeset);
Gustavo Niemeyer7bd33c52004-07-22 18:44:01 +0000627 Py_RETURN_NONE;
628}
629#endif
630
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000631#endif
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000632
Guido van Rossum220ecc81997-11-18 21:03:39 +0000633static struct PyMethodDef PyLocale_Methods[] = {
Andrew M. Kuchlinge365fb82000-08-03 02:06:16 +0000634 {"setlocale", (PyCFunction) PyLocale_setlocale,
635 METH_VARARGS, setlocale__doc__},
636 {"localeconv", (PyCFunction) PyLocale_localeconv,
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000637 METH_NOARGS, localeconv__doc__},
Martin v. Löwis92fab752008-03-08 10:40:41 +0000638#ifdef HAVE_WCSCOLL
Andrew M. Kuchlinge365fb82000-08-03 02:06:16 +0000639 {"strcoll", (PyCFunction) PyLocale_strcoll,
640 METH_VARARGS, strcoll__doc__},
Martin v. Löwis92fab752008-03-08 10:40:41 +0000641#endif
642#ifdef HAVE_WCSXFRM
Andrew M. Kuchlinge365fb82000-08-03 02:06:16 +0000643 {"strxfrm", (PyCFunction) PyLocale_strxfrm,
644 METH_VARARGS, strxfrm__doc__},
Martin v. Löwis92fab752008-03-08 10:40:41 +0000645#endif
Martin v. Löwis52ea7e92002-11-26 09:05:36 +0000646#if defined(MS_WINDOWS) || defined(__APPLE__)
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000647 {"_getdefaultlocale", (PyCFunction) PyLocale_getdefaultlocale, METH_NOARGS},
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000648#endif
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000649#ifdef HAVE_LANGINFO_H
650 {"nl_langinfo", (PyCFunction) PyLocale_nl_langinfo,
651 METH_VARARGS, nl_langinfo__doc__},
652#endif
Martin v. Löwisc6a7d7e2002-05-02 12:16:29 +0000653#ifdef HAVE_LIBINTL_H
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000654 {"gettext",(PyCFunction)PyIntl_gettext,METH_VARARGS,
655 gettext__doc__},
656 {"dgettext",(PyCFunction)PyIntl_dgettext,METH_VARARGS,
657 dgettext__doc__},
658 {"dcgettext",(PyCFunction)PyIntl_dcgettext,METH_VARARGS,
659 dcgettext__doc__},
660 {"textdomain",(PyCFunction)PyIntl_textdomain,METH_VARARGS,
661 textdomain__doc__},
662 {"bindtextdomain",(PyCFunction)PyIntl_bindtextdomain,METH_VARARGS,
663 bindtextdomain__doc__},
Gustavo Niemeyer7bd33c52004-07-22 18:44:01 +0000664#ifdef HAVE_BIND_TEXTDOMAIN_CODESET
665 {"bind_textdomain_codeset",(PyCFunction)PyIntl_bind_textdomain_codeset,
666 METH_VARARGS, bind_textdomain_codeset__doc__},
667#endif
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000668#endif
Guido van Rossum220ecc81997-11-18 21:03:39 +0000669 {NULL, NULL}
670};
671
Martin v. Löwis1a214512008-06-11 05:26:20 +0000672
673static struct PyModuleDef _localemodule = {
674 PyModuleDef_HEAD_INIT,
675 "_locale",
676 locale__doc__,
677 -1,
678 PyLocale_Methods,
679 NULL,
680 NULL,
681 NULL,
682 NULL
683};
684
Mark Hammondfe51c6d2002-08-02 02:27:13 +0000685PyMODINIT_FUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +0000686PyInit__locale(void)
Guido van Rossum220ecc81997-11-18 21:03:39 +0000687{
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000688 PyObject *m, *d, *x;
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000689#ifdef HAVE_LANGINFO_H
690 int i;
691#endif
Guido van Rossum220ecc81997-11-18 21:03:39 +0000692
Martin v. Löwis1a214512008-06-11 05:26:20 +0000693 m = PyModule_Create(&_localemodule);
Neal Norwitz1ac754f2006-01-19 06:09:39 +0000694 if (m == NULL)
Martin v. Löwis1a214512008-06-11 05:26:20 +0000695 return NULL;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000696
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000697 d = PyModule_GetDict(m);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000698
Christian Heimes217cfd12007-12-02 14:31:20 +0000699 x = PyLong_FromLong(LC_CTYPE);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000700 PyDict_SetItemString(d, "LC_CTYPE", x);
701 Py_XDECREF(x);
702
Christian Heimes217cfd12007-12-02 14:31:20 +0000703 x = PyLong_FromLong(LC_TIME);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000704 PyDict_SetItemString(d, "LC_TIME", x);
705 Py_XDECREF(x);
706
Christian Heimes217cfd12007-12-02 14:31:20 +0000707 x = PyLong_FromLong(LC_COLLATE);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000708 PyDict_SetItemString(d, "LC_COLLATE", x);
709 Py_XDECREF(x);
710
Christian Heimes217cfd12007-12-02 14:31:20 +0000711 x = PyLong_FromLong(LC_MONETARY);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000712 PyDict_SetItemString(d, "LC_MONETARY", x);
713 Py_XDECREF(x);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000714
Guido van Rossum8d9c2e31997-12-09 19:35:11 +0000715#ifdef LC_MESSAGES
Christian Heimes217cfd12007-12-02 14:31:20 +0000716 x = PyLong_FromLong(LC_MESSAGES);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000717 PyDict_SetItemString(d, "LC_MESSAGES", x);
718 Py_XDECREF(x);
Guido van Rossum8d9c2e31997-12-09 19:35:11 +0000719#endif /* LC_MESSAGES */
Guido van Rossum220ecc81997-11-18 21:03:39 +0000720
Christian Heimes217cfd12007-12-02 14:31:20 +0000721 x = PyLong_FromLong(LC_NUMERIC);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000722 PyDict_SetItemString(d, "LC_NUMERIC", x);
723 Py_XDECREF(x);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000724
Christian Heimes217cfd12007-12-02 14:31:20 +0000725 x = PyLong_FromLong(LC_ALL);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000726 PyDict_SetItemString(d, "LC_ALL", x);
727 Py_XDECREF(x);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000728
Christian Heimes217cfd12007-12-02 14:31:20 +0000729 x = PyLong_FromLong(CHAR_MAX);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000730 PyDict_SetItemString(d, "CHAR_MAX", x);
731 Py_XDECREF(x);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000732
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000733 Error = PyErr_NewException("locale.Error", NULL, NULL);
734 PyDict_SetItemString(d, "Error", Error);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000735
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000736#ifdef HAVE_LANGINFO_H
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000737 for (i = 0; langinfo_constants[i].name; i++) {
738 PyModule_AddIntConstant(m, langinfo_constants[i].name,
739 langinfo_constants[i].value);
740 }
Martin v. Löwisf95dd0a2001-08-15 17:14:33 +0000741#endif
Martin v. Löwis1a214512008-06-11 05:26:20 +0000742 return m;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000743}
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000744
745/*
746Local variables:
747c-basic-offset: 4
748indent-tabs-mode: nil
749End:
750*/