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 ******************************************************************/
22 #define WINDOWS_LEAN_AND_MEAN
30 static char locale__doc__
[] = "Support for POSIX locales.";
32 static PyObject
*Error
;
34 /* support functions for formatting floating point numbers */
36 static char setlocale__doc__
[] =
37 "(integer,string=None) -> string. Activates/queries locale processing."
40 /* to record the LC_NUMERIC settings */
41 static PyObject
* grouping
= NULL
;
42 static PyObject
* thousands_sep
= NULL
;
43 static PyObject
* decimal_point
= NULL
;
44 /* if non-null, indicates that LC_NUMERIC is different from "C" */
45 static char* saved_numeric
= NULL
;
47 /* the grouping is terminated by either 0 or CHAR_MAX */
49 copy_grouping(char* s
)
52 PyObject
*result
, *val
= NULL
;
55 /* empty string: no grouping at all */
58 for (i
= 0; s
[i
] != '\0' && s
[i
] != CHAR_MAX
; i
++)
61 result
= PyList_New(i
+1);
68 val
= PyInt_FromLong(s
[i
]);
71 if (PyList_SetItem(result
, i
, val
)) {
76 } while (s
[i
] != '\0' && s
[i
] != CHAR_MAX
);
89 PyObject
*mods
, *strop
, *string
, *ulo
;
90 unsigned char ul
[256];
93 /* find the string and strop modules */
94 mods
= PyImport_GetModuleDict();
97 string
= PyDict_GetItemString(mods
, "string");
99 string
= PyModule_GetDict(string
);
100 strop
=PyDict_GetItemString(mods
, "strop");
102 strop
= PyModule_GetDict(strop
);
103 if (!string
&& !strop
)
106 /* create uppercase map string */
108 for (c
= 0; c
< 256; c
++) {
112 ulo
= PyString_FromStringAndSize((const char *)ul
, n
);
116 PyDict_SetItemString(string
, "uppercase", ulo
);
118 PyDict_SetItemString(strop
, "uppercase", ulo
);
121 /* create lowercase string */
123 for (c
= 0; c
< 256; c
++) {
127 ulo
= PyString_FromStringAndSize((const char *)ul
, n
);
131 PyDict_SetItemString(string
, "lowercase", ulo
);
133 PyDict_SetItemString(strop
, "lowercase", ulo
);
136 /* create letters string */
138 for (c
= 0; c
< 256; c
++) {
142 ulo
= PyString_FromStringAndSize((const char *)ul
, n
);
146 PyDict_SetItemString(string
, "letters", ulo
);
152 PyLocale_setlocale(PyObject
* self
, PyObject
* args
)
155 char *locale
= NULL
, *result
;
156 PyObject
*result_object
;
159 if (!PyArg_ParseTuple(args
, "i|z:setlocale", &category
, &locale
))
164 result
= setlocale(category
, locale
);
166 /* operation failed, no setting was changed */
167 PyErr_SetString(Error
, "locale setting not supported");
170 result_object
= PyString_FromString(result
);
173 /* record changes to LC_NUMERIC */
174 if (category
== LC_NUMERIC
|| category
== LC_ALL
) {
175 if (strcmp(locale
, "C") == 0 || strcmp(locale
, "POSIX") == 0) {
176 /* user just asked for default numeric locale */
179 saved_numeric
= NULL
;
181 /* remember values */
183 Py_XDECREF(grouping
);
184 grouping
= copy_grouping(lc
->grouping
);
185 Py_XDECREF(thousands_sep
);
186 thousands_sep
= PyString_FromString(lc
->thousands_sep
);
187 Py_XDECREF(decimal_point
);
188 decimal_point
= PyString_FromString(lc
->decimal_point
);
189 saved_numeric
= strdup(locale
);
191 setlocale(LC_NUMERIC
, "C");
194 /* record changes to LC_CTYPE */
195 if (category
== LC_CTYPE
|| category
== LC_ALL
)
197 /* things that got wrong up to here are ignored */
201 /* restore LC_NUMERIC first, if appropriate */
203 setlocale(LC_NUMERIC
, saved_numeric
);
204 result
= setlocale(category
, NULL
);
206 PyErr_SetString(Error
, "locale query failed");
209 result_object
= PyString_FromString(result
);
210 /* restore back to "C" */
212 setlocale(LC_NUMERIC
, "C");
214 return result_object
;
217 static char localeconv__doc__
[] =
218 "() -> dict. Returns numeric and monetary locale-specific parameters."
222 PyLocale_localeconv(PyObject
* self
, PyObject
* args
)
228 if (!PyArg_NoArgs(args
))
231 result
= PyDict_New();
235 /* if LC_NUMERIC is different in the C library, use saved value */
238 /* hopefully, the localeconv result survives the C library calls
241 #define RESULT_STRING(s)\
242 x = PyString_FromString(l->s);\
243 if (!x) goto failed;\
244 PyDict_SetItemString(result, #s, x);\
247 #define RESULT_INT(i)\
248 x = PyInt_FromLong(l->i);\
249 if (!x) goto failed;\
250 PyDict_SetItemString(result, #i, x);\
253 /* Numeric information */
255 /* cannot use localeconv results */
256 PyDict_SetItemString(result
, "decimal_point", decimal_point
);
257 PyDict_SetItemString(result
, "grouping", grouping
);
258 PyDict_SetItemString(result
, "thousands_sep", thousands_sep
);
260 RESULT_STRING(decimal_point
);
261 RESULT_STRING(thousands_sep
);
262 x
= copy_grouping(l
->grouping
);
265 PyDict_SetItemString(result
, "grouping", x
);
269 /* Monetary information */
270 RESULT_STRING(int_curr_symbol
);
271 RESULT_STRING(currency_symbol
);
272 RESULT_STRING(mon_decimal_point
);
273 RESULT_STRING(mon_thousands_sep
);
274 x
= copy_grouping(l
->mon_grouping
);
277 PyDict_SetItemString(result
, "mon_grouping", x
);
279 RESULT_STRING(positive_sign
);
280 RESULT_STRING(negative_sign
);
281 RESULT_INT(int_frac_digits
);
282 RESULT_INT(frac_digits
);
283 RESULT_INT(p_cs_precedes
);
284 RESULT_INT(p_sep_by_space
);
285 RESULT_INT(n_cs_precedes
);
286 RESULT_INT(n_sep_by_space
);
287 RESULT_INT(p_sign_posn
);
288 RESULT_INT(n_sign_posn
);
297 static char strcoll__doc__
[] =
298 "string,string -> int. Compares two strings according to the locale."
302 PyLocale_strcoll(PyObject
* self
, PyObject
* args
)
306 if (!PyArg_ParseTuple(args
, "ss:strcoll", &s1
, &s2
))
308 return PyInt_FromLong(strcoll(s1
, s2
));
311 static char strxfrm__doc__
[] =
312 "string -> string. Returns a string that behaves for cmp locale-aware."
316 PyLocale_strxfrm(PyObject
* self
, PyObject
* args
)
322 if (!PyArg_ParseTuple(args
, "s:strxfrm", &s
))
325 /* assume no change in size, first */
327 buf
= PyMem_Malloc(n1
);
329 return PyErr_NoMemory();
330 n2
= strxfrm(buf
, s
, n1
);
332 /* more space needed */
333 buf
= PyMem_Realloc(buf
, n2
);
335 return PyErr_NoMemory();
338 result
= PyString_FromString(buf
);
343 #if defined(MS_WIN32)
345 PyLocale_getdefaultlocale(PyObject
* self
, PyObject
* args
)
350 if (!PyArg_NoArgs(args
))
353 sprintf(encoding
, "cp%d", GetACP());
355 if (GetLocaleInfo(LOCALE_USER_DEFAULT
,
356 LOCALE_SISO639LANGNAME
,
357 locale
, sizeof(locale
))) {
358 int i
= strlen(locale
);
360 if (GetLocaleInfo(LOCALE_USER_DEFAULT
,
361 LOCALE_SISO3166CTRYNAME
,
362 locale
+i
, sizeof(locale
)-i
))
363 return Py_BuildValue("ss", locale
, encoding
);
366 /* If we end up here, this windows version didn't know about
367 ISO639/ISO3166 names (it's probably Windows 95). Return the
368 Windows language identifier instead (a hexadecimal number) */
372 if (GetLocaleInfo(LOCALE_USER_DEFAULT
, LOCALE_IDEFAULTLANGUAGE
,
373 locale
+2, sizeof(locale
)-2)) {
374 return Py_BuildValue("ss", locale
, encoding
);
377 /* cannot determine the language code (very unlikely) */
379 return Py_BuildValue("Os", Py_None
, encoding
);
383 #if defined(macintosh)
385 PyLocale_getdefaultlocale(PyObject
* self
, PyObject
* args
)
387 return Py_BuildValue("Os", Py_None
, PyMac_getscript());
391 static struct PyMethodDef PyLocale_Methods
[] = {
392 {"setlocale", (PyCFunction
) PyLocale_setlocale
,
393 METH_VARARGS
, setlocale__doc__
},
394 {"localeconv", (PyCFunction
) PyLocale_localeconv
,
395 0, localeconv__doc__
},
396 {"strcoll", (PyCFunction
) PyLocale_strcoll
,
397 METH_VARARGS
, strcoll__doc__
},
398 {"strxfrm", (PyCFunction
) PyLocale_strxfrm
,
399 METH_VARARGS
, strxfrm__doc__
},
400 #if defined(MS_WIN32) || defined(macintosh)
401 {"_getdefaultlocale", (PyCFunction
) PyLocale_getdefaultlocale
, 0},
411 m
= Py_InitModule("_locale", PyLocale_Methods
);
413 d
= PyModule_GetDict(m
);
415 x
= PyInt_FromLong(LC_CTYPE
);
416 PyDict_SetItemString(d
, "LC_CTYPE", x
);
419 x
= PyInt_FromLong(LC_TIME
);
420 PyDict_SetItemString(d
, "LC_TIME", x
);
423 x
= PyInt_FromLong(LC_COLLATE
);
424 PyDict_SetItemString(d
, "LC_COLLATE", x
);
427 x
= PyInt_FromLong(LC_MONETARY
);
428 PyDict_SetItemString(d
, "LC_MONETARY", x
);
432 x
= PyInt_FromLong(LC_MESSAGES
);
433 PyDict_SetItemString(d
, "LC_MESSAGES", x
);
435 #endif /* LC_MESSAGES */
437 x
= PyInt_FromLong(LC_NUMERIC
);
438 PyDict_SetItemString(d
, "LC_NUMERIC", x
);
441 x
= PyInt_FromLong(LC_ALL
);
442 PyDict_SetItemString(d
, "LC_ALL", x
);
445 x
= PyInt_FromLong(CHAR_MAX
);
446 PyDict_SetItemString(d
, "CHAR_MAX", x
);
449 Error
= PyErr_NewException("locale.Error", NULL
, NULL
);
450 PyDict_SetItemString(d
, "Error", Error
);
452 x
= PyString_FromString(locale__doc__
);
453 PyDict_SetItemString(d
, "__doc__", x
);
456 if (PyErr_Occurred())
457 Py_FatalError("Can't initialize module locale");