diff --git a/Doc/c-api/unicode.rst b/Doc/c-api/unicode.rst index 78eec14e3a24d6..526f14a4951a47 100644 --- a/Doc/c-api/unicode.rst +++ b/Doc/c-api/unicode.rst @@ -223,6 +223,14 @@ the Python configuration. Return ``1`` or ``0`` depending on whether *ch* is a titlecase character. +.. c:function:: int Py_UNICODE_ISCASED(Py_UCS4 ch) + + Return ``1`` or ``0`` depending on whether *ch* is a cased character. + +.. c:function:: int Py_UNICODE_ISCASEIGNORABLE(Py_UCS4 ch) + + Return ``1`` or ``0`` depending on whether *ch* is a case-ignorable character. + .. c:function:: int Py_UNICODE_ISLINEBREAK(Py_UCS4 ch) @@ -322,6 +330,26 @@ These APIs can be used to work with surrogates: surrogate pair. *high* must be in the range [0xD800; 0xDBFF] and *low* must be in the range [0xDC00; 0xDFFF]. +.. c:function:: Py_ssize_t PyUnicode_ToLower(Py_UCS4 ch, Py_UCS4 *buffer, \ + Py_ssize_t size) + + Convert *ch* to lower case, store result in *buffer*, which should be + able to hold *size* characters, and return the number of characters stored. + If the buffer is not big enough, return -1. + +.. c:function:: Py_ssize_t PyUnicode_ToUpper(Py_UCS4 ch, Py_UCS4 *buffer, \ + Py_ssize_t size) + + Convert *ch* to upper case, store result in *buffer*, which should be + able to hold *size* characters, and return the number of characters stored. + If the buffer is not big enough, return -1. + +.. c:function:: Py_ssize_t PyUnicode_ToTitle(Py_UCS4 ch, Py_UCS4 *buffer, \ + Py_ssize_t size) + + Convert *ch* to title case, store result in *buffer*, which should be + able to hold *size* characters, and return the number of characters stored. + If the buffer is not big enough, return -1. Creating and accessing Unicode strings """""""""""""""""""""""""""""""""""""" diff --git a/Include/cpython/unicodeobject.h b/Include/cpython/unicodeobject.h index d9b54bce83202d..1ff07c3670cbb2 100644 --- a/Include/cpython/unicodeobject.h +++ b/Include/cpython/unicodeobject.h @@ -602,6 +602,14 @@ PyAPI_FUNC(int) _PyUnicode_IsTitlecase( Py_UCS4 ch /* Unicode character */ ); +PyAPI_FUNC(int) _PyUnicode_IsCased( + Py_UCS4 ch /* Unicode character */ + ); + +PyAPI_FUNC(int) _PyUnicode_IsCaseIgnorable( + Py_UCS4 ch /* Unicode character */ + ); + PyAPI_FUNC(int) _PyUnicode_IsWhitespace( const Py_UCS4 ch /* Unicode character */ ); @@ -671,6 +679,8 @@ static inline int Py_UNICODE_ISSPACE(Py_UCS4 ch) { #define Py_UNICODE_ISLOWER(ch) _PyUnicode_IsLowercase(ch) #define Py_UNICODE_ISUPPER(ch) _PyUnicode_IsUppercase(ch) #define Py_UNICODE_ISTITLE(ch) _PyUnicode_IsTitlecase(ch) +#define Py_UNICODE_ISCASED(ch) _PyUnicode_IsCased(ch) +#define Py_UNICODE_ISCASEIGNORABLE(ch) _PyUnicode_IsCaseIgnorable(ch) #define Py_UNICODE_ISLINEBREAK(ch) _PyUnicode_IsLinebreak(ch) #define Py_UNICODE_TOLOWER(ch) _PyUnicode_ToLowercase(ch) diff --git a/Include/internal/pycore_unicodeobject.h b/Include/internal/pycore_unicodeobject.h index fea5ceea0954f4..340e89801f1d43 100644 --- a/Include/internal/pycore_unicodeobject.h +++ b/Include/internal/pycore_unicodeobject.h @@ -21,8 +21,6 @@ extern int _PyUnicode_ToLowerFull(Py_UCS4 ch, Py_UCS4 *res); extern int _PyUnicode_ToTitleFull(Py_UCS4 ch, Py_UCS4 *res); extern int _PyUnicode_ToUpperFull(Py_UCS4 ch, Py_UCS4 *res); extern int _PyUnicode_ToFoldedFull(Py_UCS4 ch, Py_UCS4 *res); -extern int _PyUnicode_IsCaseIgnorable(Py_UCS4 ch); -extern int _PyUnicode_IsCased(Py_UCS4 ch); /* --- Unicode API -------------------------------------------------------- */ diff --git a/Include/unicodeobject.h b/Include/unicodeobject.h index dee00715b3c51d..ec12357ab64800 100644 --- a/Include/unicodeobject.h +++ b/Include/unicodeobject.h @@ -1007,6 +1007,30 @@ PyAPI_FUNC(int) PyUnicode_Contains( PyAPI_FUNC(int) PyUnicode_IsIdentifier(PyObject *s); +/* Lowercases character and adds result to buffer */ + +PyAPI_FUNC(Py_ssize_t) PyUnicode_ToLower( + Py_UCS4 ch, + Py_UCS4 *buffer, + Py_ssize_t size + ); + +/* Uppercases character and adds result to buffer */ + +PyAPI_FUNC(Py_ssize_t) PyUnicode_ToUpper( + Py_UCS4 ch, + Py_UCS4 *buffer, + Py_ssize_t size + ); + +/* Titlecases character and adds result to buffer */ + +PyAPI_FUNC(Py_ssize_t) PyUnicode_ToTitle( + Py_UCS4 ch, + Py_UCS4 *buffer, + Py_ssize_t size + ); + /* === Characters Type APIs =============================================== */ #ifndef Py_LIMITED_API diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index e412af5f797e7a..92c9bab9732e72 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -9616,6 +9616,36 @@ case_operation(PyObject *self, return res; } +Py_ssize_t +PyUnicode_ToLower(Py_UCS4 ch, Py_UCS4 *buffer, Py_ssize_t size) +{ + Py_ssize_t n = _PyUnicode_ToLowerFull(ch, buffer); + if (n > size) { + return -1; + } + return n; +} + +Py_ssize_t +PyUnicode_ToUpper(Py_UCS4 ch, Py_UCS4 *buffer, Py_ssize_t size) +{ + Py_ssize_t n = _PyUnicode_ToUpperFull(ch, buffer); + if (n > size) { + return -1; + } + return n; +} + +Py_ssize_t +PyUnicode_ToTitle(Py_UCS4 ch, Py_UCS4 *buffer, Py_ssize_t size) +{ + Py_ssize_t n = _PyUnicode_ToTitleFull(ch, buffer); + if (n > size) { + return -1; + } + return n; +} + PyObject * PyUnicode_Join(PyObject *separator, PyObject *seq) {