blob: 432df36973ddcb1cacce87a6a70c0548707c2afc [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__,
Mark Dickinson211c6252009-02-01 10:28:51 +0000275"strxfrm(string) -> string.\n\
276\n\
277Return a string that can be used as a key for locale-aware comparisons.");
Guido van Rossum220ecc81997-11-18 21:03:39 +0000278
279static PyObject*
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000280PyLocale_strxfrm(PyObject* self, PyObject* args)
Guido van Rossum220ecc81997-11-18 21:03:39 +0000281{
Martin v. Löwis92fab752008-03-08 10:40:41 +0000282 Py_UNICODE *s0;
283 Py_ssize_t n0;
284 wchar_t *s, *buf = NULL;
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000285 size_t n1, n2;
Martin v. Löwis92fab752008-03-08 10:40:41 +0000286 PyObject *result = NULL;
287 Py_ssize_t i;
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000288
Martin v. Löwis92fab752008-03-08 10:40:41 +0000289 if (!PyArg_ParseTuple(args, "u#:strxfrm", &s0, &n0))
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000290 return NULL;
291
Martin v. Löwis92fab752008-03-08 10:40:41 +0000292#ifdef HAVE_USABLE_WCHAR_T
293 s = s0;
294#else
Martin v. Löwisa69e1ef2008-03-08 10:54:31 +0000295 s = PyMem_Malloc((n0+1)*sizeof(wchar_t));
Martin v. Löwis92fab752008-03-08 10:40:41 +0000296 if (!s)
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000297 return PyErr_NoMemory();
Martin v. Löwis92fab752008-03-08 10:40:41 +0000298 for (i=0; i<=n0; i++)
299 s[i] = s0[i];
300#endif
301
302 /* assume no change in size, first */
303 n1 = wcslen(s) + 1;
Martin v. Löwisa69e1ef2008-03-08 10:54:31 +0000304 buf = PyMem_Malloc(n1*sizeof(wchar_t));
Martin v. Löwis92fab752008-03-08 10:40:41 +0000305 if (!buf) {
306 PyErr_NoMemory();
307 goto exit;
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000308 }
Martin v. Löwis92fab752008-03-08 10:40:41 +0000309 n2 = wcsxfrm(buf, s, n1);
310 if (n2 >= n1) {
311 /* more space needed */
Martin v. Löwisa69e1ef2008-03-08 10:54:31 +0000312 buf = PyMem_Realloc(buf, (n2+1)*sizeof(wchar_t));
Martin v. Löwis92fab752008-03-08 10:40:41 +0000313 if (!buf) {
314 PyErr_NoMemory();
315 goto exit;
316 }
317 n2 = wcsxfrm(buf, s, n2);
318 }
319 result = PyUnicode_FromWideChar(buf, n2);
320 exit:
321 if (buf) PyMem_Free(buf);
322#ifdef HAVE_USABLE_WCHAR_T
323 PyMem_Free(s);
324#endif
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000325 return result;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000326}
Martin v. Löwis92fab752008-03-08 10:40:41 +0000327#endif
Guido van Rossum220ecc81997-11-18 21:03:39 +0000328
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000329#if defined(MS_WINDOWS)
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000330static PyObject*
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000331PyLocale_getdefaultlocale(PyObject* self)
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000332{
333 char encoding[100];
334 char locale[100];
335
Tim Peters885d4572001-11-28 20:27:42 +0000336 PyOS_snprintf(encoding, sizeof(encoding), "cp%d", GetACP());
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000337
338 if (GetLocaleInfo(LOCALE_USER_DEFAULT,
339 LOCALE_SISO639LANGNAME,
340 locale, sizeof(locale))) {
Martin v. Löwis18e16552006-02-15 17:27:45 +0000341 Py_ssize_t i = strlen(locale);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000342 locale[i++] = '_';
343 if (GetLocaleInfo(LOCALE_USER_DEFAULT,
344 LOCALE_SISO3166CTRYNAME,
Martin v. Löwis18e16552006-02-15 17:27:45 +0000345 locale+i, (int)(sizeof(locale)-i)))
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000346 return Py_BuildValue("ss", locale, encoding);
347 }
348
349 /* If we end up here, this windows version didn't know about
350 ISO639/ISO3166 names (it's probably Windows 95). Return the
351 Windows language identifier instead (a hexadecimal number) */
352
353 locale[0] = '0';
354 locale[1] = 'x';
355 if (GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_IDEFAULTLANGUAGE,
356 locale+2, sizeof(locale)-2)) {
357 return Py_BuildValue("ss", locale, encoding);
358 }
359
360 /* cannot determine the language code (very unlikely) */
361 Py_INCREF(Py_None);
362 return Py_BuildValue("Os", Py_None, encoding);
363}
364#endif
365
Martin v. Löwis52ea7e92002-11-26 09:05:36 +0000366#if defined(__APPLE__)
Jack Jansen59f072a2004-07-15 13:31:39 +0000367/*
368** Find out what the current script is.
Brett Cannon269ab622004-08-27 05:00:22 +0000369** Donated by Fredrik Lundh.
Jack Jansen59f072a2004-07-15 13:31:39 +0000370*/
371static char *mac_getscript(void)
372{
373 CFStringEncoding enc = CFStringGetSystemEncoding();
374 static CFStringRef name = NULL;
375 /* Return the code name for the encodings for which we have codecs. */
376 switch(enc) {
377 case kCFStringEncodingMacRoman: return "mac-roman";
378 case kCFStringEncodingMacGreek: return "mac-greek";
379 case kCFStringEncodingMacCyrillic: return "mac-cyrillic";
380 case kCFStringEncodingMacTurkish: return "mac-turkish";
381 case kCFStringEncodingMacIcelandic: return "mac-icelandic";
382 /* XXX which one is mac-latin2? */
383 }
384 if (!name) {
Brett Cannon5ce25872005-03-01 03:16:34 +0000385 /* This leaks an object. */
Jack Jansen59f072a2004-07-15 13:31:39 +0000386 name = CFStringConvertEncodingToIANACharSetName(enc);
387 }
388 return (char *)CFStringGetCStringPtr(name, 0);
389}
390
Jack Jansen307d7a42000-07-15 22:31:45 +0000391static PyObject*
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000392PyLocale_getdefaultlocale(PyObject* self)
Jack Jansen307d7a42000-07-15 22:31:45 +0000393{
Jack Jansen59f072a2004-07-15 13:31:39 +0000394 return Py_BuildValue("Os", Py_None, mac_getscript());
Jack Jansen307d7a42000-07-15 22:31:45 +0000395}
396#endif
397
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000398#ifdef HAVE_LANGINFO_H
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000399#define LANGINFO(X) {#X, X}
Martin v. Löwis59683e82008-06-13 07:50:45 +0000400static struct langinfo_constant{
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000401 char* name;
402 int value;
403} langinfo_constants[] =
404{
405 /* These constants should exist on any langinfo implementation */
406 LANGINFO(DAY_1),
407 LANGINFO(DAY_2),
408 LANGINFO(DAY_3),
409 LANGINFO(DAY_4),
410 LANGINFO(DAY_5),
411 LANGINFO(DAY_6),
412 LANGINFO(DAY_7),
413
414 LANGINFO(ABDAY_1),
415 LANGINFO(ABDAY_2),
416 LANGINFO(ABDAY_3),
417 LANGINFO(ABDAY_4),
418 LANGINFO(ABDAY_5),
419 LANGINFO(ABDAY_6),
420 LANGINFO(ABDAY_7),
421
422 LANGINFO(MON_1),
423 LANGINFO(MON_2),
424 LANGINFO(MON_3),
425 LANGINFO(MON_4),
426 LANGINFO(MON_5),
427 LANGINFO(MON_6),
428 LANGINFO(MON_7),
429 LANGINFO(MON_8),
430 LANGINFO(MON_9),
431 LANGINFO(MON_10),
432 LANGINFO(MON_11),
433 LANGINFO(MON_12),
434
435 LANGINFO(ABMON_1),
436 LANGINFO(ABMON_2),
437 LANGINFO(ABMON_3),
438 LANGINFO(ABMON_4),
439 LANGINFO(ABMON_5),
440 LANGINFO(ABMON_6),
441 LANGINFO(ABMON_7),
442 LANGINFO(ABMON_8),
443 LANGINFO(ABMON_9),
444 LANGINFO(ABMON_10),
445 LANGINFO(ABMON_11),
446 LANGINFO(ABMON_12),
447
448#ifdef RADIXCHAR
449 /* The following are not available with glibc 2.0 */
450 LANGINFO(RADIXCHAR),
451 LANGINFO(THOUSEP),
452 /* YESSTR and NOSTR are deprecated in glibc, since they are
453 a special case of message translation, which should be rather
454 done using gettext. So we don't expose it to Python in the
455 first place.
456 LANGINFO(YESSTR),
457 LANGINFO(NOSTR),
458 */
459 LANGINFO(CRNCYSTR),
460#endif
461
462 LANGINFO(D_T_FMT),
463 LANGINFO(D_FMT),
464 LANGINFO(T_FMT),
465 LANGINFO(AM_STR),
466 LANGINFO(PM_STR),
467
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000468 /* The following constants are available only with XPG4, but...
469 AIX 3.2. only has CODESET.
470 OpenBSD doesn't have CODESET but has T_FMT_AMPM, and doesn't have
471 a few of the others.
472 Solution: ifdef-test them all. */
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000473#ifdef CODESET
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000474 LANGINFO(CODESET),
Martin v. Löwis496f9e42002-03-27 12:15:57 +0000475#endif
476#ifdef T_FMT_AMPM
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000477 LANGINFO(T_FMT_AMPM),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000478#endif
479#ifdef ERA
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000480 LANGINFO(ERA),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000481#endif
482#ifdef ERA_D_FMT
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000483 LANGINFO(ERA_D_FMT),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000484#endif
485#ifdef ERA_D_T_FMT
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000486 LANGINFO(ERA_D_T_FMT),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000487#endif
488#ifdef ERA_T_FMT
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000489 LANGINFO(ERA_T_FMT),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000490#endif
491#ifdef ALT_DIGITS
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000492 LANGINFO(ALT_DIGITS),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000493#endif
494#ifdef YESEXPR
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000495 LANGINFO(YESEXPR),
Martin v. Löwis2ea2c9d2002-04-19 21:04:41 +0000496#endif
497#ifdef NOEXPR
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000498 LANGINFO(NOEXPR),
499#endif
500#ifdef _DATE_FMT
501 /* This is not available in all glibc versions that have CODESET. */
502 LANGINFO(_DATE_FMT),
503#endif
504 {0, 0}
505};
506
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000507PyDoc_STRVAR(nl_langinfo__doc__,
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000508"nl_langinfo(key) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000509"Return the value for the locale information associated with key.");
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000510
511static PyObject*
512PyLocale_nl_langinfo(PyObject* self, PyObject* args)
513{
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000514 int item, i;
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000515 if (!PyArg_ParseTuple(args, "i:nl_langinfo", &item))
516 return NULL;
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000517 /* Check whether this is a supported constant. GNU libc sometimes
518 returns numeric values in the char* return value, which would
Neal Norwitz7f9d29c2007-08-26 07:21:45 +0000519 crash PyUnicode_FromString. */
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000520 for (i = 0; langinfo_constants[i].name; i++)
Hye-Shik Changc3a87b82004-03-21 19:34:30 +0000521 if (langinfo_constants[i].value == item) {
522 /* Check NULL as a workaround for GNU libc's returning NULL
523 instead of an empty string for nl_langinfo(ERA). */
524 const char *result = nl_langinfo(item);
Neal Norwitz3d7a90d2007-10-27 05:40:06 +0000525 result = result != NULL ? result : "";
Martin v. Löwis92fab752008-03-08 10:40:41 +0000526 return str2uni(result);
Hye-Shik Changc3a87b82004-03-21 19:34:30 +0000527 }
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000528 PyErr_SetString(PyExc_ValueError, "unsupported langinfo constant");
529 return NULL;
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000530}
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000531#endif /* HAVE_LANGINFO_H */
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000532
533#ifdef HAVE_LIBINTL_H
534
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000535PyDoc_STRVAR(gettext__doc__,
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000536"gettext(msg) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000537"Return translation of msg.");
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000538
539static PyObject*
540PyIntl_gettext(PyObject* self, PyObject *args)
541{
542 char *in;
Georg Brandl3dbca812008-07-23 16:10:53 +0000543 if (!PyArg_ParseTuple(args, "s", &in))
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000544 return 0;
Martin v. Löwis92fab752008-03-08 10:40:41 +0000545 return str2uni(gettext(in));
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000546}
547
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000548PyDoc_STRVAR(dgettext__doc__,
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000549"dgettext(domain, msg) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000550"Return translation of msg in domain.");
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000551
552static PyObject*
553PyIntl_dgettext(PyObject* self, PyObject *args)
554{
555 char *domain, *in;
Georg Brandl3dbca812008-07-23 16:10:53 +0000556 if (!PyArg_ParseTuple(args, "zs", &domain, &in))
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000557 return 0;
Martin v. Löwis92fab752008-03-08 10:40:41 +0000558 return str2uni(dgettext(domain, in));
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000559}
560
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000561PyDoc_STRVAR(dcgettext__doc__,
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000562"dcgettext(domain, msg, category) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000563"Return translation of msg in domain and category.");
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000564
565static PyObject*
566PyIntl_dcgettext(PyObject *self, PyObject *args)
567{
568 char *domain, *msgid;
569 int category;
Georg Brandl3dbca812008-07-23 16:10:53 +0000570 if (!PyArg_ParseTuple(args, "zsi", &domain, &msgid, &category))
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000571 return 0;
Martin v. Löwis92fab752008-03-08 10:40:41 +0000572 return str2uni(dcgettext(domain,msgid,category));
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000573}
574
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000575PyDoc_STRVAR(textdomain__doc__,
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000576"textdomain(domain) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000577"Set the C library's textdmain to domain, returning the new domain.");
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000578
579static PyObject*
580PyIntl_textdomain(PyObject* self, PyObject* args)
581{
582 char *domain;
583 if (!PyArg_ParseTuple(args, "z", &domain))
584 return 0;
585 domain = textdomain(domain);
586 if (!domain) {
587 PyErr_SetFromErrno(PyExc_OSError);
588 return NULL;
589 }
Martin v. Löwis92fab752008-03-08 10:40:41 +0000590 return str2uni(domain);
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000591}
592
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000593PyDoc_STRVAR(bindtextdomain__doc__,
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000594"bindtextdomain(domain, dir) -> string\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000595"Bind the C library's domain to dir.");
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000596
597static PyObject*
598PyIntl_bindtextdomain(PyObject* self,PyObject*args)
599{
Georg Brandl3dbca812008-07-23 16:10:53 +0000600 char *domain, *dirname;
601 if (!PyArg_ParseTuple(args, "sz", &domain, &dirname))
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000602 return 0;
Georg Brandl3dbca812008-07-23 16:10:53 +0000603 if (!strlen(domain)) {
604 PyErr_SetString(Error, "domain must be a non-empty string");
605 return 0;
606 }
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000607 dirname = bindtextdomain(domain, dirname);
608 if (!dirname) {
609 PyErr_SetFromErrno(PyExc_OSError);
610 return NULL;
611 }
Martin v. Löwis92fab752008-03-08 10:40:41 +0000612 return str2uni(dirname);
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000613}
614
Gustavo Niemeyer7bd33c52004-07-22 18:44:01 +0000615#ifdef HAVE_BIND_TEXTDOMAIN_CODESET
616PyDoc_STRVAR(bind_textdomain_codeset__doc__,
617"bind_textdomain_codeset(domain, codeset) -> string\n"
618"Bind the C library's domain to codeset.");
619
620static PyObject*
621PyIntl_bind_textdomain_codeset(PyObject* self,PyObject*args)
622{
623 char *domain,*codeset;
624 if (!PyArg_ParseTuple(args, "sz", &domain, &codeset))
625 return NULL;
626 codeset = bind_textdomain_codeset(domain, codeset);
627 if (codeset)
Martin v. Löwis92fab752008-03-08 10:40:41 +0000628 return str2uni(codeset);
Gustavo Niemeyer7bd33c52004-07-22 18:44:01 +0000629 Py_RETURN_NONE;
630}
631#endif
632
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000633#endif
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000634
Guido van Rossum220ecc81997-11-18 21:03:39 +0000635static struct PyMethodDef PyLocale_Methods[] = {
Andrew M. Kuchlinge365fb82000-08-03 02:06:16 +0000636 {"setlocale", (PyCFunction) PyLocale_setlocale,
637 METH_VARARGS, setlocale__doc__},
638 {"localeconv", (PyCFunction) PyLocale_localeconv,
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000639 METH_NOARGS, localeconv__doc__},
Martin v. Löwis92fab752008-03-08 10:40:41 +0000640#ifdef HAVE_WCSCOLL
Andrew M. Kuchlinge365fb82000-08-03 02:06:16 +0000641 {"strcoll", (PyCFunction) PyLocale_strcoll,
642 METH_VARARGS, strcoll__doc__},
Martin v. Löwis92fab752008-03-08 10:40:41 +0000643#endif
644#ifdef HAVE_WCSXFRM
Andrew M. Kuchlinge365fb82000-08-03 02:06:16 +0000645 {"strxfrm", (PyCFunction) PyLocale_strxfrm,
646 METH_VARARGS, strxfrm__doc__},
Martin v. Löwis92fab752008-03-08 10:40:41 +0000647#endif
Martin v. Löwis52ea7e92002-11-26 09:05:36 +0000648#if defined(MS_WINDOWS) || defined(__APPLE__)
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000649 {"_getdefaultlocale", (PyCFunction) PyLocale_getdefaultlocale, METH_NOARGS},
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000650#endif
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000651#ifdef HAVE_LANGINFO_H
652 {"nl_langinfo", (PyCFunction) PyLocale_nl_langinfo,
653 METH_VARARGS, nl_langinfo__doc__},
654#endif
Martin v. Löwisc6a7d7e2002-05-02 12:16:29 +0000655#ifdef HAVE_LIBINTL_H
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000656 {"gettext",(PyCFunction)PyIntl_gettext,METH_VARARGS,
657 gettext__doc__},
658 {"dgettext",(PyCFunction)PyIntl_dgettext,METH_VARARGS,
659 dgettext__doc__},
660 {"dcgettext",(PyCFunction)PyIntl_dcgettext,METH_VARARGS,
661 dcgettext__doc__},
662 {"textdomain",(PyCFunction)PyIntl_textdomain,METH_VARARGS,
663 textdomain__doc__},
664 {"bindtextdomain",(PyCFunction)PyIntl_bindtextdomain,METH_VARARGS,
665 bindtextdomain__doc__},
Gustavo Niemeyer7bd33c52004-07-22 18:44:01 +0000666#ifdef HAVE_BIND_TEXTDOMAIN_CODESET
667 {"bind_textdomain_codeset",(PyCFunction)PyIntl_bind_textdomain_codeset,
668 METH_VARARGS, bind_textdomain_codeset__doc__},
669#endif
Martin v. Löwis2e64c342002-03-27 18:49:02 +0000670#endif
Guido van Rossum220ecc81997-11-18 21:03:39 +0000671 {NULL, NULL}
672};
673
Martin v. Löwis1a214512008-06-11 05:26:20 +0000674
675static struct PyModuleDef _localemodule = {
676 PyModuleDef_HEAD_INIT,
677 "_locale",
678 locale__doc__,
679 -1,
680 PyLocale_Methods,
681 NULL,
682 NULL,
683 NULL,
684 NULL
685};
686
Mark Hammondfe51c6d2002-08-02 02:27:13 +0000687PyMODINIT_FUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +0000688PyInit__locale(void)
Guido van Rossum220ecc81997-11-18 21:03:39 +0000689{
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000690 PyObject *m, *d, *x;
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000691#ifdef HAVE_LANGINFO_H
692 int i;
693#endif
Guido van Rossum220ecc81997-11-18 21:03:39 +0000694
Martin v. Löwis1a214512008-06-11 05:26:20 +0000695 m = PyModule_Create(&_localemodule);
Neal Norwitz1ac754f2006-01-19 06:09:39 +0000696 if (m == NULL)
Martin v. Löwis1a214512008-06-11 05:26:20 +0000697 return NULL;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000698
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000699 d = PyModule_GetDict(m);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000700
Christian Heimes217cfd12007-12-02 14:31:20 +0000701 x = PyLong_FromLong(LC_CTYPE);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000702 PyDict_SetItemString(d, "LC_CTYPE", x);
703 Py_XDECREF(x);
704
Christian Heimes217cfd12007-12-02 14:31:20 +0000705 x = PyLong_FromLong(LC_TIME);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000706 PyDict_SetItemString(d, "LC_TIME", x);
707 Py_XDECREF(x);
708
Christian Heimes217cfd12007-12-02 14:31:20 +0000709 x = PyLong_FromLong(LC_COLLATE);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000710 PyDict_SetItemString(d, "LC_COLLATE", x);
711 Py_XDECREF(x);
712
Christian Heimes217cfd12007-12-02 14:31:20 +0000713 x = PyLong_FromLong(LC_MONETARY);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000714 PyDict_SetItemString(d, "LC_MONETARY", x);
715 Py_XDECREF(x);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000716
Guido van Rossum8d9c2e31997-12-09 19:35:11 +0000717#ifdef LC_MESSAGES
Christian Heimes217cfd12007-12-02 14:31:20 +0000718 x = PyLong_FromLong(LC_MESSAGES);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000719 PyDict_SetItemString(d, "LC_MESSAGES", x);
720 Py_XDECREF(x);
Guido van Rossum8d9c2e31997-12-09 19:35:11 +0000721#endif /* LC_MESSAGES */
Guido van Rossum220ecc81997-11-18 21:03:39 +0000722
Christian Heimes217cfd12007-12-02 14:31:20 +0000723 x = PyLong_FromLong(LC_NUMERIC);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000724 PyDict_SetItemString(d, "LC_NUMERIC", x);
725 Py_XDECREF(x);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000726
Christian Heimes217cfd12007-12-02 14:31:20 +0000727 x = PyLong_FromLong(LC_ALL);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000728 PyDict_SetItemString(d, "LC_ALL", x);
729 Py_XDECREF(x);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000730
Christian Heimes217cfd12007-12-02 14:31:20 +0000731 x = PyLong_FromLong(CHAR_MAX);
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000732 PyDict_SetItemString(d, "CHAR_MAX", x);
733 Py_XDECREF(x);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000734
Fredrik Lundh8f017a02000-07-08 19:57:37 +0000735 Error = PyErr_NewException("locale.Error", NULL, NULL);
736 PyDict_SetItemString(d, "Error", Error);
Guido van Rossum220ecc81997-11-18 21:03:39 +0000737
Martin v. Löwis9b75dca2001-08-10 13:58:50 +0000738#ifdef HAVE_LANGINFO_H
Martin v. Löwisdc0b61d2002-03-12 22:05:02 +0000739 for (i = 0; langinfo_constants[i].name; i++) {
740 PyModule_AddIntConstant(m, langinfo_constants[i].name,
741 langinfo_constants[i].value);
742 }
Martin v. Löwisf95dd0a2001-08-15 17:14:33 +0000743#endif
Martin v. Löwis1a214512008-06-11 05:26:20 +0000744 return m;
Guido van Rossum220ecc81997-11-18 21:03:39 +0000745}
Martin v. Löwis9c36c292002-12-21 18:34:06 +0000746
747/*
748Local variables:
749c-basic-offset: 4
750indent-tabs-mode: nil
751End:
752*/