[glib/gdbus-codegen] gdbus-codegen: Generate docs when generating C code



commit 68ba1bf074f9168a1997d674bf1d78b5e707dbf6
Author: David Zeuthen <davidz redhat com>
Date:   Mon Apr 18 14:23:19 2011 -0400

    gdbus-codegen: Generate docs when generating C code
    
    This is handy for both gtk-doc and gobject-introspection.
    
    Signed-off-by: David Zeuthen <davidz redhat com>

 gio/gdbus-codegen/codegen.py         |  659 +++++++++++++++++++++++++---------
 gio/gdbus-codegen/codegen_docbook.py |    2 +-
 gio/gdbus-codegen/codegen_main.py    |   11 +-
 gio/gdbus-codegen/utils.py           |   15 +
 4 files changed, 504 insertions(+), 183 deletions(-)
---
diff --git a/gio/gdbus-codegen/codegen.py b/gio/gdbus-codegen/codegen.py
index 7ce5316..62326ab 100644
--- a/gio/gdbus-codegen/codegen.py
+++ b/gio/gdbus-codegen/codegen.py
@@ -23,7 +23,6 @@
 
 import sys
 import argparse
-import distutils.version
 
 import config
 import utils
@@ -32,7 +31,8 @@ import dbustypes
 # ----------------------------------------------------------------------------------------------------
 
 class CodeGenerator:
-    def __init__(self, ifaces, namespace, interface_prefix, generate_objmanager, h, c):
+    def __init__(self, ifaces, namespace, interface_prefix, generate_objmanager, docbook_gen, h, c):
+        self.docbook_gen = docbook_gen
         self.generate_objmanager = generate_objmanager
         self.ifaces = ifaces
         self.h = h
@@ -265,22 +265,9 @@ class CodeGenerator:
             #
             # See https://bugzilla.gnome.org/show_bug.cgi?id=647577#c5
             # for discussion
-
-            # I'm sure this could be a lot more elegant if I was
-            # more fluent in python...
-            def my_version_cmp(a, b):
-                if len(a[0]) > 0 and len(b[0]) > 0:
-                    va = distutils.version.LooseVersion(a[0])
-                    vb = distutils.version.LooseVersion(b[0])
-                    ret = va.__cmp__(vb)
-                else:
-                    ret = cmp(a[0], b[0])
-                if ret != 0:
-                    return ret
-                return cmp(a[1], b[1])
             keys = function_pointers.keys()
             if len(keys) > 0:
-                keys.sort(cmp=my_version_cmp)
+                keys.sort(cmp=utils.my_version_cmp)
                 for key in keys:
                     self.h.write('%s'%function_pointers[key])
 
@@ -805,6 +792,15 @@ class CodeGenerator:
             self.c.write('};\n'
                          '\n')
             self.c.write('\n')
+            self.c.write(self.docbook_gen.expand(
+                    '/**\n'
+                    ' * %s_interface_info:\n'
+                    ' *\n'
+                    ' * Gets a machine-readable description of the #%s D-Bus interface.\n'
+                    ' *\n'
+                    ' * Returns: (transfer none): A #GDBusInterfaceInfo. Do not free.\n'
+                    %(i.name_lower, i.name)))
+            self.write_gtkdoc_deprecated_and_since_and_close(i, self.c, 0)
             self.c.write('GDBusInterfaceInfo *\n'
                          '%s_interface_info (void)\n'
                          '{\n'
@@ -813,6 +809,18 @@ class CodeGenerator:
                          '\n'%(i.name_lower, i.name_lower))
 
             if len(i.properties) > 0:
+                self.c.write(self.docbook_gen.expand(
+                        '/**\n'
+                        ' * %s_override_properties:\n'
+                        ' * @klass: The class structure for a #GObject<!-- -->-derived class.\n'
+                        ' * @property_id_begin: The property id to assign to the first overridden property.\n'
+                        ' *\n'
+                        ' * Overrides all #GObject properties in the #%s interface for a concrete class.\n'
+                        ' * The properties are overridden in the order they are defined.\n'
+                        ' *\n'
+                        ' * Returns: The last property id.\n'
+                        %(i.name_lower, i.camel_name)))
+                self.write_gtkdoc_deprecated_and_since_and_close(i, self.c, 0)
                 self.c.write('guint\n'
                              '%s_override_properties (GObjectClass *klass, guint property_id_begin)\n'
                              '{\n'%(i.name_lower))
@@ -828,6 +836,46 @@ class CodeGenerator:
     def generate_interface(self, i):
         self.c.write('\n')
 
+        self.c.write(self.docbook_gen.expand(
+                '/**\n'
+                ' * %s:\n'
+                ' *\n'
+                ' * Abstract interface type for the D-Bus interface #%s.\n'
+                %(i.camel_name, i.name)))
+        self.write_gtkdoc_deprecated_and_since_and_close(i, self.c, 0)
+        self.c.write('\n')
+
+        self.c.write(self.docbook_gen.expand(
+                '/**\n'
+                ' * %sIface:\n'
+                ' * @parent_iface: The parent interface.\n'
+                %(i.camel_name)))
+
+        doc_bits = {}
+        if len(i.methods) > 0:
+            for m in i.methods:
+                key = (m.since, '_method_%s'%m.name_lower)
+                value  = '@handle_%s: '%(m.name_lower)
+                value += 'Handler for the #%s::handle-%s signal.'%(i.camel_name, m.name_hyphen)
+                doc_bits[key] = value
+        if len(i.signals) > 0:
+            for s in i.signals:
+                key = (s.since, '_signal_%s'%s.name_lower)
+                value  = '@%s: '%(s.name_lower)
+                value += 'Handler for the #%s::%s signal.'%(i.camel_name, s.name_hyphen)
+                doc_bits[key] = value
+        keys = doc_bits.keys()
+        if len(keys) > 0:
+            keys.sort(cmp=utils.my_version_cmp)
+            for key in keys:
+                self.c.write(' * %s\n'%doc_bits[key])
+        self.c.write(self.docbook_gen.expand(
+                ' *\n'
+                ' * Virtual table for the D-Bus interface #%s.\n'
+                %(i.name)))
+        self.write_gtkdoc_deprecated_and_since_and_close(i, self.c, 0)
+        self.c.write('\n')
+
         self.c.write('static void\n'
                      '%s_default_init (%sIface *iface)\n'
                      '{\n'%(i.name_lower, i.camel_name));
@@ -835,6 +883,23 @@ class CodeGenerator:
         if len(i.methods) > 0:
             self.c.write('  /* GObject signals for incoming D-Bus method calls: */\n')
             for m in i.methods:
