mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-27 10:40:34 +00:00
16bb9b838e
Original commit message from CVS: * codegen/argtypes.py: * codegen/codegen.py: * codegen/definitions.py: * gst/arg-types.py: Added 'keeprefcount' argument for function/method parameters in order to cope with functions/methods that decrement the refcount of the given parameter * gst/gst.defs: Added 'keeprefcount' for buffer argument of gst_pad_push() wrapper.
575 lines
20 KiB
Python
575 lines
20 KiB
Python
# -*- Mode: Python; py-indent-offset: 4 -*-
|
|
import sys
|
|
from copy import *
|
|
|
|
def get_valid_scheme_definitions(defs):
|
|
return [x for x in defs if isinstance(x, tuple) and len(x) >= 2]
|
|
|
|
# New Parameter class, wich emulates a tuple for compatibility reasons
|
|
class Parameter(object):
|
|
def __init__(self, ptype, pname, pdflt, pnull, prop=None, keeprefcount=False):
|
|
self.ptype = ptype
|
|
self.pname = pname
|
|
self.pdflt = pdflt
|
|
self.pnull = pnull
|
|
self.keeprefcount = keeprefcount
|
|
|
|
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
|
|
|
|
# Parameter for property based constructors
|
|
class Property(object):
|
|
def __init__(self, pname, optional, argname):
|
|
self.pname = pname
|
|
self.optional = optional
|
|
self.argname = argname
|
|
|
|
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:
|
|
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
|
|
for arg in get_valid_scheme_definitions(args):
|
|
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 MiniObjectDef(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.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] == '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.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] == '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
|
|
keeprefcount = False
|
|
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] == 'keep-refcount':
|
|
keeprefcount = True
|
|
self.params.append(Parameter(ptype, pname, pdflt, pnull,
|
|
keeprefcount=keeprefcount))
|
|
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 = 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.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.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] == '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
|
|
keeprefcount = False
|
|
for farg in parg[2:]:
|
|
if farg[0] == 'default':
|
|
pdflt = farg[1]
|
|
elif farg[0] == 'null-ok':
|
|
pnull = 1
|
|
elif farg[0] == 'keep-refcount':
|
|
keeprefcount = True
|
|
self.params.append(Parameter(ptype, pname, pdflt, pnull,
|
|
keeprefcount = keeprefcount))
|
|
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 = 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 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 = 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.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')
|