ctypes-commit Mailing List for ctypes (Page 83)
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-11-25 14:04:16
|
Update of /cvsroot/ctypes/ctypes/source In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv2194 Modified Files: cfield.c Log Message: Fix a compiler warning. Index: cfield.c =================================================================== RCS file: /cvsroot/ctypes/ctypes/source/cfield.c,v retrieving revision 1.68 retrieving revision 1.69 diff -C2 -d -r1.68 -r1.69 *** cfield.c 19 Nov 2004 12:59:27 -0000 1.68 --- cfield.c 25 Nov 2004 14:04:06 -0000 1.69 *************** *** 273,277 **** 0, /* tp_setattr */ 0, /* tp_compare */ ! CField_repr, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ --- 273,277 ---- 0, /* tp_setattr */ 0, /* tp_compare */ ! (reprfunc)CField_repr, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ |
From: Thomas H. <th...@us...> - 2004-11-25 11:05:03
|
Update of /cvsroot/ctypes/ctypes In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv28874 Modified Files: ChangeLog Log Message: Index: ChangeLog =================================================================== RCS file: /cvsroot/ctypes/ctypes/ChangeLog,v retrieving revision 1.70 retrieving revision 1.71 diff -C2 -d -r1.70 -r1.71 *** ChangeLog 29 Oct 2004 19:31:09 -0000 1.70 --- ChangeLog 25 Nov 2004 11:04:27 -0000 1.71 *************** *** 1,2 **** --- 1,8 ---- + 2004-11-19 Thomas Heller <th...@py...> + + * (Message): The _fields_ attribute can now be set *after* a + Structure or Union type has been created. + XXX Describe the exact semantics. + 2004-10-29 Thomas Heller <th...@py...> |
From: Thomas H. <th...@us...> - 2004-11-25 09:37:56
|
Update of /cvsroot/ctypes/ctypes/source In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv11132 Modified Files: _ctypes.c Log Message: More refactoring - moved code around, made CData_GetList() static. Index: _ctypes.c =================================================================== RCS file: /cvsroot/ctypes/ctypes/source/_ctypes.c,v retrieving revision 1.184 retrieving revision 1.185 diff -C2 -d -r1.184 -r1.185 *** _ctypes.c 25 Nov 2004 09:01:20 -0000 1.184 --- _ctypes.c 25 Nov 2004 09:37:44 -0000 1.185 *************** *** 658,662 **** memcpy(self->b_ptr, ptr, size); - /* What about CData_GetList()? We don't care, since we have a copy of the data */ return 0; } --- 658,661 ---- *************** *** 712,717 **** Py_DECREF(value); - /* What about CData_GetList()? No need to do something, since we have - a copy of the data */ return 0; } --- 711,714 ---- *************** *** 770,774 **** done: Py_DECREF(value); ! /* What about CData_GetList()? We don't care, since we have a copy of the data */ return result; } --- 767,771 ---- done: Py_DECREF(value); ! return result; } *************** *** 1584,1617 **** * Code to keep needed objects alive */ - static int - CanKeepRef(CDataObject *target, int index) - { - PyObject *objects = CData_GetList(target); - if (!objects) - return -1; - if (index < 0 || PyList_Size(objects) <= index) { - PyErr_SetString(PyExc_IndexError, - "invalid index"); - return -1; - } - return 0; - } ! static int ! KeepRef(CDataObject *target, int index, PyObject *keep) ! { ! int result; ! PyObject *list = CData_GetList(target); ! result = PyList_SetItem(list, index, keep); ! if (result == -1) ! return -1; ! return 0; ! } ! ! /* ! * Return a list of size <size> filled with None's. ! */ static PyObject * ! RepeatedList(PyObject *ob, int size) { int i; --- 1581,1588 ---- * Code to keep needed objects alive */ ! /* Return a list of size <size> filled with None's. */ static PyObject * ! NoneList(int size) { int i; *************** *** 1622,1637 **** return NULL; for (i = 0; i < size; ++i) { ! Py_INCREF(ob); ! PyList_SET_ITEM(list, i, ob); } return list; } - static PyObject * - NoneList(int size) - { - return RepeatedList(Py_None, size); - } - #define ASSERT_CDATA(x) assert(((x)->b_base == NULL) ^ ((x)->b_objects == NULL)) --- 1593,1602 ---- return NULL; for (i = 0; i < size; ++i) { ! Py_INCREF(Py_None); ! PyList_SET_ITEM(list, i, Py_None); } return list; } #define ASSERT_CDATA(x) assert(((x)->b_base == NULL) ^ ((x)->b_objects == NULL)) *************** *** 1640,1644 **** * Borrowed reference! */ ! PyObject * CData_GetList(CDataObject *mem) { --- 1605,1609 ---- * Borrowed reference! */ ! static PyObject * CData_GetList(CDataObject *mem) { *************** *** 1692,1695 **** --- 1657,1693 ---- } + static PyObject * + GetKeepedObjects(CDataObject *target) + { + return CData_GetList(target); + } + + /* set an exception and return -1 if a call to KeepRef will fail, 0 otherwise */ + static int + CanKeepRef(CDataObject *target, int index) + { + PyObject *objects = CData_GetList(target); + if (!objects) + return -1; + if (index < 0 || PyList_Size(objects) <= index) { + PyErr_SetString(PyExc_IndexError, + "invalid index"); + return -1; + } + return 0; + } + + /* Keep a reference to 'keep' in the 'target', at index 'index' */ + static int + KeepRef(CDataObject *target, int index, PyObject *keep) + { + int result; + PyObject *list = CData_GetList(target); + result = PyList_SetItem(list, index, keep); + if (result == -1) + return -1; + return 0; + } + /******************************************************************/ /* *************** *** 1968,1972 **** /* XXX */; ! value = CData_GetList(src); Py_INCREF(value); return value; --- 1966,1970 ---- /* XXX */; ! value = GetKeepedObjects(src); Py_INCREF(value); return value; *************** *** 1989,1993 **** *(void **)ptr = src->b_ptr; ! keep = CData_GetList(src); /* We are assigning an array object to a field which represents --- 1987,1991 ---- *(void **)ptr = src->b_ptr; ! keep = GetKeepedObjects(src); /* We are assigning an array object to a field which represents *************** *** 3366,3370 **** return -1; ! keep = CData_GetList(dst); Py_INCREF(keep); return KeepRef(self, 0, keep); --- 3364,3368 ---- return -1; ! keep = GetKeepedObjects(dst); Py_INCREF(keep); return KeepRef(self, 0, keep); |
From: Thomas H. <th...@us...> - 2004-11-25 09:05:53
|
Update of /cvsroot/ctypes/ctypes/sandbox/tools/codegen In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv4481 Modified Files: gccxmlparser.py codegenerator.py Added Files: typedesc.py Removed Files: nodes.py Log Message: Renamed nodes.py to typedesc.py. --- NEW FILE: typedesc.py --- # typedesc.py - classes representing C type descriptions try: set except NameError: from sets import Set as set class _HasArgs(object): def add_argument(self, arg): self.arguments.append(arg) ################ class Function(_HasArgs): def __init__(self, name, returns, attributes, extern): self.name = name self.returns = returns self.attributes = attributes # dllimport, __stdcall__, __cdecl__ self.arguments = [] self.extern = extern class Constructor(_HasArgs): def __init__(self, name): self.name = name self.arguments = [] class OperatorFunction(_HasArgs): def __init__(self, name, returns): self.name = name self.returns = returns self.arguments = [] class FunctionType(_HasArgs): def __init__(self, returns): self.returns = returns self.arguments = [] class Method(_HasArgs): def __init__(self, name, returns): self.name = name self.returns = returns self.arguments = [] class FundamentalType(object): def __init__(self, name, size, align): self.name = name if name != "void": self.size = int(size) self.align = int(align) class PointerType(object): def __init__(self, typ, size, align): self.typ = typ self.size = int(size) self.align = int(align) class Typedef(object): def __init__(self, name, typ): self.name = name self.typ = typ class ArrayType(object): def __init__(self, typ, min, max): self.typ = typ self.min = min self.max = max class StructureHead(object): def __init__(self, struct): self.struct = struct class StructureBody(object): def __init__(self, struct): self.struct = struct class _Struct_Union_Base(object): def get_body(self): return self.struct_body def get_head(self): return self.struct_head class Structure(_Struct_Union_Base): def __init__(self, name, align, members, bases, size, artificial=None): self.name = name self.align = int(align) self.members = members self.bases = bases self.artificial = artificial if size is not None: self.size = int(size) 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 self.align = int(align) self.members = members self.bases = bases self.artificial = artificial if size is not None: self.size = int(size) else: self.size = None self.struct_body = StructureBody(self) self.struct_head = StructureHead(self) class Field(object): def __init__(self, name, typ, bits, offset): self.name = name self.typ = typ self.bits = bits self.offset = int(offset) class CvQualifiedType(object): def __init__(self, typ, attrib): self.typ = typ self.attrib = attrib class Enumeration(object): def __init__(self, name, size, align): self.name = name self.size = int(size) self.align = int(align) self.values = [] def add_value(self, name, value): self.values.append((name, value)) ################################################################ --- nodes.py DELETED --- Index: codegenerator.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/sandbox/tools/codegen/codegenerator.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** codegenerator.py 23 Nov 2004 20:04:40 -0000 1.1 --- codegenerator.py 25 Nov 2004 09:05:25 -0000 1.2 *************** *** 1,3 **** ! import nodes try: --- 1,3 ---- ! import typedesc, sys try: *************** *** 40,46 **** def storage(t): # return the size and alignment of a type ! if isinstance(t, nodes.Typedef): return storage(t.typ) ! elif isinstance(t, nodes.ArrayType): s, a = storage(t.typ) return s * (int(t.max) - int(t.min) + 1), a --- 40,46 ---- def storage(t): # return the size and alignment of a type ! if isinstance(t, typedesc.Typedef): return storage(t.typ) ! elif isinstance(t, typedesc.ArrayType): s, a = storage(t.typ) return s * (int(t.max) - int(t.min) + 1), a *************** *** 91,95 **** def calc_packing(struct, fields): # try several packings, starting with unspecified packing ! isStruct = isinstance(struct, nodes.Structure) for pack in [None, 16*8, 8*8, 4*8, 2*8, 1*8]: try: --- 91,95 ---- def calc_packing(struct, fields): # try several packings, starting with unspecified packing ! isStruct = isinstance(struct, typedesc.Structure) for pack in [None, 16*8, 8*8, 4*8, 2*8, 1*8]: try: *************** *** 106,110 **** # 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! --- 106,110 ---- # Return a string, containing an expression which can be used to # refer to the type. Assumes the ctypes.* namespace is available. ! if isinstance(t, typedesc.PointerType): result = "POINTER(%s)" % type_name(t.typ) # XXX Better to inspect t.typ! *************** *** 117,137 **** 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) # WINFUNCTYPE already *is* a pointer to a function! return "CFUNCTYPE(%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] ! 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 t.name return t.name --- 117,137 ---- return "c_void_p" return result ! elif isinstance(t, typedesc.ArrayType): return "%s * %s" % (type_name(t.typ), int(t.max)+1) ! elif isinstance(t, typedesc.FunctionType): args = map(type_name, [t.returns] + t.arguments) # WINFUNCTYPE already *is* a pointer to a function! return "CFUNCTYPE(%s)" % ", ".join(args) ! elif isinstance(t, typedesc.CvQualifiedType): return "const(%s)" % type_name(t.typ) ! elif isinstance(t, typedesc.FundamentalType): return ctypes_names[t.name] ! elif isinstance(t, typedesc.Structure): return t.name ! elif isinstance(t, typedesc.Enumeration): if t.name: return t.name return "c_int" # enums are integers ! elif isinstance(t, typedesc.Typedef): return t.name return t.name *************** *** 149,153 **** def get_real_type(tp): ! if type(tp) is nodes.Typedef: return get_real_type(tp.typ) return tp --- 149,153 ---- def get_real_type(tp): ! if type(tp) is typedesc.Typedef: return get_real_type(tp.typ) return tp *************** *** 184,187 **** --- 184,188 ---- msvcrt msimg32 + netapi32 rpcrt4""".split() *************** *** 208,217 **** print >> self.stream, "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 >> self.stream, "class %s(_com_interface):" % head.struct.name ! elif type(head.struct) == nodes.Structure: print >> self.stream, "class %s(Structure):" % head.struct.name ! elif type(head.struct) == nodes.Union: print >> self.stream, "class %s(Union):" % head.struct.name print >> self.stream, " pass" --- 209,218 ---- print >> self.stream, "class %s(%s):" % (head.struct.name, ", ".join(basenames)) else: ! methods = [m for m in head.struct.members if type(m) is typedesc.Method] if methods: print >> self.stream, "class %s(_com_interface):" % head.struct.name ! elif type(head.struct) == typedesc.Structure: print >> self.stream, "class %s(Structure):" % head.struct.name ! elif type(head.struct) == typedesc.Union: print >> self.stream, "class %s(Union):" % head.struct.name print >> self.stream, " pass" *************** *** 234,238 **** return self._typedefs += 1 ! if type(tp.typ) in (nodes.Structure, nodes.Union): self.StructureHead(tp.typ.get_head()) self.more.add(tp.typ) --- 235,239 ---- return self._typedefs += 1 ! if type(tp.typ) in (typedesc.Structure, typedesc.Union): self.StructureHead(tp.typ.get_head()) self.more.add(tp.typ) *************** *** 266,275 **** return self._pointertypes += 1 ! 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: --- 267,276 ---- return self._pointertypes += 1 ! if type(tp.typ) is typedesc.PointerType: self.PointerType(tp.typ) ! elif type(tp.typ) in (typedesc.Union, typedesc.Structure): self.StructureHead(tp.typ.get_head()) self.more.add(tp.typ) ! elif type(tp.typ) is typedesc.Typedef: self.generate(tp.typ) else: *************** *** 304,317 **** methods = [] for m in body.struct.members: ! if type(m) is nodes.Field: fields.append(m) ! if type(m.typ) is nodes.Typedef: self.generate(get_real_type(m.typ)) self.generate(m.typ) ! 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 --- 305,318 ---- methods = [] for m in body.struct.members: ! if type(m) is typedesc.Field: fields.append(m) ! if type(m.typ) is typedesc.Typedef: self.generate(get_real_type(m.typ)) self.generate(m.typ) ! elif type(m) is typedesc.Method: methods.append(m) self.generate(m.returns) self.generate_all(m.arguments) ! elif type(m) is typedesc.Constructor: pass *************** *** 320,324 **** # # Hm, how to detect a COM interface with no methods? IXMLDOMCDATASection is such a beast... ! ## if not isinstance(body.struct, nodes.Union) and not methods: if not methods: pack = calc_packing(body.struct, fields) --- 321,325 ---- # # Hm, how to detect a COM interface with no methods? IXMLDOMCDATASection is such a beast... ! ## if not isinstance(body.struct, typedesc.Union) and not methods: if not methods: pack = calc_packing(body.struct, fields) *************** *** 367,379 **** else: return dll._name ! return "?" _functiontypes = 0 def Function(self, func): if func in self.done: return - self._functiontypes += 1 dllname = self.find_dllname(func.name) ! if dllname and func.extern: self.generate(func.returns) self.generate_all(func.arguments) --- 368,381 ---- else: return dll._name ! ## print >> sys.stderr, "warning: dll not found for function %s" % name ! return None _functiontypes = 0 + _notfound_functiontypes = 0 def Function(self, func): if func in self.done: return dllname = self.find_dllname(func.name) ! if dllname: self.generate(func.returns) self.generate_all(func.arguments) *************** *** 385,388 **** --- 387,393 ---- print >> self.stream, "%s = CDECL('%s', %s, '%s', [%s])" % \ (func.name, dllname, type_name(func.returns), func.name, ", ".join(args)) + self._functiontypes += 1 + else: + self._notfound_functiontypes += 1 self.done.add(func) *************** *** 424,427 **** --- 429,433 ---- print >> stream, "# Pointertypes: %5d" % self._pointertypes print >> stream, "# Arraytypes: %5d" % self._arraytypes + print >> stream, "# Functions not located: %5d" % self._notfound_functiontypes print >> stream, "#" total = self._structures + self._functiontypes + self._enumtypes + self._typedefs +\ *************** *** 434,438 **** def generate_code(xmlfile, outfile, symbols=None): from gccxmlparser import parse - import sys items = parse(xmlfile) --- 440,443 ---- Index: gccxmlparser.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/sandbox/tools/codegen/gccxmlparser.py,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** gccxmlparser.py 23 Nov 2004 19:54:01 -0000 1.5 --- gccxmlparser.py 25 Nov 2004 09:05:25 -0000 1.6 *************** *** 1,5 **** """gccxmlparser - parse a gccxml created XML file into a sequence type descriptions""" import xml.sax ! import nodes try: set --- 1,5 ---- """gccxmlparser - parse a gccxml created XML file into a sequence type descriptions""" import xml.sax ! import typedesc try: set *************** *** 64,68 **** name = attrs["name"] typ = attrs["type"] ! return nodes.Typedef(name, typ) def _fixup_Typedef(self, t): --- 64,68 ---- name = attrs["name"] typ = attrs["type"] ! return typedesc.Typedef(name, typ) def _fixup_Typedef(self, t): *************** *** 76,80 **** size = attrs["size"] align = attrs["align"] ! return nodes.FundamentalType(name, size, align) def _fixup_FundamentalType(self, t): pass --- 76,80 ---- size = attrs["size"] align = attrs["align"] ! return typedesc.FundamentalType(name, size, align) def _fixup_FundamentalType(self, t): pass *************** *** 84,88 **** size = attrs["size"] align = attrs["align"] ! return nodes.PointerType(typ, size, align) def _fixup_PointerType(self, p): --- 84,88 ---- size = attrs["size"] align = attrs["align"] ! return typedesc.PointerType(typ, size, align) def _fixup_PointerType(self, p): *************** *** 99,103 **** if max == "ffffffffffffffff": max = "-1" ! return nodes.ArrayType(typ, min, max) def _fixup_ArrayType(self, a): --- 99,103 ---- if max == "ffffffffffffffff": max = "-1" ! return typedesc.ArrayType(typ, min, max) def _fixup_ArrayType(self, a): *************** *** 109,113 **** ## const = attrs["const"] ## volatile = attrs["volatile"] ! return nodes.CvQualifiedType(typ, "xxx") def _fixup_CvQualifiedType(self, c): --- 109,113 ---- ## const = attrs["const"] ## volatile = attrs["volatile"] ! return typedesc.CvQualifiedType(typ, "xxx") def _fixup_CvQualifiedType(self, c): *************** *** 122,126 **** attributes = attrs.get("attributes", "").split() extern = attrs.get("extern") ! return nodes.Function(name, returns, attributes, extern) def _fixup_Function(self, func): --- 122,126 ---- attributes = attrs.get("attributes", "").split() extern = attrs.get("extern") ! return typedesc.Function(name, returns, attributes, extern) def _fixup_Function(self, func): *************** *** 131,135 **** # id, returns, attributes returns = attrs["returns"] ! return nodes.FunctionType(returns) def _fixup_FunctionType(self, func): --- 131,135 ---- # id, returns, attributes returns = attrs["returns"] ! return typedesc.FunctionType(returns) def _fixup_FunctionType(self, func): *************** *** 141,145 **** name = attrs["name"] returns = attrs["returns"] ! return nodes.OperatorFunction(name, returns) def _fixup_OperatorFunction(self, func): --- 141,145 ---- name = attrs["name"] returns = attrs["returns"] ! return typedesc.OperatorFunction(name, returns) def _fixup_OperatorFunction(self, func): *************** *** 148,152 **** def Constructor(self, attrs): name = attrs["name"] ! return nodes.Constructor(name) def _fixup_Constructor(self, const): pass --- 148,152 ---- def Constructor(self, attrs): name = attrs["name"] ! return typedesc.Constructor(name) def _fixup_Constructor(self, const): pass *************** *** 156,160 **** name = attrs["name"] returns = attrs["returns"] ! return nodes.Method(name, returns) def _fixup_Method(self, m): --- 156,160 ---- name = attrs["name"] returns = attrs["returns"] ! return typedesc.Method(name, returns) def _fixup_Method(self, m): *************** *** 177,185 **** if attrs.get("artificial"): # enum {} ENUM_NAME; ! return nodes.Enumeration(name, size, align) else: # enum tagENUM {}; ! enum = nodes.Enumeration(None, size, align) ! self.artificial.append(nodes.Typedef(name, enum)) return enum --- 177,185 ---- if attrs.get("artificial"): # enum {} ENUM_NAME; ! return typedesc.Enumeration(name, size, align) else: # enum tagENUM {}; ! enum = typedesc.Enumeration(None, size, align) ! self.artificial.append(typedesc.Typedef(name, enum)) return enum *************** *** 207,218 **** name = self.demangle(attrs["mangled"]) # for debug only ## if abstract: ! ## return nodes.Class(name, members, bases) ## else: if artificial: ! return nodes.Structure(name, align, members, bases, size) 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 --- 207,218 ---- name = self.demangle(attrs["mangled"]) # for debug only ## if abstract: ! ## return typedesc.Class(name, members, bases) ## else: if artificial: ! return typedesc.Structure(name, align, members, bases, size) else: ! ## struct = typedesc.Structure(name, align, members, bases, size) ! struct = typedesc.Structure(name, align, members, bases, size) ! self.artificial.append(typedesc.Typedef(name, struct)) return struct *************** *** 232,236 **** if name is None: name = self.demangle(attrs["mangled"]) # for debug only ! return nodes.Union(name, align, members, bases, size) def Field(self, attrs): --- 232,236 ---- if name is None: name = self.demangle(attrs["mangled"]) # for debug only ! return typedesc.Union(name, align, members, bases, size) def Field(self, attrs): *************** *** 240,244 **** bits = attrs.get("bits", None) offset = attrs.get("offset") ! return nodes.Field(name, typ, bits, offset) def _fixup_Field(self, f): --- 240,244 ---- bits = attrs.get("bits", None) offset = attrs.get("offset") ! return typedesc.Field(name, typ, bits, offset) def _fixup_Field(self, f): *************** *** 248,253 **** def get_result(self): ! interesting = ( ! nodes.Typedef, nodes.Enumeration, nodes.Function, nodes.Structure, nodes.Union) result = [] remove = [] --- 248,253 ---- def get_result(self): ! interesting = (typedesc.Typedef, typedesc.Enumeration, ! typedesc.Function, typedesc.Structure, typedesc.Union) result = [] remove = [] |
From: Thomas H. <th...@us...> - 2004-11-25 09:01:43
|
Update of /cvsroot/ctypes/ctypes/source In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv3763 Modified Files: _ctypes.c Log Message: Refactored the code to keep references to objects. Index: _ctypes.c =================================================================== RCS file: /cvsroot/ctypes/ctypes/source/_ctypes.c,v retrieving revision 1.183 retrieving revision 1.184 diff -C2 -d -r1.183 -r1.184 *** _ctypes.c 19 Nov 2004 11:07:23 -0000 1.183 --- _ctypes.c 25 Nov 2004 09:01:20 -0000 1.184 *************** *** 1581,1590 **** ! /******************************************************************/ ! /* ! CData_Type */ ! char basespec_string[] = "base specification"; /* --- 1581,1611 ---- ! /***************************************************************** ! * Code to keep needed objects alive */ + static int + CanKeepRef(CDataObject *target, int index) + { + PyObject *objects = CData_GetList(target); + if (!objects) + return -1; + if (index < 0 || PyList_Size(objects) <= index) { + PyErr_SetString(PyExc_IndexError, + "invalid index"); + return -1; + } + return 0; + } ! static int ! KeepRef(CDataObject *target, int index, PyObject *keep) ! { ! int result; ! PyObject *list = CData_GetList(target); ! result = PyList_SetItem(list, index, keep); ! if (result == -1) ! return -1; ! return 0; ! } /* *************** *** 1671,1674 **** --- 1692,1702 ---- } + /******************************************************************/ + /* + CData_Type + */ + + char basespec_string[] = "base specification"; + static int CData_traverse(CDataObject *self, visitproc visit, void *arg) *************** *** 1988,1992 **** { CDataObject *mem = (CDataObject *)dst; ! PyObject *objects, *result; if (!CDataObject_Check(dst)) { --- 2016,2020 ---- { CDataObject *mem = (CDataObject *)dst; ! PyObject *result; if (!CDataObject_Check(dst)) { *************** *** 1995,2006 **** return -1; } ! objects = CData_GetList(mem); ! if (!objects) ! return -1; ! if (index < 0 || PyList_Size(objects) <= index) { ! PyErr_SetString(PyExc_IndexError, ! "invalid index"); return -1; - } result = _CData_set(mem, type, setfunc, value, size, ptr); --- 2023,2030 ---- return -1; } ! ! /* Make sure KeepRef will not fail! */ ! if (-1 == CanKeepRef(mem, index)) return -1; result = _CData_set(mem, type, setfunc, value, size, ptr); *************** *** 2008,2012 **** return -1; ! return PyList_SetItem(objects, index, result); } --- 2032,2037 ---- return -1; ! /* KeepRef steals a refcount from it's last argument */ ! return KeepRef(mem, index, result); } *************** *** 2265,2269 **** CFuncPtrObject *self; void *handle; - PyObject *objects; if (!PyArg_ParseTuple(args, "sO", &name, &dll)) --- 2290,2293 ---- *************** *** 2304,2318 **** *(void **)self->b_ptr = address; ! objects = CData_GetList((CDataObject *)self); ! if (!objects) { ! Py_DECREF((PyObject *)self); ! return NULL; ! } ! ! if (-1 == PyList_SetItem(objects, 0, dll)) { Py_DECREF((PyObject *)self); return NULL; } ! Py_INCREF((PyObject *)dll); /* for PyList_SetItem above */ Py_INCREF(self); --- 2328,2336 ---- *(void **)self->b_ptr = address; ! if (-1 == KeepRef((CDataObject *)self, 0, dll)) { Py_DECREF((PyObject *)self); return NULL; } ! Py_INCREF((PyObject *)dll); /* for KeepRef above */ Py_INCREF(self); *************** *** 2355,2359 **** StgDictObject *dict; THUNK thunk; - PyObject *objects; if (kwds && PyDict_GetItemString(kwds, "_basespec_")) { --- 2373,2376 ---- *************** *** 2438,2447 **** *(void **)self->b_ptr = *(void **)thunk; - objects = CData_GetList((CDataObject *)self); - if (!objects) { - Py_DECREF((PyObject *)self); - return NULL; - } - /* We store ourself in self->b_objects[0], because the whole instance must be kept alive if stored in a structure field, for example. --- 2455,2458 ---- *************** *** 2450,2458 **** */ ! if (-1 == PyList_SetItem(objects, 0, (PyObject *)self)) { Py_DECREF((PyObject *)self); return NULL; } ! Py_INCREF((PyObject *)self); /* for PyList_SetItem above */ return (PyObject *)self; --- 2461,2469 ---- */ ! if (-1 == KeepRef((CDataObject *)self, 0, (PyObject *)self)) { Py_DECREF((PyObject *)self); return NULL; } ! Py_INCREF((PyObject *)self); /* for KeepRef above */ return (PyObject *)self; *************** *** 3136,3140 **** { PyObject *result; - PyObject *objects; StgDictObject *dict = PyObject_stgdict((PyObject *)self); --- 3147,3150 ---- *************** *** 3142,3152 **** if (!result) return -1; ! ! /* Keep the object alive */ ! objects = CData_GetList(self); ! if (!objects) ! return -1; /* Hm. Severe bug. What now? Undo all the above? */ ! /* setfunc returns a new reference, PyList_SetItem() consumes it */ ! return PyList_SetItem(objects, 0, result); /* index is always 0 */ } --- 3152,3158 ---- if (!result) return -1; ! ! /* consumes the refcount the setfunc returns */ ! return KeepRef(self, 0, result); } *************** *** 3330,3334 **** StgDictObject *stgdict; CDataObject *dst; ! PyObject *objects, *keep; if (value == NULL) { --- 3336,3340 ---- StgDictObject *stgdict; CDataObject *dst; ! PyObject *keep; if (value == NULL) { *************** *** 3351,3356 **** *(void **)self->b_ptr = dst->b_ptr; - objects = CData_GetList(self); - /* A Pointer instance must keep a the value it points to alive. So, a --- 3357,3360 ---- *************** *** 3359,3368 **** */ Py_INCREF(value); ! if (-1 == PyList_SetItem(objects, 1, value)) return -1; keep = CData_GetList(dst); Py_INCREF(keep); ! return PyList_SetItem(objects, 0, keep); } --- 3363,3372 ---- */ Py_INCREF(value); ! if (-1 == KeepRef(self, 1, value)) return -1; keep = CData_GetList(dst); Py_INCREF(keep); ! return KeepRef(self, 0, keep); } |
From: Thomas H. <th...@us...> - 2004-11-23 20:06:09
|
Update of /cvsroot/ctypes/ctypes/sandbox/tools/codegen In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv12240 Added Files: xml2py.py h2xml.py Log Message: Two scripts with command line interface: create an XML file from one or more H files, and create a Python module from an XML file. --- NEW FILE: xml2py.py --- # bugs: # packing of structures/unions with bitfields? See '##XXX FIXME' import sys from codegenerator import generate_code ################################################################ def main(): from optparse import OptionParser parser = OptionParser("usage: %prog [options] xmlfile") parser.add_option("-s", dest="symbols", help="comma separated list of symbols to include " "(if not specified, all symbols will be included)", default=None) parser.add_option("-o", dest="python_file", help="output filename (if not specified, standard output will be used)", default="-") options, files = parser.parse_args() if len(files) != 1: parser.error("Only one input file can be specified") if options.python_file == "-": stream = sys.stdout else: stream = open(options.python_file, "w") generate_code(files[0], stream, symbols=options.symbols) if __name__ == "__main__": import sys if len(sys.argv) == 1: ## sys.argv.append("win32.xml") ## sys.argv.append("-sCoCreateInstance") sys.argv.append("win32.xml") sys.argv.append("-sCLSIDFromString,StringFromGUID2,IsEqualGUID") ## sys.argv.append("-owin32.py") main() --- NEW FILE: h2xml.py --- """h2xml - convert C include file(s) into an xml file by running gccxml.""" import sys, os, tempfile os.environ["PATH"] = r"c:\sf\buildgcc\bin\release" ################################################################ class CompilerError(Exception): pass # Create a C file containing #includes to the specified filenames. # Run GCCXML to create an XML file, and return the xml filename. def run_gccxml(fnames, options, verbose=0, xml_file=None): # fnames is the sequence of include files # options is seuqence of strings containing command line options for GCCXML # verbose - integer specifying the verbosity # # returns the filename of the generated XML file # write a temporary C file handle, c_file = tempfile.mkstemp(suffix=".c", text=True) if verbose: print >> sys.stderr, "writing temporary C source file %s" % c_file ## os.write(handle, 'extern "C" {\n'); for fname in fnames: os.write(handle, '#include <%s>\n' % fname) ## os.write(handle, '}'); os.close(handle) if xml_file is None: handle, xml_file = tempfile.mkstemp(suffix=".xml", text=True) os.close(handle) if options: options = " ".join(options) else: options = "" try: if verbose: print >> sys.stderr, r"gccxml.exe %s %s -fxml=%s" % (options, c_file, xml_file) i, o = os.popen4(r"gccxml.exe %s %s -fxml=%s" % (options, c_file, xml_file)) i.close() sys.stderr.write(o.read()) retval = o.close() if retval: raise CompilerError, "gccxml returned error %s" % retval return xml_file finally: if verbose: print >> sys.stderr, "Deleting temporary file %s" % c_file os.remove(c_file) ################################################################ def main(): from optparse import OptionParser def add_option(option, opt, value, parser): parser.values.gccxml_options.append("%s %s" % (opt, value)) parser = OptionParser() ## parser.add_option("-h", action="help") parser.add_option("-v", "--verbose", dest="verbose", action="store_true", default=False) parser.add_option("-D", type="string", action="callback", callback=add_option, dest="gccxml_options", help="macros to define", metavar="defines", default=[]) parser.add_option("-U", type="string", action="callback", callback=add_option, help="macros to undefine", metavar="defines") parser.add_option("-o", dest="xml_file", help="XML output filename", default=None) options, files = parser.parse_args() if not files: print "Error: no files to process" print >> sys.stderr, __doc__ return 1 try: xmlfile = run_gccxml(files, options.gccxml_options, options.verbose, options.xml_file) except CompilerError, detail: sys.exit(1) if options.xml_file is None: if options.verbose: print >> sys.stderr, "Deleting temporary file %s" % xmlfile os.remove(xmlfile) if __name__ == "__main__": main() |
From: Thomas H. <th...@us...> - 2004-11-23 20:04:50
|
Update of /cvsroot/ctypes/ctypes/sandbox/tools/codegen In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv11897 Added Files: codegenerator.py Removed Files: generate.py Log Message: The code generation is now in the codegenerator module. --- generate.py DELETED --- --- NEW FILE: codegenerator.py --- import nodes try: set except NameError: from sets import Set as set # XXX Should this be in ctypes itself? ctypes_names = { "unsigned char": "c_ubyte", "signed char": "c_byte", "char": "c_char", "wchar_t": "c_wchar", "short unsigned int": "c_ushort", "short int": "c_short", "long unsigned int": "c_ulong", "long int": "c_long", "long signed int": "c_long", "unsigned int": "c_uint", "int": "c_int", "long long unsigned int": "c_ulonglong", "long long int": "c_longlong", "double": "c_double", "float": "c_float", # Hm... "void": "None", } ################ def storage(t): # return the size and alignment of a type if isinstance(t, nodes.Typedef): return storage(t.typ) elif isinstance(t, nodes.ArrayType): s, a = storage(t.typ) return s * (int(t.max) - int(t.min) + 1), a return int(t.size), int(t.align) class PackingError(Exception): pass def _calc_packing(struct, fields, pack, isStruct): # Try a certain packing, raise PackingError if field offsets, # total size ot total alignment is wrong. if struct.size is None: # incomplete struct return -1 if struct.name in dont_assert_size: return None if struct.bases: size = struct.bases[0].size total_align = struct.bases[0].align else: size = 0 total_align = 8 # in bits for i, f in enumerate(fields): if f.bits: ## print "##XXX FIXME" return -2 # XXX FIXME s, a = storage(f.typ) if pack is not None: a = min(pack, a) if size % a: size += a - size % a if isStruct: if size != f.offset: raise PackingError, "field offset (%s/%s)" % (size, f.offset) size += s else: size = max(size, s) total_align = max(total_align, a) if total_align != struct.align: raise PackingError, "total alignment (%s/%s)" % (total_align, struct.align) a = total_align if pack is not None: a = min(pack, a) if size % a: size += a - size % a if size != struct.size: raise PackingError, "total size (%s/%s)" % (size, struct.size) def calc_packing(struct, fields): # try several packings, starting with unspecified packing isStruct = isinstance(struct, nodes.Structure) for pack in [None, 16*8, 8*8, 4*8, 2*8, 1*8]: try: _calc_packing(struct, fields, pack, isStruct) except PackingError, details: continue else: if pack is None: return None return pack/8 raise PackingError, "PACKING FAILED: %s" % details 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] if result.startswith("POINTER(CFUNCTYPE"): 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) # WINFUNCTYPE already *is* a pointer to a function! return "CFUNCTYPE(%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] 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 t.name return t.name # Is this needed? ##renames = { ## "POINTER(const(WCHAR))": "c_wchar_p", ## } ##def type_name(t): ## result = _type_name(t) ## return renames.get(result, result) type_name = _type_name def get_real_type(tp): if type(tp) is nodes.Typedef: return get_real_type(tp.typ) return tp # XXX These should be filtered out in gccxmlparser. 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 msimg32 rpcrt4""".split() ##rpcndr ##ntdll ##dll_names = "libxml2".split() from ctypes import CDLL searched_dlls = [CDLL(name) for name in dll_names] class Generator(object): def __init__(self, stream): self.done = set() self.stream = stream 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 >> self.stream, "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 >> self.stream, "class %s(_com_interface):" % head.struct.name elif type(head.struct) == nodes.Structure: print >> self.stream, "class %s(Structure):" % head.struct.name elif type(head.struct) == nodes.Union: print >> self.stream, "class %s(Union):" % head.struct.name print >> self.stream, " pass" self.done.add(head) _structures = 0 def Structure(self, struct): if struct in self.done: return self._structures += 1 head = struct.get_head() self.StructureHead(head) body = struct.get_body() self.StructureBody(body) self.done.add(struct) _typedefs = 0 def Typedef(self, tp): if tp in self.done: return self._typedefs += 1 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) if tp.name != type_name(tp.typ): print >> self.stream, "%s = %s # typedef" % (tp.name, type_name(tp.typ)) self.done.add(tp) _arraytypes = 0 def ArrayType(self, tp): if tp in self.done: return self._arraytypes += 1 self.generate(get_real_type(tp.typ)) self.generate(tp.typ) self.done.add(tp) _functiontypes = 0 def FunctionType(self, tp): if tp in self.done: return self._functiontypes += 1 self.generate(tp.returns) self.generate_all(tp.arguments) self.done.add(tp) _pointertypes = 0 def PointerType(self, tp): if tp in self.done: return self._pointertypes += 1 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) _enumtypes = 0 def Enumeration(self, tp): if tp in self.done: return self._enumtypes += 1 if tp.name: print >> self.stream print >> self.stream, "%s = c_int # enum" % tp.name for n, v in tp.values: print >> self.stream, "%s = %s # enum %s" % (n, v, tp.name) else: for n, v in tp.values: print >> self.stream, "%s = %s # enum" % (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.generate(get_real_type(m.typ)) self.generate(m.typ) 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 # we don't need _pack_ on Unions (I hope, at least), and # not on COM interfaces: # # Hm, how to detect a COM interface with no methods? IXMLDOMCDATASection is such a beast... ## if not isinstance(body.struct, nodes.Union) and not methods: if not methods: pack = calc_packing(body.struct, fields) if pack is not None: print >> self.stream, "%s._pack_ = %s" % (body.struct.name, pack) else: print >> self.stream, "# %s" % body.struct.name 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 >> self.stream, "%s._fields_ = %s._fields_ + [" % (body.struct.name, base) else: print >> self.stream, "%s._fields_ = [" % body.struct.name for f in fields: if f.bits is None: print >> self.stream, " ('%s', %s)," % (f.name, type_name(f.typ)) else: print >> self.stream, " ('%s', %s, %s)," % (f.name, type_name(f.typ), f.bits) print >> self.stream, "]" if methods: print >> self.stream, "%s._methods_ = [" % body.struct.name for m in methods: args = [type_name(a) for a in m.arguments] print >> self.stream, " STDMETHOD(%s, '%s', %s)," % ( type_name(m.returns), m.name, ", ".join(args)) print >> self.stream, "]" if body.struct.size and body.struct.name not in dont_assert_size: size = body.struct.size // 8 print >> self.stream, "assert sizeof(%s) == %s, sizeof(%s)" % \ (body.struct.name, size, body.struct.name) align = body.struct.align // 8 print >> self.stream, "assert alignment(%s) == %s, alignment(%s)" % \ (body.struct.name, align, body.struct.name) 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 "?" _functiontypes = 0 def Function(self, func): if func in self.done: return self._functiontypes += 1 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 >> self.stream, "%s = STDCALL('%s', %s, '%s', [%s])" % \ (func.name, dllname, type_name(func.returns), func.name, ", ".join(args)) else: print >> self.stream, "%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) def generate_code(self, items): items = set(items) loops = 0 while items: loops += 1 self.more = set() self.generate_all(items) items |= self.more items -= self.done return loops def print_stats(self, stream): print >> stream, "######################" print >> stream, "# Symbols defined:" print >> stream, "#" print >> stream, "# Struct/Unions: %5d" % self._structures print >> stream, "# Functions: %5d" % self._functiontypes print >> stream, "# Enums: %5d" % self._enumtypes print >> stream, "# Typedefs: %5d" % self._typedefs print >> stream, "# Pointertypes: %5d" % self._pointertypes print >> stream, "# Arraytypes: %5d" % self._arraytypes print >> stream, "#" total = self._structures + self._functiontypes + self._enumtypes + self._typedefs +\ self._pointertypes + self._arraytypes print >> stream, "# Total symbols: %5d" % total print >> stream, "######################" ################################################################ def generate_code(xmlfile, outfile, symbols=None): from gccxmlparser import parse import sys items = parse(xmlfile) todo = [] if symbols: syms = set(symbols.split(",")) for i in items: if i.name in syms: todo.append(i) syms.remove(i.name) items = todo if syms: print "SYMS NOT FOUND", list(syms) gen = Generator(outfile) # output header print >> outfile, "from ctypes import *" print >> outfile, "from _support import STDCALL, CDECL" print >> outfile, "def const(x): return x" print >> outfile loops = gen.generate_code(items) gen.print_stats(sys.stderr) print "needed %d loop(s)" % loops |
From: Thomas H. <th...@us...> - 2004-11-23 19:54:11
|
Update of /cvsroot/ctypes/ctypes/sandbox/tools/codegen In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv9258 Modified Files: gccxmlparser.py Log Message: Minor changes. Index: gccxmlparser.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/sandbox/tools/codegen/gccxmlparser.py,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** gccxmlparser.py 23 Nov 2004 19:23:29 -0000 1.4 --- gccxmlparser.py 23 Nov 2004 19:54:01 -0000 1.5 *************** *** 1,12 **** ! """xml2py - create ctypes module from XML file""" ! import sys import xml.sax - from sets import Set import nodes ################################################################ class GCCXML_Handler(xml.sax.handler.ContentHandler): ! has_values = Set(["Enumeration", "Function", "FunctionType", "OperatorFunction", "Method", "Constructor", "Destructor", "OperatorMethod"]) --- 1,14 ---- ! """gccxmlparser - parse a gccxml created XML file into a sequence type descriptions""" import xml.sax import nodes + try: + set + except NameError: + from sets import Set as set ################################################################ class GCCXML_Handler(xml.sax.handler.ContentHandler): ! has_values = set(["Enumeration", "Function", "FunctionType", "OperatorFunction", "Method", "Constructor", "Destructor", "OperatorMethod"]) *************** *** 265,269 **** ################################################################ ! def parse(xmlfile, options=None, verbose=0): handler = GCCXML_Handler() xml.sax.parse(xmlfile, handler) --- 267,272 ---- ################################################################ ! def parse(xmlfile): ! # parse an XML file into a sequence of type descriptions handler = GCCXML_Handler() xml.sax.parse(xmlfile, handler) |
From: Thomas H. <th...@us...> - 2004-11-23 19:53:24
|
Update of /cvsroot/ctypes/ctypes/sandbox/tools/codegen In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv9108 Modified Files: nodes.py Log Message: Removed unneeded methods. Index: nodes.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/sandbox/tools/codegen/nodes.py,v retrieving revision 1.11 retrieving revision 1.12 diff -C2 -d -r1.11 -r1.12 *** nodes.py 12 Nov 2004 09:31:18 -0000 1.11 --- nodes.py 23 Nov 2004 19:53:12 -0000 1.12 *************** *** 1,2 **** --- 1,3 ---- + # nodes.py - classes representing C type descriptions try: set *************** *** 47,53 **** self.align = int(align) - def __repr__(self): - return "<FundamentalType(%s)>" % self.name - class PointerType(object): def __init__(self, typ, size, align): --- 48,51 ---- *************** *** 56,62 **** self.align = int(align) - def __repr__(self): - return "<POINTER(%s)>" % self.typ - class Typedef(object): def __init__(self, name, typ): --- 54,57 ---- *************** *** 64,70 **** self.typ = typ - def __repr__(self): - return "<Typedef(%s) at %x>" % (self.name, id(self)) - class ArrayType(object): def __init__(self, typ, min, max): --- 59,62 ---- *************** *** 73,79 **** self.max = max - def __repr__(self): - return "<Array(%s[%s]) at %x>" % (self.typ, self.max, id(self)) - class StructureHead(object): def __init__(self, struct): --- 65,68 ---- *************** *** 84,94 **** self.struct = struct - def __repr__(self): - return "<StructureBody(%s) at %x>" % (self.struct.name, id(self)) - class _Struct_Union_Base(object): - def depends(self): - return [self.struct_head, self.struct_body] - def get_body(self): return self.struct_body --- 73,77 ---- *************** *** 97,103 **** 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): --- 80,83 ---- |
From: Thomas H. <th...@us...> - 2004-11-23 19:23:42
|
Update of /cvsroot/ctypes/ctypes/sandbox/tools/codegen In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv831 Modified Files: gccxmlparser.py Log Message: Removed the script parts of this module, and the cggxml runner code. Index: gccxmlparser.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/sandbox/tools/codegen/gccxmlparser.py,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** gccxmlparser.py 2 Nov 2004 16:33:00 -0000 1.3 --- gccxmlparser.py 23 Nov 2004 19:23:29 -0000 1.4 *************** *** 1,58 **** ! import sys, os, tempfile import xml.sax from sets import Set import nodes - # XXX - os.environ["PATH"] = r"c:\sf\buildgcc\bin\release" - - ################################################################ - - class CompilerError(Exception): - pass - - # Create a C file containing #includes to the specified filenames. - # Run GCCXML to create an XML file, and return the xml filename. - def run_gccxml(fnames, options, verbose=0, xml_file=None): - # fnames is the sequence of include files - # options is seuqence of strings containing command line options for GCCXML - # verbose - integer specifying the verbosity - # - # returns the filename of the generated XML file - - # write a temporary C file - handle, c_file = tempfile.mkstemp(suffix=".c", text=True) - if verbose: - print >> sys.stderr, "writing temporary C source file %s" % c_file - ## os.write(handle, 'extern "C" {\n'); - for fname in fnames: - os.write(handle, '#include <%s>\n' % fname) - ## os.write(handle, '}'); - os.close(handle) - - if xml_file is None: - handle, xml_file = tempfile.mkstemp(suffix=".xml", text=True) - os.close(handle) - - if options: - options = " ".join(options) - else: - options = "" - - try: - if verbose: - print >> sys.stderr, r"gccxml.exe %s %s -fxml=%s" % (options, c_file, xml_file) - i, o = os.popen4(r"gccxml.exe %s %s -fxml=%s" % (options, c_file, xml_file)) - i.close() - sys.stderr.write(o.read()) - retval = o.close() - if retval: - raise CompilerError, "gccxml returned error %s" % retval - return xml_file - finally: - if verbose: - print >> sys.stderr, "Deleting temporary file %s" % c_file - os.remove(c_file) - ################################################################ --- 1,8 ---- ! """xml2py - create ctypes module from XML file""" ! import sys import xml.sax from sets import Set import nodes ################################################################ *************** *** 315,383 **** ################################################################ ! def parse(files, options=None, verbose=0, xmlfile=None): ! # run C files through gccxml, parse the xml output, ! # and return a sequence of items found. ! xml_file = run_gccxml(files, options, verbose, xmlfile) handler = GCCXML_Handler() ! if verbose: ! print "Parsing...", ! xml.sax.parse(xml_file, handler) ! if verbose: ! print "done" return handler.get_result() - ################################################################ - - def main(args=None): - if args is None: - args = sys.argv[1:] - import getopt - - gccxml_options = [] - verbose = 0 - try: - opts, files = getopt.getopt(args, "hvc:D:U:I:", ["compiler="]) - except (getopt.GetoptError, ValueError): - print >> sys.stderr, __doc__ - return 1 - for o, a in opts: - if o in ("-c", "--compiler"): - gccxml_options.append("--gccxml-compiler %s" % a) - elif o in ("-D", "-U", "-I"): - gccxml_options.append("%s %s" % (o, a)) - elif o == "-v": - verbose += 1 - elif o == "-h": - print >> sys.stderr, __doc__ - return 0 - - if not files: - print "Error: no files to process" - print >> sys.stderr, __doc__ - return 1 - - items = parse(files, options=gccxml_options, verbose=verbose) - - interesting = (nodes.FunctionType, nodes.Function, - nodes.Method, nodes.ArrayType) - - interesting = (nodes.Structure, nodes.ArrayType) - - done = 0 - for i in range(len(items)): - - if not isinstance(items[i], interesting): - continue - ## if isinstance(items[i], (nodes.Field, nodes.Constructor, type(None))): - ## continue - if done > 60: - return 1 - print items[i] - done += 1 - return 0 - - if __name__ == "__main__": - if len(sys.argv) == 1: - ## sys.argv.extend("-v -I. test.h".split()) - sys.argv.extend("-v windows.h".split()) - sys.exit(main()) --- 265,271 ---- ################################################################ ! def parse(xmlfile, options=None, verbose=0): handler = GCCXML_Handler() ! xml.sax.parse(xmlfile, handler) return handler.get_result() |
From: Thomas H. <th...@us...> - 2004-11-19 12:59:36
|
Update of /cvsroot/ctypes/ctypes/source In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv17608 Modified Files: cfield.c Log Message: The setter methods return an object which must be kept alive, to keep the data valid which has been stored in the memory block. The ctypes object instance inserts this object into its 'b_objects' list. For simple Python types like integers or characters, there is nothing that has to been kept alive, so Py_None is returned in these cases. But this makes inspecting the 'b_objects' list, which is accessible from Python for debugging, less useful. So, defining the _CTYPES_DEBUG_KEEP symbol returns the original value instead of Py_None. Index: cfield.c =================================================================== RCS file: /cvsroot/ctypes/ctypes/source/cfield.c,v retrieving revision 1.67 retrieving revision 1.68 diff -C2 -d -r1.67 -r1.68 *** cfield.c 19 Nov 2004 11:07:23 -0000 1.67 --- cfield.c 19 Nov 2004 12:59:27 -0000 1.68 *************** *** 420,423 **** --- 420,443 ---- /***************************************************************** + * The setter methods return an object which must be kept alive, to keep the + * data valid which has been stored in the memory block. The ctypes object + * instance inserts this object into its 'b_objects' list. + * + * For simple Python types like integers or characters, there is nothing that + * has to been kept alive, so Py_None is returned in these cases. But this + * makes inspecting the 'b_objects' list, which is accessible from Python for + * debugging, less useful. + * + * So, defining the _CTYPES_DEBUG_KEEP symbol returns the original value + * instead of Py_None. + */ + + #ifdef _CTYPES_DEBUG_KEEP + #define _RET(x) Py_INCREF(x); return x + #else + #define _RET(X) Py_INCREF(Py_None); return Py_None + #endif + + /***************************************************************** * integer accessor methods, supporting bit fields */ *************** *** 430,435 **** return NULL; *(char *)ptr = (char)SET(*(char *)ptr, (char)val, size); ! Py_INCREF(Py_None); ! return Py_None; } --- 450,454 ---- return NULL; *(char *)ptr = (char)SET(*(char *)ptr, (char)val, size); ! _RET(value); } *************** *** 451,456 **** *(unsigned char *)ptr = (unsigned char)SET(*(unsigned char*)ptr, (unsigned short)val, size); ! Py_INCREF(Py_None); ! return Py_None; } --- 470,474 ---- *(unsigned char *)ptr = (unsigned char)SET(*(unsigned char*)ptr, (unsigned short)val, size); ! _RET(value); } *************** *** 471,476 **** return NULL; *(short *)ptr = (short)SET(*(short *)ptr, (short)val, size); ! Py_INCREF(Py_None); ! return Py_None; } --- 489,493 ---- return NULL; *(short *)ptr = (short)SET(*(short *)ptr, (short)val, size); ! _RET(value); } *************** *** 492,497 **** *(unsigned short *)ptr = (unsigned short)SET(*(unsigned short *)ptr, (unsigned short)val, size); ! Py_INCREF(Py_None); ! return Py_None; } --- 509,513 ---- *(unsigned short *)ptr = (unsigned short)SET(*(unsigned short *)ptr, (unsigned short)val, size); ! _RET(value); } *************** *** 512,517 **** return NULL; *(int *)ptr = (int)SET(*(int *)ptr, (int)val, size); ! Py_INCREF(Py_None); ! return Py_None; } --- 528,532 ---- return NULL; *(int *)ptr = (int)SET(*(int *)ptr, (int)val, size); ! _RET(value); } *************** *** 532,537 **** return NULL; *(unsigned int *)ptr = (unsigned int)SET(*(unsigned int *)ptr, (unsigned int)val, size); ! Py_INCREF(Py_None); ! return Py_None; } --- 547,551 ---- return NULL; *(unsigned int *)ptr = (unsigned int)SET(*(unsigned int *)ptr, (unsigned int)val, size); ! _RET(value); } *************** *** 552,557 **** return NULL; *(long *)ptr = (long)SET(*(long *)ptr, val, size); ! Py_INCREF(Py_None); ! return Py_None; } --- 566,570 ---- return NULL; *(long *)ptr = (long)SET(*(long *)ptr, val, size); ! _RET(value); } *************** *** 572,577 **** return NULL; *(unsigned long *)ptr = (unsigned long)SET(*(unsigned long *)ptr, val, size); ! Py_INCREF(Py_None); ! return Py_None; } --- 585,589 ---- return NULL; *(unsigned long *)ptr = (unsigned long)SET(*(unsigned long *)ptr, val, size); ! _RET(value); } *************** *** 593,598 **** return NULL; *(PY_LONG_LONG *)ptr = (PY_LONG_LONG)SET(*(PY_LONG_LONG *)ptr, val, size); ! Py_INCREF(Py_None); ! return Py_None; } --- 605,609 ---- return NULL; *(PY_LONG_LONG *)ptr = (PY_LONG_LONG)SET(*(PY_LONG_LONG *)ptr, val, size); ! _RET(value); } *************** *** 612,617 **** return NULL; *(unsigned PY_LONG_LONG *)ptr = (unsigned PY_LONG_LONG)SET(*(unsigned PY_LONG_LONG *)ptr, val, size); ! Py_INCREF(Py_None); ! return Py_None; } --- 623,627 ---- return NULL; *(unsigned PY_LONG_LONG *)ptr = (unsigned PY_LONG_LONG)SET(*(unsigned PY_LONG_LONG *)ptr, val, size); ! _RET(value); } *************** *** 644,649 **** } *(double *)ptr = x; ! Py_INCREF(Py_None); ! return Py_None; } --- 654,658 ---- } *(double *)ptr = x; ! _RET(value); } *************** *** 667,672 **** } *(float *)ptr = x; ! Py_INCREF(Py_None); ! return Py_None; } --- 676,680 ---- } *(float *)ptr = x; ! _RET(value); } *************** *** 709,714 **** } *(char *)ptr = PyString_AS_STRING(value)[0]; ! Py_INCREF(Py_None); ! return Py_None; } --- 717,721 ---- } *(char *)ptr = PyString_AS_STRING(value)[0]; ! _RET(value); } *************** *** 752,757 **** Py_DECREF(value); ! Py_INCREF(Py_None); ! return Py_None; } --- 759,763 ---- Py_DECREF(value); ! _RET(value); } *************** *** 876,881 **** /* Also copy the terminating NUL character */ memcpy((char *)ptr, data, size); ! Py_INCREF(Py_None); ! return Py_None; } --- 882,886 ---- /* Also copy the terminating NUL character */ memcpy((char *)ptr, data, size); ! _RET(value); } *************** *** 903,908 **** } else if (PyInt_Check(value) || PyLong_Check(value)) { *(char **)ptr = (char *)PyInt_AsUnsignedLongMask(value); ! Py_INCREF(Py_None); ! return Py_None; } PyErr_Format(PyExc_TypeError, --- 908,912 ---- } else if (PyInt_Check(value) || PyLong_Check(value)) { *(char **)ptr = (char *)PyInt_AsUnsignedLongMask(value); ! _RET(value); } PyErr_Format(PyExc_TypeError, *************** *** 1041,1046 **** /* We don't need to keep any other object */ ! Py_INCREF(Py_None); ! return Py_None; } --- 1045,1049 ---- /* We don't need to keep any other object */ ! _RET(value); } *************** *** 1069,1074 **** if (value == Py_None) { *(void **)ptr = NULL; ! Py_INCREF(Py_None); ! return Py_None; } --- 1072,1076 ---- if (value == Py_None) { *(void **)ptr = NULL; ! _RET(value); } *************** *** 1083,1088 **** } *(void **)ptr = v; ! Py_INCREF(Py_None); ! return Py_None; } --- 1085,1089 ---- } *(void **)ptr = v; ! _RET(value); } |
From: Thomas H. <th...@us...> - 2004-11-19 11:07:55
|
Update of /cvsroot/ctypes/ctypes/source In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv26414 Modified Files: stgdict.c ctypes.h cfield.c _ctypes.c Log Message: Merged in the changed from DELAYED_STRUCTS_BRANCH. Index: ctypes.h =================================================================== RCS file: /cvsroot/ctypes/ctypes/source/ctypes.h,v retrieving revision 1.60 retrieving revision 1.61 diff -C2 -d -r1.60 -r1.61 *** ctypes.h 5 Nov 2004 10:47:34 -0000 1.60 --- ctypes.h 19 Nov 2004 11:07:23 -0000 1.61 *************** *** 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.25 retrieving revision 1.26 diff -C2 -d -r1.25 -r1.26 *** stgdict.c 5 Nov 2004 11:19:07 -0000 1.25 --- stgdict.c 19 Nov 2004 11:07:22 -0000 1.26 *************** *** 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,72 ---- } + int + StgDict_clone(StgDictObject *dst, StgDictObject *src) + { + char *d, *s; + int size; + + StgDict_clear(dst); + PyMem_Free(dst->ffi_type.elements); + dst->ffi_type.elements = NULL; + + 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); + + if (src->ffi_type.elements == NULL) + return 0; + 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 = { *************** *** 128,137 **** #endif ! static int ! _get_packing(PyObject *type) { PyObject *isPacked; int pack = 0; isPacked = PyObject_GetAttrString(type, "_pack_"); if (isPacked) { --- 161,182 ---- #endif ! /* ! Retrive the (optional) _pack_ attribute from a type, the _fields_ attribute, ! and create an StgDictObject. Used for Structure and Union subclasses. ! */ ! int ! StructUnionType_update_stgdict(PyObject *type, PyObject *fields, int isStruct) { + StgDictObject *stgdict; + int len, offset, size, align, i; + int union_size, total_align; + int field_size = 0; + int bitofs; PyObject *isPacked; int pack = 0; + if (fields == NULL) + return 0; + isPacked = PyObject_GetAttrString(type, "_pack_"); if (isPacked) { *************** *** 146,203 **** } else PyErr_Clear(); - return pack; - } - - static PyObject * - _get_fields(PyObject *type, int *plen) - { - PyObject *fields; - fields = PyObject_GetAttrString(type, "_fields_"); - if (!fields) { - PyErr_SetString(PyExc_AttributeError, - "class must define a '_fields_' attribute"); - return NULL; - } ! *plen = PySequence_Length(fields); ! if (*plen == -1) { PyErr_SetString(PyExc_AttributeError, "'_fields_' must be a sequence of pairs"); ! Py_DECREF(fields); ! return NULL; } - return fields; - } - - /* - Retrieve the (optional) _pack_ attribute from a type, the _fields_ attribute, - and create an StgDictObject. Used for Structure and Union subclasses. - */ - PyObject * - StgDict_ForType(PyObject *type, int isStruct) - { - StgDictObject *stgdict; - int len, offset, size, align, i; - int union_size, total_align; - int field_size = 0; - int bitofs; - PyObject *fields; - int pack; - - pack = _get_packing(type); - if (pack == -1) - return NULL; - - fields = _get_fields(type, &len); - if (fields == NULL) - return NULL; ! stgdict = (StgDictObject *)PyObject_CallObject( ! (PyObject *)&StgDict_Type, NULL); ! if (!stgdict) { ! Py_DECREF(fields); ! return NULL; ! } offset = 0; size = 0; --- 191,209 ---- } else 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; *************** *** 218,227 **** 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); --- 224,232 ---- 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); *************** *** 251,264 **** "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 --- 256,267 ---- "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 *************** *** 280,294 **** 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); --- 283,295 ---- 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); *************** *** 296,301 **** } #undef realdict - Py_DECREF(fields); - if (!isStruct) size = union_size; --- 297,300 ---- *************** *** 310,313 **** stgdict->align = total_align; stgdict->length = len; ! return (PyObject *)stgdict; } --- 309,312 ---- stgdict->align = total_align; stgdict->length = len; ! return 0; } Index: cfield.c =================================================================== RCS file: /cvsroot/ctypes/ctypes/source/cfield.c,v retrieving revision 1.66 retrieving revision 1.67 diff -C2 -d -r1.66 -r1.67 *** cfield.c 27 Oct 2004 17:27:30 -0000 1.66 --- cfield.c 19 Nov 2004 11:07:23 -0000 1.67 *************** *** 243,246 **** --- 243,265 ---- } + static PyObject * + CField_repr(CFieldObject *self) + { + PyObject *result; + int bits = self->size >> 16; + int size = self->size & 0xFFFF; + char *name; + + name = ((PyTypeObject *)self->proto)->tp_name; + + if (bits) + result = PyString_FromFormat("<Field type=%s, ofs=%d, bits=%d>", + name, self->offset, bits); + else + result = PyString_FromFormat("<Field type=%s, ofs=%d, size=%d>", + name, self->offset, size); + return result; + } + PyTypeObject CField_Type = { PyObject_HEAD_INIT(NULL) *************** *** 254,258 **** 0, /* tp_setattr */ 0, /* tp_compare */ ! 0, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ --- 273,277 ---- 0, /* tp_setattr */ 0, /* tp_compare */ ! CField_repr, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ *************** *** 265,269 **** 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */ ! NULL, /* tp_doc */ (traverseproc)CField_traverse, /* tp_traverse */ (inquiry)CField_clear, /* tp_clear */ --- 284,288 ---- 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */ ! "Structure/Union member", /* tp_doc */ (traverseproc)CField_traverse, /* tp_traverse */ (inquiry)CField_clear, /* tp_clear */ Index: _ctypes.c =================================================================== RCS file: /cvsroot/ctypes/ctypes/source/_ctypes.c,v retrieving revision 1.182 retrieving revision 1.183 diff -C2 -d -r1.182 -r1.183 *** _ctypes.c 5 Nov 2004 10:36:36 -0000 1.182 --- _ctypes.c 19 Nov 2004 11:07:23 -0000 1.183 *************** *** 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 */ |
From: Thomas H. <th...@us...> - 2004-11-19 10:57:36
|
Update of /cvsroot/ctypes/ctypes/source In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv23950 Modified Files: Tag: DELAYED_STRUCTS_BRANCH cfield.c Log Message: Provide a useful repr for CField objects, for pydoc. Index: cfield.c =================================================================== RCS file: /cvsroot/ctypes/ctypes/source/cfield.c,v retrieving revision 1.66 retrieving revision 1.66.2.1 diff -C2 -d -r1.66 -r1.66.2.1 *** cfield.c 27 Oct 2004 17:27:30 -0000 1.66 --- cfield.c 19 Nov 2004 10:57:20 -0000 1.66.2.1 *************** *** 243,246 **** --- 243,265 ---- } + static PyObject * + CField_repr(CFieldObject *self) + { + PyObject *result; + int bits = self->size >> 16; + int size = self->size & 0xFFFF; + char *name; + + name = ((PyTypeObject *)self->proto)->tp_name; + + if (bits) + result = PyString_FromFormat("<Field type=%s, ofs=%d, bits=%d>", + name, self->offset, bits); + else + result = PyString_FromFormat("<Field type=%s, ofs=%d, size=%d>", + name, self->offset, size); + return result; + } + PyTypeObject CField_Type = { PyObject_HEAD_INIT(NULL) *************** *** 254,258 **** 0, /* tp_setattr */ 0, /* tp_compare */ ! 0, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ --- 273,277 ---- 0, /* tp_setattr */ 0, /* tp_compare */ ! CField_repr, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ *************** *** 265,269 **** 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */ ! NULL, /* tp_doc */ (traverseproc)CField_traverse, /* tp_traverse */ (inquiry)CField_clear, /* tp_clear */ --- 284,288 ---- 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */ ! "Structure/Union member", /* tp_doc */ (traverseproc)CField_traverse, /* tp_traverse */ (inquiry)CField_clear, /* tp_clear */ |
From: Thomas H. <th...@us...> - 2004-11-12 10:56:52
|
Update of /cvsroot/ctypes/ctypes/sandbox/tools/codegen In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv24952 Modified Files: generate.py Log Message: Packing unions does now also work. Added summary to the output. Index: generate.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/sandbox/tools/codegen/generate.py,v retrieving revision 1.13 retrieving revision 1.14 diff -C2 -d -r1.13 -r1.14 *** generate.py 12 Nov 2004 09:36:11 -0000 1.13 --- generate.py 12 Nov 2004 10:56:42 -0000 1.14 *************** *** 1,5 **** # bugs: ! # packing of unions (assertion errors at import time of generated module) ! # bitfields? import nodes --- 1,4 ---- # bugs: ! # packing of structures/unions with bitfields? See '##XXX FIXME' import nodes *************** *** 52,56 **** pass ! def _calc_packing(struct, fields, pack): # Try a certain packing, raise PackingError if field offsets, # total size ot total alignment is wrong. --- 51,55 ---- pass ! def _calc_packing(struct, fields, pack, isStruct): # Try a certain packing, raise PackingError if field offsets, # total size ot total alignment is wrong. *************** *** 67,70 **** --- 66,70 ---- for i, f in enumerate(fields): if f.bits: + print "##XXX FIXME" return -2 # XXX FIXME s, a = storage(f.typ) *************** *** 73,79 **** if size % a: size += a - size % a ! if size != f.offset: ! raise PackingError, "field offset (%s/%s)" % (size, f.offset) ! size += s total_align = max(total_align, a) if total_align != struct.align: --- 73,82 ---- if size % a: size += a - size % a ! if isStruct: ! if size != f.offset: ! raise PackingError, "field offset (%s/%s)" % (size, f.offset) ! size += s ! else: ! size = max(size, s) total_align = max(total_align, a) if total_align != struct.align: *************** *** 89,95 **** def calc_packing(struct, fields): # try several packings, starting with unspecified packing for pack in [None, 16*8, 8*8, 4*8, 2*8, 1*8]: try: ! _calc_packing(struct, fields, pack) except PackingError, details: continue --- 92,99 ---- def calc_packing(struct, fields): # try several packings, starting with unspecified packing + isStruct = isinstance(struct, nodes.Structure) for pack in [None, 16*8, 8*8, 4*8, 2*8, 1*8]: try: ! _calc_packing(struct, fields, pack, isStruct) except PackingError, details: continue *************** *** 147,176 **** return tp ! struct_packing = { ! "_IMAGE_SYMBOL": 2, ! "tagPDA": 2, ! "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, ! ! "_SENDCMDOUTPARAMS": 1, ! "_SENDCMDINPARAMS": 1, ! } ! dont_assert_size = set( [ --- 151,155 ---- return tp ! # XXX These should be filtered out in gccxmlparser. dont_assert_size = set( [ *************** *** 236,242 **** --- 215,223 ---- self.done.add(head) + _structures = 0 def Structure(self, struct): if struct in self.done: return + self._structures += 1 head = struct.get_head() self.StructureHead(head) *************** *** 245,251 **** --- 226,234 ---- self.done.add(struct) + _typedefs = 0 def Typedef(self, tp): if tp in self.done: return + self._typedefs += 1 if type(tp.typ) in (nodes.Structure, nodes.Union): self.StructureHead(tp.typ.get_head()) *************** *** 257,277 **** --- 240,266 ---- self.done.add(tp) + _arraytypes = 0 def ArrayType(self, tp): if tp in self.done: return + self._arraytypes += 1 self.generate(get_real_type(tp.typ)) self.generate(tp.typ) self.done.add(tp) + _functiontypes = 0 def FunctionType(self, tp): if tp in self.done: return + self._functiontypes += 1 self.generate(tp.returns) self.generate_all(tp.arguments) self.done.add(tp) + _pointertypes = 0 def PointerType(self, tp): if tp in self.done: return + self._pointertypes += 1 if type(tp.typ) is nodes.PointerType: self.PointerType(tp.typ) *************** *** 291,297 **** --- 280,288 ---- self.done.add(tp) + _enumtypes = 0 def Enumeration(self, tp): if tp in self.done: return + self._enumtypes += 1 if tp.name: print *************** *** 326,331 **** # # Hm, how to detect a COM interface with no methods? IXMLDOMCDATASection is such a beast... ! if not isinstance(body.struct, nodes.Union) and not methods: ! ## if not methods: pack = calc_packing(body.struct, fields) if pack is not None: --- 317,322 ---- # # Hm, how to detect a COM interface with no methods? IXMLDOMCDATASection is such a beast... ! ## if not isinstance(body.struct, nodes.Union) and not methods: ! if not methods: pack = calc_packing(body.struct, fields) if pack is not None: *************** *** 376,382 **** --- 367,375 ---- return "?" + _functiontypes = 0 def Function(self, func): if func in self.done: return + self._functiontypes += 1 dllname = self.find_dllname(func.name) if dllname and func.extern: *************** *** 407,410 **** --- 400,419 ---- self.generate(item) + def print_stats(self): + print "################################################################" + print "# Statistics:" + print "#" + print "# Struct/Unions: %5d" % self._structures + print "# Functions: %5d" % self._functiontypes + print "# Enums: %5d" % self._enumtypes + print "# Typedefs: %5d" % self._typedefs + print "# Pointertypes: %5d" % self._pointertypes + print "# Arraytypes: %5d" % self._arraytypes + print "#" + total = self._structures + self._functiontypes + self._enumtypes + self._typedefs +\ + self._pointertypes + self._arraytypes + print "# Total symbols: %5d" % total + print "################################################################" + ################################################################ *************** *** 451,454 **** --- 460,465 ---- pdb.set_trace() + gen.print_stats() + if __name__ == "__main__": import sys |
From: Thomas H. <th...@us...> - 2004-11-12 09:36:23
|
Update of /cvsroot/ctypes/ctypes/sandbox/tools/codegen In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv7579 Modified Files: generate.py Log Message: Field offset is an integer. Index: generate.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/sandbox/tools/codegen/generate.py,v retrieving revision 1.12 retrieving revision 1.13 diff -C2 -d -r1.12 -r1.13 *** generate.py 12 Nov 2004 09:00:36 -0000 1.12 --- generate.py 12 Nov 2004 09:36:11 -0000 1.13 *************** *** 52,61 **** pass ! def _calc_packing(struct, fields, pack, verbose): if struct.size is None: # incomplete struct return -1 if struct.name in dont_assert_size: return None - assert not isinstance(struct, nodes.Union) if struct.bases: size = struct.bases[0].size --- 52,62 ---- pass ! def _calc_packing(struct, fields, pack): ! # Try a certain packing, raise PackingError if field offsets, ! # total size ot total alignment is wrong. if struct.size is None: # incomplete struct return -1 if struct.name in dont_assert_size: return None if struct.bases: size = struct.bases[0].size *************** *** 66,70 **** for i, f in enumerate(fields): if f.bits: ! return -2 s, a = storage(f.typ) if pack is not None: --- 67,71 ---- for i, f in enumerate(fields): if f.bits: ! return -2 # XXX FIXME s, a = storage(f.typ) if pack is not None: *************** *** 72,77 **** if size % a: size += a - size % a ! if size != int(f.offset): ! raise PackingError, "field offset" size += s total_align = max(total_align, a) --- 73,78 ---- if size % a: size += a - size % a ! if size != f.offset: ! raise PackingError, "field offset (%s/%s)" % (size, f.offset) size += s total_align = max(total_align, a) *************** *** 84,94 **** size += a - size % a if size != struct.size: ! raise PackingError, "total size" ! def calc_packing(struct, fields, verbose=False): # try several packings, starting with unspecified packing for pack in [None, 16*8, 8*8, 4*8, 2*8, 1*8]: try: ! _calc_packing(struct, fields, pack, verbose) except PackingError, details: continue --- 85,95 ---- size += a - size % a if size != struct.size: ! raise PackingError, "total size (%s/%s)" % (size, struct.size) ! def calc_packing(struct, fields): # try several packings, starting with unspecified packing for pack in [None, 16*8, 8*8, 4*8, 2*8, 1*8]: try: ! _calc_packing(struct, fields, pack) except PackingError, details: continue *************** *** 326,329 **** --- 327,331 ---- # Hm, how to detect a COM interface with no methods? IXMLDOMCDATASection is such a beast... if not isinstance(body.struct, nodes.Union) and not methods: + ## if not methods: pack = calc_packing(body.struct, fields) if pack is not None: |
From: Thomas H. <th...@us...> - 2004-11-12 09:31:29
|
Update of /cvsroot/ctypes/ctypes/sandbox/tools/codegen In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv6580 Modified Files: nodes.py Log Message: Field offset is an integer. Index: nodes.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/sandbox/tools/codegen/nodes.py,v retrieving revision 1.10 retrieving revision 1.11 diff -C2 -d -r1.10 -r1.11 *** nodes.py 11 Nov 2004 12:01:45 -0000 1.10 --- nodes.py 12 Nov 2004 09:31:18 -0000 1.11 *************** *** 133,137 **** self.typ = typ self.bits = bits ! self.offset = offset class CvQualifiedType(object): --- 133,137 ---- self.typ = typ self.bits = bits ! self.offset = int(offset) class CvQualifiedType(object): |
From: Thomas H. <th...@us...> - 2004-11-12 09:00:45
|
Update of /cvsroot/ctypes/ctypes/sandbox/tools/codegen In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv427 Modified Files: generate.py Log Message: Packing of derived structures fixed (only slightly tested). Index: generate.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/sandbox/tools/codegen/generate.py,v retrieving revision 1.11 retrieving revision 1.12 diff -C2 -d -r1.11 -r1.12 *** generate.py 11 Nov 2004 21:04:47 -0000 1.11 --- generate.py 12 Nov 2004 09:00:36 -0000 1.12 *************** *** 1,4 **** # bugs: - # packing of derived structures (assertion error at build time) # packing of unions (assertion errors at import time of generated module) # bitfields? --- 1,3 ---- *************** *** 61,67 **** if struct.bases: size = struct.bases[0].size else: size = 0 ! total_align = 8 # in bits for i, f in enumerate(fields): if f.bits: --- 60,67 ---- if struct.bases: size = struct.bases[0].size + total_align = struct.bases[0].align else: size = 0 ! total_align = 8 # in bits for i, f in enumerate(fields): if f.bits: *************** *** 77,81 **** total_align = max(total_align, a) if total_align != struct.align: ! raise PackingError, "total alignment (%s/%s)" % (total_align / 8, struct.align) a = total_align if pack is not None: --- 77,81 ---- total_align = max(total_align, a) if total_align != struct.align: ! raise PackingError, "total alignment (%s/%s)" % (total_align, struct.align) a = total_align if pack is not None: *************** *** 91,95 **** try: _calc_packing(struct, fields, pack, verbose) ! except PackingError: continue else: --- 91,95 ---- try: _calc_packing(struct, fields, pack, verbose) ! except PackingError, details: continue else: *************** *** 97,102 **** return None return pack/8 ! ## assert 0, "PACKING FAILED" ! print "##WARNING: Packing failed", struct.size def _type_name(t): --- 97,101 ---- return None return pack/8 ! assert 0, "PACKING FAILED: %s" % details def _type_name(t): |
From: Thomas H. <th...@us...> - 2004-11-12 07:57:26
|
Update of /cvsroot/ctypes/ctypes/sandbox/tools/codegen In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv20201 Modified Files: _support.py Log Message: How could I miss that the inspect module already has all I need? Index: _support.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/sandbox/tools/codegen/_support.py,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** _support.py 11 Nov 2004 21:02:08 -0000 1.2 --- _support.py 12 Nov 2004 07:57:15 -0000 1.3 *************** *** 1,2 **** --- 1,5 ---- + # For using decorators with Python 2.3, see this post by Philip Eby: + # http://dirtsimple.org/2004/11/using-24-decorators-with-22-and-23.html + import new *************** *** 19,43 **** # return _api_(first, second, third) import inspect ! # inspect.getargspec() returns: (args, varargs, varkw, defaults) ! args = inspect.getargspec(func) ! if args[2]: raise TypeError, "function argument list cannot contain ** argument" ! ! argnames = args[0] ! defaults = args[-1] ! ! if not defaults: ! if args[1]: ! argnames.append("*%s" % args[1]) ! argnames = ", ".join(argnames) ! return "def %s(%s): return _api_(%s)" % (name, argnames, argnames) ! ! first_list = ", ".join(argnames) ! ! args = argnames[:-len(defaults)] ! args.extend( ["%s=%r" % t for t in zip(argnames[-len(defaults):], defaults)] ) ! args = ", ".join(args) ! ! return """def %s(%s): return _api_(%s)""" % (name, args, first_list) def _decorate_with_api_global(func, call_api): --- 22,32 ---- # return _api_(first, second, third) import inspect ! args, varargs, varkw, defaults = inspect.getargspec(func) ! if varkw: raise TypeError, "function argument list cannot contain ** argument" ! return """def %s%s: return _api_%s""" % \ ! (name, ! inspect.formatargspec(args, varargs, varkw, defaults), ! inspect.formatargspec(args, varargs, varkw)) def _decorate_with_api_global(func, call_api): |
From: Thomas H. <th...@us...> - 2004-11-11 21:06:57
|
Update of /cvsroot/ctypes/ctypes/sandbox/tools/codegen In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv14432 Removed Files: ctypes_names.py Log Message: ctypes_names isn't worth to be a complete module. --- ctypes_names.py DELETED --- |
From: Thomas H. <th...@us...> - 2004-11-11 21:04:56
|
Update of /cvsroot/ctypes/ctypes/sandbox/tools/codegen In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv14030 Modified Files: generate.py Log Message: ctypes_names isn't worth to be a complete module. Lots of other changes as well. Index: generate.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/sandbox/tools/codegen/generate.py,v retrieving revision 1.10 retrieving revision 1.11 diff -C2 -d -r1.10 -r1.11 *** generate.py 6 Oct 2004 09:17:54 -0000 1.10 --- generate.py 11 Nov 2004 21:04:47 -0000 1.11 *************** *** 1,4 **** import nodes - from ctypes_names import ctypes_names try: --- 1,8 ---- + # bugs: + # packing of derived structures (assertion error at build time) + # packing of unions (assertion errors at import time of generated module) + # bitfields? + import nodes try: *************** *** 7,13 **** from sets import Set as set ################ ! 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. --- 11,104 ---- from sets import Set as set + # XXX Should this be in ctypes itself? + ctypes_names = { + "unsigned char": "c_ubyte", + "signed char": "c_byte", + "char": "c_char", + + "wchar_t": "c_wchar", + + "short unsigned int": "c_ushort", + "short int": "c_short", + + "long unsigned int": "c_ulong", + "long int": "c_long", + "long signed int": "c_long", + + "unsigned int": "c_uint", + "int": "c_int", + + "long long unsigned int": "c_ulonglong", + "long long int": "c_longlong", + + "double": "c_double", + "float": "c_float", + + # Hm... + "void": "None", + } + ################ ! def storage(t): ! # return the size and alignment of a type ! if isinstance(t, nodes.Typedef): ! return storage(t.typ) ! elif isinstance(t, nodes.ArrayType): ! s, a = storage(t.typ) ! return s * (int(t.max) - int(t.min) + 1), a ! return int(t.size), int(t.align) ! ! class PackingError(Exception): ! pass ! ! def _calc_packing(struct, fields, pack, verbose): ! if struct.size is None: # incomplete struct ! return -1 ! if struct.name in dont_assert_size: ! return None ! assert not isinstance(struct, nodes.Union) ! if struct.bases: ! size = struct.bases[0].size ! else: ! size = 0 ! total_align = 8 # in bits ! for i, f in enumerate(fields): ! if f.bits: ! return -2 ! s, a = storage(f.typ) ! if pack is not None: ! a = min(pack, a) ! if size % a: ! size += a - size % a ! if size != int(f.offset): ! raise PackingError, "field offset" ! size += s ! total_align = max(total_align, a) ! if total_align != struct.align: ! raise PackingError, "total alignment (%s/%s)" % (total_align / 8, struct.align) ! a = total_align ! if pack is not None: ! a = min(pack, a) ! if size % a: ! size += a - size % a ! if size != struct.size: ! raise PackingError, "total size" ! ! def calc_packing(struct, fields, verbose=False): ! # try several packings, starting with unspecified packing ! for pack in [None, 16*8, 8*8, 4*8, 2*8, 1*8]: ! try: ! _calc_packing(struct, fields, pack, verbose) ! except PackingError: ! continue ! else: ! if pack is None: ! return None ! return pack/8 ! ## assert 0, "PACKING FAILED" ! print "##WARNING: Packing failed", struct.size ! ! 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. *************** *** 17,20 **** --- 108,113 ---- if result.startswith("POINTER(WINFUNCTYPE"): return result[8:-1] + if result.startswith("POINTER(CFUNCTYPE"): + return result[8:-1] # XXX See comment above... elif result == "POINTER(None)": *************** *** 25,30 **** 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 "const(%s)" % type_name(t.typ) --- 118,123 ---- elif isinstance(t, nodes.FunctionType): args = map(type_name, [t.returns] + t.arguments) ! # WINFUNCTYPE already *is* a pointer to a function! ! return "CFUNCTYPE(%s)" % ", ".join(args) elif isinstance(t, nodes.CvQualifiedType): return "const(%s)" % type_name(t.typ) *************** *** 38,44 **** 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: --- 131,145 ---- return "c_int" # enums are integers elif isinstance(t, nodes.Typedef): ! return t.name return t.name + renames = { + ## "POINTER(const(WCHAR))": "c_wchar_p", + } + + def type_name(t): + result = _type_name(t) + return renames.get(result, result) + def get_real_type(tp): if type(tp) is nodes.Typedef: *************** *** 105,109 **** ##rpcndr ##ntdll ! from ctypes import CDLL --- 206,210 ---- ##rpcndr ##ntdll ! ##dll_names = "libxml2".split() from ctypes import CDLL *************** *** 159,165 **** 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) --- 260,265 ---- if tp in self.done: return self.generate(get_real_type(tp.typ)) + self.generate(tp.typ) 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) --- 295,305 ---- return if tp.name: + print print "%s = c_int # enum" % tp.name ! for n, v in tp.values: ! print "%s = %s # enum %s" % (n, v, tp.name) ! else: ! for n, v in tp.values: ! print "%s = %s # enum" % (n, v) self.done.add(tp) *************** *** 209,214 **** fields.append(m) if type(m.typ) is nodes.Typedef: ! self.more.add(m.typ) ! self.generate(get_real_type(m.typ)) elif type(m) is nodes.Method: methods.append(m) --- 313,318 ---- fields.append(m) if type(m.typ) is nodes.Typedef: ! self.generate(get_real_type(m.typ)) ! self.generate(m.typ) elif type(m) is nodes.Method: methods.append(m) *************** *** 217,226 **** 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: if body.struct.bases: --- 321,335 ---- elif type(m) is nodes.Constructor: pass ! ! # we don't need _pack_ on Unions (I hope, at least), and ! # not on COM interfaces: ! # ! # Hm, how to detect a COM interface with no methods? IXMLDOMCDATASection is such a beast... ! if not isinstance(body.struct, nodes.Union) and not methods: ! pack = calc_packing(body.struct, fields) ! if pack is not None: ! print "%s._pack_ = %s" % (body.struct.name, pack) ! else: ! print "# %s" % body.struct.name if fields: if body.struct.bases: *************** *** 250,253 **** --- 359,365 ---- print "assert sizeof(%s) == %s, sizeof(%s)" % \ (body.struct.name, size, body.struct.name) + align = body.struct.align // 8 + print "assert alignment(%s) == %s, alignment(%s)" % \ + (body.struct.name, align, body.struct.name) self.done.add(body) *************** *** 260,264 **** else: return dll._name ! return None def Function(self, func): --- 372,377 ---- else: return dll._name ! ## return None ! return "?" def Function(self, func): *************** *** 271,278 **** 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) --- 384,391 ---- 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) *************** *** 297,301 **** def find_names(names): from gccxmlparser import parse ! items = parse(files=["windows.h"], xmlfile="windows.xml", options=["-D _WIN32_WINNT=0x500"]) if "*" in names: --- 410,417 ---- def find_names(names): from gccxmlparser import parse ! items = parse(files=["windows.h"], ! options=["-D WIN32_LEAN_AND_MEAN"], ! ## options=["-dM"], ! xmlfile="windows.xml") if "*" in names: *************** *** 309,316 **** 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" --- 425,433 ---- def main(): ## items = parse(files=["windows.h"], xmlfile="windows.xml") items = find_names(sys.argv[1:]) gen = Generator() + print "# files='windows.h'" + print "# options='-D WIN32_LEAN_AND_MEAN'" print "from ctypes import *" print "from _support import STDMETHOD, const, STDCALL, CDECL, _com_interface" *************** *** 336,340 **** import sys if len(sys.argv) == 1: ! sys.argv.extend("WNDCLASS".split()) ## sys.argv.extend("ITypeComp".split()) main() --- 453,458 ---- import sys if len(sys.argv) == 1: ! sys.argv.extend("*") ! # sys.argv.extend("WNDCLASS".split()) ## sys.argv.extend("ITypeComp".split()) main() |
From: Thomas H. <th...@us...> - 2004-11-11 21:02:22
|
Update of /cvsroot/ctypes/ctypes/sandbox/tools/codegen In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv13492 Modified Files: _support.py Log Message: Check in a version I have for quite some time here. Index: _support.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/sandbox/tools/codegen/_support.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** _support.py 5 Oct 2004 16:51:37 -0000 1.1 --- _support.py 11 Nov 2004 21:02:08 -0000 1.2 *************** *** 1,2 **** --- 1,4 ---- + import new + def STDMETHOD(*args): pass # fake def const(x): return x # fake *************** *** 6,26 **** _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 --- 8,73 ---- _fields_ = [('lpVtbl', c_void_p)] + def _create_func_codestring(func, name): + # given a function <func>, build the source code for another + # function, having the same argument list, and a function body + # which contains a call to an _api_ function. + # Assuming the <func> has this definition: + # def func(first, second="spam", third=42): + # .... + # a string containing the following code is returned: + # def <name>(first, second="spam", third=42): + # return _api_(first, second, third) + import inspect + # inspect.getargspec() returns: (args, varargs, varkw, defaults) + args = inspect.getargspec(func) + if args[2]: + raise TypeError, "function argument list cannot contain ** argument" + + argnames = args[0] + defaults = args[-1] + + if not defaults: + if args[1]: + argnames.append("*%s" % args[1]) + argnames = ", ".join(argnames) + return "def %s(%s): return _api_(%s)" % (name, argnames, argnames) + + first_list = ", ".join(argnames) + + args = argnames[:-len(defaults)] + args.extend( ["%s=%r" % t for t in zip(argnames[-len(defaults):], defaults)] ) + args = ", ".join(args) + + return """def %s(%s): return _api_(%s)""" % (name, args, first_list) + + def _decorate_with_api_global(func, call_api): + # return a new function derived from <func>, inserting an '_api_' + # symbol into the function globals, which is bound to the + # <call_api> object. + # + # If the body of <func> is empty, a new function body is created, + # which simply calls the _api_ object with all parameters passed to <func>. + if len(func.func_code.co_code) == 4: + code_string = _create_func_codestring(func, func.func_name) + d = {} + exec code_string in d + func = d[func.func_name] + func_globals = {"_api_": call_api} + func_globals.update(func.func_globals) + return new.function(func.func_code, + func_globals, + func.func_name, + func.func_defaults) + 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 '_api_' global in the namespace of the # decorated function. def decorate(func): api = getattr(WinDLL(dllname), funcname) api.restype = restype api.argtypes = argtypes ! return _decorate_with_api_global(func, api) return decorate *************** *** 28,45 **** # 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 --- 75,104 ---- # a decorator which loads the specified dll, retrieves the # function with the specified name, set its restype and argtypes, ! # and exposes it as an '_api_' global in the namespace of the # decorated function. def decorate(func): api = getattr(CDLL(dllname), funcname) api.restype = restype api.argtypes = argtypes ! return _decorate_with_api_global(func, api) return decorate + ################################################################ + + if __name__ == "__main__": + decorator = STDCALL("kernel32", c_int, "GetModuleHandleA", (c_char_p,)) + + def GetModuleHandle(name=None): + result = _api_(name) + print "GetModuleHandle(%s) -> %x" % (name, result) + return result + + print _create_func_codestring(GetModuleHandle, "GetModuleHandle") + + GetModuleHandle = decorator(GetModuleHandle) + + GetModuleHandle() + GetModuleHandle("python.exe") + GetModuleHandle("python23.dll") + import zlib + GetModuleHandle(zlib.__file__) |
From: Thomas H. <th...@us...> - 2004-11-11 12:01:54
|
Update of /cvsroot/ctypes/ctypes/sandbox/tools/codegen In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv18119 Modified Files: nodes.py Log Message: size and align attributes are integers. Index: nodes.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/sandbox/tools/codegen/nodes.py,v retrieving revision 1.9 retrieving revision 1.10 diff -C2 -d -r1.9 -r1.10 *** nodes.py 2 Nov 2004 16:33:56 -0000 1.9 --- nodes.py 11 Nov 2004 12:01:45 -0000 1.10 *************** *** 43,48 **** def __init__(self, name, size, align): self.name = name ! self.size = size ! self.align = align def __repr__(self): --- 43,49 ---- def __init__(self, name, size, align): self.name = name ! if name != "void": ! self.size = int(size) ! self.align = int(align) def __repr__(self): *************** *** 52,57 **** def __init__(self, typ, size, align): self.typ = typ ! self.size = size ! self.align = align def __repr__(self): --- 53,58 ---- def __init__(self, typ, size, align): self.typ = typ ! self.size = int(size) ! self.align = int(align) def __repr__(self): *************** *** 102,106 **** def __init__(self, name, align, members, bases, size, artificial=None): self.name = name ! self.align = align self.members = members self.bases = bases --- 103,107 ---- def __init__(self, name, align, members, bases, size, artificial=None): self.name = name ! self.align = int(align) self.members = members self.bases = bases *************** *** 116,120 **** def __init__(self, name, align, members, bases, size, artificial=None): self.name = name ! self.align = align self.members = members self.bases = bases --- 117,121 ---- def __init__(self, name, align, members, bases, size, artificial=None): self.name = name ! self.align = int(align) self.members = members self.bases = bases *************** *** 142,147 **** def __init__(self, name, size, align): self.name = name ! self.size = size ! self.align = align self.values = [] --- 143,148 ---- def __init__(self, name, size, align): self.name = name ! self.size = int(size) ! self.align = int(align) self.values = [] |
From: Thomas H. <th...@us...> - 2004-11-10 10:43:00
|
Update of /cvsroot/ctypes/ctypes/source In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv11187 Modified Files: Tag: DELAYED_STRUCTS_BRANCH stgdict.c Log Message: Small fix. Index: stgdict.c =================================================================== RCS file: /cvsroot/ctypes/ctypes/source/stgdict.c,v retrieving revision 1.23.2.1 retrieving revision 1.23.2.2 diff -C2 -d -r1.23.2.1 -r1.23.2.2 *** stgdict.c 10 Nov 2004 10:32:53 -0000 1.23.2.1 --- stgdict.c 10 Nov 2004 10:42:50 -0000 1.23.2.2 *************** *** 46,49 **** --- 46,51 ---- StgDict_clear(dst); + PyMem_Free(dst->ffi_type.elements); + dst->ffi_type.elements = NULL; d = (char *)dst; *************** *** 58,61 **** --- 60,65 ---- Py_XINCREF(dst->restype); + if (src->ffi_type.elements == NULL) + return 0; size = sizeof(ffi_type *) * (src->length + 1); dst->ffi_type.elements = PyMem_Malloc(size); |
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 */ |
From: Thomas H. <th...@us...> - 2004-11-10 08:14:37
|
Update of /cvsroot/ctypes/ctypes/unittests In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv12710 Modified Files: Tag: DELAYED_STRUCTS_BRANCH test_leaks.py Log Message: It seems we need more loops. Index: test_leaks.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/unittests/test_leaks.py,v retrieving revision 1.7 retrieving revision 1.7.2.1 diff -C2 -d -r1.7 -r1.7.2.1 *** test_leaks.py 27 Oct 2004 17:32:16 -0000 1.7 --- test_leaks.py 10 Nov 2004 08:14:28 -0000 1.7.2.1 *************** *** 58,62 **** def test_cycles_refcount(self): last_refcount = 0 ! for x in xrange(5): self.make_cyclic_structures(1000) while gc.collect(): --- 58,62 ---- def test_cycles_refcount(self): last_refcount = 0 ! for x in xrange(10): self.make_cyclic_structures(1000) while gc.collect(): |