diff --git a/Modules/_localemodule.c b/Modules/_localemodule.c index d535ee8995b..2077be827ac 100644 --- a/Modules/_localemodule.c +++ b/Modules/_localemodule.c @@ -25,6 +25,10 @@ This software comes with no warranty. Use at your own risk. #include #endif +#ifdef HAVE_WCHAR_H +#include +#endif + #if defined(MS_WINDOWS) #define WIN32_LEAN_AND_MEAN #include @@ -325,13 +329,76 @@ PyDoc_STRVAR(strcoll__doc__, 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 @@ init_locale(void) } #endif } + +/* +Local variables: +c-basic-offset: 4 +indent-tabs-mode: nil +End: +*/ diff --git a/PC/pyconfig.h b/PC/pyconfig.h index 6ff99b63239..0e7912eb947 100644 --- a/PC/pyconfig.h +++ b/PC/pyconfig.h @@ -497,6 +497,9 @@ Py_NO_ENABLE_SHARED to find out. Also support MS_NO_COREDLL for b/w compat */ /* 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 header file. */ /* #undef HAVE_DLFCN_H */ @@ -551,6 +554,9 @@ Py_NO_ENABLE_SHARED to find out. Also support MS_NO_COREDLL for b/w compat */ /* Define if you have the 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 b825d151ddc..0103ba18293 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. # @@ -12006,6 +12006,7 @@ echo "${ECHO_T}MACHDEP_OBJS" >&6 + for ac_func in alarm chown clock confstr ctermid execv \ @@ -12018,7 +12019,7 @@ for ac_func in alarm chown clock confstr ctermid execv \ 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 a3b8c675a42..b6a266d018c 100644 --- a/configure.in +++ b/configure.in @@ -1770,7 +1770,7 @@ AC_CHECK_FUNCS(alarm chown clock confstr ctermid execv \ 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 9503ea81ab3..d63c36c380c 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