diff options
author | Victor Stinner <vstinner@python.org> | 2022-03-31 07:59:27 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-03-31 07:59:27 (GMT) |
commit | c14d7e4b816134b8e93ece4066a86d229631ce96 (patch) | |
tree | 6b2ac5b9c3e502d77d1ff05bdcc88e918dba1ad4 /Include | |
parent | db4dada5108dd49ebca23e4559a53630a2df8447 (diff) | |
download | cpython-c14d7e4b816134b8e93ece4066a86d229631ce96.zip cpython-c14d7e4b816134b8e93ece4066a86d229631ce96.tar.gz cpython-c14d7e4b816134b8e93ece4066a86d229631ce96.tar.bz2 |
bpo-47164: Add _PyASCIIObject_CAST() macro (GH-32191)
Add macros to cast objects to PyASCIIObject*, PyCompactUnicodeObject*
and PyUnicodeObject*: _PyASCIIObject_CAST(),
_PyCompactUnicodeObject_CAST() and _PyUnicodeObject_CAST(). Using
these new macros make the code more readable and check their argument
with: assert(PyUnicode_Check(op)).
Remove redundant assert(PyUnicode_Check(op)) in macros using directly
or indirectly these new CAST macros.
Replacing existing casts with these macros.
Diffstat (limited to 'Include')
-rw-r--r-- | Include/cpython/unicodeobject.h | 67 | ||||
-rw-r--r-- | Include/unicodeobject.h | 2 |
2 files changed, 35 insertions, 34 deletions
diff --git a/Include/cpython/unicodeobject.h b/Include/cpython/unicodeobject.h index 77a171b..69e4abf 100644 --- a/Include/cpython/unicodeobject.h +++ b/Include/cpython/unicodeobject.h @@ -234,6 +234,15 @@ PyAPI_FUNC(int) _PyUnicode_CheckConsistency( PyObject *op, int check_content); + +#define _PyASCIIObject_CAST(op) \ + (assert(PyUnicode_Check(op)), (PyASCIIObject*)(op)) +#define _PyCompactUnicodeObject_CAST(op) \ + (assert(PyUnicode_Check(op)), (PyCompactUnicodeObject*)(op)) +#define _PyUnicodeObject_CAST(op) \ + (assert(PyUnicode_Check(op)), (PyUnicodeObject*)(op)) + + /* Fast access macros */ /* Returns the deprecated Py_UNICODE representation's size in code units @@ -243,11 +252,10 @@ PyAPI_FUNC(int) _PyUnicode_CheckConsistency( /* Py_DEPRECATED(3.3) */ #define PyUnicode_GET_SIZE(op) \ - (assert(PyUnicode_Check(op)), \ - (((PyASCIIObject *)(op))->wstr) ? \ + (_PyASCIIObject_CAST(op)->wstr ? \ PyUnicode_WSTR_LENGTH(op) : \ ((void)PyUnicode_AsUnicode(_PyObject_CAST(op)),\ - assert(((PyASCIIObject *)(op))->wstr), \ + assert(_PyASCIIObject_CAST(op)->wstr), \ PyUnicode_WSTR_LENGTH(op))) /* Py_DEPRECATED(3.3) */ @@ -261,9 +269,8 @@ PyAPI_FUNC(int) _PyUnicode_CheckConsistency( /* Py_DEPRECATED(3.3) */ #define PyUnicode_AS_UNICODE(op) \ - (assert(PyUnicode_Check(op)), \ - (((PyASCIIObject *)(op))->wstr) ? (((PyASCIIObject *)(op))->wstr) : \ - PyUnicode_AsUnicode(_PyObject_CAST(op))) + (_PyASCIIObject_CAST(op)->wstr ? _PyASCIIObject_CAST(op)->wstr : \ + PyUnicode_AsUnicode(_PyObject_CAST(op))) /* Py_DEPRECATED(3.3) */ #define PyUnicode_AS_DATA(op) \ @@ -281,25 +288,24 @@ PyAPI_FUNC(int) _PyUnicode_CheckConsistency( /* Use only if you know it's a string */ #define PyUnicode_CHECK_INTERNED(op) \ - (((PyASCIIObject *)(op))->state.interned) + (_PyASCIIObject_CAST(op)->state.interned) /* Return true if the string contains only ASCII characters, or 0 if not. The string may be compact (PyUnicode_IS_COMPACT_ASCII) or not, but must be ready. */ #define PyUnicode_IS_ASCII(op) \ - (assert(PyUnicode_Check(op)), \ - assert(PyUnicode_IS_READY(op)), \ - ((PyASCIIObject*)op)->state.ascii) + (assert(PyUnicode_IS_READY(op)), \ + _PyASCIIObject_CAST(op)->state.ascii) /* Return true if the string is compact or 0 if not. No type checks or Ready calls are performed. */ #define PyUnicode_IS_COMPACT(op) \ - (((PyASCIIObject*)(op))->state.compact) + (_PyASCIIObject_CAST(op)->state.compact) /* Return true if the string is a compact ASCII string (use PyASCIIObject structure), or 0 if not. No type checks or Ready calls are performed. */ #define PyUnicode_IS_COMPACT_ASCII(op) \ - (((PyASCIIObject*)op)->state.ascii && PyUnicode_IS_COMPACT(op)) + (_PyASCIIObject_CAST(op)->state.ascii && PyUnicode_IS_COMPACT(op)) enum PyUnicode_Kind { /* String contains only wstr byte characters. This is only possible @@ -323,23 +329,21 @@ enum PyUnicode_Kind { /* Return one of the PyUnicode_*_KIND values defined above. */ #define PyUnicode_KIND(op) \ - (assert(PyUnicode_Check(op)), \ - assert(PyUnicode_IS_READY(op)), \ - ((PyASCIIObject *)(op))->state.kind) + (assert(PyUnicode_IS_READY(op)), \ + _PyASCIIObject_CAST(op)->state.kind) /* Return a void pointer to the raw unicode buffer. */ #define _PyUnicode_COMPACT_DATA(op) \ - (PyUnicode_IS_ASCII(op) ? \ - ((void*)((PyASCIIObject*)(op) + 1)) : \ - ((void*)((PyCompactUnicodeObject*)(op) + 1))) + (PyUnicode_IS_ASCII(op) ? \ + ((void*)(_PyASCIIObject_CAST(op) + 1)) : \ + ((void*)(_PyCompactUnicodeObject_CAST(op) + 1))) #define _PyUnicode_NONCOMPACT_DATA(op) \ - (assert(((PyUnicodeObject*)(op))->data.any), \ - ((((PyUnicodeObject *)(op))->data.any))) + (assert(_PyUnicodeObject_CAST(op)->data.any), \ + (_PyUnicodeObject_CAST(op)->data.any)) #define PyUnicode_DATA(op) \ - (assert(PyUnicode_Check(op)), \ - PyUnicode_IS_COMPACT(op) ? _PyUnicode_COMPACT_DATA(op) : \ + (PyUnicode_IS_COMPACT(op) ? _PyUnicode_COMPACT_DATA(op) : \ _PyUnicode_NONCOMPACT_DATA(op)) /* In the access macros below, "kind" may be evaluated more than once. @@ -386,8 +390,7 @@ enum PyUnicode_Kind { PyUnicode_READ_CHAR, for multiple consecutive reads callers should cache kind and use PyUnicode_READ instead. */ #define PyUnicode_READ_CHAR(unicode, index) \ - (assert(PyUnicode_Check(unicode)), \ - assert(PyUnicode_IS_READY(unicode)), \ + (assert(PyUnicode_IS_READY(unicode)), \ (Py_UCS4) \ (PyUnicode_KIND((unicode)) == PyUnicode_1BYTE_KIND ? \ ((const Py_UCS1 *)(PyUnicode_DATA((unicode))))[(index)] : \ @@ -401,23 +404,21 @@ enum PyUnicode_Kind { the string has it's canonical representation set before calling this macro. Call PyUnicode_(FAST_)Ready to ensure that. */ #define PyUnicode_GET_LENGTH(op) \ - (assert(PyUnicode_Check(op)), \ - assert(PyUnicode_IS_READY(op)), \ - ((PyASCIIObject *)(op))->length) + (assert(PyUnicode_IS_READY(op)), \ + _PyASCIIObject_CAST(op)->length) /* Fast check to determine whether an object is ready. Equivalent to - PyUnicode_IS_COMPACT(op) || ((PyUnicodeObject*)(op))->data.any */ + PyUnicode_IS_COMPACT(op) || _PyUnicodeObject_CAST(op)->data.any */ -#define PyUnicode_IS_READY(op) (((PyASCIIObject*)op)->state.ready) +#define PyUnicode_IS_READY(op) (_PyASCIIObject_CAST(op)->state.ready) /* PyUnicode_READY() does less work than _PyUnicode_Ready() in the best case. If the canonical representation is not yet set, it will still call _PyUnicode_Ready(). Returns 0 on success and -1 on errors. */ #define PyUnicode_READY(op) \ - (assert(PyUnicode_Check(op)), \ - (PyUnicode_IS_READY(op) ? \ + ((PyUnicode_IS_READY(op) ? \ 0 : _PyUnicode_Ready(_PyObject_CAST(op)))) /* Return a maximum character value which is suitable for creating another @@ -436,8 +437,8 @@ enum PyUnicode_Kind { Py_DEPRECATED(3.3) static inline Py_ssize_t PyUnicode_WSTR_LENGTH(PyObject *op) { return PyUnicode_IS_COMPACT_ASCII(op) ? - ((PyASCIIObject*)op)->length : - ((PyCompactUnicodeObject*)op)->wstr_length; + _PyASCIIObject_CAST(op)->length : + _PyCompactUnicodeObject_CAST(op)->wstr_length; } #define PyUnicode_WSTR_LENGTH(op) PyUnicode_WSTR_LENGTH(_PyObject_CAST(op)) diff --git a/Include/unicodeobject.h b/Include/unicodeobject.h index 6426c5d..1d2f546 100644 --- a/Include/unicodeobject.h +++ b/Include/unicodeobject.h @@ -112,7 +112,7 @@ PyAPI_DATA(PyTypeObject) PyUnicode_Type; PyAPI_DATA(PyTypeObject) PyUnicodeIter_Type; #define PyUnicode_Check(op) \ - PyType_FastSubclass(Py_TYPE(op), Py_TPFLAGS_UNICODE_SUBCLASS) + PyType_FastSubclass(Py_TYPE(op), Py_TPFLAGS_UNICODE_SUBCLASS) #define PyUnicode_CheckExact(op) Py_IS_TYPE(op, &PyUnicode_Type) /* --- Constants ---------------------------------------------------------- */ |