diff --git a/Doc/library/locale.rst b/Doc/library/locale.rst --- a/Doc/library/locale.rst +++ b/Doc/library/locale.rst @@ -396,6 +396,17 @@ The :mod:`locale` module defines the fol Converts a string to an integer, following the :const:`LC_NUMERIC` conventions. +.. function:: width(str) + + Return the number of columns needed to represent the character string. Raise + a :exc:`locale.Error` if a nonprintable character occurs among these + characters. + + Availability: Unix. + + .. versionadded:: 3.3 + + .. data:: LC_CTYPE .. index:: module: string diff --git a/Modules/_localemodule.c b/Modules/_localemodule.c --- a/Modules/_localemodule.c +++ b/Modules/_localemodule.c @@ -483,6 +483,36 @@ PyLocale_nl_langinfo(PyObject* self, PyO } #endif /* HAVE_LANGINFO_H */ + +#ifdef HAVE_WCSWIDTH +PyDoc_STRVAR(width__doc__, +"width(str) -> int\n" +"determine columns needed for a fixed-size character string."); + +static PyObject* +PyLocale_width(PyObject* self, PyObject* args) +{ + PyObject *str; + wchar_t *wstr; + int width; + Py_ssize_t len; + + if (!PyArg_ParseTuple(args, "U:width", &str)) + return NULL; + wstr = PyUnicode_AsWideCharString(str, &len); + if (wstr == NULL) + return NULL; + width = wcswidth(wstr, len); + PyMem_Free(wstr); + if (width < 0) { + PyErr_SetString(Error, "the string is not printable"); + return NULL; + } + return PyLong_FromLong(width); +} +#endif /* HAVE_WCSWIDTH */ + + #ifdef HAVE_LIBINTL_H PyDoc_STRVAR(gettext__doc__, @@ -617,6 +647,10 @@ static struct PyMethodDef PyLocale_Metho {"nl_langinfo", (PyCFunction) PyLocale_nl_langinfo, METH_VARARGS, nl_langinfo__doc__}, #endif +#ifdef HAVE_WCSWIDTH + {"width",(PyCFunction)PyLocale_width, METH_VARARGS, + width__doc__}, +#endif #ifdef HAVE_LIBINTL_H {"gettext",(PyCFunction)PyIntl_gettext,METH_VARARGS, gettext__doc__}, diff --git a/configure b/configure --- a/configure +++ b/configure @@ -9405,7 +9405,7 @@ for ac_func in alarm accept4 setitimer g sigtimedwait sigwait sigwaitinfo snprintf strftime strlcpy symlinkat sync \ sysconf tcgetpgrp tcsetpgrp tempnam timegm times tmpfile tmpnam tmpnam_r \ truncate uname unlinkat unsetenv utimensat utimes waitid waitpid wait3 wait4 \ - wcscoll wcsftime wcsxfrm writev _getpty + wcscoll wcsftime wcsxfrm wcswidth writev _getpty do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" diff --git a/configure.in b/configure.in --- a/configure.in +++ b/configure.in @@ -2580,7 +2580,7 @@ AC_CHECK_FUNCS(alarm accept4 setitimer g sigtimedwait sigwait sigwaitinfo snprintf strftime strlcpy symlinkat sync \ sysconf tcgetpgrp tcsetpgrp tempnam timegm times tmpfile tmpnam tmpnam_r \ truncate uname unlinkat unsetenv utimensat utimes waitid waitpid wait3 wait4 \ - wcscoll wcsftime wcsxfrm writev _getpty) + wcscoll wcsftime wcsxfrm wcswidth writev _getpty) # 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 --- a/pyconfig.h.in +++ b/pyconfig.h.in @@ -1057,6 +1057,9 @@ /* Define to 1 if you have the `wcsftime' function. */ #undef HAVE_WCSFTIME +/* Define to 1 if you have the `wcswidth' function. */ +#undef HAVE_WCSWIDTH + /* Define to 1 if you have the `wcsxfrm' function. */ #undef HAVE_WCSXFRM