ctypes-commit Mailing List for ctypes (Page 91)
Brought to you by:
theller
You can subscribe to this list here.
2004 |
Jan
|
Feb
|
Mar
|
Apr
(8) |
May
(90) |
Jun
(143) |
Jul
(106) |
Aug
(94) |
Sep
(84) |
Oct
(163) |
Nov
(60) |
Dec
(58) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2005 |
Jan
(128) |
Feb
(79) |
Mar
(227) |
Apr
(192) |
May
(179) |
Jun
(41) |
Jul
(53) |
Aug
(103) |
Sep
(28) |
Oct
(38) |
Nov
(81) |
Dec
(17) |
2006 |
Jan
(184) |
Feb
(111) |
Mar
(188) |
Apr
(67) |
May
(58) |
Jun
(123) |
Jul
(73) |
Aug
|
Sep
|
Oct
(1) |
Nov
|
Dec
|
From: Thomas H. <th...@us...> - 2004-10-01 18:54:21
|
Update of /cvsroot/ctypes/ctypes/sandbox/tools/codegen In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv7590 Modified Files: pycodegen.py Log Message: This on is mangled - last checkin before cvs remove. Index: pycodegen.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/sandbox/tools/codegen/pycodegen.py,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** pycodegen.py 1 Oct 2004 06:28:34 -0000 1.3 --- pycodegen.py 1 Oct 2004 18:54:11 -0000 1.4 *************** *** 148,152 **** def gen_structs(done, items): ! bodies = [] structs = [] for i in items: --- 148,152 ---- def gen_structs(done, items): ! ## bodies = [] structs = [] for i in items: *************** *** 158,162 **** isStruct = isinstance(i.typ, nodes.Structure) make_struct_header(i.name, i.typ, isStruct) ! bodies.append((i.name, i.typ)) done.add(i) done.add(i.typ) --- 158,162 ---- isStruct = isinstance(i.typ, nodes.Structure) make_struct_header(i.name, i.typ, isStruct) ! ## bodies.append((i.name, i.typ)) done.add(i) done.add(i.typ) *************** *** 169,177 **** isStruct = isinstance(i, nodes.Structure) make_struct_header(i.name, i, isStruct) ! bodies.append((i.name, i)) done.add(i) ! for name, struct in bodies: ! make_struct_body(name, struct) return done, items - done --- 169,181 ---- isStruct = isinstance(i, nodes.Structure) make_struct_header(i.name, i, isStruct) ! ## bodies.append((i.name, i)) done.add(i) ! for i in items - done: ! if isinstance(i, nodes.StructureHead): ! print "#typedef struct %s;" % i.struct.name ! isStruct = isinstance(i, nodes.Structure) ! make_struct_header(i.struct.name, i.struct, True) ! done.add(i) return done, items - done *************** *** 284,287 **** --- 288,295 ---- done, items = gen_structs(done, items) done, items = gen_functions(done, items) + if type(item) is nodes.StructureBody: + make_struct_body(item.struct.name, item.struct) + done.add(item) + ## assert done, "no code generated for %s" % item return done *************** *** 294,307 **** else: from gccxmlparser import parse ! items = parse(files=["windows.h"], xmlfile="windows.xml") import cPickle data = cPickle.dumps(items) open("windows.pickle", "wb").write(data) result = [] for i in items: if getattr(i, "name", None) in names: result.append(i) return result --- 302,319 ---- else: from gccxmlparser import parse ! items = parse(files=["windows.h"], xmlfile="windows.xml", verbose=1) + print "# creating pickle..", import cPickle data = cPickle.dumps(items) open("windows.pickle", "wb").write(data) + print "done" + print "# searching...", result = [] for i in items: if getattr(i, "name", None) in names: result.append(i) + print "done" return result *************** *** 320,324 **** import sys ! todo.update(find(sys.argv[1:], "windows.pickle")) print "from ctypes import *" --- 332,337 ---- import sys ! ## todo.update(find(sys.argv[1:], "windows.pickle")) ! todo.update(find(sys.argv[1:])) print "from ctypes import *" *************** *** 331,335 **** print ! for howoften in range(50): for i in todo.copy(): needs = set(i.depends()) --- 344,348 ---- print ! for howoften in range(200): for i in todo.copy(): needs = set(i.depends()) *************** *** 338,341 **** --- 351,356 ---- ## print "# generate", i ## print "#depends", i.depends() + if type(i) in (nodes.Structure, nodes.Union): + todo.add(i.get_body()) a = generate(i) done.update(a) *************** *** 359,363 **** print "for type", t print "unresolved", unresolved ! if __name__ == "__main__": import sys --- 374,378 ---- print "for type", t print "unresolved", unresolved ! if __name__ == "__main__": import sys *************** *** 365,370 **** sys.argv.append("IDispatch") todo, done = main() ! if todo: ! print explain(todo[0], done) # TODO-List: --- 380,385 ---- sys.argv.append("IDispatch") todo, done = main() ! ## if todo: ! ## print explain(todo[0], done) # TODO-List: |
From: Thomas H. <th...@us...> - 2004-10-01 06:28:57
|
Update of /cvsroot/ctypes/ctypes/sandbox/tools/codegen In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv25092 Modified Files: pycodegen.py Log Message: No need to generate code for arrays. Don't generate code like 'x = x'. Index: pycodegen.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/sandbox/tools/codegen/pycodegen.py,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** pycodegen.py 30 Sep 2004 18:16:52 -0000 1.2 --- pycodegen.py 1 Oct 2004 06:28:34 -0000 1.3 *************** *** 104,108 **** text = " STDMETHOD(%s, '%s'" % (type_name(m.returns), m.name) if args: ! print "%s,%s)," % (text, ", ".join(args)) else: print "%s)," % text --- 104,108 ---- text = " STDMETHOD(%s, '%s'" % (type_name(m.returns), m.name) if args: ! print "%s, %s)," % (text, ", ".join(args)) else: print "%s)," % text *************** *** 190,199 **** done.add(i) for i in items - done: - ## if isinstance(i, nodes.Typedef) and isinstance(i.typ, nodes.FundamentalType): - ## print "%s = %s" % (i.name, type_name(i.typ)) - ## done.add(i) - ## else: if isinstance(i, nodes.Typedef): ! print "%s = %s" % (i.name, type_name(i.typ)) done.add(i) --- 190,197 ---- done.add(i) for i in items - done: if isinstance(i, nodes.Typedef): ! tp_name = type_name(i.typ) ! if tp_name != i.name: ! print "%s = %s" % (i.name, type_name(i.typ)) done.add(i) *************** *** 209,212 **** --- 207,216 ---- return done, items - done + def gen_arrays(done, items): + for i in items: + if isinstance(i, nodes.ArrayType): + done.add(i) + return done, items - done + from ctypes import windll, cdll # do we also want ntdll.dll? *************** *** 277,280 **** --- 281,285 ---- done, items = gen_enums(done, items) done, items = gen_typedefs(done, items) + done, items = gen_arrays(done, items) done, items = gen_structs(done, items) done, items = gen_functions(done, items) *************** *** 329,332 **** --- 334,338 ---- for i in todo.copy(): needs = set(i.depends()) + assert i not in needs if needs.issubset(done): # can generate this one now ## print "# generate", i *************** *** 342,351 **** if not todo: print "# done after %d iterations" % howoften ! return todo = list(todo) print "# left %d items after %d iterations" % (len(todo), howoften+1) print "#", todo ! return todo if __name__ == "__main__": --- 348,362 ---- if not todo: print "# done after %d iterations" % howoften ! return list(todo), list(done) todo = list(todo) print "# left %d items after %d iterations" % (len(todo), howoften+1) print "#", todo + return todo, list(done) ! def explain(t, done): ! needs = t.depends() ! unresolved = set(done) - set(needs) ! print "for type", t ! print "unresolved", unresolved if __name__ == "__main__": *************** *** 353,357 **** if len(sys.argv) == 1: sys.argv.append("IDispatch") ! todo = main() # TODO-List: --- 364,370 ---- if len(sys.argv) == 1: sys.argv.append("IDispatch") ! todo, done = main() ! if todo: ! print explain(todo[0], done) # TODO-List: *************** *** 359,362 **** # separate dependencies between structure body and structure fields, # so that the various IType... interfaces can be generated. # calculate/guess Structure alignment ! # read IID's from the registry --- 372,377 ---- # separate dependencies between structure body and structure fields, # so that the various IType... interfaces can be generated. + # # calculate/guess Structure alignment ! # ! # read IID's from the registry (?) |
From: Thomas H. <th...@us...> - 2004-09-30 19:57:52
|
Update of /cvsroot/ctypes/ctypes/sandbox/tools/codegen In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv9182 Modified Files: nodes.py Log Message: Pointers to struct or union don't depend on the full struct/union itself. Index: nodes.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/sandbox/tools/codegen/nodes.py,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** nodes.py 30 Sep 2004 18:33:35 -0000 1.3 --- nodes.py 30 Sep 2004 19:57:40 -0000 1.4 *************** *** 81,85 **** def depends(self): ! return [get_pointed_to(self)] def __repr__(self): --- 81,91 ---- def depends(self): ! # Well, if the pointer points to a structure or union, ! # we don't need the complete struct or union definition. ! # The header will suffice. ! t = get_pointed_to(self) ! if type(t) in (Structure, Union): ! return [] ! return [t] def __repr__(self): |
From: Thomas H. <th...@us...> - 2004-09-30 18:33:52
|
Update of /cvsroot/ctypes/ctypes/sandbox/tools/codegen In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv25785 Modified Files: nodes.py Log Message: More __repr__ methods. Index: nodes.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/sandbox/tools/codegen/nodes.py,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** nodes.py 30 Sep 2004 18:16:06 -0000 1.2 --- nodes.py 30 Sep 2004 18:33:35 -0000 1.3 *************** *** 83,86 **** --- 83,89 ---- return [get_pointed_to(self)] + def __repr__(self): + return "<POINTER(%s)>" % self.typ + class Typedef(object): def __init__(self, name, typ): *************** *** 90,98 **** def depends(self): return [self.typ] - ## return self.typ.depends() def __repr__(self): return "<Typedef(%s) at %x>" % (self.name, id(self)) class Structure(object): def __init__(self, name, align, members, bases, size, artificial=None): --- 93,112 ---- def depends(self): return [self.typ] def __repr__(self): return "<Typedef(%s) at %x>" % (self.name, id(self)) + class ArrayType(object): + def __init__(self, typ, min, max): + self.typ = typ + self.min = min + self.max = max + + def depends(self): + return [self.typ] + + def __repr__(self): + return "<Array(%s[%s]) at %x>" % (self.typ, self.max, id(self)) + class Structure(object): def __init__(self, name, align, members, bases, size, artificial=None): *************** *** 116,119 **** --- 130,135 ---- return result + def __repr__(self): + return "<Structure(%s) at %x>" % (self.name, id(self)) class Union(object): *************** *** 173,184 **** return [] - class ArrayType(object): - def __init__(self, typ, min, max): - self.typ = typ - self.min = min - self.max = max - - def depends(self): - return [self.typ] - ################################################################ --- 189,191 ---- |
From: Thomas H. <th...@us...> - 2004-09-30 18:17:40
|
Update of /cvsroot/ctypes/ctypes/sandbox/tools/codegen In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv22792 Modified Files: .cvsignore Log Message: Ignore .h files. Index: .cvsignore =================================================================== RCS file: /cvsroot/ctypes/ctypes/sandbox/tools/codegen/.cvsignore,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** .cvsignore 30 Sep 2004 17:46:36 -0000 1.1 --- .cvsignore 30 Sep 2004 18:17:32 -0000 1.2 *************** *** 1,4 **** *.pyc *.pyo ! *.pickle ! *.xml \ No newline at end of file --- 1,5 ---- + *.pickle *.pyc *.pyo ! *.xml ! *.h |
From: Thomas H. <th...@us...> - 2004-09-30 18:17:01
|
Update of /cvsroot/ctypes/ctypes/sandbox/tools/codegen In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv22661 Modified Files: pycodegen.py Log Message: Somewhat nicer code generation. Debugging. Index: pycodegen.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/sandbox/tools/codegen/pycodegen.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** pycodegen.py 30 Sep 2004 17:46:35 -0000 1.1 --- pycodegen.py 30 Sep 2004 18:16:52 -0000 1.2 *************** *** 75,85 **** methods = [m for m in struct.members if isinstance(m, nodes.Method)] fields = [m for m in struct.members if isinstance(m, nodes.Field)] - ## if methods and not struct.bases: - ## fields.append(nodes.Field("lpVtbl", nodes.FundamentalType("void"), None, "0")) - ## base_name = "_com_interface_base" - ## else: - ## base_name = map(type_name, struct.bases) - ## base_name = ", ".join(base_name) - if fields: if struct.bases: --- 75,78 ---- *************** *** 109,113 **** for m in methods: args = [type_name(a) for a in m.arguments] ! print " STDMETHOD(%s, '%s', %s)" % (type_name(m.returns), m.name, ", ".join(args)) print "]" --- 102,110 ---- for m in methods: args = [type_name(a) for a in m.arguments] ! text = " STDMETHOD(%s, '%s'" % (type_name(m.returns), m.name) ! if args: ! print "%s,%s)," % (text, ", ".join(args)) ! else: ! print "%s)," % text print "]" *************** *** 325,335 **** print "STDMETHOD = STDCALL" print "def CDECL(*x): return x" print ! for howoften in range(100): for i in todo.copy(): needs = set(i.depends()) if needs.issubset(done): # can generate this one now ## print "# generate", i a = generate(i) done.update(a) --- 322,335 ---- print "STDMETHOD = STDCALL" print "def CDECL(*x): return x" + print "class _com_interface_base(Structure):" + print " _fields_ = [('lpVtbl', c_void_p)]" print ! for howoften in range(50): for i in todo.copy(): needs = set(i.depends()) if needs.issubset(done): # can generate this one now ## print "# generate", i + ## print "#depends", i.depends() a = generate(i) done.update(a) *************** *** 343,353 **** print "# done after %d iterations" % howoften return print "# left %d items after %d iterations" % (len(todo), howoften+1) print "#", todo ! return if __name__ == "__main__": ! main() # TODO-List: --- 343,357 ---- print "# done after %d iterations" % howoften return + todo = list(todo) print "# left %d items after %d iterations" % (len(todo), howoften+1) print "#", todo ! return todo if __name__ == "__main__": ! import sys ! if len(sys.argv) == 1: ! sys.argv.append("IDispatch") ! todo = main() # TODO-List: |
From: Thomas H. <th...@us...> - 2004-09-30 18:16:17
|
Update of /cvsroot/ctypes/ctypes/sandbox/tools/codegen In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv22560 Modified Files: nodes.py Log Message: Repair the Union's depends method. Index: nodes.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/sandbox/tools/codegen/nodes.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** nodes.py 30 Sep 2004 17:46:36 -0000 1.1 --- nodes.py 30 Sep 2004 18:16:06 -0000 1.2 *************** *** 131,135 **** def depends(self): ! return [] # fake ##class Class(object): --- 131,140 ---- def depends(self): ! result = set() ! if self.bases: ! result.update(self.bases) ! for m in self.members: ! result.update(m.depends()) ! return result ##class Class(object): |
From: Thomas H. <th...@us...> - 2004-09-30 17:46:49
|
Update of /cvsroot/ctypes/ctypes/sandbox/tools/codegen In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv15839 Added Files: pycodegen.py nodes.py gccxmlparser.py ctypes_names.py .cvsignore Log Message: This starts to be fun, now that at least something works! --- NEW FILE: .cvsignore --- *.pyc *.pyo *.pickle *.xml --- NEW FILE: ctypes_names.py --- # XXX This should really be in ctypes! 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", } --- NEW FILE: nodes.py --- 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 def depends(self): result = set(self.arguments) result.add(self.returns) return result class Constructor(_HasArgs): def __init__(self, name): self.name = name self.arguments = [] def depends(self): return [] 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 = [] def depends(self): result = set(self.arguments) result.add(self.returns) return result class Method(_HasArgs): def __init__(self, name, returns): self.name = name self.returns = returns self.arguments = [] def depends(self): result = set(self.arguments) result.add(self.returns) return result class FundamentalType(object): def __init__(self, name): self.name = name def depends(self): return [] def __repr__(self): return "<FundamentalType(%s)>" % self.name def get_pointed_to(p): # if p is a pointer, return the end of the chain pointed to. if isinstance(p, PointerType): return get_pointed_to(p.typ) elif isinstance(p, CvQualifiedType): return get_pointed_to(p.typ) return p class PointerType(object): def __init__(self, typ): self.typ = typ def depends(self): return [get_pointed_to(self)] class Typedef(object): def __init__(self, name, typ): self.name = name self.typ = typ def depends(self): return [self.typ] ## return self.typ.depends() def __repr__(self): return "<Typedef(%s) at %x>" % (self.name, id(self)) class Structure(object): def __init__(self, name, align, members, bases, size, artificial=None): self.name = name assert int(align) % 8 == 0 self.align = int(align) / 8 self.members = members self.bases = bases self.artificial = artificial if size is not None: self.size = int(size) else: self.size = None def depends(self): result = set() if self.bases: result.update(self.bases) for m in self.members: result.update(m.depends()) return result class Union(object): def __init__(self, name, align, members, bases, size, artificial=None): self.name = name assert int(align) % 8 == 0 self.align = int(align) / 8 self.members = members self.bases = bases self.artificial = artificial if size is not None: self.size = int(size) else: self.size = None def depends(self): return [] # fake ##class Class(object): ## def __init__(self, name, members, bases): ## self.name = name ## self.members = members ## self.bases = bases class Field(object): def __init__(self, name, typ, bits, offset): self.name = name self.typ = typ self.bits = bits self.offset = offset def depends(self): return [self.typ] class CvQualifiedType(object): def __init__(self, typ, attrib): self.typ = typ self.attrib = attrib def depends(self): return self.typ.depends() class Enumeration(object): def __init__(self, name): self.name = name self.values = [] def add_value(self, name, value): self.values.append((name, value)) def depends(self): return [] class ArrayType(object): def __init__(self, typ, min, max): self.typ = typ self.min = min self.max = max def depends(self): return [self.typ] ################################################################ --- NEW FILE: pycodegen.py --- import nodes from ctypes_names import ctypes_names try: set except NameError: from sets import Set as set ################ renames = {} def type_name(t): # Return a string, containing an expression which can be used to # refer to the type. Assumes the ctypes.* namespace is available. if isinstance(t, nodes.PointerType): result = "POINTER(%s)" % type_name(t.typ) # XXX Better to inspect t.typ! if result.startswith("POINTER(WINFUNCTYPE"): return result[8:-1] # XXX See comment above... elif result == "POINTER(None)": return "c_void_p" return result elif isinstance(t, nodes.ArrayType): return "%s * %s" % (type_name(t.typ), int(t.max)+1) elif isinstance(t, nodes.FunctionType): args = map(type_name, [t.returns] + t.arguments) # what now? WINFUNCTYPE already *is* a pointer to a function return "WINFUNCTYPE(%s)" % ", ".join(args) elif isinstance(t, nodes.CvQualifiedType): return "c_const(%s)" % type_name(t.typ) elif isinstance(t, nodes.FundamentalType): return ctypes_names[t.name] elif isinstance(t, nodes.Structure): try: return renames[t] except KeyError: return t.name elif isinstance(t, nodes.Enumeration): try: return renames[t] except KeyError: pass if t.name: return t.name return "c_int" # enums are integers return t.name def make_enum(name, enum): if name is not None: # enums are integers (AFAIK, but may depend on the compiler) print "%s = c_int" % name for name, val in enum.values: print "%s = %s" % (name, val) print def make_struct_header(name, struct, isStruct): methods = [m for m in struct.members if isinstance(m, nodes.Method)] if struct.bases: bases = [type_name(b) for b in struct.bases] elif methods: # a com interface bases = "_com_interface_base", elif isStruct: bases = "Structure", else: bases = "Union", if isStruct: print "class %s(%s):" % (name, ", ".join(bases)) else: print "class %s(%s):" % (name, ", ".join(bases)) print " pass" def make_struct_body(name, struct): methods = [m for m in struct.members if isinstance(m, nodes.Method)] fields = [m for m in struct.members if isinstance(m, nodes.Field)] ## if methods and not struct.bases: ## fields.append(nodes.Field("lpVtbl", nodes.FundamentalType("void"), None, "0")) ## base_name = "_com_interface_base" ## else: ## base_name = map(type_name, struct.bases) ## base_name = ", ".join(base_name) if fields: if struct.bases: print "%s._fields_ = %s._fields_ + [" % (name, base_name) else: print "%s._fields_ = [" % name for m in fields: if m.bits: print " ('%s', %s, %s)," % (m.name, type_name(m.typ), m.bits) else: print " ('%s', %s)," % (m.name, type_name(m.typ)) print "]" else: if methods: pass elif struct.bases: # ??? pass ## print "%s._fields_ = %s._fields_ + [" % (name, type_name(struct.bases[0])) else: print "%s._fields_ = []" % name if methods: if struct.bases: print "%s._methods_ = %s._methods_ + [" % (name, type_name(struct.bases[0])) else: print "%s._methods_ = [" % name for m in methods: args = [type_name(a) for a in m.arguments] print " STDMETHOD(%s, '%s', %s)" % (type_name(m.returns), m.name, ", ".join(args)) print "]" try: size = int(struct.size) except TypeError: pass else: print "assert sizeof(%s) == %s" % (name, size/8) print ################ def gen_enums(done, items): # generate Python code for enums enums = [] for i in items: if isinstance(i, nodes.Typedef) and isinstance(i.typ, nodes.Enumeration): comment = "#typedef enum %s %s;" % (i.typ.name or "<unnamed>", i.name) if i.typ.name: renames[i.typ.name] = i.name renames[i.typ] = i.name enums.append((i.name, comment, i.name, i.typ)) done.add(i) done.add(i.typ) for i in items - done: if isinstance(i, nodes.Enumeration): comment = "#enum %s;" % i.name enums.append((i.name, comment, None, i)) done.add(i) enums.sort() for name, comment, enum_name, typ in enums: print comment make_enum(enum_name, typ) return done, items - done def gen_structs(done, items): bodies = [] structs = [] for i in items: if isinstance(i, nodes.Typedef) and isinstance(i.typ, (nodes.Structure, nodes.Union)): print "#typedef struct %s %s;" % (i.typ.name or "<unnamed>", i.name) if i.typ.name: ## renames[i.typ.name] = i.name renames[i.typ] = i.name isStruct = isinstance(i.typ, nodes.Structure) make_struct_header(i.name, i.typ, isStruct) bodies.append((i.name, i.typ)) done.add(i) done.add(i.typ) for i in items - done: if isinstance(i, (nodes.Structure, nodes.Union)): if i.name is None: continue # internal structure? print "#typedef struct %s;" % i.name isStruct = isinstance(i, nodes.Structure) make_struct_header(i.name, i, isStruct) bodies.append((i.name, i)) done.add(i) for name, struct in bodies: make_struct_body(name, struct) return done, items - done def get_pointed_to(p): # if p is a pointer, return the end of the chain pointed to. if isinstance(p, nodes.PointerType): return get_pointed_to(p.typ) elif isinstance(p, nodes.CvQualifiedType): return get_pointed_to(p.typ) return p def gen_typedefs(done, items): for i in items: if isinstance(i, nodes.FundamentalType): done.add(i) for i in items - done: ## if isinstance(i, nodes.Typedef) and isinstance(i.typ, nodes.FundamentalType): ## print "%s = %s" % (i.name, type_name(i.typ)) ## done.add(i) ## else: if isinstance(i, nodes.Typedef): print "%s = %s" % (i.name, type_name(i.typ)) done.add(i) for i in items - done: if not isinstance(i, nodes.Typedef): continue if i.typ in done: print "%s = %s #" % (i.name, type_name(i.typ)) done.add(i) elif isinstance(i.typ, nodes.PointerType) and get_pointed_to(i.typ) in done: print "%s = %s ##" % (i.name, type_name(i.typ)) done.add(i) return done, items - done from ctypes import windll, cdll # do we also want ntdll.dll? dllnames = """netapi32 scarddlg comctl32 mswsock mpr version opengl32 cryptnet comdlg32 shell32 winscard winspool.drv urlmon winmm imm32 user32 kernel32 advapi32 gdi32 ws2_32 rpcrt4 rpcns4 ole32 oleaut32 crypt32 msvcrt""" dlls = [getattr(cdll, name) for name in dllnames.split()] def find_dll(funcname): for l in dlls: try: getattr(l, funcname) except AttributeError: pass else: return l._name return None def gen_functions(done, items): for i in items: if not isinstance(i, nodes.Function): continue if not i.extern: done.add(i) continue dllname = find_dll(i.name) if dllname is None: dllname = "<unknown>" if "__stdcall__" in i.attributes: print "%s = STDCALL(%r, %s, '%s', %s)" % \ (i.name, dllname, type_name(i.returns), i.name, ", ".join(map(type_name, i.arguments))) else: # __cdecl is default print "%s = CDECL(%r, %s, '%s', %s)" % \ (i.name, dllname, type_name(i.returns), i.name, ", ".join(map(type_name, i.arguments))) done.add(i) return done, items - done ################ def main_old(): from gccxmlparser import parse items = parse(files=["windows.h"], xmlfile="windows.xml") items = set(items) print "# pass 1", len(items) done = set() done, items = gen_enums(done, items) print "# pass 2", len(items) done, items = gen_typedefs(done, items) print "# pass 3", len(items) done, items = gen_structs(done, items) print "# pass 4", len(items) done, items = gen_typedefs(done, items) print "# pass 5", len(items) done, items = gen_functions(done, items) print "# pass 6", len(items) items = list(items) import pdb pdb.set_trace() def generate(item): done = set() items = set([item]) done, items = gen_enums(done, items) done, items = gen_typedefs(done, items) done, items = gen_structs(done, items) done, items = gen_functions(done, items) return done ################################################################ def find(names, fname=None): if fname: import cPickle items = cPickle.loads(open(fname, "rb").read()) else: from gccxmlparser import parse items = parse(files=["windows.h"], xmlfile="windows.xml") import cPickle data = cPickle.dumps(items) open("windows.pickle", "wb").write(data) result = [] for i in items: if getattr(i, "name", None) in names: result.append(i) return result def depends(i): deps = i.depends() result = set() for x in deps: if not isinstance(x, nodes.FundamentalType): result.add(x) return result def main(): done = set() todo = set() import sys todo.update(find(sys.argv[1:], "windows.pickle")) print "from ctypes import *" print "def c_const(x): return x" print "def STDCALL(*x): return x" print "STDMETHOD = STDCALL" print "def CDECL(*x): return x" print for howoften in range(100): for i in todo.copy(): needs = set(i.depends()) if needs.issubset(done): # can generate this one now ## print "# generate", i a = generate(i) done.update(a) done.add(i) else: todo.update(needs) ## print i todo -= done ## print "#%d:" % howoften, len(done), len(todo) if not todo: print "# done after %d iterations" % howoften return print "# left %d items after %d iterations" % (len(todo), howoften+1) print "#", todo return if __name__ == "__main__": main() # TODO-List: # # separate dependencies between structure body and structure fields, # so that the various IType... interfaces can be generated. # calculate/guess Structure alignment # read IID's from the registry --- NEW FILE: gccxmlparser.py --- 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) ################################################################ class GCCXML_Handler(xml.sax.handler.ContentHandler): has_values = Set(["Enumeration", "Function", "FunctionType", "OperatorFunction", "Method", "Constructor"]) def __init__(self, *args): xml.sax.handler.ContentHandler.__init__(self, *args) self.context = [] self.all = {} self.artificial = [] def startElement(self, name, attrs): # find and call the handler for this element mth = getattr(self, name) result = mth(attrs) if result is None: return # record the result _id = attrs.get("id", None) if _id is not None: self.all[_id] = result # if this element has children, push onto the context if name in self.has_values: self.context.append(result) def endElement(self, name): # if this element has children, pop the context if name in self.has_values: self.context = self.context[:-1] ################################ # do-nothing element handlers def GCC_XML(self, attrs): pass def Namespace(self, attrs): pass def Variable(self, attrs): pass def Base(self, attrs): pass def Ellipsis(self, attrs): pass def File(self, attrs): pass ################################ # real element handlers # simple types and modifiers def Typedef(self, attrs): name = attrs["name"] typ = attrs["type"] return nodes.Typedef(name, typ) def _fixup_Typedef(self, t): t.typ = self.all[t.typ] def FundamentalType(self, attrs): name = attrs["name"] return nodes.FundamentalType(name) def _fixup_FundamentalType(self, t): pass def PointerType(self, attrs): typ = attrs["type"] return nodes.PointerType(typ) def _fixup_PointerType(self, p): p.typ = self.all[p.typ] ReferenceType = PointerType _fixup_ReferenceType = _fixup_PointerType def ArrayType(self, attrs): # type, min?, max? typ = attrs["type"] min = attrs["min"] max = attrs["max"] if max == "ffffffffffffffff": max = "-1" return nodes.ArrayType(typ, min, max) def _fixup_ArrayType(self, a): a.typ = self.all[a.typ] def CvQualifiedType(self, attrs): # id, type, [const|volatile] typ = attrs["type"] ## const = attrs["const"] ## volatile = attrs["volatile"] return nodes.CvQualifiedType(typ, "xxx") def _fixup_CvQualifiedType(self, c): c.typ = self.all[c.typ] # callables def Function(self, attrs): # name, returns, extern, attributes name = attrs["name"] returns = attrs["returns"] attributes = attrs.get("attributes", "").split() extern = attrs.get("extern") return nodes.Function(name, returns, attributes, extern) def _fixup_Function(self, func): func.returns = self.all[func.returns] func.arguments = [self.all[a] for a in func.arguments] def FunctionType(self, attrs): # id, returns, attributes returns = attrs["returns"] return nodes.FunctionType(returns) def _fixup_FunctionType(self, func): func.returns = self.all[func.returns] func.arguments = [self.all[a] for a in func.arguments] def OperatorFunction(self, attrs): # name, returns, extern, attributes name = attrs["name"] returns = attrs["returns"] return nodes.OperatorFunction(name, returns) def _fixup_OperatorFunction(self, func): func.returns = self.all[func.returns] def Constructor(self, attrs): name = attrs["name"] return nodes.Constructor(name) def _fixup_Constructor(self, const): pass def Method(self, attrs): # name, virtual, pure_virtual, returns name = attrs["name"] returns = attrs["returns"] return nodes.Method(name, returns) def _fixup_Method(self, m): m.returns = self.all[m.returns] m.arguments = [self.all[a] for a in m.arguments] def Argument(self, attrs): typ = attrs["type"] self.context[-1].add_argument(typ) # name? # enumerations def Enumeration(self, attrs): # id, name name = attrs["name"] if attrs.get("artificial"): # enum {} ENUM_NAME; return nodes.Enumeration(name) else: # enum tagENUM {}; enum = nodes.Enumeration(None) self.artificial.append(nodes.Typedef(name, enum)) return enum def _fixup_Enumeration(self, e): pass def EnumValue(self, attrs): name = attrs["name"] value = attrs["init"] self.context[-1].add_value(name, value) def _fixup_EnumValue(self, e): pass # structures, unions def Struct(self, attrs): # id, name, members name = attrs.get("name") bases = attrs.get("bases", "").split() members = attrs.get("members", "").split() abstract = attrs.get("abstract", "") align = attrs["align"] size = attrs.get("size") artificial = attrs.get("artificial") ## 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(None, align, members, bases, size) self.artificial.append(nodes.Typedef(name, struct)) return struct def _fixup_Structure(self, s): s.members = [self.all[m] for m in s.members] s.bases = [self.all[b] for b in s.bases] _fixup_Union = _fixup_Structure def Union(self, attrs): name = attrs.get("name") bases = attrs.get("bases", "").split() members = attrs.get("members", "").split() abstract = attrs.get("abstract", "") align = attrs["align"] size = attrs.get("size") artificial = attrs.get("artificial") return nodes.Union(name, align, members, bases, size) def Field(self, attrs): # name, type name = attrs["name"] typ = attrs["type"] bits = attrs.get("bits", None) offset = attrs.get("offset") return nodes.Field(name, typ, bits, offset) def _fixup_Field(self, f): f.typ = self.all[f.typ] ################ def get_result(self): interesting = ( nodes.Typedef, nodes.Enumeration, nodes.Function, nodes.Structure, nodes.Union) result = [] for i in self.all.values(): mth = getattr(self, "_fixup_" + type(i).__name__) mth(i) for i in self.artificial + self.all.values(): if isinstance(i, interesting): result.append(i) return result ################################################################ 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()) |
From: Thomas H. <th...@us...> - 2004-09-30 17:41:28
|
Update of /cvsroot/ctypes/ctypes/sandbox/tools/codegen In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv14879/codegen Log Message: Directory /cvsroot/ctypes/ctypes/sandbox/tools/codegen added to the repository |
From: Thomas H. <th...@us...> - 2004-09-28 14:17:06
|
Update of /cvsroot/ctypes/ctypes In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv17422 Modified Files: ChangeLog Log Message: Record changes. Index: ChangeLog =================================================================== RCS file: /cvsroot/ctypes/ctypes/ChangeLog,v retrieving revision 1.61 retrieving revision 1.62 diff -C2 -d -r1.61 -r1.62 *** ChangeLog 21 Sep 2004 14:16:15 -0000 1.61 --- ChangeLog 28 Sep 2004 14:16:52 -0000 1.62 *************** *** 1,2 **** --- 1,8 ---- + 2004-09-28 Thomas Heller <th...@py...> + + * (Message): Support for 'lazy' Structure and Union definitions. + The _fields_ attribute can now be set after the class has been + defined. + 2004-09-21 Thomas Heller <th...@py...> |
From: Thomas H. <th...@us...> - 2004-09-28 14:00:57
|
Update of /cvsroot/ctypes/ctypes/unittests In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv13467 Modified Files: test_structures.py Log Message: Lazy _fields_ are allowed in Unions as well. Index: test_structures.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/unittests/test_structures.py,v retrieving revision 1.23 retrieving revision 1.24 diff -C2 -d -r1.23 -r1.24 *** test_structures.py 28 Sep 2004 13:15:30 -0000 1.23 --- test_structures.py 28 Sep 2004 14:00:45 -0000 1.24 *************** *** 66,69 **** --- 66,108 ---- self.assertRaises(AttributeError, setattr, Z, "_pack_", 32) + def test_lazy_union(self): + class X(Union): + pass + + class Y(X): + pass + + class Z(X): + pass + + self.assertRaises(TypeError, sizeof, X) + self.assertRaises(TypeError, sizeof, Y) + self.assertRaises(TypeError, sizeof, Z) + + X._pack_ = 0 + Y._pack_ = 0 + Z._pack_ = 0 + + X._fields_ = [("a", c_int)] + Y._fields_ = X._fields_ + [("b", c_int)] + Z._fields_ = X._fields_ + + self.failUnlessEqual(sizeof(X), sizeof(c_int)) + self.failUnlessEqual(sizeof(Y), sizeof(c_int)) + self.failUnlessEqual(sizeof(Z), sizeof(c_int)) + + self.failUnlessEqual(X._fields_, + [("a", c_int)]) + + self.failUnlessEqual(Y._fields_, + [("a", c_int), ("b", c_int)]) + + self.failUnlessEqual(Z._fields_, + [("a", c_int)]) + + self.assertRaises(AttributeError, setattr, X, "_pack_", 32) + self.assertRaises(AttributeError, setattr, Y, "_pack_", 32) + self.assertRaises(AttributeError, setattr, Z, "_pack_", 32) + class StructureTestCase(unittest.TestCase): formats = {"c": c_char, |
From: Thomas H. <th...@us...> - 2004-09-28 14:00:45
|
Update of /cvsroot/ctypes/ctypes/source In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv13330 Modified Files: _ctypes.c Log Message: Lazy _fields_ are allowed in Unions as well. Index: _ctypes.c =================================================================== RCS file: /cvsroot/ctypes/ctypes/source/_ctypes.c,v retrieving revision 1.162 retrieving revision 1.163 diff -C2 -d -r1.162 -r1.163 *** _ctypes.c 28 Sep 2004 13:15:08 -0000 1.162 --- _ctypes.c 28 Sep 2004 14:00:18 -0000 1.163 *************** *** 286,290 **** }; - /* XXX This should probably use a cache! */ static PyObject * CDataType_repeat(PyObject *self, int length) --- 286,289 ---- *************** *** 308,312 **** static int ! StructType_setattro(PyTypeObject *self, PyObject *name, PyObject *value) { if (PyString_Check(name) --- 307,312 ---- static int ! StructUnionType_setattro(PyTypeObject *self, PyObject *name, PyObject *value, ! int isStruct) { if (PyString_Check(name) *************** *** 318,324 **** return -1; } ! dict = StgDict_FromDict(value, ! self->tp_dict, ! TRUE); if (dict == NULL) return -1; --- 318,322 ---- return -1; } ! dict = StgDict_FromDict(value, self->tp_dict, isStruct); if (dict == NULL) return -1; *************** *** 344,347 **** --- 342,357 ---- } + static int + StructType_setattro(PyTypeObject *self, PyObject *name, PyObject *value) + { + return StructUnionType_setattro(self, name, value, 1); + } + + static int + UnionType_setattro(PyTypeObject *self, PyObject *name, PyObject *value) + { + return StructUnionType_setattro(self, name, value, 0); + } + static PyTypeObject StructType_Type = { PyObject_HEAD_INIT(NULL) *************** *** 406,410 **** 0, /* tp_str */ 0, /* tp_getattro */ ! 0, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ --- 416,420 ---- 0, /* tp_str */ 0, /* tp_getattro */ ! (setattrofunc)UnionType_setattro, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ |
From: Thomas H. <th...@us...> - 2004-09-28 13:15:40
|
Update of /cvsroot/ctypes/ctypes/unittests In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv3783 Modified Files: test_structures.py Log Message: Support for 'lazy' Structure definition. Now one can assign the _fields_ attribute later, like this: class POINT(Structure): pass POINT._fields_ = [("x", c_int), ("y", c_int)] Index: test_structures.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/unittests/test_structures.py,v retrieving revision 1.22 retrieving revision 1.23 diff -C2 -d -r1.22 -r1.23 *** test_structures.py 28 Sep 2004 11:55:45 -0000 1.22 --- test_structures.py 28 Sep 2004 13:15:30 -0000 1.23 *************** *** 27,30 **** --- 27,69 ---- [("a", c_int)]) + def test_lazy_subclass(self): + class X(Structure): + pass + + class Y(X): + pass + + class Z(X): + pass + + self.assertRaises(TypeError, sizeof, X) + self.assertRaises(TypeError, sizeof, Y) + self.assertRaises(TypeError, sizeof, Z) + + X._pack_ = 0 + Y._pack_ = 0 + Z._pack_ = 0 + + X._fields_ = [("a", c_int)] + Y._fields_ = X._fields_ + [("b", c_int)] + Z._fields_ = X._fields_ + + self.failUnlessEqual(sizeof(X), sizeof(c_int)) + self.failUnlessEqual(sizeof(Y), sizeof(c_int)*2) + self.failUnlessEqual(sizeof(Z), sizeof(c_int)) + + self.failUnlessEqual(X._fields_, + [("a", c_int)]) + + self.failUnlessEqual(Y._fields_, + [("a", c_int), ("b", c_int)]) + + self.failUnlessEqual(Z._fields_, + [("a", c_int)]) + + self.assertRaises(AttributeError, setattr, X, "_pack_", 32) + self.assertRaises(AttributeError, setattr, Y, "_pack_", 32) + self.assertRaises(AttributeError, setattr, Z, "_pack_", 32) + class StructureTestCase(unittest.TestCase): formats = {"c": c_char, *************** *** 254,271 **** ! def test_subclass_creation(self): ! meta = type(Structure) ! # same as 'class X(Structure): pass' ! # fails, since we need either a _fields_ or a _abstract_ attribute ! cls, msg = self.get_except(meta, "X", (Structure,), {}) ! self.failUnlessEqual((cls, msg), ! (AttributeError, "class must define a '_fields_' attribute")) def test_abstract_class(self): class X(Structure): ! _abstract_ = "something" # try 'X()' cls, msg = self.get_except(eval, "X()", locals()) ! self.failUnlessEqual((cls, msg), (TypeError, "abstract class")) def test_methods(self): --- 293,311 ---- ! # no longer true: ! ## def test_subclass_creation(self): ! ## meta = type(Structure) ! ## # same as 'class X(Structure): pass' ! ## # fails, since we need either a _fields_ or a _abstract_ attribute ! ## cls, msg = self.get_except(meta, "X", (Structure,), {}) ! ## self.failUnlessEqual((cls, msg), ! ## (AttributeError, "class must define a '_fields_' attribute")) def test_abstract_class(self): class X(Structure): ! pass # try 'X()' cls, msg = self.get_except(eval, "X()", locals()) ! self.failUnlessEqual((cls, msg), (TypeError, "Cannot create instance: no _fields_")) def test_methods(self): |
From: Thomas H. <th...@us...> - 2004-09-28 13:15:19
|
Update of /cvsroot/ctypes/ctypes/source In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv3734 Modified Files: _ctypes.c Log Message: Support for 'lazy' Structure definition. Now one can assign the _fields_ attribute later, like this: class POINT(Structure): pass POINT._fields_ = [("x", c_int), ("y", c_int)] Index: _ctypes.c =================================================================== RCS file: /cvsroot/ctypes/ctypes/source/_ctypes.c,v retrieving revision 1.161 retrieving revision 1.162 diff -C2 -d -r1.161 -r1.162 *** _ctypes.c 28 Sep 2004 11:35:13 -0000 1.161 --- _ctypes.c 28 Sep 2004 13:15:08 -0000 1.162 *************** *** 131,147 **** return NULL; - /* If we find an _abstract_ item in the class dict, - don't equip this class with a StgDict. - The resulting class will not be able to create - instances. - The value of the _abstract_ item is ignored. - */ - - if (PyDict_GetItemString(cls_dict, "_abstract_")) - return (PyObject *)result; - fields = PyObject_GetAttrString((PyObject *)result, "_fields_"); dict = StgDict_FromDict(fields, cls_dict, isStruct); ! Py_XDECREF(fields); if (!dict) { Py_DECREF(result); --- 131,141 ---- return NULL; fields = PyObject_GetAttrString((PyObject *)result, "_fields_"); + if (fields == NULL) { + PyErr_Clear(); + return result; + } dict = StgDict_FromDict(fields, cls_dict, isStruct); ! Py_DECREF(fields); if (!dict) { Py_DECREF(result); *************** *** 313,316 **** --- 307,346 ---- }; + static int + StructType_setattro(PyTypeObject *self, PyObject *name, PyObject *value) + { + if (PyString_Check(name) + && 0 == strcmp("_fields_", PyString_AS_STRING(name))) { + PyObject *dict; + if (PyType_stgdict((PyObject *)self)) { + PyErr_SetString(PyExc_AttributeError, + "_fields_ attribute cannot be overwritten"); + return -1; + } + dict = StgDict_FromDict(value, + self->tp_dict, + TRUE); + if (dict == NULL) + return -1; + + /* replace the class dict by our updated stgdict, which holds info + about storage requirements of the instances */ + if (-1 == PyDict_Update(dict, self->tp_dict)) { + Py_DECREF(dict); + return -1; + } + Py_DECREF(self->tp_dict); + self->tp_dict = dict; + } + if (PyString_Check(name) + && 0 == strcmp("_pack_", PyString_AS_STRING(name))) { + if (PyType_stgdict((PyObject *)self)) { + PyErr_SetString(PyExc_AttributeError, + "_pack_ attribute cannot be overwritten"); + return -1; + } + } + return PyObject_GenericSetAttr((PyObject *)self, name, value); + } static PyTypeObject StructType_Type = { *************** *** 327,331 **** 0, /* tp_repr */ 0, /* tp_as_number */ ! &CDataType_as_sequence, /* tp_as_sequence */ 0, /* tp_as_mapping */ 0, /* tp_hash */ --- 357,361 ---- 0, /* tp_repr */ 0, /* tp_as_number */ ! &CDataType_as_sequence, /* tp_as_sequence */ 0, /* tp_as_mapping */ 0, /* tp_hash */ *************** *** 333,337 **** 0, /* tp_str */ 0, /* tp_getattro */ ! 0, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ --- 363,367 ---- 0, /* tp_str */ 0, /* tp_getattro */ ! (setattrofunc)StructType_setattro, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ *************** *** 2688,2691 **** --- 2718,2732 ---- }; + static PyObject * + StructUnion_new(PyTypeObject *type, PyObject *args, PyObject *kw) + { + if (!PyType_stgdict((PyObject *)type)) { + PyErr_SetString(PyExc_TypeError, + "Cannot create instance: no _fields_"); + return NULL; + } + return GenericCData_new(type, args, kw); + } + static PyTypeObject Struct_Type = { PyObject_HEAD_INIT(NULL) *************** *** 2727,2731 **** Struct_init, /* tp_init */ 0, /* tp_alloc */ ! GenericCData_new, /* tp_new */ 0, /* tp_free */ }; --- 2768,2772 ---- Struct_init, /* tp_init */ 0, /* tp_alloc */ ! StructUnion_new, /* tp_new */ 0, /* tp_free */ }; *************** *** 2770,2774 **** Struct_init, /* tp_init */ 0, /* tp_alloc */ ! GenericCData_new, /* tp_new */ 0, /* tp_free */ }; --- 2811,2815 ---- Struct_init, /* tp_init */ 0, /* tp_alloc */ ! StructUnion_new, /* tp_new */ 0, /* tp_free */ }; *************** *** 3551,3578 **** /* - static char *Structure_docs = - "An abstract base class for C struct data types\n" - "\n" - "Concrete subclasses must define a _fields_ class attribute\n" - "which must be a sequence of (name, format) tuples.\n" - "\n" - "Abstract subclasses must define an _abstract_ attribute;\n" - "the value of this is ignored."; - - static char *Pointer_docs = - "An abstract base class for C pointer data types\n" - "\n" - "Subclasses must define a _type_ class attribute which must\n" - "either be a format character or a subclass of Structure."; - - - static char *Array_docs = - "An abstract base class for C array data types\n" - "\n" - "Subclasses must define a _type_ class attribute which must\n" - "either be a format character or a subclass of Structure."; - */ - - /* * XXX What about errors ??? */ --- 3592,3595 ---- *************** *** 3605,3612 **** static char *module_docs = ! "Create and manipulate C compatible data types in Python.\n" ! "\n" ! "format descriptors: characters similar to the struct module\n" ! "XXX more"; DL_EXPORT(void) --- 3622,3626 ---- static char *module_docs = ! "Create and manipulate C compatible data types in Python."; DL_EXPORT(void) |
From: Thomas H. <th...@us...> - 2004-09-28 11:55:56
|
Update of /cvsroot/ctypes/ctypes/unittests In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv19237 Modified Files: test_structures.py Log Message: Test subclassing structures. Index: test_structures.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/unittests/test_structures.py,v retrieving revision 1.21 retrieving revision 1.22 diff -C2 -d -r1.21 -r1.22 *** test_structures.py 16 Sep 2004 10:41:15 -0000 1.21 --- test_structures.py 28 Sep 2004 11:55:45 -0000 1.22 *************** *** 3,6 **** --- 3,30 ---- from struct import calcsize + class SubclassesTest(unittest.TestCase): + def test_subclass(self): + class X(Structure): + _fields_ = [("a", c_int)] + + class Y(X): + _fields_ = X._fields_ + [("b", c_int)] + + class Z(X): + pass + + self.failUnlessEqual(sizeof(X), sizeof(c_int)) + self.failUnlessEqual(sizeof(Y), sizeof(c_int)*2) + self.failUnlessEqual(sizeof(Z), sizeof(c_int)) + + self.failUnlessEqual(X._fields_, + [("a", c_int)]) + + self.failUnlessEqual(Y._fields_, + [("a", c_int), ("b", c_int)]) + + self.failUnlessEqual(Z._fields_, + [("a", c_int)]) + class StructureTestCase(unittest.TestCase): formats = {"c": c_char, |
From: Thomas H. <th...@us...> - 2004-09-28 11:35:24
|
Update of /cvsroot/ctypes/ctypes/source In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv15171 Modified Files: stgdict.c ctypes.h _ctypes.c Log Message: Simplified a bit, by moving code into the StgDict_FromDict function. Index: ctypes.h =================================================================== RCS file: /cvsroot/ctypes/ctypes/source/ctypes.h,v retrieving revision 1.51 retrieving revision 1.52 diff -C2 -d -r1.51 -r1.52 *** ctypes.h 21 Sep 2004 17:00:59 -0000 1.51 --- ctypes.h 28 Sep 2004 11:35:13 -0000 1.52 *************** *** 68,73 **** #define StgDict_CheckExact(v) ((v)->ob_type == &StgDict_Type) #define StgDict_Check(v) PyObject_TypeCheck(v, &StgDict_Type) ! extern PyObject *StgDict_FromDict(PyObject *fields, PyObject *typedict, ! int isStruct, int pack); 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,72 ---- #define StgDict_CheckExact(v) ((v)->ob_type == &StgDict_Type) #define StgDict_Check(v) PyObject_TypeCheck(v, &StgDict_Type) ! extern PyObject *StgDict_FromDict(PyObject *fields, PyObject *typedict, 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); Index: stgdict.c =================================================================== RCS file: /cvsroot/ctypes/ctypes/source/stgdict.c,v retrieving revision 1.13 retrieving revision 1.14 diff -C2 -d -r1.13 -r1.14 *** stgdict.c 21 Sep 2004 17:00:59 -0000 1.13 --- stgdict.c 28 Sep 2004 11:35:13 -0000 1.14 *************** *** 128,132 **** PyObject * ! StgDict_FromDict(PyObject *fields, PyObject *typedict, int isStruct, int pack) { StgDictObject *stgdict; --- 128,132 ---- PyObject * ! StgDict_FromDict(PyObject *fields, PyObject *typedict, int isStruct) { StgDictObject *stgdict; *************** *** 135,142 **** --- 135,154 ---- PyObject *prev_desc = NULL; int bitofs; + PyObject *isPacked; + int pack = 0; if (!typedict) return NULL; + isPacked = PyDict_GetItemString(typedict, "_pack_"); + if (isPacked) { + pack = PyInt_AsLong(isPacked); + if (pack < 0 || PyErr_Occurred()) { + PyErr_SetString(PyExc_ValueError, + "_pack_ must be a non-negative integer"); + return NULL; + } + } + if (!fields) { PyErr_SetString(PyExc_AttributeError, Index: _ctypes.c =================================================================== RCS file: /cvsroot/ctypes/ctypes/source/_ctypes.c,v retrieving revision 1.160 retrieving revision 1.161 diff -C2 -d -r1.160 -r1.161 *** _ctypes.c 21 Sep 2004 17:01:13 -0000 1.160 --- _ctypes.c 28 Sep 2004 11:35:13 -0000 1.161 *************** *** 117,122 **** PyObject *fields, *dict; PyObject *cls_dict; - PyObject *isPacked; - int pack = 0; cls_dict = PyTuple_GetItem(args, 2); /* borrowed ref */ --- 117,120 ---- *************** *** 143,159 **** return (PyObject *)result; - isPacked = PyDict_GetItemString(cls_dict, "_pack_"); - if (isPacked) { - pack = PyInt_AsLong(isPacked); - if (pack < 0 || PyErr_Occurred()) { - PyErr_SetString(PyExc_ValueError, - "_pack_ must be a non-negative integer"); - Py_DECREF(result); - return NULL; - } - } - fields = PyObject_GetAttrString((PyObject *)result, "_fields_"); ! dict = StgDict_FromDict(fields, cls_dict, isStruct, pack); Py_XDECREF(fields); if (!dict) { --- 141,146 ---- return (PyObject *)result; fields = PyObject_GetAttrString((PyObject *)result, "_fields_"); ! dict = StgDict_FromDict(fields, cls_dict, isStruct); Py_XDECREF(fields); if (!dict) { |
From: Thomas H. <th...@us...> - 2004-09-22 07:00:49
|
Update of /cvsroot/ctypes/ctypes/source In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv11094 Modified Files: _ctypes_test.c Log Message: Add test function set_bitfields. Index: _ctypes_test.c =================================================================== RCS file: /cvsroot/ctypes/ctypes/source/_ctypes_test.c,v retrieving revision 1.27 retrieving revision 1.28 diff -C2 -d -r1.27 -r1.28 *** _ctypes_test.c 21 Sep 2004 17:01:13 -0000 1.27 --- _ctypes_test.c 22 Sep 2004 07:00:15 -0000 1.28 *************** *** 299,302 **** --- 299,325 ---- }; + DL_EXPORT(void) set_bitfields(struct BITS *bits, char name, int value) + { + switch (name) { + case 'A': bits->A = value; break; + case 'B': bits->B = value; break; + case 'C': bits->C = value; break; + case 'D': bits->D = value; break; + case 'E': bits->E = value; break; + case 'F': bits->F = value; break; + case 'G': bits->G = value; break; + case 'H': bits->H = value; break; + case 'I': bits->I = value; break; + + case 'M': bits->M = value; break; + case 'N': bits->N = value; break; + case 'O': bits->O = value; break; + case 'P': bits->P = value; break; + case 'Q': bits->Q = value; break; + case 'R': bits->R = value; break; + case 'S': bits->S = value; break; + } + } + DL_EXPORT(int) unpack_bitfields(struct BITS *bits, char name) { |
From: Thomas H. <th...@us...> - 2004-09-21 17:01:33
|
Update of /cvsroot/ctypes/ctypes/unittests In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv2257 Added Files: test_bitfields.py Log Message: Add support for bit fields in structures, plus unit tests. --- NEW FILE: test_bitfields.py --- from ctypes import * import unittest import ctypes import _ctypes_test class BITS(Structure): _fields_ = [("A", c_int, 1), ("B", c_int, 2), ("C", c_int, 3), ("D", c_int, 4), ("E", c_int, 5), ("F", c_int, 6), ("G", c_int, 7), ("H", c_int, 8), ("I", c_int, 9), ("M", c_short, 1), ("N", c_short, 2), ("O", c_short, 3), ("P", c_short, 4), ("Q", c_short, 5), ("R", c_short, 6), ("S", c_short, 7)] func = CDLL(_ctypes_test.__file__).unpack_bitfields func.argtypes = POINTER(BITS), c_char ##for n in "ABCDEFGHIMNOPQRS": ## print n, hex(getattr(BITS, n).size), getattr(BITS, n).offset class C_Test(unittest.TestCase): def test_ints(self): for i in range(512): for name in "ABCDEFGHI": b = BITS() setattr(b, name, i) self.failUnlessEqual((name, i, getattr(b, name)), (name, i, func(byref(b), name))) def test_shorts(self): for i in range(256): for name in "MNOPQRS": b = BITS() setattr(b, name, i) self.failUnlessEqual((name, i, getattr(b, name)), (name, i, func(byref(b), name))) signed_int_types = (c_byte, c_short, c_int, c_long, c_longlong) unsigned_int_types = (c_ubyte, c_ushort, c_uint, c_ulong, c_ulonglong) int_types = unsigned_int_types + signed_int_types class BitFieldTest(unittest.TestCase): def test_longlong(self): class X(Structure): _fields_ = [("a", c_longlong, 1), ("b", c_longlong, 62), ("c", c_longlong, 1)] ## self.failUnlessEqual(sizeof(X), sizeof(c_longlong)) ## x = X() ## x.a, x.b, x.c = -1, 7, -1 ## self.failUnlessEqual((x.a, x.b, x.c), (-1, 7, -1)) def X_test_ulonglong(self): class X(Structure): _fields_ = [("a", c_ulonglong, 1), ("b", c_ulonglong, 62), ("c", c_ulonglong, 1)] self.failUnlessEqual(sizeof(X), sizeof(c_longlong)) x = X() self.failUnlessEqual((x.a, x.b, x.c), (0, 0, 0)) x.a, x.b, x.c = 7, 7, 7 self.failUnlessEqual((x.a, x.b, x.c), (1, 7, 1)) def test_signed(self): for c_typ in signed_int_types: class X(Structure): _fields_ = [("dummy", c_typ), ("a", c_typ, 3), ("b", c_typ, 3), ("c", c_typ, 1)] self.failUnlessEqual(sizeof(X), sizeof(c_typ)*2) x = X() self.failUnlessEqual((c_typ, x.a, x.b, x.c), (c_typ, 0, 0, 0)) x.a = -1 self.failUnlessEqual((c_typ, x.a, x.b, x.c), (c_typ, -1, 0, 0)) x.a, x.b = 0, -1 self.failUnlessEqual((c_typ, x.a, x.b, x.c), (c_typ, 0, -1, 0)) def test_unsigned(self): for c_typ in unsigned_int_types: class X(Structure): _fields_ = [("a", c_typ, 3), ("b", c_typ, 3), ("c", c_typ, 1)] self.failUnlessEqual(sizeof(X), sizeof(c_typ)) x = X() self.failUnlessEqual((c_typ, x.a, x.b, x.c), (c_typ, 0, 0, 0)) x.a = -1 self.failUnlessEqual((c_typ, x.a, x.b, x.c), (c_typ, 7, 0, 0)) x.a, x.b = 0, -1 self.failUnlessEqual((c_typ, x.a, x.b, x.c), (c_typ, 0, 7, 0)) def fail_fields(self, *fields): return self.get_except(type(Structure), "X", (), {"_fields_": fields}) def test_nonint_types(self): # bit fields are not allowed on non-integer types. result = self.fail_fields(("a", c_char_p, 1)) self.failUnlessEqual(result, (TypeError, 'bit fields not allowed for type c_char_p')) result = self.fail_fields(("a", c_void_p, 1)) self.failUnlessEqual(result, (TypeError, 'bit fields not allowed for type c_void_p')) result = self.fail_fields(("a", POINTER(c_int), 1)) self.failUnlessEqual(result, (TypeError, 'bit fields not allowed for type LP_c_int')) result = self.fail_fields(("a", c_char, 1)) self.failUnlessEqual(result, (TypeError, 'bit fields not allowed for type c_char')) try: c_wchar except NameError: pass else: result = self.fail_fields(("a", c_char, 1)) self.failUnlessEqual(result, (TypeError, 'bit fields not allowed for type c_char')) class Dummy(Structure): _fields_ = [] result = self.fail_fields(("a", Dummy, 1)) self.failUnlessEqual(result, (TypeError, 'bit fields not allowed for type Dummy')) def test_single_bitfield_size(self): for c_typ in int_types: result = self.fail_fields(("a", c_typ, -1)) self.failUnlessEqual(result, (ValueError, 'number of bits invalid for bit field')) result = self.fail_fields(("a", c_typ, 0)) self.failUnlessEqual(result, (ValueError, 'number of bits invalid for bit field')) class X(Structure): _fields_ = [("a", c_typ, 1)] self.failUnlessEqual(sizeof(X), sizeof(c_typ)) class X(Structure): _fields_ = [("a", c_typ, sizeof(c_typ)*8)] self.failUnlessEqual(sizeof(X), sizeof(c_typ)) result = self.fail_fields(("a", c_typ, sizeof(c_typ)*8 + 1)) self.failUnlessEqual(result, (ValueError, 'number of bits invalid for bit field')) def test_multi_bitfields_size(self): class X(Structure): _fields_ = [("a", c_short, 1), ("b", c_short, 14), ("c", c_short, 1)] self.failUnlessEqual(sizeof(X), sizeof(c_short)) class X(Structure): _fields_ = [("a", c_short, 1), ("a1", c_short), ("b", c_short, 14), ("c", c_short, 1)] self.failUnlessEqual(sizeof(X), sizeof(c_short)*3) self.failUnlessEqual(X.a.offset, 0) self.failUnlessEqual(X.a1.offset, sizeof(c_short)) self.failUnlessEqual(X.b.offset, sizeof(c_short)*2) self.failUnlessEqual(X.c.offset, sizeof(c_short)*2) class X(Structure): _fields_ = [("a", c_short, 3), ("b", c_short, 14), ("c", c_short, 14)] self.failUnlessEqual(sizeof(X), sizeof(c_short)*3) self.failUnlessEqual(X.a.offset, sizeof(c_short)*0) self.failUnlessEqual(X.b.offset, sizeof(c_short)*1) self.failUnlessEqual(X.c.offset, sizeof(c_short)*2) def get_except(self, func, *args, **kw): try: func(*args, **kw) except Exception, detail: return detail.__class__, str(detail) if __name__ == "__main__": unittest.main() |
From: Thomas H. <th...@us...> - 2004-09-21 17:01:25
|
Update of /cvsroot/ctypes/ctypes/source In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv2098 Modified Files: stgdict.c ctypes.h cfield.c _ctypes_test.c _ctypes.c Log Message: Add support for bit fields in structures, plus unit tests. Index: ctypes.h =================================================================== RCS file: /cvsroot/ctypes/ctypes/source/ctypes.h,v retrieving revision 1.50 retrieving revision 1.51 diff -C2 -d -r1.50 -r1.51 *** ctypes.h 16 Sep 2004 14:17:11 -0000 1.50 --- ctypes.h 21 Sep 2004 17:00:59 -0000 1.51 *************** *** 89,92 **** --- 89,93 ---- extern PyObject * CField_FromDesc(PyObject *desc, int index, + PyObject *prev_desc, int bitsize, int *pbitofs, int *psize, int *poffset, int *palign, int pack); Index: stgdict.c =================================================================== RCS file: /cvsroot/ctypes/ctypes/source/stgdict.c,v retrieving revision 1.12 retrieving revision 1.13 diff -C2 -d -r1.12 -r1.13 *** stgdict.c 9 Jun 2004 15:55:57 -0000 1.12 --- stgdict.c 21 Sep 2004 17:00:59 -0000 1.13 *************** *** 132,137 **** StgDictObject *stgdict; int len, offset, size, align, i; - int union_size, total_align; if (!typedict) --- 132,138 ---- StgDictObject *stgdict; int len, offset, size, align, i; int union_size, total_align; + PyObject *prev_desc = NULL; + int bitofs; if (!typedict) *************** *** 172,177 **** PyObject *prop; StgDictObject *dict; ! if (!pair || !PyArg_Parse(pair, "(OO)", &name, &desc)) { PyErr_SetString(PyExc_AttributeError, "'_fields_' must be a sequence of pairs"); --- 173,179 ---- PyObject *prop; StgDictObject *dict; + int bitsize = 0; ! if (!pair || !PyArg_ParseTuple(pair, "OO|i", &name, &desc, &bitsize)) { PyErr_SetString(PyExc_AttributeError, "'_fields_' must be a sequence of pairs"); *************** *** 182,187 **** --- 184,229 ---- if (dict) stgdict->ffi_type.elements[i] = &dict->ffi_type; + if (PyTuple_Size(pair) == 3) { /* bits specified */ + switch(dict->ffi_type.type) { + case FFI_TYPE_UINT8: + case FFI_TYPE_UINT16: + case FFI_TYPE_SINT32: + case FFI_TYPE_UINT32: + case FFI_TYPE_SINT64: + case FFI_TYPE_UINT64: + break; + + case FFI_TYPE_SINT8: + case FFI_TYPE_SINT16: + if (dict->getfunc != getentry("c")->getfunc + #ifdef HAVE_USABLE_WCHAR_T + && dict->getfunc != getentry("u")->getfunc + #endif + ) + break; + /* else fall through */ + default: + PyErr_Format(PyExc_TypeError, + "bit fields not allowed for type %s", + ((PyTypeObject *)desc)->tp_name); + 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(pair); + return NULL; + } + } else + bitsize = 0; + /* + #ifdef _DEBUG + _asm int 3; + #endif + */ if (isStruct) { prop = CField_FromDesc(desc, i, + prev_desc, bitsize, &bitofs, &size, &offset, &align, pack); } else /* union */ { *************** *** 190,193 **** --- 232,236 ---- align = 0; prop = CField_FromDesc(desc, i, + prev_desc, bitsize, &bitofs, &size, &offset, &align, pack); union_size = max(size, union_size); *************** *** 208,211 **** --- 251,255 ---- Py_DECREF(pair); Py_DECREF(prop); + prev_desc = desc; /* store, in case of continued bitfield */ } #undef realdict Index: cfield.c =================================================================== RCS file: /cvsroot/ctypes/ctypes/source/cfield.c,v retrieving revision 1.43 retrieving revision 1.44 diff -C2 -d -r1.43 -r1.44 *** cfield.c 16 Sep 2004 14:17:11 -0000 1.43 --- cfield.c 21 Sep 2004 17:01:13 -0000 1.44 *************** *** 21,25 **** } - /* * Expects the size, index and offset for the current field in *psize and --- 21,24 ---- *************** *** 28,33 **** --- 27,39 ---- * *palign, and returns a field desriptor for this field. */ + /* + * bitfields extension: + * bitsize != 0: this is a bit field. + * pbitofs points to the current bit offset, this will be updated. + * prev_desc points to the type of the previous bitfield, if any. + */ PyObject * CField_FromDesc(PyObject *desc, int index, + PyObject *prev_desc, int bitsize, int *pbitofs, int *psize, int *poffset, int *palign, int pack) { *************** *** 38,41 **** --- 44,51 ---- GETFUNC getfunc = NULL; StgDictObject *dict; + int fieldtype; + #define NO_BITFIELD 0 + #define CONT_BITFIELD 1 + #define NEW_BITFIELD 2 self = (CFieldObject *)PyObject_CallObject((PyObject *)&CField_Type, *************** *** 43,47 **** if (self == NULL) return NULL; - dict = PyType_stgdict(desc); if (!dict) { --- 53,56 ---- *************** *** 51,64 **** return NULL; } size = dict->size; - if (pack) - align = min(pack, dict->align); - else - align = dict->align; length = dict->length; proto = desc; /* Field descriptors for 'c_char * n' are be scpecial cased to ! return a Python string instead of an Array object instance... */ if (ArrayTypeObject_Check(proto)) { --- 60,85 ---- return NULL; } + if (bitsize /* this is a bitfield request */ + && prev_desc == desc /* basic types are same */ + && *pbitofs /* we have a bitfield open */ + && (*pbitofs + bitsize) <= (dict->size * 8)) { /* fits into the space */ + /* continue bit field */ + fieldtype = CONT_BITFIELD; + } else if (bitsize) { + /* start new bitfield */ + fieldtype = NEW_BITFIELD; + *pbitofs = 0; + } else { + /* not a bit field */ + fieldtype = NO_BITFIELD; + *pbitofs = 0; + } + size = dict->size; length = dict->length; proto = desc; /* Field descriptors for 'c_char * n' are be scpecial cased to ! return a Python string instead of an Array object instance... */ if (ArrayTypeObject_Check(proto)) { *************** *** 89,105 **** self->proto = proto; ! if (*poffset % align) { ! int delta = align - (*poffset % align); ! *psize += delta; ! *poffset += delta; ! } ! self->size = size; ! *psize += size; ! self->offset = *poffset; ! *poffset += size; ! *palign = align; return (PyObject *)self; --- 110,145 ---- self->proto = proto; ! switch (fieldtype) { ! case NEW_BITFIELD: ! self->size = (bitsize << 16) + *pbitofs; ! *pbitofs = bitsize; ! /* fall through */ ! case NO_BITFIELD: ! if (pack) ! align = min(pack, dict->align); ! else ! align = dict->align; ! if (*poffset % align) { ! int delta = align - (*poffset % align); ! *psize += delta; ! *poffset += delta; ! } ! if (bitsize == 0) ! self->size = size; ! *psize += size; ! self->offset = *poffset; ! *poffset += size; ! *palign = align; ! break; ! ! case CONT_BITFIELD: ! self->size = (bitsize << 16) + *pbitofs; ! self->offset = *poffset - size; /* poffset is already updated for the NEXT field */ ! *pbitofs += bitsize; ! break; ! } return (PyObject *)self; *************** *** 273,367 **** #endif ! static PyObject * ! d_set(void *ptr, PyObject *value, unsigned size) ! { ! double x; ! x = PyFloat_AsDouble(value); ! if (x == -1 && PyErr_Occurred()) { ! PyErr_Format(PyExc_TypeError, ! " float expected instead of %s instance", ! value->ob_type->tp_name); ! return NULL; ! } ! *(double *)ptr = x; ! Py_INCREF(Py_None); ! return Py_None; ! } ! static PyObject * ! d_get(void *ptr, unsigned size) ! { ! return PyFloat_FromDouble(*(double *)ptr); ! } static PyObject * ! f_set(void *ptr, PyObject *value, unsigned size) { ! float x; ! ! x = (float)PyFloat_AsDouble(value); ! if (x == -1 && PyErr_Occurred()) { ! PyErr_Format(PyExc_TypeError, ! " float expected instead of %s instance", ! value->ob_type->tp_name); return NULL; ! } ! *(float *)ptr = x; Py_INCREF(Py_None); return Py_None; } static PyObject * ! f_get(void *ptr, unsigned size) { ! return PyFloat_FromDouble(*(float *)ptr); } - #ifdef HAVE_LONG_LONG static PyObject * ! Q_set(void *ptr, PyObject *value, unsigned size) { ! unsigned PY_LONG_LONG x; ! if (get_ulonglong(value, &x) < 0) return NULL; ! *(unsigned PY_LONG_LONG *)ptr = x; Py_INCREF(Py_None); return Py_None; } static PyObject * ! Q_get(void *ptr, unsigned size) { ! return PyLong_FromUnsignedLongLong(*(unsigned PY_LONG_LONG *)ptr); } static PyObject * ! q_set(void *ptr, PyObject *value, unsigned size) { ! PY_LONG_LONG x; ! if (get_longlong(value, &x) < 0) return NULL; ! *(PY_LONG_LONG *)ptr = x; Py_INCREF(Py_None); return Py_None; } static PyObject * ! q_get(void *ptr, unsigned size) { ! return PyLong_FromLongLong(*(PY_LONG_LONG *)ptr); } - #endif - static PyObject * ! i_set(void *ptr, PyObject *value, unsigned size) { ! long x; ! if (get_long(value, &x) < 0) return NULL; ! *(int *)ptr = (int)x; Py_INCREF(Py_None); return Py_None; --- 313,409 ---- #endif + /***************************************************************** + * Integer fields, with bitfield support + */ ! /* how to decode the size field, for integer get/set functions */ ! #define LOW_BIT(x) ((x) & 0xFFFF) ! #define NUM_BITS(x) ((x) >> 16) ! #define BIT_MASK(size) ((1 << NUM_BITS(size))-1) ! #define GET_BITFIELD(v, size) \ ! if (NUM_BITS(size)) { \ ! v <<= (sizeof(v)*8 - LOW_BIT(size) - NUM_BITS(size)); \ ! v >>= (sizeof(v)*8 - NUM_BITS(size)); \ ! } ! #define SET(x, v, size) \ ! NUM_BITS(size) ? \ ! ( ( x & ~(BIT_MASK(size) << LOW_BIT(size)) ) | ( (v & BIT_MASK(size)) << LOW_BIT(size) ) ) \ ! : v ! ! /***************************************************************** ! * integer accessor methods, supporting bit fields ! */ static PyObject * ! b_set(void *ptr, PyObject *value, unsigned size) { ! long val; ! if (get_long(value, &val) < 0) return NULL; ! *(char *)ptr = (char)SET(*(char *)ptr, (char)val, size); Py_INCREF(Py_None); return Py_None; } + static PyObject * ! b_get(void *ptr, unsigned size) { ! char val = *(char *)ptr; ! GET_BITFIELD(val, size); ! return PyInt_FromLong(val); } static PyObject * ! B_set(void *ptr, PyObject *value, unsigned size) { ! unsigned long val; ! if (get_ulong(value, &val) < 0) return NULL; ! *(unsigned char *)ptr = (unsigned char)SET(*(unsigned char*)ptr, ! (unsigned short)val, size); Py_INCREF(Py_None); return Py_None; } + static PyObject * ! B_get(void *ptr, unsigned size) { ! unsigned char val = *(unsigned char *)ptr; ! GET_BITFIELD(val, size); ! return PyInt_FromLong(val); } static PyObject * ! h_set(void *ptr, PyObject *value, unsigned size) { ! long val; ! if (get_long(value, &val) < 0) return NULL; ! *(short *)ptr = (short)SET(*(short *)ptr, (short)val, size); Py_INCREF(Py_None); return Py_None; } + static PyObject * ! h_get(void *ptr, unsigned size) { ! short val = *(short *)ptr; ! GET_BITFIELD(val, size); ! return PyInt_FromLong(val); } static PyObject * ! H_set(void *ptr, PyObject *value, unsigned size) { ! unsigned long val; ! if (get_ulong(value, &val) < 0) return NULL; ! *(unsigned short *)ptr = (unsigned short)SET(*(unsigned short *)ptr, ! (unsigned short)val, size); Py_INCREF(Py_None); return Py_None; *************** *** 370,392 **** static PyObject * ! O_get(void *ptr, unsigned size) { ! PyObject *ob = *(PyObject **)ptr; ! if (ob == NULL) { ! if (!PyErr_Occurred()) ! /* Set an error if not yet set */ ! PyErr_SetString(PyExc_ValueError, ! "PyObject is NULL?"); ! return NULL; ! } ! return ob; } static PyObject * ! O_set(void *ptr, PyObject *value, unsigned size) { ! *(PyObject **)ptr = value; ! Py_INCREF(value); ! return value; } --- 412,431 ---- static PyObject * ! H_get(void *ptr, unsigned size) { ! unsigned short val = *(short *)ptr; ! GET_BITFIELD(val, size); ! return PyInt_FromLong(val); } static PyObject * ! i_set(void *ptr, PyObject *value, unsigned size) { ! long val; ! if (get_long(value, &val) < 0) ! return NULL; ! *(int *)ptr = (int)SET(*(int *)ptr, (int)val, size); ! Py_INCREF(Py_None); ! return Py_None; } *************** *** 395,399 **** i_get(void *ptr, unsigned size) { ! return PyInt_FromLong(*(int *)ptr); } --- 434,440 ---- i_get(void *ptr, unsigned size) { ! int val = *(int *)ptr; ! GET_BITFIELD(val, size); ! return PyInt_FromLong(val); } *************** *** 404,408 **** if (get_ulong(value, &val) < 0) return NULL; ! *(unsigned int *)ptr = (unsigned int)val; Py_INCREF(Py_None); return Py_None; --- 445,449 ---- if (get_ulong(value, &val) < 0) return NULL; ! *(unsigned int *)ptr = (unsigned int)SET(*(unsigned int *)ptr, (unsigned int)val, size); Py_INCREF(Py_None); return Py_None; *************** *** 413,417 **** I_get(void *ptr, unsigned size) { ! return PyLong_FromUnsignedLong(*(unsigned int *)ptr); } --- 454,460 ---- I_get(void *ptr, unsigned size) { ! unsigned int val = *(unsigned int *)ptr; ! GET_BITFIELD(val, size); ! return PyLong_FromUnsignedLong(val); } *************** *** 419,426 **** l_set(void *ptr, PyObject *value, unsigned size) { ! long x; ! if (get_long(value, &x) < 0) return NULL; ! *(long *)ptr = x; Py_INCREF(Py_None); return Py_None; --- 462,469 ---- l_set(void *ptr, PyObject *value, unsigned size) { ! long val; ! if (get_long(value, &val) < 0) return NULL; ! *(long *)ptr = (long)SET(*(long *)ptr, val, size); Py_INCREF(Py_None); return Py_None; *************** *** 431,435 **** l_get(void *ptr, unsigned size) { ! return PyInt_FromLong(*(long *)ptr); } --- 474,480 ---- l_get(void *ptr, unsigned size) { ! long val = *(long *)ptr; ! GET_BITFIELD(val, size); ! return PyInt_FromLong(val); } *************** *** 440,444 **** if (get_ulong(value, &val) < 0) return NULL; ! *(unsigned long *)ptr = val; Py_INCREF(Py_None); return Py_None; --- 485,489 ---- if (get_ulong(value, &val) < 0) return NULL; ! *(unsigned long *)ptr = (unsigned long)SET(*(unsigned long *)ptr, val, size); Py_INCREF(Py_None); return Py_None; *************** *** 449,527 **** L_get(void *ptr, unsigned size) { ! return PyLong_FromUnsignedLong(*(unsigned long *)ptr); } static PyObject * ! h_set(void *ptr, PyObject *value, unsigned size) { ! long val; ! if (get_long(value, &val) < 0) return NULL; ! *(short *)ptr = (short)val; Py_INCREF(Py_None); return Py_None; } - static PyObject * ! h_get(void *ptr, unsigned size) { ! return PyInt_FromLong(*(short *)ptr); } static PyObject * ! H_set(void *ptr, PyObject *value, unsigned size) { ! unsigned long val; ! if (get_ulong(value, &val) < 0) return NULL; ! *(unsigned short *)ptr = (unsigned short)val; Py_INCREF(Py_None); return Py_None; } - static PyObject * ! H_get(void *ptr, unsigned size) { ! return PyInt_FromLong(*(unsigned short *)ptr); } static PyObject * ! b_set(void *ptr, PyObject *value, unsigned size) { ! long val; ! if (get_long(value, &val) < 0) return NULL; ! *(char *)ptr = (char)val; Py_INCREF(Py_None); return Py_None; } - static PyObject * ! b_get(void *ptr, unsigned size) { ! return PyInt_FromLong(*(char *)ptr); } static PyObject * ! B_set(void *ptr, PyObject *value, unsigned size) { ! unsigned long val; ! if (get_ulong(value, &val) < 0) return NULL; ! *(unsigned char *)ptr = (unsigned char)val; Py_INCREF(Py_None); return Py_None; } static PyObject * ! B_get(void *ptr, unsigned size) { ! return PyInt_FromLong(*(unsigned char *)ptr); } static PyObject * c_set(void *ptr, PyObject *value, unsigned size) --- 494,617 ---- L_get(void *ptr, unsigned size) { ! unsigned long val = *(unsigned long *)ptr; ! GET_BITFIELD(val, size); ! return PyLong_FromUnsignedLong(val); } + #ifdef HAVE_LONG_LONG static PyObject * ! q_set(void *ptr, PyObject *value, unsigned size) { ! PY_LONG_LONG val; ! if (get_longlong(value, &val) < 0) return NULL; ! *(PY_LONG_LONG *)ptr = (PY_LONG_LONG)SET(*(PY_LONG_LONG *)ptr, val, size); Py_INCREF(Py_None); return Py_None; } static PyObject * ! q_get(void *ptr, unsigned size) { ! PY_LONG_LONG val = *(PY_LONG_LONG *)ptr; ! GET_BITFIELD(val, size); ! return PyLong_FromLongLong(val); } static PyObject * ! Q_set(void *ptr, PyObject *value, unsigned size) { ! unsigned PY_LONG_LONG val; ! if (get_ulonglong(value, &val) < 0) 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; } static PyObject * ! Q_get(void *ptr, unsigned size) { ! unsigned PY_LONG_LONG val = *(unsigned PY_LONG_LONG *)ptr; ! GET_BITFIELD(val, size); ! return PyLong_FromUnsignedLongLong(val); } + #endif + + /***************************************************************** + * non-integer accessor methods, not supporting bit fields + */ + + static PyObject * ! d_set(void *ptr, PyObject *value, unsigned size) { ! double x; ! ! x = PyFloat_AsDouble(value); ! if (x == -1 && PyErr_Occurred()) { ! PyErr_Format(PyExc_TypeError, ! " float expected instead of %s instance", ! value->ob_type->tp_name); return NULL; ! } ! *(double *)ptr = x; Py_INCREF(Py_None); return Py_None; } static PyObject * ! d_get(void *ptr, unsigned size) { ! return PyFloat_FromDouble(*(double *)ptr); } static PyObject * ! f_set(void *ptr, PyObject *value, unsigned size) { ! float x; ! ! x = (float)PyFloat_AsDouble(value); ! if (x == -1 && PyErr_Occurred()) { ! PyErr_Format(PyExc_TypeError, ! " float expected instead of %s instance", ! value->ob_type->tp_name); return NULL; ! } ! *(float *)ptr = x; Py_INCREF(Py_None); return Py_None; } + static PyObject * + f_get(void *ptr, unsigned size) + { + return PyFloat_FromDouble(*(float *)ptr); + } static PyObject * ! O_get(void *ptr, unsigned size) { ! PyObject *ob = *(PyObject **)ptr; ! if (ob == NULL) { ! if (!PyErr_Occurred()) ! /* Set an error if not yet set */ ! PyErr_SetString(PyExc_ValueError, ! "PyObject is NULL?"); ! return NULL; ! } ! return ob; ! } ! ! static PyObject * ! O_set(void *ptr, PyObject *value, unsigned size) ! { ! *(PyObject **)ptr = value; ! Py_INCREF(value); ! return value; } + static PyObject * c_set(void *ptr, PyObject *value, unsigned size) Index: _ctypes.c =================================================================== RCS file: /cvsroot/ctypes/ctypes/source/_ctypes.c,v retrieving revision 1.159 retrieving revision 1.160 diff -C2 -d -r1.159 -r1.160 *** _ctypes.c 21 Sep 2004 14:16:34 -0000 1.159 --- _ctypes.c 21 Sep 2004 17:01:13 -0000 1.160 *************** *** 1837,1844 **** StgDictObject *dict; dict = PyType_stgdict(type); - if (dict) - assert(size == dict->size); if (dict && dict->getfunc) ! return dict->getfunc(adr, dict->size); return CData_FromBaseObj(type, src, index, adr); } --- 1837,1842 ---- StgDictObject *dict; dict = PyType_stgdict(type); if (dict && dict->getfunc) ! return dict->getfunc(adr, size); return CData_FromBaseObj(type, src, index, adr); } *************** *** 1861,1866 **** StgDictObject *dict = PyType_stgdict(type); if (dict && dict->setfunc) ! return dict->setfunc(ptr, value, ! dict->size); /* Or simply size? */ /* If value is a tuple, we try to call the type with the tuple --- 1859,1863 ---- StgDictObject *dict = PyType_stgdict(type); if (dict && dict->setfunc) ! return dict->setfunc(ptr, value, size); /* If value is a tuple, we try to call the type with the tuple Index: _ctypes_test.c =================================================================== RCS file: /cvsroot/ctypes/ctypes/source/_ctypes_test.c,v retrieving revision 1.26 retrieving revision 1.27 diff -C2 -d -r1.26 -r1.27 *** _ctypes_test.c 27 Aug 2004 18:41:21 -0000 1.26 --- _ctypes_test.c 21 Sep 2004 17:01:13 -0000 1.27 *************** *** 294,297 **** --- 294,342 ---- } + struct BITS { + int A: 1, B:2, C:3, D:4, E: 5, F: 6, G: 7, H: 8, I: 9; + short M: 1, N: 2, O: 3, P: 4, Q: 5, R: 6, S: 7; + }; + + DL_EXPORT(int) unpack_bitfields(struct BITS *bits, char name) + { + switch (name) { + case 'A': + return bits->A; + case 'B': + return bits->B; + case 'C': + return bits->C; + case 'D': + return bits->D; + case 'E': + return bits->E; + case 'F': + return bits->F; + case 'G': + return bits->G; + case 'H': + return bits->H; + case 'I': + return bits->I; + + case 'M': + return bits->M; + case 'N': + return bits->N; + case 'O': + return bits->O; + case 'P': + return bits->P; + case 'Q': + return bits->Q; + case 'R': + return bits->R; + case 'S': + return bits->S; + } + return 0; + } + PyMethodDef module_methods[] = { {"get_last_tf_arg_s", get_last_tf_arg_s, METH_NOARGS}, |
From: Thomas H. <th...@us...> - 2004-09-21 14:24:21
|
Update of /cvsroot/ctypes/ctypes/ctypes In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv1973 Modified Files: .CTYPES_DEVEL Log Message: Small hack to allow ctypes' __init__.py to be imported as module (needed for pychecker). Index: .CTYPES_DEVEL =================================================================== RCS file: /cvsroot/ctypes/ctypes/ctypes/.CTYPES_DEVEL,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** .CTYPES_DEVEL 1 Sep 2004 11:48:01 -0000 1.3 --- .CTYPES_DEVEL 21 Sep 2004 14:24:12 -0000 1.4 *************** *** 5,9 **** p = os.path.abspath( os.path.join(os.path.dirname(__file__), "..", sys.platform)) ! __path__.insert(0, p) from distutils.util import get_platform --- 5,12 ---- p = os.path.abspath( os.path.join(os.path.dirname(__file__), "..", sys.platform)) ! try: ! __path__.insert(0, p) ! except NameError: ! pass # when ctypes/__init__.py is imported *not* as package from distutils.util import get_platform |
From: Thomas H. <th...@us...> - 2004-09-21 14:22:41
|
Update of /cvsroot/ctypes/ctypes/ctypes In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv1496 Modified Files: __init__.py Log Message: Fix a typo, found by Jakub Piotr Clapa. Index: __init__.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/ctypes/__init__.py,v retrieving revision 1.36 retrieving revision 1.37 diff -C2 -d -r1.36 -r1.37 *** __init__.py 21 Sep 2004 14:16:24 -0000 1.36 --- __init__.py 21 Sep 2004 14:22:32 -0000 1.37 *************** *** 377,379 **** set_conversion_mode("mbcs", "ignore") else: ! set_coversion_mode("ascii", "strict") --- 377,379 ---- set_conversion_mode("mbcs", "ignore") else: ! set_conversion_mode("ascii", "strict") |
From: Thomas H. <th...@us...> - 2004-09-21 14:16:42
|
Update of /cvsroot/ctypes/ctypes/source In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv32537 Modified Files: _ctypes.c Log Message: Increased version number to 0.9.2. Index: _ctypes.c =================================================================== RCS file: /cvsroot/ctypes/ctypes/source/_ctypes.c,v retrieving revision 1.158 retrieving revision 1.159 diff -C2 -d -r1.158 -r1.159 *** _ctypes.c 16 Sep 2004 14:17:11 -0000 1.158 --- _ctypes.c 21 Sep 2004 14:16:34 -0000 1.159 *************** *** 3741,3745 **** PyModule_AddObject(m, "FUNCFLAG_CDECL", PyInt_FromLong(FUNCFLAG_CDECL)); PyModule_AddObject(m, "FUNCFLAG_PYTHONAPI", PyInt_FromLong(FUNCFLAG_PYTHONAPI)); ! PyModule_AddStringConstant(m, "__version__", "0.9.1"); PyExc_ArgError = PyErr_NewException("ctypes.ArgumentError", NULL, NULL); --- 3741,3745 ---- PyModule_AddObject(m, "FUNCFLAG_CDECL", PyInt_FromLong(FUNCFLAG_CDECL)); PyModule_AddObject(m, "FUNCFLAG_PYTHONAPI", PyInt_FromLong(FUNCFLAG_PYTHONAPI)); ! PyModule_AddStringConstant(m, "__version__", "0.9.2"); PyExc_ArgError = PyErr_NewException("ctypes.ArgumentError", NULL, NULL); |
From: Thomas H. <th...@us...> - 2004-09-21 14:16:33
|
Update of /cvsroot/ctypes/ctypes/ctypes In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv32513 Modified Files: __init__.py Log Message: Increased version number to 0.9.2. Index: __init__.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/ctypes/__init__.py,v retrieving revision 1.35 retrieving revision 1.36 diff -C2 -d -r1.35 -r1.36 *** __init__.py 16 Sep 2004 12:59:47 -0000 1.35 --- __init__.py 21 Sep 2004 14:16:24 -0000 1.36 *************** *** 9,13 **** del _magicfile ! __version__ = "0.9.1" from _ctypes import Union, Structure, Array --- 9,13 ---- del _magicfile ! __version__ = "0.9.2" from _ctypes import Union, Structure, Array |
From: Thomas H. <th...@us...> - 2004-09-21 14:16:24
|
Update of /cvsroot/ctypes/ctypes In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv32489 Modified Files: setup.py ChangeLog Log Message: Increased version number to 0.9.2. Index: setup.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/setup.py,v retrieving revision 1.103 retrieving revision 1.104 diff -C2 -d -r1.103 -r1.104 *** setup.py 27 Aug 2004 17:06:14 -0000 1.103 --- setup.py 21 Sep 2004 14:16:15 -0000 1.104 *************** *** 12,16 **** LIBFFI_SOURCES='source/gcc/libffi' ! __version__ = "0.9.1" ################################################################ --- 12,16 ---- LIBFFI_SOURCES='source/gcc/libffi' ! __version__ = "0.9.2" ################################################################ Index: ChangeLog =================================================================== RCS file: /cvsroot/ctypes/ctypes/ChangeLog,v retrieving revision 1.60 retrieving revision 1.61 diff -C2 -d -r1.60 -r1.61 *** ChangeLog 16 Sep 2004 19:55:31 -0000 1.60 --- ChangeLog 21 Sep 2004 14:16:15 -0000 1.61 *************** *** 1,2 **** --- 1,6 ---- + 2004-09-21 Thomas Heller <th...@py...> + + * (Message): Increased version number to 0.9.2. + 2004-09-16 Thomas Heller <th...@py...> |
From: Thomas H. <th...@us...> - 2004-09-17 17:59:30
|
Update of /cvsroot/ctypes/ctypes/sandbox/tools/constants In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv18131 Added Files: make_dump.py dump.h dummy.c Makefile .cvsignore Log Message: Forgot to check these in. --- NEW FILE: .cvsignore --- *.ilk *.pdb *.obj --- NEW FILE: dummy.c --- #include "includes.h" int main(int argc, char **argv) { return 0; } --- NEW FILE: Makefile --- all: constants.py constants.py: symbols.h make_dump.py dump.h make_dump.py symbols.h symbols.h: dummy.c gccxml -D _WIN32_WINNT=0x500 --gccxml-compiler msvc6 --preprocess -dM dummy.c >symbols.h --- NEW FILE: make_dump.py --- import os, sys, re pat = re.compile("^#define ([a-zA-Z0-9_]+) .+") PROG = r'''\ #include "dump.h" #include "includes.h" int main() { %s return 0; } ''' cmd = "cl /nologo /Zi -D _WIN32_WINNT=0x500 temp.cpp" try: os.remove("constants.py") except OSError, details: if details.errno != 2: raise # fakes - correspond to code in dump.h PY_HEADER = """\ def LPCSTR(x): return x def LPSTR(x): return x def GUID(x): return x """ open("constants.py", "w").write(PY_HEADER) try: data = open("skipped.txt", "r").read() except IOError, details: if details.errno != 2: raise data = "" skipped = data.splitlines() syms = [] for line in open(sys.argv[1]): match = pat.match(line) if match: symbol = match.group(1) if symbol in skipped: continue syms.append(symbol) syms.sort() CHUNKSIZE = len(syms) done = 0 while syms: skipped = [] while syms: now = syms[:CHUNKSIZE] syms = syms[CHUNKSIZE:] text = "\n".join([" DUMP(%s);" % s for s in now]) open("temp.cpp", "w").write(PROG % text) print "\t[%s .. %s]... " % (now[0], now[-1]), failed = os.system(cmd) if failed: print "failed" if not failed: os.system("temp.exe >> constants.py") print "%d ok" % len(now) done += len(now) print "%d done, %d remain" % (done, len(syms + skipped)) else: skipped.extend(now) if CHUNKSIZE > 512: CHUNKSIZE = 512 else: CHUNKSIZE /= 8 if CHUNKSIZE == 0: print "FAILED on %d symbols" % (len(syms) + len(skipped)) errfile = open("skipped.txt", "a+") for n in syms + skipped: errfile.write("%s\n" % n) sys.exit() print "try CHUNKSIZE", CHUNKSIZE syms = skipped --- NEW FILE: dump.h --- #include <comdef.h> #include <iostream.h> #include <stdio.h> /******************/ void dump(char *name, LPCSTR value) { int a = (int)(void *)value; if ((a & 0xFFFF0000) == 0) cout << name << " = " << "LPCSTR(" << a << ")" << endl; else cout << name << " = " << "r\"\"\"" << value << "\"\"\"" << endl; } void dump(char *name, LPCWSTR value) { bstr_t b = value; cout << name << " = " << "ur\"\"\"" << (char *)b << "\"\"\"" << endl; } void dump(char *name, LPSTR value) { int a = (int)(void *)value; if ((a & 0xFFFF0000) == 0) cout << name << " = " << "LPSTR(" << a << ")" << endl; else cout << name << " = " << "r\"\"\"" << value << "\"\"\"" << endl; } void dump(char *name, LPWSTR value) { bstr_t b = value; cout << name << " = " << "ur\"\"\"" << (char *)b << "\"\"\"" << endl; } /******************/ void dump(char *name, float value) { cout << name << " = " << value << endl; } void dump(char *name, double value) { cout << name << " = " << value << endl; } /******************/ void dump(char *name, __int8 value) { cout << name << " = " << value << endl; } void dump(char *name, unsigned __int8 value) { cout << name << " = " << value << endl; } void dump(char *name, __int16 value) { cout << name << " = " << value << endl; } void dump(char *name, unsigned __int16 value) { cout << name << " = " << value << endl; } void dump(char *name, __int32 value) { cout << name << " = " << (int) value << endl; } void dump(char *name, unsigned __int32 value) { cout << name << " = " << (unsigned int) value << endl; } void dump(char *name, __int64 value) { char buffer[32]; sprintf(buffer, "%I64d", value); cout << name << " = " << buffer << endl; } void dump(char *name, unsigned __int64 value) { char buffer[32]; sprintf(buffer, "%I64u", value); cout << name << " = " << buffer << endl; } /******************/ void dump(char *name, char value) { cout << name << " = chr(" << (int)value << ")" << endl; } void dump(char *name, short int value) { cout << name << " = " << value << endl; } void dump(char *name, unsigned short int value) { cout << name << " = " << value << endl; } void dump(char *name, int value) { cout << name << " = " << value << endl; } void dump(char *name, unsigned int value) { cout << name << " = " << value << endl; } void dump(char *name, long value) { cout << name << " = " << value << endl; } void dump(char *name, unsigned long value) { cout << name << " = " << value << endl; } /******************/ void dump(char *name, HWND value) { cout << name << " = HWND(" << (int)value << ")" << endl; } /* is HKEY signed or unsigned? */ void dump(char *name, HKEY value) { cout << name << " = HKEY(" << (int)value << ")" << endl; } void dump(char *name, GUID value) { wchar_t guid[64]; bstr_t b; StringFromGUID2(value, guid, sizeof(guid)); b = guid; cout << name << " = GUID(\"" << (char *)b << ")\"" << endl; } void dump(char *name, void *value) { cout << name << " = VOIDP(" << value << ")" << endl; } //void * //HDDEDATA //CERT_INFO /****************** This catches all remaining cases - writes a comment to the output. XXX Unfortunately, it also catches enum, and I don't know enough C++ to avoid that... So maybe it's better to comment this all out... */ /* template < class T> void dump(char *name, T value) { cout << "# " << name << " = " << value << endl; } */ /******************/ #define DUMP(sym) dump(#sym, sym) |