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
29 static char locale__doc__
[] = "Support for POSIX locales.";
31 static PyObject
*Error
;
33 /* support functions for formatting floating point numbers */
35 static char setlocale__doc__
[] =
36 "(integer,string=None) -> string. Activates/queries locale processing."
39 /* to record the LC_NUMERIC settings */
40 static PyObject
* grouping
= NULL
;
41 static PyObject
* thousands_sep
= NULL
;
42 static PyObject
* decimal_point
= NULL
;
43 /* if non-null, indicates that LC_NUMERIC is different from "C" */
44 static char* saved_numeric
= NULL
;
46 /* the grouping is terminated by either 0 or CHAR_MAX */
48 copy_grouping(char* s
)
51 PyObject
*result
, *val
= NULL
;
54 /* empty string: no grouping at all */
57 for (i
= 0; s
[i
] != '\0' && s
[i
] != CHAR_MAX
; i
++)
60 result
= PyList_New(i
+1);
67 val
= PyInt_FromLong(s
[i
]);
70 if (PyList_SetItem(result
, i
, val
)) {
75 } while (s
[i
] != '\0' && s
[i
] != CHAR_MAX
);
88 PyObject
*mods
, *strop
, *string
, *ulo
;
89 unsigned char ul
[256];
92 /* find the string and strop modules */
93 mods
= PyImport_GetModuleDict();
96 string
= PyDict_GetItemString(mods
, "string");
98 string
= PyModule_GetDict(string
);
99 strop
=PyDict_GetItemString(mods
, "strop");
101 strop
= PyModule_GetDict(strop
);
102 if (!string
&& !strop
)
105 /* create uppercase map string */
107 for (c
= 0; c
< 256; c
++) {
111 ulo
= PyString_FromStringAndSize((const char *)ul
, n
);
115 PyDict_SetItemString(string
, "uppercase", ulo
);
117 PyDict_SetItemString(strop
, "uppercase", ulo
);
120 /* create lowercase string */
122 for (c
= 0; c
< 256; c
++) {
126 ulo
= PyString_FromStringAndSize((const char *)ul
, n
);
130 PyDict_SetItemString(string
, "lowercase", ulo
);
132 PyDict_SetItemString(strop
, "lowercase", ulo
);
135 /* create letters string */
137 for (c
= 0; c
< 256; c
++) {
141 ulo
= PyString_FromStringAndSize((const char *)ul
, n
);
145 PyDict_SetItemString(string
, "letters", ulo
);
151 PyLocale_setlocale(PyObject
* self
, PyObject
* args
)
154 char *locale
= NULL
, *result
;
155 PyObject
*result_object
;
158 if (!PyArg_ParseTuple(args
, "i|z:setlocale", &category
, &locale
))
163 result
= setlocale(category
, locale
);
165 /* operation failed, no setting was changed */
166 PyErr_SetString(Error
, "locale setting not supported");
169 result_object
= PyString_FromString(result
);
172 /* record changes to LC_NUMERIC */
173 if (category
== LC_NUMERIC
|| category
== LC_ALL
) {
174 if (strcmp(locale
, "C") == 0 || strcmp(locale
, "POSIX") == 0) {
175 /* user just asked for default numeric locale */
178 saved_numeric
= NULL
;
180 /* remember values */
182 Py_XDECREF(grouping
);
183 grouping
= copy_grouping(lc
->grouping
);
184 Py_XDECREF(thousands_sep
);
185 thousands_sep
= PyString_FromString(lc
->thousands_sep
);
186 Py_XDECREF(decimal_point
);
187 decimal_point
= PyString_FromString(lc
->decimal_point
);
188 saved_numeric
= strdup(locale
);
190 setlocale(LC_NUMERIC
, "C");
193 /* record changes to LC_CTYPE */
194 if (category
== LC_CTYPE
|| category
== LC_ALL
)
196 /* things that got wrong up to here are ignored */
200 /* restore LC_NUMERIC first, if appropriate */
202 setlocale(LC_NUMERIC
, saved_numeric
);
203 result
= setlocale(category
, NULL
);
205 PyErr_SetString(Error
, "locale query failed");
208 result_object
= PyString_FromString(result
);
209 /* restore back to "C" */
211 setlocale(LC_NUMERIC
, "C");
213 return result_object
;
216 static char localeconv__doc__
[] =
217 "() -> dict. Returns numeric and monetary locale-specific parameters."
221 PyLocale_localeconv(PyObject
* self
, PyObject
* args
)
227 if (!PyArg_NoArgs(args
))
230 result
= PyDict_New();
234 /* if LC_NUMERIC is different in the C library, use saved value */
237 /* hopefully, the localeconv result survives the C library calls
240 #define RESULT_STRING(s)\
241 x = PyString_FromString(l->s);\
242 if (!x) goto failed;\
243 PyDict_SetItemString(result, #s, x);\
246 #define RESULT_INT(i)\
247 x = PyInt_FromLong(l->i);\
248 if (!x) goto failed;\
249 PyDict_SetItemString(result, #i, x);\
252 /* Numeric information */
254 /* cannot use localeconv results */
255 PyDict_SetItemString(result
, "decimal_point", decimal_point
);
256 PyDict_SetItemString(result
, "grouping", grouping
);
257 PyDict_SetItemString(result
, "thousands_sep", thousands_sep
);
259 RESULT_STRING(decimal_point
);
260 RESULT_STRING(thousands_sep
);
261 x
= copy_grouping(l
->grouping
);
264 PyDict_SetItemString(result
, "grouping", x
);
268 /* Monetary information */
269 RESULT_STRING(int_curr_symbol
);
270 RESULT_STRING(currency_symbol
);
271 RESULT_STRING(mon_decimal_point
);
272 RESULT_STRING(mon_thousands_sep
);
273 x
= copy_grouping(l
->mon_grouping
);
276 PyDict_SetItemString(result
, "mon_grouping", x
);
278 RESULT_STRING(positive_sign
);
279 RESULT_STRING(negative_sign
);
280 RESULT_INT(int_frac_digits
);
281 RESULT_INT(frac_digits
);
282 RESULT_INT(p_cs_precedes
);
283 RESULT_INT(p_sep_by_space
);
284 RESULT_INT(n_cs_precedes
);
285 RESULT_INT(n_sep_by_space
);
286 RESULT_INT(p_sign_posn
);
287 RESULT_INT(n_sign_posn
);
296 static char strcoll__doc__
[] =
297 "string,string -> int. Compares two strings according to the locale."
301 PyLocale_strcoll(PyObject
* self
, PyObject
* args
)
305 if (!PyArg_ParseTuple(args
, "ss:strcoll", &s1
, &s2
))
307 return PyInt_FromLong(strcoll(s1
, s2
));
310 static char strxfrm__doc__
[] =
311 "string -> string. Returns a string that behaves for cmp locale-aware."
315 PyLocale_strxfrm(PyObject
* self
, PyObject
* args
)
321 if (!PyArg_ParseTuple(args
, "s:strxfrm", &s
))
324 /* assume no change in size, first */
326 buf
= PyMem_Malloc(n1
);
328 return PyErr_NoMemory();
329 n2
= strxfrm(buf
, s
, n1
);
331 /* more space needed */
332 buf
= PyMem_Realloc(buf
, n2
);
334 return PyErr_NoMemory();
337 result
= PyString_FromString(buf
);
342 #if defined(MS_WIN32)
344 PyLocale_getdefaultlocale(PyObject
* self
, PyObject
* args
)
349 if (!PyArg_NoArgs(args
))
352 sprintf(encoding
, "cp%d", GetACP());
354 if (GetLocaleInfo(LOCALE_USER_DEFAULT
,
355 LOCALE_SISO639LANGNAME
,
356 locale
, sizeof(locale
))) {
357 int i
= strlen(locale
);
359 if (GetLocaleInfo(LOCALE_USER_DEFAULT
,
360 LOCALE_SISO3166CTRYNAME
,
361 locale
+i
, sizeof(locale
)-i
))
362 return Py_BuildValue("ss", locale
, encoding
);
365 /* If we end up here, this windows version didn't know about
366 ISO639/ISO3166 names (it's probably Windows 95). Return the
367 Windows language identifier instead (a hexadecimal number) */
371 if (GetLocaleInfo(LOCALE_USER_DEFAULT
, LOCALE_IDEFAULTLANGUAGE
,
372 locale
+2, sizeof(locale
)-2)) {
373 return Py_BuildValue("ss", locale
, encoding
);
376 /* cannot determine the language code (very unlikely) */
378 return Py_BuildValue("Os", Py_None
, encoding
);
382 #if defined(macintosh)
384 PyLocale_getdefaultlocale(PyObject
* self
, PyObject
* args
)
386 return Py_BuildValue("Os", Py_None
, PyMac_getscript());
390 static struct PyMethodDef PyLocale_Methods
[] = {
391 {"setlocale", (PyCFunction
) PyLocale_setlocale
,
392 METH_VARARGS
, setlocale__doc__
},
393 {"localeconv", (PyCFunction
) PyLocale_localeconv
,
394 0, localeconv__doc__
},
395 {"strcoll", (PyCFunction
) PyLocale_strcoll
,
396 METH_VARARGS
, strcoll__doc__
},
397 {"strxfrm", (PyCFunction
) PyLocale_strxfrm
,
398 METH_VARARGS
, strxfrm__doc__
},
399 #if defined(MS_WIN32) || defined(macintosh)
400 {"_getdefaultlocale", (PyCFunction
) PyLocale_getdefaultlocale
, 0},
410 m
= Py_InitModule("_locale", PyLocale_Methods
);
412 d
= PyModule_GetDict(m
);
414 x
= PyInt_FromLong(LC_CTYPE
);
415 PyDict_SetItemString(d
, "LC_CTYPE", x
);
418 x
= PyInt_FromLong(LC_TIME
);
419 PyDict_SetItemString(d
, "LC_TIME", x
);
422 x
= PyInt_FromLong(LC_COLLATE
);
423 PyDict_SetItemString(d
, "LC_COLLATE", x
);
426 x
= PyInt_FromLong(LC_MONETARY
);
427 PyDict_SetItemString(d
, "LC_MONETARY", x
);
431 x
= PyInt_FromLong(LC_MESSAGES
);
432 PyDict_SetItemString(d
, "LC_MESSAGES", x
);
434 #endif /* LC_MESSAGES */
436 x
= PyInt_FromLong(LC_NUMERIC
);
437 PyDict_SetItemString(d
, "LC_NUMERIC", x
);
440 x
= PyInt_FromLong(LC_ALL
);
441 PyDict_SetItemString(d
, "LC_ALL", x
);
444 x
= PyInt_FromLong(CHAR_MAX
);
445 PyDict_SetItemString(d
, "CHAR_MAX", x
);
448 Error
= PyErr_NewException("locale.Error", NULL
, NULL
);
449 PyDict_SetItemString(d
, "Error", Error
);
451 x
= PyString_FromString(locale__doc__
);
452 PyDict_SetItemString(d
, "__doc__", x
);