_localemodule.c 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978
  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. #ifdef __GLIBC__
  511. #if defined(ALT_DIGITS) || defined(ERA)
  512. static PyObject *
  513. decode_strings(const char *result, size_t max_count)
  514. {
  515. /* Convert a sequence of NUL-separated C strings to a Python string
  516. * containing semicolon separated items. */
  517. size_t i = 0;
  518. size_t count = 0;
  519. for (; count < max_count && result[i]; count++) {
  520. i += strlen(result + i) + 1;
  521. }
  522. char *buf = PyMem_Malloc(i);
  523. if (buf == NULL) {
  524. PyErr_NoMemory();
  525. return NULL;
  526. }
  527. memcpy(buf, result, i);
  528. /* Replace all NULs with semicolons. */
  529. i = 0;
  530. while (--count) {
  531. i += strlen(buf + i);
  532. buf[i++] = ';';
  533. }
  534. PyObject *pyresult = PyUnicode_DecodeLocale(buf, NULL);
  535. PyMem_Free(buf);
  536. return pyresult;
  537. }
  538. #endif
  539. #endif
  540. /*[clinic input]
  541. _locale.nl_langinfo
  542. key as item: int
  543. /
  544. Return the value for the locale information associated with key.
  545. [clinic start generated code]*/
  546. static PyObject *
  547. _locale_nl_langinfo_impl(PyObject *module, int item)
  548. /*[clinic end generated code: output=6aea457b47e077a3 input=00798143eecfeddc]*/
  549. {
  550. int i;
  551. /* Check whether this is a supported constant. GNU libc sometimes
  552. returns numeric values in the char* return value, which would
  553. crash PyUnicode_FromString. */
  554. for (i = 0; langinfo_constants[i].name; i++)
  555. if (langinfo_constants[i].value == item) {
  556. /* Check NULL as a workaround for GNU libc's returning NULL
  557. instead of an empty string for nl_langinfo(ERA). */
  558. const char *result = nl_langinfo(item);
  559. result = result != NULL ? result : "";
  560. PyObject *pyresult;
  561. #ifdef __GLIBC__
  562. /* According to the POSIX specification the result must be
  563. * a sequence of semicolon-separated strings.
  564. * But in Glibc they are NUL-separated. */
  565. #ifdef ALT_DIGITS
  566. if (item == ALT_DIGITS && *result) {
  567. pyresult = decode_strings(result, 100);
  568. }
  569. else
  570. #endif
  571. #ifdef ERA
  572. if (item == ERA && *result) {
  573. pyresult = decode_strings(result, SIZE_MAX);
  574. }
  575. else
  576. #endif
  577. #endif
  578. {
  579. pyresult = PyUnicode_DecodeLocale(result, NULL);
  580. }
  581. return pyresult;
  582. }
  583. PyErr_SetString(PyExc_ValueError, "unsupported langinfo constant");
  584. return NULL;
  585. }
  586. #endif /* HAVE_LANGINFO_H */
  587. #ifdef HAVE_LIBINTL_H
  588. /*[clinic input]
  589. _locale.gettext
  590. msg as in: str
  591. /
  592. gettext(msg) -> string
  593. Return translation of msg.
  594. [clinic start generated code]*/
  595. static PyObject *
  596. _locale_gettext_impl(PyObject *module, const char *in)
  597. /*[clinic end generated code: output=493bb4b38a4704fe input=949fc8efc2bb3bc3]*/
  598. {
  599. return PyUnicode_DecodeLocale(gettext(in), NULL);
  600. }
  601. /*[clinic input]
  602. _locale.dgettext
  603. domain: str(accept={str, NoneType})
  604. msg as in: str
  605. /
  606. dgettext(domain, msg) -> string
  607. Return translation of msg in domain.
  608. [clinic start generated code]*/
  609. static PyObject *
  610. _locale_dgettext_impl(PyObject *module, const char *domain, const char *in)
  611. /*[clinic end generated code: output=3c0cd5287b972c8f input=a277388a635109d8]*/
  612. {
  613. return PyUnicode_DecodeLocale(dgettext(domain, in), NULL);
  614. }
  615. /*[clinic input]
  616. _locale.dcgettext
  617. domain: str(accept={str, NoneType})
  618. msg as msgid: str
  619. category: int
  620. /
  621. Return translation of msg in domain and category.
  622. [clinic start generated code]*/
  623. static PyObject *
  624. _locale_dcgettext_impl(PyObject *module, const char *domain,
  625. const char *msgid, int category)
  626. /*[clinic end generated code: output=0f4cc4fce0aa283f input=ec5f8fed4336de67]*/
  627. {
  628. return PyUnicode_DecodeLocale(dcgettext(domain,msgid,category), NULL);
  629. }
  630. /*[clinic input]
  631. _locale.textdomain
  632. domain: str(accept={str, NoneType})
  633. /
  634. Set the C library's textdmain to domain, returning the new domain.
  635. [clinic start generated code]*/
  636. static PyObject *
  637. _locale_textdomain_impl(PyObject *module, const char *domain)
  638. /*[clinic end generated code: output=7992df06aadec313 input=66359716f5eb1d38]*/
  639. {
  640. domain = textdomain(domain);
  641. if (!domain) {
  642. PyErr_SetFromErrno(PyExc_OSError);
  643. return NULL;
  644. }
  645. return PyUnicode_DecodeLocale(domain, NULL);
  646. }
  647. /*[clinic input]
  648. _locale.bindtextdomain
  649. domain: str
  650. dir as dirname_obj: object
  651. /
  652. Bind the C library's domain to dir.
  653. [clinic start generated code]*/
  654. static PyObject *
  655. _locale_bindtextdomain_impl(PyObject *module, const char *domain,
  656. PyObject *dirname_obj)
  657. /*[clinic end generated code: output=6d6f3c7b345d785c input=c0dff085acfe272b]*/
  658. {
  659. const char *dirname, *current_dirname;
  660. PyObject *dirname_bytes = NULL, *result;
  661. if (!strlen(domain)) {
  662. PyErr_SetString(get_locale_state(module)->Error,
  663. "domain must be a non-empty string");
  664. return 0;
  665. }
  666. if (dirname_obj != Py_None) {
  667. if (!PyUnicode_FSConverter(dirname_obj, &dirname_bytes))
  668. return NULL;
  669. dirname = PyBytes_AsString(dirname_bytes);
  670. } else {
  671. dirname_bytes = NULL;
  672. dirname = NULL;
  673. }
  674. current_dirname = bindtextdomain(domain, dirname);
  675. if (current_dirname == NULL) {
  676. PyErr_SetFromErrno(PyExc_OSError);
  677. Py_XDECREF(dirname_bytes);
  678. return NULL;
  679. }
  680. result = PyUnicode_DecodeLocale(current_dirname, NULL);
  681. Py_XDECREF(dirname_bytes);
  682. return result;
  683. }
  684. #ifdef HAVE_BIND_TEXTDOMAIN_CODESET
  685. /*[clinic input]
  686. _locale.bind_textdomain_codeset
  687. domain: str
  688. codeset: str(accept={str, NoneType})
  689. /
  690. Bind the C library's domain to codeset.
  691. [clinic start generated code]*/
  692. static PyObject *
  693. _locale_bind_textdomain_codeset_impl(PyObject *module, const char *domain,
  694. const char *codeset)
  695. /*[clinic end generated code: output=fa452f9c8b1b9e89 input=23fbe3540400f259]*/
  696. {
  697. codeset = bind_textdomain_codeset(domain, codeset);
  698. if (codeset) {
  699. return PyUnicode_DecodeLocale(codeset, NULL);
  700. }
  701. Py_RETURN_NONE;
  702. }
  703. #endif // HAVE_BIND_TEXTDOMAIN_CODESET
  704. #endif // HAVE_LIBINTL_H
  705. /*[clinic input]
  706. _locale.getencoding
  707. Get the current locale encoding.
  708. [clinic start generated code]*/
  709. static PyObject *
  710. _locale_getencoding_impl(PyObject *module)
  711. /*[clinic end generated code: output=86b326b971872e46 input=6503d11e5958b360]*/
  712. {
  713. return _Py_GetLocaleEncodingObject();
  714. }
  715. static struct PyMethodDef PyLocale_Methods[] = {
  716. _LOCALE_SETLOCALE_METHODDEF
  717. _LOCALE_LOCALECONV_METHODDEF
  718. #ifdef HAVE_WCSCOLL
  719. _LOCALE_STRCOLL_METHODDEF
  720. #endif
  721. #ifdef HAVE_WCSXFRM
  722. _LOCALE_STRXFRM_METHODDEF
  723. #endif
  724. #if defined(MS_WINDOWS)
  725. _LOCALE__GETDEFAULTLOCALE_METHODDEF
  726. #endif
  727. #ifdef HAVE_LANGINFO_H
  728. _LOCALE_NL_LANGINFO_METHODDEF
  729. #endif
  730. #ifdef HAVE_LIBINTL_H
  731. _LOCALE_GETTEXT_METHODDEF
  732. _LOCALE_DGETTEXT_METHODDEF
  733. _LOCALE_DCGETTEXT_METHODDEF
  734. _LOCALE_TEXTDOMAIN_METHODDEF
  735. _LOCALE_BINDTEXTDOMAIN_METHODDEF
  736. #ifdef HAVE_BIND_TEXTDOMAIN_CODESET
  737. _LOCALE_BIND_TEXTDOMAIN_CODESET_METHODDEF
  738. #endif
  739. #endif
  740. _LOCALE_GETENCODING_METHODDEF
  741. {NULL, NULL}
  742. };
  743. static int
  744. _locale_exec(PyObject *module)
  745. {
  746. #ifdef HAVE_LANGINFO_H
  747. int i;
  748. #endif
  749. #define ADD_INT(module, value) \
  750. do { \
  751. if (PyModule_AddIntConstant(module, #value, value) < 0) { \
  752. return -1; \
  753. } \
  754. } while (0)
  755. ADD_INT(module, LC_CTYPE);
  756. ADD_INT(module, LC_TIME);
  757. ADD_INT(module, LC_COLLATE);
  758. ADD_INT(module, LC_MONETARY);
  759. #ifdef LC_MESSAGES
  760. ADD_INT(module, LC_MESSAGES);
  761. #endif /* LC_MESSAGES */
  762. ADD_INT(module, LC_NUMERIC);
  763. ADD_INT(module, LC_ALL);
  764. ADD_INT(module, CHAR_MAX);
  765. _locale_state *state = get_locale_state(module);
  766. state->Error = PyErr_NewException("locale.Error", NULL, NULL);
  767. if (state->Error == NULL) {
  768. return -1;
  769. }
  770. Py_INCREF(get_locale_state(module)->Error);
  771. if (PyModule_AddObject(module, "Error", get_locale_state(module)->Error) < 0) {
  772. Py_DECREF(get_locale_state(module)->Error);
  773. return -1;
  774. }
  775. #ifdef HAVE_LANGINFO_H
  776. for (i = 0; langinfo_constants[i].name; i++) {
  777. if (PyModule_AddIntConstant(module,
  778. langinfo_constants[i].name,
  779. langinfo_constants[i].value) < 0) {
  780. return -1;
  781. }
  782. }
  783. #endif
  784. if (PyErr_Occurred()) {
  785. return -1;
  786. }
  787. return 0;
  788. #undef ADD_INT
  789. }
  790. static struct PyModuleDef_Slot _locale_slots[] = {
  791. {Py_mod_exec, _locale_exec},
  792. {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED},
  793. {0, NULL}
  794. };
  795. static int
  796. locale_traverse(PyObject *module, visitproc visit, void *arg)
  797. {
  798. _locale_state *state = get_locale_state(module);
  799. Py_VISIT(state->Error);
  800. return 0;
  801. }
  802. static int
  803. locale_clear(PyObject *module)
  804. {
  805. _locale_state *state = get_locale_state(module);
  806. Py_CLEAR(state->Error);
  807. return 0;
  808. }
  809. static void
  810. locale_free(PyObject *module)
  811. {
  812. locale_clear(module);
  813. }
  814. static struct PyModuleDef _localemodule = {
  815. PyModuleDef_HEAD_INIT,
  816. "_locale",
  817. locale__doc__,
  818. sizeof(_locale_state),
  819. PyLocale_Methods,
  820. _locale_slots,
  821. locale_traverse,
  822. locale_clear,
  823. (freefunc)locale_free,
  824. };
  825. PyMODINIT_FUNC
  826. PyInit__locale(void)
  827. {
  828. return PyModuleDef_Init(&_localemodule);
  829. }
  830. /*
  831. Local variables:
  832. c-basic-offset: 4
  833. indent-tabs-mode: nil
  834. End:
  835. */