summaryrefslogtreecommitdiff
path: root/codegen/definitions.py
diff options
context:
space:
mode:
authorHasan Wan <hasan.wan@intel.com>2012-05-25 16:47:13 +0800
committerHasan Wan <hasan.wan@intel.com>2012-05-28 16:06:22 +0800
commit1ddee039e66b9c1feb2129a1904e60760e0e8fc3 (patch)
tree84a3b12d0f839c6a2ef702eb02f3288c91cf5902 /codegen/definitions.py
parentf7d643cbb2184346b6f8d26091eb7eb38c6bbfe1 (diff)
downloadpygobject2-1ddee039e66b9c1feb2129a1904e60760e0e8fc3.tar.gz
pygobject2-1ddee039e66b9c1feb2129a1904e60760e0e8fc3.tar.bz2
pygobject2-1ddee039e66b9c1feb2129a1904e60760e0e8fc3.zip
Updated with Tizen:Base source codes
Diffstat (limited to 'codegen/definitions.py')
-rw-r--r--codegen/definitions.py575
1 files changed, 575 insertions, 0 deletions
diff --git a/codegen/definitions.py b/codegen/definitions.py
new file mode 100644
index 0000000..aca5adb
--- /dev/null
+++ b/codegen/definitions.py
@@ -0,0 +1,575 @@
+# -*- Mode: Python; py-indent-offset: 4 -*-
+import copy
+import sys
+
+def get_valid_scheme_definitions(defs):
+ return [x for x in defs if isinstance(x, tuple) and len(x) >= 2]
+
+def unescape(s):
+ s = s.replace('\r\n', '\\r\\n').replace('\t', '\\t')
+ return s.replace('\r', '\\r').replace('\n', '\\n')
+
+def make_docstring(lines):
+ return "(char *) " + '\n'.join(['"%s"' % unescape(s) for s in lines])
+
+# New Parameter class, wich emulates a tuple for compatibility reasons
+class Parameter(object):
+ def __init__(self, ptype, pname, pdflt, pnull, pdir=None):
+ self.ptype = ptype
+ self.pname = pname
+ self.pdflt = pdflt
+ self.pnull = pnull
+ self.pdir = pdir
+
+ def __len__(self): return 4
+ def __getitem__(self, i):
+ return (self.ptype, self.pname, self.pdflt, self.pnull)[i]
+
+ def merge(self, old):
+ if old.pdflt is not None:
+ self.pdflt = old.pdflt
+ if old.pnull is not None:
+ self.pnull = old.pnull
+
+# We currently subclass 'str' to make impact on the rest of codegen as
+# little as possible. Later we can subclass 'object' instead, but
+# then we must find and adapt all places which expect return types to
+# be strings.
+class ReturnType(str):
+ def __new__(cls, *args, **kwds):
+ return str.__new__(cls, *args[:1])
+ def __init__(self, type_name, optional=False):
+ str.__init__(self)
+ self.optional = optional
+
+# Parameter for property based constructors
+class Property(object):
+ def __init__(self, pname, optional, argname):
+ self.pname = pname
+ self.optional = optional
+ self.argname = argname
+
+ def __len__(self): return 4
+ def __getitem__(self, i):
+ return ('', self.pname, self.optional, self.argname)[i]
+
+ def merge(self, old):
+ if old.optional is not None:
+ self.optional = old.optional
+ if old.argname is not None:
+ self.argname = old.argname
+
+
+class Definition(object):
+ docstring = "NULL"
+
+ def py_name(self):
+ return '%s.%s' % (self.module, self.name)
+
+ py_name = property(py_name)
+
+ 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"
+
+ def guess_return_value_ownership(self):
+ "return 1 if caller owns return value"
+ if getattr(self, 'is_constructor_of', False):
+ self.caller_owns_return = True
+ elif self.ret in ('char*', 'gchar*', 'string'):
+ self.caller_owns_return = True
+ else:
+ self.caller_owns_return = False
+
+
+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 = []
+ self.class_init_func = None
+ self.has_new_constructor_api = False
+ for arg in get_valid_scheme_definitions(args):
+ if arg[0] == 'in-module':
+ self.module = arg[1]
+ elif arg[0] == 'docstring':
+ self.docstring = make_docstring(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.vtable = None
+ self.fields = []
+ self.interface_info = None
+ for arg in get_valid_scheme_definitions(args):
+ if arg[0] == 'in-module':
+ self.module = arg[1]
+ elif arg[0] == 'docstring':
+ self.docstring = make_docstring(arg[1:])
+ elif arg[0] == 'c-name':
+ self.c_name = arg[1]
+ elif arg[0] == 'gtype-id':
+ self.typecode = arg[1]
+ elif arg[0] == 'vtable':
+ self.vtable = arg[1]
+ if self.vtable is None:
+ self.vtable = self.c_name + "Iface"
+ 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 get_valid_scheme_definitions(args):
+ 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 get_valid_scheme_definitions(args):
+ 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 get_valid_scheme_definitions(args):
+ 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 MethodDefBase(Definition):
+ def __init__(self, name, *args):
+ dump = 0
+ self.name = name
+ self.ret = None
+ self.caller_owns_return = None
+ self.unblock_threads = 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 get_valid_scheme_definitions(args):
+ if arg[0] == 'of-object':
+ self.of_object = arg[1]
+ elif arg[0] == 'docstring':
+ self.docstring = make_docstring(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':
+ type_name = arg[1]
+ optional = False
+ for prop in arg[2:]:
+ if prop[0] == 'optional':
+ optional = True
+ self.ret = ReturnType(type_name, optional)
+ elif arg[0] == 'caller-owns-return':
+ self.caller_owns_return = arg[1] in ('t', '#t')
+ elif arg[0] == 'unblock-threads':
+ self.unblock_threads = arg[1] in ('t', '#t')
+ elif arg[0] == 'parameters':
+ for parg in arg[1:]:
+ ptype = parg[0]
+ pname = parg[1]
+ pdflt = None
+ pnull = 0
+ pdir = None
+ for farg in parg[2:]:
+ assert isinstance(farg, tuple)
+ if farg[0] == 'default':
+ pdflt = farg[1]
+ elif farg[0] == 'null-ok':
+ pnull = 1
+ elif farg[0] == 'direction':
+ pdir = farg[1]
+ self.params.append(Parameter(ptype, pname, pdflt, pnull, pdir))
+ 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:
+ self.guess_return_value_ownership()
+
+ def merge(self, old, parmerge):
+ self.caller_owns_return = old.caller_owns_return
+ self.varargs = old.varargs
+ # here we merge extra parameter flags accross to the new object.
+ if not parmerge:
+ self.params = copy.deepcopy(old.params)
+ return
+ 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):
+ 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.caller_owns_return:
+ fp.write(' (caller-owns-return #t)\n')
+ if self.unblock_threads:
+ fp.write(' (unblock_threads #t)\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')
+ if self.varargs:
+ fp.write(' (varargs #t)\n')
+ fp.write(')\n\n')
+
+
+class MethodDef(MethodDefBase):
+ def __init__(self, name, *args):
+ MethodDefBase.__init__(self, name, *args)
+ 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 write_defs(self, fp=sys.stdout):
+ fp.write('(define-method ' + self.name + '\n')
+ self._write_defs(fp)
+
+class VirtualDef(MethodDefBase):
+ def write_defs(self, fp=sys.stdout):
+ fp.write('(define-virtual ' + self.name + '\n')
+ self._write_defs(fp)
+
+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.unblock_threads = 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 get_valid_scheme_definitions(args):
+ if arg[0] == 'in-module':
+ self.in_module = arg[1]
+ elif arg[0] == 'docstring':
+ self.docstring = make_docstring(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] == 'unblock-threads':
+ self.unblock_threads = 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(Parameter(ptype, pname, pdflt, pnull))
+ elif arg[0] == 'properties':
+ if self.is_constructor_of is None:
+ print >> sys.stderr, "Warning: (properties ...) "\
+ "is only valid for constructors"
+ for prop in arg[1:]:
+ pname = prop[0]
+ optional = False
+ argname = pname
+ for farg in prop[1:]:
+ if farg[0] == 'optional':
+ optional = True
+ elif farg[0] == 'argname':
+ argname = farg[1]
+ self.params.append(Property(pname, optional, argname))
+ 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:
+ self.guess_return_value_ownership()
+ 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, parmerge):
+ self.caller_owns_return = old.caller_owns_return
+ self.varargs = old.varargs
+ if not parmerge:
+ self.params = copy.deepcopy(old.params)
+ return
+ # here we merge extra parameter flags accross to the new object.
+ def merge_param(param):
+ for old_param in old.params:
+ if old_param.pname == param.pname:
+ if isinstance(old_param, Property):
+ # h2def never scans Property's, therefore if
+ # we have one it was manually written, so we
+ # keep it.
+ return copy.deepcopy(old_param)
+ else:
+ param.merge(old_param)
+ return param
+ raise RuntimeError, "could not find %s in old_parameters %r" % (
+ param.pname, [p.pname for p in old.params])
+ try:
+ self.params = map(merge_param, self.params)
+ except RuntimeError:
+ # parameter names changed and we can't find a match; it's
+ # safer to keep the old parameter list untouched.
+ self.params = copy.deepcopy(old.params)
+
+ 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.caller_owns_return:
+ fp.write(' (caller-owns-return #t)\n')
+ if self.unblock_threads:
+ fp.write(' (unblock-threads #t)\n')
+ if self.ret:
+ fp.write(' (return-type "' + self.ret + '")\n')
+ if self.deprecated:
+ fp.write(' (deprecated "' + self.deprecated + '")\n')
+ if self.params:
+ if isinstance(self.params[0], Parameter):
+ 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')
+ elif isinstance(self.params[0], Property):
+ fp.write(' (properties\n')
+ for prop in self.params:
+ fp.write(' \'("' + prop.pname +'"')
+ if prop.optional: fp.write(' (optional)')
+ fp.write(')\n')
+ fp.write(' )\n')
+ else:
+ assert False, "strange parameter list %r" % self.params[0]
+ if self.varargs:
+ fp.write(' (varargs #t)\n')
+
+ fp.write(')\n\n')