aboutsummaryrefslogtreecommitdiffstats
path: root/tools/glib-ginterface-gen.py
diff options
context:
space:
mode:
authorEmilio Pozuelo Monfort <emilio.pozuelo@collabora.co.uk>2011-02-01 21:47:58 +0800
committerEmilio Pozuelo Monfort <emilio.pozuelo@collabora.co.uk>2011-02-01 22:22:39 +0800
commit621bbbb8631f4b149d0478a3423687e4e973b04f (patch)
tree5dc21cc9d4893343c50af7e8f109905ac6ae447e /tools/glib-ginterface-gen.py
parent9503c4aa28b9a4215e3e325a31b500f2c78b712a (diff)
downloadgsoc2013-empathy-621bbbb8631f4b149d0478a3423687e4e973b04f.tar
gsoc2013-empathy-621bbbb8631f4b149d0478a3423687e4e973b04f.tar.gz
gsoc2013-empathy-621bbbb8631f4b149d0478a3423687e4e973b04f.tar.bz2
gsoc2013-empathy-621bbbb8631f4b149d0478a3423687e4e973b04f.tar.lz
gsoc2013-empathy-621bbbb8631f4b149d0478a3423687e4e973b04f.tar.xz
gsoc2013-empathy-621bbbb8631f4b149d0478a3423687e4e973b04f.tar.zst
gsoc2013-empathy-621bbbb8631f4b149d0478a3423687e4e973b04f.zip
Update tools from telepathy-glib
Diffstat (limited to 'tools/glib-ginterface-gen.py')
-rw-r--r--tools/glib-ginterface-gen.py293
1 files changed, 196 insertions, 97 deletions
diff --git a/tools/glib-ginterface-gen.py b/tools/glib-ginterface-gen.py
index 9eb7af5ce..9dfdcc75d 100644
--- a/tools/glib-ginterface-gen.py
+++ b/tools/glib-ginterface-gen.py
@@ -27,7 +27,7 @@ import os.path
import xml.dom.minidom
from libglibcodegen import Signature, type_to_gtype, cmp_by_name, \
- camelcase_to_lower, NS_TP, dbus_gutils_wincaps_to_uscore, \
+ NS_TP, dbus_gutils_wincaps_to_uscore, \
signal_to_marshal_name, method_to_glue_marshal_name
@@ -41,6 +41,7 @@ class Generator(object):
self.dom = dom
self.__header = []
self.__body = []
+ self.__docs = []
assert prefix.endswith('_')
assert not signal_marshal_prefix.endswith('_')
@@ -66,6 +67,7 @@ class Generator(object):
self.prefix_ = prefix.lower()
self.PREFIX_ = prefix.upper()
+ self.basename = basename
self.signal_marshal_prefix = signal_marshal_prefix
self.headers = headers
self.end_headers = end_headers
@@ -73,11 +75,20 @@ class Generator(object):
self.allow_havoc = allow_havoc
def h(self, s):
+ if isinstance(s, unicode):
+ s = s.encode('utf-8')
self.__header.append(s)
def b(self, s):
+ if isinstance(s, unicode):
+ s = s.encode('utf-8')
self.__body.append(s)
+ def d(self, s):
+ if isinstance(s, unicode):
+ s = s.encode('utf-8')
+ self.__docs.append(s)
+
def do_node(self, node):
node_name = node.getAttribute('name').replace('/', '')
node_name_mixed = self.node_name_mixed = node_name.replace('_', '')
@@ -157,20 +168,55 @@ class Generator(object):
self.b('}')
self.b('')
- self.h('/**')
- self.h(' * %s%s:' % (self.Prefix, node_name_mixed))
- self.h(' *')
- self.h(' * Dummy typedef representing any implementation of this '
+ self.d('/**')
+ self.d(' * %s%s:' % (self.Prefix, node_name_mixed))
+ self.d(' *')
+ self.d(' * Dummy typedef representing any implementation of this '
'interface.')
- self.h(' */')
+ self.d(' */')
+
self.h('typedef struct _%s%s %s%s;'
% (self.Prefix, node_name_mixed, self.Prefix, node_name_mixed))
self.h('')
- self.h('/**')
- self.h(' * %s%sClass:' % (self.Prefix, node_name_mixed))
- self.h(' *')
- self.h(' * The class of %s%s.' % (self.Prefix, node_name_mixed))
- self.h(' */')
+
+ self.d('/**')
+ self.d(' * %s%sClass:' % (self.Prefix, node_name_mixed))
+ self.d(' *')
+ self.d(' * The class of %s%s.' % (self.Prefix, node_name_mixed))
+
+ if methods:
+ self.d(' *')
+ self.d(' * In a full implementation of this interface (i.e. all')
+ self.d(' * methods implemented), the interface initialization')
+ self.d(' * function used in G_IMPLEMENT_INTERFACE() would')
+ self.d(' * typically look like this:')
+ self.d(' *')
+ self.d(' * <programlisting>')
+ self.d(' * static void')
+ self.d(' * implement_%s (gpointer klass,' % self.node_name_lc)
+ self.d(' * gpointer unused G_GNUC_UNUSED)')
+ self.d(' * {')
+ self.d(' * #define IMPLEMENT(x) %s%s_implement_&num;&num;x (\\'
+ % (self.prefix_, self.node_name_lc))
+ self.d(' * klass, my_object_&num;&num;x)')
+
+ for method in methods:
+ class_member_name = method.getAttribute('tp:name-for-bindings')
+ class_member_name = class_member_name.lower()
+ self.d(' * IMPLEMENT (%s);' % class_member_name)
+
+ self.d(' * #undef IMPLEMENT')
+ self.d(' * }')
+ self.d(' * </programlisting>')
+ else:
+ self.d(' * This interface has no D-Bus methods, so an')
+ self.d(' * implementation can typically pass %NULL to')
+ self.d(' * G_IMPLEMENT_INTERFACE() as the interface')
+ self.d(' * initialization function.')
+
+ self.d(' */')
+ self.d('')
+
self.h('typedef struct _%s%sClass %s%sClass;'
% (self.Prefix, node_name_mixed, self.Prefix, node_name_mixed))
self.h('')
@@ -207,48 +253,56 @@ class Generator(object):
self.b('%s%s_base_init_once (gpointer klass G_GNUC_UNUSED)'
% (self.prefix_, node_name_lc))
self.b('{')
- self.b(' static TpDBusPropertiesMixinPropInfo properties[%d] = {'
- % (len(properties) + 1))
- for m in properties:
- access = m.getAttribute('access')
- assert access in ('read', 'write', 'readwrite')
+ if properties:
+ self.b(' static TpDBusPropertiesMixinPropInfo properties[%d] = {'
+ % (len(properties) + 1))
- if access == 'read':
- flags = 'TP_DBUS_PROPERTIES_MIXIN_FLAG_READ'
- elif access == 'write':
- flags = 'TP_DBUS_PROPERTIES_MIXIN_FLAG_WRITE'
- else:
- flags = ('TP_DBUS_PROPERTIES_MIXIN_FLAG_READ | '
- 'TP_DBUS_PROPERTIES_MIXIN_FLAG_WRITE')
+ for m in properties:
+ access = m.getAttribute('access')
+ assert access in ('read', 'write', 'readwrite')
- self.b(' { 0, %s, "%s", 0, NULL, NULL }, /* %s */'
- % (flags, m.getAttribute('type'), m.getAttribute('name')))
+ if access == 'read':
+ flags = 'TP_DBUS_PROPERTIES_MIXIN_FLAG_READ'
+ elif access == 'write':
+ flags = 'TP_DBUS_PROPERTIES_MIXIN_FLAG_WRITE'
+ else:
+ flags = ('TP_DBUS_PROPERTIES_MIXIN_FLAG_READ | '
+ 'TP_DBUS_PROPERTIES_MIXIN_FLAG_WRITE')
- self.b(' { 0, 0, NULL, 0, NULL, NULL }')
- self.b(' };')
- self.b(' static TpDBusPropertiesMixinIfaceInfo interface =')
- self.b(' { 0, properties, NULL, NULL };')
- self.b('')
- self.b(' interface.dbus_interface = g_quark_from_static_string '
- '("%s");' % self.iface_name)
+ self.b(' { 0, %s, "%s", 0, NULL, NULL }, /* %s */'
+ % (flags, m.getAttribute('type'), m.getAttribute('name')))
- for i, m in enumerate(properties):
- self.b(' properties[%d].name = g_quark_from_static_string ("%s");'
- % (i, m.getAttribute('name')))
- self.b(' properties[%d].type = %s;'
- % (i, type_to_gtype(m.getAttribute('type'))[1]))
+ self.b(' { 0, 0, NULL, 0, NULL, NULL }')
+ self.b(' };')
+ self.b(' static TpDBusPropertiesMixinIfaceInfo interface =')
+ self.b(' { 0, properties, NULL, NULL };')
+ self.b('')
- self.b(' tp_svc_interface_set_dbus_properties_info (%s, &interface);'
- % self.current_gtype)
- self.b('')
- for s in base_init_code:
- self.b(s)
self.b(' dbus_g_object_type_install_info (%s%s_get_type (),'
% (self.prefix_, node_name_lc))
self.b(' &_%s%s_object_info);'
% (self.prefix_, node_name_lc))
+ self.b('')
+
+ if properties:
+ self.b(' interface.dbus_interface = g_quark_from_static_string '
+ '("%s");' % self.iface_name)
+
+ for i, m in enumerate(properties):
+ self.b(' properties[%d].name = g_quark_from_static_string ("%s");'
+ % (i, m.getAttribute('name')))
+ self.b(' properties[%d].type = %s;'
+ % (i, type_to_gtype(m.getAttribute('type'))[1]))
+
+ self.b(' tp_svc_interface_set_dbus_properties_info (%s, &interface);'
+ % self.current_gtype)
+
+ self.b('')
+
+ for s in base_init_code:
+ self.b(s)
self.b('}')
self.b('static void')
@@ -276,6 +330,10 @@ class Generator(object):
for method, offset in zip(methods, offsets):
self.do_method_glue(method, offset)
+ if len(methods) == 0:
+ # empty arrays are a gcc extension, so put in a dummy member
+ self.b(" { NULL, NULL, 0 }")
+
self.b('};')
self.b('')
@@ -335,7 +393,11 @@ class Generator(object):
return ''.join(info) + '\0', offsets
def do_method_glue(self, method, offset):
- lc_name = camelcase_to_lower(method.getAttribute('name'))
+ lc_name = method.getAttribute('tp:name-for-bindings')
+ if method.getAttribute('name') != lc_name.replace('_', ''):
+ raise AssertionError('Method %s tp:name-for-bindings (%s) does '
+ 'not match' % (method.getAttribute('name'), lc_name))
+ lc_name = lc_name.lower()
marshaller = method_to_glue_marshal_name(method,
self.signal_marshal_prefix)
@@ -357,10 +419,16 @@ class Generator(object):
def get_method_impl_names(self, method):
dbus_method_name = method.getAttribute('name')
- class_member_name = camelcase_to_lower(dbus_method_name)
+
+ class_member_name = method.getAttribute('tp:name-for-bindings')
+ if dbus_method_name != class_member_name.replace('_', ''):
+ raise AssertionError('Method %s tp:name-for-bindings (%s) does '
+ 'not match' % (dbus_method_name, class_member_name))
+ class_member_name = class_member_name.lower()
+
stub_name = (self.prefix_ + self.node_name_lc + '_' +
class_member_name)
- return (stub_name + '_impl', class_member_name)
+ return (stub_name + '_impl', class_member_name + '_cb')
def do_method(self, method):
assert self.node_name_mixed is not None
@@ -372,7 +440,12 @@ class Generator(object):
# DoStuff
dbus_method_name = method.getAttribute('name')
# do_stuff
- class_member_name = camelcase_to_lower(dbus_method_name)
+ class_member_name = method.getAttribute('tp:name-for-bindings')
+ if dbus_method_name != class_member_name.replace('_', ''):
+ raise AssertionError('Method %s tp:name-for-bindings (%s) does '
+ 'not match' % (dbus_method_name, class_member_name))
+ class_member_name = class_member_name.lower()
+
# void tp_svc_thing_do_stuff (TpSvcThing *, const char *, guint,
# DBusGMethodInvocation *);
stub_name = (self.prefix_ + self.node_name_lc + '_' +
@@ -414,18 +487,19 @@ class Generator(object):
else:
out_args.append(struct)
- # Implementation type declaration (in header, docs in body)
- self.b('/**')
- self.b(' * %s:' % impl_name)
- self.b(' * @self: The object implementing this interface')
+ # Implementation type declaration (in header, docs separated)
+ self.d('/**')
+ self.d(' * %s:' % impl_name)
+ self.d(' * @self: The object implementing this interface')
for (ctype, name) in in_args:
- self.b(' * @%s: %s (FIXME, generate documentation)'
+ self.d(' * @%s: %s (FIXME, generate documentation)'
% (name, ctype))
- self.b(' * @context: Used to return values or throw an error')
- self.b(' *')
- self.b(' * The signature of an implementation of the D-Bus method')
- self.b(' * %s on interface %s.' % (dbus_method_name, self.iface_name))
- self.b(' */')
+ self.d(' * @context: Used to return values or throw an error')
+ self.d(' *')
+ self.d(' * The signature of an implementation of the D-Bus method')
+ self.d(' * %s on interface %s.' % (dbus_method_name, self.iface_name))
+ self.d(' */')
+
self.h('typedef void (*%s) (%s%s *self,'
% (impl_name, self.Prefix, self.node_name_mixed))
for (ctype, name) in in_args:
@@ -443,7 +517,7 @@ class Generator(object):
self.b(' %s%s,' % (ctype, name))
self.b(' DBusGMethodInvocation *context)')
self.b('{')
- self.b(' %s impl = (%s%s_GET_CLASS (self)->%s);'
+ self.b(' %s impl = (%s%s_GET_CLASS (self)->%s_cb);'
% (impl_name, self.PREFIX_, self.node_name_uc, class_member_name))
self.b('')
self.b(' if (impl != NULL)')
@@ -470,38 +544,41 @@ class Generator(object):
% (self.prefix_, self.node_name_lc, class_member_name,
self.Prefix, self.node_name_mixed, impl_name))
- self.b('/**')
- self.b(' * %s%s_implement_%s:'
+ self.d('/**')
+ self.d(' * %s%s_implement_%s:'
% (self.prefix_, self.node_name_lc, class_member_name))
- self.b(' * @klass: A class whose instances implement this interface')
- self.b(' * @impl: A callback used to implement the %s D-Bus method'
+ self.d(' * @klass: A class whose instances implement this interface')
+ self.d(' * @impl: A callback used to implement the %s D-Bus method'
% dbus_method_name)
- self.b(' *')
- self.b(' * Register an implementation for the %s method in the vtable'
+ self.d(' *')
+ self.d(' * Register an implementation for the %s method in the vtable'
% dbus_method_name)
- self.b(' * of an implementation of this interface. To be called from')
- self.b(' * the interface init function.')
- self.b(' */')
+ self.d(' * of an implementation of this interface. To be called from')
+ self.d(' * the interface init function.')
+ self.d(' */')
+
self.b('void')
self.b('%s%s_implement_%s (%s%sClass *klass, %s impl)'
% (self.prefix_, self.node_name_lc, class_member_name,
self.Prefix, self.node_name_mixed, impl_name))
self.b('{')
- self.b(' klass->%s = impl;' % class_member_name)
+ self.b(' klass->%s_cb = impl;' % class_member_name)
self.b('}')
self.b('')
# Return convenience function (static inline, in header)
- self.h('/**')
- self.h(' * %s:' % ret_name)
- self.h(' * @context: The D-Bus method invocation context')
+ self.d('/**')
+ self.d(' * %s:' % ret_name)
+ self.d(' * @context: The D-Bus method invocation context')
for (ctype, name) in out_args:
- self.h(' * @%s: %s (FIXME, generate documentation)'
+ self.d(' * @%s: %s (FIXME, generate documentation)'
% (name, ctype))
- self.h(' *')
- self.h(' * Return successfully by calling dbus_g_method_return().')
- self.h(' * This inline function exists only to provide type-safety.')
- self.h(' */')
+ self.d(' *')
+ self.d(' * Return successfully by calling dbus_g_method_return().')
+ self.d(' * This inline function exists only to provide type-safety.')
+ self.d(' */')
+ self.d('')
+
tmp = (['DBusGMethodInvocation *context'] +
[ctype + name for (ctype, name) in out_args])
self.h('static inline')
@@ -533,8 +610,15 @@ class Generator(object):
# const char *arg0, guint arg1);
dbus_name = signal.getAttribute('name')
+
+ ugly_name = signal.getAttribute('tp:name-for-bindings')
+ if dbus_name != ugly_name.replace('_', ''):
+ raise AssertionError('Signal %s tp:name-for-bindings (%s) does '
+ 'not match' % (dbus_name, ugly_name))
+
stub_name = (self.prefix_ + self.node_name_lc + '_emit_' +
- camelcase_to_lower(dbus_name))
+ ugly_name.lower())
+
const_name = self.get_signal_const_entry(signal)
# Gather arguments
@@ -564,17 +648,17 @@ class Generator(object):
# FIXME: emit docs
- self.b('/**')
- self.b(' * %s:' % stub_name)
- self.b(' * @instance: The object implementing this interface')
+ self.d('/**')
+ self.d(' * %s:' % stub_name)
+ self.d(' * @instance: The object implementing this interface')
for (ctype, name, gtype) in args:
- self.b(' * @%s: %s (FIXME, generate documentation)'
+ self.d(' * @%s: %s (FIXME, generate documentation)'
% (name, ctype))
- self.b(' *')
- self.b(' * Type-safe wrapper around g_signal_emit to emit the')
- self.b(' * %s signal on interface %s.'
+ self.d(' *')
+ self.d(' * Type-safe wrapper around g_signal_emit to emit the')
+ self.d(' * %s signal on interface %s.'
% (dbus_name, self.iface_name))
- self.b(' */')
+ self.d(' */')
self.b('void')
self.b(('%s (' % stub_name) + (',\n '.join(tmp)) + ')')
@@ -590,16 +674,20 @@ class Generator(object):
signal_name = dbus_gutils_wincaps_to_uscore(dbus_name).replace('_',
'-')
- in_base_init.append(' /**')
- in_base_init.append(' * %s%s::%s:'
+
+ self.d('/**')
+ self.d(' * %s%s::%s:'
% (self.Prefix, self.node_name_mixed, signal_name))
+ self.d(' * @self: an object')
for (ctype, name, gtype) in args:
- in_base_init.append(' * @%s: %s (FIXME, generate documentation)'
+ self.d(' * @%s: %s (FIXME, generate documentation)'
% (name, ctype))
- in_base_init.append(' *')
- in_base_init.append(' * The %s D-Bus signal is emitted whenever '
+ self.d(' *')
+ self.d(' * The %s D-Bus signal is emitted whenever '
'this GObject signal is.' % dbus_name)
- in_base_init.append(' */')
+ self.d(' */')
+ self.d('')
+
in_base_init.append(' %s_signals[%s] ='
% (self.node_name_lc, const_name))
in_base_init.append(' g_signal_new ("%s",' % signal_name)
@@ -616,23 +704,33 @@ class Generator(object):
return in_base_init
+ def have_properties(self, nodes):
+ for node in nodes:
+ interface = node.getElementsByTagName('interface')[0]
+ if interface.getElementsByTagName('property'):
+ return True
+ return False
+
def __call__(self):
+ nodes = self.dom.getElementsByTagName('node')
+ nodes.sort(cmp_by_name)
+
self.h('#include <glib-object.h>')
self.h('#include <dbus/dbus-glib.h>')
- self.h('#include <telepathy-glib/dbus-properties-mixin.h>')
+
+ if self.have_properties(nodes):
+ self.h('#include <telepathy-glib/dbus-properties-mixin.h>')
+
self.h('')
self.h('G_BEGIN_DECLS')
self.h('')
- self.b('#include "%s.h"' % basename)
+ self.b('#include "%s.h"' % self.basename)
self.b('')
for header in self.headers:
self.b('#include %s' % header)
self.b('')
- nodes = self.dom.getElementsByTagName('node')
- nodes.sort(cmp_by_name)
-
for node in nodes:
self.do_node(node)
@@ -645,8 +743,9 @@ class Generator(object):
self.h('')
self.b('')
- open(basename + '.h', 'w').write('\n'.join(self.__header))
- open(basename + '.c', 'w').write('\n'.join(self.__body))
+ open(self.basename + '.h', 'w').write('\n'.join(self.__header))
+ open(self.basename + '.c', 'w').write('\n'.join(self.__body))
+ open(self.basename + '-gtk-doc.h', 'w').write('\n'.join(self.__docs))
def cmdline_error():