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