diff options
author | Simon McVittie <simon.mcvittie@collabora.co.uk> | 2007-11-29 13:08:41 +0000 |
---|---|---|
committer | Simon McVittie <simon.mcvittie@collabora.co.uk> | 2007-11-29 13:08:41 +0000 |
commit | e37b57ae2cc68266d08fc7b7dc5b04317896a17d (patch) | |
tree | 190c4b4532e6d5fa5beeac20f43187adc0a14592 | |
parent | d8695095978882927ecf9d58301a1c6ce079f4a5 (diff) |
Update tools from telepathy-glib: generated GInterfaces no longer need external glue
-rw-r--r-- | tools/Makefile.am | 13 | ||||
-rw-r--r-- | tools/glib-ginterface-gen.py | 116 | ||||
-rw-r--r-- | tools/libglibcodegen.py | 30 |
3 files changed, 133 insertions, 26 deletions
diff --git a/tools/Makefile.am b/tools/Makefile.am index f0666ae..95a4b5d 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -5,7 +5,12 @@ EXTRA_DIST = \ glib-ginterface-gen.py \ glib-signals-marshal-gen.py \ identity.xsl \ - libglibcodegen.py \ - ls-interfaces.xsl \ - make-all-async.xsl \ - spec-to-introspect.xsl + libglibcodegen.py + +CLEANFILES = libglibcodegen.pyc libglibcodegen.pyo + +glib-ginterface-gen.py: libglibcodegen.py + touch $@ + +glib-signals-marshal-gen.py: libglibcodegen.py + touch $@ diff --git a/tools/glib-ginterface-gen.py b/tools/glib-ginterface-gen.py index ef5f978..f806131 100644 --- a/tools/glib-ginterface-gen.py +++ b/tools/glib-ginterface-gen.py @@ -28,7 +28,7 @@ import xml.dom.minidom from libglibcodegen import Signature, type_to_gtype, cmp_by_name, \ camelcase_to_lower, NS_TP, dbus_gutils_wincaps_to_uscore, \ - signal_to_marshal_name + signal_to_marshal_name, method_to_glue_marshal_name NS_TP = "http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0" @@ -45,6 +45,22 @@ class Generator(object): assert prefix.endswith('_') assert not signal_marshal_prefix.endswith('_') + # The main_prefix, sub_prefix thing is to get: + # FOO_ -> (FOO_, _) + # FOO_SVC_ -> (FOO_, _SVC_) + # but + # FOO_BAR/ -> (FOO_BAR_, _) + # FOO_BAR/SVC_ -> (FOO_BAR_, _SVC_) + + if '/' in prefix: + main_prefix, sub_prefix = prefix.upper().split('/', 1) + prefix = prefix.replace('/', '_') + else: + main_prefix, sub_prefix = prefix.upper().split('_', 1) + + self.MAIN_PREFIX_ = main_prefix + '_' + self._SUB_PREFIX_ = '_' + sub_prefix + self.Prefix_ = prefix self.Prefix = prefix.replace('_', '') self.prefix_ = prefix.lower() @@ -77,7 +93,7 @@ class Generator(object): if tmp and not self.allow_havoc: raise AssertionError('%s is %s' % (self.iface_name, tmp)) - self.b('const DBusGObjectInfo dbus_glib_%s%s_object_info;' + self.b('static const DBusGObjectInfo _%s%s_object_info;' % (self.prefix_, node_name_lc)) self.b('') @@ -154,14 +170,8 @@ class Generator(object): self.h('GType %s%s_get_type (void);' % (self.prefix_, node_name_lc)) - main_prefix, sub_prefix = self.PREFIX_.split('_', 1) - main_prefix += '_' - sub_prefix = '_' + sub_prefix - # FOO_ -> (FOO_, _) - # FOO_SVC_ -> (FOO_, _SVC_) - gtype = self.current_gtype = \ - main_prefix + 'TYPE' + sub_prefix + node_name_uc + self.MAIN_PREFIX_ + 'TYPE' + self._SUB_PREFIX_ + node_name_uc classname = self.Prefix + node_name_mixed self.h('#define %s \\\n (%s%s_get_type ())' @@ -171,7 +181,7 @@ class Generator(object): % (self.PREFIX_, node_name_uc, gtype, classname)) self.h('#define %sIS%s%s(obj) \\\n' ' (G_TYPE_CHECK_INSTANCE_TYPE((obj), %s))' - % (main_prefix, sub_prefix, node_name_uc, gtype)) + % (self.MAIN_PREFIX_, self._SUB_PREFIX_, node_name_uc, gtype)) self.h('#define %s%s_GET_CLASS(obj) \\\n' ' (G_TYPE_INSTANCE_GET_INTERFACE((obj), %s, %sClass))' % (self.PREFIX_, node_name_uc, gtype, classname)) @@ -201,16 +211,94 @@ class Generator(object): self.b(s) self.b(' dbus_g_object_type_install_info (%s%s_get_type (),' % (self.prefix_, node_name_lc)) - self.b(' &dbus_glib_%s%s_object_info);' + self.b(' &_%s%s_object_info);' % (self.prefix_, node_name_lc)) self.b('}') self.h('') + self.b('static const DBusGMethodInfo _%s%s_methods[] = {' + % (self.prefix_, node_name_lc)) + + method_blob, offsets = self.get_method_glue(methods) + + for method, offset in zip(methods, offsets): + self.do_method_glue(method, offset) + + self.b('};') + self.b('') + + self.b('static const DBusGObjectInfo _%s%s_object_info = {' + % (self.prefix_, node_name_lc)) + self.b(' 0,') # version + self.b(' _%s%s_methods,' % (self.prefix_, node_name_lc)) + self.b(' %d,' % len(methods)) + self.b('"' + method_blob.replace('\0', '\\0') + '",') + self.b('"' + self.get_signal_glue(signals).replace('\0', '\\0') + '",') + self.b('"\\0"') + self.b('};') + self.b('') + self.node_name_mixed = None self.node_name_lc = None self.node_name_uc = None + def get_method_glue(self, methods): + info = [] + offsets = [] + + for method in methods: + offsets.append(len(''.join(info))) + + info.append(self.iface_name + '\0') + info.append(method.getAttribute('name') + '\0') + + info.append('A\0') # async + + counter = 0 + for arg in method.getElementsByTagName('arg'): + out = arg.getAttribute('direction') == 'out' + + name = arg.getAttribute('name') + if not name: + assert out + name = 'arg%u' % counter + counter += 1 + + info.append(name + '\0') + + if out: + info.append('O\0') + else: + info.append('I\0') + + if out: + info.append('F\0') # not const + info.append('N\0') # not error or return + info.append(arg.getAttribute('type') + '\0') + + info.append('\0') + + return ''.join(info) + '\0', offsets + + def do_method_glue(self, method, offset): + lc_name = camelcase_to_lower(method.getAttribute('name')) + + marshaller = method_to_glue_marshal_name(method, + self.signal_marshal_prefix) + wrapper = self.prefix_ + self.node_name_lc + '_' + lc_name + + self.b(" { (GCallback) %s, %s, %d }," % (wrapper, marshaller, offset)) + + def get_signal_glue(self, signals): + info = [] + + for signal in signals: + info.append(self.iface_name) + info.append(signal.getAttribute('name')) + + return '\0'.join(info) + '\0\0' + def get_method_impl_names(self, method): dbus_method_name = method.getAttribute('name') class_member_name = camelcase_to_lower(dbus_method_name) @@ -321,12 +409,6 @@ class Generator(object): self.b('}') self.b('') - # Fixup for dbus-binding-tool crack - dbus_glib_name = (self.prefix_ + self.node_name_lc + '_' + - dbus_gutils_wincaps_to_uscore(dbus_method_name)) - if dbus_glib_name != stub_name: - self.b('#define %s %s' % (dbus_glib_name, stub_name)) - # Implementation registration (in both header and body) self.h('void %s%s_implement_%s (%s%sClass *klass, %s impl);' % (self.prefix_, self.node_name_lc, class_member_name, diff --git a/tools/libglibcodegen.py b/tools/libglibcodegen.py index c1929e4..20ce455 100644 --- a/tools/libglibcodegen.py +++ b/tools/libglibcodegen.py @@ -129,11 +129,13 @@ def signal_to_marshal_type(signal): return mtype +_glib_marshallers = ['VOID', 'BOOLEAN', 'CHAR', 'UCHAR', 'INT', + 'STRING', 'UINT', 'LONG', 'ULONG', 'ENUM', 'FLAGS', 'FLOAT', + 'DOUBLE', 'STRING', 'PARAM', 'BOXED', 'POINTER', 'OBJECT', + 'UINT_POINTER'] + + def signal_to_marshal_name(signal, prefix): - glib_marshallers = ['VOID', 'BOOLEAN', 'CHAR', 'UCHAR', 'INT', - 'STRING', 'UINT', 'LONG', 'ULONG', 'ENUM', 'FLAGS', 'FLOAT', - 'DOUBLE', 'STRING', 'PARAM', 'BOXED', 'POINTER', 'OBJECT', - 'UINT_POINTER'] mtype = signal_to_marshal_type(signal) if len(mtype): @@ -141,7 +143,25 @@ def signal_to_marshal_name(signal, prefix): else: name = 'VOID' - if name in glib_marshallers: + if name in _glib_marshallers: + return 'g_cclosure_marshal_VOID__' + name + else: + return prefix + '_marshal_VOID__' + name + + +def method_to_glue_marshal_name(method, prefix): + + mtype = [] + for i in method.getElementsByTagName("arg"): + if i.getAttribute("direction") != "out": + type = i.getAttribute("type") + mtype.append(type_to_gtype(type)[2]) + + mtype.append('POINTER') + + name = '_'.join(mtype) + + if name in _glib_marshallers: return 'g_cclosure_marshal_VOID__' + name else: return prefix + '_marshal_VOID__' + name |