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