|
1 /*********************************************************** |
|
2 Copyright (C) 1997, 2002, 2003 Martin von Loewis |
|
3 |
|
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. |
|
7 |
|
8 This software comes with no warranty. Use at your own risk. |
|
9 |
|
10 ******************************************************************/ |
|
11 |
|
12 #include "Python.h" |
|
13 |
|
14 #include <stdio.h> |
|
15 #include <locale.h> |
|
16 #include <string.h> |
|
17 #include <ctype.h> |
|
18 |
|
19 #ifdef HAVE_ERRNO_H |
|
20 #include <errno.h> |
|
21 #endif |
|
22 |
|
23 #ifdef HAVE_LANGINFO_H |
|
24 #include <langinfo.h> |
|
25 #endif |
|
26 |
|
27 #ifdef HAVE_LIBINTL_H |
|
28 #include <libintl.h> |
|
29 #endif |
|
30 |
|
31 #ifdef HAVE_WCHAR_H |
|
32 #include <wchar.h> |
|
33 #endif |
|
34 |
|
35 #if defined(__APPLE__) |
|
36 #include <CoreFoundation/CoreFoundation.h> |
|
37 #endif |
|
38 |
|
39 #if defined(MS_WINDOWS) |
|
40 #define WIN32_LEAN_AND_MEAN |
|
41 #include <windows.h> |
|
42 #endif |
|
43 |
|
44 #ifdef RISCOS |
|
45 char *strdup(const char *); |
|
46 #endif |
|
47 |
|
48 PyDoc_STRVAR(locale__doc__, "Support for POSIX locales."); |
|
49 |
|
50 static PyObject *Error; |
|
51 |
|
52 /* support functions for formatting floating point numbers */ |
|
53 |
|
54 PyDoc_STRVAR(setlocale__doc__, |
|
55 "(integer,string=None) -> string. Activates/queries locale processing."); |
|
56 |
|
57 /* the grouping is terminated by either 0 or CHAR_MAX */ |
|
58 static PyObject* |
|
59 copy_grouping(char* s) |
|
60 { |
|
61 int i; |
|
62 PyObject *result, *val = NULL; |
|
63 |
|
64 if (s[0] == '\0') |
|
65 /* empty string: no grouping at all */ |
|
66 return PyList_New(0); |
|
67 |
|
68 for (i = 0; s[i] != '\0' && s[i] != CHAR_MAX; i++) |
|
69 ; /* nothing */ |
|
70 |
|
71 result = PyList_New(i+1); |
|
72 if (!result) |
|
73 return NULL; |
|
74 |
|
75 i = -1; |
|
76 do { |
|
77 i++; |
|
78 val = PyInt_FromLong(s[i]); |
|
79 if (!val) |
|
80 break; |
|
81 if (PyList_SetItem(result, i, val)) { |
|
82 Py_DECREF(val); |
|
83 val = NULL; |
|
84 break; |
|
85 } |
|
86 } while (s[i] != '\0' && s[i] != CHAR_MAX); |
|
87 |
|
88 if (!val) { |
|
89 Py_DECREF(result); |
|
90 return NULL; |
|
91 } |
|
92 |
|
93 return result; |
|
94 } |
|
95 |
|
96 static void |
|
97 fixup_ulcase(void) |
|
98 { |
|
99 PyObject *mods, *strop, *string, *ulo; |
|
100 unsigned char ul[256]; |
|
101 int n, c; |
|
102 |
|
103 /* find the string and strop modules */ |
|
104 mods = PyImport_GetModuleDict(); |
|
105 if (!mods) |
|
106 return; |
|
107 string = PyDict_GetItemString(mods, "string"); |
|
108 if (string) |
|
109 string = PyModule_GetDict(string); |
|
110 strop=PyDict_GetItemString(mods, "strop"); |
|
111 if (strop) |
|
112 strop = PyModule_GetDict(strop); |
|
113 if (!string && !strop) |
|
114 return; |
|
115 |
|
116 /* create uppercase map string */ |
|
117 n = 0; |
|
118 for (c = 0; c < 256; c++) { |
|
119 if (isupper(c)) |
|
120 ul[n++] = c; |
|
121 } |
|
122 ulo = PyString_FromStringAndSize((const char *)ul, n); |
|
123 if (!ulo) |
|
124 return; |
|
125 if (string) |
|
126 PyDict_SetItemString(string, "uppercase", ulo); |
|
127 if (strop) |
|
128 PyDict_SetItemString(strop, "uppercase", ulo); |
|
129 Py_DECREF(ulo); |
|
130 |
|
131 /* create lowercase string */ |
|
132 n = 0; |
|
133 for (c = 0; c < 256; c++) { |
|
134 if (islower(c)) |
|
135 ul[n++] = c; |
|
136 } |
|
137 ulo = PyString_FromStringAndSize((const char *)ul, n); |
|
138 if (!ulo) |
|
139 return; |
|
140 if (string) |
|
141 PyDict_SetItemString(string, "lowercase", ulo); |
|
142 if (strop) |
|
143 PyDict_SetItemString(strop, "lowercase", ulo); |
|
144 Py_DECREF(ulo); |
|
145 |
|
146 /* create letters string */ |
|
147 n = 0; |
|
148 for (c = 0; c < 256; c++) { |
|
149 if (isalpha(c)) |
|
150 ul[n++] = c; |
|
151 } |
|
152 ulo = PyString_FromStringAndSize((const char *)ul, n); |
|
153 if (!ulo) |
|
154 return; |
|
155 if (string) |
|
156 PyDict_SetItemString(string, "letters", ulo); |
|
157 Py_DECREF(ulo); |
|
158 } |
|
159 |
|
160 static PyObject* |
|
161 PyLocale_setlocale(PyObject* self, PyObject* args) |
|
162 { |
|
163 int category; |
|
164 char *locale = NULL, *result; |
|
165 PyObject *result_object; |
|
166 |
|
167 if (!PyArg_ParseTuple(args, "i|z:setlocale", &category, &locale)) |
|
168 return NULL; |
|
169 |
|
170 if (locale) { |
|
171 /* set locale */ |
|
172 result = setlocale(category, locale); |
|
173 if (!result) { |
|
174 /* operation failed, no setting was changed */ |
|
175 PyErr_SetString(Error, "unsupported locale setting"); |
|
176 return NULL; |
|
177 } |
|
178 result_object = PyString_FromString(result); |
|
179 if (!result_object) |
|
180 return NULL; |
|
181 /* record changes to LC_CTYPE */ |
|
182 if (category == LC_CTYPE || category == LC_ALL) |
|
183 fixup_ulcase(); |
|
184 /* things that got wrong up to here are ignored */ |
|
185 PyErr_Clear(); |
|
186 } else { |
|
187 /* get locale */ |
|
188 result = setlocale(category, NULL); |
|
189 if (!result) { |
|
190 PyErr_SetString(Error, "locale query failed"); |
|
191 return NULL; |
|
192 } |
|
193 result_object = PyString_FromString(result); |
|
194 } |
|
195 return result_object; |
|
196 } |
|
197 |
|
198 PyDoc_STRVAR(localeconv__doc__, |
|
199 "() -> dict. Returns numeric and monetary locale-specific parameters."); |
|
200 |
|
201 static PyObject* |
|
202 PyLocale_localeconv(PyObject* self) |
|
203 { |
|
204 PyObject* result; |
|
205 struct lconv *l; |
|
206 PyObject *x; |
|
207 |
|
208 result = PyDict_New(); |
|
209 if (!result) |
|
210 return NULL; |
|
211 |
|
212 /* if LC_NUMERIC is different in the C library, use saved value */ |
|
213 l = localeconv(); |
|
214 |
|
215 /* hopefully, the localeconv result survives the C library calls |
|
216 involved herein */ |
|
217 |
|
218 #define RESULT_STRING(s)\ |
|
219 x = PyString_FromString(l->s);\ |
|
220 if (!x) goto failed;\ |
|
221 PyDict_SetItemString(result, #s, x);\ |
|
222 Py_XDECREF(x) |
|
223 |
|
224 #define RESULT_INT(i)\ |
|
225 x = PyInt_FromLong(l->i);\ |
|
226 if (!x) goto failed;\ |
|
227 PyDict_SetItemString(result, #i, x);\ |
|
228 Py_XDECREF(x) |
|
229 |
|
230 /* Numeric information */ |
|
231 RESULT_STRING(decimal_point); |
|
232 RESULT_STRING(thousands_sep); |
|
233 x = copy_grouping(l->grouping); |
|
234 if (!x) |
|
235 goto failed; |
|
236 PyDict_SetItemString(result, "grouping", x); |
|
237 Py_XDECREF(x); |
|
238 |
|
239 /* Monetary information */ |
|
240 RESULT_STRING(int_curr_symbol); |
|
241 RESULT_STRING(currency_symbol); |
|
242 RESULT_STRING(mon_decimal_point); |
|
243 RESULT_STRING(mon_thousands_sep); |
|
244 x = copy_grouping(l->mon_grouping); |
|
245 if (!x) |
|
246 goto failed; |
|
247 PyDict_SetItemString(result, "mon_grouping", x); |
|
248 Py_XDECREF(x); |
|
249 RESULT_STRING(positive_sign); |
|
250 RESULT_STRING(negative_sign); |
|
251 RESULT_INT(int_frac_digits); |
|
252 RESULT_INT(frac_digits); |
|
253 RESULT_INT(p_cs_precedes); |
|
254 RESULT_INT(p_sep_by_space); |
|
255 RESULT_INT(n_cs_precedes); |
|
256 RESULT_INT(n_sep_by_space); |
|
257 RESULT_INT(p_sign_posn); |
|
258 RESULT_INT(n_sign_posn); |
|
259 return result; |
|
260 |
|
261 failed: |
|
262 Py_XDECREF(result); |
|
263 Py_XDECREF(x); |
|
264 return NULL; |
|
265 } |
|
266 |
|
267 PyDoc_STRVAR(strcoll__doc__, |
|
268 "string,string -> int. Compares two strings according to the locale."); |
|
269 |
|
270 static PyObject* |
|
271 PyLocale_strcoll(PyObject* self, PyObject* args) |
|
272 { |
|
273 #if !defined(HAVE_WCSCOLL) || !defined(Py_USING_UNICODE) |
|
274 char *s1,*s2; |
|
275 |
|
276 if (!PyArg_ParseTuple(args, "ss:strcoll", &s1, &s2)) |
|
277 return NULL; |
|
278 return PyInt_FromLong(strcoll(s1, s2)); |
|
279 #else |
|
280 PyObject *os1, *os2, *result = NULL; |
|
281 wchar_t *ws1 = NULL, *ws2 = NULL; |
|
282 int rel1 = 0, rel2 = 0, len1, len2; |
|
283 |
|
284 if (!PyArg_UnpackTuple(args, "strcoll", 2, 2, &os1, &os2)) |
|
285 return NULL; |
|
286 /* If both arguments are byte strings, use strcoll. */ |
|
287 if (PyString_Check(os1) && PyString_Check(os2)) |
|
288 return PyInt_FromLong(strcoll(PyString_AS_STRING(os1), |
|
289 PyString_AS_STRING(os2))); |
|
290 /* If neither argument is unicode, it's an error. */ |
|
291 if (!PyUnicode_Check(os1) && !PyUnicode_Check(os2)) { |
|
292 PyErr_SetString(PyExc_ValueError, "strcoll arguments must be strings"); |
|
293 } |
|
294 /* Convert the non-unicode argument to unicode. */ |
|
295 if (!PyUnicode_Check(os1)) { |
|
296 os1 = PyUnicode_FromObject(os1); |
|
297 if (!os1) |
|
298 return NULL; |
|
299 rel1 = 1; |
|
300 } |
|
301 if (!PyUnicode_Check(os2)) { |
|
302 os2 = PyUnicode_FromObject(os2); |
|
303 if (!os2) { |
|
304 if (rel1) { |
|
305 Py_DECREF(os1); |
|
306 } |
|
307 return NULL; |
|
308 } |
|
309 rel2 = 1; |
|
310 } |
|
311 /* Convert the unicode strings to wchar[]. */ |
|
312 len1 = PyUnicode_GET_SIZE(os1) + 1; |
|
313 ws1 = PyMem_MALLOC(len1 * sizeof(wchar_t)); |
|
314 if (!ws1) { |
|
315 PyErr_NoMemory(); |
|
316 goto done; |
|
317 } |
|
318 if (PyUnicode_AsWideChar((PyUnicodeObject*)os1, ws1, len1) == -1) |
|
319 goto done; |
|
320 ws1[len1 - 1] = 0; |
|
321 len2 = PyUnicode_GET_SIZE(os2) + 1; |
|
322 ws2 = PyMem_MALLOC(len2 * sizeof(wchar_t)); |
|
323 if (!ws2) { |
|
324 PyErr_NoMemory(); |
|
325 goto done; |
|
326 } |
|
327 if (PyUnicode_AsWideChar((PyUnicodeObject*)os2, ws2, len2) == -1) |
|
328 goto done; |
|
329 ws2[len2 - 1] = 0; |
|
330 /* Collate the strings. */ |
|
331 result = PyInt_FromLong(wcscoll(ws1, ws2)); |
|
332 done: |
|
333 /* Deallocate everything. */ |
|
334 if (ws1) PyMem_FREE(ws1); |
|
335 if (ws2) PyMem_FREE(ws2); |
|
336 if (rel1) { |
|
337 Py_DECREF(os1); |
|
338 } |
|
339 if (rel2) { |
|
340 Py_DECREF(os2); |
|
341 } |
|
342 return result; |
|
343 #endif |
|
344 } |
|
345 |
|
346 |
|
347 PyDoc_STRVAR(strxfrm__doc__, |
|
348 "string -> string. Returns a string that behaves for cmp locale-aware."); |
|
349 |
|
350 static PyObject* |
|
351 PyLocale_strxfrm(PyObject* self, PyObject* args) |
|
352 { |
|
353 char *s, *buf; |
|
354 size_t n1, n2; |
|
355 PyObject *result; |
|
356 |
|
357 if (!PyArg_ParseTuple(args, "s:strxfrm", &s)) |
|
358 return NULL; |
|
359 |
|
360 /* assume no change in size, first */ |
|
361 n1 = strlen(s) + 1; |
|
362 buf = PyMem_Malloc(n1); |
|
363 if (!buf) |
|
364 return PyErr_NoMemory(); |
|
365 n2 = strxfrm(buf, s, n1) + 1; |
|
366 if (n2 > n1) { |
|
367 /* more space needed */ |
|
368 buf = PyMem_Realloc(buf, n2); |
|
369 if (!buf) |
|
370 return PyErr_NoMemory(); |
|
371 strxfrm(buf, s, n2); |
|
372 } |
|
373 result = PyString_FromString(buf); |
|
374 PyMem_Free(buf); |
|
375 return result; |
|
376 } |
|
377 |
|
378 #if defined(MS_WINDOWS) |
|
379 static PyObject* |
|
380 PyLocale_getdefaultlocale(PyObject* self) |
|
381 { |
|
382 char encoding[100]; |
|
383 char locale[100]; |
|
384 |
|
385 PyOS_snprintf(encoding, sizeof(encoding), "cp%d", GetACP()); |
|
386 |
|
387 if (GetLocaleInfo(LOCALE_USER_DEFAULT, |
|
388 LOCALE_SISO639LANGNAME, |
|
389 locale, sizeof(locale))) { |
|
390 Py_ssize_t i = strlen(locale); |
|
391 locale[i++] = '_'; |
|
392 if (GetLocaleInfo(LOCALE_USER_DEFAULT, |
|
393 LOCALE_SISO3166CTRYNAME, |
|
394 locale+i, (int)(sizeof(locale)-i))) |
|
395 return Py_BuildValue("ss", locale, encoding); |
|
396 } |
|
397 |
|
398 /* If we end up here, this windows version didn't know about |
|
399 ISO639/ISO3166 names (it's probably Windows 95). Return the |
|
400 Windows language identifier instead (a hexadecimal number) */ |
|
401 |
|
402 locale[0] = '0'; |
|
403 locale[1] = 'x'; |
|
404 if (GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_IDEFAULTLANGUAGE, |
|
405 locale+2, sizeof(locale)-2)) { |
|
406 return Py_BuildValue("ss", locale, encoding); |
|
407 } |
|
408 |
|
409 /* cannot determine the language code (very unlikely) */ |
|
410 Py_INCREF(Py_None); |
|
411 return Py_BuildValue("Os", Py_None, encoding); |
|
412 } |
|
413 #endif |
|
414 |
|
415 #if defined(__APPLE__) |
|
416 /* |
|
417 ** Find out what the current script is. |
|
418 ** Donated by Fredrik Lundh. |
|
419 */ |
|
420 static char *mac_getscript(void) |
|
421 { |
|
422 CFStringEncoding enc = CFStringGetSystemEncoding(); |
|
423 static CFStringRef name = NULL; |
|
424 /* Return the code name for the encodings for which we have codecs. */ |
|
425 switch(enc) { |
|
426 case kCFStringEncodingMacRoman: return "mac-roman"; |
|
427 case kCFStringEncodingMacGreek: return "mac-greek"; |
|
428 case kCFStringEncodingMacCyrillic: return "mac-cyrillic"; |
|
429 case kCFStringEncodingMacTurkish: return "mac-turkish"; |
|
430 case kCFStringEncodingMacIcelandic: return "mac-icelandic"; |
|
431 /* XXX which one is mac-latin2? */ |
|
432 } |
|
433 if (!name) { |
|
434 /* This leaks an object. */ |
|
435 name = CFStringConvertEncodingToIANACharSetName(enc); |
|
436 } |
|
437 return (char *)CFStringGetCStringPtr(name, 0); |
|
438 } |
|
439 |
|
440 static PyObject* |
|
441 PyLocale_getdefaultlocale(PyObject* self) |
|
442 { |
|
443 return Py_BuildValue("Os", Py_None, mac_getscript()); |
|
444 } |
|
445 #endif |
|
446 |
|
447 #ifdef HAVE_LANGINFO_H |
|
448 #define LANGINFO(X) {#X, X} |
|
449 static struct langinfo_constant{ |
|
450 char* name; |
|
451 int value; |
|
452 } langinfo_constants[] = |
|
453 { |
|
454 /* These constants should exist on any langinfo implementation */ |
|
455 LANGINFO(DAY_1), |
|
456 LANGINFO(DAY_2), |
|
457 LANGINFO(DAY_3), |
|
458 LANGINFO(DAY_4), |
|
459 LANGINFO(DAY_5), |
|
460 LANGINFO(DAY_6), |
|
461 LANGINFO(DAY_7), |
|
462 |
|
463 LANGINFO(ABDAY_1), |
|
464 LANGINFO(ABDAY_2), |
|
465 LANGINFO(ABDAY_3), |
|
466 LANGINFO(ABDAY_4), |
|
467 LANGINFO(ABDAY_5), |
|
468 LANGINFO(ABDAY_6), |
|
469 LANGINFO(ABDAY_7), |
|
470 |
|
471 LANGINFO(MON_1), |
|
472 LANGINFO(MON_2), |
|
473 LANGINFO(MON_3), |
|
474 LANGINFO(MON_4), |
|
475 LANGINFO(MON_5), |
|
476 LANGINFO(MON_6), |
|
477 LANGINFO(MON_7), |
|
478 LANGINFO(MON_8), |
|
479 LANGINFO(MON_9), |
|
480 LANGINFO(MON_10), |
|
481 LANGINFO(MON_11), |
|
482 LANGINFO(MON_12), |
|
483 |
|
484 LANGINFO(ABMON_1), |
|
485 LANGINFO(ABMON_2), |
|
486 LANGINFO(ABMON_3), |
|
487 LANGINFO(ABMON_4), |
|
488 LANGINFO(ABMON_5), |
|
489 LANGINFO(ABMON_6), |
|
490 LANGINFO(ABMON_7), |
|
491 LANGINFO(ABMON_8), |
|
492 LANGINFO(ABMON_9), |
|
493 LANGINFO(ABMON_10), |
|
494 LANGINFO(ABMON_11), |
|
495 LANGINFO(ABMON_12), |
|
496 |
|
497 #ifdef RADIXCHAR |
|
498 /* The following are not available with glibc 2.0 */ |
|
499 LANGINFO(RADIXCHAR), |
|
500 LANGINFO(THOUSEP), |
|
501 /* YESSTR and NOSTR are deprecated in glibc, since they are |
|
502 a special case of message translation, which should be rather |
|
503 done using gettext. So we don't expose it to Python in the |
|
504 first place. |
|
505 LANGINFO(YESSTR), |
|
506 LANGINFO(NOSTR), |
|
507 */ |
|
508 LANGINFO(CRNCYSTR), |
|
509 #endif |
|
510 |
|
511 LANGINFO(D_T_FMT), |
|
512 LANGINFO(D_FMT), |
|
513 LANGINFO(T_FMT), |
|
514 LANGINFO(AM_STR), |
|
515 LANGINFO(PM_STR), |
|
516 |
|
517 /* The following constants are available only with XPG4, but... |
|
518 AIX 3.2. only has CODESET. |
|
519 OpenBSD doesn't have CODESET but has T_FMT_AMPM, and doesn't have |
|
520 a few of the others. |
|
521 Solution: ifdef-test them all. */ |
|
522 #ifdef CODESET |
|
523 LANGINFO(CODESET), |
|
524 #endif |
|
525 #ifdef T_FMT_AMPM |
|
526 LANGINFO(T_FMT_AMPM), |
|
527 #endif |
|
528 #ifdef ERA |
|
529 LANGINFO(ERA), |
|
530 #endif |
|
531 #ifdef ERA_D_FMT |
|
532 LANGINFO(ERA_D_FMT), |
|
533 #endif |
|
534 #ifdef ERA_D_T_FMT |
|
535 LANGINFO(ERA_D_T_FMT), |
|
536 #endif |
|
537 #ifdef ERA_T_FMT |
|
538 LANGINFO(ERA_T_FMT), |
|
539 #endif |
|
540 #ifdef ALT_DIGITS |
|
541 LANGINFO(ALT_DIGITS), |
|
542 #endif |
|
543 #ifdef YESEXPR |
|
544 LANGINFO(YESEXPR), |
|
545 #endif |
|
546 #ifdef NOEXPR |
|
547 LANGINFO(NOEXPR), |
|
548 #endif |
|
549 #ifdef _DATE_FMT |
|
550 /* This is not available in all glibc versions that have CODESET. */ |
|
551 LANGINFO(_DATE_FMT), |
|
552 #endif |
|
553 {0, 0} |
|
554 }; |
|
555 |
|
556 PyDoc_STRVAR(nl_langinfo__doc__, |
|
557 "nl_langinfo(key) -> string\n" |
|
558 "Return the value for the locale information associated with key."); |
|
559 |
|
560 static PyObject* |
|
561 PyLocale_nl_langinfo(PyObject* self, PyObject* args) |
|
562 { |
|
563 int item, i; |
|
564 if (!PyArg_ParseTuple(args, "i:nl_langinfo", &item)) |
|
565 return NULL; |
|
566 /* Check whether this is a supported constant. GNU libc sometimes |
|
567 returns numeric values in the char* return value, which would |
|
568 crash PyString_FromString. */ |
|
569 for (i = 0; langinfo_constants[i].name; i++) |
|
570 if (langinfo_constants[i].value == item) { |
|
571 /* Check NULL as a workaround for GNU libc's returning NULL |
|
572 instead of an empty string for nl_langinfo(ERA). */ |
|
573 const char *result = nl_langinfo(item); |
|
574 return PyString_FromString(result != NULL ? result : ""); |
|
575 } |
|
576 PyErr_SetString(PyExc_ValueError, "unsupported langinfo constant"); |
|
577 return NULL; |
|
578 } |
|
579 #endif /* HAVE_LANGINFO_H */ |
|
580 |
|
581 #ifdef HAVE_LIBINTL_H |
|
582 |
|
583 PyDoc_STRVAR(gettext__doc__, |
|
584 "gettext(msg) -> string\n" |
|
585 "Return translation of msg."); |
|
586 |
|
587 static PyObject* |
|
588 PyIntl_gettext(PyObject* self, PyObject *args) |
|
589 { |
|
590 char *in; |
|
591 if (!PyArg_ParseTuple(args, "s", &in)) |
|
592 return 0; |
|
593 return PyString_FromString(gettext(in)); |
|
594 } |
|
595 |
|
596 PyDoc_STRVAR(dgettext__doc__, |
|
597 "dgettext(domain, msg) -> string\n" |
|
598 "Return translation of msg in domain."); |
|
599 |
|
600 static PyObject* |
|
601 PyIntl_dgettext(PyObject* self, PyObject *args) |
|
602 { |
|
603 char *domain, *in; |
|
604 if (!PyArg_ParseTuple(args, "zs", &domain, &in)) |
|
605 return 0; |
|
606 return PyString_FromString(dgettext(domain, in)); |
|
607 } |
|
608 |
|
609 PyDoc_STRVAR(dcgettext__doc__, |
|
610 "dcgettext(domain, msg, category) -> string\n" |
|
611 "Return translation of msg in domain and category."); |
|
612 |
|
613 static PyObject* |
|
614 PyIntl_dcgettext(PyObject *self, PyObject *args) |
|
615 { |
|
616 char *domain, *msgid; |
|
617 int category; |
|
618 if (!PyArg_ParseTuple(args, "zsi", &domain, &msgid, &category)) |
|
619 return 0; |
|
620 return PyString_FromString(dcgettext(domain,msgid,category)); |
|
621 } |
|
622 |
|
623 PyDoc_STRVAR(textdomain__doc__, |
|
624 "textdomain(domain) -> string\n" |
|
625 "Set the C library's textdmain to domain, returning the new domain."); |
|
626 |
|
627 static PyObject* |
|
628 PyIntl_textdomain(PyObject* self, PyObject* args) |
|
629 { |
|
630 char *domain; |
|
631 if (!PyArg_ParseTuple(args, "z", &domain)) |
|
632 return 0; |
|
633 domain = textdomain(domain); |
|
634 if (!domain) { |
|
635 PyErr_SetFromErrno(PyExc_OSError); |
|
636 return NULL; |
|
637 } |
|
638 return PyString_FromString(domain); |
|
639 } |
|
640 |
|
641 PyDoc_STRVAR(bindtextdomain__doc__, |
|
642 "bindtextdomain(domain, dir) -> string\n" |
|
643 "Bind the C library's domain to dir."); |
|
644 |
|
645 static PyObject* |
|
646 PyIntl_bindtextdomain(PyObject* self,PyObject*args) |
|
647 { |
|
648 char *domain, *dirname; |
|
649 if (!PyArg_ParseTuple(args, "sz", &domain, &dirname)) |
|
650 return 0; |
|
651 if (!strlen(domain)) { |
|
652 PyErr_SetString(Error, "domain must be a non-empty string"); |
|
653 return 0; |
|
654 } |
|
655 dirname = bindtextdomain(domain, dirname); |
|
656 if (!dirname) { |
|
657 PyErr_SetFromErrno(PyExc_OSError); |
|
658 return NULL; |
|
659 } |
|
660 return PyString_FromString(dirname); |
|
661 } |
|
662 |
|
663 #ifdef HAVE_BIND_TEXTDOMAIN_CODESET |
|
664 PyDoc_STRVAR(bind_textdomain_codeset__doc__, |
|
665 "bind_textdomain_codeset(domain, codeset) -> string\n" |
|
666 "Bind the C library's domain to codeset."); |
|
667 |
|
668 static PyObject* |
|
669 PyIntl_bind_textdomain_codeset(PyObject* self,PyObject*args) |
|
670 { |
|
671 char *domain,*codeset; |
|
672 if (!PyArg_ParseTuple(args, "sz", &domain, &codeset)) |
|
673 return NULL; |
|
674 codeset = bind_textdomain_codeset(domain, codeset); |
|
675 if (codeset) |
|
676 return PyString_FromString(codeset); |
|
677 Py_RETURN_NONE; |
|
678 } |
|
679 #endif |
|
680 |
|
681 #endif |
|
682 |
|
683 static struct PyMethodDef PyLocale_Methods[] = { |
|
684 {"setlocale", (PyCFunction) PyLocale_setlocale, |
|
685 METH_VARARGS, setlocale__doc__}, |
|
686 {"localeconv", (PyCFunction) PyLocale_localeconv, |
|
687 METH_NOARGS, localeconv__doc__}, |
|
688 {"strcoll", (PyCFunction) PyLocale_strcoll, |
|
689 METH_VARARGS, strcoll__doc__}, |
|
690 {"strxfrm", (PyCFunction) PyLocale_strxfrm, |
|
691 METH_VARARGS, strxfrm__doc__}, |
|
692 #if defined(MS_WINDOWS) || defined(__APPLE__) |
|
693 {"_getdefaultlocale", (PyCFunction) PyLocale_getdefaultlocale, METH_NOARGS}, |
|
694 #endif |
|
695 #ifdef HAVE_LANGINFO_H |
|
696 {"nl_langinfo", (PyCFunction) PyLocale_nl_langinfo, |
|
697 METH_VARARGS, nl_langinfo__doc__}, |
|
698 #endif |
|
699 #ifdef HAVE_LIBINTL_H |
|
700 {"gettext",(PyCFunction)PyIntl_gettext,METH_VARARGS, |
|
701 gettext__doc__}, |
|
702 {"dgettext",(PyCFunction)PyIntl_dgettext,METH_VARARGS, |
|
703 dgettext__doc__}, |
|
704 {"dcgettext",(PyCFunction)PyIntl_dcgettext,METH_VARARGS, |
|
705 dcgettext__doc__}, |
|
706 {"textdomain",(PyCFunction)PyIntl_textdomain,METH_VARARGS, |
|
707 textdomain__doc__}, |
|
708 {"bindtextdomain",(PyCFunction)PyIntl_bindtextdomain,METH_VARARGS, |
|
709 bindtextdomain__doc__}, |
|
710 #ifdef HAVE_BIND_TEXTDOMAIN_CODESET |
|
711 {"bind_textdomain_codeset",(PyCFunction)PyIntl_bind_textdomain_codeset, |
|
712 METH_VARARGS, bind_textdomain_codeset__doc__}, |
|
713 #endif |
|
714 #endif |
|
715 {NULL, NULL} |
|
716 }; |
|
717 |
|
718 PyMODINIT_FUNC |
|
719 init_locale(void) |
|
720 { |
|
721 PyObject *m, *d, *x; |
|
722 #ifdef HAVE_LANGINFO_H |
|
723 int i; |
|
724 #endif |
|
725 |
|
726 m = Py_InitModule("_locale", PyLocale_Methods); |
|
727 if (m == NULL) |
|
728 return; |
|
729 |
|
730 d = PyModule_GetDict(m); |
|
731 |
|
732 x = PyInt_FromLong(LC_CTYPE); |
|
733 PyDict_SetItemString(d, "LC_CTYPE", x); |
|
734 Py_XDECREF(x); |
|
735 |
|
736 x = PyInt_FromLong(LC_TIME); |
|
737 PyDict_SetItemString(d, "LC_TIME", x); |
|
738 Py_XDECREF(x); |
|
739 |
|
740 x = PyInt_FromLong(LC_COLLATE); |
|
741 PyDict_SetItemString(d, "LC_COLLATE", x); |
|
742 Py_XDECREF(x); |
|
743 |
|
744 x = PyInt_FromLong(LC_MONETARY); |
|
745 PyDict_SetItemString(d, "LC_MONETARY", x); |
|
746 Py_XDECREF(x); |
|
747 |
|
748 #ifdef LC_MESSAGES |
|
749 x = PyInt_FromLong(LC_MESSAGES); |
|
750 PyDict_SetItemString(d, "LC_MESSAGES", x); |
|
751 Py_XDECREF(x); |
|
752 #endif /* LC_MESSAGES */ |
|
753 |
|
754 x = PyInt_FromLong(LC_NUMERIC); |
|
755 PyDict_SetItemString(d, "LC_NUMERIC", x); |
|
756 Py_XDECREF(x); |
|
757 |
|
758 x = PyInt_FromLong(LC_ALL); |
|
759 PyDict_SetItemString(d, "LC_ALL", x); |
|
760 Py_XDECREF(x); |
|
761 |
|
762 x = PyInt_FromLong(CHAR_MAX); |
|
763 PyDict_SetItemString(d, "CHAR_MAX", x); |
|
764 Py_XDECREF(x); |
|
765 |
|
766 Error = PyErr_NewException("locale.Error", NULL, NULL); |
|
767 PyDict_SetItemString(d, "Error", Error); |
|
768 |
|
769 x = PyString_FromString(locale__doc__); |
|
770 PyDict_SetItemString(d, "__doc__", x); |
|
771 Py_XDECREF(x); |
|
772 |
|
773 #ifdef HAVE_LANGINFO_H |
|
774 for (i = 0; langinfo_constants[i].name; i++) { |
|
775 PyModule_AddIntConstant(m, langinfo_constants[i].name, |
|
776 langinfo_constants[i].value); |
|
777 } |
|
778 #endif |
|
779 } |
|
780 |
|
781 /* |
|
782 Local variables: |
|
783 c-basic-offset: 4 |
|
784 indent-tabs-mode: nil |
|
785 End: |
|
786 */ |