# -*- Mode: Python; py-indent-offset: 4 -*- import sys class Definition: def __init__(self, *args): """Create a new defs object of this type. The arguments are the components of the definition""" raise RuntimeError, "this is an abstract class" def merge(self, old): """Merge in customisations from older version of definition""" raise RuntimeError, "this is an abstract class" def write_defs(self, fp=sys.stdout): """write out this definition in defs file format""" raise RuntimeError, "this is an abstract class" class ObjectDef(Definition): def __init__(self, name, *args): self.name = name self.module = None self.parent = None self.c_name = None self.typecode = None self.fields = [] self.implements = [] for arg in args: if type(arg) != type(()) or len(arg) < 2: continue if arg[0] == 'in-module': self.module = arg[1] elif arg[0] == 'parent': self.parent = arg[1] elif arg[0] == 'c-name': self.c_name = arg[1] elif arg[0] == 'gtype-id': self.typecode = arg[1] elif arg[0] == 'fields': for parg in arg[1:]: self.fields.append((parg[0], parg[1])) elif arg[0] == 'implements': self.implements.append(arg[1]) def merge(self, old): # currently the .h parser doesn't try to work out what fields of # an object structure should be public, so we just copy the list # from the old version ... self.fields = old.fields self.implements = old.implements def write_defs(self, fp=sys.stdout): fp.write('(define-object ' + self.name + '\n') if self.module: fp.write(' (in-module "' + self.module + '")\n') if self.parent != (None, None): fp.write(' (parent "' + self.parent + '")\n') for interface in self.implements: fp.write(' (implements "' + interface + '")\n') if self.c_name: fp.write(' (c-name "' + self.c_name + '")\n') if self.typecode: fp.write(' (gtype-id "' + self.typecode + '")\n') if self.fields: fp.write(' (fields\n') for (ftype, fname) in self.fields: fp.write(' \'("' + ftype + '" "' + fname + '")\n') fp.write(' )\n') fp.write(')\n\n') class InterfaceDef(Definition): def __init__(self, name, *args): self.name = name self.module = None self.c_name = None self.typecode = None self.fields = [] for arg in args: if type(arg) != type(()) or len(arg) < 2: continue if arg[0] == 'in-module': self.module = arg[1] elif arg[0] == 'c-name': self.c_name = arg[1] elif arg[0] == 'gtype-id': self.typecode = arg[1] def write_defs(self, fp=sys.stdout): fp.write('(define-interface ' + self.name + '\n') if self.module: fp.write(' (in-module "' + self.module + '")\n') if self.c_name: fp.write(' (c-name "' + self.c_name + '")\n') if self.typecode: fp.write(' (gtype-id "' + self.typecode + '")\n') fp.write(')\n\n') class EnumDef(Definition): def __init__(self, name, *args): self.deftype = 'enum' self.name = name self.in_module = None self.c_name = None self.typecode = None self.values = [] for arg in args: if type(arg) != type(()) or len(arg) < 2: continue if arg[0] == 'in-module': self.in_module = arg[1] elif arg[0] == 'c-name': self.c_name = arg[1] elif arg[0] == 'gtype-id': self.typecode = arg[1] elif arg[0] == 'values': for varg in arg[1:]: self.values.append((varg[0], varg[1])) def merge(self, old): pass def write_defs(self, fp=sys.stdout): fp.write('(define-' + self.deftype + ' ' + self.name + '\n') if self.in_module: fp.write(' (in-module "' + self.in_module + '")\n') fp.write(' (c-name "' + self.c_name + '")\n') fp.write(' (gtype-id "' + self.typecode + '")\n') if self.values: fp.write(' (values\n') for name, val in self.values: fp.write(' \'("' + name + '" "' + val + '")\n') fp.write(' )\n') fp.write(')\n\n') class FlagsDef(EnumDef): def __init__(self, *args): apply(EnumDef.__init__, (self,) + args) self.deftype = 'flags' class BoxedDef(Definition): def __init__(self, name, *args): self.name = name self.module = None self.c_name = None self.typecode = None self.copy = None self.release = None self.fields = [] for arg in args: if type(arg) != type(()) or len(arg) < 2: continue if arg[0] == 'in-module': self.module = arg[1] elif arg[0] == 'c-name': self.c_name = arg[1] elif arg[0] == 'gtype-id': self.typecode = arg[1] elif arg[0] == 'copy-func': self.copy = arg[1] elif arg[0] == 'release-func': self.release = arg[1] elif arg[0] == 'fields': for parg in arg[1:]: self.fields.append((parg[0], parg[1])) def merge(self, old): # currently the .h parser doesn't try to work out what fields of # an object structure should be public, so we just copy the list # from the old version ... self.fields = old.fields def write_defs(self, fp=sys.stdout): fp.write('(define-boxed ' + self.name + '\n') if self.module: fp.write(' (in-module "' + self.module + '")\n') if self.c_name: fp.write(' (c-name "' + self.c_name + '")\n') if self.typecode: fp.write(' (gtype-id "' + self.typecode + '")\n') if self.copy: fp.write(' (copy-func "' + self.copy + '")\n') if self.release: fp.write(' (release-func "' + self.release + '")\n') if self.fields: fp.write(' (fields\n') for (ftype, fname) in self.fields: fp.write(' \'("' + ftype + '" "' + fname + '")\n') fp.write(' )\n') fp.write(')\n\n') class PointerDef(Definition): def __init__(self, name, *args): self.name = name self.module = None self.c_name = None self.typecode = None self.fields = [] for arg in args: if type(arg) != type(()) or len(arg) < 2: continue if arg[0] == 'in-module': self.module = arg[1] elif arg[0] == 'c-name': self.c_name = arg[1] elif arg[0] == 'gtype-id': self.typecode = arg[1] elif arg[0] == 'fields': for parg in arg[1:]: self.fields.append((parg[0], parg[1])) def merge(self, old): # currently the .h parser doesn't try to work out what fields of # an object structure should be public, so we just copy the list # from the old version ... self.fields = old.fields def write_defs(self, fp=sys.stdout): fp.write('(define-pointer ' + self.name + '\n') if self.module: fp.write(' (in-module "' + self.module + '")\n') if self.c_name: fp.write(' (c-name "' + self.c_name + '")\n') if self.typecode: fp.write(' (gtype-id "' + self.typecode + '")\n') if self.fields: fp.write(' (fields\n') for (ftype, fname) in self.fields: fp.write(' \'("' + ftype + '" "' + fname + '")\n') fp.write(' )\n') fp.write(')\n\n') class MethodDef(Definition): def __init__(self, name, *args): dump = 0 self.name = name self.ret = None self.caller_owns_return = None self.c_name = None self.typecode = None self.of_object = None self.params = [] # of form (type, name, default, nullok) self.varargs = 0 self.deprecated = None for arg in args: if type(arg) != type(()) or len(arg) < 2: continue if arg[0] == 'of-object': self.of_object = arg[1] elif arg[0] == 'c-name': self.c_name = arg[1] elif arg[0] == 'gtype-id': self.typecode = arg[1] elif arg[0] == 'return-type': self.ret = arg[1] elif arg[0] == 'caller-owns-return': self.caller_owns_return = arg[1] in ('t', '#t') elif arg[0] == 'parameters': for parg in arg[1:]: ptype = parg[0] pname = parg[1] pdflt = None pnull = 0 for farg in parg[2:]: if farg[0] == 'default': pdflt = farg[1] elif farg[0] == 'null-ok': pnull = 1 self.params.append((ptype, pname, pdflt, pnull)) elif arg[0] == 'varargs': self.varargs = arg[1] in ('t', '#t') elif arg[0] == 'deprecated': self.deprecated = arg[1] else: sys.stderr.write("Warning: %s argument unsupported.\n" % (arg[0])) dump = 1 if dump: self.write_defs(sys.stderr) if self.caller_owns_return is None and self.ret is not None: if self.ret[:6] == 'const-': self.caller_owns_return = 0 elif self.ret in ('char*', 'gchar*', 'string'): self.caller_owns_return = 1 else: self.caller_owns_return = 0 for item in ('c_name', 'of_object'): if self.__dict__[item] == None: self.write_defs(sys.stderr) raise RuntimeError, "definition missing required %s" % (item,) def merge(self, old): # here we merge extra parameter flags accross to the new object. for i in range(len(self.params)): ptype, pname, pdflt, pnull = self.params[i] for p2 in old.params: if p2[1] == pname: self.params[i] = (ptype, pname, p2[2], p2[3]) break def write_defs(self, fp=sys.stdout): fp.write('(define-method ' + self.name + '\n') if self.of_object != (None, None): fp.write(' (of-object "' + self.of_object + '")\n') if self.c_name: fp.write(' (c-name "' + self.c_name + '")\n') if self.typecode: fp.write(' (gtype-id "' + self.typecode + '")\n') if self.ret: fp.write(' (return-type "' + self.ret + '")\n') if self.deprecated: fp.write(' (deprecated "' + self.deprecated + '")\n') if self.params: fp.write(' (parameters\n') for ptype, pname, pdflt, pnull in self.params: fp.write(' \'("' + ptype + '" "' + pname +'"') if pdflt: fp.write(' (default "' + pdflt + '")') if pnull: fp.write(' (null-ok)') fp.write(')\n') fp.write(' )\n') fp.write(')\n\n') class FunctionDef(Definition): def __init__(self, name, *args): dump = 0 self.name = name self.in_module = None self.is_constructor_of = None self.ret = None self.caller_owns_return = None self.c_name = None self.typecode = None self.params = [] # of form (type, name, default, nullok) self.varargs = 0 self.deprecated = None for arg in args: if type(arg) != type(()) or len(arg) < 2: continue if arg[0] == 'in-module': self.in_module = arg[1] elif arg[0] == 'is-constructor-of': self.is_constructor_of = arg[1] elif arg[0] == 'c-name': self.c_name = arg[1] elif arg[0] == 'gtype-id': self.typecode = arg[1] elif arg[0] == 'return-type': self.ret = arg[1] elif arg[0] == 'caller-owns-return': self.caller_owns_return = arg[1] in ('t', '#t') elif arg[0] == 'parameters': for parg in arg[1:]: ptype = parg[0] pname = parg[1] pdflt = None pnull = 0 for farg in parg[2:]: if farg[0] == 'default': pdflt = farg[1] elif farg[0] == 'null-ok': pnull = 1 self.params.append((ptype, pname, pdflt, pnull)) elif arg[0] == 'varargs': self.varargs = arg[1] in ('t', '#t') elif arg[0] == 'deprecated': self.deprecated = arg[1] else: sys.stderr.write("Warning: %s argument unsupported\n" % (arg[0],)) dump = 1 if dump: self.write_defs(sys.stderr) if self.caller_owns_return is None and self.ret is not None: if self.ret[:6] == 'const-': self.caller_owns_return = 0 elif self.is_constructor_of: self.caller_owns_return = 1 elif self.ret in ('char*', 'gchar*', 'string'): self.caller_owns_return = 1 else: self.caller_owns_return = 0 for item in ('c_name',): if self.__dict__[item] == None: self.write_defs(sys.stderr) raise RuntimeError, "definition missing required %s" % (item,) _method_write_defs = MethodDef.__dict__['write_defs'] def merge(self, old): # here we merge extra parameter flags accross to the new object. for i in range(len(self.params)): ptype, pname, pdflt, pnull = self.params[i] for p2 in old.params: if p2[1] == pname: self.params[i] = (ptype, pname, p2[2], p2[3]) break if not self.is_constructor_of: try: self.is_constructor_of = old.is_constructor_of except AttributeError: pass if isinstance(old, MethodDef): self.name = old.name # transmogrify from function into method ... self.write_defs = self._method_write_defs self.of_object = old.of_object del self.params[0] def write_defs(self, fp=sys.stdout): fp.write('(define-function ' + self.name + '\n') if self.in_module: fp.write(' (in-module "' + self.in_module + '")\n') if self.is_constructor_of: fp.write(' (is-constructor-of "' + self.is_constructor_of +'")\n') if self.c_name: fp.write(' (c-name "' + self.c_name + '")\n') if self.typecode: fp.write(' (gtype-id "' + self.typecode + '")\n') if self.ret: fp.write(' (return-type "' + self.ret + '")\n') if self.deprecated: fp.write(' (deprecated "' + self.deprecated + '")\n') if self.params: fp.write(' (parameters\n') for ptype, pname, pdflt, pnull in self.params: fp.write(' \'("' + ptype + '" "' + pname +'"') if pdflt: fp.write(' (default "' + pdflt + '")') if pnull: fp.write(' (null-ok)') fp.write(')\n') fp.write(' )\n') fp.write(')\n\n')