summaryrefslogtreecommitdiff
path: root/Modules/_localemodule.c
diff options
context:
space:
mode:
Diffstat (limited to 'Modules/_localemodule.c')
-rw-r--r--Modules/_localemodule.c103
1 files changed, 29 insertions, 74 deletions
diff --git a/Modules/_localemodule.c b/Modules/_localemodule.c
index 1001dd22b7..cc688ba140 100644
--- a/Modules/_localemodule.c
+++ b/Modules/_localemodule.c
@@ -42,43 +42,6 @@ PyDoc_STRVAR(locale__doc__, "Support for POSIX locales.");
static PyObject *Error;
-/* Convert a char* to a Unicode object according to the current locale */
-static PyObject*
-str2uni(const char* s)
-{
-#ifdef HAVE_BROKEN_MBSTOWCS
- size_t needed = strlen(s);
-#else
- size_t needed = mbstowcs(NULL, s, 0);
-#endif
- size_t res1;
- wchar_t smallbuf[30];
- wchar_t *dest;
- PyObject *res2;
- if (needed == (size_t)-1) {
- PyErr_SetString(PyExc_ValueError, "Cannot convert byte to string");
- return NULL;
- }
- if (needed*sizeof(wchar_t) < sizeof(smallbuf))
- dest = smallbuf;
- else {
- dest = PyMem_Malloc((needed+1)*sizeof(wchar_t));
- if (!dest)
- return PyErr_NoMemory();
- }
- /* This shouldn't fail now */
- res1 = mbstowcs(dest, s, needed+1);
-#ifdef HAVE_BROKEN_MBSTOWCS
- assert(res1 != (size_t)-1);
-#else
- assert(res1 == needed);
-#endif
- res2 = PyUnicode_FromWideChar(dest, res1);
- if (dest != smallbuf)
- PyMem_Free(dest);
- return res2;
-}
-
/* support functions for formatting floating point numbers */
PyDoc_STRVAR(setlocale__doc__,
@@ -149,7 +112,7 @@ PyLocale_setlocale(PyObject* self, PyObject* args)
PyErr_SetString(Error, "unsupported locale setting");
return NULL;
}
- result_object = str2uni(result);
+ result_object = PyUnicode_DecodeLocale(result, NULL);
if (!result_object)
return NULL;
} else {
@@ -159,7 +122,7 @@ PyLocale_setlocale(PyObject* self, PyObject* args)
PyErr_SetString(Error, "locale query failed");
return NULL;
}
- result_object = str2uni(result);
+ result_object = PyUnicode_DecodeLocale(result, NULL);
}
return result_object;
}
@@ -185,7 +148,7 @@ PyLocale_localeconv(PyObject* self)
involved herein */
#define RESULT_STRING(s)\
- x = str2uni(l->s); \
+ x = PyUnicode_DecodeLocale(l->s, NULL); \
if (!x) goto failed;\
PyDict_SetItemString(result, #s, x);\
Py_XDECREF(x)
@@ -271,51 +234,43 @@ Return a string that can be used as a key for locale-aware comparisons.");
static PyObject*
PyLocale_strxfrm(PyObject* self, PyObject* args)
{
- Py_UNICODE *s0;
- Py_ssize_t n0;
- wchar_t *s, *buf = NULL;
- size_t n1, n2;
+ PyObject *str;
+ Py_ssize_t n1;
+ wchar_t *s = NULL, *buf = NULL;
+ size_t n2;
PyObject *result = NULL;
-#if Py_UNICODE_SIZE != SIZEOF_WCHAR_T
- Py_ssize_t i;
-#endif
- if (!PyArg_ParseTuple(args, "u#:strxfrm", &s0, &n0))
+ if (!PyArg_ParseTuple(args, "U:strxfrm", &str))
return NULL;
-#if Py_UNICODE_SIZE == SIZEOF_WCHAR_T
- s = (wchar_t *) s0;
-#else
- s = PyMem_Malloc((n0+1)*sizeof(wchar_t));
- if (!s)
- return PyErr_NoMemory();
- for (i=0; i<=n0; i++)
- s[i] = s0[i];
-#endif
+ s = PyUnicode_AsWideCharString(str, &n1);
+ if (s == NULL)
+ goto exit;
/* assume no change in size, first */
- n1 = wcslen(s) + 1;
- buf = PyMem_Malloc(n1*sizeof(wchar_t));
+ n1 = n1 + 1;
+ buf = PyMem_Malloc(n1 * sizeof(wchar_t));
if (!buf) {
PyErr_NoMemory();
goto exit;
}
n2 = wcsxfrm(buf, s, n1);
- if (n2 >= n1) {
+ if (n2 >= (size_t)n1) {
/* more space needed */
- buf = PyMem_Realloc(buf, (n2+1)*sizeof(wchar_t));
- if (!buf) {
+ wchar_t * new_buf = PyMem_Realloc(buf, (n2+1)*sizeof(wchar_t));
+ if (!new_buf) {
PyErr_NoMemory();
goto exit;
}
+ buf = new_buf;
n2 = wcsxfrm(buf, s, n2+1);
}
result = PyUnicode_FromWideChar(buf, n2);
- exit:
- if (buf) PyMem_Free(buf);
-#if Py_UNICODE_SIZE != SIZEOF_WCHAR_T
- PyMem_Free(s);
-#endif
+exit:
+ if (buf)
+ PyMem_Free(buf);
+ if (s)
+ PyMem_Free(s);
return result;
}
#endif
@@ -485,7 +440,7 @@ PyLocale_nl_langinfo(PyObject* self, PyObject* args)
instead of an empty string for nl_langinfo(ERA). */
const char *result = nl_langinfo(item);
result = result != NULL ? result : "";
- return str2uni(result);
+ return PyUnicode_DecodeLocale(result, NULL);
}
PyErr_SetString(PyExc_ValueError, "unsupported langinfo constant");
return NULL;
@@ -504,7 +459,7 @@ PyIntl_gettext(PyObject* self, PyObject *args)
char *in;
if (!PyArg_ParseTuple(args, "s", &in))
return 0;
- return str2uni(gettext(in));
+ return PyUnicode_DecodeLocale(gettext(in), NULL);
}
PyDoc_STRVAR(dgettext__doc__,
@@ -517,7 +472,7 @@ PyIntl_dgettext(PyObject* self, PyObject *args)
char *domain, *in;
if (!PyArg_ParseTuple(args, "zs", &domain, &in))
return 0;
- return str2uni(dgettext(domain, in));
+ return PyUnicode_DecodeLocale(dgettext(domain, in), NULL);
}
PyDoc_STRVAR(dcgettext__doc__,
@@ -531,7 +486,7 @@ PyIntl_dcgettext(PyObject *self, PyObject *args)
int category;
if (!PyArg_ParseTuple(args, "zsi", &domain, &msgid, &category))
return 0;
- return str2uni(dcgettext(domain,msgid,category));
+ return PyUnicode_DecodeLocale(dcgettext(domain,msgid,category), NULL);
}
PyDoc_STRVAR(textdomain__doc__,
@@ -549,7 +504,7 @@ PyIntl_textdomain(PyObject* self, PyObject* args)
PyErr_SetFromErrno(PyExc_OSError);
return NULL;
}
- return str2uni(domain);
+ return PyUnicode_DecodeLocale(domain, NULL);
}
PyDoc_STRVAR(bindtextdomain__doc__,
@@ -581,7 +536,7 @@ PyIntl_bindtextdomain(PyObject* self,PyObject*args)
PyErr_SetFromErrno(PyExc_OSError);
return NULL;
}
- result = str2uni(current_dirname);
+ result = PyUnicode_DecodeLocale(current_dirname, NULL);
Py_XDECREF(dirname_bytes);
return result;
}
@@ -599,7 +554,7 @@ PyIntl_bind_textdomain_codeset(PyObject* self,PyObject*args)
return NULL;
codeset = bind_textdomain_codeset(domain, codeset);
if (codeset)
- return str2uni(codeset);
+ return PyUnicode_DecodeLocale(codeset, NULL);
Py_RETURN_NONE;
}
#endif