Index: Modules/_ctypes/_ctypes.c =================================================================== --- Modules/_ctypes/_ctypes.c (revision 73339) +++ Modules/_ctypes/_ctypes.c (working copy) @@ -4729,9 +4729,76 @@ return memcmp(self->b_ptr, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", self->b_size); } +static PyObject * +_SimplePtr_inplace_offset(CDataObject *self, Py_ssize_t diff) +{ + char *fmt; + StgDictObject *dict = PyObject_stgdict((PyObject *)self); + assert(dict); + fmt = PyString_AsString(dict->proto); + assert(fmt); + switch (fmt[0]) { + case 'z': + *(char **)self->b_ptr += diff; + Py_INCREF(self); + return (PyObject *)self; + case 'Z': + *(char **)self->b_ptr += diff * sizeof(wchar_t); + Py_INCREF(self); + return (PyObject *)self; + + default: + PyErr_SetString(PyExc_TypeError, "unsupported operand types"); + return NULL; + } +} + +static PyObject * +Simple_inplace_add(CDataObject *self, PyObject *other) +{ + Py_ssize_t diff; + diff = PyNumber_AsSsize_t(other, PyExc_OverflowError); + if (diff == -1 && PyErr_Occurred()) + return NULL; + return _SimplePtr_inplace_offset(self, diff); +} + +static PyObject * +Simple_inplace_substract(CDataObject *self, PyObject *other) +{ + Py_ssize_t diff; + diff = PyNumber_AsSsize_t(other, PyExc_OverflowError); + if (diff == -1 && PyErr_Occurred()) + return NULL; + return _SimplePtr_inplace_offset(self, -diff); +} + +/* pointer - pointer -> integer */ +static PyObject * +Simple_substract(CDataObject *self, PyObject *other) +{ + if (Py_TYPE(self) == Py_TYPE(other)) { + StgDictObject *dict = PyObject_stgdict((PyObject *)self); + StgDictObject *itemdict = PyType_stgdict(dict->proto); + CDataObject *c_other = (CDataObject *)other; + Py_ssize_t diff; + char *fmt = PyString_AsString(dict->proto); + switch (fmt[0]) { + case 'z': + diff = *(char **)self->b_ptr - *(char **)c_other->b_ptr; + return PyInt_FromSsize_t(diff); + case 'Z': + diff = *(wchar_t **)self->b_ptr - *(wchar_t **)c_other->b_ptr; + return PyInt_FromSsize_t(diff); + } + } + PyErr_SetString(PyExc_TypeError, "unsupported operand type(s)"); + return NULL; +} + static PyNumberMethods Simple_as_number = { 0, /* nb_add */ - 0, /* nb_subtract */ + Simple_substract, /* nb_subtract */ 0, /* nb_multiply */ 0, /* nb_divide */ 0, /* nb_remainder */ @@ -4741,6 +4808,23 @@ 0, /* nb_positive */ 0, /* nb_absolute */ (inquiry)Simple_nonzero, /* nb_nonzero */ + + 0, /* nb_invert */ + 0, /* nb_lshift */ + 0, /* nb_rshift */ + 0, /* nb_and */ + 0, /* nb_xor */ + 0, /* nb_or */ + 0, /* nb_coerce */ /* Used by the coerce() function */ + 0, /* nb_int */ + 0, /* nb_long */ + 0, /* nb_float */ + 0, /* nb_oct */ + 0, /* nb_hex */ + + /* Added in release 2.0 */ + (binaryfunc)Simple_inplace_add, /* nb_inplace_add */ + (binaryfunc)Simple_inplace_substract, /* nb_inplace_subtract */ }; /* "%s(%s)" % (self.__class__.__name__, self.value) */ @@ -5188,9 +5272,55 @@ return (*(void **)self->b_ptr != NULL); } +static PyObject * +_Pointer_inplace_offset(CDataObject *self, Py_ssize_t diff) +{ + StgDictObject *dict = PyObject_stgdict((PyObject *)self); + StgDictObject *itemdict; + assert(dict->proto); + itemdict = PyType_stgdict(dict->proto); + assert(itemdict); + *(char **)self->b_ptr += diff * itemdict->size; + Py_INCREF(self); + return (PyObject *)self; +} + +static PyObject * +Pointer_inplace_add(CDataObject *self, PyObject *other) +{ + Py_ssize_t diff = PyNumber_AsSsize_t(other, PyExc_OverflowError); + if (diff == -1 && PyErr_Occurred()) + return NULL; + return _Pointer_inplace_offset(self, diff); +} + +static PyObject * +Pointer_inplace_substract(CDataObject *self, PyObject *other) +{ + Py_ssize_t diff = PyNumber_AsSsize_t(other, PyExc_OverflowError); + if (diff == -1 && PyErr_Occurred()) + return NULL; + return _Pointer_inplace_offset(self, -diff); +} + +static PyObject * +Pointer_substract(CDataObject *self, PyObject *other) +{ + if (Py_TYPE(self) == Py_TYPE(other)) { + StgDictObject *dict = PyObject_stgdict(self); + StgDictObject *itemdict = PyType_stgdict(dict->proto); + CDataObject *c_other = (CDataObject *)other; + Py_ssize_t diff; + diff = *(char **)self->b_ptr - *(char **)c_other->b_ptr; + return PyInt_FromSsize_t(diff / itemdict->size); + } + PyErr_SetString(PyExc_TypeError, "unsupported operand type(s) for -"); + return NULL; +} + static PyNumberMethods Pointer_as_number = { 0, /* nb_add */ - 0, /* nb_subtract */ + Pointer_substract, /* nb_subtract */ 0, /* nb_multiply */ 0, /* nb_divide */ 0, /* nb_remainder */ @@ -5200,6 +5330,22 @@ 0, /* nb_positive */ 0, /* nb_absolute */ (inquiry)Pointer_nonzero, /* nb_nonzero */ + 0, /* nb_invert */ + 0, /* nb_lshift */ + 0, /* nb_rshift */ + 0, /* nb_and */ + 0, /* nb_xor */ + 0, /* nb_or */ + 0, /* nb_coerce */ /* Used by the coerce() function */ + 0, /* nb_int */ + 0, /* nb_long */ + 0, /* nb_float */ + 0, /* nb_oct */ + 0, /* nb_hex */ + + /* Added in release 2.0 */ + (binaryfunc)Pointer_inplace_add, /* nb_inplace_add */ + (binaryfunc)Pointer_inplace_substract, /* nb_inplace_subtract */ }; PyTypeObject PyCPointer_Type = {