ctypes-commit Mailing List for ctypes (Page 93)
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-09-10 21:34:17
|
Update of /cvsroot/ctypes/ctypes/sandbox/tools/structures In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv14874 Modified Files: genapi.py Log Message: First, pass the objects with resolved dependencies, then the unresolved. Improve commenting out the failed code - this can now be uncommented in the output file with XEmacs more easily. Index: genapi.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/sandbox/tools/structures/genapi.py,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** genapi.py 10 Sep 2004 11:15:36 -0000 1.4 --- genapi.py 10 Sep 2004 11:42:03 -0000 1.5 *************** *** 98,103 **** class CodeGenerator(gccxmltools.Visitor): ! def __init__(self, *args, **kw): ! super(CodeGenerator, self).__init__(*args, **kw) self._env = {} self.try_code(HEADER) --- 98,102 ---- class CodeGenerator(gccxmltools.Visitor): ! def __init__(self): self._env = {} self.try_code(HEADER) *************** *** 161,165 **** except Exception, details: print "# --- %s: %s ---" % (details.__class__.__name__, details) ! print "# " + "\n# ".join(text.splitlines()) else: print text --- 160,164 ---- except Exception, details: print "# --- %s: %s ---" % (details.__class__.__name__, details) ! print "##" + "\n##".join(text.splitlines()) else: print text *************** *** 199,211 **** p = DependencyResolver(result) ! result, remaining = p.run() ! cg = CodeGenerator(result) ! cg.go() ! for o in remaining: ! print "#", o ! ## cg = CodeGenerator(result + list(remaining)) ! ## cg.go() --- 198,214 ---- p = DependencyResolver(result) ! resolved, unresolved = p.run() ! ## cg = CodeGenerator(result) ! ## cg.go() ! ## for o in remaining: ! ## print "#", o ! cg = CodeGenerator() ! cg.go(resolved) ! print ! print "################################################################" ! print ! cg.go(unresolved) |
From: Thomas H. <th...@us...> - 2004-09-10 11:16:10
|
Update of /cvsroot/ctypes/ctypes/sandbox/tools/structures In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv9371 Modified Files: genapi.py Log Message: Fake IUnknown and IDispatch. Refactored code outputting somewhat. Index: genapi.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/sandbox/tools/structures/genapi.py,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** genapi.py 10 Sep 2004 09:48:53 -0000 1.3 --- genapi.py 10 Sep 2004 11:15:36 -0000 1.4 *************** *** 77,81 **** resolved.add(o) result.append(o) ! print "# resolved %d of %d -> %d" % (len(resolved), len(remaining), len(remaining) - len(resolved)) if not resolved: print "# %d unresolved deps" % len(remaining) --- 77,82 ---- resolved.add(o) result.append(o) ! print "# resolved %d of %d -> %d" % (len(resolved), len(remaining), ! len(remaining) - len(resolved)) if not resolved: print "# %d unresolved deps" % len(remaining) *************** *** 87,90 **** --- 88,99 ---- ################################################################ + HEADER = """\ + from ctypes import * + + IUnknown = c_void_p + IDispatch = c_void_p + IRecordInfo = c_void_p + """ + class CodeGenerator(gccxmltools.Visitor): *************** *** 92,96 **** super(CodeGenerator, self).__init__(*args, **kw) self._env = {} ! exec "from ctypes import *" in self._env def PointerType(self, ptr): --- 101,105 ---- super(CodeGenerator, self).__init__(*args, **kw) self._env = {} ! self.try_code(HEADER) def PointerType(self, ptr): *************** *** 101,107 **** code = ["class %s(c_int):" % enum.name] code += [" %s = %s" % pair for pair in enum.values] ! code = "\n".join(code) ! exec code in self._env ! print code def Typedef(self, td): --- 110,114 ---- code = ["class %s(c_int):" % enum.name] code += [" %s = %s" % pair for pair in enum.values] ! self.try_code(code) def Typedef(self, td): *************** *** 109,116 **** return code = "%s = %s" % (td.name, self.ctypes_name(td.typ)) ! if self.try_code(code): ! print code ! else: ! print "# failed", code def Structure(self, struct): --- 116,120 ---- return code = "%s = %s" % (td.name, self.ctypes_name(td.typ)) ! self.try_code(code) def Structure(self, struct): *************** *** 118,125 **** if struct.name.startswith("$_"): return ! if self.try_code("\n".join(code)): ! print "\n".join(code) ! else: ! print "# failed " + "\n# ".join(code) Union = Structure --- 122,126 ---- if struct.name.startswith("$_"): return ! self.try_code(code) Union = Structure *************** *** 152,160 **** def try_code(self, code): # code it either a string or a sequence of strings try: ! exec code in self._env ! except Exception: ! return False ! return True def ctypes_name(self, obj): --- 153,167 ---- def try_code(self, code): # code it either a string or a sequence of strings + if isinstance(code, (str, unicode)): + text = code + else: + text = "\n".join(code) try: ! exec text in self._env ! except Exception, details: ! print "# --- %s: %s ---" % (details.__class__.__name__, details) ! print "# " + "\n# ".join(text.splitlines()) ! else: ! print text def ctypes_name(self, obj): *************** *** 173,177 **** assert obj.min == 0 return "%s * %d" % (self.ctypes_name(obj.typ), obj.max + 1) ! elif type(obj) in (gccxmltools.Typedef, gccxmltools.Enumeration, gccxmltools.Structure, gccxmltools.Union): name = obj.name if obj.name.startswith("$_"): --- 180,185 ---- assert obj.min == 0 return "%s * %d" % (self.ctypes_name(obj.typ), obj.max + 1) ! elif type(obj) in (gccxmltools.Typedef, gccxmltools.Enumeration, \ ! gccxmltools.Structure, gccxmltools.Union): name = obj.name if obj.name.startswith("$_"): *************** *** 193,199 **** result, remaining = p.run() - print "from ctypes import *" - print - cg = CodeGenerator(result) cg.go() --- 201,204 ---- *************** *** 201,202 **** --- 206,211 ---- for o in remaining: print "#", o + + ## cg = CodeGenerator(result + list(remaining)) + ## cg.go() + |
From: Thomas H. <th...@us...> - 2004-09-10 09:49:03
|
Update of /cvsroot/ctypes/ctypes/sandbox/tools/structures In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv24677 Modified Files: genapi.py Log Message: Works - although there are still bugs and limitations. Index: genapi.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/sandbox/tools/structures/genapi.py,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** genapi.py 10 Sep 2004 08:47:18 -0000 1.2 --- genapi.py 10 Sep 2004 09:48:53 -0000 1.3 *************** *** 1,2 **** --- 1,17 ---- + # Create ctypes python wrapper for everything in windows.h. + # '#define' preprocessor statements are *not* handled - this will be a + # separate effort. + # + # Bugs: + # Structure packing is wrong (gccxml doesn't handle the #pragma statements) + # + # COM interfaces are not included, so structures and unions containing + # pointers to COM interfaces will not be generated (VARIANT, for example) + # + # enums are generated as subclasses of c_int, with the enum values as + # class variables. This should probably change. + # + # Unnamed structure fields will probably not work correctly. + # import gccxmltools from sets import Set *************** *** 79,82 **** --- 94,100 ---- exec "from ctypes import *" in self._env + def PointerType(self, ptr): + pass + def Enumeration(self, enum): # generate the ctypes code for an enumeration. *************** *** 91,115 **** return code = "%s = %s" % (td.name, self.ctypes_name(td.typ)) ! try: ! exec code in self._env ! except Exception: ! print "#", code ! else: print code def Structure(self, struct): if struct.name.startswith("$_"): return ! code = ["class %s(Structure):" % struct.name] ! code += [" _fields_ = []"] ! try: ! exec "\n".join(code) in self._env ! except Exception: ! print "#", code[0] ! else: print "\n".join(code) Union = Structure def ctypes_name(self, obj): if type(obj) is gccxmltools.FundamentalType: --- 109,161 ---- return code = "%s = %s" % (td.name, self.ctypes_name(td.typ)) ! if self.try_code(code): print code + else: + print "# failed", code def Structure(self, struct): + code = self.gen_structure(struct) if struct.name.startswith("$_"): return ! if self.try_code("\n".join(code)): print "\n".join(code) + else: + print "# failed " + "\n# ".join(code) Union = Structure + def gen_structure(self, struct, indent=""): + # create inner classes + base = struct.__class__.__name__ + inner = [] + name = struct.name + if name.startswith("$_"): + name = "_inner_" + name[2:] + for field in struct.members: + if type(field.typ) in (gccxmltools.Structure, gccxmltools.Union) \ + and field.typ.name.startswith("$_"): + inner.append(field.typ) + code = [indent + "class %s(%s):" % (name, base)] + for i in inner: + code += self.gen_structure(i, indent = indent + " ") + code += [indent + " _fields_ = ["] + code += [indent + " ('%s', %s)," % self.gen_member(f) for f in struct.members] + code += [indent + " ]"] + return code + + def gen_member(self, field): + name = field.name + if name.startswith("$_"): + name = "_inner_" + name[2:] + return name, self.ctypes_name(field.typ) + + def try_code(self, code): + # code it either a string or a sequence of strings + try: + exec code in self._env + except Exception: + return False + return True + def ctypes_name(self, obj): if type(obj) is gccxmltools.FundamentalType: *************** *** 128,132 **** return "%s * %d" % (self.ctypes_name(obj.typ), obj.max + 1) elif type(obj) in (gccxmltools.Typedef, gccxmltools.Enumeration, gccxmltools.Structure, gccxmltools.Union): ! return obj.name raise TypeError, type(obj) --- 174,181 ---- return "%s * %d" % (self.ctypes_name(obj.typ), obj.max + 1) elif type(obj) in (gccxmltools.Typedef, gccxmltools.Enumeration, gccxmltools.Structure, gccxmltools.Union): ! name = obj.name ! if obj.name.startswith("$_"): ! name = "_inner_" + name[2:] ! return name raise TypeError, type(obj) *************** *** 136,141 **** import sys if len(sys.argv) == 1: ! sys.argv.extend("-D NONAMELESSUNION -D _WIN32_WINNT=0x500 -c msvc6 -o- windef.h".split()) ! ## sys.argv.extend("-D NONAMELESSUNION -D _WIN32_WINNT=0x500 -c msvc6 -o- windows.h".split()) result = gccxmltools.main() --- 185,190 ---- import sys if len(sys.argv) == 1: ! ## sys.argv.extend("-D NONAMELESSUNION -D _WIN32_WINNT=0x500 -c msvc6 -o- windef.h".split()) ! sys.argv.extend("-D NONAMELESSUNION -D _WIN32_WINNT=0x500 -c msvc6 -o- windows.h".split()) result = gccxmltools.main() |
From: Thomas H. <th...@us...> - 2004-09-10 09:36:55
|
Update of /cvsroot/ctypes/ctypes/sandbox/tools/structures In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv22209 Modified Files: gccxmltools.py Log Message: No warnings. Index: gccxmltools.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/sandbox/tools/structures/gccxmltools.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** gccxmltools.py 10 Sep 2004 07:43:21 -0000 1.1 --- gccxmltools.py 10 Sep 2004 09:36:46 -0000 1.2 *************** *** 280,286 **** if _id is not None: self.all[_id] = result ! else: ! import warnings ! warnings.warn(name, Warning) if name in self.has_values: self.context.append(result) --- 280,286 ---- if _id is not None: self.all[_id] = result ! ## else: ! ## import warnings ! ## warnings.warn(name, Warning) if name in self.has_values: self.context.append(result) *************** *** 399,402 **** --- 399,405 ---- if mth is not None: mth(obj) + ## else: + ## import warnings + ## warnings.warn(type(obj), Warning) def go(self): |
From: Thomas H. <th...@us...> - 2004-09-09 11:41:39
|
Update of /cvsroot/ctypes/ctypes/sandbox/tools/structures In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv25940 Modified Files: resolve.py Log Message: Fixes, and support bit fields. Index: resolve.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/sandbox/tools/structures/resolve.py,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** resolve.py 8 Sep 2004 19:32:15 -0000 1.3 --- resolve.py 9 Sep 2004 11:41:27 -0000 1.4 *************** *** 165,169 **** class FundamentalType(object): def __init__(self, name): ! self.name = ctypes_names[name] def resolve(self, find_typ): --- 165,169 ---- class FundamentalType(object): def __init__(self, name): ! self.name = name def resolve(self, find_typ): *************** *** 173,179 **** --- 173,186 ---- return "FundamentalType(%s)" % self.name + def as_ctype(self): + return ctypes_names[self.name] + class Enumeration(object): def __init__(self, name): self.name = name + self.values = [] + + def add_value(self, name, value): + self.values.append((name, value)) def resolve(self, find_typ): *************** *** 183,186 **** --- 190,197 ---- return "Enumeration(%s)" % self.name + def as_ctype(self): + ## return "enum(%s)" % self.name + return "C_INT" # fixme (or not?) + class TypeContainer(object): typ = None *************** *** 199,202 **** --- 210,220 ---- return "PointerType(%s)" % self.typ + def as_ctype(self): + # fixme: special case POINTER(FUNCTION) + # fixme: special case POINTER(void) + if type(self.typ) is FunctionType: + return self.typ.as_ctype() + return "POINTER(%s)" % self.typ.as_ctype() + class Typedef(TypeContainer): def __init__(self, name, typ): *************** *** 204,214 **** self._typ = typ def __repr__(self): return "Typedef(%s -> %s)" % (self.name, self.typ) class Field(TypeContainer): ! def __init__(self, name, typ): self.name = name self._typ = typ def __repr__(self): --- 222,236 ---- self._typ = typ + def as_ctype(self): + return self.name + def __repr__(self): return "Typedef(%s -> %s)" % (self.name, self.typ) class Field(TypeContainer): ! def __init__(self, name, typ, bits=None): self.name = name self._typ = typ + self.bits = bits def __repr__(self): *************** *** 222,226 **** self.max = -1 elif max == "ffffffffffffffff": ! self.max = 0xFFFFFFFFFFFFFFFF else: self.max = int(max) --- 244,248 ---- self.max = -1 elif max == "ffffffffffffffff": ! self.max = -99 ##0xFFFFFFFFFFFFFFFF else: self.max = int(max) *************** *** 229,232 **** --- 251,257 ---- return "Array(%s[%s:%s])" % (self.typ, self.min, self.max) + def as_ctype(self): + return "%s * %s" % (self.typ.as_ctype(), self.max+1) + class CvQualifiedType(TypeContainer): def __init__(self, typ, const): *************** *** 237,240 **** --- 262,268 ---- return "ConstQualifier(%s)" % (self.typ) + def as_ctype(self): + return "CONST(%s)" % self.typ.as_ctype() + class Union(object): members = None *************** *** 251,255 **** f = find_typ(id) f.resolve(find_typ) ! if isinstance(f, (Field, Method)): self.members.append(f) --- 279,283 ---- f = find_typ(id) f.resolve(find_typ) ! if type(f) in (Field, Method): self.members.append(f) *************** *** 257,260 **** --- 285,294 ---- return "Union(%s)" % self.name + def as_ctype(self): + name = self.name + if name.startswith("$_"): + name = "__internal_" + name[2:] + return name + class Structure(Union): bases = None *************** *** 293,296 **** --- 327,339 ---- return False + def __repr__(self): + return "Structure(%s)" % self.name + + def as_ctype(self): + name = self.name + if name.startswith("$_"): + name = "__internal_" + name[2:] + return name + class Constructor(object): def resolve(self, find_typ): *************** *** 314,322 **** class FunctionType(object): def __repr__(self): ! return "FUNCTYPE()" def resolve(self, find_typ): return class Function(object): returns = None --- 357,368 ---- class FunctionType(object): def __repr__(self): ! return "FUNCTYPE(fixme)" def resolve(self, find_typ): return + def as_ctype(self): + return "FUNCTYPE(fixme)" + class Function(object): returns = None *************** *** 335,339 **** class Enum_Handler(GCCXML_Handler_Base): ! ## has_values = Set("Structure") def __init__(self, *args): --- 381,386 ---- class Enum_Handler(GCCXML_Handler_Base): ! has_values = Set(["Enumeration"]) ! typedefs = {} def __init__(self, *args): *************** *** 346,350 **** name = attrs["name"] typ = attrs["type"] ! self.all[id] = Field(name, typ) def Constructor(self, attrs): --- 393,398 ---- name = attrs["name"] typ = attrs["type"] ! bits = attrs.get("bits", None) ! self.all[id] = Field(name, typ, bits) def Constructor(self, attrs): *************** *** 356,360 **** name = attrs["name"] typ = attrs["type"] ! self.all[id] = Typedef(name, typ) def FundamentalType(self, attrs): --- 404,410 ---- name = attrs["name"] typ = attrs["type"] ! td = Typedef(name, typ) ! self.typedefs[name] = td ! self.all[id] = td def FundamentalType(self, attrs): *************** *** 388,392 **** id = attrs["id"] name = attrs["name"] ! self.all[id] = Enumeration(name) def Struct(self, attrs): --- 438,444 ---- id = attrs["id"] name = attrs["name"] ! e = Enumeration(name) ! self.all[id] = e ! self.context[-1] = e def Struct(self, attrs): *************** *** 435,439 **** def EnumValue(self, attrs): ! pass # OperatorFunction --- 487,493 ---- def EnumValue(self, attrs): ! name = attrs["name"] ! value = attrs["init"] ! self.context[-1].add_value(name, value) # OperatorFunction *************** *** 444,447 **** --- 498,511 ---- ################################################################ + def dump_enums(handler): + for t in handler.all.values(): + if type(t) is Enumeration: + import pprint + print t.name + pprint.pprint(t.values) + print + + ################################################################ + def main(args=None): if args is None: *************** *** 484,523 **** from pprint import pprint as pp - - ## pp(handler.all) - - ## raise SystemExit() - - ## print def find_typ(id): return handler.all[id] - print "#include <windows.h>" - print "#include <stdio.h>" - print "int main(int argc, char **argv) {" - for item in handler.all.values(): item.resolve(find_typ) for obj in handler.all.values(): ! if isinstance(obj, Typedef): ! if type(obj.typ) is Enumeration: ! print obj ! continue ! if isinstance(obj, Typedef): ! ## obj.resolve(find_typ) ! ## obj.typ.resolve(find_typ) ! if type(obj.typ) is Structure and not obj.typ.isClass(): ! ## print ' printf("sizeof(%s) = %%d\\n", sizeof(%s));' % (obj.name, obj.name) ! print obj, len(obj.typ.members) ! elif type(obj.typ) is Union: ! ## print ' printf("sizeof(%s) = %%d\\n", sizeof(%s));' % (obj.name, obj.name) ! print obj, len(obj.typ.members) ! print "}" if __name__ == "__main__": if len(sys.argv) == 1: ! ## sys.argv.extend("-D NONAMELESSUNION -I. -D _WIN32_WINNT=0x500 -c msvc71 -o- test.h".split()) ! sys.argv.extend("-D NONAMELESSUNION -I. -D _WIN32_WINNT=0x500 -c msvc6 -o- windows.h".split()) main() --- 548,605 ---- from pprint import pprint as pp def find_typ(id): return handler.all[id] for item in handler.all.values(): item.resolve(find_typ) + if 0: + dump_enums(handler) + sys.exit() + else: + pass + + # Structures and Unions + compounds = {} + for obj in handler.all.values(): ! if type(obj) is Structure and not obj.isClass(): ! compounds[obj.name] = obj ! elif type(obj) is Union: ! compounds[obj.name] = obj ! print "from ctypes import *" ! print ! ! s_names = compounds.keys() ! s_names.sort() ! ## for n in s_names: ! ## print "class %s(c_int):" % n ! ## print " pass" ! ## print ! ! for n in s_names: ! s = compounds[n] ! print "class %s(c_int):" % n ! for m in s.members: ! assert type(m) is Field ! ## assert not m.bits, (m.name, m.typ.name, m.bits) ! if type(m.typ) in (Structure, Union): ! if m.typ.name.startswith("$_"): ! name = m.typ.name.replace("$_", "__internal_") ! print " class %s(c_int):" % name ! print " _fields_ = [" ! for mi in m.typ.members: ! print " ('%s', %s)" % (mi.name, mi.typ.as_ctype()) ! ## print "%s._fields_ = [" % n ! print " _fields_ = [" ! for m in s.members: ! print " ('%s', %s)," % (m.name, m.typ.as_ctype()) ! print " ]" ! print if __name__ == "__main__": if len(sys.argv) == 1: ! ## sys.argv.extend("-D NONAMELESSUNION -I. -D _WIN32_WINNT=0x500 -c msvc71 -o- windows.h richedit.h".split()) ! sys.argv.extend("-D NONAMELESSUNION -D _WIN32_WINNT=0x500 -c msvc6 -o- windows.h".split()) main() |
From: Thomas H. <th...@us...> - 2004-09-08 19:32:27
|
Update of /cvsroot/ctypes/ctypes/sandbox/tools/structures In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv32220 Modified Files: resolve.py Log Message: (Small) refactoring done. Index: resolve.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/sandbox/tools/structures/resolve.py,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** resolve.py 8 Sep 2004 16:55:31 -0000 1.2 --- resolve.py 8 Sep 2004 19:32:15 -0000 1.3 *************** *** 237,246 **** return "ConstQualifier(%s)" % (self.typ) ! class Structure(object): members = None ! def __init__(self, name, members, bases): self.name = name self._members = members - self._bases = bases def resolve(self, find_typ): --- 237,245 ---- return "ConstQualifier(%s)" % (self.typ) ! class Union(object): members = None ! def __init__(self, name, members): self.name = name self._members = members def resolve(self, find_typ): *************** *** 254,257 **** --- 253,272 ---- if isinstance(f, (Field, Method)): self.members.append(f) + + def __repr__(self): + return "Union(%s)" % self.name + + class Structure(Union): + bases = None + def __init__(self, name, members, bases): + self.name = name + self._members = members + self._bases = bases + + def resolve(self, find_typ): + super(Structure, self).resolve(find_typ) + if self.bases is not None: + return + self.bases = [] for id in self._bases.split(): *************** *** 278,300 **** return False - class Union(Structure): - def __init__(self, name, members): - self.name = name - self._members = members - - def resolve(self, find_typ): - if self.members is not None: - return - - self.members = [] - for id in self._members: - f = find_typ(id) - f.resolve(find_typ) - if isinstance(f, (Field, Method)): - self.members.append(f) - - def __repr__(self): - return "Union(%s)" % self.name - class Constructor(object): def resolve(self, find_typ): --- 293,296 ---- *************** *** 331,335 **** def resolve(self, find_typ): if self.returns is None: ! r = find_type(self._returns) self.returns = r r.resolve(find_typ) --- 327,331 ---- def resolve(self, find_typ): if self.returns is None: ! r = find_typ(self._returns) self.returns = r r.resolve(find_typ) *************** *** 497,519 **** return handler.all[id] for obj in handler.all.values(): - ## if isinstance(obj, (Structure, Union)): - ## print obj.name - ## obj.resolve(find_typ) - ## pp(obj.members) - ## print - ## continue if isinstance(obj, Typedef): ! obj.resolve(find_typ) ! if isinstance(obj.typ, (Structure, Union)) and not obj.typ.isClass(): print obj, len(obj.typ.members) - ## if isinstance(obj, Structure): - ## print obj.typ.bases - ## for f in obj.typ.members: - ## print " ", f - ## print ! ## pp(handler.all) ! ## print if __name__ == "__main__": --- 493,519 ---- return handler.all[id] + print "#include <windows.h>" + print "#include <stdio.h>" + print "int main(int argc, char **argv) {" + + for item in handler.all.values(): + item.resolve(find_typ) + for obj in handler.all.values(): if isinstance(obj, Typedef): ! if type(obj.typ) is Enumeration: ! print obj ! continue ! if isinstance(obj, Typedef): ! ## obj.resolve(find_typ) ! ## obj.typ.resolve(find_typ) ! if type(obj.typ) is Structure and not obj.typ.isClass(): ! ## print ' printf("sizeof(%s) = %%d\\n", sizeof(%s));' % (obj.name, obj.name) ! print obj, len(obj.typ.members) ! elif type(obj.typ) is Union: ! ## print ' printf("sizeof(%s) = %%d\\n", sizeof(%s));' % (obj.name, obj.name) print obj, len(obj.typ.members) ! print "}" if __name__ == "__main__": |
From: Thomas H. <th...@us...> - 2004-09-08 16:55:58
|
Update of /cvsroot/ctypes/ctypes/sandbox/tools/structures In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv1021 Modified Files: resolve.py Log Message: About to refactor. Index: resolve.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/sandbox/tools/structures/resolve.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** resolve.py 8 Sep 2004 06:30:20 -0000 1.1 --- resolve.py 8 Sep 2004 16:55:31 -0000 1.2 *************** *** 272,275 **** --- 272,281 ---- return "Structure(%s)" % self.name + def isClass(self): + for m in self.members: + if isinstance(m, Method): + return True + return False + class Union(Structure): def __init__(self, name, members): *************** *** 492,514 **** for obj in handler.all.values(): ! if isinstance(obj, (Structure, Union)): ! print obj.name obj.resolve(find_typ) ! pp(obj.members) ! print ! elif isinstance(obj, Typedef): ! if 1: ! ## try: ! obj.resolve(find_typ) ! ## except: ! ## pass ! ## else: ! if isinstance(obj.typ, (Structure, Union)): ! print obj ! if isinstance(obj, Structure): ! print obj.typ.bases ! for f in obj.typ.members: ! print " ", f ! print ## pp(handler.all) --- 498,516 ---- for obj in handler.all.values(): ! ## if isinstance(obj, (Structure, Union)): ! ## print obj.name ! ## obj.resolve(find_typ) ! ## pp(obj.members) ! ## print ! ## continue ! if isinstance(obj, Typedef): obj.resolve(find_typ) ! if isinstance(obj.typ, (Structure, Union)) and not obj.typ.isClass(): ! print obj, len(obj.typ.members) ! ## if isinstance(obj, Structure): ! ## print obj.typ.bases ! ## for f in obj.typ.members: ! ## print " ", f ! ## print ## pp(handler.all) |
From: Thomas H. <th...@us...> - 2004-09-08 06:30:29
|
Update of /cvsroot/ctypes/ctypes/sandbox/tools/structures In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv14584 Added Files: resolve.py Log Message: Parse the xml output of gccxml. --- NEW FILE: resolve.py --- """ Usage: gen_structs [options] files... Command line flags: -c <value>, --compiler <value> Specifies the compiler that GCCXML should emulate. For Windows, typically use msvc6 or msvc71. -D <symbol> -D <symbol=value> -U <symbol> -I <directory> These flags are passed to GCCXML. -o <filename> Write the parsing results to <filename>. Using '-' as filename will write the results to standard output. -v Increases the verbosity. Verbosity 1 prints out what the program is doing, verbosity 2 additionally prints lines it could not parse. -h Display help, then quit. Sample command line (depends on the MSVC compiler you have): gen_structs -D NONAMELESSUNION -D _WIN32_WINNT=0x500 -c msvc71 -o- windows.h """ import sys, os, tempfile from xml.sax import make_parser, parse, handler ################################################################ class CompilerError(Exception): pass # Create a C file containing #includes to the specified filenames. # Parse it with GCCXML into a XML file, and return the xml filename. def run_gccxml(options, verbose, *fnames): # options is a sequence of command line options for GCCXML # fnames is the sequence of include files # verbose - integer specifying the verbosity # returns the filename of the generated XML file options = " ".join(options) def read_stderr(fd): import threading def get_errout(fd): errs = fd.read() if errs: sys.stderr.write(errs) retval = fd.close() if retval: raise ParserError, "gccxml returned error %s" % retval thread = threading.Thread(target=get_errout, args=(fd,)) thread.start() return thread # write a temporary C file handle, c_file = tempfile.mkstemp(suffix=".c", text=True) os.write(handle, 'extern "C" {\n'); for fname in fnames: os.write(handle, '#include <%s>\n' % fname) os.write(handle, '}'); os.close(handle) ## handle, xml_file = tempfile.mkstemp(suffix=".xml", text=True) ## os.close(handle) xml_file = "~temp.xml" 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) ################################################################ ##ELEMENTS = ['Function', ## 'Typedef', ## 'Struct', ## 'Field', ## 'Union', ## 'CvQualifiedType', ## 'FundamentalType', ## 'Namespace', ## 'Argument', ## 'Enumeration', ## 'EnumValue', ## 'GCC_XML', ## 'Variable', ## 'ArrayType', ## 'File', ## 'Constructor', ## 'PointerType', ## 'Ellipsis', ## 'ReferenceType', ## 'FunctionType'] from sets import Set class GCCXML_Handler_Base(handler.ContentHandler): has_values = Set() def __init__(self, *args): handler.ContentHandler.__init__(self, *args) self.context = [] def startElement(self, name, attrs): if name in self.has_values: self.context.append(name) mth = getattr(self, name, None) if mth is not None: mth(attrs) else: import warnings warnings.warn(name, Warning) ## print "???", name def endElement(self, name): if name in self.has_values: self.context = self.context[:-1] ################################################################ ################ ctypes_names = { "short int": "c_short", "int": "c_int", "long int": "c_long", "long long int": "c_longlong", "short unsigned int": "c_ushort", "unsigned int": "c_uint", "long unsigned int": "c_ulong", "long long unsigned int": "c_ulonglong", "float": "c_float", "double": "c_double", "char": "c_char", "signed char": "c_byte", "unsigned char": "c_ubyte", "wchar_t": "c_wchar", "void": "void", # ? } class FundamentalType(object): def __init__(self, name): self.name = ctypes_names[name] def resolve(self, find_typ): return def __repr__(self): return "FundamentalType(%s)" % self.name class Enumeration(object): def __init__(self, name): self.name = name def resolve(self, find_typ): return def __repr__(self): return "Enumeration(%s)" % self.name class TypeContainer(object): typ = None def resolve(self, find_typ): if self.typ is not None: return self.typ = find_typ(self._typ) self.typ.resolve(find_typ) class PointerType(TypeContainer): def __init__(self, typ): self._typ = typ def __repr__(self): return "PointerType(%s)" % self.typ class Typedef(TypeContainer): def __init__(self, name, typ): self.name = name self._typ = typ def __repr__(self): return "Typedef(%s -> %s)" % (self.name, self.typ) class Field(TypeContainer): def __init__(self, name, typ): self.name = name self._typ = typ def __repr__(self): return "Field(%s -> %s)" % (self.name, self.typ) class ArrayType(TypeContainer): def __init__(self, typ, min, max): self._typ = typ self.min = int(min) if max == "": self.max = -1 elif max == "ffffffffffffffff": self.max = 0xFFFFFFFFFFFFFFFF else: self.max = int(max) def __repr__(self): return "Array(%s[%s:%s])" % (self.typ, self.min, self.max) class CvQualifiedType(TypeContainer): def __init__(self, typ, const): self._typ = typ self.const = const def __repr__(self): return "ConstQualifier(%s)" % (self.typ) class Structure(object): members = None def __init__(self, name, members, bases): self.name = name self._members = members self._bases = bases def resolve(self, find_typ): if self.members is not None: return self.members = [] for id in self._members: f = find_typ(id) f.resolve(find_typ) if isinstance(f, (Field, Method)): self.members.append(f) self.bases = [] for id in self._bases.split(): b = find_typ(id) b.resolve(find_typ) self.bases.append(b) def __repr__(self): if self.bases: for m in self.members: if isinstance(m, Method): return "Class(%s)(%s)" % (self.name, self.bases) return "Structure(%s)(%s)" % (self.name, self.bases) else: for m in self.members: if isinstance(m, Method): return "Class(%s)" % self.name return "Structure(%s)" % self.name class Union(Structure): def __init__(self, name, members): self.name = name self._members = members def resolve(self, find_typ): if self.members is not None: return self.members = [] for id in self._members: f = find_typ(id) f.resolve(find_typ) if isinstance(f, (Field, Method)): self.members.append(f) def __repr__(self): return "Union(%s)" % self.name class Constructor(object): def resolve(self, find_typ): return class Method(object): returns = None def __init__(self, name, returns): self.name = name self._returns = returns def resolve(self, find_typ): if self.returns is not None: return self.returns = find_typ(self._returns) self.returns.resolve(find_typ) def __repr__(self): return "Method(%s, %s)" % (self.name, self.returns) class FunctionType(object): def __repr__(self): return "FUNCTYPE()" def resolve(self, find_typ): return class Function(object): returns = None def __init__(self, name, returns, **kw): self.name = name self._returns = returns def resolve(self, find_typ): if self.returns is None: r = find_type(self._returns) self.returns = r r.resolve(find_typ) return ################ class Enum_Handler(GCCXML_Handler_Base): ## has_values = Set("Structure") def __init__(self, *args): GCCXML_Handler_Base.__init__(self, *args) self.all = {} def Field(self, attrs): # name, type id = attrs["id"] name = attrs["name"] typ = attrs["type"] self.all[id] = Field(name, typ) def Constructor(self, attrs): id = attrs["id"] self.all[id] = Constructor() def Typedef(self, attrs): id = attrs["id"] name = attrs["name"] typ = attrs["type"] self.all[id] = Typedef(name, typ) def FundamentalType(self, attrs): id = attrs["id"] name = attrs["name"] self.all[id] = FundamentalType(name) def PointerType(self, attrs): # id, type id = attrs["id"] typ = attrs["type"] self.all[id] = PointerType(typ) def CvQualifiedType(self, attrs): # id, type, [const|volatile] id = attrs["id"] typ = attrs["type"] ## const = attrs["const"] self.all[id] = CvQualifiedType(typ, "xxx") def ArrayType(self, attrs): # id, type, min?, max? id = attrs["id"] typ = attrs["type"] min = attrs["min"] max = attrs["max"] self.all[id] = ArrayType(typ, min, max) def Enumeration(self, attrs): # id, name id = attrs["id"] name = attrs["name"] self.all[id] = Enumeration(name) def Struct(self, attrs): # id, name, members id = attrs["id"] name = attrs["name"] bases = attrs.get("bases", "") members = attrs.get("members", "").split() self.all[id] = Structure(name, members, bases) def Union(self, attrs): # id, name, members id = attrs["id"] name = attrs["name"] self.all[id] = Union(name, attrs.get("members", "").split()) def Method(self, attrs): # id, name, virtual, pure_virtual, returns id = attrs["id"] name = attrs["name"] returns = attrs["returns"] self.all[id] = Method(name, returns) def FunctionType(self, attrs): # id, returns, attributes id = attrs["id"] self.all[id] = FunctionType() def Function(self, attrs): # id, name, returns, extern, attributes id = attrs["id"] name = attrs["name"] returns = attrs["returns"] self.all[id] = Function(name, returns) def Variable(self, attrs): # Variable <Variable id="_652" name="IID_StdOle" type="_3925c" # context="_1" location="f4:30" file="f4" line="30" extern="1"/> id = attrs["id"] name = attrs["name"] typ = attrs["type"] extern = attrs["extern"] def Argument(self, attrs): pass def EnumValue(self, attrs): pass # OperatorFunction # Ellipsis # ReferenceType # File ################################################################ 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:o:", ["compiler="]) except (getopt.GetoptError, ValueError): print >> sys.stderr, __doc__ return 1 py_file = None 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 elif o == "-o": py_file = a if not files: print "Error: no files to process" print >> sys.stderr, __doc__ return 1 xml_file = run_gccxml(gccxml_options, verbose, *files) handler = Enum_Handler() parse(xml_file, handler) ## os.remove(xml_file) from pprint import pprint as pp ## pp(handler.all) ## raise SystemExit() ## print def find_typ(id): return handler.all[id] for obj in handler.all.values(): if isinstance(obj, (Structure, Union)): print obj.name obj.resolve(find_typ) pp(obj.members) print elif isinstance(obj, Typedef): if 1: ## try: obj.resolve(find_typ) ## except: ## pass ## else: if isinstance(obj.typ, (Structure, Union)): print obj if isinstance(obj, Structure): print obj.typ.bases for f in obj.typ.members: print " ", f print ## pp(handler.all) ## print if __name__ == "__main__": if len(sys.argv) == 1: ## sys.argv.extend("-D NONAMELESSUNION -I. -D _WIN32_WINNT=0x500 -c msvc71 -o- test.h".split()) sys.argv.extend("-D NONAMELESSUNION -I. -D _WIN32_WINNT=0x500 -c msvc6 -o- windows.h".split()) main() |
From: Thomas H. <th...@us...> - 2004-09-07 09:48:15
|
Update of /cvsroot/ctypes/ctypes/sandbox/tools/structures In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv18324 Added Files: gen_structs.py Log Message: Generate a Python module defining the structures from <windows.h>. --- NEW FILE: gen_structs.py --- """ Usage: parse_structs [options] files... Command line flags: -c <value>, --compiler <value> Specifies the compiler that GCCXML should emulate. For Windows, typically use msvc6 or msvc71. -D <symbol> -D <symbol=value> -U <symbol> -I <directory> These flags are passed to GCCXML. -o <filename> Write the parsing results to <filename>. Using '-' as filename will write the results to standard output. -v Increases the verbosity. Verbosity 1 prints out what the program is doing, verbosity 2 additionally prints lines it could not parse. -h Display help, then quit. Sample command line (depends on the MSVC compiler you have): parse_structs -D _WIN32_WINNT=0x500 -c msvc71 -o- windows.h """ import sys, os, tempfile from xml.sax import make_parser, parse, handler ################################################################ class CompilerError(Exception): pass # Create a C file containing #includes to the specified filenames. # Parse it with GCCXML into a XML file, and return the xml filename. def run_gccxml(options, verbose, *fnames): # options is a sequence of command line options for GCCXML # fnames is the sequence of include files # verbose - integer specifying the verbosity # returns the filename of the generated XML file compiler = "" for o in options: if o.startswith("--gccxml-compiler"): compiler = o options = " ".join(options) def read_stderr(fd): import threading def get_errout(fd): errs = fd.read() if errs: sys.stderr.write(errs) retval = fd.close() if retval: raise ParserError, "gccxml returned error %s" % retval thread = threading.Thread(target=get_errout, args=(fd,)) thread.start() return thread # write a temporary C file handle, c_file = tempfile.mkstemp(suffix=".c", text=True) for fname in fnames: os.write(handle, '#include <%s>\n' % fname) os.close(handle) handle, xml_file = tempfile.mkstemp(suffix=".xml", text=True) os.close(handle) 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) ################################################################ ##ELEMENTS = ['Function', ## 'Typedef', ## 'Struct', ## 'Field', ## 'Union', ## 'CvQualifiedType', ## 'FundamentalType', ## 'Namespace', ## 'Argument', ## 'Enumeration', ## 'EnumValue', ## 'GCC_XML', ## 'Variable', ## 'ArrayType', ## 'File', ## 'Constructor', ## 'PointerType', ## 'Ellipsis', ## 'ReferenceType', ## 'FunctionType'] from sets import Set class GCCXML_Handler_Base(handler.ContentHandler): has_values = Set() def __init__(self, *args): handler.ContentHandler.__init__(self, *args) self.context = [] def startElement(self, name, attrs): if name in self.has_values: self.context.append(name) mth = getattr(self, name, None) if mth is not None: mth(attrs) ## else: ## print "???", name def endElement(self, name): if name in self.has_values: self.context = self.context[:-1] ################################################################ class Struct(object): # represents a Structure or Union def __init__(self, attrs): self.name = attrs["name"] self.members = attrs["members"].split() def dump(self, stream, handler): print >> stream, "class %s(Structure):" % self.name print >> stream, " _fields_ = [" for m in self.members: try: field = handler.fields[m] except KeyError: # not a Field, maybe a Constructor pass else: print >> stream, " (%s, %s)," % (field.name, field.type) print >> stream, " ]" print >> stream class StructField(object): def __init__(self, attrs, types): self.name = attrs["name"] self.attrs = attrs self.types = types def _get_type(self): id = self.attrs["type"] return self.types[id] type = property(fget=_get_type) ################ class Enum_Handler(GCCXML_Handler_Base): has_values = Set() def __init__(self, *args): GCCXML_Handler_Base.__init__(self, *args) self.structs = {} self.fields = {} self.typedefs = {} self.types = {} def Struct(self, attrs): self.types[attrs["id"]] = attrs["name"] try: attrs["members"] except: attrs["incomplete"] else: s = Struct(attrs) self.structs[attrs["id"]] = s def Union(self, attrs): print "UNION", attrs["name"] self.Struct(attrs) def Field(self, attrs): f = StructField(attrs, self.types) self.fields[attrs["id"]] = f def Typedef(self, attrs): self.types[attrs["id"]] = attrs["name"] def FundamentalType(self, attrs): self.types[attrs["id"]] = attrs["name"] def PointerType(self, attrs): self.types[attrs["id"]] = "POINTER" def ArrayType(self, attrs): self.types[attrs["id"]] = "ARRAY" def Enumeration(self, attrs): self.types[attrs["id"]] = attrs["name"] def Constructor(self, attrs): self.types[attrs["id"]] = attrs["name"] ################################################################ 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:o:", ["compiler="]) except (getopt.GetoptError, ValueError): print >> sys.stderr, __doc__ return 1 py_file = None 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 elif o == "-o": py_file = a if not files: print "Error: no files to process" print >> sys.stderr, __doc__ return 1 xml_file = run_gccxml(gccxml_options, verbose, *files) handler = Enum_Handler() parse(xml_file, handler) os.remove(xml_file) if py_file is None: return 0 if py_file == "-": ofi = sys.stdout else: ofi = open(py_file, "w") for struct in handler.structs.values(): struct.dump(ofi, handler) return 0 if __name__ == "__main__": sys.exit(main()) |
From: Thomas H. <th...@us...> - 2004-09-07 09:47:19
|
Update of /cvsroot/ctypes/ctypes/sandbox/tools/structures In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv18114/structures Log Message: Directory /cvsroot/ctypes/ctypes/sandbox/tools/structures added to the repository |
From: Thomas H. <th...@us...> - 2004-09-07 06:41:59
|
Update of /cvsroot/ctypes/ctypes/unittests In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv16294 Added Files: test_buffers.py Log Message: Tests for create_string_buffer() and create_unicode buffer(). --- NEW FILE: test_buffers.py --- from ctypes import * import unittest class StringBufferTestCase(unittest.TestCase): def test_buffer(self): b = create_string_buffer(32) self.failUnlessEqual(len(b), 32) self.failUnlessEqual(sizeof(b), 32 * sizeof(c_char)) self.failUnless(type(b[0]) is str) b = create_string_buffer("abc") self.failUnlessEqual(len(b), 4) # trailing nul char self.failUnlessEqual(sizeof(b), 4 * sizeof(c_char)) self.failUnless(type(b[0]) is str) self.failUnlessEqual(b[0], "a") self.failUnlessEqual(b[:], "abc\0") def test_string_conversion(self): b = create_string_buffer(u"abc") self.failUnlessEqual(len(b), 4) # trailing nul char self.failUnlessEqual(sizeof(b), 4 * sizeof(c_char)) self.failUnless(type(b[0]) is str) self.failUnlessEqual(b[0], "a") self.failUnlessEqual(b[:], "abc\0") try: c_wchar except NameError: pass else: def test_unicode_buffer(self): b = create_unicode_buffer(32) self.failUnlessEqual(len(b), 32) self.failUnlessEqual(sizeof(b), 32 * sizeof(c_wchar)) self.failUnless(type(b[0]) is unicode) b = create_unicode_buffer(u"abc") self.failUnlessEqual(len(b), 4) # trailing nul char self.failUnlessEqual(sizeof(b), 4 * sizeof(c_wchar)) self.failUnless(type(b[0]) is unicode) self.failUnlessEqual(b[0], u"a") self.failUnlessEqual(b[:], "abc\0") def test_unicode_conversion(self): b = create_unicode_buffer("abc") self.failUnlessEqual(len(b), 4) # trailing nul char self.failUnlessEqual(sizeof(b), 4 * sizeof(c_wchar)) self.failUnless(type(b[0]) is unicode) self.failUnlessEqual(b[0], u"a") self.failUnlessEqual(b[:], "abc\0") if __name__ == "__main__": unittest.main() |
From: Thomas H. <th...@us...> - 2004-09-07 06:40:12
|
Update of /cvsroot/ctypes/ctypes/win32/com In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv15917 Modified Files: ChangeLog Log Message: Record changes. Index: ChangeLog =================================================================== RCS file: /cvsroot/ctypes/ctypes/win32/com/ChangeLog,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -d -r1.7 -r1.8 *** ChangeLog 20 Aug 2004 15:33:41 -0000 1.7 --- ChangeLog 7 Sep 2004 06:39:52 -0000 1.8 *************** *** 1,2 **** --- 1,7 ---- + 2004-09-06 Thomas Heller <th...@py...> + + * (Message): Patch from Bruce Dodson to fix an infinite loop if a + typelib references types defined in another typelib. + 2004-08-20 Thomas Heller <th...@py...> |
From: Thomas H. <th...@us...> - 2004-09-07 06:39:55
|
Update of /cvsroot/ctypes/ctypes In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv15885 Modified Files: ChangeLog ANNOUNCE ACKS Log Message: Record changes. Index: ANNOUNCE =================================================================== RCS file: /cvsroot/ctypes/ctypes/ANNOUNCE,v retrieving revision 1.11 retrieving revision 1.12 diff -C2 -d -r1.11 -r1.12 *** ANNOUNCE 1 Sep 2004 12:45:36 -0000 1.11 --- ANNOUNCE 7 Sep 2004 06:39:43 -0000 1.12 *************** *** 28,31 **** --- 28,38 ---- ctypes changes + Fixed the create_unicode_buffer function - it was returning c_char + arrays instead of c_wchar arrays. + + Both create_string_buffer and create_unicode_buffer can now be + called with string and unicode instances, they will do the needed + conversions themselves. + ctypes now allows calling Python C api functions. The pythonapi symbol should be used to access these functions, this will *************** *** 67,70 **** --- 74,84 ---- ctypes.com changes + + Applied a patch from Bruce Dodson which fixes an infinite loop in + readtlb.py if a typelib references types defined in another + typelib. readtlb still generates bad code for such cases, but the + results could be edited by hand if the dependencies can be sorted + out. + ctypes now caches the types that WINFUNCTYPE and CFUNCTYPE creates, to avoid unneeeded creation of classes. This Index: ACKS =================================================================== RCS file: /cvsroot/ctypes/ctypes/ACKS,v retrieving revision 1.12 retrieving revision 1.13 diff -C2 -d -r1.12 -r1.13 *** ACKS 18 Jul 2003 20:10:05 -0000 1.12 --- ACKS 7 Sep 2004 06:39:43 -0000 1.13 *************** *** 16,19 **** --- 16,20 ---- Greg Chapman David Creemer + Bruce Dodson Chuck Esterbrook Mike Fletcher Index: ChangeLog =================================================================== RCS file: /cvsroot/ctypes/ctypes/ChangeLog,v retrieving revision 1.55 retrieving revision 1.56 diff -C2 -d -r1.55 -r1.56 *** ChangeLog 1 Sep 2004 12:45:35 -0000 1.55 --- ChangeLog 7 Sep 2004 06:39:43 -0000 1.56 *************** *** 1,2 **** --- 1,11 ---- + 2004-09-07 Thomas Heller <th...@py...> + + * (Message): Fix the create_unicode_buffer function - it was + returning c_char arrays instead of c_wchar arrays. + + Both create_string_buffer and create_unicode_buffer can now be + called with string and unicode instances, they will do the needed + conversions themselves. + 2004-09-01 Thomas Heller <th...@py...> |
From: Thomas H. <th...@us...> - 2004-09-07 06:37:46
|
Update of /cvsroot/ctypes/ctypes/ctypes In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv15543 Modified Files: __init__.py Log Message: Fix the create_unicode_buffer function - it was returning c_char arrays instead of c_wchar arrays. Both create_string_buffer and create_unicode_buffer can now be called with string and unicode instances, they will do the needed conversions themselves. Index: __init__.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/ctypes/__init__.py,v retrieving revision 1.31 retrieving revision 1.32 diff -C2 -d -r1.31 -r1.32 *** __init__.py 1 Sep 2004 11:55:05 -0000 1.31 --- __init__.py 7 Sep 2004 06:37:36 -0000 1.32 *************** *** 42,46 **** create_string_buffer(aString, anInteger) -> character array """ ! if isinstance(init, str): if size is None: size = len(init)+1 --- 42,47 ---- create_string_buffer(aString, anInteger) -> character array """ ! if isinstance(init, (str, unicode)): ! init = str(init) if size is None: size = len(init)+1 *************** *** 60,72 **** create_unicode_buffer(aString, anInteger) -> character array """ ! if isinstance(init, str): if size is None: size = len(init)+1 ! buftype = c_char * size buf = buftype() buf.value = init return buf elif isinstance(init, (int, long)): ! buftype = c_char * init buf = buftype() return buf --- 61,74 ---- create_unicode_buffer(aString, anInteger) -> character array """ ! if isinstance(init, (str, unicode)): ! init = unicode(init) if size is None: size = len(init)+1 ! buftype = c_wchar * size buf = buftype() buf.value = init return buf elif isinstance(init, (int, long)): ! buftype = c_wchar * init buf = buftype() return buf |
From: Thomas H. <th...@us...> - 2004-09-06 19:19:24
|
Update of /cvsroot/ctypes/ctypes/win32/com/tools In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv30914 Modified Files: readtlb.py Log Message: Patch by Bruce Dodson to fix an infinite loop if a typelib references types defined in another typelib. Thanks! Index: readtlb.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/win32/com/tools/readtlb.py,v retrieving revision 1.28 retrieving revision 1.29 diff -C2 -d -r1.28 -r1.29 *** readtlb.py 16 Jul 2004 16:02:06 -0000 1.28 --- readtlb.py 6 Sep 2004 19:19:07 -0000 1.29 *************** *** 740,754 **** if 1: done = ["IUnknown", "IDispatch", "dispinterface"] while interfaces: interfaces = [i for i in interfaces if i.name not in done] for itf in interfaces: for b in itf._uses: if b not in done: ! break ! else: print >> ofi print >> ofi, itf.declaration() done.append(itf.name) else: # We *try* to sort the interfaces so that dependencies are --- 740,771 ---- if 1: + itfnames = [i.name for i in interfaces] done = ["IUnknown", "IDispatch", "dispinterface"] + skipped = [] while interfaces: interfaces = [i for i in interfaces if i.name not in done] for itf in interfaces: + do_this = 1 for b in itf._uses: if b not in done: ! # Prevent an infinite loop if a required interface is not ! # defined here. The generated module will still need to ! # be edited by hand before it can be imported. ! if b in itfnames: ! do_this = 0 ! elif b not in skipped: ! skipped.append(b + '') ! ! if do_this: print >> ofi print >> ofi, itf.declaration() done.append(itf.name) + + if skipped: + print >> ofi + print >> ofi, "### Some base classes were not found." + print >> ofi, "### They must be imported by hand near the top of the file:" + for b in skipped: + print >> ofi, "### -", b else: # We *try* to sort the interfaces so that dependencies are *************** *** 785,788 **** --- 802,810 ---- print >> ofi print >> ofi, cls.declaration() + + # Warning: the coclasses may also reference interfaces defined elsewhere. + # These also need to be added by hand. It would be very nice to have it + # figure things out from the importlibs referenced in the typelib (looking + # in the same directory as the source typelib and also in the path). def main(): |
From: Thomas H. <th...@us...> - 2004-09-06 12:22:48
|
Update of /cvsroot/ctypes/ctypes/sandbox/tools/constants In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv19374/constants Log Message: Directory /cvsroot/ctypes/ctypes/sandbox/tools/constants added to the repository |
From: Thomas H. <th...@us...> - 2004-09-03 18:00:49
|
Update of /cvsroot/ctypes/ctypes/sandbox/tools In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv1130 Added Files: runme.py Log Message: A test script which creates a wincon.py file, and makes some comparisons with win32con.py. --- NEW FILE: runme.py --- # This is a test script, which uses both inc2py and parse_enums # to create constant definitions from windows.h to wincon.py. # # The output shows that inc2py plus parse_enums create 12556 symbols # not in win32con, and win32con has 71 symbols not in wincon. A rough # inspection shows that the 71 symbols are either not in the header # files I have, or they are C macros converted to Python functions # (sometimes correct, sometimes wrong) in win32con that the above # toolchain does not (yet?) create. # For the _WIN32_WINNT definition, see # http://msdn.microsoft.com/library/en-us/winprog/winprog/using_the_windows_headers.asp import os, sys from xml.sax import parse import inc2py import parse_enums files = ["windows.h", "richedit.h"] gccxml_options = ["--gccxml-compiler msvc71", "-D", "_WIN32_WINNT=0x500", ## "-D", "_WIN32_WINIE=0x600", ## "-D", "WINVER=0x500", "-D", "OEMRESOURCE"] verbose = 0 xml_file = parse_enums.run_gccxml(gccxml_options, verbose, *files) handler = parse_enums.Enum_Handler() parse(xml_file, handler) os.remove(xml_file) namespace = {} for enum in handler.enums.values(): for n, v in enum.values: namespace[n] = v parser = inc2py.IncludeParser(gccxml_options, verbose=verbose, env=namespace) parser.parse(*files) parser.write_symbols("wincon.py", False) ################################################################ import wincon import win32con from sets import Set a = Set(dir(wincon)) b = Set(dir(win32con)) ##print len(a) ##print len(b) print "wincon has %d symbols not in win32con" % len(a - b) print "win32con has %d symbols not in wincon" % len(b - a) ##sys.exit() common = list(a & b) common.sort() for name in common: v1 = getattr(win32con, name) v2 = getattr(wincon, name) if v1 != v2: print name, hex(v1), hex(v2) sys.exit() import pprint missing = list(b - a) missing.sort() for name in missing: value = getattr(win32con, name) print name, value |
From: Thomas H. <th...@us...> - 2004-09-03 17:15:06
|
Update of /cvsroot/ctypes/ctypes/sandbox/tools In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv25603 Added Files: parse_enums.py Log Message: A script to parse C header files, and spit out Python constant definitions for the enum values found. --- NEW FILE: parse_enums.py --- """ Usage: parse_enums [options] files... Command line flags: -c <value>, --compiler <value> Specifies the compiler that GCCXML should emulate. For Windows, typically use msvc6 or msvc71. -D <symbol> -D <symbol=value> -U <symbol> -I <directory> These flags are passed to GCCXML. -o <filename> Write the parsing results to <filename>. Using '-' as filename will write the results to standard output. -v Increases the verbosity. Verbosity 1 prints out what the program is doing, verbosity 2 additionally prints lines it could not parse. -h Display help, then quit. Sample command line (depends on the MSVC compiler you have): parse_enums -D _WIN32_WINNT=0x500 -c msvc71 -o- windows.h """ import sys, os, tempfile from xml.sax import make_parser, parse, handler ################################################################ class CompilerError(Exception): pass # Create a C file containing #includes to the specified filenames. # Parse it with GCCXML into a XML file, and return the xml filename. def run_gccxml(options, verbose, *fnames): # options is a sequence of command line options for GCCXML # fnames is the sequence of include files # verbose - integer specifying the verbosity # returns the filename of the generated XML file compiler = "" for o in options: if o.startswith("--gccxml-compiler"): compiler = o options = " ".join(options) def read_stderr(fd): import threading def get_errout(fd): errs = fd.read() if errs: sys.stderr.write(errs) retval = fd.close() if retval: raise ParserError, "gccxml returned error %s" % retval thread = threading.Thread(target=get_errout, args=(fd,)) thread.start() return thread # write a temporary C file handle, c_file = tempfile.mkstemp(suffix=".c", text=True) for fname in fnames: os.write(handle, '#include <%s>\n' % fname) os.close(handle) handle, xml_file = tempfile.mkstemp(suffix=".xml", text=True) os.close(handle) try: if verbose: print >> sys.stderr, r"run gccxml.exe %s --preprocess -dM" % compiler 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) ################################################################ ##ELEMENTS = ['Function', ## 'Typedef', ## 'Struct', ## 'Field', ## 'Union', ## 'CvQualifiedType', ## 'FundamentalType', ## 'Namespace', ## 'Argument', ## 'Enumeration', ## 'EnumValue', ## 'GCC_XML', ## 'Variable', ## 'ArrayType', ## 'File', ## 'Constructor', ## 'PointerType', ## 'Ellipsis', ## 'ReferenceType', ## 'FunctionType'] from sets import Set class GCCXML_Handler_Base(handler.ContentHandler): has_values = Set() def __init__(self, *args): handler.ContentHandler.__init__(self, *args) self.context = [] def startElement(self, name, attrs): if name in self.has_values: self.context.append(name) mth = getattr(self, name, None) if mth is not None: mth(attrs) def endElement(self, name): if name in self.has_values: self.context = self.context[:-1] ################################################################ class Enum(object): # represents an enumeration def __init__(self, attrs): self.name = attrs["name"] self.values = [] def add_value(self, attrs): self.values.append((attrs["name"], int(attrs["init"]))) def dump_as_class(self, stream): print >> stream, "class %s(object):" % self.name for name, value in self.values: print >> stream, " %s = %r" % (name, value) print >> stream def dump_as_constants(self, stream): for name, value in self.values: print >> stream, "%s = %r" % (name, value) ################ class Enum_Handler(GCCXML_Handler_Base): has_values = Set("Enumeration".split()) def __init__(self, *args): GCCXML_Handler_Base.__init__(self, *args) self.enums = {} self.typedefs = {} def Enumeration(self, attrs): e = Enum(attrs) self.context[-1] = e self.enums[attrs["id"]] = e def EnumValue(self, attrs): e = self.context[-1] e.add_value(attrs) def Typedef(self, attrs): self.typedefs[attrs["name"]] = attrs["type"] ################################################################ 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:o:", ["compiler="]) except (getopt.GetoptError, ValueError): print >> sys.stderr, __doc__ return 1 py_file = None 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 elif o == "-o": py_file = a if not files: print "Error: no files to process" print >> sys.stderr, __doc__ return 1 xml_file = run_gccxml(gccxml_options, verbose, *files) handler = Enum_Handler() parse(xml_file, handler) os.remove(xml_file) if py_file is None: return 0 if py_file == "-": ofi = sys.stdout else: ofi = open(py_file, "w") for enum in handler.enums.values(): ## enum.dump_as_class() enum.dump_as_constants(ofi) return 0 # do we have a use for typedefs? Not yet... for name, typ in handler.typedefs.items(): try: e = handler.enums[typ] except KeyError: pass else: print "%s = %s" % (name, e.name) print "del %s" % e.name return 0 if __name__ == "__main__": sys.exit(main()) |
From: Thomas H. <th...@us...> - 2004-09-03 16:47:58
|
Update of /cvsroot/ctypes/ctypes/sandbox/tools In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv20897 Modified Files: inc2py.py Log Message: Add some more ignore patterns, and be more careful when comiling them: remove all surrounding whitespace. Allow an environment passed to the IncludeParser. Add a -h command line flag. Index: inc2py.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/sandbox/tools/inc2py.py,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** inc2py.py 3 Sep 2004 14:38:12 -0000 1.6 --- inc2py.py 3 Sep 2004 16:47:48 -0000 1.7 *************** *** 68,71 **** --- 68,74 ---- not parse. + -h + Display help, and quit. + For a start (on windows), try this: *************** *** 84,89 **** # patterns to replace by a single blank (platform specific) if sys.platform == "win32": - # ignore type casts. Sounds strange, but works. ignores = r""" \(\s*HRESULT\s*\) --- 87,93 ---- # patterns to replace by a single blank (platform specific) + # ignore type casts. Sounds strange, but works. + if sys.platform == "win32": ignores = r""" \(\s*HRESULT\s*\) *************** *** 106,114 **** --- 110,122 ---- \(\s*HANDLE\s*\) \(\s*HWND\s*\) + \(\s*HKEY\s*\) \(\s*HCURSOR\s*\) + \(\s*HBITMAP\s*\) \(\s*HICON\s*\) \(\s*HDDEDATA\s*\) + \(\s*NTSTATUS\s*\) \(\s*int\s*\) \(\s*u_long\s*\) + \(\s*ULONG_PTR\s*\) \(\s*unsigned\s*long\s*\) """ *************** *** 116,120 **** ignores = [] ! ignores = map(re.compile, ignores.strip().splitlines()) # a sequence of pattern / replacement pairs for macro bodies, --- 124,128 ---- ignores = [] ! ignores = [re.compile(p.strip()) for p in ignores.strip().splitlines()] # a sequence of pattern / replacement pairs for macro bodies, *************** *** 204,209 **** class IncludeParser(object): ! def __init__(self, cpp_options=(), verbose=0): ! self._env = {} self._statements = [] self._errlines = [] --- 212,220 ---- class IncludeParser(object): ! def __init__(self, cpp_options=(), verbose=0, env=None): ! if env is None: ! self._env = {} ! else: ! self._env = env self._statements = [] self._errlines = [] *************** *** 331,338 **** raw = 0 try: ! opts, files = getopt.getopt(args, "rvc:D:U:I:o:", ["compiler="]) ! if not files: ! raise ValueError ! except (getopt.GetoptError, ValueError): print >> sys.stderr, __doc__ return 1 --- 342,348 ---- raw = 0 try: ! opts, files = getopt.getopt(args, "hrvc:D:U:I:o:", ["compiler="]) ! except (getopt.GetoptError, ValueError), details: ! print "Error:", details print >> sys.stderr, __doc__ return 1 *************** *** 348,352 **** --- 358,370 ---- elif o == "-r": raw = 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 + parser = IncludeParser(gccxml_options, verbose=verbose) parser.parse(*files) |
From: Thomas H. <th...@us...> - 2004-09-03 14:38:21
|
Update of /cvsroot/ctypes/ctypes/sandbox/tools In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv29202 Modified Files: inc2py.py Log Message: Add a sample command line. Fix a problem where unparsed lines were missing in the error output. Index: inc2py.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/sandbox/tools/inc2py.py,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** inc2py.py 3 Sep 2004 12:16:02 -0000 1.5 --- inc2py.py 3 Sep 2004 14:38:12 -0000 1.6 *************** *** 67,70 **** --- 67,74 ---- program is doing, verbosity 2 additionally prints lines it could not parse. + + For a start (on windows), try this: + + inc2py.py -D _WIN32_WINNT=0x500 -c msvc71 -o windows.py windows.h """ *************** *** 196,199 **** --- 200,204 ---- os.remove(c_file) + ################################################################ class IncludeParser(object): *************** *** 216,221 **** def parse(self, *files): ! self._parse(*files) self._env.pop("__builtins__", None) def _parse(self, *files): --- 221,230 ---- def parse(self, *files): ! remaining = self._parse(*files) self._env.pop("__builtins__", None) + # self._errlines are lines we do not know how to handle, and + # self.lines are the remaining lines where we know how to + # handle them but fail. + self._errlines = self._errlines + remaining def _parse(self, *files): *************** *** 240,243 **** --- 249,253 ---- print >> sys.stderr, "Parsing done." + return lines def create_statement(self, line): *************** *** 267,271 **** try: exec stmt in self._env ! except: pass else: --- 277,281 ---- try: exec stmt in self._env ! except Exception: pass else: |
From: Thomas H. <th...@us...> - 2004-09-03 12:42:17
|
Update of /cvsroot/ctypes/ctypes/sandbox/tools In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv10847 Added Files: .cvsignore Log Message: Ignore .pyc and .pyo --- NEW FILE: .cvsignore --- *.pyc *.pyo |
From: Thomas H. <th...@us...> - 2004-09-03 12:16:13
|
Update of /cvsroot/ctypes/ctypes/sandbox/tools In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv7636 Modified Files: inc2py.py Log Message: Add documentation and a command line interface. Convert C style L"xxxxx" into Python's u"xxxxx". Write diagnostic info (if -v or -vv is specified) to standard error. Index: inc2py.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/sandbox/tools/inc2py.py,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** inc2py.py 3 Sep 2004 10:05:21 -0000 1.4 --- inc2py.py 3 Sep 2004 12:16:02 -0000 1.5 *************** *** 30,33 **** --- 30,71 ---- # - turn C Boolean operators "&& || !" into Python "and or not" # - what to do about macros with multiple parameters? + """ + Usage: inc2py [options] files... + + This program parses C include files and converts #define statements + into Python code. It requires that the GCCXML C++ parser from + http://www.gccxml.org/ is installed and on the PATH. + + Command line flags: + + -c <value>, --compiler <value> + Specifies the compiler that GCCXML should emulate. For Windows, + typically use msvc6 or msvc71. + + -D <symbol> + -D <symbol=value> + -U <symbol> + -I <directory> + These flags are passed to GCCXML. + + -o <filename> + Write the parsing results to <filename>. Using '-' as filename + will write the results to standard output. + + -r + Create the output file in raw format - default is non-raw. + + In non-raw format, only constant values are written to the + output file, sorted by names. + + In raw format, the names are not sorted, C macros are included + as Python functions, and the last section of the file will + contain the #define directives that could not be parsed. + + -v + Increases the verbosity. Verbosity 1 prints out what the + program is doing, verbosity 2 additionally prints lines it could + not parse. + """ import sys, re, os, tempfile *************** *** 82,86 **** (re.compile(r"(\d+)U"), r"\1"), # Remove the U suffix from hex constants ! (re.compile(r"(0[xX][0-9a-fA-F]+)U"), r"\1") ] --- 120,126 ---- (re.compile(r"(\d+)U"), r"\1"), # Remove the U suffix from hex constants ! (re.compile(r"(0[xX][0-9a-fA-F]+)U"), r"\1"), ! # Replace L"spam" with u"spam" ! (re.compile(r'[lL]("[^"]*")'), r"u\1") ] *************** *** 91,99 **** # sequence of text lines containing the #define's that the # preprocessor dumps out. ! def get_cpp_symbols(options, *fnames): # options is a sequence of command line options for GCCXML # fnames is the sequence of include files # options = " ".join(options) --- 131,143 ---- # sequence of text lines containing the #define's that the # preprocessor dumps out. ! def get_cpp_symbols(options, verbose, *fnames): # options is a sequence of command line options for GCCXML # fnames is the sequence of include files # + compiler = "" + for o in options: + if o.startswith("--gccxml-compiler"): + compiler = o options = " ".join(options) *************** *** 101,105 **** handle, c_file = tempfile.mkstemp(suffix=".c", text=True) for fname in fnames: ! os.write(handle, "#include <%s>\n" % fname) os.close(handle) --- 145,149 ---- handle, c_file = tempfile.mkstemp(suffix=".c", text=True) for fname in fnames: ! os.write(handle, '#include <%s>\n' % fname) os.close(handle) *************** *** 115,143 **** raise ParserError, "gccxml returned error %s" % retval ! threading.Thread(target=get_errout, args=(fd,)).start() try: # We don't want the predefined symbols. So we get them and # remove them later. ! i, o, e = os.popen3(r"gccxml.exe --preprocess -dM") i.close() - read_stderr(e) builtin_syms = o.readlines() retval = o.close() if retval: raise ParserError, "gccxml returned error %s" % retval result = [] i, o, e = os.popen3(r"gccxml.exe %s %s --preprocess -dM" % (options, c_file)) i.close() - read_stderr(e) for line in o.readlines(): if not line in builtin_syms: result.append(line) retval = o.close() if retval: raise ParserError, "gccxml returned error %s" % retval return result finally: os.remove(c_file) --- 159,197 ---- raise ParserError, "gccxml returned error %s" % retval ! thread = threading.Thread(target=get_errout, args=(fd,)) ! thread.start() ! return thread try: # We don't want the predefined symbols. So we get them and # remove them later. ! if verbose: ! print >> sys.stderr, r"run gccxml.exe %s --preprocess -dM" % compiler ! i, o, e = os.popen3(r"gccxml.exe %s --preprocess -dM" % compiler) ! t = read_stderr(e) i.close() builtin_syms = o.readlines() retval = o.close() if retval: raise ParserError, "gccxml returned error %s" % retval + t.join() result = [] + if verbose: + print >> sys.stderr, r"run gccxml.exe %s %s --preprocess -dM" % (options, c_file) i, o, e = os.popen3(r"gccxml.exe %s %s --preprocess -dM" % (options, c_file)) + t = read_stderr(e) i.close() for line in o.readlines(): if not line in builtin_syms: result.append(line) retval = o.close() + t.join() if retval: raise ParserError, "gccxml returned error %s" % retval return result finally: + if verbose: + print >> sys.stderr, "Deleting temporary file %s" % c_file os.remove(c_file) *************** *** 145,153 **** class IncludeParser(object): ! def __init__(self, cpp_options=()): self._env = {} self._statements = [] self._errlines = [] self._cpp_options = cpp_options # ripped from h2py --- 199,208 ---- class IncludeParser(object): ! def __init__(self, cpp_options=(), verbose=0): self._env = {} self._statements = [] self._errlines = [] self._cpp_options = cpp_options + self._verbose = verbose # ripped from h2py *************** *** 166,179 **** def _parse(self, *files): self.files = files ! lines = get_cpp_symbols(self._cpp_options, *files) total = 0 for i in range(10): processed = self.parse_lines(lines) total += processed ! print "processed %d (%d) defs in pass %d, %d defs remain" % \ ! (processed, total, i, len(lines)) if not processed: ! return def create_statement(self, line): --- 221,243 ---- def _parse(self, *files): self.files = files ! lines = get_cpp_symbols(self._cpp_options, self._verbose, *files) + if self._verbose: + print >> sys.stderr, "Start parsing..." total = 0 for i in range(10): processed = self.parse_lines(lines) total += processed ! if self._verbose: ! print >> sys.stderr, "processed %d (%d) defs in pass %d, %d defs remain" % \ ! (processed, total, i, len(lines)) if not processed: ! break ! if self._verbose > 1: ! for line in lines: ! print >> sys.stderr, "Skipped '%s'" % line.rstrip("\n") ! if self._verbose: ! print >> sys.stderr, "Parsing done." ! def create_statement(self, line): *************** *** 199,203 **** if stmt is None: # cannot process this line self._errlines.append(line) - print line.rstrip() processed.append(lineno) else: --- 263,266 ---- *************** *** 227,254 **** return self._errlines[:] ! # script start ! if __name__ == "__main__": ! import time ! import types ! os.environ["GCCXML_COMPILER"] = "msvc71" ! ! start = time.clock() ! parser = IncludeParser() ! parser.parse("windows.h") ! print "%.2f seconds" % (time.clock() - start) ! ! n = 0 ! ofi = open("symbols.py", "w") ! names = parser._env.keys() ! names.sort() # it's nicer ! for name in names: ! value = parser._env[name] ! if not type(value) is types.FunctionType: ! ## ofi.write("%s = %r\n" % (name, value)) ! print name, value ! n += 1 ! print "Dumped %d symbols" % n ! ## from pprint import pprint as pp ! ## pp(parser._errlines) --- 290,348 ---- return self._errlines[:] ! def write_symbols(self, fname, raw): ! import types ! if fname == "-": ! ofi = sys.stdout ! else: ! ofi = open(fname, "w") ! if raw: ! for s in self._statements: ! ofi.write(s) ! ofi.write("\n\n##### skipped lines #####\n\n") ! for s in self._errlines: ! ofi.write(s) ! else: ! symbols = self.get_symbols() ! names = symbols.keys() ! names.sort() # it's nicer ! for name in names: ! value = symbols[name] ! if not type(value) is types.FunctionType: ! ofi.write("%s = %r\n" % (name, value)) ! ! ################################################################ ! def main(args=sys.argv[1:]): ! import getopt ! gccxml_options = [] ! verbose = 0 ! py_file = None ! raw = 0 ! try: ! opts, files = getopt.getopt(args, "rvc:D:U:I:o:", ["compiler="]) ! if not files: ! raise ValueError ! 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 == "-o": ! py_file = a ! elif o == "-v": ! verbose += 1 ! elif o == "-r": ! raw = 1 ! ! parser = IncludeParser(gccxml_options, verbose=verbose) ! parser.parse(*files) ! if py_file: ! parser.write_symbols(py_file, raw) ! return 0 ! ! if __name__ == "__main__": ! sys.exit(main()) |
From: Thomas H. <th...@us...> - 2004-09-03 10:05:31
|
Update of /cvsroot/ctypes/ctypes/sandbox/tools In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv21021 Modified Files: inc2py.py Log Message: Allow to pass command line options to GCCXML. Create accessor methods for the parsing result. Index: inc2py.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/sandbox/tools/inc2py.py,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** inc2py.py 3 Sep 2004 09:09:16 -0000 1.3 --- inc2py.py 3 Sep 2004 10:05:21 -0000 1.4 *************** *** 91,95 **** # sequence of text lines containing the #define's that the # preprocessor dumps out. ! def get_cpp_symbols(*fnames): # write a temporary C file handle, c_file = tempfile.mkstemp(suffix=".c", text=True) --- 91,101 ---- # sequence of text lines containing the #define's that the # preprocessor dumps out. ! def get_cpp_symbols(options, *fnames): ! # options is a sequence of command line options for GCCXML ! # fnames is the sequence of include files ! # ! ! options = " ".join(options) ! # write a temporary C file handle, c_file = tempfile.mkstemp(suffix=".c", text=True) *************** *** 109,113 **** raise ParserError, "gccxml returned error %s" % retval ! threading.Thread(target=get_errout, args=(e,)).start() try: --- 115,119 ---- raise ParserError, "gccxml returned error %s" % retval ! threading.Thread(target=get_errout, args=(fd,)).start() try: *************** *** 123,128 **** result = [] ! ##print (r"# gccxml.exe %s --preprocess -dM" % c_file) ! i, o, e = os.popen3(r"gccxml.exe %s --preprocess -dM" % c_file) i.close() read_stderr(e) --- 129,133 ---- result = [] ! i, o, e = os.popen3(r"gccxml.exe %s %s --preprocess -dM" % (options, c_file)) i.close() read_stderr(e) *************** *** 140,149 **** class IncludeParser(object): ! def __init__(self, env=None): ! if env is None: ! self.env = {} ! else: ! self.env = env ! self.statements = [] # ripped from h2py --- 145,153 ---- class IncludeParser(object): ! def __init__(self, cpp_options=()): ! self._env = {} ! self._statements = [] ! self._errlines = [] ! self._cpp_options = cpp_options # ripped from h2py *************** *** 158,173 **** def parse(self, *files): self._parse(*files) ! try: ! del self.env["__builtins__"] ! except KeyError: ! pass def _parse(self, *files): self.files = files ! lines = get_cpp_symbols(*files) total = 0 for i in range(10): ! processed = self.create_pycode(lines) total += processed print "processed %d (%d) defs in pass %d, %d defs remain" % \ --- 162,174 ---- def parse(self, *files): self._parse(*files) ! self._env.pop("__builtins__", None) def _parse(self, *files): self.files = files ! lines = get_cpp_symbols(self._cpp_options, *files) total = 0 for i in range(10): ! processed = self.parse_lines(lines) total += processed print "processed %d (%d) defs in pass %d, %d defs remain" % \ *************** *** 176,218 **** return ! def create_pycode(self, lines): processed = [] # line numbers of processed lines for lineno, line in enumerate(lines): ! match = p_define.match(line) ! if match: ! name = match.group(1) ! if name in self.env: ! continue ! body = line[match.end():] ! body = self.pytify(body) ! stmt = '%s = %s\n' % (name, body.strip()) ! try: ! exec stmt in self.env ! except: ! pass ! else: ! self.statements.append(stmt) ! processed.append(lineno) ! continue ! ! match = p_macro.match(line) ! if match: ! macro, arg = match.group(1, 2) ! if macro in self.env: ! continue ! body = line[match.end():] ! body = self.pytify(body) ! stmt = 'def %s(%s): return %s\n' % (macro, arg, body) try: ! exec stmt in self.env except: pass else: ! self.statements.append(stmt) processed.append(lineno) - continue - - # no pattern matches, cannot process this line - processed.append(lineno) processed.reverse() --- 177,212 ---- return ! def create_statement(self, line): ! match = p_define.match(line) ! if match: ! name = match.group(1) ! body = line[match.end():] ! body = self.pytify(body) ! return '%s = %s\n' % (name, body.strip()) ! ! match = p_macro.match(line) ! if match: ! macro, arg = match.group(1, 2) ! body = line[match.end():] ! body = self.pytify(body) ! return 'def %s(%s): return %s\n' % (macro, arg, body) ! return None ! ! def parse_lines(self, lines): processed = [] # line numbers of processed lines for lineno, line in enumerate(lines): ! stmt = self.create_statement(line) ! if stmt is None: # cannot process this line ! self._errlines.append(line) ! print line.rstrip() ! processed.append(lineno) ! else: try: ! exec stmt in self._env except: pass else: ! self._statements.append(stmt) processed.append(lineno) processed.reverse() *************** *** 221,224 **** --- 215,230 ---- return len(processed) + def get_symbols(self): + # return a dictionary containing the symbols collected + return self._env.copy() + + def get_statements(self): + # return a sequence of Python statements generated from the #defines + return self._statements[:] + + def get_errlines(self): + # return a sequence of #define lines which could not be processed + return self._errlines[:] + # script start if __name__ == "__main__": *************** *** 227,243 **** os.environ["GCCXML_COMPILER"] = "msvc71" - parser = IncludeParser() start = time.clock() ! parser.parse("windows.h", "sql.h") print "%.2f seconds" % (time.clock() - start) n = 0 ofi = open("symbols.py", "w") ! names = parser.env.keys() names.sort() # it's nicer for name in names: ! value = parser.env[name] if not type(value) is types.FunctionType: ! ofi.write("%s = %r\n" % (name, value)) n += 1 print "Dumped %d symbols" % n --- 233,254 ---- os.environ["GCCXML_COMPILER"] = "msvc71" start = time.clock() ! ! parser = IncludeParser() ! parser.parse("windows.h") print "%.2f seconds" % (time.clock() - start) n = 0 ofi = open("symbols.py", "w") ! names = parser._env.keys() names.sort() # it's nicer for name in names: ! value = parser._env[name] if not type(value) is types.FunctionType: ! ## ofi.write("%s = %r\n" % (name, value)) ! print name, value n += 1 print "Dumped %d symbols" % n + ## from pprint import pprint as pp + + ## pp(parser._errlines) |
From: Thomas H. <th...@us...> - 2004-09-03 09:09:25
|
Update of /cvsroot/ctypes/ctypes/sandbox/tools In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv13171 Modified Files: inc2py.py Log Message: Read stderr output from gccxml separately. Index: inc2py.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/sandbox/tools/inc2py.py,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** inc2py.py 3 Sep 2004 08:40:41 -0000 1.2 --- inc2py.py 3 Sep 2004 09:09:16 -0000 1.3 *************** *** 98,106 **** os.close(handle) try: # We don't want the predefined symbols. So we get them and # remove them later. ! i, o = os.popen4(r"gccxml.exe --preprocess -dM") i.close() builtin_syms = o.readlines() retval = o.close() --- 98,120 ---- os.close(handle) + def read_stderr(fd): + import threading + + def get_errout(fd): + errs = fd.read() + if errs: + sys.stderr.write(errs) + retval = fd.close() + if retval: + raise ParserError, "gccxml returned error %s" % retval + + threading.Thread(target=get_errout, args=(e,)).start() + try: # We don't want the predefined symbols. So we get them and # remove them later. ! i, o, e = os.popen3(r"gccxml.exe --preprocess -dM") i.close() + read_stderr(e) builtin_syms = o.readlines() retval = o.close() *************** *** 109,115 **** result = [] ! print (r"# gccxml.exe %s --preprocess -dM" % c_file) ! i, o = os.popen4(r"gccxml.exe %s --preprocess -dM" % c_file) i.close() for line in o.readlines(): if not line in builtin_syms: --- 123,130 ---- result = [] ! ##print (r"# gccxml.exe %s --preprocess -dM" % c_file) ! i, o, e = os.popen3(r"gccxml.exe %s --preprocess -dM" % c_file) i.close() + read_stderr(e) for line in o.readlines(): if not line in builtin_syms: *************** *** 143,147 **** def parse(self, *files): self._parse(*files) ! del self.env["__builtins__"] def _parse(self, *files): --- 158,165 ---- def parse(self, *files): self._parse(*files) ! try: ! del self.env["__builtins__"] ! except KeyError: ! pass def _parse(self, *files): *************** *** 211,215 **** parser = IncludeParser() start = time.clock() ! parser.parse("windows.h", "sqlX.h") print "%.2f seconds" % (time.clock() - start) --- 229,233 ---- parser = IncludeParser() start = time.clock() ! parser.parse("windows.h", "sql.h") print "%.2f seconds" % (time.clock() - start) |
From: Thomas H. <th...@us...> - 2004-09-03 08:40:51
|
Update of /cvsroot/ctypes/ctypes/sandbox/tools In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv9315 Modified Files: inc2py.py Log Message: Lots of internal cleanup. Index: inc2py.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/sandbox/tools/inc2py.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** inc2py.py 3 Sep 2004 07:32:58 -0000 1.1 --- inc2py.py 3 Sep 2004 08:40:41 -0000 1.2 *************** *** 85,88 **** --- 85,91 ---- ] + class ParserError(Exception): + pass + # pass one or more include files to the preprocessor, and return a # sequence of text lines containing the #define's that the *************** *** 96,187 **** try: i, o = os.popen4(r"gccxml.exe --preprocess -dM") i.close() ! ignores = o.readlines() result = [] - log = open("temp.log", "w") - print (r"# gccxml.exe %s --preprocess -dM" % c_file) i, o = os.popen4(r"gccxml.exe %s --preprocess -dM" % c_file) i.close() for line in o.readlines(): ! log.write(line) ! if not line in ignores: result.append(line) return result finally: os.remove(c_file) - ##ignores = [] ! # ripped from h2py ! def pytify(body): ! # replace ignored patterns by spaces ! for p in ignores: ! body = p.sub(' ', body) ! for pat, repl in replaces: ! body = pat.sub(repl, body) ! return body ! ! def create_pycode(lines, env, stream, include_errors = False): ! errors = 0 ! def try_stmt(stmt): ! try: ! exec stmt in env ! except: ! if include_errors and stream: ! stream.write("# %s" % stmt) ! return 1 else: ! if stream: ! stream.write(stmt) ! return 0 ! for line in lines: ! match = p_define.match(line) ! if match: ! name = match.group(1) ! if name in env: ! continue ! body = line[match.end():] ! body = pytify(body) ! stmt = '%s = %s\n' % (name, body.strip()) ! errors += try_stmt(stmt) ! continue ! match = p_macro.match(line) ! if match: ! macro, arg = match.group(1, 2) ! if macro in env: ! continue ! body = line[match.end():] ! body = pytify(body) ! stmt = 'def %s(%s): return %s\n' % (macro, arg, body) ! errors += try_stmt(stmt) ! continue ! if include_errors and stream: # no pattern matches ! stream.write("# %s" % line) ! errors += 1 ! return errors ! # script start ! os.environ["GCCXML_COMPILER"] = "msvc71" ! lines = get_cpp_symbols("windows.h")#, "winsock.h") ! ofi = sys.stdout ! env = {} ! e = 0 ! for i in range(10): ! errors = create_pycode(lines, env, ofi, None) ! ## print "%d errors in pass %d" % (errors, i) ! if e == errors: ! create_pycode(lines, env, sys.stdout, True) ! print "# processed %d lines into %d definitions" % (len(lines), len(env)) ! print "# %d errors remaining after %d passes" % (errors, i) ! break ! e = errors --- 99,225 ---- try: + # We don't want the predefined symbols. So we get them and + # remove them later. i, o = os.popen4(r"gccxml.exe --preprocess -dM") i.close() ! builtin_syms = o.readlines() ! retval = o.close() ! if retval: ! raise ParserError, "gccxml returned error %s" % retval result = [] print (r"# gccxml.exe %s --preprocess -dM" % c_file) i, o = os.popen4(r"gccxml.exe %s --preprocess -dM" % c_file) i.close() for line in o.readlines(): ! if not line in builtin_syms: result.append(line) + retval = o.close() + if retval: + raise ParserError, "gccxml returned error %s" % retval return result finally: os.remove(c_file) ! class IncludeParser(object): ! def __init__(self, env=None): ! if env is None: ! self.env = {} else: ! self.env = env ! self.statements = [] ! # ripped from h2py ! def pytify(self, body): ! # replace ignored patterns by spaces ! for p in ignores: ! body = p.sub(' ', body) ! for pat, repl in replaces: ! body = pat.sub(repl, body) ! return body ! def parse(self, *files): ! self._parse(*files) ! del self.env["__builtins__"] ! def _parse(self, *files): ! self.files = files ! lines = get_cpp_symbols(*files) ! total = 0 ! for i in range(10): ! processed = self.create_pycode(lines) ! total += processed ! print "processed %d (%d) defs in pass %d, %d defs remain" % \ ! (processed, total, i, len(lines)) ! if not processed: ! return ! def create_pycode(self, lines): ! processed = [] # line numbers of processed lines ! for lineno, line in enumerate(lines): ! match = p_define.match(line) ! if match: ! name = match.group(1) ! if name in self.env: ! continue ! body = line[match.end():] ! body = self.pytify(body) ! stmt = '%s = %s\n' % (name, body.strip()) ! try: ! exec stmt in self.env ! except: ! pass ! else: ! self.statements.append(stmt) ! processed.append(lineno) ! continue ! match = p_macro.match(line) ! if match: ! macro, arg = match.group(1, 2) ! if macro in self.env: ! continue ! body = line[match.end():] ! body = self.pytify(body) ! stmt = 'def %s(%s): return %s\n' % (macro, arg, body) ! try: ! exec stmt in self.env ! except: ! pass ! else: ! self.statements.append(stmt) ! processed.append(lineno) ! continue ! # no pattern matches, cannot process this line ! processed.append(lineno) ! ! processed.reverse() ! for i in processed: ! del lines[i] ! return len(processed) ! ! # script start ! if __name__ == "__main__": ! import time ! import types ! os.environ["GCCXML_COMPILER"] = "msvc71" ! ! parser = IncludeParser() ! start = time.clock() ! parser.parse("windows.h", "sqlX.h") ! print "%.2f seconds" % (time.clock() - start) ! ! n = 0 ! ofi = open("symbols.py", "w") ! names = parser.env.keys() ! names.sort() # it's nicer ! for name in names: ! value = parser.env[name] ! if not type(value) is types.FunctionType: ! ofi.write("%s = %r\n" % (name, value)) ! n += 1 ! print "Dumped %d symbols" % n |