[ctypes-commit] ctypes/source stgdict.c,1.23,1.23.2.1 ctypes.h,1.59.2.1,1.59.2.2 _ctypes.c,1.182,1.1
Brought to you by:
theller
From: Thomas H. <th...@us...> - 2004-11-10 10:33:10
|
Update of /cvsroot/ctypes/ctypes/source In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv9477 Modified Files: Tag: DELAYED_STRUCTS_BRANCH stgdict.c ctypes.h _ctypes.c Log Message: Support for delay struct and union definition is now done. Index: ctypes.h =================================================================== RCS file: /cvsroot/ctypes/ctypes/source/ctypes.h,v retrieving revision 1.59.2.1 retrieving revision 1.59.2.2 diff -C2 -d -r1.59.2.1 -r1.59.2.2 *** ctypes.h 5 Nov 2004 10:50:13 -0000 1.59.2.1 --- ctypes.h 10 Nov 2004 10:32:53 -0000 1.59.2.2 *************** *** 68,72 **** #define StgDict_CheckExact(v) ((v)->ob_type == &StgDict_Type) #define StgDict_Check(v) PyObject_TypeCheck(v, &StgDict_Type) ! extern PyObject *StgDict_ForType(PyObject *type, int isStruct); extern int PyType_stginfo(PyTypeObject *self, int *psize, int *palign, int *plength); extern int PyObject_stginfo(PyObject *self, int *psize, int *palign, int *plength); --- 68,73 ---- #define StgDict_CheckExact(v) ((v)->ob_type == &StgDict_Type) #define StgDict_Check(v) PyObject_TypeCheck(v, &StgDict_Type) ! ! extern int StructUnionType_update_stgdict(PyObject *fields, PyObject *type, int isStruct); extern int PyType_stginfo(PyTypeObject *self, int *psize, int *palign, int *plength); extern int PyObject_stginfo(PyObject *self, int *psize, int *palign, int *plength); *************** *** 175,178 **** --- 176,181 ---- extern StgDictObject *PyObject_stgdict(PyObject *self); + extern int StgDict_clone(StgDictObject *src, StgDictObject *dst); + typedef int(* PPROC)(void); Index: stgdict.c =================================================================== RCS file: /cvsroot/ctypes/ctypes/source/stgdict.c,v retrieving revision 1.23 retrieving revision 1.23.2.1 diff -C2 -d -r1.23 -r1.23.2.1 *** stgdict.c 4 Nov 2004 20:42:56 -0000 1.23 --- stgdict.c 10 Nov 2004 10:32:53 -0000 1.23.2.1 *************** *** 25,28 **** --- 25,31 ---- { Py_CLEAR(self->proto); + Py_CLEAR(self->argtypes); + Py_CLEAR(self->converters); + Py_CLEAR(self->restype); return 0; } *************** *** 36,39 **** --- 39,68 ---- } + int + StgDict_clone(StgDictObject *dst, StgDictObject *src) + { + char *d, *s; + int size; + + StgDict_clear(dst); + + d = (char *)dst; + s = (char *)src; + memcpy(d + sizeof(PyDictObject), + s + sizeof(PyDictObject), + sizeof(StgDictObject) - sizeof(PyDictObject)); + + Py_XINCREF(dst->proto); + Py_XINCREF(dst->argtypes); + Py_XINCREF(dst->converters); + Py_XINCREF(dst->restype); + + size = sizeof(ffi_type *) * (src->length + 1); + dst->ffi_type.elements = PyMem_Malloc(size); + if (dst->ffi_type.elements == NULL) + return -1; + memcpy(dst->ffi_type.elements, src->ffi_type.elements, size); + return 0; + } PyTypeObject StgDict_Type = { *************** *** 132,137 **** and create an StgDictObject. Used for Structure and Union subclasses. */ ! PyObject * ! StgDict_ForType(PyObject *type, int isStruct) { StgDictObject *stgdict; --- 161,166 ---- and create an StgDictObject. Used for Structure and Union subclasses. */ ! int ! StructUnionType_update_stgdict(PyObject *type, PyObject *fields, int isStruct) { StgDictObject *stgdict; *************** *** 141,147 **** int bitofs; PyObject *isPacked; - PyObject *fields; int pack = 0; isPacked = PyObject_GetAttrString(type, "_pack_"); if (isPacked) { --- 170,178 ---- int bitofs; PyObject *isPacked; int pack = 0; + if (fields == NULL) + return 0; + isPacked = PyObject_GetAttrString(type, "_pack_"); if (isPacked) { *************** *** 151,155 **** PyErr_SetString(PyExc_ValueError, "_pack_ must be a non-negative integer"); ! return NULL; } Py_DECREF(isPacked); --- 182,186 ---- PyErr_SetString(PyExc_ValueError, "_pack_ must be a non-negative integer"); ! return -1; } Py_DECREF(isPacked); *************** *** 157,182 **** PyErr_Clear(); - fields = PyObject_GetAttrString(type, "_fields_"); - if (!fields) { - PyErr_SetString(PyExc_AttributeError, - "class must define a '_fields_' attribute"); - return NULL; - } - len = PySequence_Length(fields); if (len == -1) { PyErr_SetString(PyExc_AttributeError, "'_fields_' must be a sequence of pairs"); ! Py_DECREF(fields); ! return NULL; } ! stgdict = (StgDictObject *)PyObject_CallObject( ! (PyObject *)&StgDict_Type, NULL); ! if (!stgdict) { ! Py_DECREF(fields); ! return NULL; ! } offset = 0; size = 0; --- 188,205 ---- PyErr_Clear(); len = PySequence_Length(fields); if (len == -1) { PyErr_SetString(PyExc_AttributeError, "'_fields_' must be a sequence of pairs"); ! return -1; } ! stgdict = PyType_stgdict(type); ! if (!stgdict) ! return -1; + if (stgdict->ffi_type.elements) + PyMem_Free(stgdict->ffi_type.elements); + offset = 0; size = 0; *************** *** 197,206 **** int bitsize = 0; ! if (!pair || !PyArg_ParseTuple(pair, "OO|i", &name, &desc, &bitsize)) { PyErr_SetString(PyExc_AttributeError, "'_fields_' must be a sequence of pairs"); - Py_DECREF(fields); Py_XDECREF(pair); ! return NULL; } dict = PyType_stgdict(desc); --- 220,228 ---- int bitsize = 0; ! if (!pair || !PyArg_ParseTuple(pair, "OO|i", &name, &desc, &bitsize)) { PyErr_SetString(PyExc_AttributeError, "'_fields_' must be a sequence of pairs"); Py_XDECREF(pair); ! return -1; } dict = PyType_stgdict(desc); *************** *** 230,243 **** "bit fields not allowed for type %s", ((PyTypeObject *)desc)->tp_name); - Py_DECREF(fields); Py_DECREF(pair); ! return NULL; } if (bitsize <= 0 || bitsize > dict->size * 8) { PyErr_SetString(PyExc_ValueError, "number of bits invalid for bit field"); - Py_DECREF(fields); Py_DECREF(pair); ! return NULL; } } else --- 252,263 ---- "bit fields not allowed for type %s", ((PyTypeObject *)desc)->tp_name); Py_DECREF(pair); ! return -1; } if (bitsize <= 0 || bitsize > dict->size * 8) { PyErr_SetString(PyExc_ValueError, "number of bits invalid for bit field"); Py_DECREF(pair); ! return -1; } } else *************** *** 259,273 **** if (!prop) { - Py_DECREF(fields); Py_DECREF(pair); Py_DECREF((PyObject *)stgdict); ! return NULL; } if (-1 == PyDict_SetItem(realdict, name, prop)) { - Py_DECREF(fields); Py_DECREF(prop); Py_DECREF(pair); Py_DECREF((PyObject *)stgdict); ! return NULL; } Py_DECREF(pair); --- 279,291 ---- if (!prop) { Py_DECREF(pair); Py_DECREF((PyObject *)stgdict); ! return -1; } if (-1 == PyDict_SetItem(realdict, name, prop)) { Py_DECREF(prop); Py_DECREF(pair); Py_DECREF((PyObject *)stgdict); ! return -1; } Py_DECREF(pair); *************** *** 275,280 **** } #undef realdict - Py_DECREF(fields); - if (!isStruct) size = union_size; --- 293,296 ---- *************** *** 289,292 **** stgdict->align = total_align; stgdict->length = len; ! return (PyObject *)stgdict; } --- 305,308 ---- stgdict->align = total_align; stgdict->length = len; ! return 0; } Index: _ctypes.c =================================================================== RCS file: /cvsroot/ctypes/ctypes/source/_ctypes.c,v retrieving revision 1.182 retrieving revision 1.182.2.1 diff -C2 -d -r1.182 -r1.182.2.1 *** _ctypes.c 5 Nov 2004 10:36:36 -0000 1.182 --- _ctypes.c 10 Nov 2004 10:32:53 -0000 1.182.2.1 *************** *** 115,119 **** { PyTypeObject *result; ! PyObject *dict; /* create the new instance (which is a class, --- 115,120 ---- { PyTypeObject *result; ! PyObject *fields; ! StgDictObject *dict; /* create the new instance (which is a class, *************** *** 127,146 **** return (PyObject *)result; ! dict = StgDict_ForType((PyObject *)result, isStruct); if (!dict) { Py_DECREF(result); return NULL; } - /* replace the class dict by our updated stgdict, which holds info about storage requirements of the instances */ ! if (-1 == PyDict_Update(dict, result->tp_dict)) { Py_DECREF(result); ! Py_DECREF(dict); return NULL; } Py_DECREF(result->tp_dict); ! result->tp_dict = dict; return (PyObject *)result; } --- 128,164 ---- return (PyObject *)result; ! dict = (StgDictObject *)PyObject_CallObject((PyObject *)&StgDict_Type, NULL); if (!dict) { Py_DECREF(result); return NULL; } /* replace the class dict by our updated stgdict, which holds info about storage requirements of the instances */ ! if (-1 == PyDict_Update((PyObject *)dict, result->tp_dict)) { Py_DECREF(result); ! Py_DECREF((PyObject *)dict); return NULL; } Py_DECREF(result->tp_dict); ! result->tp_dict = (PyObject *)dict; ! ! fields = PyDict_GetItemString((PyObject *)dict, "_fields_"); ! if (!fields) { ! StgDictObject *basedict = PyType_stgdict((PyObject *)result->tp_base); + if (basedict == NULL) + return (PyObject *)result; + /* copy base dict */ + if (-1 == StgDict_clone(dict, basedict)) { + Py_DECREF(result); + return NULL; + } + return (PyObject *)result; + } + + if (-1 == PyObject_SetAttrString((PyObject *)result, "_fields_", fields)) { + Py_DECREF(result); + return NULL; + } return (PyObject *)result; } *************** *** 314,317 **** --- 332,363 ---- } + static int + StructType_setattro(PyObject *self, PyObject *key, PyObject *value) + { + /* XXX Should we disallow deleting _fields_? */ + if (-1 == PyObject_GenericSetAttr(self, key, value)) + return -1; + + if (value && PyString_Check(key) && + 0 == strcmp(PyString_AS_STRING(key), "_fields_")) + return StructUnionType_update_stgdict(self, value, 1); + return 0; + } + + + static int + UnionType_setattro(PyObject *self, PyObject *key, PyObject *value) + { + /* XXX Should we disallow deleting _fields_? */ + if (-1 == PyObject_GenericSetAttr(self, key, value)) + return -1; + + if (PyString_Check(key) && + 0 == strcmp(PyString_AS_STRING(key), "_fields_")) + return StructUnionType_update_stgdict(self, value, 0); + return 0; + } + + static PyTypeObject StructType_Type = { PyObject_HEAD_INIT(NULL) *************** *** 333,337 **** 0, /* tp_str */ 0, /* tp_getattro */ ! 0, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, /* tp_flags */ --- 379,383 ---- 0, /* tp_str */ 0, /* tp_getattro */ ! StructType_setattro, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, /* tp_flags */ *************** *** 376,380 **** 0, /* tp_str */ 0, /* tp_getattro */ ! 0, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, /* tp_flags */ --- 422,426 ---- 0, /* tp_str */ 0, /* tp_getattro */ ! UnionType_setattro, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, /* tp_flags */ |