+                self.c.write(self.docbook_gen.expand(
+                        '  /**\n'
+                        '   * %s::handle-%s:\n'
+                        '   * @object: A #%s.\n'
+                        '   * @invocation: A #GDBusMethodInvocation.\n'
+                        %(i.camel_name, m.name_hyphen, i.camel_name, )))
+                for a in m.in_args:
+                    self.c.write ('   * @%s: Argument passed by remote caller.\n'%(a.name))
+                self.c.write(self.docbook_gen.expand(
+                        '   *\n'
+                        '   * Signal emitted when a remote caller is invoking the %s.%s() D-Bus method.\n'
+                        '   *\n'
+                        '   * If a signal handler returns %%TRUE, it means the signal handler will handle the invocation (e.g. take a reference to @invocation and eventually call %s_complete_%s() or e.g. g_dbus_method_invocation_return_error() on it) and no order signal handlers will run. If no signal handler handles the invocation, the %%G_DBUS_ERROR_UNKNOWN_METHOD error is returned.\n'
+                        '   *\n'
+                        '   * Returns: %%TRUE if the invocation was handled, %%FALSE to let other signal handlers run.\n'
+                        %(i.name, m.name, i.name_lower, m.name_lower)))
+                self.write_gtkdoc_deprecated_and_since_and_close(m, self.c, 2)
                 self.c.write('  g_signal_new ("handle-%s",\n'
                              '    G_TYPE_FROM_INTERFACE (iface),\n'
                              '    G_SIGNAL_RUN_LAST,\n'
@@ -854,6 +919,20 @@ class CodeGenerator:
         if len(i.signals) > 0:
             self.c.write('  /* GObject signals for received D-Bus signals: */\n')
             for s in i.signals:
+                self.c.write(self.docbook_gen.expand(
+                        '  /**\n'
+                        '   * %s::%s:\n'
+                        '   * @object: A #%s.\n'
+                        %(i.camel_name, s.name_hyphen, i.camel_name, )))
+                for a in s.args:
+                    self.c.write ('   * @%s: Argument.\n'%(a.name))
+                self.c.write(self.docbook_gen.expand(
+                        '   *\n'
+                        '   * On the client-side, this signal is emitted whenever the D-Bus signal #%s::%s is received.\n'
+                        '   *\n'
+                        '   * On the service-side, this signal can be used with e.g. g_signal_emit_by_name() to make the object emit the D-Bus signal.\n'
+                        %(i.name, s.name)))
+                self.write_gtkdoc_deprecated_and_since_and_close(s, self.c, 2)
                 self.c.write('  g_signal_new ("%s",\n'
                              '    G_TYPE_FROM_INTERFACE (iface),\n'
                              '    G_SIGNAL_RUN_LAST,\n'
@@ -872,6 +951,23 @@ class CodeGenerator:
         if len(i.properties) > 0:
             self.c.write('  /* GObject properties for D-Bus properties: */\n')
             for p in i.properties:
+                if p.readable and p.writable:
+                    hint = 'Since the D-Bus property for this #GObject property is both readable and writable, it is meaningful to both read from it and write to it on both the service- and client-side.'
+                elif p.readable:
+                    hint = 'Since the D-Bus property for this #GObject property is readable but not writable, it is meaningful to read from it on both the client- and service-side. It is only meaningful, however, to write to it on the service-side.'
+                elif p.writable:
+                    hint = 'Since the D-Bus property for this #GObject property is writable but not readable, it is meaningful to write to it on both the client- and service-side. It is only meaningful, however, to read from it on the service-side.'
+                else:
+                    raise RuntimeError('Cannot handle property %s that neither readable nor writable'%(p.name))
+                self.c.write(self.docbook_gen.expand(
+                        '  /**\n'
+                        '   * %s:%s:\n'
+                        '   *\n'
+                        '   * Represents the D-Bus property #%s:%s.\n'
+                        '   *\n'
+                        '   * %s\n'
+                        %(i.camel_name, p.name_hyphen, i.name, p.name, hint)))
+                self.write_gtkdoc_deprecated_and_since_and_close(p, self.c, 2)
                 self.c.write('  g_object_interface_install_property (iface,\n')
                 if p.arg.gtype == 'G_TYPE_VARIANT':
                     s = 'g_param_spec_variant ("%s", NULL, NULL, G_VARIANT_TYPE ("%s"), NULL'%(p.name_hyphen, p.arg.signature)
@@ -922,13 +1018,26 @@ class CodeGenerator:
     def generate_property_accessors(self, i):
         for p in i.properties:
             # getter
-            self.c.write('/**\n'
-                         ' * %s_get_%s:\n'
-                         ' * @object: \n'
-                         ' *\n'
-                         ' * Returns: (transfer none): \n'
-                         %(i.name_lower, p.name_lower))
-            self.c.write(' */\n')
+            if p.readable and p.writable:
+                hint = 'Since this D-Bus property is both readable and writable, it is meaningful to use this function on both the client- and service-side.'
+            elif p.readable:
+                hint = 'Since this D-Bus property is readable, it is meaningful to use this function on both the client- and service-side.'
+            elif p.writable:
+                hint = 'Since this D-Bus property is not readable, it is only meaningful to use this function on the service-side.'
+            else:
+                raise RuntimeError('Cannot handle property %s that neither readable nor writable'%(p.name))
+            self.c.write(self.docbook_gen.expand(
+                    '/**\n'
+                    ' * %s_get_%s:\n'
+                    ' * @object: A #%s.\n'
+                    ' *\n'
+                    ' * Gets the value of the #%s:%s D-Bus property.\n'
+                    ' *\n'
+                    ' * %s\n'
+                    ' *\n'
+                    ' * Returns: (transfer none): The property value.\n'
+                    %(i.name_lower, p.name_lower, i.camel_name, i.name, p.name, hint)))
+            self.write_gtkdoc_deprecated_and_since_and_close(p, self.c, 0)
             self.c.write('%s\n'
                          '%s_get_%s (%s *object)\n'
                          '{\n'
@@ -944,13 +1053,25 @@ class CodeGenerator:
             self.c.write('}\n')
             self.c.write('\n')
             # setter
-            self.c.write('/**\n'
-                         ' * %s_set_%s:\n'
-                         ' * @object: \n'
-                         ' * @value: \n'
-                         ' *\n'
-                         %(i.name_lower, p.name_lower))
-            self.c.write(' */\n')
+            if p.readable and p.writable:
+                hint = 'Since this D-Bus property is both readable and writable, it is meaningful to use this function on both the client- and service-side.'
+            elif p.readable:
+                hint = 'Since this D-Bus property is not writable, it is only meaningful to use this function on the service-side.'
+            elif p.writable:
+                hint = 'Since this D-Bus property is writable, it is meaningful to use this function on both the client- and service-side.'
+            else:
+                raise RuntimeError('Cannot handle property %s that neither readable nor writable'%(p.name))
+            self.c.write(self.docbook_gen.expand(
+                    '/**\n'
+                    ' * %s_set_%s:\n'
+                    ' * @object: A #%s.\n'
+                    ' * @value: The value to set.\n'
+                    ' *\n'
+                    ' * Sets the #%s:%s D-Bus property to @value.\n'
+                    ' *\n'
+                    ' * %s\n'
+                    %(i.name_lower, p.name_lower, i.camel_name, i.name, p.name, hint)))
+            self.write_gtkdoc_deprecated_and_since_and_close(p, self.c, 0)
             self.c.write('void\n'
                          '%s_set_%s (%s *object, %svalue)\n'
                          '{\n'%(i.name_lower, p.name_lower, i.camel_name, p.arg.ctype_in, ))
@@ -962,6 +1083,18 @@ class CodeGenerator:
 
     def generate_signal_emitters(self, i):
         for s in i.signals:
+            self.c.write(self.docbook_gen.expand(
+                    '/**\n'
+                    ' * %s_emit_%s:\n'
+                    ' * @object: A #%s.\n'
+                    %(i.name_lower, s.name_lower, i.camel_name)))
+            for a in s.args:
+                self.c.write(' * @%s: Argument to pass with the signal.\n'%(a.name))
+            self.c.write(self.docbook_gen.expand(
+                    ' *\n'
+                    ' * Emits the #%s::%s D-Bus signal.\n'
+                    %(i.name, s.name)))
+            self.write_gtkdoc_deprecated_and_since_and_close(s, self.c, 0)
             self.c.write('void\n'
                          '%s_emit_%s (\n'
                          '    %s *object'%(i.name_lower, s.name_lower, i.camel_name))
@@ -983,15 +1116,22 @@ class CodeGenerator:
             # async begin
             self.c.write('/**\n'
                          ' * %s_call_%s:\n'
-                         ' * @proxy: \n'
-                         %(i.name_lower, m.name_lower))
+                         ' * @proxy: A #%sProxy.\n'
+                         %(i.name_lower, m.name_lower, i.camel_name))
             for a in m.in_args:
-                self.c.write(' * @%s: \n'%(a.name))
-            self.c.write(' * @cancellable: \n'
-                         ' * @callback: \n'
-                         ' * @user_data: \n'
-                         ' *\n')
-            self.c.write(' */\n')
+                self.c.write(' * @%s: Argument to pass with the method invocation.\n'%(a.name))
+            self.c.write(self.docbook_gen.expand(
+                    ' * @cancellable: (allow-none): A #GCancellable or %%NULL.\n'
+                    ' * @callback: A #GAsyncReadyCallback to call when the request is satisfied or %%NULL.\n'
+                    ' * @user_data: User data to pass to @callback.\n'
+                    ' *\n'
+                    ' * Asynchronously invokes the %s.%s() D-Bus method on @proxy.\n'
+                    ' * When the operation is finished, @callback will be invoked in the <link linkend="g-main-context-push-thread-default">thread-default main loop</link> of the thread you are calling this method from.\n'
+                    ' * You can then call %s_call_%s_finish() to get the result of the operation.\n'
+                    ' *\n'
+                    ' * See %s_call_%s_sync() for the synchronous, blocking version of this method.\n'
+                    %(i.name, m.name, i.name_lower, m.name_lower, i.name_lower, m.name_lower)))
+            self.write_gtkdoc_deprecated_and_since_and_close(m, self.c, 0)
             self.c.write('void\n'
                          '%s_call_%s (\n'
                          '    %s *proxy'%(i.name_lower, m.name_lower, i.camel_name))
@@ -1021,15 +1161,19 @@ class CodeGenerator:
             # async finish
             self.c.write('/**\n'
                          ' * %s_call_%s_finish:\n'
-                         ' * @proxy: \n'
-                         %(i.name_lower, m.name_lower))
+                         ' * @proxy: A #%sProxy.\n'
+                         %(i.name_lower, m.name_lower, i.camel_name))
             for a in m.out_args:
-                self.c.write(' * @out_%s: (out): \n'%(a.name))
-            self.c.write(' * @res: \n'
-                         ' * @error: \n'
-                         ' *\n'
-                         ' * Returns: \n')
-            self.c.write(' */\n')
+                self.c.write(' * @out_%s: (out): Return location for return parameter or %%NULL to ignore.\n'%(a.name))
+            self.c.write(self.docbook_gen.expand(
+                    ' * @res: The #GAsyncResult obtained from the #GAsyncReadyCallback passed to %s_call_%s().\n'
+                    ' * @error: Return location for error or %%NULL.\n'
+                    ' *\n'
+                    ' * Finishes an operation started with %s_call_%s().\n'
+                    ' *\n'
+                    ' * Returns: %%TRUE if the call succeded, %%FALSE if @error is set.\n'
+                    %(i.name_lower, m.name_lower, i.name_lower, m.name_lower)))
+            self.write_gtkdoc_deprecated_and_since_and_close(m, self.c, 0)
             self.c.write('gboolean\n'
                          '%s_call_%s_finish (\n'
                          '    %s *proxy'%(i.name_lower, m.name_lower, i.camel_name))
@@ -1061,17 +1205,23 @@ class CodeGenerator:
             # sync
             self.c.write('/**\n'
                          ' * %s_call_%s_sync:\n'
-                         ' * @proxy: \n'
-                         %(i.name_lower, m.name_lower))
+                         ' * @proxy: A #%sProxy.\n'
+                         %(i.name_lower, m.name_lower, i.camel_name))
             for a in m.in_args:
