1 /***********************************************************
2 Copyright (C) 1997 Martin von Loewis
4 Permission to use, copy, modify, and distribute this software and its
5 documentation for any purpose and without fee is hereby granted,
6 provided that the above copyright notice appear in all copies.
8 This software comes with no warranty. Use at your own risk.
10 ******************************************************************/
21 #define WINDOWS_LEAN_AND_MEAN
30 char *strdup(const char *);
33 static char locale__doc__
[] = "Support for POSIX locales.";
35 static PyObject
*Error
;
37 /* support functions for formatting floating point numbers */
39 static char setlocale__doc__
[] =
40 "(integer,string=None) -> string. Activates/queries locale processing."
43 /* to record the LC_NUMERIC settings */
44 static PyObject
* grouping
= NULL
;
45 static PyObject
* thousands_sep
= NULL
;
46 static PyObject
* decimal_point
= NULL
;
47 /* if non-null, indicates that LC_NUMERIC is different from "C" */
48 static char* saved_numeric
= NULL
;
50 /* the grouping is terminated by either 0 or CHAR_MAX */
52 copy_grouping(char* s
)
55 PyObject
*result
, *val
= NULL
;
58 /* empty string: no grouping at all */
61 for (i
= 0; s
[i
] != '\0' && s
[i
] != CHAR_MAX
; i
++)
64 result
= PyList_New(i
+1);
71 val
= PyInt_FromLong(s
[i
]);
74 if (PyList_SetItem(result
, i
, val
)) {
79 } while (s
[i
] != '\0' && s
[i
] != CHAR_MAX
);
92 PyObject
*mods
, *strop
, *string
, *ulo
;
93 unsigned char ul
[256];
96 /* find the string and strop modules */
97 mods
= PyImport_GetModuleDict();
100 string
= PyDict_GetItemString(mods
, "string");
102 string
= PyModule_GetDict(string
);
103 strop
=PyDict_GetItemString(mods
, "strop");
105 strop
= PyModule_GetDict(strop
);
106 if (!string
&& !strop
)
109 /* create uppercase map string */
111 for (c
= 0; c
< 256; c
++) {
115 ulo
= PyString_FromStringAndSize((const char *)ul
, n
);
119 PyDict_SetItemString(string
, "uppercase", ulo
);
121 PyDict_SetItemString(strop
, "uppercase", ulo
);
124 /* create lowercase string */
126 for (c
= 0; c
< 256; c
++) {
130 ulo
= PyString_FromStringAndSize((const char *)ul
, n
);
134 PyDict_SetItemString(string
, "lowercase", ulo
);
136 PyDict_SetItemString(strop
, "lowercase", ulo
);
139 /* create letters string */
141 for (c
= 0; c
< 256; c
++) {
145 ulo
= PyString_FromStringAndSize((const char *)ul
, n
);
149 PyDict_SetItemString(string
, "letters", ulo
);
155 PyLocale_setlocale(PyObject
* self
, PyObject
* args
)
158 char *locale
= NULL
, *result
;
159 PyObject
*result_object
;
162 if (!PyArg_ParseTuple(args
, "i|z:setlocale", &category
, &locale
))
167 result
= setlocale(category
, locale
);
169 /* operation failed, no setting was changed */
170 PyErr_SetString(Error
, "locale setting not supported");
173 result_object
= PyString_FromString(result
);
176 /* record changes to LC_NUMERIC */
177 if (category
== LC_NUMERIC
|| category
== LC_ALL
) {
178 if (strcmp(locale
, "C") == 0 || strcmp(locale
, "POSIX") == 0) {
179 /* user just asked for default numeric locale */
182 saved_numeric
= NULL
;
184 /* remember values */
186 Py_XDECREF(grouping
);
187 grouping
= copy_grouping(lc
->grouping
);
188 Py_XDECREF(thousands_sep
);
189 thousands_sep
= PyString_FromString(lc
->thousands_sep
);
190 Py_XDECREF(decimal_point
);
191 decimal_point
= PyString_FromString(lc
->decimal_point
);
192 saved_numeric
= strdup(locale
);
194 setlocale(LC_NUMERIC
, "C");
197 /* record changes to LC_CTYPE */
198 if (category
== LC_CTYPE
|| category
== LC_ALL
)
200 /* things that got wrong up to here are ignored */
204 /* restore LC_NUMERIC first, if appropriate */
206 setlocale(LC_NUMERIC
, saved_numeric
);
207 result
= setlocale(category
, NULL
);
209 PyErr_SetString(Error
, "locale query failed");
212 result_object
= PyString_FromString(result
);
213 /* restore back to "C" */
215 setlocale(LC_NUMERIC
, "C");
217 return result_object
;
220 static char localeconv__doc__
[] =
221 "() -> dict. Returns numeric and monetary locale-specific parameters."
225 PyLocale_localeconv(PyObject
* self
, PyObject
* args
)
231 if (!PyArg_NoArgs(args
))
234 result
= PyDict_New();
238 /* if LC_NUMERIC is different in the C library, use saved value */
241 /* hopefully, the localeconv result survives the C library calls
244 #define RESULT_STRING(s)\
245 x = PyString_FromString(l->s);\
246 if (!x) goto failed;\
247 PyDict_SetItemString(result, #s, x);\
250 #define RESULT_INT(i)\
251 x = PyInt_FromLong(l->i);\
252 if (!x) goto failed;\
253 PyDict_SetItemString(result, #i, x);\
256 /* Numeric information */
258 /* cannot use localeconv results */
259 PyDict_SetItemString(result
, "decimal_point", decimal_point
);
260 PyDict_SetItemString(result
, "grouping", grouping
);
261 PyDict_SetItemString(result
, "thousands_sep", thousands_sep
);
263 RESULT_STRING(decimal_point
);
264 RESULT_STRING(thousands_sep
);
265 x
= copy_grouping(l
->grouping
);
268 PyDict_SetItemString(result
, "grouping", x
);
272 /* Monetary information */
273 RESULT_STRING(int_curr_symbol
);
274 RESULT_STRING(currency_symbol
);
275 RESULT_STRING(mon_decimal_point
);
276 RESULT_STRING(mon_thousands_sep
);
277 x
= copy_grouping(l
->mon_grouping
);
280 PyDict_SetItemString(result
, "mon_grouping", x
);
282 RESULT_STRING(positive_sign
);
283 RESULT_STRING(negative_sign
);
284 RESULT_INT(int_frac_digits
);
285 RESULT_INT(frac_digits
);
286 RESULT_INT(p_cs_precedes
);
287 RESULT_INT(p_sep_by_space
);
288 RESULT_INT(n_cs_precedes
);
289 RESULT_INT(n_sep_by_space
);
290 RESULT_INT(p_sign_posn
);
291 RESULT_INT(n_sign_posn
);
300 static char strcoll__doc__
[] =
301 "string,string -> int. Compares two strings according to the locale."
305 PyLocale_strcoll(PyObject
* self
, PyObject
* args
)
309 if (!PyArg_ParseTuple(args
, "ss:strcoll", &s1
, &s2
))
311 return PyInt_FromLong(strcoll(s1
, s2
));
314 static char strxfrm__doc__
[] =
315 "string -> string. Returns a string that behaves for cmp locale-aware."
319 PyLocale_strxfrm(PyObject
* self
, PyObject
* args
)
325 if (!PyArg_ParseTuple(args
, "s:strxfrm", &s
))
328 /* assume no change in size, first */
330 buf
= PyMem_Malloc(n1
);
332 return PyErr_NoMemory();
333 n2
= strxfrm(buf
, s
, n1
);
335 /* more space needed */
336 buf
= PyMem_Realloc(buf
, n2
);
338 return PyErr_NoMemory();
341 result
= PyString_FromString(buf
);
346 #if defined(MS_WIN32)
348 PyLocale_getdefaultlocale(PyObject
* self
, PyObject
* args
)
353 if (!PyArg_NoArgs(args
))
356 sprintf(encoding
, "cp%d", GetACP());
358 if (GetLocaleInfo(LOCALE_USER_DEFAULT
,
359 LOCALE_SISO639LANGNAME
,
360 locale
, sizeof(locale
))) {
361 int i
= strlen(locale
);
363 if (GetLocaleInfo(LOCALE_USER_DEFAULT
,
364 LOCALE_SISO3166CTRYNAME
,
365 locale
+i
, sizeof(locale
)-i
))
366 return Py_BuildValue("ss", locale
, encoding
);
369 /* If we end up here, this windows version didn't know about
370 ISO639/ISO3166 names (it's probably Windows 95). Return the
371 Windows language identifier instead (a hexadecimal number) */
375 if (GetLocaleInfo(LOCALE_USER_DEFAULT
, LOCALE_IDEFAULTLANGUAGE
,
376 locale
+2, sizeof(locale
)-2)) {
377 return Py_BuildValue("ss", locale
, encoding
);
380 /* cannot determine the language code (very unlikely) */
382 return Py_BuildValue("Os", Py_None
, encoding
);
386 #if defined(macintosh)
388 PyLocale_getdefaultlocale(PyObject
* self
, PyObject
* args
)
390 return Py_BuildValue("Os", Py_None
, PyMac_getscript());
394 static struct PyMethodDef PyLocale_Methods
[] = {
395 {"setlocale", (PyCFunction
) PyLocale_setlocale
,
396 METH_VARARGS
, setlocale__doc__
},
397 {"localeconv", (PyCFunction
) PyLocale_localeconv
,
398 0, localeconv__doc__
},
399 {"strcoll", (PyCFunction
) PyLocale_strcoll
,
400 METH_VARARGS
, strcoll__doc__
},
401 {"strxfrm", (PyCFunction
) PyLocale_strxfrm
,
402 METH_VARARGS
, strxfrm__doc__
},
403 #if defined(MS_WIN32) || defined(macintosh)
404 {"_getdefaultlocale", (PyCFunction
) PyLocale_getdefaultlocale
, 0},
414 m
= Py_InitModule("_locale", PyLocale_Methods
);
416 d
= PyModule_GetDict(m
);
418 x
= PyInt_FromLong(LC_CTYPE
);
419 PyDict_SetItemString(d
, "LC_CTYPE", x
);
422 x
= PyInt_FromLong(LC_TIME
);
423 PyDict_SetItemString(d
, "LC_TIME", x
);
426 x
= PyInt_FromLong(LC_COLLATE
);
427 PyDict_SetItemString(d
, "LC_COLLATE", x
);
430 x
= PyInt_FromLong(LC_MONETARY
);
431 PyDict_SetItemString(d
, "LC_MONETARY", x
);
435 x
= PyInt_FromLong(LC_MESSAGES
);
436 PyDict_SetItemString(d
, "LC_MESSAGES", x
);
438 #endif /* LC_MESSAGES */
440 x
= PyInt_FromLong(LC_NUMERIC
);
441 PyDict_SetItemString(d
, "LC_NUMERIC", x
);
444 x
= PyInt_FromLong(LC_ALL
);
445 PyDict_SetItemString(d
, "LC_ALL", x
);
448 x
= PyInt_FromLong(CHAR_MAX
);
449 PyDict_SetItemString(d
, "CHAR_MAX", x
);
452 Error
= PyErr_NewException("locale.Error", NULL
, NULL
);
453 PyDict_SetItemString(d
, "Error", Error
);
455 x
= PyString_FromString(locale__doc__
);
456 PyDict_SetItemString(d
, "__doc__", x
);