Use wcscoll for _locale.strcoll if available.
diff --git a/Modules/_localemodule.c b/Modules/_localemodule.c
index d535ee8..2077be8 100644
--- a/Modules/_localemodule.c
+++ b/Modules/_localemodule.c
@@ -25,6 +25,10 @@
#include <libintl.h>
#endif
+#ifdef HAVE_WCHAR_H
+#include <wchar.h>
+#endif
+
#if defined(MS_WINDOWS)
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
@@ -325,13 +329,76 @@
static PyObject*
PyLocale_strcoll(PyObject* self, PyObject* args)
{
- char *s1,*s2;
-
- if (!PyArg_ParseTuple(args, "ss:strcoll", &s1, &s2))
- return NULL;
- return PyInt_FromLong(strcoll(s1, s2));
+#if !defined(HAVE_WCSCOLL) || !defined(Py_USING_UNICODE)
+ char *s1,*s2;
+
+ if (!PyArg_ParseTuple(args, "ss:strcoll", &s1, &s2))
+ return NULL;
+ return PyInt_FromLong(strcoll(s1, s2));
+#else
+ PyObject *os1, *os2, *result = NULL;
+ wchar_t *ws1 = NULL, *ws2 = NULL;
+ int rel1 = 0, rel2 = 0, len1, len2;
+
+ if (!PyArg_ParseTuple(args, "OO:strcoll", &os1, &os2))
+ return NULL;
+ /* If both arguments are byte strings, use strcoll. */
+ if (PyString_Check(os1) && PyString_Check(os2))
+ return PyInt_FromLong(strcoll(PyString_AS_STRING(os1),
+ PyString_AS_STRING(os2)));
+ /* If neither argument is unicode, it's an error. */
+ if (!PyUnicode_Check(os1) && !PyUnicode_Check(os2)) {
+ PyErr_SetString(PyExc_ValueError, "strcoll arguments must be strings");
+ }
+ /* Convert the non-unicode argument to unicode. */
+ if (!PyUnicode_Check(os1)) {
+ os1 = PyUnicode_FromObject(os1);
+ if (!os1)
+ return NULL;
+ rel1 = 1;
+ }
+ if (!PyUnicode_Check(os2)) {
+ os2 = PyUnicode_FromObject(os2);
+ if (!os2) {
+ Py_DECREF(os1);
+ return NULL;
+ }
+ rel2 = 1;
+ }
+ /* Convert the unicode strings to wchar[]. */
+ len1 = PyUnicode_GET_SIZE(os1) + 1;
+ len2 = PyUnicode_GET_SIZE(os2) + 1;
+ ws1 = PyMem_MALLOC(len1 * sizeof(wchar_t));
+ if (!ws1) {
+ PyErr_NoMemory();
+ goto done;
+ }
+ if (PyUnicode_AsWideChar((PyUnicodeObject*)os1, ws1, len1) == -1)
+ goto done;
+ ws2 = PyMem_MALLOC(len2 * sizeof(wchar_t));
+ if (!ws2) {
+ PyErr_NoMemory();
+ goto done;
+ }
+ if (PyUnicode_AsWideChar((PyUnicodeObject*)os2, ws2, len2) == -1)
+ goto done;
+ /* Collate the strings. */
+ result = PyInt_FromLong(wcscoll(ws1, ws2));
+ done:
+ /* Deallocate everything. */
+ if (ws1) PyMem_FREE(ws1);
+ if (ws2) PyMem_FREE(ws2);
+ if (rel1) {
+ Py_DECREF(os1);
+ }
+ if (rel2) {
+ Py_DECREF(os2);
+ }
+ return result;
+#endif
}
+
PyDoc_STRVAR(strxfrm__doc__,
"string -> string. Returns a string that behaves for cmp locale-aware.");
@@ -709,3 +776,10 @@
}
#endif
}
+
+/*
+Local variables:
+c-basic-offset: 4
+indent-tabs-mode: nil
+End:
+*/
diff --git a/PC/pyconfig.h b/PC/pyconfig.h
index 6ff99b6..0e7912e 100644
--- a/PC/pyconfig.h
+++ b/PC/pyconfig.h
@@ -497,6 +497,9 @@
/* Define if you have waitpid. */
/* #undef HAVE_WAITPID */
+/* Define to 1 if you have the `wcscoll' function. */
+#define HAVE_WCSCOLL 1
+
/* Define if you have the <dlfcn.h> header file. */
/* #undef HAVE_DLFCN_H */
@@ -551,6 +554,9 @@
/* Define if you have the <utime.h> header file. */
/* #define HAVE_UTIME_H 1 */
+/* Define if the compiler provides a wchar.h header file. */
+#define HAVE_WCHAR_H 1
+
/* Define if you have the dl library (-ldl). */
/* #undef HAVE_LIBDL */
diff --git a/configure b/configure
index b825d15..0103ba1 100755
--- a/configure
+++ b/configure
@@ -1,5 +1,5 @@
#! /bin/sh
-# From configure.in Revision: 1.376 .
+# From configure.in Revision: 1.377 .
# Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.53 for python 2.3.
#
@@ -12008,6 +12008,7 @@
+
for ac_func in alarm chown clock confstr ctermid execv \
fchdir flock fork fsync fdatasync fpathconf ftime ftruncate \
gai_strerror getgroups getlogin getpeername getpgid getpid getpwent getwd \
@@ -12018,7 +12019,7 @@
setlocale setregid setreuid setsid setpgid setuid setvbuf snprintf \
sigaction siginterrupt sigrelse strftime strptime \
sysconf tcgetpgrp tcsetpgrp tempnam timegm times tmpfile tmpnam tmpnam_r \
- truncate uname unsetenv utimes waitpid _getpty getpriority
+ truncate uname unsetenv utimes waitpid wcscoll _getpty getpriority
do
as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
echo "$as_me:$LINENO: checking for $ac_func" >&5
diff --git a/configure.in b/configure.in
index a3b8c67..b6a266d 100644
--- a/configure.in
+++ b/configure.in
@@ -1770,7 +1770,7 @@
setlocale setregid setreuid setsid setpgid setuid setvbuf snprintf \
sigaction siginterrupt sigrelse strftime strptime \
sysconf tcgetpgrp tcsetpgrp tempnam timegm times tmpfile tmpnam tmpnam_r \
- truncate uname unsetenv utimes waitpid _getpty getpriority)
+ truncate uname unsetenv utimes waitpid wcscoll _getpty getpriority)
# For some functions, having a definition is not sufficient, since
# we want to take their address.
diff --git a/pyconfig.h.in b/pyconfig.h.in
index 9503ea8..d63c36c 100644
--- a/pyconfig.h.in
+++ b/pyconfig.h.in
@@ -586,6 +586,9 @@
/* Define if the compiler provides a wchar.h header file. */
#undef HAVE_WCHAR_H
+/* Define to 1 if you have the `wcscoll' function. */
+#undef HAVE_WCSCOLL
+
/* Define to 1 if you have the `_getpty' function. */
#undef HAVE__GETPTY