-                self.c.write(' * @%s: \n'%(a.name))
+                self.c.write(' * @%s: Argument to pass with the method invocation.\n'%(a.name))
             for a in m.out_args:
-                self.c.write(' * @out_%s: (out): \n'%(a.name))
-            self.c.write(' * @cancellable: \n'
-                         ' * @error: \n'
-                         ' *\n'
-                         ' * Returns: \n')
-            self.c.write(' */\n')
+                self.c.write(' * @out_%s: (out): Return location for return parameter or %%NULL to ignore.\n'%(a.name))
+            self.c.write(self.docbook_gen.expand(
+                    ' * @cancellable: (allow-none): A #GCancellable or %%NULL.\n'
+                    ' * @error: Return location for error or %%NULL.\n'
+                    ' *\n'
+                    ' * Synchronously invokes the %s.%s() D-Bus method on @proxy. The calling thread is blocked until a reply is received.\n'
+                    ' *\n'
+                    ' * See %s_call_%s() for the asynchronous version of this method.\n'
+                    ' *\n'
+                    ' * Returns: %%TRUE if the call succeded, %%FALSE if @error is set.\n'
+                    %(i.name, m.name, i.name_lower, m.name_lower)))
+            self.write_gtkdoc_deprecated_and_since_and_close(m, self.c, 0)
             self.c.write('gboolean\n'
                          '%s_call_%s_sync (\n'
                          '    %s *proxy'%(i.name_lower, m.name_lower, i.camel_name))
