#!/usr/bin/env python # -*- Mode: Python; py-indent-offset: 4 -*- # # Copyright (C) 2006-2009 John Finlay. # # Scan the given public .h files of a GTK module (or module using # GTK object conventions) and generates a set of scheme defs. # # defsgen uses the ctypes module to extract information from the installed # module library (or libraries) to generate the object, interface, function, # method, virtual, enum and flags defs. defsgen uses the gobject library # g_type_* functions. defsgen will try to open the "libgobject-2.0.so" library # if one is not specified on the command line. # # Basically the operation of defsgen is: # # - open and initialize the gobject and module libraries # - read each .h file into a buffer which is scrubbed of extraneous data # - find all *_get_type() functions prototypes # - look in the module libraries for the get_type symbols # - if found run the get_type() function to retrieve the GType # - find the parent type name and save the object info # - find each function prototypes in the file and check if it has a symbol in # the module libraries - save the info if found # - extract the virtual prototypes from the Class or Iface structs and save # - write out the various defs. # # The command line options are: # # -l --modulelib Adds the given module library name to the list to be used # for finding symbols. Mor ethan one modulefile may be # specified. (required) # -L --libgobject Specifies the name of the gobject library (optional but # must be specified if "libgobject-2.0.so" is not availble) # -s --separate Create separate files for objects and function/method defs # using the given name as the base name (optional). If this # is not specified the combined object and function defs # will be output to sys.stdout. # -f --defsfile Extract defs from the given file to filter the output defs # that is don't output defs that are defined in the # defsfile. More than one deffile may be specified. # -D --defines Include portions of the defsfile defs that are conditional # on the given define, for example GDK_TARGET_X11. Only # useful with the --defsfile option # -m --modulename The prefix to be stripped from the front of function names # for the given module # -p --useprefix Use the modulename prefix as a hint to split names into # module and name for object and enum defs. Also used for # generating type codes. # --onlyenums Only produce defs for enums and flags # --onlyobjdefs Only produce defs for objects # --onlyvirtuals Only produce defs for virtuals # --genpropgetsets Experimental option to generate prop-getset annotations. # Not supported by codegen.py and friends. # # Examples: # # python defsgen.py -m pango -l libpango-1.0.so \ # /usr/local/include/pango-1.0/pango/*.h >/tmp/pango.defs # # - Outputs all defs for the pango module.using the library module # libpango-1.0.so. # # python defsgen.py -m gdk -DGDK_TARGET_X11 -l libgdk-x11-2.0.so \ # -l libgdk_pixbuf-2.0.so -s /tmp/gdk-2.10 \ # -f /usr/tmp/pygtk/gtk/gdk-base.defs \ # /usr/local/include/gtk-2.0/gdk/*.h \ # /usr/local/include/gtk-2.0/gdk-pixbuf/*.h # # - Outputs the gdk module defs that are not contained in the defs file # /usr/tmp/pygtk/gtk/gdk-base.defs. Two output files are created: # /tmp/gdk-2.10-types.defs and /tmp/gdk-2.10.defs. # # Based on the original h2def.py program by # Toby D. Reeves and # modified by James Henstridge to output stuff in # Havoc's new defs format. Info on this format can be seen at: # http://www.gnome.org/mailing-lists/archives/gtk-devel-list/2000-January/0085.shtml # Updated to be PEP-8 compatible and refactored to use OOP # Extensively modified by John Finlay to use ctypes module to extract GType # info from the given library and to create virtual defines. # import getopt import os import re, string import sys import ctypes import defsparser #------------------ utility defs ----------------- _upperstr_pat1 = re.compile(r'([^A-Z])([A-Z])') _upperstr_pat2 = re.compile(r'([A-Z][A-Z])([A-Z][0-9a-z])') _upperstr_pat3 = re.compile(r'^([A-Z])([A-Z])') def to_upper_str(name): """Converts a typename to the equivalent uppercase and underscores name. This is used to form the type conversion macros and enum/flag name variables""" name = _upperstr_pat1.sub(r'\1_\2', name) name = _upperstr_pat2.sub(r'\1_\2', name) name = _upperstr_pat3.sub(r'\1_\2', name, count=1) return name.upper() def typecode(typename, prefix, use_prefix): """create a typecode (eg. GTK_TYPE_WIDGET) from a typename""" tcode = to_upper_str(typename) if (use_prefix and prefix and tcode.lower() != prefix and tcode.lower().startswith(prefix)): l = len(prefix) tcode = tcode[:l] + '_TYPE' + tcode[l:] else: tcode = tcode.replace('_', '_TYPE_', 1) return tcode _class_iface_pat = re.compile(r'\w+(Class|Iface)') def class_iface_sub(mobj): '''Returns matched string if it matches a Class or Iface struct otherwise returns the empty string''' if not _class_iface_pat.match(mobj.group(1)): return '' return mobj.group(0) clean_patterns = [ # strip comments (re.compile(r'/\*.*?\*/', re.DOTALL), ''), # compact continued lines (re.compile(r"\\\n", re.MULTILINE), ''), # remove preprocess directives (re.compile(r"""^[#].*?$""", re.MULTILINE), ''), # strip DECLS macros and Windows DLL API macros (re.compile(r"""G_BEGIN_DECLS|BEGIN_LIBGTOP_DECLS|G_END_DECLS|[A-Z]+_API """, re.MULTILINE), ''), # remove extern "C" (re.compile(r'^\s*(extern)\s+"C"\s+{', re.MULTILINE), ''), # remove singleline typedefs of stucts (re.compile(r'^typedef\s+struct\s*[^{;\n]*;\s*$', re.MULTILINE), ''), # remove all struct definitons but those for object classes and interfaces (re.compile(r'^struct\s+(\w+)\s+{[^}]+}\s*;\s*$', re.MULTILINE), class_iface_sub), # compress multiple whitespace (re.compile(r'\s+', re.MULTILINE), ' '), # clean up line ends (re.compile(r';\s*', re.MULTILINE), '\n'), (re.compile(r'^\s*', re.MULTILINE), ''), # associate *, &, and [] with type instead of variable (re.compile(r' \s* ([*|&]+) \s* ([(\w]+)', re.VERBOSE), r'\1 \2'), (re.compile(r'\s+ (\w+) \[ \s* \]', re.VERBOSE), r'[] \1'), # make return types that are const work. (re.compile(r'\s*\*\s*G_CONST_RETURN\s*\*\s*'), '** '), (re.compile(r'G_CONST_RETURN |const '), 'const-'), # remove typedefs of callback types (re.compile(r'^typedef\s+\w+\s*\*?\s*\(\s*\*\s*\w+\)\s*\([^(]*\)\n', re.MULTILINE), ''), #strip GSEAL macros from the middle of function declarations: (re.compile(r"""GSEAL""", re.VERBOSE), '') ] def clean_buffer(buf): """Cleans out extraneous data leaving function prototypes, Class and Iface structs.""" for pat, subst in clean_patterns: buf = pat.sub(subst, buf) return buf # ------------------ utility classes ------------------------- class ObjDef(object): def __init__(self, name, type_id, parent_name, parent_type, base_name): self.name = name self.type = type_id self.parent_name = parent_name self.parent_type = parent_type self.base_name = base_name self.props = [] return def __cmp__(self, other): try: res = cmp(self.name, other.name) except AttributeError: res = cmp(id(self), id(other)) return res def set_properties(self, gobj): if self.base_name == 'GObject': self.props = self._get_gobject_properties(gobj) elif self.base_name == 'GInterface': self.props = self._get_ginterface_properties(gobj) def _get_gobject_properties(self, gobj): klass = gobj.g_type_class_ref(self.type) num = ctypes.c_uint() plist = gobj.g_object_class_list_properties(klass, ctypes.byref(num)) props = [plist[i][0].name for i in range(num.value) if self.name == gobj.g_type_name(plist[i][0].owner_type)] return props def _get_ginterface_properties(self, gobj): iface = gobj.g_type_default_interface_ref(self.type) num = ctypes.c_uint() plist = gobj.g_object_interface_list_properties(iface, ctypes.byref(num)) props = [plist[i][0].name for i in range(num.value)] return props # ------------------ Find object definitions ----------------- split_prefix_pat = re.compile('([A-Z]+[a-z]*)([A-Za-z0-9]+)') get_type_pat = re.compile(r'''^\s*(GType|GtkType)\s+ ([a-z]\w+_get_type)\s*(\(void\)|\(\)).*$''', re.VERBOSE | re.MULTILINE) defkeys = 'GBoxed GInterface GObject gpointer GEnum GFlags' def find_defs(buf, gobj, modlib, defs): """Find possible gobject, gboxed, interface, gpointer, enum and flags definitions in header files.and find parent type.""" # find all *_get_type() functions that may represent a GObject for m in get_type_pat.findall(buf): func_name = m[1] for lib in modlib: if hasattr(lib, func_name): objtype = getattr(lib, func_name)() obj_name = gobj.g_type_name(objtype) parent = gobj.g_type_parent(objtype) parent_name = gobj.g_type_name(parent) base_name = gobj.g_type_name(gobj.g_type_fundamental(parent)) #if gobj.g_type_is_a(parent, gobj.GObject): # base_name = 'GObject' if base_name in defkeys: obj = ObjDef(obj_name, objtype, parent_name, parent, base_name) obj.set_properties(gobj) defs[obj.base_name].append(obj) break return # ------------------ Find function definitions ----------------- arg_split_pat = re.compile("\s*,\s*") proto_pat=re.compile(r"""^ \s*((?:-|\w|\&|\*)+) # return type \s+ # skip whitespace ([a-z]\w+)\s*[(] # match the function name until the opening ( \s*(.*?)\s*[)].* # group the function arguments $""", re.IGNORECASE|re.VERBOSE|re.MULTILINE) def find_func_defs(buf, modlib, deffile, defs, verbose): '''Find function prototypes in buf that have symbols in modlib and save in defs.''' funcs = defs['funcs'][deffile] = [] for m in proto_pat.findall(buf): ret, func, args = m if not True in [hasattr(lib, func) for lib in modlib]: if verbose: sys.stderr.write('no symbol for function: ' + func + ' from file' + deffile + '\n') else: args = arg_split_pat.split(args) args = [a.replace(' ','-', a.count(' ')-1) for a in args] funcs.append((func, ret, args)) return virtual_pat = re.compile(r'''^ \s*((?:-|\w|\&|\*)+) # return type \s* # skip whitespace \(\s*\*\s* # opening ( ([a-z]\w+)\) # match the function name until the closing ) \s*\(\s*([^)]*)\).* # group the function arguments $''', re.VERBOSE|re.MULTILINE) class_iface_struct_pat = re.compile( r'^struct\s+_(\w+)(?:Class|Iface)\s+{([^}]+)}\s*$', re.MULTILINE) def find_virt_defs(buf, deffile, defs): '''Find virtual function prototypes in buf and save in defs.''' virts = defs['virts'][deffile] = [] # get the Class or Iface structs for m in class_iface_struct_pat.findall(buf): objname, virtuals = m for v in virtual_pat.findall(virtuals): ret, func, args = v if 'reserved' in func or args == 'void': continue args = arg_split_pat.split(args) args = [a.replace(' ','-', a.count(' ')-1) for a in args] virts.append((func, ret, args, objname)) return enum_pat = re.compile(r'^\s*typedef enum\s+{\s*([^}]*)}\s*([^\s]*)$', re.MULTILINE) values_splitter = re.compile(r'\s*,\s', re.MULTILINE) def find_enums(buf, defs): for vals, name in enum_pat.findall(buf): if name != 'GdkCursorType': isflags = '<<' in vals entries = [val.split()[0] for val in values_splitter.split(vals) if val.strip()] if entries: defs['untypedenums'][name] = (isflags, entries) return # ------------------ write definitions ----------------- type_pat = re.compile(r'(?:const-)?([A-Za-z0-9]+)\*?\s+') pointer_pat = re.compile('(.*)\*$') func_new_pat = re.compile('(\w+)_new$') getset_pat = re.compile(r'^(?:get|set)_(.*)$') def split_prefix(cname, prefix, use_prefix): # use the module prefix to split the cname pre = prefix.replace('_', '') if use_prefix and cname.lower().startswith(pre): l = len(pre) module = cname[:l] name = cname[l:] else: m = split_prefix_pat.match(cname) if m: module = m.group(1) name = m.group(2) return module, name class DefsWriter: def __init__(self, defs, fp=None, prefix=None, verbose=False, defsfiles=None, defines={}, genpropgetsets=False, useprefix=False): self.defs = defs self.use_prefix = useprefix self.objnames = reduce(list.__add__, [[o.name for o in defs[base]] for base in defkeys.split()[:3]]) self.othernames = reduce(list.__add__, [[o.name for o in defs[base]] for base in defkeys.split()[3:]]) self.objifacedefs = dict(reduce(list.__add__, [[(o.name, o) for o in defs[base]] for base in defkeys.split()[1:3]])) self.fp = (fp, sys.stdout)[not fp] self.prefix = prefix self.verbose = verbose self.genpropgetsets = genpropgetsets self._c_names={} for defsfile in defsfiles: filter = defsparser.DefsParser(defsfile, defines) filter.startParsing() self._c_names.update(filter.c_name) for vdef in filter.virtuals: self._c_names[vdef.of_object + '.' + vdef.name] = None return def write_func_defs(self, deffiles, onlyvirts=False): filter = self._c_names for deffile in deffiles: self.fp.write('\n;; From %s\n\n' % os.path.basename(deffile)) if not onlyvirts: for func, ret, args in self.defs['funcs'][deffile]: if not func in filter: self._write_func(func, ret, args) for virt, ret, args, objname in self.defs['virts'][deffile]: if not objname + '.' + virt in filter: self._write_virt(objname, virt, ret, args) self.fp.write('\n') return def write_enum_defs(self, fp=None): fp = (fp, self.fp)[not fp] klassptrs = {'GEnum':ctypes.POINTER(EnumClass), 'GFlags':ctypes.POINTER(FlagsClass)} filter = self._c_names objs = self.defs['GEnum'] + self.defs ['GFlags'] #objs.sort() fp.write(';; Enumerations and Flags ...\n\n') for obj in objs: cname = name = obj.name tcode = typecode(cname, self.prefix, self.use_prefix) if cname in filter: continue if cname in self.defs['untypedenums']: if tcode not in self.defs['typedefines']: # no type define so skip and print as untyped enum continue self.defs['untypedenums'].pop(cname, None) parent_name = obj.parent_name klassptr = klassptrs[parent_name] typename = parent_name.lower()[1:] module = None module, name = split_prefix(cname, self.prefix, self.use_prefix) fp.write('(define-' + typename + ' ' + name + '\n') if module: fp.write(' (in-module "' + module + '")\n') fp.write(' (c-name "' + cname + '")\n') fp.write(' (gtype-id "' + tcode + '")\n') fp.write(' (values\n') classref = self.gobj.g_type_class_ref(obj.type) itemclass = ctypes.cast(classref, klassptr).contents for i in range(itemclass.n_values): val = itemclass.values[i] fp.write(' \'("%s" "%s")\n' % (val.value_nick, val.value_name)) fp.write(' )\n') fp.write(')\n\n') if self.defs['untypedenums']: self.write_untyped_enum_defs(fp) return def write_untyped_enum_defs(self, fp): fp.write(';; Untyped enumerations and flags ...\n\n') filter = self._c_names for cname, (isflags, entries) in self.defs['untypedenums'].items(): if filter and cname in filter: continue module, name = split_prefix(cname, self.prefix, self.use_prefix) if isflags: fp.write('(define-flags ' + name + '\n') else: fp.write('(define-enum ' + name + '\n') if module: fp.write(' (in-module "' + module + '")\n') fp.write(' (c-name "' + cname + '")\n') preindex = entries[0].rfind('_') for ent in entries[1:]: while (preindex > 0 and ent[:preindex] != entries[0][:preindex]): preindex = ent[:preindex].rfind('_') fp.write(' (values\n') for ent in entries: fp.write(' \'("%s" "%s")\n' % (ent[preindex+1:].lower().replace('_', '-'), ent)) fp.write(' )\n') fp.write(')\n\n') def _write_obj_helper(self, obj, fp): base_name = obj.base_name.lower()[1:] cmodule = None cname = name = obj.name type_id = obj.type parent_name = obj.parent_name cmodule, name = split_prefix(cname, self.prefix, self.use_prefix) fp.write('(define-' + base_name + ' ' + name + '\n') if cmodule: fp.write(' (in-module "' + cmodule + '")\n') if base_name == 'object': fp.write(' (parent "' + parent_name + '")\n') fp.write(' (c-name "' + cname + '")\n') fp.write(' (gtype-id "' + typecode(cname, self.prefix, self.use_prefix) + '")\n') n = ctypes.c_uint() ifaces = self.gobj.g_type_interfaces(type_id, ctypes.byref(n)) for i in range(n.value): iface_name = self.gobj.g_type_name(ifaces[i]) if iface_name in self.interfaces: fp.write(' (implements "%s")\n' % iface_name) if base_name == 'interface': prereq = self.gobj.g_type_interface_prerequisites(type_id, ctypes.byref(n)) for i in range(n.value): fp.write(' (prerequisite "%s")\n' % self.gobj.g_type_name(prereq[i])) # should do something about accessible fields fp.write(')\n\n') return def write_obj_defs(self, fp=None): fp = (fp, self.fp)[not fp] fp.write(';; -*- scheme -*-\n') filter = self._c_names for base in defkeys.split()[:4]: base_name = base.lower()[1:] fp.write('; %s definitions ...\n\n' % base_name) for obj in self.defs[base]: if not obj.name in filter: self._write_obj_helper(obj, fp) return def _write_func(self, name, ret, args): if len(args) >= 1: # methods must have at least one argument munged_name = name.replace('_', '') m = type_pat.match(args[0]) if m: obj = m.group(1) if munged_name.startswith(obj.lower()): if obj not in self.othernames: self._write_method(obj, name, ret, args) return fname = name if self.prefix: fname = re.sub('^'+self.prefix+'_', '', fname) # it is either a constructor or normal function self.fp.write('(define-function ' + fname + '\n') self.fp.write(' (c-name "' + name + '")\n') # Asume that a constructor function name # ends with '_new' and it returns an object pointer. m = func_new_pat.match(name) r = pointer_pat.match(ret) if m and r: cname = '' # get the type name by using the _get_type function func = m.group(1) + '_get_type' lib = [l for l in self.modlib if hasattr(l, func)] if lib: cname = self.gobj.g_type_name(getattr(lib[0], func)()) if cname and self.gobj.g_type_from_name(r.group(1)): self.fp.write(' (is-constructor-of "' + cname + '")\n') self._write_return(ret) self._write_arguments(args) return def _write_method(self, obj, name, ret, args): regex = ''.join([c+'_?' for c in obj.lower()]) mname, count = re.subn(regex, '', name, 1) if not count and self.prefix: mname = re.sub('^'+self.prefix+'_', '', mname) self.fp.write('(define-method ' + mname + '\n') self.fp.write(' (of-object "' + obj + '")\n') self.fp.write(' (c-name "' + name + '")\n') m = getset_pat.match(mname) if self.genpropgetsets and m and len(args[1:]) <= 1: prop = m.group(1) if obj in self.objifacedefs: oidef = self.objifacedefs[obj] if prop.replace('_', '-') in oidef.props: self.fp.write(' (prop-getset "' + prop + '")\n') self._write_return(ret) self._write_arguments(args[1:]) return def _write_virt(self, obj, name, ret, args): self.fp.write('(define-virtual ' + name + '\n') self.fp.write(' (of-object "' + obj + '")\n') self._write_return(ret) self._write_arguments(args[1:]) return def _write_return(self, ret): if ret == 'void': ret = 'none' self.fp.write(' (return-type "' + ret + '")\n') return def _write_arguments(self, args): if args and not 'void' in args: varargs = '' self.fp.write(' (parameters\n') for arg in args: if arg == '...': varargs = ' (varargs #t)\n' else: tupleArg = tuple(arg.split()) if len(tupleArg) == 2: self.fp.write(' \'("%s" "%s")\n' % tupleArg) self.fp.write(' )\n' + varargs) self.fp.write(')\n\n') # ---------- ctypes support classes for gobject library functions ---------- GType = ctypes.c_uint class GTypeClass(ctypes.Structure): _fields_ = [('g_type', GType)] class GTypeInstance(ctypes.Structure): _fields_ = [('g_class', ctypes.POINTER(GTypeClass))] class EnumValue(ctypes.Structure): _fields_ = [('value', ctypes.c_int), ('value_name', ctypes.c_char_p), ('value_nick', ctypes.c_char_p)] class FlagsValue(ctypes.Structure): _fields_ = [('value', ctypes.c_uint), ('value_name', ctypes.c_char_p), ('value_nick', ctypes.c_char_p)] class EnumClass(ctypes.Structure): _fields_ = [('g_type_class', GTypeClass), ('minimum', ctypes.c_int), ('maximum', ctypes.c_int), ('n_values', ctypes.c_uint), ('values', ctypes.POINTER(EnumValue))] class FlagsClass(ctypes.Structure): _fields_ = [('g_type_class', GTypeClass), ('mask', ctypes.c_uint), ('n_values', ctypes.c_uint), ('values', ctypes.POINTER(FlagsValue))] class GTypeInterface(ctypes.Structure): _fields_ = [('g_type', GType), ('g_instance_type', GType)] class GParamSpec(ctypes.Structure): _fields_ = [('g_type_instance', GTypeInstance), ('name', ctypes.c_char_p), ('flags', ctypes.c_uint), ('value_type', GType), ('owner_type', GType)] # ------------------ Main function ----------------- def main(args): verbose = False all = True onlyenums = False onlyobjdefs = False onlyvirtuals = False separate = False modulename = None defsfiles = [] libgobject = None modulelibs = [] defines = {} genpropgetsets = False use_prefix = False opts, args = getopt.getopt(args[1:], 'vs:m:f:D:L:l:p', ['onlyenums', 'onlyobjdefs', 'onlyvirtuals', 'modulename=', 'separate=', 'defsfile=', 'defines=', 'genpropgetsets', 'libgobject-', 'modulelib=', 'useprefix']) for o, v in opts: if o == '-v': verbose = True if o == '--onlyenums': onlyenums = True all = False if o == '--onlyvirtuals': onlyvirtuals = True all = False if o == '--onlyobjdefs': onlyobjdefs = True all = False if o in ('-p', '--useprefix'): use_prefix = True if o == '--genpropgetsets': genpropgetsets = True if o in ('-s', '--separate'): separate = v if o in ('-m', '--modulename'): modulename = v if o in ('-L', '--libgobject'): libgobject = v if o in ('-l', '--modulelib'): modulelibs.append(v) if o in ('-f', '--defsfile'): defsfiles.append(v) if o in ('-D', '--defines'): nameval = v.split('=') try: defines[nameval[0]] = nameval[1] except IndexError: defines[nameval[0]] = None if not args[0:1]: print 'Must specify at least one input file name' return -1 if not modulelibs: print 'Must specify one or more modulelib names' return -1 # load the gobject and module libraries and init the gtype system if not libgobject: if verbose: sys.stderr.write('Using "libgobject-2.0.so" as the libobject' \ 'library name by default\n') gobj = ctypes.cdll.LoadLibrary('libgobject-2.0.so') else: gobj = ctypes.cdll.LoadLibrary(libgobject) modlib = [ctypes.cdll.LoadLibrary(lib) for lib in modulelibs] gobj.g_type_init() gobj.g_type_name.restype = ctypes.c_char_p gobj.g_type_from_name.argtypes = [ctypes.c_char_p] gobj.g_type_interfaces.restype = ctypes.POINTER(ctypes.c_int) gobj.g_type_interface_prerequisites.restype = ctypes.POINTER(ctypes.c_int) gobj.g_object_class_list_properties.restype = ctypes.POINTER(ctypes.POINTER(GParamSpec)) gobj.g_object_interface_list_properties.restype = ctypes.POINTER(ctypes.POINTER(GParamSpec)) gobj.GObject = gobj.g_type_from_name('GObject') gobj.g_object_new(gobj.GObject, None) defs = {} for key in defkeys.split(): defs[key] = [] defs['funcs'] = {} defs['virts'] = {} defs['untypedenums'] = {} defs['typedefines'] = [] # read in all the object and function definitions args.sort() type_define_pat = re.compile( r'^#define\s+([A-Z]\S+_TYPE_\S+)\s+.*[a-z]\w+_get_type.*$', re.MULTILINE) for filename in args: buf = open(filename).read() defs['typedefines'] += type_define_pat.findall(buf) buf = clean_buffer(buf) find_enums(buf, defs) find_defs(buf, gobj, modlib, defs) find_func_defs(buf, modlib, filename, defs, verbose) find_virt_defs(buf, filename, defs) for key in defkeys.split(): defs[key].sort() methods = types = None if separate: methods = file(separate + '.defs', 'w') types = file(separate + '-types.defs', 'w') dw = DefsWriter(defs, methods, prefix=modulename, verbose=verbose, defsfiles=defsfiles, defines=defines, genpropgetsets=genpropgetsets, useprefix=use_prefix) dw.interfaces = [i.name for i in defs['GInterface']] dw.gobj = gobj dw.modlib = modlib if onlyobjdefs or all: dw.write_obj_defs(types) if separate: print "Wrote object defs to %s-types.defs" % separate if onlyenums or all: dw.write_enum_defs(types) if separate: print "Wrote enum and flags defs to %s-types.defs" % separate if onlyvirtuals or all: dw.write_func_defs(args, onlyvirtuals) if separate: print "Wrote function and virtual defs to %s.defs" % separate if __name__ == '__main__': sys.exit(main(sys.argv))