_localemodule.c 22 KB

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