@@ -1117,6 +1267,20 @@ class CodeGenerator:
 
     def generate_method_completers(self, i):
         for m in i.methods:
+            self.c.write('/**\n'
+                         ' * %s_complete_%s:\n'
+                         ' * @object: A #%s.\n'
+                         ' * @invocation: (transfer full): A #GDBusMethodInvocation.\n'
+                         %(i.name_lower, m.name_lower, i.camel_name))
+            for a in m.out_args:
+                self.c.write(' * @%s: Parameter to return.\n'%(a.name))
+            self.c.write(self.docbook_gen.expand(
+                    ' *\n'
+                    ' * Helper function used in service implementations to finish handling invocations of the %s.%s() D-Bus method. If you instead want to finish handling an invocation by returning an error, use g_dbus_method_invocation_return_error() or similar.\n'
+                    ' *\n'
+                    ' * This method will free @invocation, you cannot use it afterwards.\n'
+                    %(i.name, m.name)))
+            self.write_gtkdoc_deprecated_and_since_and_close(m, self.c, 0)
             self.c.write('void\n'
                          '%s_complete_%s (\n'
                          '    %s *object,\n'
@@ -1143,6 +1307,26 @@ class CodeGenerator:
         # class boilerplate
         self.c.write('/* ------------------------------------------------------------------------ */\n'
                      '\n')
+
+        self.c.write(self.docbook_gen.expand(
+                '/**\n'
+                ' * %sProxy:\n'
+                ' *\n'
+                ' * The #%sProxy structure contains only private data and should only be accessed using the provided API.\n'
+                %(i.camel_name, i.camel_name)))
+        self.write_gtkdoc_deprecated_and_since_and_close(i, self.c, 0)
+        self.c.write('\n')
+
+        self.c.write(self.docbook_gen.expand(
+                '/**\n'
+                ' * %sProxyClass:\n'
+                ' * @parent_class: The parent class.\n'
+                ' *\n'
+                ' * Class structure for #%sProxy.\n'
+                %(i.camel_name, i.camel_name)))
+        self.write_gtkdoc_deprecated_and_since_and_close(i, self.c, 0)
+        self.c.write('\n')
+
         self.c.write('static void\n'
                      '%s_proxy_iface_init (%sIface *iface)\n'
                      '{\n'
@@ -1324,20 +1508,29 @@ class CodeGenerator:
         if len(i.properties) > 0:
             self.c.write('\n'
                          '  %s_override_properties (gobject_class, 1);\n'%(i.name_lower))
-        self.c.write('}\n')
+        self.c.write('}\n'
+                     '\n')
 
         # constructors
-        self.c.write('/**\n'
-                     ' * %s_proxy_new:\n'
-                     ' * @connection: \n'
-                     ' * @flags: \n'
-                     ' * @name: \n'
-                     ' * @object_path: \n'
-                     ' * @callback: \n'
-                     ' * @user_data: \n'
-                     ' *\n'
-                     %(i.name_lower))
-        self.c.write(' */\n')
+        self.c.write(self.docbook_gen.expand(
+                '/**\n'
+                ' * %s_proxy_new:\n'
+                ' * @connection: A #GDBusConnection.\n'
+                ' * @flags: Flags from the #GDBusProxyFlags enumeration.\n'
+                ' * @name: (allow-none): A bus name (well-known or unique) or %%NULL if @connection is not a message bus connection.\n'
+                ' * @object_path: An object path.\n'
+                ' * @cancellable: (allow-none): A #GCancellable or %%NULL.\n'
+                ' * @callback: A #GAsyncReadyCallback to call when the request is satisfied.\n'
+                ' * @user_data: User data to pass to @callback.\n'
+                ' *\n'
+                ' * Asynchronously creates a proxy for the D-Bus interface #%s. See g_dbus_proxy_new() for more details.\n'
+                ' *\n'
+                ' * When the operation is finished, @callback will be invoked in the <link linkend="g-main-context-push-thread-default">thread-default main loop</link> of the thread you are calling this method from.\n'
+                ' * You can then call %s_proxy_new_finish() to get the result of the operation.\n'
+                ' *\n'
+                ' * See %s_proxy_new_sync() for the synchronous, blocking version of this constructor.\n'
+                %(i.name_lower, i.name, i.name_lower, i.name_lower)))
+        self.write_gtkdoc_deprecated_and_since_and_close(i, self.c, 0)
         self.c.write('void\n'
                      '%s_proxy_new (\n'
                      '    GDBusConnection     *connection,\n'
@@ -1354,12 +1547,14 @@ class CodeGenerator:
                      %(i.name_lower, i.ns_upper, i.name_upper, i.name))
         self.c.write('/**\n'
                      ' * %s_proxy_new_finish:\n'
-                     ' * @res: \n'
-                     ' * @error: \n'
+                     ' * @res: The #GAsyncResult obtained from the #GAsyncReadyCallback passed to %s_proxy_new().\n'
+                     ' * @error: Return location for error or %%NULL\n'
                      ' *\n'
-                     ' * Returns: (transfer full) (type %sProxy):\n'
-                     %(i.name_lower, i.camel_name))
-        self.c.write(' */\n')
+                     ' * Finishes an operation started with %s_proxy_new().\n'
+                     ' *\n'
+                     ' * Returns: (transfer full) (type %sProxy): The constructed proxy object or %%NULL if @error is set.\n'
+                     %(i.name_lower, i.name_lower, i.name_lower, i.camel_name))
+        self.write_gtkdoc_deprecated_and_since_and_close(i, self.c, 0)
         self.c.write('%s *\n'
                      '%s_proxy_new_finish (\n'
                      '    GAsyncResult        *res,\n'
@@ -1377,18 +1572,25 @@ class CodeGenerator:
                      '}\n'
                      '\n'
                      %(i.camel_name, i.name_lower, i.ns_upper, i.name_upper))
-        self.c.write('/**\n'
-                     ' * %s_proxy_new_sync:\n'
-                     ' * @connection: \n'
-                     ' * @flags: \n'
-                     ' * @name: \n'
-                     ' * @object_path: \n'
-                     ' * @cancellable: \n'
-                     ' * @error: \n'
-                     ' *\n'
-                     ' * Returns: (transfer full) (type %sProxy):\n'
-                     %(i.name_lower, i.camel_name))
-        self.c.write(' */\n')
+        self.c.write(self.docbook_gen.expand(
+                '/**\n'
+                ' * %s_proxy_new_sync:\n'
+                ' * @connection: A #GDBusConnection.\n'
+                ' * @flags: Flags from the #GDBusProxyFlags enumeration.\n'
+                ' * @name: (allow-none): A bus name (well-known or unique) or %%NULL if @connection is not a message bus connection.\n'
+                ' * @object_path: An object path.\n'
+                ' * @cancellable: (allow-none): A #GCancellable or %%NULL.\n'
+                ' * @error: Return location for error or %%NULL\n'
+                ' *\n'
+                ' * Synchronously creates a proxy for the D-Bus interface #%s. See g_dbus_proxy_new_sync() for more details.\n'
+                ' *\n'
+                ' * The calling thread is blocked until a reply is received.\n'
+                ' *\n'
+                ' * See %s_proxy_new() for the asynchronous version of this constructor.\n'
+                ' *\n'
+                ' * Returns: (transfer full) (type %sProxy): The constructed proxy object or %%NULL if @error is set.\n'
+                %(i.name_lower, i.name, i.name_lower, i.camel_name)))
+        self.write_gtkdoc_deprecated_and_since_and_close(i, self.c, 0)
         self.c.write('%s *\n'
                      '%s_proxy_new_sync (\n'
                      '    GDBusConnection     *connection,\n'
@@ -1408,17 +1610,25 @@ class CodeGenerator:
                      '\n'
                      %(i.camel_name, i.name_lower, i.ns_upper, i.name_upper, i.name, i.ns_upper, i.name_upper))
         self.c.write('\n')
-        self.c.write('/**\n'
-                     ' * %s_proxy_new_for_bus:\n'
-                     ' * @bus_type: \n'
-                     ' * @flags: \n'
-                     ' * @name: \n'
-                     ' * @object_path: \n'
-                     ' * @callback: \n'
-                     ' * @user_data: \n'
-                     ' *\n'
-                     %(i.name_lower))
-        self.c.write(' */\n')
+        self.c.write(self.docbook_gen.expand(
+                '/**\n'
+                ' * %s_proxy_new_for_bus:\n'
+                ' * @bus_type: A #GBusType.\n'
+                ' * @flags: Flags from the #GDBusProxyFlags enumeration.\n'
+                ' * @name: A bus name (well-known or unique).\n'
+                ' * @object_path: An object path.\n'
+                ' * @cancellable: (allow-none): A #GCancellable or %%NULL.\n'
+                ' * @callback: A #GAsyncReadyCallback to call when the request is satisfied.\n'
+                ' * @user_data: User data to pass to @callback.\n'
+                ' *\n'
+                ' * Like %s_proxy_new() but takes a #GBusType instead of a #GDBusConnection.\n'
+                ' *\n'
+                ' * When the operation is finished, @callback will be invoked in the <link linkend="g-main-context-push-thread-default">thread-default main loop</link> of the thread you are calling this method from.\n'
+                ' * You can then call %s_proxy_new_for_bus_finish() to get the result of the operation.\n'
+                ' *\n'
+                ' * See %s_proxy_new_for_bus_sync() for the synchronous, blocking version of this constructor.\n'
+                %(i.name_lower, i.name_lower, i.name_lower, i.name_lower)))
+        self.write_gtkdoc_deprecated_and_since_and_close(i, self.c, 0)
         self.c.write('void\n'
                      '%s_proxy_new_for_bus (\n'
                      '    GBusType             bus_type,\n'
@@ -1435,12 +1645,14 @@ class CodeGenerator:
                      %(i.name_lower, i.ns_upper, i.name_upper, i.name))
         self.c.write('/**\n'
                      ' * %s_proxy_new_for_bus_finish:\n'
-                     ' * @res: \n'
-                     ' * @error: \n'
+                     ' * @res: The #GAsyncResult obtained from the #GAsyncReadyCallback passed to %s_proxy_new_for_bus().\n'
+                     ' * @error: Return location for error or %%NULL\n'
                      ' *\n'
-                     ' * Returns: (transfer full) (type %sProxy):\n'
-                     %(i.name_lower, i.camel_name))
-        self.c.write(' */\n')
+                     ' * Finishes an operation started with %s_proxy_new_for_bus().\n'
+                     ' *\n'
+                     ' * Returns: (transfer full) (type %sProxy): The constructed proxy object or %%NULL if @error is set.\n'
+                     %(i.name_lower, i.name_lower, i.name_lower, i.camel_name))
+        self.write_gtkdoc_deprecated_and_since_and_close(i, self.c, 0)
         self.c.write('%s *\n'
                      '%s_proxy_new_for_bus_finish (\n'
                      '    GAsyncResult        *res,\n'
@@ -1458,18 +1670,25 @@ class CodeGenerator:
                      '}\n'
                      '\n'
                      %(i.camel_name, i.name_lower, i.ns_upper, i.name_upper))
