Author: Armin Rigo <ar...@tunes.org> Branch: Changeset: r1395:88d2b9436efd Date: 2013-11-09 09:09 +0100 http://bitbucket.org/cffi/cffi/changeset/88d2b9436efd/
Log: Arithmetic using "void *" should work; at least it does in gcc without warning. diff --git a/c/_cffi_backend.c b/c/_cffi_backend.c --- a/c/_cffi_backend.c +++ b/c/_cffi_backend.c @@ -2050,7 +2050,7 @@ static PyObject * _cdata_add_or_sub(PyObject *v, PyObject *w, int sign) { - Py_ssize_t i; + Py_ssize_t i, itemsize; CDataObject *cd; CTypeDescrObject *ctptr; @@ -2073,14 +2073,19 @@ cd->c_type->ct_name); return NULL; } - if (ctptr->ct_itemdescr->ct_size < 0) { - PyErr_Format(PyExc_TypeError, - "ctype '%s' points to items of unknown size", - cd->c_type->ct_name); - return NULL; - } - return new_simple_cdata(cd->c_data + i * ctptr->ct_itemdescr->ct_size, - ctptr); + itemsize = ctptr->ct_itemdescr->ct_size; + if (itemsize < 0) { + if (ctptr->ct_flags & CT_IS_VOID_PTR) { + itemsize = 1; + } + else { + PyErr_Format(PyExc_TypeError, + "ctype '%s' points to items of unknown size", + cd->c_type->ct_name); + return NULL; + } + } + return new_simple_cdata(cd->c_data + i * itemsize, ctptr); not_implemented: Py_INCREF(Py_NotImplemented); @@ -2101,18 +2106,23 @@ CDataObject *cdw = (CDataObject *)w; CTypeDescrObject *ct = cdw->c_type; Py_ssize_t diff; + Py_ssize_t itemsize; if (ct->ct_flags & CT_ARRAY) /* ptr_to_T - array_of_T: ok */ ct = (CTypeDescrObject *)ct->ct_stuff; + itemsize = ct->ct_itemdescr->ct_size; + if (ct->ct_flags & CT_IS_VOID_PTR) + itemsize = 1; + if (ct != cdv->c_type || !(ct->ct_flags & CT_POINTER) || - (ct->ct_itemdescr->ct_size <= 0)) { + (itemsize <= 0)) { PyErr_Format(PyExc_TypeError, "cannot subtract cdata '%s' and cdata '%s'", cdv->c_type->ct_name, ct->ct_name); return NULL; } - diff = (cdv->c_data - cdw->c_data) / ct->ct_itemdescr->ct_size; + diff = (cdv->c_data - cdw->c_data) / itemsize; #if PY_MAJOR_VERSION < 3 return PyInt_FromSsize_t(diff); #else diff --git a/c/test_c.py b/c/test_c.py --- a/c/test_c.py +++ b/c/test_c.py @@ -1642,9 +1642,6 @@ def test_void_errors(): py.test.raises(ValueError, alignof, new_void_type()) py.test.raises(TypeError, newp, new_pointer_type(new_void_type()), None) - x = cast(new_pointer_type(new_void_type()), 42) - py.test.raises(TypeError, "x + 1") - py.test.raises(TypeError, "x - 1") def test_too_many_items(): BChar = new_primitive_type("char") @@ -3108,6 +3105,18 @@ py.test.raises(TypeError, "p[1:5] = b'XYZT'") py.test.raises(TypeError, "p[1:5] = [1, 2, 3, 4]") +def test_void_p_arithmetic(): + BVoid = new_void_type() + BInt = new_primitive_type("intptr_t") + p = cast(new_pointer_type(BVoid), 100000) + assert int(cast(BInt, p)) == 100000 + assert int(cast(BInt, p + 42)) == 100042 + assert int(cast(BInt, p - (-42))) == 100042 + assert (p + 42) - p == 42 + q = cast(new_pointer_type(new_primitive_type("char")), 100000) + py.test.raises(TypeError, "p - q") + py.test.raises(TypeError, "q - p") + def test_version(): # this test is here mostly for PyPy _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit