ctypes-commit Mailing List for ctypes (Page 90)
Brought to you by:
theller
You can subscribe to this list here.
2004 |
Jan
|
Feb
|
Mar
|
Apr
(8) |
May
(90) |
Jun
(143) |
Jul
(106) |
Aug
(94) |
Sep
(84) |
Oct
(163) |
Nov
(60) |
Dec
(58) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2005 |
Jan
(128) |
Feb
(79) |
Mar
(227) |
Apr
(192) |
May
(179) |
Jun
(41) |
Jul
(53) |
Aug
(103) |
Sep
(28) |
Oct
(38) |
Nov
(81) |
Dec
(17) |
2006 |
Jan
(184) |
Feb
(111) |
Mar
(188) |
Apr
(67) |
May
(58) |
Jun
(123) |
Jul
(73) |
Aug
|
Sep
|
Oct
(1) |
Nov
|
Dec
|
From: Thomas H. <th...@us...> - 2004-10-11 09:00:10
|
Update of /cvsroot/ctypes/ctypes/ctypes In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv27621 Modified Files: __init__.py Log Message: Enable unicode on non-windows platforms. Index: __init__.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/ctypes/__init__.py,v retrieving revision 1.38 retrieving revision 1.39 diff -C2 -d -r1.38 -r1.39 *** __init__.py 8 Oct 2004 20:17:41 -0000 1.38 --- __init__.py 11 Oct 2004 08:59:50 -0000 1.39 *************** *** 58,81 **** raise TypeError, init - def create_unicode_buffer(init, size=None): - """create_unicode_buffer(aString) -> character array - create_unicode_buffer(anInteger) -> character array - create_unicode_buffer(aString, anInteger) -> character array - """ - if isinstance(init, (str, unicode)): - init = unicode(init) - if size is None: - size = len(init)+1 - buftype = c_wchar * size - buf = buftype() - buf.value = init - return buf - elif isinstance(init, (int, long)): - buftype = c_wchar * init - buf = buftype() - return buf - raise TypeError, init - - def c_buffer(init, size=None): ## "deprecated, use create_string_buffer instead" --- 58,61 ---- *************** *** 206,220 **** c_voidp = c_void_p # backwards compatibility (to a bug) - if _os.name == "nt": - class c_wchar_p(_SimpleCData): - _type_ = "Z" - def __repr__(self): - return "%s(%r)" % (self.__class__.__name__, self.value) - - class c_wchar(_SimpleCData): - _type_ = "u" - def __repr__(self): - return "c_wchar(%r)" % self.value - # This cache maps types to pointers to them. from _ctypes import _pointer_type_cache --- 186,189 ---- *************** *** 239,247 **** return klass ! POINTER(c_char).from_param = c_char_p.from_param #_SimpleCData.c_char_p_from_param - if _os.name == "nt": POINTER(c_wchar).from_param = c_wchar_p.from_param #_SimpleCData.c_wchar_p_from_param def SetPointerType(pointer, cls): if _pointer_type_cache.get(cls, None) is not None: --- 208,255 ---- return klass ! try: ! from _ctypes import set_conversion_mode ! except ImportError: ! pass ! else: ! if _os.name == "nt": ! set_conversion_mode("mbcs", "ignore") ! else: ! set_conversion_mode("ascii", "strict") ! ! class c_wchar_p(_SimpleCData): ! _type_ = "Z" ! def __repr__(self): ! return "%s(%r)" % (self.__class__.__name__, self.value) ! ! class c_wchar(_SimpleCData): ! _type_ = "u" ! def __repr__(self): ! return "c_wchar(%r)" % self.value POINTER(c_wchar).from_param = c_wchar_p.from_param #_SimpleCData.c_wchar_p_from_param + + def create_unicode_buffer(init, size=None): + """create_unicode_buffer(aString) -> character array + create_unicode_buffer(anInteger) -> character array + create_unicode_buffer(aString, anInteger) -> character array + """ + if isinstance(init, (str, unicode)): + init = unicode(init) + if size is None: + size = len(init)+1 + buftype = c_wchar * size + buf = buftype() + buf.value = init + return buf + elif isinstance(init, (int, long)): + buftype = c_wchar * init + buf = buftype() + return buf + raise TypeError, init + + POINTER(c_char).from_param = c_char_p.from_param #_SimpleCData.c_char_p_from_param + def SetPointerType(pointer, cls): if _pointer_type_cache.get(cls, None) is not None: *************** *** 369,381 **** return WindowsError(code, descr) - try: - from _ctypes import set_conversion_mode - except ImportError: - pass - else: - if _os.name == "nt": - set_conversion_mode("mbcs", "ignore") - else: - set_conversion_mode("ascii", "strict") - _pointer_type_cache[None] = c_void_p --- 377,379 ---- |
From: Thomas H. <th...@us...> - 2004-10-11 08:58:41
|
Update of /cvsroot/ctypes/ctypes/source In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv27421 Modified Files: stgdict.c cfield.c callproc.c _ctypes.c Log Message: Replace #ifdef HAVE_USABLE_WCHAR_T with #ifdef Py_USING_UNICODE to do proper detection of unicode support. Index: stgdict.c =================================================================== RCS file: /cvsroot/ctypes/ctypes/source/stgdict.c,v retrieving revision 1.15 retrieving revision 1.16 diff -C2 -d -r1.15 -r1.16 *** stgdict.c 6 Oct 2004 12:13:40 -0000 1.15 --- stgdict.c 11 Oct 2004 08:58:28 -0000 1.16 *************** *** 209,213 **** case FFI_TYPE_SINT16: if (dict->getfunc != getentry("c")->getfunc ! #ifdef HAVE_USABLE_WCHAR_T && dict->getfunc != getentry("u")->getfunc #endif --- 209,213 ---- case FFI_TYPE_SINT16: if (dict->getfunc != getentry("c")->getfunc ! #ifdef Py_USING_UNICODE && dict->getfunc != getentry("u")->getfunc #endif Index: callproc.c =================================================================== RCS file: /cvsroot/ctypes/ctypes/source/callproc.c,v retrieving revision 1.105 retrieving revision 1.106 diff -C2 -d -r1.105 -r1.106 *** callproc.c 8 Oct 2004 20:21:04 -0000 1.105 --- callproc.c 11 Oct 2004 08:58:28 -0000 1.106 *************** *** 501,505 **** } ! #ifdef HAVE_USABLE_WCHAR_T if (PyUnicode_Check(obj)) { pa->ffi_type = &ffi_type_pointer; --- 501,505 ---- } ! #ifdef Py_USING_UNICODE if (PyUnicode_Check(obj)) { pa->ffi_type = &ffi_type_pointer; *************** *** 1225,1229 **** } ! #ifdef HAVE_USABLE_WCHAR_T static PyObject * --- 1225,1229 ---- } ! #ifdef Py_USING_UNICODE static PyObject * *************** *** 1261,1265 **** struct argument a; CDataObject *result; - int size; if (!PyArg_ParseTuple(args, "OO", &obj, &ctype)) --- 1261,1264 ---- *************** *** 1267,1271 **** if (-1 == ConvParam(obj, 0, &a)) return NULL; ! result = PyObject_CallFunctionObjArgs(ctype, NULL); if (result == NULL) return NULL; --- 1266,1270 ---- if (-1 == ConvParam(obj, 0, &a)) return NULL; ! result = (CDataObject *)PyObject_CallFunctionObjArgs(ctype, NULL); if (result == NULL) return NULL; *************** *** 1274,1283 **** memcpy(result->b_ptr, &a.value, min(result->b_size, a.ffi_type->size)); ! return result; } PyMethodDef module_methods[] = { {"cast", cast, METH_VARARGS}, ! #ifdef HAVE_USABLE_WCHAR_T {"set_conversion_mode", set_conversion_mode, METH_VARARGS, set_conversion_mode_doc}, #endif --- 1273,1282 ---- memcpy(result->b_ptr, &a.value, min(result->b_size, a.ffi_type->size)); ! return (PyObject *)result; } PyMethodDef module_methods[] = { {"cast", cast, METH_VARARGS}, ! #ifdef Py_USING_UNICODE {"set_conversion_mode", set_conversion_mode, METH_VARARGS, set_conversion_mode_doc}, #endif Index: cfield.c =================================================================== RCS file: /cvsroot/ctypes/ctypes/source/cfield.c,v retrieving revision 1.45 retrieving revision 1.46 diff -C2 -d -r1.45 -r1.46 *** cfield.c 7 Oct 2004 18:54:37 -0000 1.45 --- cfield.c 11 Oct 2004 08:58:28 -0000 1.46 *************** *** 95,99 **** setfunc = fd->setfunc; } ! #ifdef HAVE_USABLE_WCHAR_T if (idict->getfunc == getentry("u")->getfunc) { struct fielddesc *fd = getentry("U"); --- 95,99 ---- setfunc = fd->setfunc; } ! #ifdef Py_USING_UNICODE if (idict->getfunc == getentry("u")->getfunc) { struct fielddesc *fd = getentry("U"); *************** *** 636,640 **** } ! #ifdef HAVE_USABLE_WCHAR_T /* u - a single unicode character */ static PyObject * --- 636,640 ---- } ! #ifdef Py_USING_UNICODE /* u - a single unicode character */ static PyObject * *************** *** 836,840 **** } ! #ifdef HAVE_USABLE_WCHAR_T static PyObject * Z_set(void *ptr, PyObject *value, unsigned size) --- 836,840 ---- } ! #ifdef Py_USING_UNICODE static PyObject * Z_set(void *ptr, PyObject *value, unsigned size) *************** *** 1004,1008 **** { 'P', P_set, P_get, &ffi_type_pointer}, { 'z', z_set, z_get, &ffi_type_pointer}, ! #ifdef HAVE_USABLE_WCHAR_T /* Correct or not? */ { 'u', u_set, u_get, &ffi_type_sshort}, --- 1004,1008 ---- { 'P', P_set, P_get, &ffi_type_pointer}, { 'z', z_set, z_get, &ffi_type_pointer}, ! #ifdef Py_USING_UNICODE /* Correct or not? */ { 'u', u_set, u_get, &ffi_type_sshort}, Index: _ctypes.c =================================================================== RCS file: /cvsroot/ctypes/ctypes/source/_ctypes.c,v retrieving revision 1.164 retrieving revision 1.165 diff -C2 -d -r1.164 -r1.165 *** _ctypes.c 8 Oct 2004 20:16:28 -0000 1.164 --- _ctypes.c 11 Oct 2004 08:58:28 -0000 1.165 *************** *** 736,740 **** }; ! #ifdef HAVE_USABLE_WCHAR_T static PyObject * WCharArray_get_value(CDataObject *self) --- 736,740 ---- }; ! #ifdef Py_USING_UNICODE static PyObject * WCharArray_get_value(CDataObject *self) *************** *** 926,930 **** if (-1 == add_getset(result, CharArray_getsets)) return NULL; ! #ifdef HAVE_USABLE_WCHAR_T } else if (itemdict->getfunc == getentry("u")->getfunc) { if (-1 == add_getset(result, WCharArray_getsets)) --- 926,930 ---- if (-1 == add_getset(result, CharArray_getsets)) return NULL; ! #ifdef Py_USING_UNICODE } else if (itemdict->getfunc == getentry("u")->getfunc) { if (-1 == add_getset(result, WCharArray_getsets)) *************** *** 2991,2995 **** char *ptr = (char *)self->b_ptr; return PyString_FromStringAndSize(ptr + ilow, len); ! #ifdef HAVE_USABLE_WCHAR_T } else if (itemdict->getfunc == getentry("u")->getfunc) { wchar_t *ptr = (wchar_t *)self->b_ptr; --- 2991,2995 ---- char *ptr = (char *)self->b_ptr; return PyString_FromStringAndSize(ptr + ilow, len); ! #ifdef Py_USING_UNICODE } else if (itemdict->getfunc == getentry("u")->getfunc) { wchar_t *ptr = (wchar_t *)self->b_ptr; *************** *** 3520,3524 **** char *ptr = *(char **)self->b_ptr; return PyString_FromStringAndSize(ptr + ilow, len); ! #ifdef HAVE_USABLE_WCHAR_T } else if (itemdict->getfunc == getentry("u")->getfunc) { wchar_t *ptr = *(wchar_t **)self->b_ptr; --- 3520,3524 ---- char *ptr = *(char **)self->b_ptr; return PyString_FromStringAndSize(ptr + ilow, len); ! #ifdef Py_USING_UNICODE } else if (itemdict->getfunc == getentry("u")->getfunc) { wchar_t *ptr = *(wchar_t **)self->b_ptr; |
From: Thomas H. <th...@us...> - 2004-10-08 20:22:24
|
Update of /cvsroot/ctypes/ctypes In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv32104 Modified Files: ChangeLog Log Message: Record changes. Index: ChangeLog =================================================================== RCS file: /cvsroot/ctypes/ctypes/ChangeLog,v retrieving revision 1.63 retrieving revision 1.64 diff -C2 -d -r1.63 -r1.64 *** ChangeLog 8 Oct 2004 20:19:14 -0000 1.63 --- ChangeLog 8 Oct 2004 20:22:10 -0000 1.64 *************** *** 1,4 **** --- 1,9 ---- 2004-10-08 Thomas Heller <th...@py...> + * source\callbacks.c: Added a cast function, which creates a new + ctypes type instance from an existing instance. Does not yet work + correctly for integers of different sizes, but should work for + pointers - and that's where it is needed. + * ctypes\__init__.py: POINTER(None) will now return c_void_p. This change was made to ease automatic code generation (and makes |
From: Thomas H. <th...@us...> - 2004-10-08 20:21:19
|
Update of /cvsroot/ctypes/ctypes/source In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv31870 Modified Files: callproc.c Log Message: Added a cast function, which creates a new ctypes type instance from an existing instance. Does not yet work correctly for integers of different sizes, but should work for pointers - and that's where it is needed. Index: callproc.c =================================================================== RCS file: /cvsroot/ctypes/ctypes/source/callproc.c,v retrieving revision 1.104 retrieving revision 1.105 diff -C2 -d -r1.104 -r1.105 *** callproc.c 16 Sep 2004 14:17:11 -0000 1.104 --- callproc.c 8 Oct 2004 20:21:04 -0000 1.105 *************** *** 1256,1260 **** --- 1256,1282 ---- #endif + static PyObject *cast(PyObject *self, PyObject *args) + { + PyObject *obj, *ctype; + struct argument a; + CDataObject *result; + int size; + + if (!PyArg_ParseTuple(args, "OO", &obj, &ctype)) + return NULL; + if (-1 == ConvParam(obj, 0, &a)) + return NULL; + result = PyObject_CallFunctionObjArgs(ctype, NULL); + if (result == NULL) + return NULL; + // result->b_size + // a.ffi_type->size + memcpy(result->b_ptr, &a.value, + min(result->b_size, a.ffi_type->size)); + return result; + } + PyMethodDef module_methods[] = { + {"cast", cast, METH_VARARGS}, #ifdef HAVE_USABLE_WCHAR_T {"set_conversion_mode", set_conversion_mode, METH_VARARGS, set_conversion_mode_doc}, |
From: Thomas H. <th...@us...> - 2004-10-08 20:19:32
|
Update of /cvsroot/ctypes/ctypes In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv31279 Modified Files: ChangeLog Log Message: Changes. Index: ChangeLog =================================================================== RCS file: /cvsroot/ctypes/ctypes/ChangeLog,v retrieving revision 1.62 retrieving revision 1.63 diff -C2 -d -r1.62 -r1.63 *** ChangeLog 28 Sep 2004 14:16:52 -0000 1.62 --- ChangeLog 8 Oct 2004 20:19:14 -0000 1.63 *************** *** 1,2 **** --- 1,26 ---- + 2004-10-08 Thomas Heller <th...@py...> + + * ctypes\__init__.py: POINTER(None) will now return c_void_p. + This change was made to ease automatic code generation (and makes + sense, since None is used in other places for 'void' as well. + + * source\_ctypes.c: ctypes _pointer_type_cache now lives in the + _ctypes module, to make it available to C code. + + Setting the _fields_ attribute on a Structure or Union type after + creation automatically update the POINTER instance to it when it + already exists, this allows to use POINTER(<type>) in the _fields_ + list without need to update the POINTER type later. + + Implemented a customg from_param class method for CFuncPtrType: + Python callables can now be passed directly as arguments to + functions requiring callbacks: WINFUNCTYPE() or CFUNCTYPE() in the + argtypes list. + + To avoid having to keep a reference to the created callback + function explicitely (which will always be forgotten), started + code to keep a reference automatically - currently this only works + for functions, *not* for methods!!! + 2004-09-28 Thomas Heller <th...@py...> |
From: Thomas H. <th...@us...> - 2004-10-08 20:17:52
|
Update of /cvsroot/ctypes/ctypes/ctypes In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv30965 Modified Files: __init__.py Log Message: ctypes _pointer_type_cache now lives in the _ctypes module, to make it available to C code. Index: __init__.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/ctypes/__init__.py,v retrieving revision 1.37 retrieving revision 1.38 diff -C2 -d -r1.37 -r1.38 *** __init__.py 21 Sep 2004 14:22:32 -0000 1.37 --- __init__.py 8 Oct 2004 20:17:41 -0000 1.38 *************** *** 218,222 **** # This cache maps types to pointers to them. ! _pointer_type_cache = {} def POINTER(cls): --- 218,222 ---- # This cache maps types to pointers to them. ! from _ctypes import _pointer_type_cache def POINTER(cls): *************** *** 378,379 **** --- 378,381 ---- else: set_conversion_mode("ascii", "strict") + + _pointer_type_cache[None] = c_void_p |
From: Thomas H. <th...@us...> - 2004-10-08 20:17:03
|
Update of /cvsroot/ctypes/ctypes/source In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv30719 Modified Files: _ctypes.c Log Message: ctypes _pointer_type_cache now lives in the _ctypes module, to make it available to C code. Setting the _fields_ attribute on a Structure or Union type after creation automatically update the POINTER instance to it when it already exists, this allows to use POINTER(<type>) in the _fields_ list without need to update the POINTER type later. Implemented a customg from_param class method for CFuncPtrType: Python callables can now be passed directly as arguments to functions requiring callbacks: WINFUNCTYPE() or CFUNCTYPE() in the argtypes list. To avoid having to keep a reference to the created callback function explicitely (which will always be forgotten), started code to keep a reference automatically - currently this only works for functions, *not* for methods!!! Index: _ctypes.c =================================================================== RCS file: /cvsroot/ctypes/ctypes/source/_ctypes.c,v retrieving revision 1.163 retrieving revision 1.164 diff -C2 -d -r1.163 -r1.164 *** _ctypes.c 28 Sep 2004 14:00:18 -0000 1.163 --- _ctypes.c 8 Oct 2004 20:16:28 -0000 1.164 *************** *** 98,101 **** --- 98,102 ---- PyObject *PyExc_ArgError; + static PyObject *PointerType_cache; char *conversion_mode_encoding = NULL; *************** *** 134,138 **** if (fields == NULL) { PyErr_Clear(); ! return result; } dict = StgDict_FromDict(fields, cls_dict, isStruct); --- 135,139 ---- if (fields == NULL) { PyErr_Clear(); ! return (PyObject *)result; } dict = StgDict_FromDict(fields, cls_dict, isStruct); *************** *** 306,309 **** --- 307,327 ---- }; + staticforward PyObject * + PointerType_set_type(PyTypeObject *, PyObject *); + + /* If the _fields_ attribute has been set on a Structure or Union type, + * we must update the Pointer's type if there is already one. + */ + static int + StructUnion_UpdatePointer_Type(PyObject *self) + { + PyObject *ptr = PyDict_GetItem(PointerType_cache, self); + if (ptr + && PyType_Check(ptr) + && (NULL == PointerType_set_type((PyTypeObject *)ptr, self))) + return -1; + return 0; + } + static int StructUnionType_setattro(PyTypeObject *self, PyObject *name, PyObject *value, *************** *** 330,333 **** --- 348,353 ---- Py_DECREF(self->tp_dict); self->tp_dict = dict; + if (-1 == StructUnion_UpdatePointer_Type((PyObject *)self)) + return -1; } if (PyString_Check(name) *************** *** 460,463 **** --- 480,486 ---- PointerType_SetProto(StgDictObject *stgdict, PyObject *proto) { + /* XXX makes no sense to check for proto != NULL, + * and later call Py_INCREF on it. + */ if (proto && !PyType_Check(proto)) { PyErr_SetString(PyExc_TypeError, *************** *** 500,508 **** proto = PyDict_GetItemString(typedict, "_type_"); /* Borrowed ref */ ! if (proto && -1 == PointerType_SetProto(stgdict, proto)) { ! Py_DECREF((PyObject *)stgdict); ! return NULL; } - /* create the new instance (which is a class, since we are a metatype!) */ --- 523,532 ---- proto = PyDict_GetItemString(typedict, "_type_"); /* Borrowed ref */ ! if (proto && PyType_stgdict(proto)) { ! if (-1 == PointerType_SetProto(stgdict, proto)) { ! Py_DECREF((PyObject *)stgdict); ! return NULL; ! } } /* create the new instance (which is a class, since we are a metatype!) */ *************** *** 510,515 **** if (result == NULL) return NULL; ! ! /* replace the class dict by our updated spam dict */ if (-1 == PyDict_Update((PyObject *)stgdict, result->tp_dict)) { Py_DECREF(result); --- 534,538 ---- if (result == NULL) return NULL; ! /* replace the class dict by our updated StgDict */ if (-1 == PyDict_Update((PyObject *)stgdict, result->tp_dict)) { Py_DECREF(result); *************** *** 519,523 **** Py_DECREF(result->tp_dict); result->tp_dict = (PyObject *)stgdict; - return (PyObject *)result; } --- 542,545 ---- *************** *** 528,531 **** --- 550,554 ---- { StgDictObject *dict; + PyObject *old_type; dict = PyType_stgdict((PyObject *)self); *************** *** 535,538 **** --- 558,567 ---- return NULL; + old_type = PyDict_GetItemString((PyObject *)dict, "_type_"); + if (old_type && old_type != type) { + PyErr_SetString(PyExc_AttributeError, + "_type_ already set"); + return NULL; + } if (-1 == PyDict_SetItemString((PyObject *)dict, "_type_", type)) return NULL; *************** *** 559,566 **** } } if (PointerObject_Check(value)) { StgDictObject *v = PyObject_stgdict(value); StgDictObject *t = PyType_stgdict(type); ! if (PyObject_IsSubclass(v->proto, t->proto)) { Py_INCREF(value); return value; --- 588,601 ---- } } + if (PyObject_IsInstance(value, type)) { + Py_INCREF(value); + return value; + } if (PointerObject_Check(value)) { StgDictObject *v = PyObject_stgdict(value); StgDictObject *t = PyType_stgdict(type); ! if (v && v->proto ! && t && t->proto ! && PyObject_IsSubclass(v->proto, t->proto)) { Py_INCREF(value); return value; *************** *** 1290,1294 **** PyCArgObject *parg; struct fielddesc *fd; - /* If the value is already an instance of the requested type, we can use it as is */ --- 1325,1328 ---- *************** *** 1513,1516 **** --- 1547,1608 ---- } + static PyObject * + CFuncPtrType_from_param(PyObject *type, PyObject *value) + { + if (1 == PyObject_IsInstance(value, type)) { + Py_INCREF(value); + return value; + } + /* normal python object, maybe a function, maybe another callable. We + * create an object of the required type automatically, but we have to + * keep a reference to it alive as long as the callback is used. We + * do not know how long it is used, but we assume that the lifetime of + * the callable is suffifient. This works for normal functions (where + * we attach it as _callback_ attribute to the function), but not for + * bound methods. + * + * For bound methods, we should keep the callback alive as long as the + * instance is alive, but we do not want to insret something into the + * instance's __dict__. + * Can we use a weak ref to the instance? XXX Later. + */ + if (0 == PyObject_IsInstance(value, (PyObject *)&CFuncPtr_Type)) { + PyObject *result = PyObject_CallFunctionObjArgs(type, value, NULL); + if (result == NULL) + return NULL; + if (-1 == PyObject_SetAttrString(value, "_callback_", result)) { + PyErr_Clear(); + } + return result; + } + /* Not sure this one is possible. byref() of a FUNCTYPE? */ + if (PyCArg_CheckExact(value)) { + PyCArgObject *p = (PyCArgObject *)value; + PyObject *ob = p->obj; + StgDictObject *dict; + dict = PyType_stgdict(type); + + /* If we got a PyCArgObject, we must check if the object packed in it + is an instance of the type's dict->proto */ + if(dict && ob + && PyObject_IsInstance(ob, dict->proto)) { + Py_INCREF(value); + return value; + } + } + PyErr_Format(PyExc_TypeError, + "expected %s instance instead of %s", + ((PyTypeObject *)type)->tp_name, + value->ob_type->tp_name); + return NULL; + } + + static PyMethodDef CFuncPtrType_methods[] = { + { "from_param", CFuncPtrType_from_param, METH_O, from_param_doc }, + { "from_address", CDataType_from_address, METH_O, from_address_doc }, + { "in_dll", CDataType_in_dll, METH_VARARGS, in_dll_doc }, + { NULL, NULL }, + }; + PyTypeObject CFuncPtrType_Type = { PyObject_HEAD_INIT(NULL) *************** *** 1542,1546 **** 0, /* tp_iter */ 0, /* tp_iternext */ ! CDataType_methods, /* tp_methods */ 0, /* tp_members */ 0, /* tp_getset */ --- 1634,1638 ---- 0, /* tp_iter */ 0, /* tp_iternext */ ! CFuncPtrType_methods, /* tp_methods */ 0, /* tp_members */ 0, /* tp_getset */ *************** *** 3283,3287 **** return -1; } - stgdict = PyObject_stgdict((PyObject *)self); if (index != 0) { --- 3375,3378 ---- *************** *** 3291,3295 **** } size = stgdict->size / stgdict->length; ! return CData_set((PyObject *)self, stgdict->proto, stgdict->setfunc, value, index, size, *(void **)self->b_ptr); --- 3382,3389 ---- } size = stgdict->size / stgdict->length; ! /* Later... ! return Pointer_set((PyObject *)self, stgdict->proto, stgdict->setfunc, value, ! index, size, self->b_ptr); ! */ return CData_set((PyObject *)self, stgdict->proto, stgdict->setfunc, value, index, size, *(void **)self->b_ptr); *************** *** 3749,3752 **** --- 3843,3849 ---- PyModule_AddObject(m, "FUNCFLAG_CDECL", PyInt_FromLong(FUNCFLAG_CDECL)); PyModule_AddObject(m, "FUNCFLAG_PYTHONAPI", PyInt_FromLong(FUNCFLAG_PYTHONAPI)); + PointerType_cache = PyDict_New(); + Py_INCREF(PointerType_cache); + PyModule_AddObject(m, "_pointer_type_cache", PointerType_cache); PyModule_AddStringConstant(m, "__version__", "0.9.2"); |
From: Thomas H. <th...@us...> - 2004-10-07 18:54:47
|
Update of /cvsroot/ctypes/ctypes/source In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv29841 Modified Files: cfield.c Log Message: It seems bit fields of the same size (short, int, long), independend from signed/unsigned are packed together in one field. Index: cfield.c =================================================================== RCS file: /cvsroot/ctypes/ctypes/source/cfield.c,v retrieving revision 1.44 retrieving revision 1.45 diff -C2 -d -r1.44 -r1.45 *** cfield.c 21 Sep 2004 17:01:13 -0000 1.44 --- cfield.c 7 Oct 2004 18:54:37 -0000 1.45 *************** *** 43,47 **** SETFUNC setfunc = NULL; GETFUNC getfunc = NULL; ! StgDictObject *dict; int fieldtype; #define NO_BITFIELD 0 --- 43,47 ---- SETFUNC setfunc = NULL; GETFUNC getfunc = NULL; ! StgDictObject *dict, *prev_dict; int fieldtype; #define NO_BITFIELD 0 *************** *** 54,57 **** --- 54,58 ---- return NULL; dict = PyType_stgdict(desc); + prev_dict = prev_desc ? PyType_stgdict(prev_desc) : NULL; if (!dict) { PyErr_SetString(PyExc_TypeError, *************** *** 61,65 **** } if (bitsize /* this is a bitfield request */ ! && prev_desc == desc /* basic types are same */ && *pbitofs /* we have a bitfield open */ && (*pbitofs + bitsize) <= (dict->size * 8)) { /* fits into the space */ --- 62,67 ---- } if (bitsize /* this is a bitfield request */ ! // && prev_desc == desc /* basic types are same */ ! && prev_dict && dict->size == prev_dict->size && *pbitofs /* we have a bitfield open */ && (*pbitofs + bitsize) <= (dict->size * 8)) { /* fits into the space */ |
From: Thomas H. <th...@us...> - 2004-10-06 12:13:53
|
Update of /cvsroot/ctypes/ctypes/source In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv4322 Modified Files: stgdict.c Log Message: Remove debug code. Index: stgdict.c =================================================================== RCS file: /cvsroot/ctypes/ctypes/source/stgdict.c,v retrieving revision 1.14 retrieving revision 1.15 diff -C2 -d -r1.14 -r1.15 *** stgdict.c 28 Sep 2004 11:35:13 -0000 1.14 --- stgdict.c 6 Oct 2004 12:13:40 -0000 1.15 *************** *** 230,238 **** } else bitsize = 0; - /* - #ifdef _DEBUG - _asm int 3; - #endif - */ if (isStruct) { prop = CField_FromDesc(desc, i, --- 230,233 ---- |
From: Thomas H. <th...@us...> - 2004-10-06 09:18:07
|
Update of /cvsroot/ctypes/ctypes/sandbox/tools/codegen In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv31219 Modified Files: generate.py Log Message: Cleanup. Index: generate.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/sandbox/tools/codegen/generate.py,v retrieving revision 1.9 retrieving revision 1.10 diff -C2 -d -r1.9 -r1.10 *** generate.py 6 Oct 2004 09:16:40 -0000 1.9 --- generate.py 6 Oct 2004 09:17:54 -0000 1.10 *************** *** 210,218 **** if type(m.typ) is nodes.Typedef: self.more.add(m.typ) - t = get_real_type(m.typ) self.generate(get_real_type(m.typ)) - if type(t) in (nodes.Structure, nodes.Union): - assert t.get_body() in self.done - elif type(m) is nodes.Method: methods.append(m) --- 210,214 ---- |
From: Thomas H. <th...@us...> - 2004-10-06 09:16:49
|
Update of /cvsroot/ctypes/ctypes/sandbox/tools/codegen In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv30992 Modified Files: generate.py Log Message: annotate assignments in the generated code. Index: generate.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/sandbox/tools/codegen/generate.py,v retrieving revision 1.8 retrieving revision 1.9 diff -C2 -d -r1.8 -r1.9 *** generate.py 6 Oct 2004 08:53:16 -0000 1.8 --- generate.py 6 Oct 2004 09:16:40 -0000 1.9 *************** *** 153,157 **** self.generate(tp.typ) if tp.name != type_name(tp.typ): ! print "%s = %s" % (tp.name, type_name(tp.typ)) self.done.add(tp) --- 153,157 ---- self.generate(tp.typ) if tp.name != type_name(tp.typ): ! print "%s = %s # typedef" % (tp.name, type_name(tp.typ)) self.done.add(tp) *************** *** 195,201 **** return if tp.name: ! print "%s = c_int" % tp.name for n, v in tp.values: ! print "%s = %s" % (n, v) self.done.add(tp) --- 195,201 ---- return if tp.name: ! print "%s = c_int # enum" % tp.name for n, v in tp.values: ! print "%s = %s # enum" % (n, v) self.done.add(tp) *************** *** 340,344 **** import sys if len(sys.argv) == 1: ! sys.argv.extend("MessageBox".split()) ## sys.argv.extend("ITypeComp".split()) main() --- 340,344 ---- import sys if len(sys.argv) == 1: ! sys.argv.extend("WNDCLASS".split()) ## sys.argv.extend("ITypeComp".split()) main() |
From: Thomas H. <th...@us...> - 2004-10-06 08:53:26
|
Update of /cvsroot/ctypes/ctypes/sandbox/tools/codegen In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv26494 Modified Files: generate.py Log Message: Remove debug code. Index: generate.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/sandbox/tools/codegen/generate.py,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -d -r1.7 -r1.8 *** generate.py 5 Oct 2004 16:50:50 -0000 1.7 --- generate.py 6 Oct 2004 08:53:16 -0000 1.8 *************** *** 269,275 **** if func in self.done: return - if func.name == "qsort": - import pdb - pdb.set_trace() dllname = self.find_dllname(func.name) if dllname and func.extern: --- 269,272 ---- |
From: Thomas H. <th...@us...> - 2004-10-05 16:52:07
|
Update of /cvsroot/ctypes/ctypes/sandbox/tools/codegen In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv16067 Added Files: _support.py Log Message: Support module for generated code. --- NEW FILE: _support.py --- def STDMETHOD(*args): pass # fake def const(x): return x # fake from ctypes import * class _com_interface(Structure): _fields_ = [('lpVtbl', c_void_p)] def STDCALL(dllname, restype, funcname, argtypes): # a decorator which loads the specified dll, retrieves the # function with the specified name, set its restype and argtypes, # and exposes it as an '_call_' global in the namespace of the # decorated function. def decorate(func): import new api = getattr(WinDLL(dllname), funcname) api.restype = restype api.argtypes = argtypes f_globals = dict(func.func_globals) f_globals["_call_"] = api f = new.function(func.func_code, f_globals, func.func_name, func.func_defaults) return f return decorate def CDECL(dllname, restype, funcname, argtypes): # a decorator which loads the specified dll, retrieves the # function with the specified name, set its restype and argtypes, # and exposes it as an '_call_' global in the namespace of the # decorated function. def decorate(func): import new api = getattr(CDLL(dllname), funcname) api.restype = restype api.argtypes = argtypes f_globals = dict(func.func_globals) f_globals["_call_"] = api f = new.function(func.func_code, f_globals, func.func_name, func.func_defaults) return f return decorate |
From: Thomas H. <th...@us...> - 2004-10-05 16:51:14
|
Update of /cvsroot/ctypes/ctypes/sandbox/tools/codegen In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv15922 Modified Files: generate.py Log Message: Refactoring. Index: generate.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/sandbox/tools/codegen/generate.py,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** generate.py 5 Oct 2004 13:32:30 -0000 1.6 --- generate.py 5 Oct 2004 16:50:50 -0000 1.7 *************** *** 28,32 **** return "WINFUNCTYPE(%s)" % ", ".join(args) elif isinstance(t, nodes.CvQualifiedType): ! return "c_const(%s)" % type_name(t.typ) elif isinstance(t, nodes.FundamentalType): return ctypes_names[t.name] --- 28,32 ---- return "WINFUNCTYPE(%s)" % ", ".join(args) elif isinstance(t, nodes.CvQualifiedType): ! return "const(%s)" % type_name(t.typ) elif isinstance(t, nodes.FundamentalType): return ctypes_names[t.name] *************** *** 67,70 **** --- 67,73 ---- "_SHFILEOPSTRUCTW": 2, "_SHFILEOPSTRUCTA": 2, + + "_SENDCMDOUTPARAMS": 1, + "_SENDCMDINPARAMS": 1, } *************** *** 148,152 **** self.more.add(tp.typ) else: ! self.generate([tp.typ]) if tp.name != type_name(tp.typ): print "%s = %s" % (tp.name, type_name(tp.typ)) --- 151,155 ---- self.more.add(tp.typ) else: ! self.generate(tp.typ) if tp.name != type_name(tp.typ): print "%s = %s" % (tp.name, type_name(tp.typ)) *************** *** 158,162 **** if type(tp.typ) is nodes.Typedef: self.more.add(tp.typ) ! self.generate([get_real_type(tp.typ)]) self.done.add(tp) --- 161,165 ---- if type(tp.typ) is nodes.Typedef: self.more.add(tp.typ) ! self.generate(get_real_type(tp.typ)) self.done.add(tp) *************** *** 164,169 **** if tp in self.done: return ! self.generate([tp.returns]) ! self.generate(tp.arguments) self.done.add(tp) --- 167,172 ---- if tp in self.done: return ! self.generate(tp.returns) ! self.generate_all(tp.arguments) self.done.add(tp) *************** *** 177,183 **** self.more.add(tp.typ) elif type(tp.typ) is nodes.Typedef: ! self.generate([tp.typ]) else: ! self.generate([tp.typ]) self.done.add(tp) --- 180,186 ---- self.more.add(tp.typ) elif type(tp.typ) is nodes.Typedef: ! self.generate(tp.typ) else: ! self.generate(tp.typ) self.done.add(tp) *************** *** 185,189 **** if tp in self.done: return ! self.generate([tp.typ]) self.done.add(tp) --- 188,192 ---- if tp in self.done: return ! self.generate(tp.typ) self.done.add(tp) *************** *** 208,212 **** self.more.add(m.typ) t = get_real_type(m.typ) ! self.generate([get_real_type(m.typ)]) if type(t) in (nodes.Structure, nodes.Union): assert t.get_body() in self.done --- 211,215 ---- self.more.add(m.typ) t = get_real_type(m.typ) ! self.generate(get_real_type(m.typ)) if type(t) in (nodes.Structure, nodes.Union): assert t.get_body() in self.done *************** *** 214,219 **** elif type(m) is nodes.Method: methods.append(m) ! self.generate([m.returns]) ! self.generate(m.arguments) elif type(m) is nodes.Constructor: pass --- 217,222 ---- elif type(m) is nodes.Method: methods.append(m) ! self.generate(m.returns) ! self.generate_all(m.arguments) elif type(m) is nodes.Constructor: pass *************** *** 266,307 **** if func in self.done: return dllname = self.find_dllname(func.name) if dllname and func.extern: ! self.generate([func.returns]) ! self.generate(func.arguments) args = [type_name(a) for a in func.arguments] if "__stdcall__" in func.attributes: ! print "STDCALL('%s', %s, '%s', %s)" % \ ! (dllname, type_name(func.returns), func.name, ", ".join(args)) else: ! print "CDECL('%s', %s, '%s', %s)" % \ ! (dllname, type_name(func.returns), func.name, ", ".join(args)) self.done.add(func) ! def generate(self, items): for item in items: ! tp = type(item) ! if tp in (nodes.Structure, nodes.Union): ! self.Structure(item) ! elif tp == nodes.Typedef: ! self.Typedef(item) ! elif tp == nodes.FundamentalType: ! pass ! elif tp == nodes.PointerType: ! self.PointerType(item) ! elif tp == nodes.CvQualifiedType: ! self.CvQualifiedType(item) ! elif tp == nodes.ArrayType: ! self.ArrayType(item) ! elif tp == nodes.Enumeration: ! self.Enumeration(item) ! elif tp == nodes.StructureHead: ! self.StructureHead(item) ! elif tp == nodes.FunctionType: ! self.FunctionType(item) ! elif tp == nodes.Function: ! self.Function(item) ! else: ! raise "NYI", tp ################################################################ --- 269,302 ---- if func in self.done: return + if func.name == "qsort": + import pdb + pdb.set_trace() dllname = self.find_dllname(func.name) if dllname and func.extern: ! self.generate(func.returns) ! self.generate_all(func.arguments) args = [type_name(a) for a in func.arguments] if "__stdcall__" in func.attributes: ! print "%s = STDCALL('%s', %s, '%s', (%s))" % \ ! (func.name, dllname, type_name(func.returns), func.name, ", ".join(args)) else: ! print "%s = CDECL('%s', %s, '%s', (%s))" % \ ! (func.name, dllname, type_name(func.returns), func.name, ", ".join(args)) self.done.add(func) ! Union = Structure ! ! def FundamentalType(self, item): ! self.done.add(item) ! ! ######## ! ! def generate(self, item): ! mth = getattr(self, type(item).__name__) ! mth(item) ! ! def generate_all(self, items): for item in items: ! self.generate(item) ################################################################ *************** *** 309,313 **** def find_names(names): from gccxmlparser import parse ! items = parse(files=["windows.h"], xmlfile="windows.xml") result = [] --- 304,311 ---- def find_names(names): from gccxmlparser import parse ! items = parse(files=["windows.h"], xmlfile="windows.xml", options=["-D _WIN32_WINNT=0x500"]) ! ! if "*" in names: ! return items result = [] *************** *** 319,336 **** def main(): from gccxmlparser import parse ! items = parse(files=["windows.h"], xmlfile="windows.xml") ! ## items = find_names(sys.argv[1:]) gen = Generator() print "from ctypes import *" ! print "def STDMETHOD(*args): pass" ! print "def c_const(x): return x" ! print "STDCALL = CDECL = STDMETHOD" ! print "class _com_interface(Structure):" ! print " _fields_ = [('lpVtbl', c_void_p)]" print for i in range(20): gen.more = set() ! gen.generate(items) items = gen.more if not items: --- 317,335 ---- def main(): from gccxmlparser import parse ! ## items = parse(files=["windows.h"], xmlfile="windows.xml") ! items = find_names(sys.argv[1:]) gen = Generator() print "from ctypes import *" ! print "from _support import STDMETHOD, const, STDCALL, CDECL, _com_interface" ! ## print "def STDMETHOD(*args): pass" ! ## print "def const(x): return x" ! ## print "STDCALL = CDECL = STDMETHOD" ! ## print "class _com_interface(Structure):" ! ## print " _fields_ = [('lpVtbl', c_void_p)]" print for i in range(20): gen.more = set() ! gen.generate_all(items) items = gen.more if not items: *************** *** 344,348 **** import sys if len(sys.argv) == 1: ! sys.argv.extend("IDispatch".split()) ## sys.argv.extend("ITypeComp".split()) main() --- 343,347 ---- import sys if len(sys.argv) == 1: ! sys.argv.extend("MessageBox".split()) ## sys.argv.extend("ITypeComp".split()) main() |
From: Thomas H. <th...@us...> - 2004-10-05 13:33:48
|
Update of /cvsroot/ctypes/ctypes/sandbox/tools/codegen In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv31992 Modified Files: generate.py Log Message: Make structure classes subclassing work. Find functions in system dlls. Index: generate.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/sandbox/tools/codegen/generate.py,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** generate.py 5 Oct 2004 09:15:37 -0000 1.5 --- generate.py 5 Oct 2004 13:32:30 -0000 1.6 *************** *** 51,56 **** --- 51,110 ---- "tagPDW": 2, "DLGITEMTEMPLATE": 2, + "tWAVEFORMATEX": 2, + "DLGTEMPLATE": 2, + "tagMETAHEADER": 2, + "tagBITMAPFILEHEADER": 2, + + "_SHQUERYRBINFO": 4, + + "waveformat_tag": 2, + "_py_N17_IMAGE_AUX_SYMBOL4__26E": 2, + "_IMAGE_AUX_SYMBOL": 2, + "IMAGE_AUX_SYMBOL_TOKEN_DEF": 2, + "_IMAGE_LINENUMBER": 2, + "_IMAGE_RELOCATION": 2, + + "_SHFILEOPSTRUCTW": 2, + "_SHFILEOPSTRUCTA": 2, } + dont_assert_size = set( + [ + "__si_class_type_info_pseudo", + "__class_type_info_pseudo", + ] + ) + + dll_names = """\ + user32 + kernel32 + gdi32 + advapi32 + oleaut32 + ole32 + imm32 + comdlg32 + shell32 + version + winmm + mpr + winscard + winspool.drv + urlmon + crypt32 + cryptnet + ws2_32 + opengl32 + mswsock + msvcrt + rpcrt4""".split() + + ##rpcndr + ##ntdll + + + from ctypes import CDLL + searched_dlls = [CDLL(name) for name in dll_names] + class Generator(object): def __init__(self): *************** *** 95,99 **** else: self.generate([tp.typ]) ! print "%s = %s" % (tp.name, type_name(tp.typ)) self.done.add(tp) --- 149,154 ---- else: self.generate([tp.typ]) ! if tp.name != type_name(tp.typ): ! print "%s = %s" % (tp.name, type_name(tp.typ)) self.done.add(tp) *************** *** 170,174 **** print "%s._pack_ = %s" % (body.struct.name, pack) if fields: ! print "%s._fields_ = [" % body.struct.name for f in fields: if f.bits is None: --- 225,235 ---- print "%s._pack_ = %s" % (body.struct.name, pack) if fields: ! if body.struct.bases: ! assert len(body.struct.bases) == 1 ! base = body.struct.bases[0].name ! self.StructureBody(body.struct.bases[0].get_body()) ! print "%s._fields_ = %s._fields_ + [" % (body.struct.name, base) ! else: ! print "%s._fields_ = [" % body.struct.name for f in fields: if f.bits is None: *************** *** 186,190 **** ", ".join(args)) print "]" ! if body.struct.size: size = body.struct.size // 8 print "assert sizeof(%s) == %s, sizeof(%s)" % \ --- 247,251 ---- ", ".join(args)) print "]" ! if body.struct.size and body.struct.name not in dont_assert_size: size = body.struct.size // 8 print "assert sizeof(%s) == %s, sizeof(%s)" % \ *************** *** 192,208 **** self.done.add(body) def Function(self, func): if func in self.done: return ! if func.extern: self.generate([func.returns]) self.generate(func.arguments) args = [type_name(a) for a in func.arguments] if "__stdcall__" in func.attributes: ! print "STDCALL(%s, '%s', %s)" % \ ! (type_name(func.returns), func.name, ", ".join(args)) else: ! print "CDECL(%s, '%s', %s)" % \ ! (type_name(func.returns), func.name, ", ".join(args)) self.done.add(func) --- 253,280 ---- self.done.add(body) + def find_dllname(self, name): + for dll in searched_dlls: + try: + getattr(dll, name) + except AttributeError: + pass + else: + return dll._name + return None + def Function(self, func): if func in self.done: return ! dllname = self.find_dllname(func.name) ! if dllname and func.extern: self.generate([func.returns]) self.generate(func.arguments) args = [type_name(a) for a in func.arguments] if "__stdcall__" in func.attributes: ! print "STDCALL('%s', %s, '%s', %s)" % \ ! (dllname, type_name(func.returns), func.name, ", ".join(args)) else: ! print "CDECL('%s', %s, '%s', %s)" % \ ! (dllname, type_name(func.returns), func.name, ", ".join(args)) self.done.add(func) |
From: Thomas H. <th...@us...> - 2004-10-05 09:15:50
|
Update of /cvsroot/ctypes/ctypes/sandbox/tools/codegen In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv386 Modified Files: generate.py Log Message: Specify packing for structures (later, this should be replaced by code which actually calculates the _pack_ value). _com_interface base class for COM interfaces. Remove some debug code. Generate bit field definitions. Index: generate.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/sandbox/tools/codegen/generate.py,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** generate.py 4 Oct 2004 19:42:50 -0000 1.4 --- generate.py 5 Oct 2004 09:15:37 -0000 1.5 *************** *** 46,49 **** --- 46,56 ---- return tp + struct_packing = { + "_IMAGE_SYMBOL": 2, + "tagPDA": 2, + "tagPDW": 2, + "DLGITEMTEMPLATE": 2, + } + class Generator(object): def __init__(self): *************** *** 61,65 **** print "class %s(%s):" % (head.struct.name, ", ".join(basenames)) else: ! if type(head.struct) == nodes.Structure: print "class %s(Structure):" % head.struct.name elif type(head.struct) == nodes.Union: --- 68,75 ---- print "class %s(%s):" % (head.struct.name, ", ".join(basenames)) else: ! methods = [m for m in head.struct.members if type(m) is nodes.Method] ! if methods: ! print "class %s(_com_interface):" % head.struct.name ! elif type(head.struct) == nodes.Structure: print "class %s(Structure):" % head.struct.name elif type(head.struct) == nodes.Union: *************** *** 69,72 **** --- 79,84 ---- def Structure(self, struct): + if struct in self.done: + return head = struct.get_head() self.StructureHead(head) *************** *** 142,152 **** t = get_real_type(m.typ) self.generate([get_real_type(m.typ)]) - if getattr(t, "name", None) == "SIZE": - import pdb - pdb.set_trace() if type(t) in (nodes.Structure, nodes.Union): assert t.get_body() in self.done - ## self.generate([m.typ]) elif type(m) is nodes.Method: methods.append(m) --- 154,160 ---- *************** *** 155,162 **** elif type(m) is nodes.Constructor: pass if fields: print "%s._fields_ = [" % body.struct.name for f in fields: ! print " ('%s', %s)," % (f.name, type_name(f.typ)) print "]" if methods: --- 163,179 ---- elif type(m) is nodes.Constructor: pass + try: + pack = struct_packing[body.struct.name] + except KeyError: + pass + else: + print "%s._pack_ = %s" % (body.struct.name, pack) if fields: print "%s._fields_ = [" % body.struct.name for f in fields: ! if f.bits is None: ! print " ('%s', %s)," % (f.name, type_name(f.typ)) ! else: ! print " ('%s', %s, %s)," % (f.name, type_name(f.typ), f.bits) print "]" if methods: *************** *** 169,172 **** --- 186,193 ---- ", ".join(args)) print "]" + if body.struct.size: + size = body.struct.size // 8 + print "assert sizeof(%s) == %s, sizeof(%s)" % \ + (body.struct.name, size, body.struct.name) self.done.add(body) *************** *** 226,235 **** def main(): from gccxmlparser import parse ! ## items = parse(files=["windows.h"], xmlfile="windows.xml") ! items = find_names(sys.argv[1:]) gen = Generator() print "from ctypes import *" print "def STDMETHOD(*args): pass" print "def c_const(x): return x" print --- 247,259 ---- def main(): from gccxmlparser import parse ! items = parse(files=["windows.h"], xmlfile="windows.xml") ! ## items = find_names(sys.argv[1:]) gen = Generator() print "from ctypes import *" print "def STDMETHOD(*args): pass" print "def c_const(x): return x" + print "STDCALL = CDECL = STDMETHOD" + print "class _com_interface(Structure):" + print " _fields_ = [('lpVtbl', c_void_p)]" print |
From: Thomas H. <th...@us...> - 2004-10-05 06:52:57
|
Update of /cvsroot/ctypes/ctypes/sandbox/tools/codegen In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv428 Modified Files: nodes.py Log Message: Remove all the unneeded stuff. Index: nodes.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/sandbox/tools/codegen/nodes.py,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -d -r1.7 -r1.8 *** nodes.py 4 Oct 2004 19:42:49 -0000 1.7 --- nodes.py 5 Oct 2004 06:52:44 -0000 1.8 *************** *** 18,26 **** self.extern = extern - def depends(self): - result = set(self.arguments) - result.add(self.returns) - return result - class Constructor(_HasArgs): def __init__(self, name): --- 18,21 ---- *************** *** 28,34 **** self.arguments = [] - def depends(self): - return [] - class OperatorFunction(_HasArgs): def __init__(self, name, returns): --- 23,26 ---- *************** *** 42,50 **** self.arguments = [] - def depends(self): - result = set(self.arguments) - result.add(self.returns) - return result - class Method(_HasArgs): def __init__(self, name, returns): --- 34,37 ---- *************** *** 53,94 **** self.arguments = [] - def depends(self): - result = set(self.arguments) - result.add(self.returns) - return result - class FundamentalType(object): def __init__(self, name): self.name = name - def depends(self): - return [] - def __repr__(self): return "<FundamentalType(%s)>" % self.name - def get_pointed_to(p): - # if p is a pointer, return the end of the chain pointed to. - if isinstance(p, PointerType): - return get_pointed_to(p.typ) - elif isinstance(p, CvQualifiedType): - return get_pointed_to(p.typ) - elif isinstance(p, Typedef): - return get_pointed_to(p.typ) - return p - class PointerType(object): def __init__(self, typ): self.typ = typ - def depends(self): - # Well, if the pointer points to a structure or union, - # we don't need the complete struct or union definition. - # The header will suffice. - t = get_pointed_to(self) - if type(t) in (Structure, Union): - return [t.get_head()] - return [t] - def __repr__(self): return "<POINTER(%s)>" % self.typ --- 40,54 ---- *************** *** 99,107 **** self.typ = typ - def depends(self): - if type(self.typ) in (Structure, Union): - return [self.typ.get_head()] - return [self.typ] - def __repr__(self): return "<Typedef(%s) at %x>" % (self.name, id(self)) --- 59,62 ---- *************** *** 113,152 **** self.max = max - def depends(self): - return [self.typ] - def __repr__(self): return "<Array(%s[%s]) at %x>" % (self.typ, self.max, id(self)) - # Structures (and Unions, as well) are split into three objects. - # Structure depends on StructureHead and StructureBody - # StructureHead depends on bases, - # StructureBody depends on head and members. - # - # Pointer to Structure depends on StructureHead only - class StructureHead(object): def __init__(self, struct): self.struct = struct - def depends(self): - # XXX Hm, does it depend on bases, or does it depends on the bases' head? - return self.struct.bases - class StructureBody(object): def __init__(self, struct): self.struct = struct - def depends(self): - result = set() - # needed, so that the head is defined before the body - result.add(self.struct.get_head()) - for m in self.struct.members: - if type(m) is Field: - result.add(m.typ) - if type(m) is Method: - result.update(m.depends()) - return result - def __repr__(self): return "<StructureBody(%s) at %x>" % (self.struct.name, id(self)) --- 68,82 ---- *************** *** 202,208 **** self.offset = offset - def depends(self): - return [self.typ] - class CvQualifiedType(object): def __init__(self, typ, attrib): --- 132,135 ---- *************** *** 210,216 **** self.attrib = attrib - def depends(self): - return self.typ.depends() - class Enumeration(object): def __init__(self, name): --- 137,140 ---- *************** *** 221,226 **** self.values.append((name, value)) - def depends(self): - return [] - ################################################################ --- 145,147 ---- |
From: Thomas H. <th...@us...> - 2004-10-04 19:43:02
|
Update of /cvsroot/ctypes/ctypes/sandbox/tools/codegen In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv14163 Modified Files: nodes.py generate.py Log Message: Seems to work now... Index: nodes.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/sandbox/tools/codegen/nodes.py,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** nodes.py 4 Oct 2004 09:14:01 -0000 1.6 --- nodes.py 4 Oct 2004 19:42:49 -0000 1.7 *************** *** 74,77 **** --- 74,79 ---- elif isinstance(p, CvQualifiedType): return get_pointed_to(p.typ) + elif isinstance(p, Typedef): + return get_pointed_to(p.typ) return p Index: generate.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/sandbox/tools/codegen/generate.py,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** generate.py 4 Oct 2004 09:15:06 -0000 1.3 --- generate.py 4 Oct 2004 19:42:50 -0000 1.4 *************** *** 9,164 **** ################ ! ##renames = {} class Generator(object): def __init__(self): self.done = set() ! def type_name(self, t): ! # Return a string, containing an expression which can be used to ! # refer to the type. Assumes the ctypes.* namespace is available. ! if isinstance(t, nodes.PointerType): ! result = "POINTER(%s)" % self.type_name(t.typ) ! # XXX Better to inspect t.typ! ! if result.startswith("POINTER(WINFUNCTYPE"): ! return result[8:-1] ! # XXX See comment above... ! elif result == "POINTER(None)": ! return "c_void_p" ! return result ! elif isinstance(t, nodes.ArrayType): ! return "%s * %s" % (self.type_name(t.typ), int(t.max)+1) ! elif isinstance(t, nodes.FunctionType): ! args = map(self.type_name, [t.returns] + t.arguments) ! # what now? WINFUNCTYPE already *is* a pointer to a function ! return "WINFUNCTYPE(%s)" % ", ".join(args) ! elif isinstance(t, nodes.CvQualifiedType): ! return "c_const(%s)" % self.type_name(t.typ) ! elif isinstance(t, nodes.FundamentalType): ! return ctypes_names[t.name] ! elif isinstance(t, nodes.Structure): ! ## try: ! ## return renames[t] ! ## except KeyError: ! return t.name ! elif isinstance(t, nodes.Enumeration): ! ## try: ! ## return renames[t] ! ## except KeyError: ! ## pass ! if t.name: ! return t.name ! return "c_int" # enums are integers ! return t.name ! ! def Enumeration(self, enum): ! if enum.name is not None: ! # enums are integers (AFAIK, but may depend on the compiler) ! print "%s = c_int" % enum.name ! for name, val in enum.values: ! print "%s = %s" % (name, val) ! print ! def Typedef(self, t): ! print "%s = %s" % (t.name, self.type_name(t.typ)) ! def StructureHead(self, t): ! assert t.struct.name is not None ! print "class %s(Structure):" % t.struct.name ! print " pass" ! def StructureBody(self, t): ! self.done.update(t.struct.members) ! fields = [m for m in t.struct.members if type(m) is nodes.Field] if fields: ! print "%s._fields_ = [" % t.struct.name ! for m in fields: ! if m.bits: ! print " ('%s', %s, %s)," % (m.name, self.type_name(m.typ), m.bits) ! else: ! print " ('%s', %s)," % (m.name, self.type_name(m.typ)) print "]" - - methods = [m for m in t.struct.members if type(m) is nodes.Method] if methods: ! print "%s._methods_ = [" % t.struct.name for m in methods: ! args = [self.type_name(a) for a in m.arguments] ! text = " STDMETHOD(%s, '%s'" % (self.type_name(m.returns), m.name) ! if args: ! print "%s, %s)," % (text, ", ".join(args)) ! else: ! print "%s)," % text print "]" ! ! def Function(self, t): ! if not t.extern: return ! dllname = "<unknown>" ! if "__stdcall__" in t.attributes: ! print "%s = STDCALL(%r, %s, '%s', %s)" % \ ! (t.name, dllname, self.type_name(t.returns), ! t.name, ", ".join(map(self.type_name, t.arguments))) ! else: # __cdecl is default ! print "%s = CDECL(%r, %s, '%s', %s)" % \ ! (t.name, dllname, self.type_name(t.returns), ! t.name, ", ".join(map(self.type_name, t.arguments))) - def _generate(self, t): - # the dispatcher - typ = type(t) - if typ is nodes.Enumeration: - self.Enumeration(t) - elif typ is nodes.Typedef: - self.Typedef(t) - elif typ is nodes.StructureHead: - self.StructureHead(t) - elif typ is nodes.StructureBody: - self.StructureBody(t) - elif typ is nodes.Function: - self.Function(t) - elif typ in (nodes.Structure, nodes.Union, - nodes.PointerType, nodes.FundamentalType, - nodes.ArrayType, nodes.FunctionType): - self.done.add(t) - else: - raise TypeError, "don't know how to generate code for %s" % t - self.done.add(t) - def generate(self, items): ! todo = set(items) ! # todo contains definitions we have to generate ! # self.done contains definitions already done ! ! for i in range(80): ! for td in todo.copy(): ! if type(td) in (nodes.StructureBody, nodes.StructureHead): ! todo.add(td.struct) ! if type(td) is nodes.PointerType \ ! and type(td.typ) in (nodes.Structure, nodes.Union): ! # pointers to struct or union only depend on their head, ! # but we want the body as well. ! # ! # XXX Maybe it would be better to have this in the ! # code generator for the struct/union head. ! todo.add(td.typ) ! needs = set(td.depends()) ! assert td not in needs ! if needs.issubset(self.done): ! self._generate(td) ! assert td in self.done ! else: ! todo.update(needs) ! todo -= self.done ! if not todo: ! break ! ! for i in self.done: ! if type(i) in (nodes.StructureBody, nodes.StructureHead): ! assert i.struct in self.done ! if type(i) in (nodes.Structure,): ! assert i.get_body() in self.done ! assert i.get_head() in self.done ! if todo: ! raise "Not enough loops???", (len(todo), todo) ################################################################ --- 9,214 ---- ################ ! def type_name(t): ! # Return a string, containing an expression which can be used to ! # refer to the type. Assumes the ctypes.* namespace is available. ! if isinstance(t, nodes.PointerType): ! result = "POINTER(%s)" % type_name(t.typ) ! # XXX Better to inspect t.typ! ! if result.startswith("POINTER(WINFUNCTYPE"): ! return result[8:-1] ! # XXX See comment above... ! elif result == "POINTER(None)": ! return "c_void_p" ! return result ! elif isinstance(t, nodes.ArrayType): ! return "%s * %s" % (type_name(t.typ), int(t.max)+1) ! elif isinstance(t, nodes.FunctionType): ! args = map(type_name, [t.returns] + t.arguments) ! # what now? WINFUNCTYPE already *is* a pointer to a function ! return "WINFUNCTYPE(%s)" % ", ".join(args) ! elif isinstance(t, nodes.CvQualifiedType): ! return "c_const(%s)" % type_name(t.typ) ! elif isinstance(t, nodes.FundamentalType): ! return ctypes_names[t.name] ! elif isinstance(t, nodes.Structure): ! return t.name ! elif isinstance(t, nodes.Enumeration): ! if t.name: ! return t.name ! return "c_int" # enums are integers ! elif isinstance(t, nodes.Typedef): ! return type_name(get_real_type(t.typ)) ! return t.name ! ! def get_real_type(tp): ! if type(tp) is nodes.Typedef: ! return get_real_type(tp.typ) ! return tp ! class Generator(object): def __init__(self): self.done = set() + self.more = set() ! def StructureHead(self, head): ! if head in self.done: ! return ! for struct in head.struct.bases: ! self.StructureHead(struct.get_head()) ! self.more.add(struct) ! basenames = [type_name(b) for b in head.struct.bases] ! if basenames: ! print "class %s(%s):" % (head.struct.name, ", ".join(basenames)) ! else: ! if type(head.struct) == nodes.Structure: ! print "class %s(Structure):" % head.struct.name ! elif type(head.struct) == nodes.Union: ! print "class %s(Union):" % head.struct.name ! print " pass" ! self.done.add(head) ! def Structure(self, struct): ! head = struct.get_head() ! self.StructureHead(head) ! body = struct.get_body() ! self.StructureBody(body) ! self.done.add(struct) ! ! def Typedef(self, tp): ! if tp in self.done: ! return ! if type(tp.typ) in (nodes.Structure, nodes.Union): ! self.StructureHead(tp.typ.get_head()) ! self.more.add(tp.typ) ! else: ! self.generate([tp.typ]) ! print "%s = %s" % (tp.name, type_name(tp.typ)) ! self.done.add(tp) ! def ArrayType(self, tp): ! if tp in self.done: ! return ! if type(tp.typ) is nodes.Typedef: ! self.more.add(tp.typ) ! self.generate([get_real_type(tp.typ)]) ! self.done.add(tp) ! def FunctionType(self, tp): ! if tp in self.done: ! return ! self.generate([tp.returns]) ! self.generate(tp.arguments) ! self.done.add(tp) ! ! def PointerType(self, tp): ! if tp in self.done: ! return ! if type(tp.typ) is nodes.PointerType: ! self.PointerType(tp.typ) ! elif type(tp.typ) in (nodes.Union, nodes.Structure): ! self.StructureHead(tp.typ.get_head()) ! self.more.add(tp.typ) ! elif type(tp.typ) is nodes.Typedef: ! self.generate([tp.typ]) ! else: ! self.generate([tp.typ]) ! self.done.add(tp) ! ! def CvQualifiedType(self, tp): ! if tp in self.done: ! return ! self.generate([tp.typ]) ! self.done.add(tp) ! ! def Enumeration(self, tp): ! if tp in self.done: ! return ! if tp.name: ! print "%s = c_int" % tp.name ! for n, v in tp.values: ! print "%s = %s" % (n, v) ! self.done.add(tp) ! ! def StructureBody(self, body): ! if body in self.done: ! return ! fields = [] ! methods = [] ! for m in body.struct.members: ! if type(m) is nodes.Field: ! fields.append(m) ! if type(m.typ) is nodes.Typedef: ! self.more.add(m.typ) ! t = get_real_type(m.typ) ! self.generate([get_real_type(m.typ)]) ! if getattr(t, "name", None) == "SIZE": ! import pdb ! pdb.set_trace() ! if type(t) in (nodes.Structure, nodes.Union): ! assert t.get_body() in self.done ! ! ## self.generate([m.typ]) ! elif type(m) is nodes.Method: ! methods.append(m) ! self.generate([m.returns]) ! self.generate(m.arguments) ! elif type(m) is nodes.Constructor: ! pass if fields: ! print "%s._fields_ = [" % body.struct.name ! for f in fields: ! print " ('%s', %s)," % (f.name, type_name(f.typ)) print "]" if methods: ! print "%s._methods_ = [" % body.struct.name for m in methods: ! args = [type_name(a) for a in m.arguments] ! print " STDMETHOD(%s, '%s', %s)," % ( ! type_name(m.returns), ! m.name, ! ", ".join(args)) print "]" ! self.done.add(body) ! ! def Function(self, func): ! if func in self.done: return ! if func.extern: ! self.generate([func.returns]) ! self.generate(func.arguments) ! args = [type_name(a) for a in func.arguments] ! if "__stdcall__" in func.attributes: ! print "STDCALL(%s, '%s', %s)" % \ ! (type_name(func.returns), func.name, ", ".join(args)) ! else: ! print "CDECL(%s, '%s', %s)" % \ ! (type_name(func.returns), func.name, ", ".join(args)) ! self.done.add(func) def generate(self, items): ! for item in items: ! tp = type(item) ! if tp in (nodes.Structure, nodes.Union): ! self.Structure(item) ! elif tp == nodes.Typedef: ! self.Typedef(item) ! elif tp == nodes.FundamentalType: ! pass ! elif tp == nodes.PointerType: ! self.PointerType(item) ! elif tp == nodes.CvQualifiedType: ! self.CvQualifiedType(item) ! elif tp == nodes.ArrayType: ! self.ArrayType(item) ! elif tp == nodes.Enumeration: ! self.Enumeration(item) ! elif tp == nodes.StructureHead: ! self.StructureHead(item) ! elif tp == nodes.FunctionType: ! self.FunctionType(item) ! elif tp == nodes.Function: ! self.Function(item) ! else: ! raise "NYI", tp ################################################################ *************** *** 175,178 **** --- 225,230 ---- def main(): + from gccxmlparser import parse + ## items = parse(files=["windows.h"], xmlfile="windows.xml") items = find_names(sys.argv[1:]) gen = Generator() *************** *** 180,184 **** print "def STDMETHOD(*args): pass" print "def c_const(x): return x" ! gen.generate(items) if __name__ == "__main__": --- 232,247 ---- print "def STDMETHOD(*args): pass" print "def c_const(x): return x" ! print ! ! for i in range(20): ! gen.more = set() ! gen.generate(items) ! items = gen.more ! if not items: ! break ! if items: ! print "left after 20 loops", len(items) ! import pdb ! pdb.set_trace() if __name__ == "__main__": *************** *** 186,188 **** --- 249,252 ---- if len(sys.argv) == 1: sys.argv.extend("IDispatch".split()) + ## sys.argv.extend("ITypeComp".split()) main() |
From: Thomas H. <th...@us...> - 2004-10-04 09:15:16
|
Update of /cvsroot/ctypes/ctypes/sandbox/tools/codegen In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv7099 Modified Files: generate.py Log Message: Index: generate.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/sandbox/tools/codegen/generate.py,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** generate.py 1 Oct 2004 19:55:46 -0000 1.2 --- generate.py 4 Oct 2004 09:15:06 -0000 1.3 *************** *** 132,135 **** --- 132,137 ---- for i in range(80): for td in todo.copy(): + if type(td) in (nodes.StructureBody, nodes.StructureHead): + todo.add(td.struct) if type(td) is nodes.PointerType \ and type(td.typ) in (nodes.Structure, nodes.Union): *************** *** 149,153 **** todo -= self.done if not todo: ! return if todo: raise "Not enough loops???", (len(todo), todo) --- 151,162 ---- todo -= self.done if not todo: ! break ! ! for i in self.done: ! if type(i) in (nodes.StructureBody, nodes.StructureHead): ! assert i.struct in self.done ! if type(i) in (nodes.Structure,): ! assert i.get_body() in self.done ! assert i.get_head() in self.done if todo: raise "Not enough loops???", (len(todo), todo) |
From: Thomas H. <th...@us...> - 2004-10-04 09:14:13
|
Update of /cvsroot/ctypes/ctypes/sandbox/tools/codegen In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv6936 Modified Files: nodes.py Log Message: Index: nodes.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/sandbox/tools/codegen/nodes.py,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** nodes.py 1 Oct 2004 18:58:09 -0000 1.5 --- nodes.py 4 Oct 2004 09:14:01 -0000 1.6 *************** *** 98,101 **** --- 98,103 ---- def depends(self): + if type(self.typ) in (Structure, Union): + return [self.typ.get_head()] return [self.typ] *************** *** 118,122 **** # Structure depends on StructureHead and StructureBody # StructureHead depends on bases, ! # StructureBody depends on members. # # Pointer to Structure depends on StructureHead only --- 120,124 ---- # Structure depends on StructureHead and StructureBody # StructureHead depends on bases, ! # StructureBody depends on head and members. # # Pointer to Structure depends on StructureHead only *************** *** 127,130 **** --- 129,133 ---- def depends(self): + # XXX Hm, does it depend on bases, or does it depends on the bases' head? return self.struct.bases *************** *** 135,138 **** --- 138,143 ---- def depends(self): result = set() + # needed, so that the head is defined before the body + result.add(self.struct.get_head()) for m in self.struct.members: if type(m) is Field: *************** *** 142,145 **** --- 147,153 ---- return result + def __repr__(self): + return "<StructureBody(%s) at %x>" % (self.struct.name, id(self)) + class _Struct_Union_Base(object): def depends(self): |
From: Thomas H. <th...@us...> - 2004-10-01 19:58:05
|
Update of /cvsroot/ctypes/ctypes/sandbox/tools/codegen In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv18369 Modified Files: gccxmlparser.py Log Message: Use a mangled name for unnamed structures or unions. Index: gccxmlparser.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/sandbox/tools/codegen/gccxmlparser.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** gccxmlparser.py 30 Sep 2004 17:46:36 -0000 1.1 --- gccxmlparser.py 1 Oct 2004 19:56:50 -0000 1.2 *************** *** 67,70 **** --- 67,73 ---- self.artificial = [] + def demangle(self, name): + return "_py_" + name.replace("$", "_") + def startElement(self, name, attrs): # find and call the handler for this element *************** *** 234,237 **** --- 237,242 ---- size = attrs.get("size") artificial = attrs.get("artificial") + if name is None: + name = self.demangle(attrs["mangled"]) # for debug only ## if abstract: ## return nodes.Class(name, members, bases) *************** *** 241,245 **** else: ## struct = nodes.Structure(name, align, members, bases, size) ! struct = nodes.Structure(None, align, members, bases, size) self.artificial.append(nodes.Typedef(name, struct)) return struct --- 246,250 ---- else: ## struct = nodes.Structure(name, align, members, bases, size) ! struct = nodes.Structure(name, align, members, bases, size) self.artificial.append(nodes.Typedef(name, struct)) return struct *************** *** 258,261 **** --- 263,268 ---- size = attrs.get("size") artificial = attrs.get("artificial") + if name is None: + name = self.demangle(attrs["mangled"]) # for debug only return nodes.Union(name, align, members, bases, size) |
From: Thomas H. <th...@us...> - 2004-10-01 19:57:12
|
Update of /cvsroot/ctypes/ctypes/sandbox/tools/codegen In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv18185 Modified Files: generate.py Log Message: Output ctypes header. Index: generate.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/sandbox/tools/codegen/generate.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** generate.py 1 Oct 2004 19:04:35 -0000 1.1 --- generate.py 1 Oct 2004 19:55:46 -0000 1.2 *************** *** 63,66 **** --- 63,67 ---- def StructureHead(self, t): + assert t.struct.name is not None print "class %s(Structure):" % t.struct.name print " pass" *************** *** 149,152 **** --- 150,155 ---- if not todo: return + if todo: + raise "Not enough loops???", (len(todo), todo) ################################################################ *************** *** 165,168 **** --- 168,174 ---- items = find_names(sys.argv[1:]) gen = Generator() + print "from ctypes import *" + print "def STDMETHOD(*args): pass" + print "def c_const(x): return x" gen.generate(items) |
From: Thomas H. <th...@us...> - 2004-10-01 19:04:46
|
Update of /cvsroot/ctypes/ctypes/sandbox/tools/codegen In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv9391 Added Files: generate.py Log Message: This one seems to handle the dependencies, although it still generates invalid cod for more complicated cases. Examples that do work, and worth to try, are CLSCTX, RegisterClassExA, and DCB, but beware that struct packing is not yet correct. --- NEW FILE: generate.py --- import nodes from ctypes_names import ctypes_names try: set except NameError: from sets import Set as set ################ ##renames = {} class Generator(object): def __init__(self): self.done = set() def type_name(self, t): # Return a string, containing an expression which can be used to # refer to the type. Assumes the ctypes.* namespace is available. if isinstance(t, nodes.PointerType): result = "POINTER(%s)" % self.type_name(t.typ) # XXX Better to inspect t.typ! if result.startswith("POINTER(WINFUNCTYPE"): return result[8:-1] # XXX See comment above... elif result == "POINTER(None)": return "c_void_p" return result elif isinstance(t, nodes.ArrayType): return "%s * %s" % (self.type_name(t.typ), int(t.max)+1) elif isinstance(t, nodes.FunctionType): args = map(self.type_name, [t.returns] + t.arguments) # what now? WINFUNCTYPE already *is* a pointer to a function return "WINFUNCTYPE(%s)" % ", ".join(args) elif isinstance(t, nodes.CvQualifiedType): return "c_const(%s)" % self.type_name(t.typ) elif isinstance(t, nodes.FundamentalType): return ctypes_names[t.name] elif isinstance(t, nodes.Structure): ## try: ## return renames[t] ## except KeyError: return t.name elif isinstance(t, nodes.Enumeration): ## try: ## return renames[t] ## except KeyError: ## pass if t.name: return t.name return "c_int" # enums are integers return t.name def Enumeration(self, enum): if enum.name is not None: # enums are integers (AFAIK, but may depend on the compiler) print "%s = c_int" % enum.name for name, val in enum.values: print "%s = %s" % (name, val) print def Typedef(self, t): print "%s = %s" % (t.name, self.type_name(t.typ)) def StructureHead(self, t): print "class %s(Structure):" % t.struct.name print " pass" def StructureBody(self, t): self.done.update(t.struct.members) fields = [m for m in t.struct.members if type(m) is nodes.Field] if fields: print "%s._fields_ = [" % t.struct.name for m in fields: if m.bits: print " ('%s', %s, %s)," % (m.name, self.type_name(m.typ), m.bits) else: print " ('%s', %s)," % (m.name, self.type_name(m.typ)) print "]" methods = [m for m in t.struct.members if type(m) is nodes.Method] if methods: print "%s._methods_ = [" % t.struct.name for m in methods: args = [self.type_name(a) for a in m.arguments] text = " STDMETHOD(%s, '%s'" % (self.type_name(m.returns), m.name) if args: print "%s, %s)," % (text, ", ".join(args)) else: print "%s)," % text print "]" def Function(self, t): if not t.extern: return dllname = "<unknown>" if "__stdcall__" in t.attributes: print "%s = STDCALL(%r, %s, '%s', %s)" % \ (t.name, dllname, self.type_name(t.returns), t.name, ", ".join(map(self.type_name, t.arguments))) else: # __cdecl is default print "%s = CDECL(%r, %s, '%s', %s)" % \ (t.name, dllname, self.type_name(t.returns), t.name, ", ".join(map(self.type_name, t.arguments))) def _generate(self, t): # the dispatcher typ = type(t) if typ is nodes.Enumeration: self.Enumeration(t) elif typ is nodes.Typedef: self.Typedef(t) elif typ is nodes.StructureHead: self.StructureHead(t) elif typ is nodes.StructureBody: self.StructureBody(t) elif typ is nodes.Function: self.Function(t) elif typ in (nodes.Structure, nodes.Union, nodes.PointerType, nodes.FundamentalType, nodes.ArrayType, nodes.FunctionType): self.done.add(t) else: raise TypeError, "don't know how to generate code for %s" % t self.done.add(t) def generate(self, items): todo = set(items) # todo contains definitions we have to generate # self.done contains definitions already done for i in range(80): for td in todo.copy(): if type(td) is nodes.PointerType \ and type(td.typ) in (nodes.Structure, nodes.Union): # pointers to struct or union only depend on their head, # but we want the body as well. # # XXX Maybe it would be better to have this in the # code generator for the struct/union head. todo.add(td.typ) needs = set(td.depends()) assert td not in needs if needs.issubset(self.done): self._generate(td) assert td in self.done else: todo.update(needs) todo -= self.done if not todo: return ################################################################ def find_names(names): from gccxmlparser import parse items = parse(files=["windows.h"], xmlfile="windows.xml") result = [] for i in items: if getattr(i, "name", None) in names: result.append(i) return result def main(): items = find_names(sys.argv[1:]) gen = Generator() gen.generate(items) if __name__ == "__main__": import sys if len(sys.argv) == 1: sys.argv.extend("IDispatch".split()) main() |
From: Thomas H. <th...@us...> - 2004-10-01 18:58:19
|
Update of /cvsroot/ctypes/ctypes/sandbox/tools/codegen In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv8309 Modified Files: nodes.py Log Message: Remove Class, which is not used. Split off body and head items off Structure and Union. Index: nodes.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/sandbox/tools/codegen/nodes.py,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** nodes.py 30 Sep 2004 19:57:40 -0000 1.4 --- nodes.py 1 Oct 2004 18:58:09 -0000 1.5 *************** *** 86,90 **** t = get_pointed_to(self) if type(t) in (Structure, Union): ! return [] return [t] --- 86,90 ---- t = get_pointed_to(self) if type(t) in (Structure, Union): ! return [t.get_head()] return [t] *************** *** 115,119 **** return "<Array(%s[%s]) at %x>" % (self.typ, self.max, id(self)) ! class Structure(object): def __init__(self, name, align, members, bases, size, artificial=None): self.name = name --- 115,159 ---- return "<Array(%s[%s]) at %x>" % (self.typ, self.max, id(self)) ! # Structures (and Unions, as well) are split into three objects. ! # Structure depends on StructureHead and StructureBody ! # StructureHead depends on bases, ! # StructureBody depends on members. ! # ! # Pointer to Structure depends on StructureHead only ! ! class StructureHead(object): ! def __init__(self, struct): ! self.struct = struct ! ! def depends(self): ! return self.struct.bases ! ! class StructureBody(object): ! def __init__(self, struct): ! self.struct = struct ! ! def depends(self): ! result = set() ! for m in self.struct.members: ! if type(m) is Field: ! result.add(m.typ) ! if type(m) is Method: ! result.update(m.depends()) ! return result ! ! class _Struct_Union_Base(object): ! def depends(self): ! return [self.struct_head, self.struct_body] ! ! def get_body(self): ! return self.struct_body ! ! def get_head(self): ! return self.struct_head ! ! def __repr__(self): ! return "<%s(%s) at %x>" % (self.__class__.__name__, self.name, id(self)) ! ! class Structure(_Struct_Union_Base): def __init__(self, name, align, members, bases, size, artificial=None): self.name = name *************** *** 127,143 **** else: self.size = None ! def depends(self): ! result = set() ! if self.bases: ! result.update(self.bases) ! for m in self.members: ! result.update(m.depends()) ! return result ! ! def __repr__(self): ! return "<Structure(%s) at %x>" % (self.name, id(self)) ! ! class Union(object): def __init__(self, name, align, members, bases, size, artificial=None): self.name = name --- 167,174 ---- else: self.size = None + self.struct_body = StructureBody(self) + self.struct_head = StructureHead(self) ! class Union(_Struct_Union_Base): def __init__(self, name, align, members, bases, size, artificial=None): self.name = name *************** *** 151,168 **** else: self.size = None ! ! def depends(self): ! result = set() ! if self.bases: ! result.update(self.bases) ! for m in self.members: ! result.update(m.depends()) ! return result ! ! ##class Class(object): ! ## def __init__(self, name, members, bases): ! ## self.name = name ! ## self.members = members ! ## self.bases = bases class Field(object): --- 182,187 ---- else: self.size = None ! self.struct_body = StructureBody(self) ! self.struct_head = StructureHead(self) class Field(object): |
From: Thomas H. <th...@us...> - 2004-10-01 18:55:09
|
Update of /cvsroot/ctypes/ctypes/sandbox/tools/codegen In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv7671 Removed Files: pycodegen.py Log Message: --- pycodegen.py DELETED --- |