-        self.c.write('/**\n'
-                     ' * %s_proxy_new_for_bus_sync:\n'
-                     ' * @bus_type: \n'
-                     ' * @flags: \n'
-                     ' * @name: \n'
-                     ' * @object_path: \n'
-                     ' * @cancellable: \n'
-                     ' * @error: \n'
-                     ' *\n'
-                     ' * Returns: (transfer full) (type %sProxy):\n'
-                     %(i.name_lower, i.camel_name))
-        self.c.write(' */\n')
+        self.c.write(self.docbook_gen.expand(
+                '/**\n'
+                ' * %s_proxy_new_for_bus_sync:\n'
+                ' * @bus_type: A #GBusType.\n'
+                ' * @flags: Flags from the #GDBusProxyFlags enumeration.\n'
+                ' * @name: A bus name (well-known or unique).\n'
+                ' * @object_path: An object path.\n'
+                ' * @cancellable: (allow-none): A #GCancellable or %%NULL.\n'
+                ' * @error: Return location for error or %%NULL\n'
+                ' *\n'
+                ' * Like %s_proxy_new_sync() but takes a #GBusType instead of a #GDBusConnection.\n'
+                ' *\n'
+                ' * The calling thread is blocked until a reply is received.\n'
+                ' *\n'
+                ' * See %s_proxy_new_for_bus() for the asynchronous version of this constructor.\n'
+                ' *\n'
+                ' * Returns: (transfer full) (type %sProxy): The constructed proxy object or %%NULL if @error is set.\n'
+                %(i.name_lower, i.name_lower, i.name_lower, i.camel_name)))
+        self.write_gtkdoc_deprecated_and_since_and_close(i, self.c, 0)
         self.c.write('%s *\n'
                      '%s_proxy_new_for_bus_sync (\n'
                      '    GBusType             bus_type,\n'
@@ -1497,6 +1716,25 @@ class CodeGenerator:
         self.c.write('/* ------------------------------------------------------------------------ */\n'
                      '\n')
 
+        self.c.write(self.docbook_gen.expand(
+                '/**\n'
+                ' * %sSkeleton:\n'
+                ' *\n'
+                ' * The #%sSkeleton structure contains only private data and should only be accessed using the provided API.\n'
+                %(i.camel_name, i.camel_name)))
+        self.write_gtkdoc_deprecated_and_since_and_close(i, self.c, 0)
+        self.c.write('\n')
+
+        self.c.write(self.docbook_gen.expand(
+                '/**\n'
+                ' * %sSkeletonClass:\n'
+                ' * @parent_class: The parent class.\n'
+                ' *\n'
+                ' * Class structure for #%sSkeleton.\n'
+                %(i.camel_name, i.camel_name)))
+        self.write_gtkdoc_deprecated_and_since_and_close(i, self.c, 0)
+        self.c.write('\n')
+
         self.c.write('struct _%sSkeletonPrivate\n'
                      '{\n'
                      '  GValueArray *properties;\n'
@@ -1955,12 +2193,15 @@ class CodeGenerator:
                      '\n')
 
         # constructors
-        self.c.write('/**\n'
-                     ' * %s_skeleton_new:\n'
-                     ' *\n'
-                     ' * Returns: (transfer full) (type %sSkeleton):\n'
-                     %(i.name_lower, i.camel_name))
-        self.c.write(' */\n')
+        self.c.write(self.docbook_gen.expand(
+                '/**\n'
+                ' * %s_skeleton_new:\n'
+                ' *\n'
+                ' * Creates a skeleton object for the D-Bus interface #%s.\n'
+                ' *\n'
+                ' * Returns: (transfer full) (type %sSkeleton): The skeleton object.\n'
+                %(i.name_lower, i.name, i.camel_name)))
+        self.write_gtkdoc_deprecated_and_since_and_close(i, self.c, 0)
         self.c.write('%s *\n'
                      '%s_skeleton_new (void)\n'
                      '{\n'
@@ -1972,18 +2213,15 @@ class CodeGenerator:
 
     def generate_object_manager_client(self):
         self.c.write('/* ------------------------------------------------------------------------\n'
-                     ' * Code for proxy manager\n'
+                     ' * Code for ObjectManager client\n'
                      ' * ------------------------------------------------------------------------\n'
                      ' */\n'
                      '\n')
 
         # class boilerplate
-        self.c.write('/* ------------------------------------------------------------------------ */\n'
-                     '\n')
-        self.c.write('#define %sobject_manager_client_get_type %sobject_manager_client_get_type\n'%(self.ns_lower, self.ns_lower))
-        self.c.write('G_DEFINE_TYPE (%sObjectManagerClient, %sobject_manager_client, G_TYPE_DBUS_OBJECT_MANAGER_CLIENT);\n'%(self.namespace, self.ns_lower))
-        self.c.write('#undef %sobject_manager_client_get_type\n'
-                     '\n'%(self.ns_lower))
+        self.c.write('G_DEFINE_TYPE (%sObjectManagerClient, %sobject_manager_client, G_TYPE_DBUS_OBJECT_MANAGER_CLIENT);\n'
+                     '\n'
+                     %(self.namespace, self.ns_lower))
 
         # class boilerplate
         self.c.write('static void\n'
@@ -1997,6 +2235,17 @@ class CodeGenerator:
                      '}\n'
                      '\n'%(self.ns_lower, self.namespace))
 
+        self.c.write(self.docbook_gen.expand(
+                '/**\n'
+                ' * %sobject_manager_client_get_proxy_type:\n'
+                ' * @manager: A #GDBusObjectManagerClient.\n'
+                ' * @object_path: The object path of the remote object (unused).\n'
+                ' * @interface_name: Interface name of the remote object.\n'
+                ' * @user_data: User data (unused).\n'
+                ' *\n'
+                ' * A #GDBusProxyFunc that maps @interface_name to the generated #GDBusProxy<!-- -->-derived types.\n'
+                %(self.ns_lower)))
+        self.c.write(' */\n')
         self.c.write('GType\n'
                      '%sobject_manager_client_get_proxy_type (GDBusObjectManagerClient *manager, const gchar *object_path, const gchar *interface_name, gpointer user_data)\n'
                      '{\n'
@@ -2021,17 +2270,24 @@ class CodeGenerator:
                      '\n')
 
         # constructors
-        self.c.write('/**\n'
-                     ' * %sobject_manager_client_new:\n'
-                     ' * @connection: \n'
-                     ' * @flags: \n'
-                     ' * @name: \n'
-                     ' * @object_path: \n'
-                     ' * @cancellable: \n'
-                     ' * @callback: \n'
-                     ' * @user_data: \n'
-                     ' *\n'
-                     %(self.ns_lower))
+        self.c.write(self.docbook_gen.expand(
+                '/**\n'
+                ' * %sobject_manager_client_new:\n'
+                ' * @connection: A #GDBusConnection.\n'
+                ' * @flags: Flags from the #GDBusObjectManagerClientFlags enumeration.\n'
+                ' * @name: (allow-none): A bus name (well-known or unique) or %%NULL if @connection is not a message bus connection.\n'
+                ' * @object_path: An object path.\n'
+                ' * @cancellable: (allow-none): A #GCancellable or %%NULL.\n'
+                ' * @callback: A #GAsyncReadyCallback to call when the request is satisfied.\n'
+                ' * @user_data: User data to pass to @callback.\n'
+                ' *\n'
+                ' * Asynchronously creates #GDBusObjectManagerClient using %sobject_manager_client_get_proxy_type() as the #GDBusProxyFunc. See g_dbus_object_manager_client_new() for more details.\n'
+                ' *\n'
+                ' * When the operation is finished, @callback will be invoked in the <link linkend="g-main-context-push-thread-default">thread-default main loop</link> of the thread you are calling this method from.\n'
+                ' * You can then call %sobject_manager_client_new_finish() to get the result of the operation.\n'
+                ' *\n'
+                ' * See %sobject_manager_client_new_sync() for the synchronous, blocking version of this constructor.\n'
+                %(self.ns_lower, self.ns_lower, self.ns_lower, self.ns_lower)))
         self.c.write(' */\n')
         self.c.write('void\n'
                      '%sobject_manager_client_new (\n'
@@ -2049,11 +2305,13 @@ class CodeGenerator:
                      %(self.ns_lower, self.ns_upper, self.ns_lower))
         self.c.write('/**\n'
                      ' * %sobject_manager_client_new_finish:\n'
-                     ' * @res: \n'
-                     ' * @error: \n'
+                     ' * @res: The #GAsyncResult obtained from the #GAsyncReadyCallback passed to %sobject_manager_client_new().\n'
+                     ' * @error: Return location for error or %%NULL\n'
+                     ' *\n'
+                     ' * Finishes an operation started with %sobject_manager_client_new().\n'
                      ' *\n'
-                     ' * Returns: (transfer full) (type %sObjectManagerClient):\n'
-                     %(self.ns_lower, self.namespace))
+                     ' * Returns: (transfer full) (type %sObjectManagerClient): The constructed object manager client or %%NULL if @error is set.\n'
+                     %(self.ns_lower, self.ns_lower, self.ns_lower, self.namespace))
         self.c.write(' */\n')
         self.c.write('GDBusObjectManager *\n'
                      '%sobject_manager_client_new_finish (\n'
@@ -2072,17 +2330,24 @@ class CodeGenerator:
                      '}\n'
                      '\n'
                      %(self.ns_lower))
-        self.c.write('/**\n'
-                     ' * %sobject_manager_client_new_sync:\n'
-                     ' * @connection: \n'
-                     ' * @flags: \n'
-                     ' * @name: \n'
-                     ' * @object_path: \n'
-                     ' * @cancellable: \n'
-                     ' * @error: \n'
-                     ' *\n'
-                     ' * Returns: (transfer full) (type %sObjectManagerClient):\n'
-                     %(self.ns_lower, self.namespace))
+        self.c.write(self.docbook_gen.expand(
+                '/**\n'
+                ' * %sobject_manager_client_new_sync:\n'
+                ' * @connection: A #GDBusConnection.\n'
+                ' * @flags: Flags from the #GDBusObjectManagerClientFlags enumeration.\n'
+                ' * @name: (allow-none): A bus name (well-known or unique) or %%NULL if @connection is not a message bus connection.\n'
+                ' * @object_path: An object path.\n'
+                ' * @cancellable: (allow-none): A #GCancellable or %%NULL.\n'
+                ' * @error: Return location for error or %%NULL\n'
+                ' *\n'
+                ' * Synchronously creates #GDBusObjectManagerClient using %sobject_manager_client_get_proxy_type() as the #GDBusProxyFunc. See g_dbus_object_manager_client_new_sync() for more details.\n'
+                ' *\n'
+                ' * The calling thread is blocked until a reply is received.\n'
+                ' *\n'
+                ' * See %sobject_manager_client_new() for the asynchronous version of this constructor.\n'
+                ' *\n'
+                ' * Returns: (transfer full) (type %sObjectManagerClient): The constructed object manager client or %%NULL if @error is set.\n'
+                %(self.ns_lower, self.ns_lower, self.ns_lower, self.namespace)))
         self.c.write(' */\n')
         self.c.write('GDBusObjectManager *\n'
                      '%sobject_manager_client_new_sync (\n'
@@ -2103,17 +2368,24 @@ class CodeGenerator:
                      '\n'
                      %(self.ns_lower, self.ns_upper, self.ns_lower))
         self.c.write('\n')
-        self.c.write('/**\n'
-                     ' * %sobject_manager_client_new_for_bus:\n'
-                     ' * @bus_type: \n'
-                     ' * @flags: \n'
-                     ' * @name: \n'
-                     ' * @object_path: \n'
-                     ' * @cancellable: \n'
-                     ' * @callback: \n'
-                     ' * @user_data: \n'
-                     ' *\n'
-                     %(self.ns_lower))
+        self.c.write(self.docbook_gen.expand(
+                '/**\n'
+                ' * %sobject_manager_client_new_for_bus:\n'
+                ' * @bus_type: A #GBusType.\n'
+                ' * @flags: Flags from the #GDBusObjectManagerClientFlags enumeration.\n'
+                ' * @name: A bus name (well-known or unique).\n'
+                ' * @object_path: An object path.\n'
+                ' * @cancellable: (allow-none): A #GCancellable or %%NULL.\n'
+                ' * @callback: A #GAsyncReadyCallback to call when the request is satisfied.\n'
+                ' * @user_data: User data to pass to @callback.\n'
+                ' *\n'
+                ' * Like %sobject_manager_client_new() but takes a #GBusType instead of a #GDBusConnection.\n'
+                ' *\n'
+                ' * When the operation is finished, @callback will be invoked in the <link linkend="g-main-context-push-thread-default">thread-default main loop</link> of the thread you are calling this method from.\n'
+                ' * You can then call %sobject_manager_client_new_for_bus_finish() to get the result of the operation.\n'
+                ' *\n'
+                ' * See %sobject_manager_client_new_for_bus_sync() for the synchronous, blocking version of this constructor.\n'
+                %(self.ns_lower, self.ns_lower, self.ns_lower, self.ns_lower)))
         self.c.write(' */\n')
         self.c.write('void\n'
                      '%sobject_manager_client_new_for_bus (\n'
@@ -2131,11 +2403,13 @@ class CodeGenerator:
                      %(self.ns_lower, self.ns_upper, self.ns_lower))
         self.c.write('/**\n'
                      ' * %sobject_manager_client_new_for_bus_finish:\n'
-                     ' * @res: \n'
-                     ' * @error: \n'
+                     ' * @res: The #GAsyncResult obtained from the #GAsyncReadyCallback passed to %sobject_manager_client_new_for_bus().\n'
+                     ' * @error: Return location for error or %%NULL\n'
+                     ' *\n'
+                     ' * Finishes an operation started with %sobject_manager_client_new_for_bus().\n'
                      ' *\n'
-                     ' * Returns: (transfer full) (type %sObjectManagerClient):\n'
-                     %(self.ns_lower, self.namespace))
+                     ' * Returns: (transfer full) (type %sObjectManagerClient): The constructed object manager client or %%NULL if @error is set.\n'
+                     %(self.ns_lower, self.ns_lower, self.ns_lower, self.namespace))
         self.c.write(' */\n')
         self.c.write('GDBusObjectManager *\n'
                      '%sobject_manager_client_new_for_bus_finish (\n'
@@ -2154,17 +2428,24 @@ class CodeGenerator:
                      '}\n'
                      '\n'
                      %(self.ns_lower))
-        self.c.write('/**\n'
-                     ' * %sobject_manager_client_new_for_bus_sync:\n'
-                     ' * @bus_type: \n'
-                     ' * @flags: \n'
-                     ' * @name: \n'
-                     ' * @object_path: \n'
-                     ' * @cancellable: \n'
-                     ' * @error: \n'
-                     ' *\n'
-                     ' * Returns: (transfer full) (type %sObjectManagerClient):\n'
-                     %(self.ns_lower, self.namespace))
+        self.c.write(self.docbook_gen.expand(
+                '/**\n'
+                ' * %sobject_manager_client_new_for_bus_sync:\n'
+                ' * @bus_type: A #GBusType.\n'
+                ' * @flags: Flags from the #GDBusObjectManagerClientFlags enumeration.\n'
+                ' * @name: A bus name (well-known or unique).\n'
+                ' * @object_path: An object path.\n'
+                ' * @cancellable: (allow-none): A #GCancellable or %%NULL.\n'
+                ' * @error: Return location for error or %%NULL\n'
+                ' *\n'
+                ' * Like %sobject_manager_client_new_sync() but takes a #GBusType instead of a #GDBusConnection.\n'
+                ' *\n'
+                ' * The calling thread is blocked until a reply is received.\n'
+                ' *\n'
+                ' * See %sobject_manager_client_new_for_bus() for the asynchronous version of this constructor.\n'
+                ' *\n'
+                ' * Returns: (transfer full) (type %sObjectManagerClient): The constructed object manager client or %%NULL if @error is set.\n'
+                %(self.ns_lower, self.ns_lower, self.ns_lower, self.namespace)))
         self.c.write(' */\n')
         self.c.write('GDBusObjectManager *\n'
                      '%sobject_manager_client_new_for_bus_sync (\n'
@@ -2188,6 +2469,30 @@ class CodeGenerator:
 
     # ---------------------------------------------------------------------------------------------------
 
+    def write_gtkdoc_deprecated_and_since_and_close(self, obj, f, indent):
+        if len(obj.since) > 0:
+            f.write('%*s *\n'
+                    '%*s * Since: %s\n'
+                    %(indent, '', indent, '', obj.since))
+        if obj.deprecated:
+            if isinstance(obj, dbustypes.Interface):
+                thing = 'The D-Bus interface'
+            elif isinstance(obj, dbustypes.Method):
+                thing = 'The D-Bus method'
+            elif isinstance(obj, dbustypes.Signal):
+                thing = 'The D-Bus signal'
+            elif isinstance(obj, dbustypes.Property):
+                thing = 'The D-Bus property'
+            else:
+                raise RuntimeError('Cannot handle object ', obj)
+            f.write(self.docbook_gen.expand(
+                    '%*s *\n'
+                    '%*s * Deprecated: %s has been deprecated.\n'
+                    %(indent, '', indent, '', thing)))
+        f.write('%*s */\n'%(indent, ''))
+
+    # ---------------------------------------------------------------------------------------------------
+
     def generate(self):
         self.generate_intro()
         self.declare_types()
diff --git a/gio/gdbus-codegen/codegen_docbook.py b/gio/gdbus-codegen/codegen_docbook.py
index 18b1fc0..4e5245b 100644
--- a/gio/gdbus-codegen/codegen_docbook.py
+++ b/gio/gdbus-codegen/codegen_docbook.py
@@ -35,6 +35,7 @@ class DocbookCodeGenerator:
     def __init__(self, ifaces, docbook):
         self.ifaces = ifaces
         self.docbook = docbook
+        self.generate_expand_dicts()
 
     def print_method_prototype(self, i, m, in_synopsis):
         max_method_len = 0
@@ -259,7 +260,6 @@ class DocbookCodeGenerator:
         self.expand_iface_dict_keys.sort(reverse=True)
 
     def generate(self):
-        self.generate_expand_dicts()
         for i in self.ifaces:
             self.out = file('%s-%s.xml'%(self.docbook, i.name), 'w')
             self.out.write(''%())
diff --git a/gio/gdbus-codegen/codegen_main.py b/gio/gdbus-codegen/codegen_main.py
index 0eeab6e..f0ff805 100644
--- a/gio/gdbus-codegen/codegen_main.py
+++ b/gio/gdbus-codegen/codegen_main.py
@@ -176,6 +176,11 @@ def codegen_main():
     for i in parsed_ifaces:
         i.post_process(args.interface_prefix, args.c_namespace)
 
+    docbook = args.generate_docbook
+    docbook_gen = codegen_docbook.DocbookCodeGenerator(all_ifaces, docbook);
+    if docbook:
+        ret = docbook_gen.generate()
+
     c_code = args.generate_c_code
     if c_code:
         h = file(c_code + '.h', 'w')
@@ -184,14 +189,10 @@ def codegen_main():
                                     args.c_namespace,
                                     args.interface_prefix,
                                     args.c_generate_object_manager,
+                                    docbook_gen,
                                     h, c);
         ret = gen.generate()
 
-    docbook = args.generate_docbook
-    if docbook:
-        gen = codegen_docbook.DocbookCodeGenerator(all_ifaces, docbook);
-        ret = gen.generate()
-
     sys.exit(0)
 
 if __name__ == "__main__":
diff --git a/gio/gdbus-codegen/utils.py b/gio/gdbus-codegen/utils.py
index 2c7fbd3..687b979 100644
--- a/gio/gdbus-codegen/utils.py
+++ b/gio/gdbus-codegen/utils.py
@@ -21,6 +21,8 @@
 #
 # Author: David Zeuthen <davidz redhat com>
 
+import distutils.version
+
 def strip_dots(s):
     ret = ''
     force_upper = False
@@ -87,3 +89,16 @@ def lookup_brief_docs(annotations):
         return ''
     else:
         return s
+
+# I'm sure this could be a lot more elegant if I was
+# more fluent in python...
+def my_version_cmp(a, b):
+    if len(a[0]) > 0 and len(b[0]) > 0:
+        va = distutils.version.LooseVersion(a[0])
+        vb = distutils.version.LooseVersion(b[0])
+        ret = va.__cmp__(vb)
+    else:
+        ret = cmp(a[0], b[0])
+    if ret != 0:
+        return ret
+    return cmp(a[1], b[1])



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]