summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--tools/glib-client-gen.py319
-rw-r--r--tools/glib-client-marshaller-gen.py3
-rw-r--r--tools/glib-ginterface-gen.py207
-rw-r--r--tools/glib-gtypes-generator.py193
-rw-r--r--tools/libglibcodegen.py3
-rw-r--r--tools/libtpcodegen.py24
6 files changed, 474 insertions, 275 deletions
diff --git a/tools/glib-client-gen.py b/tools/glib-client-gen.py
index 69885968..f8465a62 100644
--- a/tools/glib-client-gen.py
+++ b/tools/glib-client-gen.py
@@ -27,8 +27,9 @@ import os.path
import xml.dom.minidom
from getopt import gnu_getopt
+from libtpcodegen import file_set_contents
from libglibcodegen import Signature, type_to_gtype, cmp_by_name, \
- get_docstring, xml_escape
+ get_docstring, xml_escape, get_deprecated
NS_TP = "http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0"
@@ -39,6 +40,7 @@ class Generator(object):
self.dom = dom
self.__header = []
self.__body = []
+ self.__docs = []
self.prefix_lc = prefix.lower()
self.prefix_uc = prefix.upper()
@@ -55,9 +57,21 @@ class Generator(object):
% opts.get('--subclass', 'TpProxy'))
if self.proxy_arg == 'void *':
self.proxy_arg = 'gpointer '
- self.generate_reentrant = ('--generate-reentrant' in opts or
- '--deprecate-reentrant' in opts)
+
+ self.reentrant_symbols = set()
+ try:
+ filename = opts['--generate-reentrant']
+ with open(filename, 'r') as f:
+ for line in f.readlines():
+ self.reentrant_symbols.add(line.strip())
+ except KeyError:
+ pass
+
self.deprecate_reentrant = opts.get('--deprecate-reentrant', None)
+ self.deprecation_attribute = opts.get('--deprecation-attribute',
+ 'G_GNUC_DEPRECATED')
+
+ self.guard = opts.get('--guard', None)
def h(self, s):
if isinstance(s, unicode):
@@ -69,6 +83,11 @@ class Generator(object):
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 get_iface_quark(self):
assert self.iface_dbus is not None
assert self.iface_uc is not None
@@ -121,25 +140,31 @@ class Generator(object):
# guint arg_handle, gboolean arg_suppress_handler,
# gpointer user_data, GObject *weak_object);
- self.b('/**')
- self.b(' * %s:' % callback_name)
- self.b(' * @proxy: The proxy on which %s_%s_connect_to_%s ()'
+ self.d('/**')
+ self.d(' * %s:' % callback_name)
+ self.d(' * @proxy: The proxy on which %s_%s_connect_to_%s ()'
% (self.prefix_lc, iface_lc, member_lc))
- self.b(' * was called')
+ self.d(' * was called')
for arg in args:
name, info, tp_type, elt = arg
ctype, gtype, marshaller, pointer = info
- self.b(' * @%s: %s' % (name,
- xml_escape(get_docstring(elt) or '(Undocumented)')))
+ docs = get_docstring(elt) or '(Undocumented)'
+
+ if ctype == 'guint ' and tp_type != '':
+ docs += ' (#%s)' % ('Tp' + tp_type.replace('_', ''))
- self.b(' * @user_data: User-supplied data')
- self.b(' * @weak_object: User-supplied weakly referenced object')
- self.b(' *')
- self.b(' * Represents the signature of a callback for the signal %s.'
+ self.d(' * @%s: %s' % (name, xml_escape(docs)))
+
+ self.d(' * @user_data: User-supplied data')
+ self.d(' * @weak_object: User-supplied weakly referenced object')
+ self.d(' *')
+ self.d(' * Represents the signature of a callback for the signal %s.'
% member)
- self.b(' */')
+ self.d(' */')
+ self.d('')
+
self.h('typedef void (*%s) (%sproxy,'
% (callback_name, self.proxy_cls))
@@ -288,31 +313,33 @@ class Generator(object):
# emitted the 'invalidated' signal, or because the weakly referenced
# object has gone away.
- self.b('/**')
- self.b(' * %s_%s_connect_to_%s:'
+ self.d('/**')
+ self.d(' * %s_%s_connect_to_%s:'
% (self.prefix_lc, iface_lc, member_lc))
- self.b(' * @proxy: %s' % self.proxy_doc)
- self.b(' * @callback: Callback to be called when the signal is')
- self.b(' * received')
- self.b(' * @user_data: User-supplied data for the callback')
- self.b(' * @destroy: Destructor for the user-supplied data, which')
- self.b(' * will be called when this signal is disconnected, or')
- self.b(' * before this function returns %NULL')
- self.b(' * @weak_object: A #GObject which will be weakly referenced; ')
- self.b(' * if it is destroyed, this callback will automatically be')
- self.b(' * disconnected')
- self.b(' * @error: If not %NULL, used to raise an error if %NULL is')
- self.b(' * returned')
- self.b(' *')
- self.b(' * Connect a handler to the signal %s.' % member)
- self.b(' *')
- self.b(' * %s' % xml_escape(get_docstring(signal) or '(Undocumented)'))
- self.b(' *')
- self.b(' * Returns: a #TpProxySignalConnection containing all of the')
- self.b(' * above, which can be used to disconnect the signal; or')
- self.b(' * %NULL if the proxy does not have the desired interface')
- self.b(' * or has become invalid.')
- self.b(' */')
+ self.d(' * @proxy: %s' % self.proxy_doc)
+ self.d(' * @callback: Callback to be called when the signal is')
+ self.d(' * received')
+ self.d(' * @user_data: User-supplied data for the callback')
+ self.d(' * @destroy: Destructor for the user-supplied data, which')
+ self.d(' * will be called when this signal is disconnected, or')
+ self.d(' * before this function returns %NULL')
+ self.d(' * @weak_object: A #GObject which will be weakly referenced; ')
+ self.d(' * if it is destroyed, this callback will automatically be')
+ self.d(' * disconnected')
+ self.d(' * @error: If not %NULL, used to raise an error if %NULL is')
+ self.d(' * returned')
+ self.d(' *')
+ self.d(' * Connect a handler to the signal %s.' % member)
+ self.d(' *')
+ self.d(' * %s' % xml_escape(get_docstring(signal) or '(Undocumented)'))
+ self.d(' *')
+ self.d(' * Returns: a #TpProxySignalConnection containing all of the')
+ self.d(' * above, which can be used to disconnect the signal; or')
+ self.d(' * %NULL if the proxy does not have the desired interface')
+ self.d(' * or has become invalid.')
+ 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(' %s callback,' % callback_name)
@@ -320,6 +347,7 @@ class Generator(object):
self.h(' GDestroyNotify destroy,')
self.h(' GObject *weak_object,')
self.h(' GError **error);')
+ self.h('')
self.b('TpProxySignalConnection *')
self.b('%s_%s_connect_to_%s (%sproxy,'
@@ -359,8 +387,6 @@ class Generator(object):
self.b('}')
self.b('')
- self.h('')
-
def do_method(self, iface, method):
iface_lc = iface.lower()
@@ -412,27 +438,40 @@ class Generator(object):
# gpointer user_data,
# GObject *weak_object);
- self.b('/**')
- self.b(' * %s_%s_callback_for_%s:'
+ self.d('/**')
+ self.d(' * %s_%s_callback_for_%s:'
% (self.prefix_lc, iface_lc, member_lc))
- self.b(' * @proxy: the proxy on which the call was made')
+ self.d(' * @proxy: the proxy on which the call was made')
for arg in out_args:
name, info, tp_type, elt = arg
ctype, gtype, marshaller, pointer = info
- self.b(' * @%s: Used to return an \'out\' argument if @error is '
+ docs = xml_escape(get_docstring(elt) or '(Undocumented)')
+
+ if ctype == 'guint ' and tp_type != '':
+ docs += ' (#%s)' % ('Tp' + tp_type.replace('_', ''))
+
+ self.d(' * @%s: Used to return an \'out\' argument if @error is '
'%%NULL: %s'
- % (name, xml_escape(get_docstring(elt) or '(Undocumented)')))
+ % (name, docs))
- self.b(' * @error: %NULL on success, or an error on failure')
- self.b(' * @user_data: user-supplied data')
- self.b(' * @weak_object: user-supplied object')
- self.b(' *')
- self.b(' * Signature of the callback called when a %s method call'
+ self.d(' * @error: %NULL on success, or an error on failure')
+ self.d(' * @user_data: user-supplied data')
+ self.d(' * @weak_object: user-supplied object')
+ self.d(' *')
+ self.d(' * Signature of the callback called when a %s method call'
% member)
- self.b(' * succeeds or fails.')
- self.b(' */')
+ self.d(' * succeeds or fails.')
+
+ deprecated = method.getElementsByTagName('tp:deprecated')
+ if deprecated:
+ d = deprecated[0]
+ self.d(' *')
+ self.d(' * Deprecated: %s' % xml_escape(get_deprecated(d)))
+
+ self.d(' */')
+ self.d('')
callback_name = '%s_%s_callback_for_%s' % (self.prefix_lc, iface_lc,
member_lc)
@@ -657,42 +696,56 @@ class Generator(object):
% (self.prefix_lc, iface_lc, member_lc, self.proxy_arg))
self.h(' gint timeout_ms,')
- self.b('/**')
- self.b(' * %s_%s_call_%s:'
+ self.d('/**')
+ self.d(' * %s_%s_call_%s:'
% (self.prefix_lc, iface_lc, member_lc))
- self.b(' * @proxy: the #TpProxy')
- self.b(' * @timeout_ms: the timeout in milliseconds, or -1 to use the')
- self.b(' * default')
+ self.d(' * @proxy: the #TpProxy')
+ self.d(' * @timeout_ms: the timeout in milliseconds, or -1 to use the')
+ self.d(' * default')
for arg in in_args:
name, info, tp_type, elt = arg
ctype, gtype, marshaller, pointer = info
- self.b(' * @%s: Used to pass an \'in\' argument: %s'
- % (name, xml_escape(get_docstring(elt) or '(Undocumented)')))
+ docs = xml_escape(get_docstring(elt) or '(Undocumented)')
+
+ if ctype == 'guint ' and tp_type != '':
+ docs += ' (#%s)' % ('Tp' + tp_type.replace('_', ''))
+
+ self.d(' * @%s: Used to pass an \'in\' argument: %s'
+ % (name, docs))
+
+ self.d(' * @callback: called when the method call succeeds or fails;')
+ self.d(' * may be %NULL to make a "fire and forget" call with no ')
+ self.d(' * reply tracking')
+ self.d(' * @user_data: user-supplied data passed to the callback;')
+ self.d(' * must be %NULL if @callback is %NULL')
+ self.d(' * @destroy: called with the user_data as argument, after the')
+ self.d(' * call has succeeded, failed or been cancelled;')
+ self.d(' * must be %NULL if @callback is %NULL')
+ self.d(' * @weak_object: If not %NULL, a #GObject which will be ')
+ self.d(' * weakly referenced; if it is destroyed, this call ')
+ self.d(' * will automatically be cancelled. Must be %NULL if ')
+ self.d(' * @callback is %NULL')
+ self.d(' *')
+ self.d(' * Start a %s method call.' % member)
+ self.d(' *')
+ self.d(' * %s' % xml_escape(get_docstring(method) or '(Undocumented)'))
+ self.d(' *')
+ self.d(' * Returns: a #TpProxyPendingCall representing the call in')
+ self.d(' * progress. It is borrowed from the object, and will become')
+ self.d(' * invalid when the callback is called, the call is')
+ self.d(' * cancelled or the #TpProxy becomes invalid.')
+
+ deprecated = method.getElementsByTagName('tp:deprecated')
+ if deprecated:
+ d = deprecated[0]
+ self.d(' *')
+ self.d(' * Deprecated: %s' % xml_escape(get_deprecated(d)))
+
+ self.d(' */')
+ self.d('')
- self.b(' * @callback: called when the method call succeeds or fails;')
- self.b(' * may be %NULL to make a "fire and forget" call with no ')
- self.b(' * reply tracking')
- self.b(' * @user_data: user-supplied data passed to the callback;')
- self.b(' * must be %NULL if @callback is %NULL')
- self.b(' * @destroy: called with the user_data as argument, after the')
- self.b(' * call has succeeded, failed or been cancelled;')
- self.b(' * must be %NULL if @callback is %NULL')
- self.b(' * @weak_object: If not %NULL, a #GObject which will be ')
- self.b(' * weakly referenced; if it is destroyed, this call ')
- self.b(' * will automatically be cancelled. Must be %NULL if ')
- self.b(' * @callback is %NULL')
- self.b(' *')
- self.b(' * Start a %s method call.' % member)
- self.b(' *')
- self.b(' * %s' % xml_escape(get_docstring(method) or '(Undocumented)'))
- self.b(' *')
- self.b(' * Returns: a #TpProxyPendingCall representing the call in')
- self.b(' * progress. It is borrowed from the object, and will become')
- self.b(' * invalid when the callback is called, the call is')
- self.b(' * cancelled or the #TpProxy becomes invalid.')
- self.b(' */')
self.b('TpProxyPendingCall *\n%s_%s_call_%s (%sproxy,'
% (self.prefix_lc, iface_lc, member_lc, self.proxy_arg))
self.b(' gint timeout_ms,')
@@ -730,9 +783,11 @@ class Generator(object):
self.b(' g_return_val_if_fail (callback != NULL || '
'weak_object == NULL, NULL);')
self.b('')
+ self.b(' G_GNUC_BEGIN_IGNORE_DEPRECATIONS')
self.b(' iface = tp_proxy_borrow_interface_by_id (')
self.b(' (TpProxy *) proxy,')
self.b(' interface, &error);')
+ self.b(' G_GNUC_END_IGNORE_DEPRECATIONS')
self.b('')
self.b(' if (iface == NULL)')
self.b(' {')
@@ -804,11 +859,11 @@ class Generator(object):
self.b('}')
self.b('')
- if self.generate_reentrant:
- self.do_method_reentrant(method, iface_lc, member, member_lc,
- in_args, out_args, collect_callback)
+ self.do_method_reentrant(method, iface_lc, member, member_lc,
+ in_args, out_args, collect_callback)
# leave a gap for the end of the method
+ self.d('')
self.b('')
self.h('')
@@ -824,6 +879,10 @@ class Generator(object):
# GError **error,
# GMainLoop **loop);
+ run_method_name = '%s_%s_run_%s' % (self.prefix_lc, iface_lc, member_lc)
+ if run_method_name not in self.reentrant_symbols:
+ return
+
self.b('typedef struct {')
self.b(' GMainLoop *loop;')
self.b(' GError **error;')
@@ -901,50 +960,64 @@ class Generator(object):
if self.deprecate_reentrant:
self.h('#ifndef %s' % self.deprecate_reentrant)
- self.h('gboolean %s_%s_run_%s (%sproxy,'
- % (self.prefix_lc, iface_lc, member_lc, self.proxy_arg))
+ self.h('gboolean %s (%sproxy,'
+ % (run_method_name, self.proxy_arg))
self.h(' gint timeout_ms,')
- self.b('/**')
- self.b(' * %s_%s_run_%s:' % (self.prefix_lc, iface_lc, member_lc))
- self.b(' * @proxy: %s' % self.proxy_doc)
- self.b(' * @timeout_ms: Timeout in milliseconds, or -1 for default')
+ self.d('/**')
+ self.d(' * %s:' % run_method_name)
+ self.d(' * @proxy: %s' % self.proxy_doc)
+ self.d(' * @timeout_ms: Timeout in milliseconds, or -1 for default')
for arg in in_args:
name, info, tp_type, elt = arg
ctype, gtype, marshaller, pointer = info
- self.b(' * @%s: Used to pass an \'in\' argument: %s'
- % (name, xml_escape(get_docstring(elt) or '(Undocumented)')))
+ docs = xml_escape(get_docstring(elt) or '(Undocumented)')
+
+ if ctype == 'guint ' and tp_type != '':
+ docs += ' (#%s)' % ('Tp' + tp_type.replace('_', ''))
+
+ self.d(' * @%s: Used to pass an \'in\' argument: %s'
+ % (name, docs))
for arg in out_args:
name, info, tp_type, elt = arg
ctype, gtype, marshaller, pointer = info
- self.b(' * @%s: Used to return an \'out\' argument if %%TRUE is '
+ self.d(' * @%s: Used to return an \'out\' argument if %%TRUE is '
'returned: %s'
% (name, xml_escape(get_docstring(elt) or '(Undocumented)')))
- self.b(' * @error: If not %NULL, used to return errors if %FALSE ')
- self.b(' * is returned')
- self.b(' * @loop: If not %NULL, set before re-entering ')
- self.b(' * the main loop, to point to a #GMainLoop ')
- self.b(' * which can be used to cancel this call with ')
- self.b(' * g_main_loop_quit(), causing a return of ')
- self.b(' * %FALSE with @error set to %TP_DBUS_ERROR_CANCELLED')
- self.b(' *')
- self.b(' * Call the method %s and run the main loop' % member)
- self.b(' * until it returns. Before calling this method, you must')
- self.b(' * add a reference to any borrowed objects you need to keep,')
- self.b(' * and generally ensure that everything is in a consistent')
- self.b(' * state.')
- self.b(' *')
- self.b(' * %s' % xml_escape(get_docstring(method) or '(Undocumented)'))
- self.b(' *')
- self.b(' * Returns: TRUE on success, FALSE and sets @error on error')
- self.b(' */')
- self.b('gboolean\n%s_%s_run_%s (%sproxy,'
- % (self.prefix_lc, iface_lc, member_lc, self.proxy_arg))
+ self.d(' * @error: If not %NULL, used to return errors if %FALSE ')
+ self.d(' * is returned')
+ self.d(' * @loop: If not %NULL, set before re-entering ')
+ self.d(' * the main loop, to point to a #GMainLoop ')
+ self.d(' * which can be used to cancel this call with ')
+ self.d(' * g_main_loop_quit(), causing a return of ')
+ self.d(' * %FALSE with @error set to %TP_DBUS_ERROR_CANCELLED')
+ self.d(' *')
+ self.d(' * Call the method %s and run the main loop' % member)
+ self.d(' * until it returns. Before calling this method, you must')
+ self.d(' * add a reference to any borrowed objects you need to keep,')
+ self.d(' * and generally ensure that everything is in a consistent')
+ self.d(' * state.')
+ self.d(' *')
+ self.d(' * %s' % xml_escape(get_docstring(method) or '(Undocumented)'))
+ self.d(' *')
+ self.d(' * Returns: TRUE on success, FALSE and sets @error on error')
+
+ deprecated = method.getElementsByTagName('tp:deprecated')
+ if deprecated:
+ d = deprecated[0]
+ self.d(' *')
+ self.d(' * Deprecated: %s' % xml_escape(get_deprecated(d)))
+
+ self.d(' */')
+ self.d('')
+
+ self.b('gboolean\n%s (%sproxy,'
+ % (run_method_name, self.proxy_arg))
self.b(' gint timeout_ms,')
for arg in in_args:
@@ -966,7 +1039,7 @@ class Generator(object):
self.h(' GError **error,')
if self.deprecate_reentrant:
- self.h(' GMainLoop **loop) G_GNUC_DEPRECATED;')
+ self.h(' GMainLoop **loop) %s;' % self.deprecation_attribute)
self.h('#endif /* not %s */' % self.deprecate_reentrant)
else:
self.h(' GMainLoop **loop);')
@@ -993,8 +1066,10 @@ class Generator(object):
self.b(' g_return_val_if_fail (%s (proxy), FALSE);'
% self.proxy_assert)
self.b('')
+ self.b(' G_GNUC_BEGIN_IGNORE_DEPRECATIONS')
self.b(' iface = tp_proxy_borrow_interface_by_id')
self.b(' ((TpProxy *) proxy, interface, error);')
+ self.b(' G_GNUC_END_IGNORE_DEPRECATIONS')
self.b('')
self.b(' if (iface == NULL)')
self.b(' return FALSE;')
@@ -1102,6 +1177,11 @@ class Generator(object):
def __call__(self):
+ if self.guard is not None:
+ self.h('#ifndef %s' % self.guard)
+ self.h('#define %s' % self.guard)
+ self.h('')
+
self.h('G_BEGIN_DECLS')
self.h('')
@@ -1160,9 +1240,13 @@ class Generator(object):
self.h('G_END_DECLS')
self.h('')
- open(self.basename + '.h', 'w').write('\n'.join(self.__header))
- open(self.basename + '-body.h', 'w').write('\n'.join(self.__body))
+ if self.guard is not None:
+ self.h('#endif /* defined (%s) */' % self.guard)
+ self.h('')
+ file_set_contents(self.basename + '.h', '\n'.join(self.__header))
+ file_set_contents(self.basename + '-body.h', '\n'.join(self.__body))
+ file_set_contents(self.basename + '-gtk-doc.h', '\n'.join(self.__docs))
def types_to_gtypes(types):
return [type_to_gtype(t)[1] for t in types]
@@ -1172,7 +1256,8 @@ if __name__ == '__main__':
options, argv = gnu_getopt(sys.argv[1:], '',
['group=', 'subclass=', 'subclass-assert=',
'iface-quark-prefix=', 'tp-proxy-api=',
- 'generate-reentrant', 'deprecate-reentrant='])
+ 'generate-reentrant=', 'deprecate-reentrant=',
+ 'deprecation-attribute=', 'guard='])
opts = {}
diff --git a/tools/glib-client-marshaller-gen.py b/tools/glib-client-marshaller-gen.py
index 54447255..cb27d638 100644
--- a/tools/glib-client-marshaller-gen.py
+++ b/tools/glib-client-marshaller-gen.py
@@ -40,7 +40,8 @@ class Generator(object):
for marshaller in all:
rhs = self.marshallers[marshaller]
- print ' dbus_g_object_register_marshaller (%s,' % marshaller
+ print ' dbus_g_object_register_marshaller ('
+ print ' g_cclosure_marshal_generic,'
print ' G_TYPE_NONE, /* return */'
for type in rhs:
print ' G_TYPE_%s,' % type.replace('VOID', 'NONE')
diff --git a/tools/glib-ginterface-gen.py b/tools/glib-ginterface-gen.py
index b361c7f4..6fec0d3c 100644
--- a/tools/glib-ginterface-gen.py
+++ b/tools/glib-ginterface-gen.py
@@ -26,13 +26,23 @@ import sys
import os.path
import xml.dom.minidom
+from libtpcodegen import file_set_contents
from libglibcodegen import Signature, type_to_gtype, cmp_by_name, \
- NS_TP, dbus_gutils_wincaps_to_uscore, \
- signal_to_marshal_name, method_to_glue_marshal_name
+ NS_TP, dbus_gutils_wincaps_to_uscore
NS_TP = "http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0"
+def get_emits_changed(node):
+ try:
+ return [
+ annotation.getAttribute('value')
+ for annotation in node.getElementsByTagName('annotation')
+ if annotation.getAttribute('name') == 'org.freedesktop.DBus.Property.EmitsChangedSignal'
+ ][0]
+ except IndexError:
+ return None
+
class Generator(object):
def __init__(self, dom, prefix, basename, signal_marshal_prefix,
@@ -41,6 +51,7 @@ class Generator(object):
self.dom = dom
self.__header = []
self.__body = []
+ self.__docs = []
assert prefix.endswith('_')
assert not signal_marshal_prefix.endswith('_')
@@ -74,11 +85,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('_', '')
@@ -98,6 +118,8 @@ class Generator(object):
if tmp and not self.allow_havoc:
raise AssertionError('%s is %s' % (self.iface_name, tmp))
+ iface_emits_changed = get_emits_changed(interface)
+
self.b('static const DBusGObjectInfo _%s%s_object_info;'
% (self.prefix_, node_name_lc))
self.b('')
@@ -158,20 +180,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('')
@@ -225,6 +282,16 @@ class Generator(object):
flags = ('TP_DBUS_PROPERTIES_MIXIN_FLAG_READ | '
'TP_DBUS_PROPERTIES_MIXIN_FLAG_WRITE')
+ prop_emits_changed = get_emits_changed(m)
+
+ if prop_emits_changed is None:
+ prop_emits_changed = iface_emits_changed
+
+ if prop_emits_changed == 'true':
+ flags += ' | TP_DBUS_PROPERTIES_MIXIN_FLAG_EMITS_CHANGED'
+ elif prop_emits_changed == 'invalidates':
+ flags += ' | TP_DBUS_PROPERTIES_MIXIN_FLAG_EMITS_INVALIDATED'
+
self.b(' { 0, %s, "%s", 0, NULL, NULL }, /* %s */'
% (flags, m.getAttribute('type'), m.getAttribute('name')))
@@ -354,8 +421,7 @@ class Generator(object):
'not match' % (method.getAttribute('name'), lc_name))
lc_name = lc_name.lower()
- marshaller = method_to_glue_marshal_name(method,
- self.signal_marshal_prefix)
+ marshaller = 'g_cclosure_marshal_generic'
wrapper = self.prefix_ + self.node_name_lc + '_' + lc_name
self.b(" { (GCallback) %s, %s, %d }," % (wrapper, marshaller, offset))
@@ -383,7 +449,7 @@ class Generator(object):
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
@@ -442,18 +508,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:
@@ -471,7 +538,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)')
@@ -498,38 +565,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')
@@ -599,17 +669,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)) + ')')
@@ -625,16 +695,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)
@@ -642,8 +716,7 @@ class Generator(object):
in_base_init.append(' G_SIGNAL_RUN_LAST|G_SIGNAL_DETAILED,')
in_base_init.append(' 0,')
in_base_init.append(' NULL, NULL,')
- in_base_init.append(' %s,'
- % signal_to_marshal_name(signal, self.signal_marshal_prefix))
+ in_base_init.append(' g_cclosure_marshal_generic,')
in_base_init.append(' G_TYPE_NONE,')
tmp = ['%d' % len(args)] + [gtype for (ctype, name, gtype) in args]
in_base_init.append(' %s);' % ',\n '.join(tmp))
@@ -665,8 +738,9 @@ class Generator(object):
self.h('#include <glib-object.h>')
self.h('#include <dbus/dbus-glib.h>')
- if self.have_properties(nodes):
- self.h('#include <telepathy-glib/dbus-properties-mixin.h>')
+ for header in self.headers:
+ self.h('#include %s' % header)
+ self.h('')
self.h('')
self.h('G_BEGIN_DECLS')
@@ -674,9 +748,6 @@ class Generator(object):
self.b('#include "%s.h"' % self.basename)
self.b('')
- for header in self.headers:
- self.b('#include %s' % header)
- self.b('')
for node in nodes:
self.do_node(node)
@@ -690,9 +761,9 @@ class Generator(object):
self.h('')
self.b('')
- open(self.basename + '.h', 'w').write('\n'.join(self.__header))
- open(self.basename + '.c', 'w').write('\n'.join(self.__body))
-
+ file_set_contents(self.basename + '.h', '\n'.join(self.__header))
+ file_set_contents(self.basename + '.c', '\n'.join(self.__body))
+ file_set_contents(self.basename + '-gtk-doc.h', '\n'.join(self.__docs))
def cmdline_error():
print """\
diff --git a/tools/glib-gtypes-generator.py b/tools/glib-gtypes-generator.py
index 29debf17..21dfc6aa 100644
--- a/tools/glib-gtypes-generator.py
+++ b/tools/glib-gtypes-generator.py
@@ -23,6 +23,7 @@
import sys
import xml.dom.minidom
+from libtpcodegen import file_set_contents
from libglibcodegen import escape_as_identifier, \
get_docstring, \
NS_TP, \
@@ -42,14 +43,16 @@ class GTypesGenerator(object):
self.PREFIX_ = self.Prefix.upper() + '_'
self.prefix_ = self.Prefix.lower() + '_'
- self.header = open(output + '.h', 'w')
- self.body = open(output + '-body.h', 'w')
+ self.header = []
+ self.body = []
+ self.docs = []
+ self.output = output
- for f in (self.header, self.body):
- f.write('/* Auto-generated, do not edit.\n *\n'
- ' * This file may be distributed under the same terms\n'
- ' * as the specification from which it was generated.\n'
- ' */\n\n')
+ for f in (self.header, self.body, self.docs):
+ f.append('/* Auto-generated, do not edit.\n *\n'
+ ' * This file may be distributed under the same terms\n'
+ ' * as the specification from which it was generated.\n'
+ ' */\n\n')
# keys are e.g. 'sv', values are the key escaped
self.need_mappings = {}
@@ -64,6 +67,15 @@ class GTypesGenerator(object):
# values are the key escaped
self.need_other_arrays = {}
+ def h(self, code):
+ self.header.append(code.encode("utf-8"))
+
+ def c(self, code):
+ self.body.append(code.encode("utf-8"))
+
+ def d(self, code):
+ self.docs.append(code.encode('utf-8'))
+
def do_mapping_header(self, mapping):
members = mapping.getElementsByTagNameNS(NS_TP, 'member')
assert len(members) == 2
@@ -79,43 +91,43 @@ class GTypesGenerator(object):
docstring = get_docstring(mapping) or '(Undocumented)'
- self.header.write('/**\n * %s:\n *\n' % name)
- self.header.write(' * %s\n' % xml_escape(docstring))
- self.header.write(' *\n')
- self.header.write(' * This macro expands to a call to a function\n')
- self.header.write(' * that returns the #GType of a #GHashTable\n')
- self.header.write(' * appropriate for representing a D-Bus\n')
- self.header.write(' * dictionary of signature\n')
- self.header.write(' * <literal>a{%s}</literal>.\n' % impl_sig)
- self.header.write(' *\n')
+ self.d('/**\n * %s:\n *\n' % name.strip())
+ self.d(' * %s\n' % xml_escape(docstring))
+ self.d(' *\n')
+ self.d(' * This macro expands to a call to a function\n')
+ self.d(' * that returns the #GType of a #GHashTable\n')
+ self.d(' * appropriate for representing a D-Bus\n')
+ self.d(' * dictionary of signature\n')
+ self.d(' * <literal>a{%s}</literal>.\n' % impl_sig)
+ self.d(' *\n')
key, value = members
- self.header.write(' * Keys (D-Bus type <literal>%s</literal>,\n'
+ self.d(' * Keys (D-Bus type <literal>%s</literal>,\n'
% key.getAttribute('type'))
tp_type = key.getAttributeNS(NS_TP, 'type')
if tp_type:
- self.header.write(' * type <literal>%s</literal>,\n' % tp_type)
- self.header.write(' * named <literal>%s</literal>):\n'
+ self.d(' * type <literal>%s</literal>,\n' % tp_type)
+ self.d(' * named <literal>%s</literal>):\n'
% key.getAttribute('name'))
docstring = get_docstring(key) or '(Undocumented)'
- self.header.write(' * %s\n' % xml_escape(docstring))
- self.header.write(' *\n')
+ self.d(' * %s\n' % xml_escape(docstring))
+ self.d(' *\n')
- self.header.write(' * Values (D-Bus type <literal>%s</literal>,\n'
+ self.d(' * Values (D-Bus type <literal>%s</literal>,\n'
% value.getAttribute('type'))
tp_type = value.getAttributeNS(NS_TP, 'type')
if tp_type:
- self.header.write(' * type <literal>%s</literal>,\n' % tp_type)
- self.header.write(' * named <literal>%s</literal>):\n'
+ self.d(' * type <literal>%s</literal>,\n' % tp_type)
+ self.d(' * named <literal>%s</literal>):\n'
% value.getAttribute('name'))
docstring = get_docstring(value) or '(Undocumented)'
- self.header.write(' * %s\n' % xml_escape(docstring))
- self.header.write(' *\n')
+ self.d(' * %s\n' % xml_escape(docstring))
+ self.d(' *\n')
- self.header.write(' */\n')
+ self.d(' */\n')
- self.header.write('#define %s (%s ())\n\n' % (name, impl))
+ self.h('#define %s (%s ())\n\n' % (name, impl))
self.need_mappings[impl_sig] = esc_impl_sig
array_name = mapping.getAttribute('array-name')
@@ -124,12 +136,13 @@ class GTypesGenerator(object):
contents_sig = 'a{' + impl_sig + '}'
esc_contents_sig = escape_as_identifier(contents_sig)
impl = self.prefix_ + 'type_dbus_array_of_' + esc_contents_sig
- self.header.write('/**\n * %s:\n\n' % gtype_name)
- self.header.write(' * Expands to a call to a function\n')
- self.header.write(' * that returns the #GType of a #GPtrArray\n')
- self.header.write(' * of #%s.\n' % name)
- self.header.write(' */\n')
- self.header.write('#define %s (%s ())\n\n' % (gtype_name, impl))
+ self.d('/**\n * %s:\n\n' % gtype_name)
+ self.d(' * Expands to a call to a function\n')
+ self.d(' * that returns the #GType of a #GPtrArray\n')
+ self.d(' * of #%s.\n' % name)
+ self.d(' */\n\n')
+
+ self.h('#define %s (%s ())\n\n' % (gtype_name, impl))
self.need_other_arrays[contents_sig] = esc_contents_sig
def do_struct_header(self, struct):
@@ -151,42 +164,44 @@ class GTypesGenerator(object):
docstring = '(Undocumented)'
else:
docstring = '(Undocumented)'
- self.header.write('/**\n * %s:\n\n' % name)
- self.header.write(' * %s\n' % xml_escape(docstring))
- self.header.write(' *\n')
- self.header.write(' * This macro expands to a call to a function\n')
- self.header.write(' * that returns the #GType of a #GValueArray\n')
- self.header.write(' * appropriate for representing a D-Bus struct\n')
- self.header.write(' * with signature <literal>(%s)</literal>.\n'
+ self.d('/**\n * %s:\n\n' % name)
+ self.d(' * %s\n' % xml_escape(docstring))
+ self.d(' *\n')
+ self.d(' * This macro expands to a call to a function\n')
+ self.d(' * that returns the #GType of a #GValueArray\n')
+ self.d(' * appropriate for representing a D-Bus struct\n')
+ self.d(' * with signature <literal>(%s)</literal>.\n'
% impl_sig)
- self.header.write(' *\n')
+ self.d(' *\n')
for i, member in enumerate(members):
- self.header.write(' * Member %d (D-Bus type '
+ self.d(' * Member %d (D-Bus type '
'<literal>%s</literal>,\n'
% (i, member.getAttribute('type')))
tp_type = member.getAttributeNS(NS_TP, 'type')
if tp_type:
- self.header.write(' * type <literal>%s</literal>,\n' % tp_type)
- self.header.write(' * named <literal>%s</literal>):\n'
+ self.d(' * type <literal>%s</literal>,\n' % tp_type)
+ self.d(' * named <literal>%s</literal>):\n'
% member.getAttribute('name'))
docstring = get_docstring(member) or '(Undocumented)'
- self.header.write(' * %s\n' % xml_escape(docstring))
- self.header.write(' *\n')
+ self.d(' * %s\n' % xml_escape(docstring))
+ self.d(' *\n')
- self.header.write(' */\n')
- self.header.write('#define %s (%s ())\n\n' % (name, impl))
+ self.d(' */\n\n')
+
+ self.h('#define %s (%s ())\n\n' % (name, impl))
array_name = struct.getAttribute('array-name')
if array_name != '':
array_name = (self.PREFIX_ + 'ARRAY_TYPE_' + array_name.upper())
impl = self.prefix_ + 'type_dbus_array_' + esc_impl_sig
- self.header.write('/**\n * %s:\n\n' % array_name)
- self.header.write(' * Expands to a call to a function\n')
- self.header.write(' * that returns the #GType of a #GPtrArray\n')
- self.header.write(' * of #%s.\n' % name)
- self.header.write(' */\n')
- self.header.write('#define %s (%s ())\n\n' % (array_name, impl))
+ self.d('/**\n * %s:\n\n' % array_name)
+ self.d(' * Expands to a call to a function\n')
+ self.d(' * that returns the #GType of a #GPtrArray\n')
+ self.d(' * of #%s.\n' % name)
+ self.d(' */\n\n')
+
+ self.h('#define %s (%s ())\n\n' % (array_name, impl))
self.need_struct_arrays[impl_sig] = esc_impl_sig
self.need_structs[impl_sig] = esc_impl_sig
@@ -199,83 +214,87 @@ class GTypesGenerator(object):
self.do_mapping_header(mapping)
for sig in self.need_mappings:
- self.header.write('GType %stype_dbus_hash_%s (void);\n\n' %
+ self.h('GType %stype_dbus_hash_%s (void);\n\n' %
(self.prefix_, self.need_mappings[sig]))
- self.body.write('GType\n%stype_dbus_hash_%s (void)\n{\n' %
+ self.c('GType\n%stype_dbus_hash_%s (void)\n{\n' %
(self.prefix_, self.need_mappings[sig]))
- self.body.write(' static GType t = 0;\n\n')
- self.body.write(' if (G_UNLIKELY (t == 0))\n')
+ self.c(' static GType t = 0;\n\n')
+ self.c(' if (G_UNLIKELY (t == 0))\n')
# FIXME: translate sig into two GTypes
items = tuple(Signature(sig))
gtypes = types_to_gtypes(items)
- self.body.write(' t = dbus_g_type_get_map ("GHashTable", '
+ self.c(' t = dbus_g_type_get_map ("GHashTable", '
'%s, %s);\n' % (gtypes[0], gtypes[1]))
- self.body.write(' return t;\n')
- self.body.write('}\n\n')
+ self.c(' return t;\n')
+ self.c('}\n\n')
for struct in structs:
self.do_struct_header(struct)
for sig in self.need_structs:
- self.header.write('GType %stype_dbus_struct_%s (void);\n\n' %
+ self.h('GType %stype_dbus_struct_%s (void);\n\n' %
(self.prefix_, self.need_structs[sig]))
- self.body.write('GType\n%stype_dbus_struct_%s (void)\n{\n' %
+ self.c('GType\n%stype_dbus_struct_%s (void)\n{\n' %
(self.prefix_, self.need_structs[sig]))
- self.body.write(' static GType t = 0;\n\n')
- self.body.write(' if (G_UNLIKELY (t == 0))\n')
- self.body.write(' t = dbus_g_type_get_struct ("GValueArray",\n')
+ self.c(' static GType t = 0;\n\n')
+ self.c(' if (G_UNLIKELY (t == 0))\n')
+ self.c(' t = dbus_g_type_get_struct ("GValueArray",\n')
items = tuple(Signature(sig))
gtypes = types_to_gtypes(items)
for gtype in gtypes:
- self.body.write(' %s,\n' % gtype)
- self.body.write(' G_TYPE_INVALID);\n')
- self.body.write(' return t;\n')
- self.body.write('}\n\n')
+ self.c(' %s,\n' % gtype)
+ self.c(' G_TYPE_INVALID);\n')
+ self.c(' return t;\n')
+ self.c('}\n\n')
for sig in self.need_struct_arrays:
- self.header.write('GType %stype_dbus_array_%s (void);\n\n' %
+ self.h('GType %stype_dbus_array_%s (void);\n\n' %
(self.prefix_, self.need_struct_arrays[sig]))
- self.body.write('GType\n%stype_dbus_array_%s (void)\n{\n' %
+ self.c('GType\n%stype_dbus_array_%s (void)\n{\n' %
(self.prefix_, self.need_struct_arrays[sig]))
- self.body.write(' static GType t = 0;\n\n')
- self.body.write(' if (G_UNLIKELY (t == 0))\n')
- self.body.write(' t = dbus_g_type_get_collection ("GPtrArray", '
+ self.c(' static GType t = 0;\n\n')
+ self.c(' if (G_UNLIKELY (t == 0))\n')
+ self.c(' t = dbus_g_type_get_collection ("GPtrArray", '
'%stype_dbus_struct_%s ());\n' %
(self.prefix_, self.need_struct_arrays[sig]))
- self.body.write(' return t;\n')
- self.body.write('}\n\n')
+ self.c(' return t;\n')
+ self.c('}\n\n')
for sig in self.need_other_arrays:
- self.header.write('GType %stype_dbus_array_of_%s (void);\n\n' %
+ self.h('GType %stype_dbus_array_of_%s (void);\n\n' %
(self.prefix_, self.need_other_arrays[sig]))
- self.body.write('GType\n%stype_dbus_array_of_%s (void)\n{\n' %
+ self.c('GType\n%stype_dbus_array_of_%s (void)\n{\n' %
(self.prefix_, self.need_other_arrays[sig]))
- self.body.write(' static GType t = 0;\n\n')
- self.body.write(' if (G_UNLIKELY (t == 0))\n')
+ self.c(' static GType t = 0;\n\n')
+ self.c(' if (G_UNLIKELY (t == 0))\n')
if sig[:2] == 'a{' and sig[-1:] == '}':
# array of mappings
- self.body.write(' t = dbus_g_type_get_collection ('
+ self.c(' t = dbus_g_type_get_collection ('
'"GPtrArray", '
'%stype_dbus_hash_%s ());\n' %
(self.prefix_, escape_as_identifier(sig[2:-1])))
elif sig[:2] == 'a(' and sig[-1:] == ')':
# array of arrays of struct
- self.body.write(' t = dbus_g_type_get_collection ('
+ self.c(' t = dbus_g_type_get_collection ('
'"GPtrArray", '
'%stype_dbus_array_%s ());\n' %
(self.prefix_, escape_as_identifier(sig[2:-1])))
elif sig[:1] == 'a':
# array of arrays of non-struct
- self.body.write(' t = dbus_g_type_get_collection ('
+ self.c(' t = dbus_g_type_get_collection ('
'"GPtrArray", '
'%stype_dbus_array_of_%s ());\n' %
(self.prefix_, escape_as_identifier(sig[1:])))
else:
raise AssertionError("array of '%s' not supported" % sig)
- self.body.write(' return t;\n')
- self.body.write('}\n\n')
+ self.c(' return t;\n')
+ self.c('}\n\n')
+
+ file_set_contents(self.output + '.h', ''.join(self.header))
+ file_set_contents(self.output + '-body.h', ''.join(self.body))
+ file_set_contents(self.output + '-gtk-doc.h', ''.join(self.docs))
if __name__ == '__main__':
argv = sys.argv[1:]
diff --git a/tools/libglibcodegen.py b/tools/libglibcodegen.py
index 0cf52a82..6a9d2148 100644
--- a/tools/libglibcodegen.py
+++ b/tools/libglibcodegen.py
@@ -28,7 +28,8 @@ from libtpcodegen import NS_TP, \
get_by_path, \
get_descendant_text, \
get_docstring, \
- xml_escape
+ xml_escape, \
+ get_deprecated
def dbus_gutils_wincaps_to_uscore(s):
"""Bug-for-bug compatible Python port of _dbus_gutils_wincaps_to_uscore
diff --git a/tools/libtpcodegen.py b/tools/libtpcodegen.py
index e5114b7a..7e9eb9a5 100644
--- a/tools/libtpcodegen.py
+++ b/tools/libtpcodegen.py
@@ -20,7 +20,7 @@ please make any changes there.
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-
+import os
from string import ascii_letters, digits
@@ -28,6 +28,18 @@ NS_TP = "http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0"
_ASCII_ALNUM = ascii_letters + digits
+def file_set_contents(filename, contents):
+ try:
+ os.remove(filename)
+ except OSError:
+ pass
+ try:
+ os.remove(filename + '.tmp')
+ except OSError:
+ pass
+
+ open(filename + '.tmp', 'w').write(contents)
+ os.rename(filename + '.tmp', filename)
def cmp_by_name(node1, node2):
return cmp(node1.getAttributeNode("name").nodeValue,
@@ -120,6 +132,16 @@ def get_docstring(element):
docstring = ''
return docstring
+def get_deprecated(element):
+ text = []
+ for x in element.childNodes:
+ if hasattr(x, 'data'):
+ text.append(x.data.replace('\n', ' ').strip())
+ else:
+ # This caters for tp:dbus-ref elements, but little else.
+ if x.childNodes and hasattr(x.childNodes[0], 'data'):
+ text.append(x.childNodes[0].data.replace('\n', ' ').strip())
+ return ' '.join(text)
def get_descendant_text(element_or_elements):
if not element_or_elements: