[next] telepathy-glib: codegen: inline type-checks into the generated header file
Simon McVittie
smcv at kemper.freedesktop.org
Mon Apr 30 11:04:03 PDT 2012
Module: telepathy-glib
Branch: next
Commit: 553a2105c6b077da0cd4c194ab274cdbd5054600
URL: http://cgit.freedesktop.org/telepathy/telepathy-glib/commit/?id=553a2105c6b077da0cd4c194ab274cdbd5054600
Author: Simon McVittie <simon.mcvittie at collabora.co.uk>
Date: Fri Apr 27 15:38:32 2012 +0100
codegen: inline type-checks into the generated header file
We don't want tp_cli_channel_foo() (in the -dbus library) to depend on
TP_IS_CHANNEL, which expands to something involving tp_channel_get_type()
(in the -main library). So, do the type-check in an inline wrapper around
the real function.
As a double-check, we should make sure that the proxy is at least a
proxy. Every generated function calls tp_proxy_borrow_interface_by_id()
early on, so we can use that to host the type-check.
Signed-off-by: Simon McVittie <simon.mcvittie at collabora.co.uk>
Reviewed-by: Jonny Lamb <jonny.lamb at collabora.co.uk>
Bug: https://bugs.freedesktop.org/show_bug.cgi?id=46835
---
telepathy-glib/proxy.c | 2 +
tools/glib-client-gen.py | 83 +++++++++++++++++++++++++++++++++++++---------
2 files changed, 69 insertions(+), 16 deletions(-)
diff --git a/telepathy-glib/proxy.c b/telepathy-glib/proxy.c
index 0dab0be..6990ee4 100644
--- a/telepathy-glib/proxy.c
+++ b/telepathy-glib/proxy.c
@@ -434,6 +434,8 @@ _tp_proxy_borrow_interface_by_id (TpProxy *self,
{
gpointer dgproxy;
+ g_return_val_if_fail (TP_IS_PROXY (self), NULL);
+
if (self->invalidated != NULL)
{
g_set_error (error, self->invalidated->domain, self->invalidated->code,
diff --git a/tools/glib-client-gen.py b/tools/glib-client-gen.py
index c357470..1cdb405 100644
--- a/tools/glib-client-gen.py
+++ b/tools/glib-client-gen.py
@@ -325,9 +325,11 @@ class Generator(object):
# emitted the 'invalidated' signal, or because the weakly referenced
# object has gone away.
- self.d('/**')
- self.d(' * %s_%s_connect_to_%s:'
+ connect_to = ('%s_%s_connect_to_%s'
% (self.prefix_lc, iface_lc, member_lc))
+
+ self.d('/**')
+ self.d(' * %s:' % connect_to)
self.d(' * @proxy: %s' % self.proxy_doc)
self.d(' * @callback: Callback to be called when the signal is')
self.d(' * received')
@@ -352,8 +354,8 @@ class Generator(object):
self.d(' */')
self.d('')
- self.h('TpProxySignalConnection *%s_%s_connect_to_%s (%sproxy,'
- % (self.prefix_lc, iface_lc, member_lc, self.proxy_arg))
+ self.h('TpProxySignalConnection *%s (%sproxy,'
+ % (connect_to, self.proxy_arg))
self.h(' %s callback,' % callback_name)
self.h(' gpointer user_data,')
self.h(' GDestroyNotify destroy,')
@@ -362,8 +364,7 @@ class Generator(object):
self.h('')
self.b('TpProxySignalConnection *')
- self.b('%s_%s_connect_to_%s (%sproxy,'
- % (self.prefix_lc, iface_lc, member_lc, self.proxy_arg))
+ self.b('(%s) (%sproxy,' % (connect_to, self.proxy_arg))
self.b(' %s callback,' % callback_name)
self.b(' gpointer user_data,')
self.b(' GDestroyNotify destroy,')
@@ -380,8 +381,6 @@ class Generator(object):
self.b(' G_TYPE_INVALID };')
self.b('')
- self.b(' g_return_val_if_fail (%s (proxy), NULL);'
- % self.proxy_assert)
self.b(' g_return_val_if_fail (callback != NULL, NULL);')
self.b('')
self.b(' return tp_proxy_signal_connection_v0_new ((TpProxy *) proxy,')
@@ -399,6 +398,26 @@ class Generator(object):
self.b('}')
self.b('')
+ # Inline the type-check into the header file, so the object code
+ # doesn't depend on tp_channel_get_type() or whatever
+ self.h('#ifndef __GTK_DOC_IGNORE__')
+ self.h('static inline TpProxySignalConnection *')
+ self.h('_%s (%sproxy,' % (connect_to, self.proxy_arg))
+ self.h(' %s callback,' % callback_name)
+ self.h(' gpointer user_data,')
+ self.h(' GDestroyNotify destroy,')
+ self.h(' GObject *weak_object,')
+ self.h(' GError **error)')
+ self.h('{')
+ self.h(' g_return_val_if_fail (%s (proxy), NULL);'
+ % self.proxy_assert)
+ self.h(' return %s (proxy, callback, user_data,' % connect_to)
+ self.h(' destroy, weak_object, error);')
+ self.h('}')
+ self.h('#define %s(...) _%s (__VA_ARGS__)'
+ % (connect_to, connect_to))
+ self.h('#endif /* __GTK_DOC_IGNORE__ */')
+
def do_method(self, iface, method):
iface_lc = iface.lower()
@@ -711,13 +730,15 @@ class Generator(object):
# gpointer user_data,
# GDestroyNotify *destructor);
- self.h('TpProxyPendingCall *%s_%s_call_%s (%sproxy,'
- % (self.prefix_lc, iface_lc, member_lc, self.proxy_arg))
+ caller_name = ('%s_%s_call_%s'
+ % (self.prefix_lc, iface_lc, member_lc))
+
+ self.h('TpProxyPendingCall *%s (%sproxy,'
+ % (caller_name, self.proxy_arg))
self.h(' gint timeout_ms,')
self.d('/**')
- self.d(' * %s_%s_call_%s:'
- % (self.prefix_lc, iface_lc, member_lc))
+ self.d(' * %s:' % caller_name)
self.d(' * @proxy: the #TpProxy')
self.d(' * @timeout_ms: the timeout in milliseconds, or -1 to use the')
self.d(' * default')
@@ -765,8 +786,8 @@ class Generator(object):
self.d(' */')
self.d('')
- self.b('TpProxyPendingCall *\n%s_%s_call_%s (%sproxy,'
- % (self.prefix_lc, iface_lc, member_lc, self.proxy_arg))
+ self.b('TpProxyPendingCall *\n(%s) (%sproxy,'
+ % (caller_name, self.proxy_arg))
self.b(' gint timeout_ms,')
for arg in in_args:
@@ -793,8 +814,6 @@ class Generator(object):
self.b(' GQuark interface = %s;' % self.get_iface_quark())
self.b(' DBusGProxy *iface;')
self.b('')
- self.b(' g_return_val_if_fail (%s (proxy), NULL);'
- % self.proxy_assert)
self.b(' g_return_val_if_fail (callback != NULL || '
'user_data == NULL, NULL);')
self.b(' g_return_val_if_fail (callback != NULL || '
@@ -868,6 +887,38 @@ class Generator(object):
self.b('}')
self.b('')
+ # Inline the type-check into the header file, so the object code
+ # doesn't depend on tp_channel_get_type() or whatever
+ self.h('#ifndef __GTK_DOC_IGNORE__')
+ self.h('static inline TpProxyPendingCall *')
+ self.h('_%s (%sproxy,' % (caller_name, self.proxy_arg))
+ self.h(' gint timeout_ms,')
+
+ for arg in in_args:
+ name, info, tp_type, elt = arg
+ ctype, gtype, marshaller, pointer = info
+ const = pointer and 'const ' or ''
+ self.h(' %s%s%s,' % (const, ctype, name))
+
+ self.h(' %s callback,' % callback_name)
+ self.h(' gpointer user_data,')
+ self.h(' GDestroyNotify destroy,')
+ self.h(' GObject *weak_object)')
+ self.h('{')
+ self.h(' g_return_val_if_fail (%s (proxy), NULL);'
+ % self.proxy_assert)
+ self.h(' return %s (proxy, timeout_ms,' % caller_name)
+
+ for arg in in_args:
+ name, info, tp_type, elt = arg
+ self.h(' %s,' % name)
+
+ self.h(' callback, user_data, destroy, weak_object);')
+ self.h('}')
+ self.h('#define %s(...) _%s (__VA_ARGS__)'
+ % (caller_name, caller_name))
+ self.h('#endif /* __GTK_DOC_IGNORE__ */')
+
self.do_method_reentrant(method, iface_lc, member, member_lc,
in_args, out_args, collect_callback)
More information about the telepathy-commits
mailing list