ctypes-commit Mailing List for ctypes (Page 74)
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...> - 2005-02-04 18:05:40
|
Update of /cvsroot/ctypes/ctypes/ctypes In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv16609 Modified Files: decorators.py Log Message: Remove the stuff that doesn't work. Index: decorators.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/ctypes/decorators.py,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** decorators.py 28 Jan 2005 18:16:35 -0000 1.4 --- decorators.py 4 Feb 2005 18:05:29 -0000 1.5 *************** *** 28,41 **** cdef >>> - >>> @ cdecl(c_char_p, 'msvcrt', [c_char_p, c_int]) - ... def strchr(string, c): - ... 'find a character in a string' - ... - >>> print strchr('abcdef', ord('x')) - None - >>> print strchr('abcdef', ord('c')) - cdef - >>> """ import sys import ctypes --- 28,44 ---- cdef >>> """ + + # This doesn't work, see below. + ##>>> @ cdecl(c_char_p, 'msvcrt', [c_char_p, c_int]) + ##... def strchr(string, c): + ##... 'find a character in a string' + ##... + ##>>> print strchr('abcdef', ord('x')) + ##None + ##>>> print strchr('abcdef', ord('c')) + ##cdef + ##>>> + import sys import ctypes *************** *** 43,73 **** LOGGING = False ! def _create_func_codestring(func, doc=None): ! # given a function object <func>, build the source code for ! # another function, having the same argument list, and a function ! # body which contains a call to an _api_ function. ! # ! # Assuming the <func> has this definition: ! # def func(first, second="spam", third=42): ! # .... ! # a string containing the following code is returned: ! # def func(first, second="spam", third=42): ! # return _api_(first, second, third) ! import inspect ! args, varargs, varkw, defaults = inspect.getargspec(func) ! if varkw: ! raise TypeError, "function argument list cannot contain ** argument" ! if doc: ! return "def %s%s:\n %r\n return %s._api_%s" % \ ! (func.func_name, ! inspect.formatargspec(args, varargs, varkw, defaults), ! doc, ! func.func_name, ! inspect.formatargspec(args, varargs, varkw)) ! return "def %s%s:\n return %s._api_%s" % \ ! (func.func_name, ! inspect.formatargspec(args, varargs, varkw, defaults), ! func.func_name, ! inspect.formatargspec(args, varargs, varkw)) ################################################################ --- 46,76 ---- LOGGING = False ! ##def _create_func_codestring(func, doc=None): ! ## # given a function object <func>, build the source code for ! ## # another function, having the same argument list, and a function ! ## # body which contains a call to an _api_ function. ! ## # ! ## # Assuming the <func> has this definition: ! ## # def func(first, second="spam", third=42): ! ## # .... ! ## # a string containing the following code is returned: ! ## # def func(first, second="spam", third=42): ! ## # return _api_(first, second, third) ! ## import inspect ! ## args, varargs, varkw, defaults = inspect.getargspec(func) ! ## if varkw: ! ## raise TypeError, "function argument list cannot contain ** argument" ! ## if doc: ! ## return "def %s%s:\n %r\n return %s._api_%s" % \ ! ## (func.func_name, ! ## inspect.formatargspec(args, varargs, varkw, defaults), ! ## doc, ! ## func.func_name, ! ## inspect.formatargspec(args, varargs, varkw)) ! ## return "def %s%s:\n return %s._api_%s" % \ ! ## (func.func_name, ! ## inspect.formatargspec(args, varargs, varkw, defaults), ! ## func.func_name, ! ## inspect.formatargspec(args, varargs, varkw)) ################################################################ *************** *** 80,89 **** this_dll = dll api = ctypes.WINFUNCTYPE(restype, *argtypes)(func.func_name, this_dll) ! if len(func.func_code.co_code) == 4: ! # Hacky way to detect an empty function body. ! codestring = _create_func_codestring(func, func.__doc__) ! d = {} ! exec codestring in d ! func = d[func.func_name] func._api_ = api if logging or LOGGING: --- 83,92 ---- this_dll = dll api = ctypes.WINFUNCTYPE(restype, *argtypes)(func.func_name, this_dll) ! # This simple way to find out an empty function body doesn't work. ! ## if len(func.func_code.co_code) == 4: ! ## codestring = _create_func_codestring(func, func.__doc__) ! ## d = {} ! ## exec codestring in d ! ## func = d[func.func_name] func._api_ = api if logging or LOGGING: *************** *** 104,109 **** this_dll = dll api = ctypes.CFUNCTYPE(restype, *argtypes)(func.func_name, this_dll) ## if len(func.func_code.co_code) == 4: - ## # Hacky way to detect an empty function body. ## codestring = _create_func_codestring(func, func.__doc__) ## d = {} --- 107,112 ---- this_dll = dll api = ctypes.CFUNCTYPE(restype, *argtypes)(func.func_name, this_dll) + # This simple way to find out an empty function body doesn't work. ## if len(func.func_code.co_code) == 4: ## codestring = _create_func_codestring(func, func.__doc__) ## d = {} *************** *** 123,127 **** ################################################################ ! if __name__ == "__main__": import doctest doctest.testmod() --- 126,131 ---- ################################################################ ! ##if __name__ == "__main__": ! if 0: import doctest doctest.testmod() |
From: Thomas H. <th...@us...> - 2005-02-04 18:04:49
|
Update of /cvsroot/ctypes/ctypes/ctypes/wrap In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv16372 Modified Files: codegenerator.py Log Message: The code generator now assumes decorators are present in the ctypes module. Index: codegenerator.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/ctypes/wrap/codegenerator.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** codegenerator.py 4 Feb 2005 17:01:24 -0000 1.1 --- codegenerator.py 4 Feb 2005 18:04:24 -0000 1.2 *************** *** 3,13 **** # $Log$ # Revision 1.1 2005/02/04 17:01:24 theller # Moved the code generation stuff from the sandbox to it's final location. # - # Revision 1.49 2005/02/04 08:14:29 theller - # Oops. - # - # import typedesc, sys --- 3,12 ---- # $Log$ + # Revision 1.2 2005/02/04 18:04:24 theller + # The code generator now assumes decorators are present in the ctypes module. + # # Revision 1.1 2005/02/04 17:01:24 theller # Moved the code generation stuff from the sandbox to it's final location. # import typedesc, sys *************** *** 495,506 **** self._STDMETHOD_defined = True - _decorators_defined = False - def need_decorators(self): - if self._decorators_defined: - return "decorators" - print >> self.imports, "from ctypes import decorators" - self._decorators_defined = True - return "decorators" - _functiontypes = 0 _notfound_functiontypes = 0 --- 494,497 ---- *************** *** 511,519 **** self.generate_all(func.arguments) args = [self.type_name(a) for a in func.arguments] - prefix = self.need_decorators() if "__stdcall__" in func.attributes: ! cc = "%s.stdcall" % prefix else: ! cc = "%s.cdecl" % prefix libname = self.get_sharedlib(dllname) print >> self.stream --- 502,509 ---- self.generate_all(func.arguments) args = [self.type_name(a) for a in func.arguments] if "__stdcall__" in func.attributes: ! cc = "stdcall" else: ! cc = "cdecl" libname = self.get_sharedlib(dllname) print >> self.stream |
Update of /cvsroot/ctypes/ctypes/ctypes/wrap In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv1510 Added Files: xml2py.py typedesc.py h2xml.py gccxmlparser.py cparser_config.py cparser.py codegenerator.py __init__.py .cvsignore Log Message: Moved the code generation stuff from the sandbox to it's final location. --- NEW FILE: .cvsignore --- *.pyc *.pyo --- NEW FILE: xml2py.py --- import sys, re from optparse import OptionParser from codegenerator import generate_code import typedesc ################################################################ windows_dll_names = """\ imagehlp user32 kernel32 gdi32 advapi32 oleaut32 ole32 imm32 comdlg32 shell32 version winmm mpr winscard winspool.drv urlmon crypt32 cryptnet ws2_32 opengl32 glu32 mswsock msvcrt msimg32 netapi32 rpcrt4""".split() ##rpcndr ##ntdll def main(args=None): if args is None: args = sys.argv def windows_dlls(option, opt, value, parser): parser.values.dlls.extend(windows_dll_names) parser = OptionParser("usage: %prog xmlfile [options]") parser.add_option("-d", action="store_true", dest="use_decorators", help="use Python 2.4 function decorators", default=False) parser.add_option("-k", action="store", dest="kind", help="kind of type descriptions to include: " "d = #defines, " "e = enumerations, " "f = functions, " "s = structures, " "t = typedefs", metavar="TYPEKIND", default=None) parser.add_option("-l", dest="dlls", help="libraries to search for exported functions", action="append", default=[]) parser.add_option("-o", dest="output", help="output filename (if not specified, standard output will be used)", default="-") parser.add_option("-r", dest="expressions", metavar="EXPRESSION", action="append", help="regular expression for symbols to include " "(if neither symbols nor expressions are specified," "everything will be included)", default=None) parser.add_option("-s", dest="symbols", metavar="SYMBOL", action="append", help="symbol to include " "(if neither symbols nor expressions are specified," "everything will be included)", default=None) parser.add_option("-v", action="store_true", dest="verbose", help="verbose output", default=False) parser.add_option("-w", action="callback", callback=windows_dlls, help="add all standard windows dlls to the searched dlls list") ## try: ## import comtypes ## except ImportError: ## default_modules = ["ctypes", "ctypes.com"] ## else: ## default_modules = ["ctypes", "comtypes"] default_modules = ["ctypes"] parser.add_option("-m", dest="modules", metavar="module", help="Python module(s) containing symbols which will " "be imported instead of generated", action="append", default=default_modules) options, files = parser.parse_args(args[1:]) if len(files) != 1: parser.error("Exactly one input file must be specified") if options.output == "-": stream = sys.stdout else: stream = open(options.output, "w") if options.expressions: options.expressions = map(re.compile, options.expressions) stream.write("# generated by 'xml2py'\n") stream.write("# flags '%s'\n" % " ".join(sys.argv[1:])) known_symbols = {} from ctypes import CDLL dlls = [CDLL(name) for name in options.dlls] for name in options.modules: mod = __import__(name) for submodule in name.split(".")[1:]: mod = getattr(mod, submodule) for name in mod.__dict__: known_symbols[name] = mod.__name__ if options.kind: types = [] for char in options.kind: typ = {"a": [typedesc.Alias], "d": [typedesc.Variable], "e": [typedesc.Enumeration, typedesc.EnumValue], "f": [typedesc.Function], "m": [typedesc.Macro], "s": [typedesc.Structure], "t": [typedesc.Typedef], }[char] types.extend(typ) options.kind = tuple(types) generate_code(files[0], stream, symbols=options.symbols, expressions=options.expressions, verbose=options.verbose, use_decorators=options.use_decorators, known_symbols=known_symbols, searched_dlls=dlls, types=options.kind) if __name__ == "__main__": sys.exit(main()) --- NEW FILE: h2xml.py --- """h2xml - convert C include file(s) into an xml file by running gccxml.""" import sys, os, tempfile import cparser from optparse import OptionParser if sys.platform == "win32": def _locate_gccxml(): import _winreg for subkey in (r"Software\gccxml", r"Software\Kitware\GCC_XML"): for root in (_winreg.HKEY_CURRENT_USER, _winreg.HKEY_LOCAL_MACHINE): try: hkey = _winreg.OpenKey(root, subkey, 0, _winreg.KEY_READ) except WindowsError, detail: if detail.errno != 2: raise else: return _winreg.QueryValueEx(hkey, "loc")[0] + r"\bin" loc = _locate_gccxml() if loc: os.environ["PATH"] = loc ################################################################ def main(): def add_option(option, opt, value, parser): parser.values.gccxml_options.extend((opt, value)) parser = OptionParser("usage: %prog includefile ... [options]") ## parser.add_option("-h", action="help") parser.add_option("-q", "--quiet", dest="quiet", action="store_true", default=False) parser.add_option("-D", type="string", action="callback", callback=add_option, dest="gccxml_options", help="macros to define", metavar="NAME[=VALUE]", default=[]) parser.add_option("-U", type="string", action="callback", callback=add_option, help="macros to undefine", metavar="NAME") parser.add_option("-I", type="string", action="callback", callback=add_option, dest="gccxml_options", help="additional include directories", metavar="DIRECTORY") parser.add_option("-o", dest="xmlfile", help="XML output filename", default=None) options, files = parser.parse_args() if not files: print "Error: no files to process" print >> sys.stderr, __doc__ return 1 options.flags = options.gccxml_options options.verbose = not options.quiet try: parser = cparser.IncludeParser() parser.parse(files, options) except cparser.CompilerError, detail: import traceback traceback.print_exc() ## print detail sys.exit(1) if __name__ == "__main__": main() --- NEW FILE: codegenerator.py --- # Create ctypes wrapper code for abstract type descriptions. # Type descriptions are collections of typedesc instances. # $Log: codegenerator.py,v $ # Revision 1.1 2005/02/04 17:01:24 theller # Moved the code generation stuff from the sandbox to it's final location. # # Revision 1.49 2005/02/04 08:14:29 theller # Oops. # # import typedesc, sys try: set except NameError: from sets import Set as set try: import cStringIO as StringIO except ImportError: import StringIO # XXX Should this be in ctypes itself? ctypes_names = { "unsigned char": "c_ubyte", "signed char": "c_byte", "char": "c_char", "wchar_t": "c_wchar", "short unsigned int": "c_ushort", "short int": "c_short", "long unsigned int": "c_ulong", "long int": "c_long", "long signed int": "c_long", "unsigned int": "c_uint", "int": "c_int", "long long unsigned int": "c_ulonglong", "long long int": "c_longlong", "double": "c_double", "float": "c_float", # Hm... "void": "None", } ################ def storage(t): # return the size and alignment of a type if isinstance(t, typedesc.Typedef): return storage(t.typ) elif isinstance(t, typedesc.ArrayType): s, a = storage(t.typ) return s * (int(t.max) - int(t.min) + 1), a return int(t.size), int(t.align) class PackingError(Exception): pass def _calc_packing(struct, fields, pack, isStruct): # Try a certain packing, raise PackingError if field offsets, # total size ot total alignment is wrong. if struct.size is None: # incomplete struct return -1 if struct.name in dont_assert_size: return None if struct.bases: size = struct.bases[0].size total_align = struct.bases[0].align else: size = 0 total_align = 8 # in bits for i, f in enumerate(fields): if f.bits: ## print "##XXX FIXME" return -2 # XXX FIXME s, a = storage(f.typ) if pack is not None: a = min(pack, a) if size % a: size += a - size % a if isStruct: if size != f.offset: raise PackingError, "field offset (%s/%s)" % (size, f.offset) size += s else: size = max(size, s) total_align = max(total_align, a) if total_align != struct.align: raise PackingError, "total alignment (%s/%s)" % (total_align, struct.align) a = total_align if pack is not None: a = min(pack, a) if size % a: size += a - size % a if size != struct.size: raise PackingError, "total size (%s/%s)" % (size, struct.size) def calc_packing(struct, fields): # try several packings, starting with unspecified packing isStruct = isinstance(struct, typedesc.Structure) for pack in [None, 16*8, 8*8, 4*8, 2*8, 1*8]: try: _calc_packing(struct, fields, pack, isStruct) except PackingError, details: continue else: if pack is None: return None return pack/8 raise PackingError, "PACKING FAILED: %s" % details def decode_value(init): # decode init value from gccxml if init[0] == "0": return int(init, 16) # hex integer elif init[0] == "'": return eval(init) # character elif init[0] == '"': return eval(init) # string return int(init) # integer def get_real_type(tp): if type(tp) is typedesc.Typedef: return get_real_type(tp.typ) return tp # XXX These should be filtered out in gccxmlparser. dont_assert_size = set( [ "__si_class_type_info_pseudo", "__class_type_info_pseudo", ] ) class Generator(object): def __init__(self, output, use_decorators=False): self.output = output self.stream = StringIO.StringIO() self.imports = StringIO.StringIO() self.use_decorators = use_decorators self.done = set() # type descriptions that have been generated self.names = set() # names that have been generated def init_value(self, t, init): tn = self.type_name(t, False) if tn in ["c_ulonglong", "c_ulong", "c_uint", "c_ushort", "c_ubyte"]: return decode_value(init) elif tn in ["c_longlong", "c_long", "c_int", "c_short", "c_byte"]: return decode_value(init) elif tn in ["c_float", "c_double"]: return float(init) elif tn == "POINTER(c_char)": if init[0] == '"': value = eval(init) else: value = int(init, 16) return value elif tn == "POINTER(c_wchar)": if init[0] == '"': value = eval(init) else: value = int(init, 16) if isinstance(value, str): value = value[:-1] # gccxml outputs "D\000S\000\000" for L"DS" value = value.decode("utf-16") # XXX Is this correct? return value elif tn == "c_void_p": if init[0] == "0": value = int(init, 16) else: value = int(init) # hm.. # Hm, ctypes represents them as SIGNED int return value elif tn == "c_char": return decode_value(init) elif tn == "c_wchar": value = decode_value(init) if isinstance(value, int): return unichr(value) return value elif tn.startswith("POINTER("): # Hm, POINTER(HBITMAP__) for example return decode_value(init) else: raise ValueError, "cannot decode %s(%r)" % (tn, init) def type_name(self, t, generate=True): # Return a string, containing an expression which can be used to # refer to the type. Assumes the * namespace is available. if isinstance(t, typedesc.PointerType): result = "POINTER(%s)" % self.type_name(t.typ, generate) # XXX Better to inspect t.typ! if result.startswith("POINTER(WINFUNCTYPE"): return result[len("POINTER("):-1] if result.startswith("POINTER(CFUNCTYPE"): return result[len("POINTER("):-1] elif result == "POINTER(None)": return "c_void_p" return result elif isinstance(t, typedesc.ArrayType): return "%s * %s" % (self.type_name(t.typ, generate), int(t.max)+1) elif isinstance(t, typedesc.FunctionType): args = [self.type_name(x, generate) for x in [t.returns] + t.arguments] if "__stdcall__" in t.attributes: return "WINFUNCTYPE(%s)" % ", ".join(args) else: return "CFUNCTYPE(%s)" % ", ".join(args) elif isinstance(t, typedesc.CvQualifiedType): # const and volatile are ignored return "%s" % self.type_name(t.typ, generate) elif isinstance(t, typedesc.FundamentalType): return ctypes_names[t.name] elif isinstance(t, typedesc.Structure): return t.name elif isinstance(t, typedesc.Enumeration): if t.name: return t.name return "c_int" # enums are integers elif isinstance(t, typedesc.Typedef): return t.name return t.name ################################################################ def Alias(self, alias): if alias.typ is not None: # we can resolve it self.generate(alias.typ) if alias.alias in self.names: print >> self.stream, "%s = %s # alias" % (alias.name, alias.alias) self.names.add(alias.name) return # we cannot resolve it print >> self.stream, "# %s = %s # alias" % (alias.name, alias.alias) print "# unresolved alias: %s = %s" % (alias.name, alias.alias) def Macro(self, macro): # We don't know if we can generate valid, error free Python # code All we can do is to try to compile the code. If the # compile fails, we know it cannot work, so we generate # commented out code. If it succeeds, it may fail at runtime. code = "def %s%s: return %s # macro" % (macro.name, macro.args, macro.body) try: compile(code, "<string>", "exec") except SyntaxError: print >> self.stream, "#", code else: print >> self.stream, code self.names.add(macro.name) def StructureHead(self, head): for struct in head.struct.bases: self.generate(struct.get_head()) self.more.add(struct) basenames = [self.type_name(b) for b in head.struct.bases] if basenames: print >> self.stream, "class %s(%s):" % (head.struct.name, ", ".join(basenames)) else: methods = [m for m in head.struct.members if type(m) is typedesc.Method] if methods: self.need_cominterface() print >> self.stream, "class %s(_com_interface):" % head.struct.name elif type(head.struct) == typedesc.Structure: print >> self.stream, "class %s(Structure):" % head.struct.name elif type(head.struct) == typedesc.Union: print >> self.stream, "class %s(Union):" % head.struct.name if head.struct.location: print >> self.stream, " # %s %s" % head.struct.location print >> self.stream, " pass" self.names.add(head.struct.name) _structures = 0 def Structure(self, struct): self._structures += 1 self.generate(struct.get_head()) self.generate(struct.get_body()) Union = Structure _typedefs = 0 def Typedef(self, tp): self._typedefs += 1 if type(tp.typ) in (typedesc.Structure, typedesc.Union): self.generate(tp.typ.get_head()) self.more.add(tp.typ) else: self.generate(tp.typ) if self.type_name(tp.typ) in self.known_symbols: stream = self.imports else: stream = self.stream if tp.name != self.type_name(tp.typ): print >> stream, "%s = %s" % \ (tp.name, self.type_name(tp.typ)) self.names.add(tp.name) _arraytypes = 0 def ArrayType(self, tp): self._arraytypes += 1 self.generate(get_real_type(tp.typ)) self.generate(tp.typ) _functiontypes = 0 def FunctionType(self, tp): self._functiontypes += 1 self.generate(tp.returns) self.generate_all(tp.arguments) _pointertypes = 0 def PointerType(self, tp): self._pointertypes += 1 if type(tp.typ) is typedesc.PointerType: self.generate(tp.typ) elif type(tp.typ) in (typedesc.Union, typedesc.Structure): self.generate(tp.typ.get_head()) self.more.add(tp.typ) elif type(tp.typ) is typedesc.Typedef: self.generate(tp.typ) else: self.generate(tp.typ) def CvQualifiedType(self, tp): self.generate(tp.typ) _variables = 0 def Variable(self, tp): self._variables += 1 if tp.init is None: # wtypes.h contains IID_IProcessInitControl, for example return try: value = self.init_value(tp.typ, tp.init) except (TypeError, ValueError), detail: print "Could not init", tp.name, tp.init, detail return print >> self.stream, \ "%s = %r # Variable %s" % (tp.name, value, self.type_name(tp.typ, False)) self.names.add(tp.name) _enumvalues = 0 def EnumValue(self, tp): value = int(tp.value) print >> self.stream, \ "%s = %d" % (tp.name, value) self.names.add(tp.name) self._enumvalues += 1 _enumtypes = 0 def Enumeration(self, tp): self._enumtypes += 1 if tp.name: print >> self.stream print >> self.stream, "%s = c_int # enum" % tp.name for item in tp.values: self.generate(item) def StructureBody(self, body): fields = [] methods = [] for m in body.struct.members: if type(m) is typedesc.Field: fields.append(m) if type(m.typ) is typedesc.Typedef: self.generate(get_real_type(m.typ)) self.generate(m.typ) elif type(m) is typedesc.Method: methods.append(m) self.generate(m.returns) self.generate_all(m.arguments) elif type(m) is typedesc.Constructor: pass # we don't need _pack_ on Unions (I hope, at least), and # not on COM interfaces: # # Hm, how to detect a COM interface with no methods? IXMLDOMCDATASection is such a beast... ## if not isinstance(body.struct, typedesc.Union) and not methods: if not methods: pack = calc_packing(body.struct, fields) if pack is not None: print >> self.stream, "%s._pack_ = %s" % (body.struct.name, pack) if fields: if body.struct.bases: assert len(body.struct.bases) == 1 self.generate(body.struct.bases[0].get_body()) # field definition normally span several lines. # Before we generate them, we need to 'import' everything they need. # So, call type_name for each field once, for f in fields: self.type_name(f.typ) print >> self.stream, "%s._fields_ = [" % body.struct.name if body.struct.location: print >> self.stream, " # %s %s" % body.struct.location # unnamed fields will get autogenerated names "_", "_1". "_2", "_3", ... unnamed_index = 0 for f in fields: if not f.name: if unnamed_index: fieldname = "_%d" % unnamed_index else: fieldname = "_" unnamed_index += 1 print >> self.stream, " # Unnamed field renamed to '%s'" % fieldname else: fieldname = f.name if f.bits is None: print >> self.stream, " ('%s', %s)," % (fieldname, self.type_name(f.typ)) else: print >> self.stream, " ('%s', %s, %s)," % (fieldname, self.type_name(f.typ), f.bits) print >> self.stream, "]" # generate assert statements for size and alignment if body.struct.size and body.struct.name not in dont_assert_size: size = body.struct.size // 8 print >> self.stream, "assert sizeof(%s) == %s, sizeof(%s)" % \ (body.struct.name, size, body.struct.name) align = body.struct.align // 8 print >> self.stream, "assert alignment(%s) == %s, alignment(%s)" % \ (body.struct.name, align, body.struct.name) if methods: self.need_STDMETHOD() # method definitions normally span several lines. # Before we generate them, we need to 'import' everything they need. # So, call type_name for each field once, for m in methods: self.type_name(m.returns) for a in m.arguments: self.type_name(a) print >> self.stream, "%s._methods_ = [" % body.struct.name if body.struct.location: print >> self.stream, "# %s %s" % body.struct.location for m in methods: args = [self.type_name(a) for a in m.arguments] print >> self.stream, " STDMETHOD(%s, '%s', [%s])," % ( self.type_name(m.returns), m.name, ", ".join(args)) print >> self.stream, "]" def find_dllname(self, func): if hasattr(func, "dllname"): return func.dllname name = func.name for dll in self.searched_dlls: try: getattr(dll, name) except AttributeError: pass else: return dll._name ## if self.verbose: # warnings.warn, maybe? ## print >> sys.stderr, "function %s not found in any dll" % name return None _loadedlibs = None def get_sharedlib(self, dllname): if self._loadedlibs is None: self._loadedlibs = {} try: return self._loadedlibs[dllname] except KeyError: pass import os basename = os.path.basename(dllname) name, ext = os.path.splitext(basename) self._loadedlibs[dllname] = name print >> self.stream, "%s = CDLL(%r)" % (name, dllname) return name _cominterface_defined = False def need_cominterface(self): if self._cominterface_defined: return print >> self.imports, "from comtypes import _com_interface" self._cominterface_defined = True _STDMETHOD_defined = False def need_STDMETHOD(self): if self._STDMETHOD_defined: return print >> self.imports, "from comtypes import STDMETHOD" self._STDMETHOD_defined = True _decorators_defined = False def need_decorators(self): if self._decorators_defined: return "decorators" print >> self.imports, "from ctypes import decorators" self._decorators_defined = True return "decorators" _functiontypes = 0 _notfound_functiontypes = 0 def Function(self, func): dllname = self.find_dllname(func) if dllname: self.generate(func.returns) self.generate_all(func.arguments) args = [self.type_name(a) for a in func.arguments] prefix = self.need_decorators() if "__stdcall__" in func.attributes: cc = "%s.stdcall" % prefix else: cc = "%s.cdecl" % prefix libname = self.get_sharedlib(dllname) print >> self.stream if self.use_decorators: print >> self.stream, "@ %s(%s, %s, [%s])" % \ (cc, self.type_name(func.returns), libname, ", ".join(args)) argnames = ["p%d" % i for i in range(1, 1+len(args))] # function definition print >> self.stream, "def %s(%s):" % (func.name, ", ".join(argnames)) if func.location: print >> self.stream, " # %s %s" % func.location print >> self.stream, " return %s._api_(%s)" % (func.name, ", ".join(argnames)) if not self.use_decorators: print >> self.stream, "%s = %s(%s, %s, [%s]) (%s)" % \ (func.name, cc, self.type_name(func.returns), libname, ", ".join(args), func.name) print >> self.stream self.names.add(func.name) self._functiontypes += 1 else: self._notfound_functiontypes += 1 def FundamentalType(self, item): pass # we should check if this is known somewhere ## name = ctypes_names[item.name] ## if name != "None": ## print >> self.stream, "from ctypes import %s" % name ## self.done.add(item) ######## def generate(self, item): if item in self.done: return if isinstance(item, typedesc.StructureHead): name = getattr(item.struct, "name", None) else: name = getattr(item, "name", None) if name in self.known_symbols: mod = self.known_symbols[name] print >> self.imports, "from %s import %s" % (mod, name) self.done.add(item) if isinstance(item, typedesc.Structure): self.done.add(item.get_head()) self.done.add(item.get_body()) return mth = getattr(self, type(item).__name__) # to avoid infinite recursion, we have to mark it as done # before actually generating the code. self.done.add(item) mth(item) def generate_all(self, items): for item in items: self.generate(item) def generate_code(self, items, known_symbols, searched_dlls): print >> self.imports, "from ctypes import *" items = set(items) if known_symbols: self.known_symbols = known_symbols else: self.known_symbols = {} self.searched_dlls = searched_dlls loops = 0 while items: loops += 1 self.more = set() self.generate_all(items) items |= self.more items -= self.done self.output.write(self.imports.getvalue()) self.output.write("\n\n") self.output.write(self.stream.getvalue()) return loops def print_stats(self, stream): total = self._structures + self._functiontypes + self._enumtypes + self._typedefs +\ self._pointertypes + self._arraytypes print >> stream, "###########################" print >> stream, "# Symbols defined:" print >> stream, "#" print >> stream, "# Variables: %5d" % self._variables print >> stream, "# Struct/Unions: %5d" % self._structures print >> stream, "# Functions: %5d" % self._functiontypes print >> stream, "# Enums: %5d" % self._enumtypes print >> stream, "# Enum values: %5d" % self._enumvalues print >> stream, "# Typedefs: %5d" % self._typedefs print >> stream, "# Pointertypes: %5d" % self._pointertypes print >> stream, "# Arraytypes: %5d" % self._arraytypes print >> stream, "# unknown functions: %5d" % self._notfound_functiontypes print >> stream, "#" print >> stream, "# Total symbols: %5d" % total print >> stream, "###########################" ################################################################ def generate_code(xmlfile, outfile, expressions=None, symbols=None, verbose=False, use_decorators=False, known_symbols=None, searched_dlls=None, types=None): # expressions is a sequence of compiled regular expressions, # symbols is a sequence of names from gccxmlparser import parse items = parse(xmlfile) todo = [] if types: items = [i for i in items if isinstance(i, types)] if symbols: syms = set(symbols) for i in items: if i.name in syms: todo.append(i) syms.remove(i.name) if syms: print "symbols not found", list(syms) if expressions: for i in items: for s in expressions: if i.name is None: continue match = s.match(i.name) # we only want complete matches if match and match.group() == i.name: todo.append(i) break if symbols or expressions: items = todo gen = Generator(outfile, use_decorators=use_decorators) loops = gen.generate_code(items, known_symbols, searched_dlls) if verbose: gen.print_stats(sys.stderr) print >> sys.stderr, "needed %d loop(s)" % loops --- NEW FILE: cparser_config.py --- # cparser_config.py - configuration items for cparser.py # # XXX should be made platform specific! import re, sys, os # C keywords, according to MSDN, plus some additional # names like __forceinline, near, far. # Skip all definitions where the rhs is a keyword # Example: #define CALLBACK __stdcall # # Hm, should types be handled differently? # Example: #define VOID void C_KEYWORDS = """__asm else main struct __assume enum __multiple_inheritance switch auto __except __single_inheritance template __based explicit __virtual_inheritance this bool extern mutable thread break false naked throw case __fastcall namespace true catch __finally new try __cdecl float noreturn __try char for operator typedef class friend private typeid const goto protected typename const_cast if public union continue inline register unsigned __declspec __inline default int return uuid delete __int8 short __uuidof dllexport __int16 signed virtual dllimport __int32 sizeof void do __int64 static volatile double __leave static_cast wmain dynamic_cast long __stdcall while far near __forceinline __w64 __noop""".split() C_KEYWORDS.append("long long") # defines we know that won't work # for windows.h EXCLUDED_win32 = """ TTTOOLINFOA_V3_SIZE TTTOOLINFOW_V3_SIZE NMLVCUSTOMDRAW_V3_SIZE NOTIFYICONDATAA_V1_SIZE NOTIFYICONDATAA_V2_SIZE PROPSHEETHEADERA_V1_SIZE PROPSHEETHEADERA_V2_SIZE PROPSHEETHEADERW_V2_SIZE NOTIFYICONDATAW_V2_SIZE s_imp s_host s_lh s_net s_addr h_addr s_impno _VARIANT_BOOL MIDL_uhyper WINSCARDDATA __MIDL_DECLSPEC_DLLIMPORT __MIDL_DECLSPEC_DLLEXPORT NCB_POST STDAPI STDAPIV WINAPI SHDOCAPI WINOLEAUTAPI WINOLEAPI APIENTRY EXTERN_C FIRMWARE_PTR STDMETHODIMPV STDMETHODIMP DEFAULT_UNREACHABLE MAXLONGLONG IMAGE_ORDINAL_FLAG64 SECURITY_NT_AUTHORITY """.strip().split() EXCLUDED_linux = """ _IOT_termios """.strip().split() if sys.platform == "win32": EXCLUDED = EXCLUDED_win32 elif sys.platform.startswith("linux"): EXCLUDED = EXCLUDED_linux EXCLUDED = [text for text in EXCLUDED if not text.startswith("#")] EXCLUDED_RE_win32 = r""" ^DECLSPEC\w*$ """.strip().split() EXCLUDED_RE_linux = r""" ^__\w*$ ^__attribute_\w*_$ ^_G_HAVE_ST_BLKSIZE$ """.strip().split() if sys.platform == "win32": EXCLUDED_RE = EXCLUDED_RE_win32 elif sys.platform.startswith("linux"): EXCLUDED_RE = EXCLUDED_RE_linux EXCLUDED_RE = [re.compile(pat) for pat in EXCLUDED_RE if not pat.startswith("#")] --- NEW FILE: cparser.py --- import sys, os, re, tempfile from cparser_config import C_KEYWORDS, EXCLUDED, EXCLUDED_RE import gccxmlparser, typedesc try: import subprocess except ImportError: subprocess = None if sys.platform == "win32": def _locate_gccxml(): import _winreg for subkey in (r"Software\gccxml", r"Software\Kitware\GCC_XML"): for root in (_winreg.HKEY_CURRENT_USER, _winreg.HKEY_LOCAL_MACHINE): try: hkey = _winreg.OpenKey(root, subkey, 0, _winreg.KEY_READ) except WindowsError, detail: if detail.errno != 2: raise else: return _winreg.QueryValueEx(hkey, "loc")[0] + r"\bin" loc = _locate_gccxml() if loc: os.environ["PATH"] = loc class CompilerError(Exception): pass class IncludeParser(object): def create_source_file(self, lines, ext=".cpp"): "Create a temporary file, write lines to it, and return the filename" fd, fname = tempfile.mkstemp(ext, text=True) stream = os.fdopen(fd, "w") if lines: for line in lines: stream.write("%s\n" % line) stream.close() return fname def compile_and_dump(self, lines=None): """Create a temporary source file, dump preprocessor definitions, and remove the source file again.""" fname = self.create_source_file(lines) try: args = ["gccxml", "--preprocess", "-dM", fname] if lines and self.options.flags: args.extend(self.options.flags) if self.options.verbose: print >> sys.stderr, "running:", " ".join(args) if subprocess: proc = subprocess.Popen(args, stdout=subprocess.PIPE, stdin=subprocess.PIPE) data, err = proc.communicate() else: i, o = os.popen4(" ".join(args)) i.close() data = o.read() finally: os.remove(fname) return [line[len("#define "):] for line in data.splitlines() if line.startswith("#define ")] def create_xml(self, lines, xmlfile): """Create a temporary source file, 'compile' with gccxml to an xmlfile, and remove the source file again.""" fname = self.create_source_file(lines) args = ["gccxml", fname, "-fxml=%s" % xmlfile] if self.options.flags: args.extend(self.options.flags) try: if self.options.verbose: print >> sys.stderr, "running:", " ".join(args) if subprocess: retcode = subprocess.call(args) else: retcode = os.system(" ".join(args)) if retcode: raise CompilerError, "gccxml returned %s" % retcode finally: os.remove(fname) def get_defines(self, include_files): """'Compile' an include file with gccxml, and return a dictionary of preprocessor definitions. Empty and compiler internal definitions are not included.""" # compiler internal definitions lines = self.compile_and_dump() predefined = [line.split(None, 1)[0] for line in lines] # all definitions code = ['#include "%s"' % fname for fname in include_files] lines = self.compile_and_dump(code) defined = [line.split(None, 1) for line in lines] # remove empty and compiler internal definitions defined = [pair for pair in defined if len(pair) == 2 and pair[0] not in predefined] return dict(defined) wordpat = re.compile("^[a-zA-Z_][a-zA-Z0-9_]*$") def is_excluded(self, name, value): INVALID_CHARS = "=/{}&;" if "(" in name: return "IS_FUNCTION" if value in C_KEYWORDS: return "value is keyword" if name in EXCLUDED: return "excluded" for pat in EXCLUDED_RE: if pat.match(name): return "excluded (regex)" if value[0] in INVALID_CHARS or value[-1] in INVALID_CHARS: return "cannot be a value" if self.wordpat.match(name) and self.wordpat.match(value): # aliases are handled later, when (and if!) the rhs is known return "IS_ALIAS" return False def filter_definitions(self, defines): """Return a dict of aliases, a dict of fucntion-like macros, and another dict of constants and literals""" result = {} aliases = {} functions = {} excluded = {} for name, value in defines.iteritems(): why = self.is_excluded(name, value) if not why: result[name] = value elif why == "IS_ALIAS": aliases[name] = value elif why == "IS_FUNCTION": functions[name] = value else: excluded[name] = value return aliases, functions, excluded, result ################################################################ def find_types(self, include_files, defines): source = [] for fname in include_files: source.append('#include "%s"' % fname) source.append("#define DECLARE(sym) template <typename T> T symbol_##sym(T) {}") source.append("#define DEFINE(sym) symbol_##sym(sym)") for name in defines: # create a function template for each value source.append("DECLARE(%s)" % name) source.append("int main() {") for name in defines: # instantiate a function template. # The return type of the function is the symbol's type. source.append(" DEFINE(%s);" % name) source.append("}") fd, fname = tempfile.mkstemp(".xml") os.close(fd) self.create_xml(source, fname) try: items = gccxmlparser.parse(fname) finally: # make sure the temporary file is removed after using it os.remove(fname) types = {} for i in items: name = getattr(i, "name", None) if name and name.startswith("symbol_"): name = name[len("symbol_"):] typ = i.returns try: typ = self.c_type_name(i.returns) except TypeError, detail: # XXX Warning? print >> sys.stderr, "skipped #define %s %s" % (name, defines[name]), detail else: types[name] = typ return types def create_final_xml(self, include_files, types): source = [] for fname in include_files: source.append('#include "%s"' % fname) for name, value in types.iteritems(): source.append("const %s cpp_sym_%s = %s;" % (types[name], name, name)) fname = self.options.xmlfile self.create_xml(source, fname) def c_type_name(self, tp): "Return the C type name for this type." if isinstance(tp, typedesc.FundamentalType): return tp.name elif isinstance(tp, typedesc.PointerType): return "%s *" % self.c_type_name(tp.typ) elif isinstance(tp, typedesc.CvQualifiedType): return self.c_type_name(tp.typ) elif isinstance(tp, typedesc.Typedef): return self.c_type_name(tp.typ) elif isinstance(tp, typedesc.Structure): return tp.name raise TypeError, type(tp).__name__ def dump_as_cdata(self, f, mapping, name): f.write(' <CPP_DUMP name="%s"><![CDATA[' % name) names = mapping.keys() names.sort() for n in names: v = mapping[n] f.write("%s %s\n" % (n, v)) f.write("]]></CPP_DUMP>\n") ################################################################ def parse(self, include_files, options): """Main method. The options object must have these attribuites: verbose - integer flags - sequence of strings """ self.options = options if options.verbose: print >> sys.stderr, "finding definitions ..." defines = self.get_defines(include_files) if options.verbose: print >> sys.stderr, "%d found" % len(defines) print >> sys.stderr, "filtering definitions ..." aliases, functions, excluded, defines = self.filter_definitions(defines) if options.verbose: print >> sys.stderr, "%d values, %d aliases" % (len(defines), len(aliases)) if options.verbose: print >> sys.stderr, "finding definitions types ..." # invoke C++ template magic types = self.find_types(include_files, defines) if options.verbose: print >> sys.stderr, "found %d types ..." % len(types) if options.verbose: print >> sys.stderr, "creating xml output file ..." self.create_final_xml(include_files, types) # Include additional preprecessor definitions into the XML file. if self.options.xmlfile: f = open(self.options.xmlfile, "r+") f.seek(-12, 2) data = f.read() if len(data) == 11: # text mode on windows is strange. You read 12 # characters, but get 11. assert data == "</GCC_XML>\n" f.seek(-12, 2) else: # linux, ... assert data == "\n</GCC_XML>\n" f.seek(-11, 2) f.flush() self.dump_as_cdata(f, functions, "functions") self.dump_as_cdata(f, aliases, "aliases") self.dump_as_cdata(f, excluded, "excluded") f.write("</GCC_XML>\n") f.close() --- NEW FILE: typedesc.py --- # typedesc.py - classes representing C type descriptions try: set except NameError: from sets import Set as set class _HasArgs(object): def add_argument(self, arg): self.arguments.append(arg) ################ class Alias(object): # a C preprocessor alias, like #define A B def __init__(self, name, alias, typ=None): self.name = name self.alias = alias self.typ = typ class Macro(object): # a C preprocessor definition with arguments def __init__(self, name, args, body): # all arguments are strings, args is the literal argument list # *with* the parens around it: # Example: Macro("CD_INDRIVE", "(status)", "((int)status > 0)") self.name = name self.args = args self.body = body class File(object): def __init__(self, name): self.name = name class Function(_HasArgs): location = None def __init__(self, name, returns, attributes, extern): self.name = name self.returns = returns self.attributes = attributes # dllimport, __stdcall__, __cdecl__ self.arguments = [] self.extern = extern class Constructor(_HasArgs): location = None def __init__(self, name): self.name = name self.arguments = [] class OperatorFunction(_HasArgs): location = None def __init__(self, name, returns): self.name = name self.returns = returns self.arguments = [] class FunctionType(_HasArgs): location = None def __init__(self, returns, attributes): self.returns = returns self.attributes = attributes self.arguments = [] class Method(_HasArgs): location = None def __init__(self, name, returns): self.name = name self.returns = returns self.arguments = [] class FundamentalType(object): location = None def __init__(self, name, size, align): self.name = name if name != "void": self.size = int(size) self.align = int(align) class PointerType(object): location = None def __init__(self, typ, size, align): self.typ = typ self.size = int(size) self.align = int(align) class Typedef(object): location = None def __init__(self, name, typ): self.name = name self.typ = typ class ArrayType(object): location = None def __init__(self, typ, min, max): self.typ = typ self.min = min self.max = max class StructureHead(object): location = None def __init__(self, struct): self.struct = struct class StructureBody(object): location = None def __init__(self, struct): self.struct = struct class _Struct_Union_Base(object): location = None def get_body(self): return self.struct_body def get_head(self): return self.struct_head class Structure(_Struct_Union_Base): def __init__(self, name, align, members, bases, size, artificial=None): self.name = name self.align = int(align) self.members = members self.bases = bases self.artificial = artificial if size is not None: self.size = int(size) else: self.size = None self.struct_body = StructureBody(self) self.struct_head = StructureHead(self) class Union(_Struct_Union_Base): def __init__(self, name, align, members, bases, size, artificial=None): self.name = name self.align = int(align) self.members = members self.bases = bases self.artificial = artificial if size is not None: self.size = int(size) else: self.size = None self.struct_body = StructureBody(self) self.struct_head = StructureHead(self) class Field(object): def __init__(self, name, typ, bits, offset): self.name = name self.typ = typ self.bits = bits self.offset = int(offset) class CvQualifiedType(object): def __init__(self, typ, const, volatile): self.typ = typ self.const = const self.volatile = volatile class Enumeration(object): location = None def __init__(self, name, size, align): self.name = name self.size = int(size) self.align = int(align) self.values = [] def add_value(self, v): self.values.append(v) class EnumValue(object): def __init__(self, name, value, enumeration): self.name = name self.value = value self.enumeration = enumeration class Variable(object): location = None def __init__(self, name, typ, init=None): self.name = name self.typ = typ self.init = init ################################################################ --- NEW FILE: __init__.py --- # ctypes.wrap package - tools for code generation --- NEW FILE: gccxmlparser.py --- """gccxmlparser - parse a gccxml created XML file into a sequence type descriptions""" import xml.sax import typedesc import sys try: set except NameError: from sets import Set as set import re ################################################################ def MAKE_NAME(name): name = name.replace("$", "DOLLAR") name = name.replace(".", "DOT") if name.startswith("__"): return "_X" + name elif name[0] in "01234567879": return "_" + name return name WORDPAT = re.compile("^[a-zA-Z_][a-zA-Z0-9_]*$") def CHECK_NAME(name): if WORDPAT.match(name): return name return None class GCCXML_Handler(xml.sax.handler.ContentHandler): has_values = set(["Enumeration", "Function", "FunctionType", "OperatorFunction", "Method", "Constructor", "Destructor", "OperatorMethod"]) def __init__(self, *args): xml.sax.handler.ContentHandler.__init__(self, *args) self.context = [] self.all = {} self.cpp_data = {} def startElement(self, name, attrs): # find and call the handler for this element mth = getattr(self, name) result = mth(attrs) if result is not None: location = attrs.get("location", None) if location is not None: result.location = location # record the result _id = attrs.get("id", None) # The '_id' attribute is used to link together all the # nodes, in the _fixup_ methods. if _id is not None: self.all[_id] = result else: # EnumValue, for example, has no "_id" attribute. # Invent our own... self.all[id(result)] = result # if this element has children, push onto the context if name in self.has_values: self.context.append(result) cdata = None def endElement(self, name): # if this element has children, pop the context if name in self.has_values: self.context.pop() self.cdata = None ################################ # do-nothing element handlers def Class(self, attrs): pass def Destructor(self, attrs): pass def GCC_XML(self, attrs): pass def Namespace(self, attrs): pass def Base(self, attrs): pass def Ellipsis(self, attrs): pass def OperatorMethod(self, attrs): pass ################################ # real element handlers def CPP_DUMP(self, attrs): name = attrs["name"] # Insert a new list for each named section into self.cpp_data, # and point self.cdata to it. self.cdata will be set to None # again at the end of each section. self.cpp_data[name] = self.cdata = [] def characters(self, content): if self.cdata is not None: self.cdata.append(content) def File(self, attrs): name = attrs["name"] if sys.platform == "win32" and " " in name: # On windows, convert to short filename if it contains blanks from ctypes import windll, create_unicode_buffer, sizeof, WinError buf = create_unicode_buffer(512) if windll.kernel32.GetShortPathNameW(name, buf, sizeof(buf)): name = buf.value return typedesc.File(name) def _fixup_File(self, f): pass # simple types and modifiers def Variable(self, attrs): name = attrs["name"] if name.startswith("cpp_sym_"): # XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXx fix me! name = name[len("cpp_sym_"):] init = attrs.get("init", None) typ = attrs["type"] return typedesc.Variable(name, typ, init) def _fixup_Variable(self, t): t.typ = self.all[t.typ] def Typedef(self, attrs): name = attrs["name"] typ = attrs["type"] return typedesc.Typedef(name, typ) def _fixup_Typedef(self, t): t.typ = self.all[t.typ] def FundamentalType(self, attrs): name = attrs["name"] if name == "void": size = "" else: size = attrs["size"] align = attrs["align"] return typedesc.FundamentalType(name, size, align) def _fixup_FundamentalType(self, t): pass def PointerType(self, attrs): typ = attrs["type"] size = attrs["size"] align = attrs["align"] return typedesc.PointerType(typ, size, align) 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 typedesc.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.get("const", None) volatile = attrs.get("volatile", None) return typedesc.CvQualifiedType(typ, const, volatile) 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 typedesc.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"] attributes = attrs.get("attributes", "").split() return typedesc.FunctionType(returns, attributes) 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 typedesc.OperatorFunction(name, returns) def _fixup_OperatorFunction(self, func): func.returns = self.all[func.returns] def Constructor(self, attrs): name = attrs["name"] return typedesc.Constructor(name) def _fixup_Constructor(self, const): pass def Method(self, attrs): # name, virtual, pure_virtual, returns name = attrs["name"] returns = attrs["returns"] return typedesc.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"] parent = self.context[-1] if parent is not None: parent.add_argument(typ) # name? # enumerations def Enumeration(self, attrs): # id, name name = attrs["name"] # If the name isn't a valid Python identifier, create an unnamed enum name = CHECK_NAME(name) size = attrs["size"] align = attrs["align"] return typedesc.Enumeration(name, size, align) def _fixup_Enumeration(self, e): pass def EnumValue(self, attrs): name = attrs["name"] value = attrs["init"] v = typedesc.EnumValue(name, value, self.context[-1]) self.context[-1].add_value(v) return v def _fixup_EnumValue(self, e): pass # structures, unions def Struct(self, attrs): # id, name, members name = attrs.get("name") if name is None: name = MAKE_NAME(attrs["mangled"]) bases = attrs.get("bases", "").split() members = attrs.get("members", "").split() align = attrs["align"] size = attrs.get("size") return typedesc.Structure(name, align, members, bases, size) 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") if name is None: name = MAKE_NAME(attrs["mangled"]) bases = attrs.get("bases", "").split() members = attrs.get("members", "").split() align = attrs["align"] size = attrs.get("size") return typedesc.Union(name, align, members, bases, size) def Field(self, attrs): # name, type name = attrs["name"] ## if name.startswith("__") and not name.endswith("__"): ## print "INVALID FIELD NAME", name typ = attrs["type"] bits = attrs.get("bits", None) offset = attrs.get("offset") return typedesc.Field(name, typ, bits, offset) def _fixup_Field(self, f): f.typ = self.all[f.typ] ################ def _fixup_Macro(self, m): pass def get_macros(self, text): if text is None: return text = "".join(text) # preprocessor definitions that look like macros with one or more arguments for m in text.splitlines(): name, body = m.split(None, 1) name, args = name.split("(", 1) args = "(%s" % args self.all[name] = typedesc.Macro(name, args, body) def get_aliases(self, text, namespace): if text is None: return # preprocessor definitions that look like aliases: # #define A B text = "".join(text) aliases = {} for a in text.splitlines(): name, value = a.split(None, 1) a = typedesc.Alias(name, value) aliases[name] = a self.all[name] = a for name, a in aliases.items(): value = a.alias # the value should be either in namespace... if value in namespace: # set the type a.typ = namespace[value] # or in aliases... elif value in aliases: a.typ = aliases[value] # or unknown. else: # not known print "skip %s = %s" % (name, value) def get_result(self): interesting = (typedesc.Typedef, typedesc.Enumeration, typedesc.EnumValue, typedesc.Function, typedesc.Structure, typedesc.Union, typedesc.Variable, typedesc.Macro, typedesc.Alias) self.get_macros(self.cpp_data.get("functions")) remove = [] for n, i in self.all.items(): location = getattr(i, "location", None) if location: fil, line = l... [truncated message content] |
From: Thomas H. <th...@us...> - 2005-02-04 16:50:21
|
Update of /cvsroot/ctypes/ctypes/ctypes/wrap In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv31727/wrap Log Message: Directory /cvsroot/ctypes/ctypes/ctypes/wrap added to the repository |
From: Thomas H. <th...@us...> - 2005-02-04 08:14:39
|
Update of /cvsroot/ctypes/ctypes/sandbox/tools/codegen In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv26737 Modified Files: codegenerator.py Log Message: Oops. Index: codegenerator.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/sandbox/tools/codegen/codegenerator.py,v retrieving revision 1.48 retrieving revision 1.49 diff -C2 -d -r1.48 -r1.49 *** codegenerator.py 4 Feb 2005 08:13:47 -0000 1.48 --- codegenerator.py 4 Feb 2005 08:14:29 -0000 1.49 *************** *** 2,6 **** # Type descriptions are collections of typedesc instances. ! # $Log" # --- 2,9 ---- # Type descriptions are collections of typedesc instances. ! # $Log$ ! # Revision 1.49 2005/02/04 08:14:29 theller ! # Oops. ! # # |
From: Thomas H. <th...@us...> - 2005-02-04 08:13:57
|
Update of /cvsroot/ctypes/ctypes/sandbox/tools/codegen In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv26639 Modified Files: codegenerator.py Log Message: Avoid infinite recursion by marking a typedescription as done just before generating the code. Index: codegenerator.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/sandbox/tools/codegen/codegenerator.py,v retrieving revision 1.47 retrieving revision 1.48 diff -C2 -d -r1.47 -r1.48 *** codegenerator.py 2 Feb 2005 09:25:43 -0000 1.47 --- codegenerator.py 4 Feb 2005 08:13:47 -0000 1.48 *************** *** 2,5 **** --- 2,8 ---- # Type descriptions are collections of typedesc instances. + # $Log" + # + import typedesc, sys *************** *** 552,557 **** return mth = getattr(self, type(item).__name__) ! mth(item) self.done.add(item) def generate_all(self, items): --- 555,562 ---- return mth = getattr(self, type(item).__name__) ! # to avoid infinite recursion, we have to mark it as done ! # before actually generating the code. self.done.add(item) + mth(item) def generate_all(self, items): |
From: Thomas H. <th...@us...> - 2005-02-03 19:39:23
|
Update of /cvsroot/ctypes/ctypes/comtypes In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv12017 Modified Files: automation.py Log Message: Add PARAMFLAGS. Index: automation.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/comtypes/automation.py,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** automation.py 3 Feb 2005 14:15:15 -0000 1.3 --- automation.py 3 Feb 2005 19:39:14 -0000 1.4 *************** *** 5,16 **** from comtypes import IUnknown, GUID, BSTR, STDMETHOD ! PARAMFLAG_NONE = 0 # Variable c_int ! PARAMFLAG_FIN = 1 # Variable c_int ! PARAMFLAG_FOUT = 2 # Variable c_int ! PARAMFLAG_FLCID = 4 # Variable c_int ! PARAMFLAG_FRETVAL = 8 # Variable c_int ! PARAMFLAG_FOPT = 16 # Variable c_int ! PARAMFLAG_FHASDEFAULT = 32 # Variable c_int ! PARAMFLAG_FHASCUSTDATA = 64 # Variable c_int IMPLTYPEFLAG_FDEFAULT = 1 --- 5,16 ---- from comtypes import IUnknown, GUID, BSTR, STDMETHOD ! PARAMFLAG_NONE = 0 ! PARAMFLAG_FIN = 1 ! PARAMFLAG_FOUT = 2 ! PARAMFLAG_FLCID = 4 ! PARAMFLAG_FRETVAL = 8 ! PARAMFLAG_FOPT = 16 ! PARAMFLAG_FHASDEFAULT = 32 ! PARAMFLAG_FHASCUSTDATA = 64 IMPLTYPEFLAG_FDEFAULT = 1 *************** *** 19,22 **** --- 19,43 ---- IMPLTYPEFLAG_FDEFAULTVTABLE = 8 + tagFUNCFLAGS = c_int # enum + FUNCFLAG_FRESTRICTED = 1 + FUNCFLAG_FSOURCE = 2 + FUNCFLAG_FBINDABLE = 4 + FUNCFLAG_FREQUESTEDIT = 8 + FUNCFLAG_FDISPLAYBIND = 16 + FUNCFLAG_FDEFAULTBIND = 32 + FUNCFLAG_FHIDDEN = 64 + FUNCFLAG_FUSESGETLASTERROR = 128 + FUNCFLAG_FDEFAULTCOLLELEM = 256 + FUNCFLAG_FUIDEFAULT = 512 + FUNCFLAG_FNONBROWSABLE = 1024 + FUNCFLAG_FREPLACEABLE = 2048 + FUNCFLAG_FIMMEDIATEBIND = 4096 + FUNCFLAGS = tagFUNCFLAGS + + DISPATCH_PROPERTYPUTREF = 8 + DISPATCH_PROPERTYPUT = 4 + DISPATCH_PROPERTYGET = 2 + DISPATCH_METHOD = 1 + UINT = c_uint # typedef LONG = c_long # typedef |
From: Thomas H. <th...@us...> - 2005-02-03 19:30:43
|
Update of /cvsroot/ctypes/ctypes/source In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv10353 Modified Files: callproc.c Log Message: 'X' is not a recongnized format character for PyErr_Format - replaced by 'x'. Thanks to Toyotomi Hideyoshi for spotting this. Index: callproc.c =================================================================== RCS file: /cvsroot/ctypes/ctypes/source/callproc.c,v retrieving revision 1.125 retrieving revision 1.126 diff -C2 -d -r1.125 -r1.126 *** callproc.c 28 Jan 2005 16:09:47 -0000 1.125 --- callproc.c 3 Feb 2005 19:30:30 -0000 1.126 *************** *** 245,249 **** printf("error %d\n", code); PyErr_Format(PyExc_WindowsError, ! "exception code 0x%08X", code); break; --- 245,249 ---- printf("error %d\n", code); PyErr_Format(PyExc_WindowsError, ! "exception code 0x%08x", code); break; |
From: Thomas H. <th...@us...> - 2005-02-03 14:15:24
|
Update of /cvsroot/ctypes/ctypes/comtypes In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv4345 Modified Files: automation.py Log Message: Implement GetImplTypeFlags. Index: automation.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/comtypes/automation.py,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** automation.py 27 Jan 2005 20:30:04 -0000 1.2 --- automation.py 3 Feb 2005 14:15:15 -0000 1.3 *************** *** 14,17 **** --- 14,22 ---- PARAMFLAG_FHASCUSTDATA = 64 # Variable c_int + IMPLTYPEFLAG_FDEFAULT = 1 + IMPLTYPEFLAG_FSOURCE = 2 + IMPLTYPEFLAG_FRESTRICTED = 4 + IMPLTYPEFLAG_FDEFAULTVTABLE = 8 + UINT = c_uint # typedef LONG = c_long # typedef *************** *** 210,215 **** return hreftype.value ! def GetImplTypeFlags(self, p0, p1): ! pass def GetIDsOfNames(self, p0, p1, p2): --- 215,223 ---- return hreftype.value ! def GetImplTypeFlags(self, index): ! "Return the impltypeflags" ! flags = c_int() ! self.__com_GetImplTypeFlags(index, byref(flags)) ! return flags.value def GetIDsOfNames(self, p0, p1, p2): |
From: Thomas H. <th...@us...> - 2005-02-03 14:10:49
|
Update of /cvsroot/ctypes/ctypes/comtypes/unittests In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv3424 Modified Files: test_basic.py Log Message: Test inheritance. Index: test_basic.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/comtypes/unittests/test_basic.py,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** test_basic.py 13 Jan 2005 09:37:49 -0000 1.2 --- test_basic.py 3 Feb 2005 14:10:41 -0000 1.3 *************** *** 57,60 **** --- 57,67 ---- self.failUnlessEqual(method_count(IMyInterface), 4) + def test_heirarchy(self): + class IMyInterface(IUnknown): + pass + + self.failUnless(issubclass(IMyInterface, IUnknown)) + self.failUnless(issubclass(POINTER(IMyInterface), POINTER(IUnknown))) + def test_mro(self): mro = POINTER(IUnknown).__mro__ |
From: Thomas H. <th...@us...> - 2005-02-03 14:09:40
|
Update of /cvsroot/ctypes/ctypes/comtypes In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv3026 Modified Files: GUID.py Log Message: Add __all__. Index: GUID.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/comtypes/GUID.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** GUID.py 12 Jan 2005 20:53:51 -0000 1.1 --- GUID.py 3 Feb 2005 14:09:12 -0000 1.2 *************** *** 50,51 **** --- 50,59 ---- assert(sizeof(GUID) == 16), sizeof(GUID) + + __all__ = ["GUID"] + + if __name__ == "__main__": + print GUID() + print repr(GUID()) + print GUID().copy() + print GUID(GUID()) |
From: Thomas H. <th...@us...> - 2005-02-03 14:08:37
|
Update of /cvsroot/ctypes/ctypes/comtypes In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv2835 Modified Files: __init__.py Log Message: The _compointer_basr class now overrides the .value attribute from c_void_p. This is mainly for symmetry with other ctypes types. In a COM method implementation, we can now write: def GetInterface(self): p = POINTER(IUnknown)() self.__com_GetInterface(byref(p)) return p.value # <--- here The .value property returns 'self'! Index: __init__.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/comtypes/__init__.py,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** __init__.py 2 Feb 2005 17:58:26 -0000 1.6 --- __init__.py 3 Feb 2005 14:08:27 -0000 1.7 *************** *** 72,82 **** def __del__(self): "Release the COM refcount we own." ! if self.value: self.Release() def __eq__(self, other): if not isinstance(other, _compointer_base): return False ! return self.value == other.value ################################################################ --- 72,102 ---- def __del__(self): "Release the COM refcount we own." ! if self: # calls __nonzero__ self.Release() + + # Hm, shouldn't this be in c_void_p ? + def __nonzero__(self): + # get the value property of the baseclass, this is the pointer value + # both variants below do the same, and both are equally unreadable ;-) + return bool(super(_compointer_base, self).value) + ## return bool(c_void_p.value.__get__(self)) + def __eq__(self, other): + # COM identity rule if not isinstance(other, _compointer_base): return False ! # get the value property of the c_void_p baseclass, this is the pointer value ! return super(_compointer_base, self).value == super(_compointer_base, other).value + # override the .value property of c_void_p + # + # for symmetry with other ctypes types + # XXX explain + def __get_value(self): + return self + value = property(__get_value) + + def __repr__(self): + return "<%s instance at %x>" % (self.__class__.__name__, id(self)) ################################################################ *************** *** 118,122 **** if __name__ == "__main__": ! help(POINTER(IUnknown)) class IMyInterface(IUnknown): --- 138,142 ---- if __name__ == "__main__": ! ## help(POINTER(IUnknown)) class IMyInterface(IUnknown): *************** *** 134,137 **** --- 154,160 ---- windll.oleaut32.CreateTypeLib(1, u"blabla", byref(p)) + + print p + assert (2, 1) == (p.AddRef(), p.Release()) |
From: Thomas H. <th...@us...> - 2005-02-03 10:57:47
|
Update of /cvsroot/ctypes/ctypes/sandbox/tools/codegen In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv560 Modified Files: tlbparser.py Log Message: Lots of changes, but in principle fairly complete now. Index: tlbparser.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/sandbox/tools/codegen/tlbparser.py,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** tlbparser.py 1 Feb 2005 09:34:33 -0000 1.2 --- tlbparser.py 3 Feb 2005 10:57:26 -0000 1.3 *************** *** 26,35 **** VARIANT_BOOL_type = typedesc.Typedef("VARIANT_BOOL", short_type) HRESULT_type = typedesc.Typedef("HRESULT", ulong_type) ! VARIANT_type = typedesc.Typedef("VARIANT", None) # 128 , 32 ? # faked COM data types CURRENCY_type = float_type # wrong ! DATE_type = double_type ! DECIMAL_type = double_type # wrong - it's a 12 byte structure COMTYPES = { --- 26,38 ---- VARIANT_BOOL_type = typedesc.Typedef("VARIANT_BOOL", short_type) HRESULT_type = typedesc.Typedef("HRESULT", ulong_type) ! ! VARIANT_type = typedesc.Typedef("VARIANT", None) # ! IDISPATCH_type = typedesc.Typedef("IDispatch", None) # ! IUNKNOWN_type = typedesc.Typedef("IUnknown", None) # # faked COM data types CURRENCY_type = float_type # wrong ! DATE_type = double_type # not toally wrong... ! DECIMAL_type = double_type # wrong - it's a 12 byte structure (or was it 16 bytes?) COMTYPES = { *************** *** 39,52 **** automation.VT_R8: double_type, # 5 automation.VT_CY: CURRENCY_type, # 6 - automation.VT_DATE: DATE_type, # 7 automation.VT_BSTR: BSTR_type, # 8 ! ! automation.VT_DISPATCH: PTR(int_type), # 9 XXXX ! automation.VT_ERROR: SCODE_type, # 10 automation.VT_BOOL: VARIANT_BOOL_type, # 11 automation.VT_VARIANT: VARIANT_type, # 12 ! automation.VT_UNKNOWN: PTR(int_type), # 13 XXX automation.VT_DECIMAL: DECIMAL_type, # 14 --- 42,52 ---- automation.VT_R8: double_type, # 5 automation.VT_CY: CURRENCY_type, # 6 automation.VT_DATE: DATE_type, # 7 automation.VT_BSTR: BSTR_type, # 8 ! automation.VT_DISPATCH: PTR(IDISPATCH_type), # 9 automation.VT_ERROR: SCODE_type, # 10 automation.VT_BOOL: VARIANT_BOOL_type, # 11 automation.VT_VARIANT: VARIANT_type, # 12 ! automation.VT_UNKNOWN: PTR(IUNKNOWN_type), # 13 automation.VT_DECIMAL: DECIMAL_type, # 14 *************** *** 77,85 **** #automation.VT_BYREF = 16384 # enum VARENUM ! known_symbols = {"VARIANT": "comtypes", "None": "XXX", } ! for name in ("comtypes", "ctypes"): mod = __import__(name) for submodule in name.split(".")[1:]: --- 77,85 ---- #automation.VT_BYREF = 16384 # enum VARENUM ! known_symbols = {#"VARIANT": "comtypes", "None": "XXX", } ! for name in ("comtypes.automation", "comtypes", "ctypes"): mod = __import__(name) for submodule in name.split(".")[1:]: *************** *** 93,97 **** def __init__(self, path): ! self.tlib = automation.LoadTypeLibEx(path) self.items = {} --- 93,97 ---- def __init__(self, path): ! self.tlib = automation.LoadTypeLibEx(path, regkind=automation.REGKIND_REGISTER) self.items = {} *************** *** 175,179 **** dllname, func_name, ordinal = tinfo.GetDllEntry(fd.memid, fd.invkind) ## func_doc = tinfo.GetDocumentation(fd.memid)[1] ! assert 0 == fd.cParamsOpt # ? returns = self.make_type(fd.elemdescFunc.tdesc, tinfo) --- 175,179 ---- dllname, func_name, ordinal = tinfo.GetDllEntry(fd.memid, fd.invkind) ## func_doc = tinfo.GetDocumentation(fd.memid)[1] ! assert 0 == fd.cParamsOpt # XXX returns = self.make_type(fd.elemdescFunc.tdesc, tinfo) *************** *** 193,201 **** func.add_argument(argtype) - # constants are disabled for now, we need VARIANT - # functionality to create them, and codegenerator fixes also. - # But then, constants are not really common in typelibs. - return - # constants for i in range(ta.cVars): --- 193,196 ---- *************** *** 226,238 **** hr = tinfo.GetRefTypeOfImplType(0) tibase = tinfo.GetRefTypeInfo(hr) ! bases = [self.parse_typeinfo(tibase)] else: ! bases = [] members = [] ! itf = typedesc.Structure(itf_name, ! align=32, ! members=members, ! bases=bases, ! size=32) self.items[itf_name] = itf --- 221,233 ---- hr = tinfo.GetRefTypeOfImplType(0) tibase = tinfo.GetRefTypeInfo(hr) ! base = self.parse_typeinfo(tibase) else: ! base = None members = [] ! itf = typedesc.ComInterface(itf_name, ! members=members, ! base=base, ! iid=str(ta.guid), ! wTypeFlags=ta.wTypeFlags) self.items[itf_name] = itf *************** *** 243,257 **** func_name = tinfo.GetDocumentation(fd.memid)[0] returns = self.make_type(fd.elemdescFunc.tdesc, tinfo) ! mth = typedesc.Method(func_name, returns) ! ## assert fd.cParamsOpt == 0, "optional parameters not yet implemented" ! ## print "CUST %s::%s" % (itf_name, func_name), for p in range(fd.cParams): - ## print fd.lprgelemdescParam[p]._.paramdesc.wParamFlags, typ = self.make_type(fd.lprgelemdescParam[p].tdesc, tinfo) ! mth.add_argument(typ) ! ## print itf.members.append(mth) - itf.iid = ta.guid return itf --- 238,266 ---- func_name = tinfo.GetDocumentation(fd.memid)[0] returns = self.make_type(fd.elemdescFunc.tdesc, tinfo) ! names = tinfo.GetNames(fd.memid, fd.cParams+1) ! names.append("rhs") ! names = names[:fd.cParams + 1] ! assert len(names) == fd.cParams + 1 ! mth = typedesc.ComMethod(fd.invkind, func_name, returns, fd.wFuncFlags) ! assert fd.cParamsOpt == 0, "optional parameters not yet implemented" for p in range(fd.cParams): typ = self.make_type(fd.lprgelemdescParam[p].tdesc, tinfo) ! name = names[p+1] ! flags = fd.lprgelemdescParam[p]._.paramdesc.wParamFlags ! if flags & automation.PARAMFLAG_FHASDEFAULT: ! var = fd.lprgelemdescParam[p]._.paramdesc.pparamdescex[0].varDefaultValue ! if var.n1.n2.vt == automation.VT_BSTR: ! default = var.n1.n2.n3.bstrVal ! elif var.n1.n2.vt == automation.VT_I4: ! default = var.n1.n2.n3.iVal ! elif var.n1.n2.vt == automation.VT_BOOL: ! default = bool(var.n1.n2.n3.boolVal) ! else: ! raise "NYI", var.n1.n2.vt ! else: ! default = None ! mth.add_argument(typ, name, flags, default) itf.members.append(mth) return itf *************** *** 259,263 **** def ParseDispatch(self, tinfo, ta): itf_name, doc = tinfo.GetDocumentation(-1)[0:2] - ## print itf_name assert ta.cImplTypes == 1 --- 268,271 ---- *************** *** 282,293 **** assert ta.cFuncs >= 7, "where are the IDispatch methods?" - assert ta.cVars == 0, "properties on interface not yet implemented" for i in range(ta.cVars): vd = tinfo.GetVarDesc(i) ! ## assert vd.varkind == automation.VAR_DISPATCH var_name = tinfo.GetDocumentation(vd.memid)[0] - print "VAR", itf_name, tinfo.GetDocumentation(vd.memid)[0], vd.varkind typ = self.make_type(vd.elemdescVar.tdesc, tinfo) ! mth = typedesc.DispProperty(vd.memid, vd.varkind, var_name, typ) itf.members.append(mth) --- 290,299 ---- assert ta.cFuncs >= 7, "where are the IDispatch methods?" for i in range(ta.cVars): vd = tinfo.GetVarDesc(i) ! assert vd.varkind == automation.VAR_DISPATCH var_name = tinfo.GetDocumentation(vd.memid)[0] typ = self.make_type(vd.elemdescVar.tdesc, tinfo) ! mth = typedesc.DispProperty(vd.memid, vd.varkind, var_name, typ, vd.wVarFlags) itf.members.append(mth) *************** *** 299,304 **** names.append("rhs") names = names[:fd.cParams + 1] ! assert len(names) == fd.cParams + 1 ! mth = typedesc.DispMethod(fd.memid, fd.invkind, func_name, returns) for p in range(fd.cParams): typ = self.make_type(fd.lprgelemdescParam[p].tdesc, tinfo) --- 305,313 ---- names.append("rhs") names = names[:fd.cParams + 1] ! assert len(names) == fd.cParams + 1 # function name first, then parameter names ! mth = typedesc.DispMethod(fd.memid, fd.invkind, func_name, returns, fd.wFuncFlags) ! doc = tinfo.GetDocumentation(fd.memid)[1] ! if doc is not None: ! mth.doc = str(doc) for p in range(fd.cParams): typ = self.make_type(fd.lprgelemdescParam[p].tdesc, tinfo) *************** *** 320,327 **** itf.members.append(mth) - itf.iid = ta.guid return itf ! # TKIND_COCLASS = 5 # TKIND_ALIAS = 6 --- 329,347 ---- itf.members.append(mth) return itf ! # TKIND_COCLASS = 5 + def ParseCoClass(self, tinfo, ta): + # possible ta.wTypeFlags: helpstring, helpcontext, licensed, + # version, control, hidden, and appobject + coclass_name = tinfo.GetDocumentation(-1)[0] + coclass = typedesc.CoClass(coclass_name, str(ta.guid), ta.wTypeFlags) + self.items[coclass_name] = coclass + for i in range(ta.cImplTypes): + hr = tinfo.GetRefTypeOfImplType(i) + ti = tinfo.GetRefTypeInfo(hr) + itf = self.parse_typeinfo(ti) + flags = tinfo.GetImplTypeFlags(i) + coclass.add_interface(itf, flags) # TKIND_ALIAS = 6 *************** *** 377,381 **** elif tkind == automation.TKIND_DISPATCH: # 4 return self.ParseDispatch(tinfo, ta) ! # TKIND_COCLASS = 5 elif tkind == automation.TKIND_ALIAS: # 6 return self.ParseAlias(tinfo, ta) --- 397,402 ---- elif tkind == automation.TKIND_DISPATCH: # 4 return self.ParseDispatch(tinfo, ta) ! elif tkind == automation.TKIND_COCLASS: # 5 ! return self.ParseCoClass(tinfo, ta) elif tkind == automation.TKIND_ALIAS: # 6 return self.ParseAlias(tinfo, ta) *************** *** 383,388 **** return self.ParseUnion(tinfo, ta) else: ! ## raise "NYI", tkind ! print "NYI", tkind ################################################################ --- 404,408 ---- return self.ParseUnion(tinfo, ta) else: ! raise "NYI", tkind ################################################################ *************** *** 399,409 **** import sys ! path = r"hnetcfg.dll" ## path = r"simpdata.tlb" ## path = r"nscompat.tlb" ## path = r"mshtml.tlb" ! ## path = r"stdole32.tlb" ## path = r"c:\tss5\include\MeasurementModule.tlb" ## path = r"c:\tss5\include\fpanel.tlb" ## path = r"x.tlb" ## path = r"shdocvw.dll" --- 419,430 ---- import sys ! ## path = r"hnetcfg.dll" ## path = r"simpdata.tlb" ## path = r"nscompat.tlb" ## path = r"mshtml.tlb" ! path = r"stdole32.tlb" ## path = r"c:\tss5\include\MeasurementModule.tlb" ## path = r"c:\tss5\include\fpanel.tlb" + ## path = "msscript.ocx" ## path = r"x.tlb" ## path = r"shdocvw.dll" *************** *** 419,428 **** ## path = r"C:\Dokumente und Einstellungen\thomas\Desktop\tlb\win32.tlb" ## path = r"MSHFLXGD.OCX" ! ## path = r"scrrun.dll" ## path = r"c:\Programme\Gemeinsame Dateien\Microsoft Shared\Speech\sapi.dll" ## path = r"C:\Dokumente und Einstellungen\thomas\Desktop\tlb\threadapi.tlb" ## path = r"C:\Dokumente und Einstellungen\thomas\Desktop\tlb\win32.tlb" ! ## path = "mytlb.tlb" p = TlbParser(path) --- 440,449 ---- ## path = r"C:\Dokumente und Einstellungen\thomas\Desktop\tlb\win32.tlb" ## path = r"MSHFLXGD.OCX" ! path = r"scrrun.dll" ## path = r"c:\Programme\Gemeinsame Dateien\Microsoft Shared\Speech\sapi.dll" ## path = r"C:\Dokumente und Einstellungen\thomas\Desktop\tlb\threadapi.tlb" ## path = r"C:\Dokumente und Einstellungen\thomas\Desktop\tlb\win32.tlb" ! path = "mytlb.tlb" p = TlbParser(path) |
From: Thomas H. <th...@us...> - 2005-02-02 17:58:51
|
Update of /cvsroot/ctypes/ctypes/comtypes In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv23597 Modified Files: __init__.py Log Message: The actual COM method is _always_ attached with the __com_... private name, and with the actual name only when there is no custom implementation. Index: __init__.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/comtypes/__init__.py,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** __init__.py 2 Feb 2005 15:27:12 -0000 1.5 --- __init__.py 2 Feb 2005 17:58:26 -0000 1.6 *************** *** 57,65 **** impl = getattr(self, name, None) if impl is None: setattr(self, name, mth) ! else: ! mthname = "_%s__com_%s" % (self.__name__, name) ! # attach it with a private name (__com_AddRef, for example) ! setattr(self, mthname, mth) # metaclass for COM interface pointer classes --- 57,65 ---- impl = getattr(self, name, None) if impl is None: + # don't overwrite a custom implementation setattr(self, name, mth) ! # attach it with a private name (__com_AddRef, for example) ! mthname = "_%s__com_%s" % (self.__name__, name) ! setattr(self, mthname, mth) # metaclass for COM interface pointer classes |
From: Thomas H. <th...@us...> - 2005-02-02 15:27:20
|
Update of /cvsroot/ctypes/ctypes/comtypes In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv21815 Modified Files: __init__.py Log Message: Remove the _com_interface base class. It didn't serve a useful purpose. Index: __init__.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/comtypes/__init__.py,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** __init__.py 31 Jan 2005 16:04:50 -0000 1.4 --- __init__.py 2 Feb 2005 15:27:12 -0000 1.5 *************** *** 63,71 **** setattr(self, mthname, mth) ! # metaclass for COM interface pointers class _compointer_meta(type(c_void_p), _cominterface_meta): pass ! # base class for COM interface pointers class _compointer_base(c_void_p): __metaclass__ = _compointer_meta --- 63,71 ---- setattr(self, mthname, mth) ! # metaclass for COM interface pointer classes class _compointer_meta(type(c_void_p), _cominterface_meta): pass ! # base class for COM interface pointer classes class _compointer_base(c_void_p): __metaclass__ = _compointer_meta *************** *** 87,96 **** return restype, name, argtypes - class _com_interface(object): - __metaclass__ = _cominterface_meta - ################################################################ ! class IUnknown(_com_interface): _iid_ = GUID("{00000000-0000-0000-C000-000000000046}") --- 87,94 ---- return restype, name, argtypes ################################################################ ! class IUnknown(object): ! __metaclass__ = _cominterface_meta _iid_ = GUID("{00000000-0000-0000-C000-000000000046}") *************** *** 120,123 **** --- 118,123 ---- if __name__ == "__main__": + help(POINTER(IUnknown)) + class IMyInterface(IUnknown): pass |
From: Thomas H. <th...@us...> - 2005-02-02 09:25:52
|
Update of /cvsroot/ctypes/ctypes/sandbox/tools/codegen In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv9974 Modified Files: codegenerator.py Log Message: Two small fixes. Index: codegenerator.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/sandbox/tools/codegen/codegenerator.py,v retrieving revision 1.46 retrieving revision 1.47 diff -C2 -d -r1.46 -r1.47 *** codegenerator.py 2 Feb 2005 09:18:56 -0000 1.46 --- codegenerator.py 2 Feb 2005 09:25:43 -0000 1.47 *************** *** 286,295 **** else: self.generate(tp.typ) ! if self.type_name(tp.typ) in self.known_symbols: stream = self.imports else: stream = self.stream if tp.name != self.type_name(tp.typ): ! print >> self.stream, "%s = %s" % \ (tp.name, self.type_name(tp.typ)) self.names.add(tp.name) --- 286,295 ---- else: self.generate(tp.typ) ! if self.type_name(tp.typ) in self.known_symbols: stream = self.imports else: stream = self.stream if tp.name != self.type_name(tp.typ): ! print >> stream, "%s = %s" % \ (tp.name, self.type_name(tp.typ)) self.names.add(tp.name) |
From: Thomas H. <th...@us...> - 2005-02-02 09:19:08
|
Update of /cvsroot/ctypes/ctypes/sandbox/tools/codegen In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv8137 Modified Files: codegenerator.py Log Message: Put import statements at the top of the generated code. Generate less comments. Better handling of known_symbols. Import STDMETHOD if needed. Index: codegenerator.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/sandbox/tools/codegen/codegenerator.py,v retrieving revision 1.45 retrieving revision 1.46 diff -C2 -d -r1.45 -r1.46 *** codegenerator.py 31 Jan 2005 10:01:55 -0000 1.45 --- codegenerator.py 2 Feb 2005 09:18:56 -0000 1.46 *************** *** 9,12 **** --- 9,16 ---- from sets import Set as set + try: + import cStringIO as StringIO + except ImportError: + import StringIO *************** *** 130,135 **** class Generator(object): ! def __init__(self, stream, use_decorators=False): ! self.stream = stream self.use_decorators = use_decorators self.done = set() # type descriptions that have been generated --- 134,141 ---- class Generator(object): ! def __init__(self, output, use_decorators=False): ! self.output = output ! self.stream = StringIO.StringIO() ! self.imports = StringIO.StringIO() self.use_decorators = use_decorators self.done = set() # type descriptions that have been generated *************** *** 280,290 **** else: self.generate(tp.typ) if tp.name != self.type_name(tp.typ): ! if getattr(tp, "location", None): ! print >> self.stream, "%s = %s # typedef %s %s" % \ ! (tp.name, self.type_name(tp.typ), tp.location[0], tp.location[1]) ! else: ! print >> self.stream, "%s = %s # typedef" % \ ! (tp.name, self.type_name(tp.typ)) self.names.add(tp.name) --- 286,296 ---- else: self.generate(tp.typ) + if self.type_name(tp.typ) in self.known_symbols: + stream = self.imports + else: + stream = self.stream if tp.name != self.type_name(tp.typ): ! print >> self.stream, "%s = %s" % \ ! (tp.name, self.type_name(tp.typ)) self.names.add(tp.name) *************** *** 338,342 **** value = int(tp.value) print >> self.stream, \ ! "%s = %d # enum %s" % (tp.name, value, tp.enumeration.name or "") self.names.add(tp.name) self._enumvalues += 1 --- 344,348 ---- value = int(tp.value) print >> self.stream, \ ! "%s = %d" % (tp.name, value) self.names.add(tp.name) self._enumvalues += 1 *************** *** 416,419 **** --- 422,426 ---- if methods: + self.need_STDMETHOD() # method definitions normally span several lines. # Before we generate them, we need to 'import' everything they need. *************** *** 469,480 **** if self._cominterface_defined: return ! print >> self.stream, "from comtypes import _com_interface" self._cominterface_defined = True _decorators_defined = False def need_decorators(self): if self._decorators_defined: return "decorators" ! print >> self.stream, "from ctypes import decorators" self._decorators_defined = True return "decorators" --- 476,494 ---- if self._cominterface_defined: return ! print >> self.imports, "from comtypes import _com_interface" self._cominterface_defined = True + _STDMETHOD_defined = False + def need_STDMETHOD(self): + if self._STDMETHOD_defined: + return + print >> self.imports, "from comtypes import STDMETHOD" + self._STDMETHOD_defined = True + _decorators_defined = False def need_decorators(self): if self._decorators_defined: return "decorators" ! print >> self.imports, "from ctypes import decorators" self._decorators_defined = True return "decorators" *************** *** 525,532 **** if item in self.done: return ! name = getattr(item, "name", None) if name in self.known_symbols: ! print >> self.stream, "from %s import %s" % (self.known_symbols[name], name) self.done.add(item) return mth = getattr(self, type(item).__name__) --- 539,553 ---- if item in self.done: return ! if isinstance(item, typedesc.StructureHead): ! name = getattr(item.struct, "name", None) ! else: ! name = getattr(item, "name", None) if name in self.known_symbols: ! mod = self.known_symbols[name] ! print >> self.imports, "from %s import %s" % (mod, name) self.done.add(item) + if isinstance(item, typedesc.Structure): + self.done.add(item.get_head()) + self.done.add(item.get_body()) return mth = getattr(self, type(item).__name__) *************** *** 539,543 **** def generate_code(self, items, known_symbols, searched_dlls): ! print >> self.stream, "from ctypes import *" items = set(items) if known_symbols: --- 560,564 ---- def generate_code(self, items, known_symbols, searched_dlls): ! print >> self.imports, "from ctypes import *" items = set(items) if known_symbols: *************** *** 554,557 **** --- 575,583 ---- items |= self.more items -= self.done + + self.output.write(self.imports.getvalue()) + self.output.write("\n\n") + self.output.write(self.stream.getvalue()) + return loops |
From: Thomas H. <th...@us...> - 2005-02-01 09:34:42
|
Update of /cvsroot/ctypes/ctypes/sandbox/tools/codegen In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv9537 Modified Files: tlbparser.py Log Message: Work in progress. Does now also parse TKIND_INTERFACE and TKIND_DISPATCH. Index: tlbparser.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/sandbox/tools/codegen/tlbparser.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** tlbparser.py 25 Jan 2005 15:53:20 -0000 1.1 --- tlbparser.py 1 Feb 2005 09:34:33 -0000 1.2 *************** *** 62,65 **** --- 62,67 ---- automation.VT_HRESULT: HRESULT_type, # 25 + automation.VT_SAFEARRAY: typedesc.Typedef("SAFEARRAY", None), # 27 + automation.VT_LPSTR: PTR(char_type), # 30 automation.VT_LPWSTR: PTR(wchar_t_type), # 31 *************** *** 67,71 **** #automation.VT_PTR = 26 # enum VARENUM - #automation.VT_SAFEARRAY = 27 # enum VARENUM #automation.VT_CARRAY = 28 # enum VARENUM #automation.VT_USERDEFINED = 29 # enum VARENUM --- 69,72 ---- *************** *** 77,84 **** known_symbols = {"VARIANT": "comtypes", ! "BSTR": "comtypes", ! "None": "ctypes", ! "ERROR": "ctypes", ! "GUID": "comtypes"} ################################################################ --- 78,90 ---- known_symbols = {"VARIANT": "comtypes", ! "None": "XXX", ! } ! ! for name in ("comtypes", "ctypes"): ! mod = __import__(name) ! for submodule in name.split(".")[1:]: ! mod = getattr(mod, submodule) ! for name in mod.__dict__: ! known_symbols[name] = mod.__name__ ################################################################ *************** *** 164,172 **** def ParseModule(self, tinfo, ta): assert 0 == ta.cImplTypes - dllname = tinfo.GetDocumentation(-1)[0] # dllname? # functions for i in range(ta.cFuncs): fd = tinfo.GetFuncDesc(i) ! func_name, func_doc = tinfo.GetDocumentation(fd.memid)[:2] assert 0 == fd.cParamsOpt # ? returns = self.make_type(fd.elemdescFunc.tdesc, tinfo) --- 170,178 ---- def ParseModule(self, tinfo, ta): assert 0 == ta.cImplTypes # functions for i in range(ta.cFuncs): fd = tinfo.GetFuncDesc(i) ! dllname, func_name, ordinal = tinfo.GetDllEntry(fd.memid, fd.invkind) ! ## func_doc = tinfo.GetDocumentation(fd.memid)[1] assert 0 == fd.cParamsOpt # ? returns = self.make_type(fd.elemdescFunc.tdesc, tinfo) *************** *** 191,195 **** # But then, constants are not really common in typelibs. return - # constants --- 197,200 ---- *************** *** 214,220 **** --- 219,336 ---- # TKIND_INTERFACE = 3 + def ParseInterface(self, tinfo, ta): + itf_name, doc = tinfo.GetDocumentation(-1)[0:2] + assert ta.cImplTypes <= 1 + + if ta.cImplTypes: + hr = tinfo.GetRefTypeOfImplType(0) + tibase = tinfo.GetRefTypeInfo(hr) + bases = [self.parse_typeinfo(tibase)] + else: + bases = [] + members = [] + itf = typedesc.Structure(itf_name, + align=32, + members=members, + bases=bases, + size=32) + self.items[itf_name] = itf + + assert ta.cVars == 0, "vars on an Interface?" + + for i in range(ta.cFuncs): + fd = tinfo.GetFuncDesc(i) + func_name = tinfo.GetDocumentation(fd.memid)[0] + returns = self.make_type(fd.elemdescFunc.tdesc, tinfo) + mth = typedesc.Method(func_name, returns) + ## assert fd.cParamsOpt == 0, "optional parameters not yet implemented" + ## print "CUST %s::%s" % (itf_name, func_name), + for p in range(fd.cParams): + ## print fd.lprgelemdescParam[p]._.paramdesc.wParamFlags, + typ = self.make_type(fd.lprgelemdescParam[p].tdesc, tinfo) + mth.add_argument(typ) + ## print + itf.members.append(mth) + + itf.iid = ta.guid + return itf + # TKIND_DISPATCH = 4 + def ParseDispatch(self, tinfo, ta): + itf_name, doc = tinfo.GetDocumentation(-1)[0:2] + ## print itf_name + assert ta.cImplTypes == 1 + + hr = tinfo.GetRefTypeOfImplType(0) + tibase = tinfo.GetRefTypeInfo(hr) + base = self.parse_typeinfo(tibase) + members = [] + itf = typedesc.DispInterface(itf_name, + members=members, + base=base, + iid=str(ta.guid), + wTypeFlags=ta.wTypeFlags) + self.items[itf_name] = itf + + flags = ta.wTypeFlags & (automation.TYPEFLAG_FDISPATCHABLE | automation.TYPEFLAG_FDUAL) + if flags == automation.TYPEFLAG_FDISPATCHABLE: + # dual interface + basemethods = 0 + else: + # pure dispinterface, does only include dispmethods + basemethods = 7 + assert ta.cFuncs >= 7, "where are the IDispatch methods?" + + assert ta.cVars == 0, "properties on interface not yet implemented" + for i in range(ta.cVars): + vd = tinfo.GetVarDesc(i) + ## assert vd.varkind == automation.VAR_DISPATCH + var_name = tinfo.GetDocumentation(vd.memid)[0] + print "VAR", itf_name, tinfo.GetDocumentation(vd.memid)[0], vd.varkind + typ = self.make_type(vd.elemdescVar.tdesc, tinfo) + mth = typedesc.DispProperty(vd.memid, vd.varkind, var_name, typ) + itf.members.append(mth) + + for i in range(basemethods, ta.cFuncs): + fd = tinfo.GetFuncDesc(i) + func_name = tinfo.GetDocumentation(fd.memid)[0] + returns = self.make_type(fd.elemdescFunc.tdesc, tinfo) + names = tinfo.GetNames(fd.memid, fd.cParams+1) + names.append("rhs") + names = names[:fd.cParams + 1] + assert len(names) == fd.cParams + 1 + mth = typedesc.DispMethod(fd.memid, fd.invkind, func_name, returns) + for p in range(fd.cParams): + typ = self.make_type(fd.lprgelemdescParam[p].tdesc, tinfo) + name = names[p+1] + flags = fd.lprgelemdescParam[p]._.paramdesc.wParamFlags + if flags & automation.PARAMFLAG_FHASDEFAULT: + var = fd.lprgelemdescParam[p]._.paramdesc.pparamdescex[0].varDefaultValue + if var.n1.n2.vt == automation.VT_BSTR: + default = var.n1.n2.n3.bstrVal + elif var.n1.n2.vt == automation.VT_I4: + default = var.n1.n2.n3.iVal + elif var.n1.n2.vt == automation.VT_BOOL: + default = bool(var.n1.n2.n3.boolVal) + else: + raise "NYI", var.n1.n2.vt + else: + default = None + mth.add_argument(typ, name, flags, default) + itf.members.append(mth) + + itf.iid = ta.guid + return itf + # TKIND_COCLASS = 5 + # TKIND_ALIAS = 6 + def ParseAlias(self, tinfo, ta): + name = tinfo.GetDocumentation(-1)[0] + typ = self.make_type(ta.tdescAlias, tinfo) + alias = typedesc.Typedef(name, typ) + self.items[name] = alias + return alias + # TKIND_UNION = 7 def ParseUnion(self, tinfo, ta): *************** *** 239,252 **** offset) members.append(field) ! return struct - # TKIND_ALIAS = 6 - def ParseAlias(self, tinfo, ta): - name = tinfo.GetDocumentation(-1)[0] - typ = self.make_type(ta.tdescAlias, tinfo) - alias = typedesc.Typedef(name, typ) - self.items[name] = alias - return alias - ################################################################ --- 355,360 ---- offset) members.append(field) ! return union ################################################################ *************** *** 265,275 **** elif tkind == automation.TKIND_MODULE: # 2 return self.ParseModule(tinfo, ta) elif tkind == automation.TKIND_ALIAS: # 6 return self.ParseAlias(tinfo, ta) elif tkind == automation.TKIND_UNION: # 7 return self.ParseUnion(tinfo, ta) ! ## else: ## raise "NYI", tkind ! ## print "NYI", tkind ################################################################ --- 373,388 ---- elif tkind == automation.TKIND_MODULE: # 2 return self.ParseModule(tinfo, ta) + elif tkind == automation.TKIND_INTERFACE: # 3 + return self.ParseInterface(tinfo, ta) + elif tkind == automation.TKIND_DISPATCH: # 4 + return self.ParseDispatch(tinfo, ta) + # TKIND_COCLASS = 5 elif tkind == automation.TKIND_ALIAS: # 6 return self.ParseAlias(tinfo, ta) elif tkind == automation.TKIND_UNION: # 7 return self.ParseUnion(tinfo, ta) ! else: ## raise "NYI", tkind ! print "NYI", tkind ################################################################ *************** *** 286,311 **** import sys ! ## path = r"c:\windows\system32\hnetcfg.dll" ! ## path = r"c:\windows\system32\simpdata.tlb" ! ## path = r"c:\windows\system32\nscompat.tlb" ! path = r"c:\windows\system32\mshtml.tlb" ## path = r"stdole32.tlb" ! path = r"c:\tss5\include\MeasurementModule.tlb" ! path = r"c:\tss5\include\fpanel.tlb" ## path = r"shdocvw.dll" ## path = r"c:\Programme\Microsoft Office\Office\MSO97.DLL" ## path = r"c:\Programme\Microsoft Office\Office\MSWORD8.OLB" ! ## path = r"c:\windows\system32\msi.dll" ## path = r"c:\tss5\include\ITDPersist.tlb" ! ## path = r"c:\Windows\System32\PICCLP32.OCX" ! ## path = r"c:\windows\system32\Macromed\Flash\swflash.ocx" ## path = r"C:\Dokumente und Einstellungen\thomas\Desktop\tlb\win.tlb" ! ## path = r"C:\WINDOWS\System32\MSHFLXGD.OCX" ! ## path = r"c:\windows\system32\scrrun.dll" ## path = r"c:\Programme\Gemeinsame Dateien\Microsoft Shared\Speech\sapi.dll" ## path = r"C:\Dokumente und Einstellungen\thomas\Desktop\tlb\threadapi.tlb" ! path = r"C:\Dokumente und Einstellungen\thomas\Desktop\tlb\win32.tlb" p = TlbParser(path) --- 399,428 ---- import sys ! path = r"hnetcfg.dll" ! ## path = r"simpdata.tlb" ! ## path = r"nscompat.tlb" ! ## path = r"mshtml.tlb" ## path = r"stdole32.tlb" ! ## path = r"c:\tss5\include\MeasurementModule.tlb" ! ## path = r"c:\tss5\include\fpanel.tlb" ! ## path = r"x.tlb" ## path = r"shdocvw.dll" ## path = r"c:\Programme\Microsoft Office\Office\MSO97.DLL" ## path = r"c:\Programme\Microsoft Office\Office\MSWORD8.OLB" ! ## path = r"msi.dll" ## path = r"c:\tss5\include\ITDPersist.tlb" ! ## path = r"PICCLP32.OCX" ! ## path = r"Macromed\Flash\swflash.ocx" ## path = r"C:\Dokumente und Einstellungen\thomas\Desktop\tlb\win.tlb" ! ## path = r"C:\Dokumente und Einstellungen\thomas\Desktop\tlb\win32.tlb" ! ## path = r"MSHFLXGD.OCX" ! ## path = r"scrrun.dll" ## path = r"c:\Programme\Gemeinsame Dateien\Microsoft Shared\Speech\sapi.dll" ## path = r"C:\Dokumente und Einstellungen\thomas\Desktop\tlb\threadapi.tlb" ! ## path = r"C:\Dokumente und Einstellungen\thomas\Desktop\tlb\win32.tlb" ! ! ## path = "mytlb.tlb" p = TlbParser(path) |
From: Thomas H. <th...@us...> - 2005-01-31 16:05:02
|
Update of /cvsroot/ctypes/ctypes/comtypes In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv7498 Modified Files: __init__.py Log Message: Make sure that, if B is a subclass of A, then POINTER(B) is also a subclass of POINTER(A). This should be true if both A and B are com interfaces. Index: __init__.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/comtypes/__init__.py,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** __init__.py 25 Jan 2005 15:31:11 -0000 1.3 --- __init__.py 31 Jan 2005 16:04:50 -0000 1.4 *************** *** 17,24 **** if methods: setattr(cls, "_methods_", methods) # The interface 'cls' is used as a mixin. # XXX "POINTER(<interface>)" looks nice as class name, but is it ok? p = type(_compointer_base)("POINTER(%s)" % cls.__name__, ! (cls, _compointer_base), {}) from ctypes import _pointer_type_cache --- 17,34 ---- if methods: setattr(cls, "_methods_", methods) + + # If we sublass a COM interface, for example: + # class IDispatch(IUnknown): + # .... + # then we want (need?) that + # POINTER(IDispatch) is a subclass of POINTER(IUnknown). + if bases == (object,): + _ptr_bases = (cls, _compointer_base) + else: + _ptr_bases = (cls, POINTER(bases[0])) # The interface 'cls' is used as a mixin. # XXX "POINTER(<interface>)" looks nice as class name, but is it ok? p = type(_compointer_base)("POINTER(%s)" % cls.__name__, ! _ptr_bases, {}) from ctypes import _pointer_type_cache *************** *** 80,83 **** --- 90,95 ---- __metaclass__ = _cominterface_meta + ################################################################ + class IUnknown(_com_interface): _iid_ = GUID("{00000000-0000-0000-C000-000000000046}") *************** *** 107,110 **** --- 119,129 ---- if __name__ == "__main__": + + class IMyInterface(IUnknown): + pass + + assert issubclass(IMyInterface, IUnknown) + assert issubclass(POINTER(IMyInterface), POINTER(IUnknown)) + POINTER(IUnknown)() |
From: Thomas H. <th...@us...> - 2005-01-31 10:02:18
|
Update of /cvsroot/ctypes/ctypes/sandbox/tools/codegen In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv22656 Modified Files: codegenerator.py Log Message: get_real_type made sense! Index: codegenerator.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/sandbox/tools/codegen/codegenerator.py,v retrieving revision 1.44 retrieving revision 1.45 diff -C2 -d -r1.44 -r1.45 *** codegenerator.py 31 Jan 2005 09:47:39 -0000 1.44 --- codegenerator.py 31 Jan 2005 10:01:55 -0000 1.45 *************** *** 117,123 **** def get_real_type(tp): ! # why was this? ! ## if type(tp) is typedesc.Typedef: ! ## return get_real_type(tp.typ) return tp --- 117,122 ---- def get_real_type(tp): ! if type(tp) is typedesc.Typedef: ! return get_real_type(tp.typ) return tp |
From: Thomas H. <th...@us...> - 2005-01-31 09:47:49
|
Update of /cvsroot/ctypes/ctypes/sandbox/tools/codegen In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv19101 Modified Files: codegenerator.py Log Message: Using 'from ctypes import *' in the generated code again. Index: codegenerator.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/sandbox/tools/codegen/codegenerator.py,v retrieving revision 1.43 retrieving revision 1.44 diff -C2 -d -r1.43 -r1.44 *** codegenerator.py 28 Jan 2005 09:48:20 -0000 1.43 --- codegenerator.py 31 Jan 2005 09:47:39 -0000 1.44 *************** *** 13,37 **** # XXX Should this be in ctypes itself? ctypes_names = { ! "unsigned char": "C.c_ubyte", ! "signed char": "C.c_byte", ! "char": "C.c_char", ! "wchar_t": "C.c_wchar", ! "short unsigned int": "C.c_ushort", ! "short int": "C.c_short", ! "long unsigned int": "C.c_ulong", ! "long int": "C.c_long", ! "long signed int": "C.c_long", ! "unsigned int": "C.c_uint", ! "int": "C.c_int", ! "long long unsigned int": "C.c_ulonglong", ! "long long int": "C.c_longlong", ! "double": "C.c_double", ! "float": "C.c_float", # Hm... --- 13,37 ---- # XXX Should this be in ctypes itself? ctypes_names = { ! "unsigned char": "c_ubyte", ! "signed char": "c_byte", ! "char": "c_char", ! "wchar_t": "c_wchar", ! "short unsigned int": "c_ushort", ! "short int": "c_short", ! "long unsigned int": "c_ulong", ! "long int": "c_long", ! "long signed int": "c_long", ! "unsigned int": "c_uint", ! "int": "c_int", ! "long long unsigned int": "c_ulonglong", ! "long long int": "c_longlong", ! "double": "c_double", ! "float": "c_float", # Hm... *************** *** 118,123 **** def get_real_type(tp): # why was this? ! if type(tp) is typedesc.Typedef: ! return get_real_type(tp.typ) return tp --- 118,123 ---- def get_real_type(tp): # why was this? ! ## if type(tp) is typedesc.Typedef: ! ## return get_real_type(tp.typ) return tp *************** *** 139,149 **** def init_value(self, t, init): tn = self.type_name(t, False) ! if tn in ["C.c_ulonglong", "C.c_ulong", "C.c_uint", "C.c_ushort", "C.c_ubyte"]: return decode_value(init) ! elif tn in ["C.c_longlong", "C.c_long", "C.c_int", "C.c_short", "C.c_byte"]: return decode_value(init) ! elif tn in ["C.c_float", "C.c_double"]: return float(init) ! elif tn == "C.POINTER(C.c_char)": if init[0] == '"': value = eval(init) --- 139,149 ---- def init_value(self, t, init): tn = self.type_name(t, False) ! if tn in ["c_ulonglong", "c_ulong", "c_uint", "c_ushort", "c_ubyte"]: return decode_value(init) ! elif tn in ["c_longlong", "c_long", "c_int", "c_short", "c_byte"]: return decode_value(init) ! elif tn in ["c_float", "c_double"]: return float(init) ! elif tn == "POINTER(c_char)": if init[0] == '"': value = eval(init) *************** *** 151,155 **** value = int(init, 16) return value ! elif tn == "C.POINTER(C.c_wchar)": if init[0] == '"': value = eval(init) --- 151,155 ---- value = int(init, 16) return value ! elif tn == "POINTER(c_wchar)": if init[0] == '"': value = eval(init) *************** *** 160,164 **** value = value.decode("utf-16") # XXX Is this correct? return value ! elif tn == "C.c_void_p": if init[0] == "0": value = int(init, 16) --- 160,164 ---- value = value.decode("utf-16") # XXX Is this correct? return value ! elif tn == "c_void_p": if init[0] == "0": value = int(init, 16) *************** *** 167,178 **** # Hm, ctypes represents them as SIGNED int return value ! elif tn == "C.c_char": return decode_value(init) ! elif tn == "C.c_wchar": value = decode_value(init) if isinstance(value, int): return unichr(value) return value ! elif tn.startswith("C.POINTER("): # Hm, POINTER(HBITMAP__) for example return decode_value(init) --- 167,178 ---- # Hm, ctypes represents them as SIGNED int return value ! elif tn == "c_char": return decode_value(init) ! elif tn == "c_wchar": value = decode_value(init) if isinstance(value, int): return unichr(value) return value ! elif tn.startswith("POINTER("): # Hm, POINTER(HBITMAP__) for example return decode_value(init) *************** *** 182,195 **** def type_name(self, t, generate=True): # Return a string, containing an expression which can be used to ! # refer to the type. Assumes the C.* namespace is available. if isinstance(t, typedesc.PointerType): ! result = "C.POINTER(%s)" % self.type_name(t.typ, generate) # XXX Better to inspect t.typ! ! if result.startswith("C.POINTER(C.WINFUNCTYPE"): ! return result[len("C.POINTER("):-1] ! if result.startswith("C.POINTER(C.CFUNCTYPE"): ! return result[len("C.POINTER("):-1] ! elif result == "C.POINTER(None)": ! return "C.c_void_p" return result elif isinstance(t, typedesc.ArrayType): --- 182,195 ---- def type_name(self, t, generate=True): # Return a string, containing an expression which can be used to ! # refer to the type. Assumes the * namespace is available. if isinstance(t, typedesc.PointerType): ! result = "POINTER(%s)" % self.type_name(t.typ, generate) # XXX Better to inspect t.typ! ! if result.startswith("POINTER(WINFUNCTYPE"): ! return result[len("POINTER("):-1] ! if result.startswith("POINTER(CFUNCTYPE"): ! return result[len("POINTER("):-1] ! elif result == "POINTER(None)": ! return "c_void_p" return result elif isinstance(t, typedesc.ArrayType): *************** *** 198,204 **** args = [self.type_name(x, generate) for x in [t.returns] + t.arguments] if "__stdcall__" in t.attributes: ! return "C.WINFUNCTYPE(%s)" % ", ".join(args) else: ! return "C.CFUNCTYPE(%s)" % ", ".join(args) elif isinstance(t, typedesc.CvQualifiedType): # const and volatile are ignored --- 198,204 ---- args = [self.type_name(x, generate) for x in [t.returns] + t.arguments] if "__stdcall__" in t.attributes: ! return "WINFUNCTYPE(%s)" % ", ".join(args) else: ! return "CFUNCTYPE(%s)" % ", ".join(args) elif isinstance(t, typedesc.CvQualifiedType): # const and volatile are ignored *************** *** 211,215 **** if t.name: return t.name ! return "C.c_int" # enums are integers elif isinstance(t, typedesc.Typedef): return t.name --- 211,215 ---- if t.name: return t.name ! return "c_int" # enums are integers elif isinstance(t, typedesc.Typedef): return t.name *************** *** 257,263 **** print >> self.stream, "class %s(_com_interface):" % head.struct.name elif type(head.struct) == typedesc.Structure: ! print >> self.stream, "class %s(C.Structure):" % head.struct.name elif type(head.struct) == typedesc.Union: ! print >> self.stream, "class %s(C.Union):" % head.struct.name if head.struct.location: print >> self.stream, " # %s %s" % head.struct.location --- 257,263 ---- print >> self.stream, "class %s(_com_interface):" % head.struct.name elif type(head.struct) == typedesc.Structure: ! print >> self.stream, "class %s(Structure):" % head.struct.name elif type(head.struct) == typedesc.Union: ! print >> self.stream, "class %s(Union):" % head.struct.name if head.struct.location: print >> self.stream, " # %s %s" % head.struct.location *************** *** 348,352 **** if tp.name: print >> self.stream ! print >> self.stream, "%s = C.c_int # enum" % tp.name for item in tp.values: self.generate(item) --- 348,352 ---- if tp.name: print >> self.stream ! print >> self.stream, "%s = c_int # enum" % tp.name for item in tp.values: self.generate(item) *************** *** 410,417 **** if body.struct.size and body.struct.name not in dont_assert_size: size = body.struct.size // 8 ! print >> self.stream, "assert C.sizeof(%s) == %s, C.sizeof(%s)" % \ (body.struct.name, size, body.struct.name) align = body.struct.align // 8 ! print >> self.stream, "assert C.alignment(%s) == %s, C.alignment(%s)" % \ (body.struct.name, align, body.struct.name) --- 410,417 ---- if body.struct.size and body.struct.name not in dont_assert_size: size = body.struct.size // 8 ! print >> self.stream, "assert sizeof(%s) == %s, sizeof(%s)" % \ (body.struct.name, size, body.struct.name) align = body.struct.align // 8 ! print >> self.stream, "assert alignment(%s) == %s, alignment(%s)" % \ (body.struct.name, align, body.struct.name) *************** *** 429,433 **** for m in methods: args = [self.type_name(a) for a in m.arguments] ! print >> self.stream, " C.STDMETHOD(%s, '%s', [%s])," % ( self.type_name(m.returns), m.name, --- 429,433 ---- for m in methods: args = [self.type_name(a) for a in m.arguments] ! print >> self.stream, " STDMETHOD(%s, '%s', [%s])," % ( self.type_name(m.returns), m.name, *************** *** 463,467 **** name, ext = os.path.splitext(basename) self._loadedlibs[dllname] = name ! print >> self.stream, "%s = C.CDLL(%r)" % (name, dllname) return name --- 463,467 ---- name, ext = os.path.splitext(basename) self._loadedlibs[dllname] = name ! print >> self.stream, "%s = CDLL(%r)" % (name, dllname) return name *************** *** 540,544 **** def generate_code(self, items, known_symbols, searched_dlls): ! print >> self.stream, "import ctypes as C" items = set(items) if known_symbols: --- 540,544 ---- def generate_code(self, items, known_symbols, searched_dlls): ! print >> self.stream, "from ctypes import *" items = set(items) if known_symbols: |
From: Thomas H. <th...@us...> - 2005-01-31 08:42:53
|
Update of /cvsroot/ctypes/ctypes/sandbox/tools/codegen In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv4088 Modified Files: VARIANT.py Log Message: Added VARENUM. Index: VARIANT.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/sandbox/tools/codegen/VARIANT.py,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** VARIANT.py 30 Jan 2005 10:30:41 -0000 1.3 --- VARIANT.py 31 Jan 2005 08:42:44 -0000 1.4 *************** *** 87,90 **** --- 87,144 ---- VARKIND = tagVARKIND + VARENUM = c_int + VT_EMPTY = 0 + VT_NULL = 1 + VT_I2 = 2 + VT_I4 = 3 + VT_R4 = 4 + VT_R8 = 5 + VT_CY = 6 + VT_DATE = 7 + VT_BSTR = 8 + VT_DISPATCH = 9 + VT_ERROR = 10 + VT_BOOL = 11 + VT_VARIANT = 12 + VT_UNKNOWN = 13 + VT_DECIMAL = 14 + VT_I1 = 16 + VT_UI1 = 17 + VT_UI2 = 18 + VT_UI4 = 19 + VT_I8 = 20 + VT_UI8 = 21 + VT_INT = 22 + VT_UINT = 23 + VT_VOID = 24 + VT_HRESULT = 25 + VT_PTR = 26 + VT_SAFEARRAY = 27 + VT_CARRAY = 28 + VT_USERDEFINED = 29 + VT_LPSTR = 30 + VT_LPWSTR = 31 + VT_RECORD = 36 + VT_INT_PTR = 37 + VT_UINT_PTR = 38 + VT_FILETIME = 64 + VT_BLOB = 65 + VT_STREAM = 66 + VT_STORAGE = 67 + VT_STREAMED_OBJECT = 68 + VT_STORED_OBJECT = 69 + VT_BLOB_OBJECT = 70 + VT_CF = 71 + VT_CLSID = 72 + VT_VERSIONED_STREAM = 73 + VT_BSTR_BLOB = 4095 + VT_VECTOR = 4096 + VT_ARRAY = 8192 + VT_BYREF = 16384 + VT_RESERVED = 32768 + VT_ILLEGAL = 65535 + VT_ILLEGALMASKED = 4095 + VT_TYPEMASK = 4095 + ################################################################ # forward declaration of com interfaces |
From: Thomas H. <th...@us...> - 2005-01-30 10:30:52
|
Update of /cvsroot/ctypes/ctypes/sandbox/tools/codegen In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv6109 Modified Files: VARIANT.py Log Message: Refactored DECIMAL into human readable code. Index: VARIANT.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/sandbox/tools/codegen/VARIANT.py,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** VARIANT.py 30 Jan 2005 10:05:01 -0000 1.2 --- VARIANT.py 30 Jan 2005 10:30:41 -0000 1.3 *************** *** 224,285 **** # DECIMAL ! class tagDEC(Structure): ! pass ! DECIMAL = tagDEC ! class N6tagDEC5DOLLAR_144E(Union): ! # C:/PROGRA~1/MICROS~3.NET/Vc7/PLATFO~1/Include/wtypes.h 1022 ! pass ! class N6tagDEC5DOLLAR_1445DOLLAR_145E(Structure): ! # C:/PROGRA~1/MICROS~3.NET/Vc7/PLATFO~1/Include/wtypes.h 1023 ! pass ! N6tagDEC5DOLLAR_1445DOLLAR_145E._fields_ = [ ! # C:/PROGRA~1/MICROS~3.NET/Vc7/PLATFO~1/Include/wtypes.h 1023 ! ('scale', c_ubyte), ! ('sign', c_ubyte), ! ] ! assert sizeof(N6tagDEC5DOLLAR_1445DOLLAR_145E) == 2, sizeof(N6tagDEC5DOLLAR_1445DOLLAR_145E) ! assert alignment(N6tagDEC5DOLLAR_1445DOLLAR_145E) == 1, alignment(N6tagDEC5DOLLAR_1445DOLLAR_145E) ! N6tagDEC5DOLLAR_144E._fields_ = [ ! # C:/PROGRA~1/MICROS~3.NET/Vc7/PLATFO~1/Include/wtypes.h 1022 ! # Unnamed field renamed to '_' ! ('_', N6tagDEC5DOLLAR_1445DOLLAR_145E), ! ('signscale', c_ushort), ! ] ! assert sizeof(N6tagDEC5DOLLAR_144E) == 2, sizeof(N6tagDEC5DOLLAR_144E) ! assert alignment(N6tagDEC5DOLLAR_144E) == 2, alignment(N6tagDEC5DOLLAR_144E) ! class N6tagDEC5DOLLAR_146E(Union): ! # C:/PROGRA~1/MICROS~3.NET/Vc7/PLATFO~1/Include/wtypes.h 1030 ! pass ! class N6tagDEC5DOLLAR_1465DOLLAR_147E(Structure): ! # C:/PROGRA~1/MICROS~3.NET/Vc7/PLATFO~1/Include/wtypes.h 1031 ! pass ! N6tagDEC5DOLLAR_1465DOLLAR_147E._fields_ = [ ! # C:/PROGRA~1/MICROS~3.NET/Vc7/PLATFO~1/Include/wtypes.h 1031 ! ('Lo32', c_ulong), ! ('Mid32', c_ulong), ! ] ! assert sizeof(N6tagDEC5DOLLAR_1465DOLLAR_147E) == 8, sizeof(N6tagDEC5DOLLAR_1465DOLLAR_147E) ! assert alignment(N6tagDEC5DOLLAR_1465DOLLAR_147E) == 4, alignment(N6tagDEC5DOLLAR_1465DOLLAR_147E) ! N6tagDEC5DOLLAR_146E._fields_ = [ ! # C:/PROGRA~1/MICROS~3.NET/Vc7/PLATFO~1/Include/wtypes.h 1030 ! # Unnamed field renamed to '_' ! ('_', N6tagDEC5DOLLAR_1465DOLLAR_147E), ! ('Lo64', c_ulonglong), ! ] ! assert sizeof(N6tagDEC5DOLLAR_146E) == 8, sizeof(N6tagDEC5DOLLAR_146E) ! assert alignment(N6tagDEC5DOLLAR_146E) == 8, alignment(N6tagDEC5DOLLAR_146E) ! tagDEC._fields_ = [ ! # C:/PROGRA~1/MICROS~3.NET/Vc7/PLATFO~1/Include/wtypes.h 1020 ! ('wReserved', c_ushort), ! # Unnamed field renamed to '_' ! ('_', N6tagDEC5DOLLAR_144E), ! ('Hi32', c_ulong), ! # Unnamed field renamed to '_1' ! ('_1', N6tagDEC5DOLLAR_146E), ! ] assert sizeof(tagDEC) == 16, sizeof(tagDEC) assert alignment(tagDEC) == 8, alignment(tagDEC) ################################################################ # VARIANT --- 224,272 ---- # DECIMAL ! # A fixed point decimal number, stored as 12-byte integer, scaled by ! # scale which is between 0 and 28. Sign stored separately. ! class _tagDEC_144E(Union): ! class _tagDEC_1445DOLLAR_145E(Structure): ! _fields_ = [ ! ('scale', c_ubyte), ! ('sign', c_ubyte), ! ] ! _fields_ = [ ! # Unnamed field renamed to '_' ! ('_', _tagDEC_1445DOLLAR_145E), ! ('signscale', c_ushort), ! ] ! assert sizeof(_tagDEC_144E) == 2, sizeof(_tagDEC_144E) ! assert alignment(_tagDEC_144E) == 2, alignment(_tagDEC_144E) ! class _tagDEC_146E(Union): ! class _tagDEC_1465DOLLAR_147E(Structure): ! _fields_ = [ ! ('Lo32', c_ulong), ! ('Mid32', c_ulong), ! ] ! _fields_ = [ ! # Unnamed field renamed to '_' ! ('_', _tagDEC_1465DOLLAR_147E), ! ('Lo64', c_ulonglong), ! ] ! assert sizeof(_tagDEC_146E) == 8, sizeof(_tagDEC_146E) ! assert alignment(_tagDEC_146E) == 8, alignment(_tagDEC_146E) ! ! class tagDEC(Structure): ! _fields_ = [ ! # C:/PROGRA~1/MICROS~3.NET/Vc7/PLATFO~1/Include/wtypes.h 1020 ! ('wReserved', c_ushort), ! # Unnamed field renamed to '_' ! ('_', _tagDEC_144E), ! ('Hi32', c_ulong), ! # Unnamed field renamed to '_1' ! ('_1', _tagDEC_146E), ! ] assert sizeof(tagDEC) == 16, sizeof(tagDEC) assert alignment(tagDEC) == 8, alignment(tagDEC) + DECIMAL = tagDEC + ################################################################ # VARIANT |
From: Thomas H. <th...@us...> - 2005-01-30 10:05:11
|
Update of /cvsroot/ctypes/ctypes/sandbox/tools/codegen In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv797 Modified Files: VARIANT.py Log Message: Refactored CURRENCY into readable code. Index: VARIANT.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/sandbox/tools/codegen/VARIANT.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** VARIANT.py 28 Jan 2005 21:13:11 -0000 1.1 --- VARIANT.py 30 Jan 2005 10:05:01 -0000 1.2 *************** *** 201,230 **** ################################################################ ! ## CY start class tagCY(Union): ! # C:/PROGRA~1/MICROS~3.NET/Vc7/PLATFO~1/Include/wtypes.h 990 ! pass ! class N5tagCY5DOLLAR_143E(Structure): ! # C:/PROGRA~1/MICROS~3.NET/Vc7/PLATFO~1/Include/wtypes.h 991 ! pass ! N5tagCY5DOLLAR_143E._fields_ = [ ! # C:/PROGRA~1/MICROS~3.NET/Vc7/PLATFO~1/Include/wtypes.h 991 ! ('Lo', c_ulong), ! ('Hi', c_long), ! ] ! assert sizeof(N5tagCY5DOLLAR_143E) == 8, sizeof(N5tagCY5DOLLAR_143E) ! assert alignment(N5tagCY5DOLLAR_143E) == 4, alignment(N5tagCY5DOLLAR_143E) ! tagCY._fields_ = [ ! # C:/PROGRA~1/MICROS~3.NET/Vc7/PLATFO~1/Include/wtypes.h 990 ! # Unnamed field renamed to '_' ! ('_', N5tagCY5DOLLAR_143E), ! ('int64', c_longlong), ! ] assert sizeof(tagCY) == 8, sizeof(tagCY) assert alignment(tagCY) == 8, alignment(tagCY) CY = tagCY ! CURRENY = tagCY ################################################################ --- 201,223 ---- ################################################################ ! ## CURRENCY + # A fixed point decimal number, stored as integer scaled by 10000. class tagCY(Union): ! class _tagCY_143E(Structure): ! _fields_ = [ ! ('Lo', c_ulong), ! ('Hi', c_long), ! ] ! _fields_ = [ ! # Unnamed field renamed to '_' ! ('_', _tagCY_143E), ! ('int64', c_longlong), ! ] assert sizeof(tagCY) == 8, sizeof(tagCY) assert alignment(tagCY) == 8, alignment(tagCY) CY = tagCY ! CURRENCY = tagCY ################################################################ |
From: Thomas H. <th...@us...> - 2005-01-29 22:07:02
|
Update of /cvsroot/ctypes/ctypes/sandbox/tools/codegen In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv23369 Modified Files: README.txt Log Message: Markup improvements. Index: README.txt =================================================================== RCS file: /cvsroot/ctypes/ctypes/sandbox/tools/codegen/README.txt,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** README.txt 29 Jan 2005 21:42:22 -0000 1.1 --- README.txt 29 Jan 2005 22:06:52 -0000 1.2 *************** *** 69,73 **** C:\> ! Generate code for the RECT structure:: C:\>xml2py.py windows.xml -s RECT --- 69,73 ---- C:\> ! Generate code for the ``RECT`` structure:: C:\>xml2py.py windows.xml -s RECT *************** *** 87,91 **** C:\> ! Generate the MB_xxx constants, which are flags used for the MessageBox function:: c:\>python xml2py.py windows.xml -r MB_.* --- 87,91 ---- C:\> ! Generate the ``MB_xxx`` constants, which are flags used for the ``MessageBox`` function:: c:\>python xml2py.py windows.xml -r MB_.* *************** *** 133,137 **** C:\> ! Generate code for the RegisterClass function, please note how this pulls in a lot of types:: --- 133,137 ---- C:\> ! Generate code for the ``RegisterClass`` function, note how this pulls in a lot of types:: *************** *** 188,195 **** C:\>python xml2py.py win_lean.xml -w -o win_lean.py ! Create a Python module ``SDL.py`` containing wrappers for the SDL library. To work around a problem gccxml has with a certain construct ! in the SDL header files, you must define the SDLCALL macro to an empty ! value:: C:\>python h2xml.py SDL.h -I SDL\include -D SDLCALL= -o SDL.xml -q --- 188,195 ---- C:\>python xml2py.py win_lean.xml -w -o win_lean.py ! Create a Python module ``SDL.py`` containing wrappers for the ``SDL`` library. To work around a problem gccxml has with a certain construct ! in the SDL header files on Windows, you must define the ``SDLCALL`` ! macro to an empty value:: C:\>python h2xml.py SDL.h -I SDL\include -D SDLCALL= -o SDL.xml -q *************** *** 244,258 **** Specifies the kind of types to include in the output: ! d = simple preprocessor definitions: #define <identifier> <identifier> ! e = enumerations ! f = function declarations ! m = preprocessor macros taking parameters: #define <ident>(parameters) something ! s = structures and unions ! t = typedefs ``-l sharedlib`` --- 244,258 ---- Specifies the kind of types to include in the output: ! ``d`` - simple preprocessor definitions: #define <identifier> <identifier> ! ``e`` - enumerations ! ``f`` - function declarations ! ``m`` - preprocessor macros taking parameters: #define <ident>(parameters) something ! ``s`` - structures and unions ! ``t`` - typedefs ``-l sharedlib`` |