197ace
From fe823e3cfe25c96de5e453d1acbdc036892a9c36 Mon Sep 17 00:00:00 2001
197ace
From: Philip Withnall <withnall@endlessm.com>
197ace
Date: Tue, 17 Apr 2018 14:07:50 +0100
197ace
Subject: [PATCH 1/4] codegen: Support Since and name changing annotations on
197ace
 annotations
197ace
197ace
Recursive annotations do seem to be supported, so we should support them
197ace
properly in the type system representation. This currently introduces no
197ace
behavioural changes, but will be used in upcoming commits.
197ace
197ace
Signed-off-by: Philip Withnall <withnall@endlessm.com>
197ace
197ace
https://bugzilla.gnome.org/show_bug.cgi?id=795304
197ace
---
197ace
 gio/gdbus-2.0/codegen/dbustypes.py | 33 ++++++++++++++++++++++++++++++
197ace
 1 file changed, 33 insertions(+)
197ace
197ace
diff --git a/gio/gdbus-2.0/codegen/dbustypes.py b/gio/gdbus-2.0/codegen/dbustypes.py
197ace
index 359880ff7..29222f987 100644
197ace
--- a/gio/gdbus-2.0/codegen/dbustypes.py
197ace
+++ b/gio/gdbus-2.0/codegen/dbustypes.py
197ace
@@ -27,6 +27,25 @@ class Annotation:
197ace
         self.key = key
197ace
         self.value = value
197ace
         self.annotations = []
197ace
+        self.since = ''
197ace
+
197ace
+    def post_process(self, interface_prefix, cns, cns_upper, cns_lower, container):
197ace
+        key = self.key
197ace
+        overridden_key = utils.lookup_annotation(self.annotations, 'org.gtk.GDBus.C.Name')
197ace
+        if utils.is_ugly_case(overridden_key):
197ace
+            self.key_lower = overridden_key.lower()
197ace
+        else:
197ace
+            if overridden_key:
197ace
+                key = overridden_key
197ace
+            self.key_lower = utils.camel_case_to_uscore(key).lower().replace('-', '_').replace('.', '_')
197ace
+
197ace
+        if len(self.since) == 0:
197ace
+            self.since = utils.lookup_since(self.annotations)
197ace
+            if len(self.since) == 0:
197ace
+                self.since = container.since
197ace
+
197ace
+        for a in self.annotations:
197ace
+            a.post_process(interface_prefix, cns, cns_upper, cns_lower, self)
197ace
 
197ace
 class Arg:
197ace
     def __init__(self, name, signature):
197ace
@@ -229,6 +248,8 @@ class Arg:
197ace
                 self.gvalue_get = 'g_value_get_boxed'
197ace
                 self.array_annotation = '(array zero-terminated=1)'
197ace
 
197ace
+        for a in self.annotations:
197ace
+            a.post_process(interface_prefix, cns, cns_upper, cns_lower, self)
197ace
 
197ace
 class Method:
197ace
     def __init__(self, name):
197ace
@@ -270,6 +291,9 @@ class Method:
197ace
         if utils.lookup_annotation(self.annotations, 'org.freedesktop.DBus.Deprecated') == 'true':
197ace
             self.deprecated = True
197ace
 
197ace
+        for a in self.annotations:
197ace
+            a.post_process(interface_prefix, cns, cns_upper, cns_lower, self)
197ace
+
197ace
 class Signal:
197ace
     def __init__(self, name):
197ace
         self.name = name
197ace
@@ -305,6 +329,9 @@ class Signal:
197ace
         if utils.lookup_annotation(self.annotations, 'org.freedesktop.DBus.Deprecated') == 'true':
197ace
             self.deprecated = True
197ace
 
197ace
+        for a in self.annotations:
197ace
+            a.post_process(interface_prefix, cns, cns_upper, cns_lower, self)
197ace
+
197ace
 class Property:
197ace
     def __init__(self, name, signature, access):
197ace
         self.name = name
197ace
@@ -357,6 +384,9 @@ class Property:
197ace
         if utils.lookup_annotation(self.annotations, 'org.freedesktop.DBus.Deprecated') == 'true':
197ace
             self.deprecated = True
197ace
 
197ace
+        for a in self.annotations:
197ace
+            a.post_process(interface_prefix, cns, cns_upper, cns_lower, self)
197ace
+
197ace
         # FIXME: for now we only support 'false' and 'const' on the signal itself, see #674913 and
197ace
         # http://dbus.freedesktop.org/doc/dbus-specification.html#introspection-format
197ace
         # for details
197ace
@@ -436,3 +466,6 @@ class Interface:
197ace
 
197ace
         for p in self.properties:
197ace
             p.post_process(interface_prefix, cns, cns_upper, cns_lower, self)
197ace
+
197ace
+        for a in self.annotations:
197ace
+            a.post_process(interface_prefix, cns, cns_upper, cns_lower, self)
197ace
-- 
197ace
2.35.1
197ace
197ace
From dcb1c3fbd588dcf5cdcaeb65547fdbe176312e10 Mon Sep 17 00:00:00 2001
197ace
From: Philip Withnall <withnall@endlessm.com>
197ace
Date: Tue, 17 Apr 2018 14:10:07 +0100
197ace
Subject: [PATCH 2/4] codegen: Add --interface-info-[body|header] modes
197ace
197ace
These generate basic .c and .h files containing the GDBusInterfaceInfo
197ace
for a D-Bus introspection XML file, but no other code (no skeletons,
197ace
proxies, GObjects, etc.).
197ace
197ace
This is useful for projects who want to describe their D-Bus interfaces
197ace
using introspection XML, but who wish to implement the interfaces
197ace
manually (for various reasons, typically because the skeletons generated
197ace
by gdbus-codegen are too simplistic and limiting). Previously, these
197ace
projects would have had to write the GDBusInterfaceInfo manually, which
197ace
is painstaking and error-prone.
197ace
197ace
The new --interface-info-[body|header] options are very similar to
197ace
--[body|header], but mutually exclusive with them.
197ace
197ace
Signed-off-by: Philip Withnall <withnall@endlessm.com>
197ace
197ace
https://bugzilla.gnome.org/show_bug.cgi?id=795304
197ace
---
197ace
 docs/reference/gio/gdbus-codegen.xml  |  65 +++++-
197ace
 gio/gdbus-2.0/codegen/codegen.py      | 280 ++++++++++++++++++++++++++
197ace
 gio/gdbus-2.0/codegen/codegen_main.py |  39 ++++
197ace
 3 files changed, 377 insertions(+), 7 deletions(-)
197ace
197ace
diff --git a/docs/reference/gio/gdbus-codegen.xml b/docs/reference/gio/gdbus-codegen.xml
197ace
index b1145e5ef..3e1a9d668 100644
197ace
--- a/docs/reference/gio/gdbus-codegen.xml
197ace
+++ b/docs/reference/gio/gdbus-codegen.xml
197ace
@@ -39,6 +39,8 @@
197ace
     <arg><option>--xml-files</option> <replaceable>FILE</replaceable></arg>
197ace
     <arg><option>--header</option></arg>
197ace
     <arg><option>--body</option></arg>
197ace
+    <arg><option>--interface-info-header</option></arg>
197ace
+    <arg><option>--interface-info-body</option></arg>
197ace
     <arg><option>--output</option> <replaceable>OUTFILE</replaceable></arg>
197ace
     <group choice="plain" rep="repeat">
197ace
       <arg>
197ace
@@ -69,7 +71,11 @@
197ace
     arguments on the command line and generates output files.
197ace
     It currently supports generating C source code (via
197ace
     <option>--body</option>) or header (via <option>--header</option>)
197ace
-    and Docbook XML (via <option>--generate-docbook</option>).
197ace
+    and Docbook XML (via <option>--generate-docbook</option>). Alternatively,
197ace
+    more restricted C source code and headers can be generated, which just
197ace
+    contain the interface information (as <type>GDBusInterfaceInfo</type>
197ace
+    structures) using <option>--interface-info-body</option> and
197ace
+    <option>--interface-info-header</option>.
197ace
   </para>
197ace
 </refsect1>
197ace
 
197ace
@@ -90,8 +96,11 @@
197ace
   </para>
197ace
   <para>
197ace
     For C code generation either <option>--body</option> that
197ace
-    generates source code, or <option>--header</option> that
197ace
-    generates headers, can be used. These options must be used along with
197ace
+    generates source code, <option>--header</option> that
197ace
+    generates headers, <option>--interface-info-body</option> that generates
197ace
+    interface information source code, or
197ace
+    <option>--interface-info-header</option> that generates interface information
197ace
+    headers, can be used. These options must be used along with
197ace
     <option>--output</option>, which is used to specify the file to output to.
197ace
   </para>
197ace
   <para>
197ace
@@ -282,8 +291,10 @@
197ace
           Directory to output generated source to. Equivalent to changing directory before generation.
197ace
         </para>
197ace
         <para>
197ace
-          This option cannot be used with neither <option>--body</option> nor
197ace
-          <option>--header</option>, and <option>--output</option> must be used.
197ace
+          This option cannot be used with <option>--body</option>,
197ace
+          <option>--header</option>, <option>--interface-info-body</option> or
197ace
+          <option>--interface-info-header</option>; and
197ace
+          <option>--output</option> must be used.
197ace
         </para>
197ace
 
197ace
       </listitem>
197ace
@@ -321,12 +332,52 @@
197ace
       </listitem>
197ace
     </varlistentry>
197ace
 
197ace
+    <varlistentry>
197ace
+      <term><option>--interface-info-header</option></term>
197ace
+      <listitem>
197ace
+        <para>
197ace
+          If this option is passed, it will generate the header code for the
197ace
+          <type>GDBusInterfaceInfo</type> structures only and will write it to
197ace
+          the disk by using the path and file name provided by
197ace
+          <option>--output</option>.
197ace
+        </para>
197ace
+        <para>
197ace
+          Using <option>--generate-c-code</option>, <option>--generate-docbook</option> or
197ace
+          <option>--output-directory</option> are not allowed to be used along with
197ace
+          the <option>--interface-info-header</option> and
197ace
+          <option>--interface-info-body</option> options, because these options
197ace
+          are used to generate only one file.
197ace
+        </para>
197ace
+      </listitem>
197ace
+    </varlistentry>
197ace
+
197ace
+    <varlistentry>
197ace
+      <term><option>--interface-info-body</option></term>
197ace
+      <listitem>
197ace
+        <para>
197ace
+          If this option is passed, it will generate the source code for the
197ace
+          <type>GDBusInterfaceInfo</type> structures only and will write it to
197ace
+          the disk by using the path and file name provided by
197ace
+          <option>--output</option>.
197ace
+        </para>
197ace
+        <para>
197ace
+          Using <option>--generate-c-code</option>, <option>--generate-docbook</option> or
197ace
+          <option>--output-directory</option> are not allowed to be used along with
197ace
+          the <option>--interface-info-header</option> and
197ace
+          <option>--interface-info-body</option> options, because these options
197ace
+          are used to generate only one file.
197ace
+        </para>
197ace
+      </listitem>
197ace
+    </varlistentry>
197ace
+
197ace
     <varlistentry>
197ace
       <term><option>--output</option> <replaceable>OUTFILE</replaceable></term>
197ace
       <listitem>
197ace
         <para>
197ace
-          The full path where the header (<option>--header</option>) or the source code
197ace
-          (<option>--body</option>) will be written, using the path and filename provided by
197ace
+          The full path where the header (<option>--header</option>,
197ace
+          <option>--interface-info-header</option>) or the source code
197ace
+          (<option>--body</option>, <option>--interface-info-body</option>) will
197ace
+          be written, using the path and filename provided by
197ace
           <option>--output</option>. The full path could be something like
197ace
           <literal>$($OUTFILE).{c,h}</literal>.
197ace
         </para>
197ace
diff --git a/gio/gdbus-2.0/codegen/codegen.py b/gio/gdbus-2.0/codegen/codegen.py
197ace
index 442bd3f5d..4e258332d 100644
197ace
--- a/gio/gdbus-2.0/codegen/codegen.py
197ace
+++ b/gio/gdbus-2.0/codegen/codegen.py
197ace
@@ -610,6 +610,286 @@ class HeaderCodeGenerator:
197ace
 
197ace
 # ----------------------------------------------------------------------------------------------------
197ace
 
197ace
+class InterfaceInfoHeaderCodeGenerator:
197ace
+    def __init__(self, ifaces, namespace, header_name, use_pragma, outfile):
197ace
+        self.ifaces = ifaces
197ace
+        self.namespace, self.ns_upper, self.ns_lower = generate_namespace(namespace)
197ace
+        self.header_guard = header_name.upper().replace('.', '_').replace('-', '_').replace('/', '_').replace(':', '_')
197ace
+        self.use_pragma = use_pragma
197ace
+        self.outfile = outfile
197ace
+
197ace
+    # ----------------------------------------------------------------------------------------------------
197ace
+
197ace
+    def generate_header_preamble(self):
197ace
+        self.outfile.write(LICENSE_STR.format(config.VERSION))
197ace
+        self.outfile.write('\n')
197ace
+
197ace
+        if self.use_pragma:
197ace
+            self.outfile.write('#pragma once\n')
197ace
+        else:
197ace
+            self.outfile.write('#ifndef __{!s}__\n'.format(self.header_guard))
197ace
+            self.outfile.write('#define __{!s}__\n'.format(self.header_guard))
197ace
+
197ace
+        self.outfile.write('\n')
197ace
+        self.outfile.write('#include <gio/gio.h>\n')
197ace
+        self.outfile.write('\n')
197ace
+        self.outfile.write('G_BEGIN_DECLS\n')
197ace
+        self.outfile.write('\n')
197ace
+
197ace
+    # ----------------------------------------------------------------------------------------------------
197ace
+
197ace
+    def declare_infos(self):
197ace
+        for i in self.ifaces:
197ace
+            self.outfile.write('extern const GDBusInterfaceInfo %s_interface;\n' % i.name_lower)
197ace
+
197ace
+    # ----------------------------------------------------------------------------------------------------
197ace
+
197ace
+    def generate_header_postamble(self):
197ace
+        self.outfile.write('\n')
197ace
+        self.outfile.write('G_END_DECLS\n')
197ace
+
197ace
+        if not self.use_pragma:
197ace
+            self.outfile.write('\n')
197ace
+            self.outfile.write('#endif /* __{!s}__ */\n'.format(self.header_guard))
197ace
+
197ace
+    # ----------------------------------------------------------------------------------------------------
197ace
+
197ace
+    def generate(self):
197ace
+        self.generate_header_preamble()
197ace
+        self.declare_infos()
197ace
+        self.generate_header_postamble()
197ace
+
197ace
+# ----------------------------------------------------------------------------------------------------
197ace
+
197ace
+class InterfaceInfoBodyCodeGenerator:
197ace
+    def __init__(self, ifaces, namespace, header_name, outfile):
197ace
+        self.ifaces = ifaces
197ace
+        self.namespace, self.ns_upper, self.ns_lower = generate_namespace(namespace)
197ace
+        self.header_name = header_name
197ace
+        self.outfile = outfile
197ace
+
197ace
+    # ----------------------------------------------------------------------------------------------------
197ace
+
197ace
+    def generate_body_preamble(self):
197ace
+        self.outfile.write(LICENSE_STR.format(config.VERSION))
197ace
+        self.outfile.write('\n')
197ace
+        self.outfile.write('#ifdef HAVE_CONFIG_H\n'
197ace
+                           '#  include "config.h"\n'
197ace
+                           '#endif\n'
197ace
+                           '\n'
197ace
+                           '#include "%s"\n'
197ace
+                           '\n'
197ace
+                           '#include <string.h>\n'
197ace
+                           % (self.header_name))
197ace
+        self.outfile.write('\n')
197ace
+
197ace
+    # ----------------------------------------------------------------------------------------------------
197ace
+
197ace
+    def generate_array(self, array_name_lower, element_type, elements):
197ace
+        self.outfile.write('const %s * const %s[] =\n' % (element_type, array_name_lower))
197ace
+        self.outfile.write('{\n')
197ace
+        for (_, name) in sorted(elements, key=utils.version_cmp_key):
197ace
+            self.outfile.write('  &%s,\n' % name)
197ace
+        self.outfile.write('  NULL,\n')
197ace
+        self.outfile.write('};\n')
197ace
+        self.outfile.write('\n')
197ace
+
197ace
+    def define_annotations(self, array_name_lower, annotations):
197ace
+        if len(annotations) == 0:
197ace
+            return
197ace
+
197ace
+        annotation_pointers = []
197ace
+
197ace
+        for a in annotations:
197ace
+            # Skip internal annotations.
197ace
+            if a.key.startswith('org.gtk.GDBus'):
197ace
+                continue
197ace
+
197ace
+            self.define_annotations('%s__%s_annotations' % (array_name_lower, a.key_lower), a.annotations)
197ace
+
197ace
+            self.outfile.write('const GDBusAnnotationInfo %s__%s_annotation =\n' % (array_name_lower, a.key_lower))
197ace
+            self.outfile.write('{\n')
197ace
+            self.outfile.write('  -1,  /* ref count */\n')
197ace
+            self.outfile.write('  (gchar *) "%s",\n' % a.key)
197ace
+            self.outfile.write('  (gchar *) "%s",\n' % a.value)
197ace
+            if len(a.annotations) > 0:
197ace
+                self.outfile.write('  (GDBusAnnotationInfo **) %s__%s_annotations,\n' % (array_name_lower, a.key_lower))
197ace
+            else:
197ace
+                self.outfile.write('  NULL,  /* no annotations */\n')
197ace
+            self.outfile.write('};\n')
197ace
+            self.outfile.write('\n')
197ace
+
197ace
+            key = (a.since, '%s__%s_annotation' % (array_name_lower, a.key_lower))
197ace
+            annotation_pointers.append(key)
197ace
+
197ace
+        self.generate_array(array_name_lower, 'GDBusAnnotationInfo',
197ace
+                            annotation_pointers)
197ace
+
197ace
+    def define_args(self, array_name_lower, args):
197ace
+        if len(args) == 0:
197ace
+            return
197ace
+
197ace
+        arg_pointers = []
197ace
+
197ace
+        for a in args:
197ace
+            self.define_annotations('%s__%s_arg_annotations' % (array_name_lower, a.name), a.annotations)
197ace
+
197ace
+            self.outfile.write('const GDBusArgInfo %s__%s_arg =\n' % (array_name_lower, a.name))
197ace
+            self.outfile.write('{\n')
197ace
+            self.outfile.write('  -1,  /* ref count */\n')
197ace
+            self.outfile.write('  (gchar *) "%s",\n' % a.name)
197ace
+            self.outfile.write('  (gchar *) "%s",\n' % a.signature)
197ace
+            if len(a.annotations) > 0:
197ace
+                self.outfile.write('  (GDBusAnnotationInfo **) %s__%s_arg_annotations,\n' % (array_name_lower, a.name))
197ace
+            else:
197ace
+                self.outfile.write('  NULL,  /* no annotations */\n')
197ace
+            self.outfile.write('};\n')
197ace
+            self.outfile.write('\n')
197ace
+
197ace
+            key = (a.since, '%s__%s_arg' % (array_name_lower, a.name))
197ace
+            arg_pointers.append(key)
197ace
+
197ace
+        self.generate_array(array_name_lower, 'GDBusArgInfo', arg_pointers)
197ace
+
197ace
+    def define_infos(self):
197ace
+        for i in self.ifaces:
197ace
+            self.outfile.write('/* ------------------------------------------------------------------------ */\n')
197ace
+            self.outfile.write('/* Definitions for %s */\n' % i.name)
197ace
+            self.outfile.write('\n')
197ace
+
197ace
+            # GDBusMethodInfos.
197ace
+            if len(i.methods) > 0:
197ace
+                method_pointers = []
197ace
+
197ace
+                for m in i.methods:
197ace
+                    self.define_args('%s_interface__%s_method_in_args' % (i.name_lower, m.name_lower), m.in_args)
197ace
+                    self.define_args('%s_interface__%s_method_out_args' % (i.name_lower, m.name_lower), m.out_args)
197ace
+                    self.define_annotations('%s_interface__%s_method_annotations' % (i.name_lower, m.name_lower), m.annotations)
197ace
+
197ace
+                    self.outfile.write('const GDBusMethodInfo %s_interface__%s_method =\n' % (i.name_lower, m.name_lower))
197ace
+                    self.outfile.write('{\n')
197ace
+                    self.outfile.write('  -1,  /* ref count */\n')
197ace
+                    self.outfile.write('  (gchar *) "%s",\n' % m.name)
197ace
+                    if len(m.in_args) > 0:
197ace
+                        self.outfile.write('  (GDBusArgInfo **) %s_interface__%s_method_in_args,\n' % (i.name_lower, m.name_lower))
197ace
+                    else:
197ace
+                        self.outfile.write('  NULL,  /* no in args */\n')
197ace
+                    if len(m.out_args) > 0:
197ace
+                        self.outfile.write('  (GDBusArgInfo **) %s_interface__%s_method_out_args,\n' % (i.name_lower, m.name_lower))
197ace
+                    else:
197ace
+                        self.outfile.write('  NULL,  /* no out args */\n')
197ace
+                    if len(m.annotations) > 0:
197ace
+                        self.outfile.write('  (GDBusAnnotationInfo **) %s_interface__%s_method_annotations,\n' % (i.name_lower, m.name_lower))
197ace
+                    else:
197ace
+                        self.outfile.write('  NULL,  /* no annotations */\n')
197ace
+                    self.outfile.write('};\n')
197ace
+                    self.outfile.write('\n')
197ace
+
197ace
+                    key = (m.since, '%s_interface__%s_method' % (i.name_lower, m.name_lower))
197ace
+                    method_pointers.append(key)
197ace
+
197ace
+                self.generate_array('%s_interface_methods' % i.name_lower,
197ace
+                                    'GDBusMethodInfo', method_pointers)
197ace
+
197ace
+            # GDBusSignalInfos.
197ace
+            if len(i.signals) > 0:
197ace
+                signal_pointers = []
197ace
+
197ace
+                for s in i.signals:
197ace
+                    self.define_args('%s_interface__%s_signal_args' % (i.name_lower, s.name_lower), s.args)
197ace
+                    self.define_annotations('%s_interface__%s_signal_annotations' % (i.name_lower, s.name_lower), s.annotations)
197ace
+
197ace
+                    self.outfile.write('const GDBusSignalInfo %s_interface__%s_signal =\n' % (i.name_lower, s.name_lower))
197ace
+                    self.outfile.write('{\n')
197ace
+                    self.outfile.write('  -1,  /* ref count */\n')
197ace
+                    self.outfile.write('  (gchar *) "%s",\n' % s.name)
197ace
+                    if len(s.args) > 0:
197ace
+                        self.outfile.write('  (GDBusArgInfo **) %s_interface__%s_signal_args,\n' % (i.name_lower, s.name_lower))
197ace
+                    else:
197ace
+                        self.outfile.write('  NULL,  /* no args */\n')
197ace
+                    if len(s.annotations) > 0:
197ace
+                        self.outfile.write('  (GDBusAnnotationInfo **) %s_interface__%s_signal_annotations,\n' % (i.name_lower, s.name_lower))
197ace
+                    else:
197ace
+                        self.outfile.write('  NULL,  /* no annotations */\n')
197ace
+                    self.outfile.write('};\n')
197ace
+                    self.outfile.write('\n')
197ace
+
197ace
+                    key = (m.since, '%s_interface__%s_signal' % (i.name_lower, s.name_lower))
197ace
+                    signal_pointers.append(key)
197ace
+
197ace
+                self.generate_array('%s_interface_signals' % i.name_lower,
197ace
+                                    'GDBusSignalInfo', signal_pointers)
197ace
+
197ace
+            # GDBusPropertyInfos.
197ace
+            if len(i.properties) > 0:
197ace
+                property_pointers = []
197ace
+
197ace
+                for p in i.properties:
197ace
+                    if p.readable and p.writable:
197ace
+                        flags = 'G_DBUS_PROPERTY_INFO_FLAGS_READABLE | G_DBUS_PROPERTY_INFO_FLAGS_WRITABLE'
197ace
+                    elif p.readable:
197ace
+                        flags = 'G_DBUS_PROPERTY_INFO_FLAGS_READABLE'
197ace
+                    elif p.writable:
197ace
+                        flags = 'G_DBUS_PROPERTY_INFO_FLAGS_WRITABLE'
197ace
+                    else:
197ace
+                        flags = 'G_DBUS_PROPERTY_INFO_FLAGS_NONE'
197ace
+
197ace
+                    self.define_annotations('%s_interface__%s_property_annotations' % (i.name_lower, p.name_lower), p.annotations)
197ace
+
197ace
+                    self.outfile.write('const GDBusPropertyInfo %s_interface__%s_property =\n' % (i.name_lower, p.name_lower))
197ace
+                    self.outfile.write('{\n')
197ace
+                    self.outfile.write('  -1,  /* ref count */\n')
197ace
+                    self.outfile.write('  (gchar *) "%s",\n' % p.name)
197ace
+                    self.outfile.write('  (gchar *) "%s",\n' % p.signature)
197ace
+                    self.outfile.write('  %s,\n' % flags)
197ace
+                    if len(p.annotations) > 0:
197ace
+                        self.outfile.write('  (GDBusAnnotationInfo **) %s_interface__%s_property_annotations,\n' % (i.name_lower, p.name_lower))
197ace
+                    else:
197ace
+                        self.outfile.write('  NULL,  /* no annotations */\n')
197ace
+                    self.outfile.write('};\n')
197ace
+                    self.outfile.write('\n')
197ace
+
197ace
+                    key = (m.since, '%s_interface__%s_property' % (i.name_lower, p.name_lower))
197ace
+                    property_pointers.append(key)
197ace
+
197ace
+                self.generate_array('%s_interface_properties' % i.name_lower,
197ace
+                                    'GDBusPropertyInfo', property_pointers)
197ace
+
197ace
+            # Finally the GDBusInterfaceInfo.
197ace
+            self.define_annotations('%s_interface_annotations' % i.name_lower,
197ace
+                                    i.annotations)
197ace
+
197ace
+            self.outfile.write('const GDBusInterfaceInfo %s_interface =\n' % i.name_lower)
197ace
+            self.outfile.write('{\n')
197ace
+            self.outfile.write('  -1,  /* ref count */\n')
197ace
+            self.outfile.write('  (gchar *) "%s",\n' % i.name)
197ace
+            if len(i.methods) > 0:
197ace
+                self.outfile.write('  (GDBusMethodInfo **) %s_interface_methods,\n' % i.name_lower)
197ace
+            else:
197ace
+                self.outfile.write('  NULL,  /* no methods */\n')
197ace
+            if len(i.signals) > 0:
197ace
+                self.outfile.write('  (GDBusSignalInfo **) %s_interface_signals,\n' % i.name_lower)
197ace
+            else:
197ace
+                self.outfile.write('  NULL,  /* no signals */\n')
197ace
+            if len(i.properties) > 0:
197ace
+                self.outfile.write('  (GDBusPropertyInfo **) %s_interface_properties,\n' % i.name_lower)
197ace
+            else:
197ace
+                self.outfile.write(  'NULL,  /* no properties */\n')
197ace
+            if len(i.annotations) > 0:
197ace
+                self.outfile.write('  (GDBusAnnotationInfo **) %s_interface_annotations,\n' % i.name_lower)
197ace
+            else:
197ace
+                self.outfile.write('  NULL,  /* no annotations */\n')
197ace
+            self.outfile.write('};\n')
197ace
+            self.outfile.write('\n')
197ace
+
197ace
+    # ----------------------------------------------------------------------------------------------------
197ace
+
197ace
+    def generate(self):
197ace
+        self.generate_body_preamble()
197ace
+        self.define_infos()
197ace
+
197ace
+# ----------------------------------------------------------------------------------------------------
197ace
+
197ace
 class CodeGenerator:
197ace
     def __init__(self, ifaces, namespace, generate_objmanager, header_name,
197ace
                  docbook_gen, outfile):
197ace
diff --git a/gio/gdbus-2.0/codegen/codegen_main.py b/gio/gdbus-2.0/codegen/codegen_main.py
197ace
index 1cfe7c1bb..37efb3bcf 100755
197ace
--- a/gio/gdbus-2.0/codegen/codegen_main.py
197ace
+++ b/gio/gdbus-2.0/codegen/codegen_main.py
197ace
@@ -175,6 +175,10 @@ def codegen_main():
197ace
                        help='Generate C headers')
197ace
     group.add_argument('--body', action='store_true',
197ace
                        help='Generate C code')
197ace
+    group.add_argument('--interface-info-header', action='store_true',
197ace
+                       help='Generate GDBusInterfaceInfo C header')
197ace
+    group.add_argument('--interface-info-body', action='store_true',
197ace
+                       help='Generate GDBusInterfaceInfo C code')
197ace
 
197ace
     group = arg_parser.add_mutually_exclusive_group()
197ace
     group.add_argument('--output', metavar='FILE',
197ace
@@ -210,6 +214,24 @@ def codegen_main():
197ace
 
197ace
         c_file = args.output
197ace
         header_name = os.path.splitext(os.path.basename(c_file))[0] + '.h'
197ace
+    elif args.interface_info_header:
197ace
+        if args.output is None:
197ace
+            print_error('Using --interface-info-header requires --output')
197ace
+        if args.c_generate_object_manager:
197ace
+            print_error('--c-generate-object-manager is incompatible with '
197ace
+                        '--interface-info-header')
197ace
+
197ace
+        h_file = args.output
197ace
+        header_name = os.path.basename(h_file)
197ace
+    elif args.interface_info_body:
197ace
+        if args.output is None:
197ace
+            print_error('Using --interface-info-body requires --output')
197ace
+        if args.c_generate_object_manager:
197ace
+            print_error('--c-generate-object-manager is incompatible with '
197ace
+                        '--interface-info-body')
197ace
+
197ace
+        c_file = args.output
197ace
+        header_name = os.path.splitext(os.path.basename(c_file))[0] + '.h'
197ace
 
197ace
     all_ifaces = []
197ace
     for fname in args.files + args.xml_files:
197ace
@@ -250,6 +272,23 @@ def codegen_main():
197ace
                                         outfile)
197ace
             gen.generate()
197ace
 
197ace
+    if args.interface_info_header:
197ace
+        with open(h_file, 'w') as outfile:
197ace
+            gen = codegen.InterfaceInfoHeaderCodeGenerator(all_ifaces,
197ace
+                                                           args.c_namespace,
197ace
+                                                           header_name,
197ace
+                                                           args.pragma_once,
197ace
+                                                           outfile)
197ace
+            gen.generate()
197ace
+
197ace
+    if args.interface_info_body:
197ace
+        with open(c_file, 'w') as outfile:
197ace
+            gen = codegen.InterfaceInfoBodyCodeGenerator(all_ifaces,
197ace
+                                                         args.c_namespace,
197ace
+                                                         header_name,
197ace
+                                                         outfile)
197ace
+            gen.generate()
197ace
+
197ace
     sys.exit(0)
197ace
 
197ace
 if __name__ == "__main__":
197ace
-- 
197ace
2.35.1
197ace
197ace
From 11de9adfe6f57521ea5ed881b6862480c742414c Mon Sep 17 00:00:00 2001
197ace
From: Philip Withnall <withnall@endlessm.com>
197ace
Date: Tue, 17 Apr 2018 14:12:18 +0100
197ace
Subject: [PATCH 3/4] codegen: Suppress the old --xml-files option in the
197ace
 --help output
197ace
MIME-Version: 1.0
197ace
Content-Type: text/plain; charset=UTF-8
197ace
Content-Transfer-Encoding: 8bit
197ace
197ace
Since it’s deprecated in favour of positional arguments, including it in
197ace
the help output is confusing.
197ace
197ace
Signed-off-by: Philip Withnall <withnall@endlessm.com>
197ace
197ace
https://bugzilla.gnome.org/show_bug.cgi?id=795304
197ace
---
197ace
 gio/gdbus-2.0/codegen/codegen_main.py | 2 +-
197ace
 1 file changed, 1 insertion(+), 1 deletion(-)
197ace
197ace
diff --git a/gio/gdbus-2.0/codegen/codegen_main.py b/gio/gdbus-2.0/codegen/codegen_main.py
197ace
index 37efb3bcf..d3763eb0f 100755
197ace
--- a/gio/gdbus-2.0/codegen/codegen_main.py
197ace
+++ b/gio/gdbus-2.0/codegen/codegen_main.py
197ace
@@ -152,7 +152,7 @@ def codegen_main():
197ace
     arg_parser.add_argument('files', metavar='FILE', nargs='*',
197ace
                             help='D-Bus introspection XML file')
197ace
     arg_parser.add_argument('--xml-files', metavar='FILE', action='append', default=[],
197ace
-                            help='D-Bus introspection XML file')
197ace
+                            help=argparse.SUPPRESS)
197ace
     arg_parser.add_argument('--interface-prefix', metavar='PREFIX', default='',
197ace
                             help='String to strip from D-Bus interface names for code and docs')
197ace
     arg_parser.add_argument('--c-namespace', metavar='NAMESPACE', default='',
197ace
-- 
197ace
2.35.1
197ace
197ace
From b2b72837b0545e297db7ded8773377b4b6473a55 Mon Sep 17 00:00:00 2001
197ace
From: Philip Withnall <withnall@endlessm.com>
197ace
Date: Tue, 17 Apr 2018 14:13:05 +0100
197ace
Subject: [PATCH 4/4] codegen: Fix a minor Python linting warning
197ace
197ace
This introduces no functional changes.
197ace
197ace
Signed-off-by: Philip Withnall <withnall@endlessm.com>
197ace
197ace
https://bugzilla.gnome.org/show_bug.cgi?id=795304
197ace
---
197ace
 gio/gdbus-2.0/codegen/codegen_main.py | 2 +-
197ace
 1 file changed, 1 insertion(+), 1 deletion(-)
197ace
197ace
diff --git a/gio/gdbus-2.0/codegen/codegen_main.py b/gio/gdbus-2.0/codegen/codegen_main.py
197ace
index d3763eb0f..fa9c71373 100755
197ace
--- a/gio/gdbus-2.0/codegen/codegen_main.py
197ace
+++ b/gio/gdbus-2.0/codegen/codegen_main.py
197ace
@@ -240,7 +240,7 @@ def codegen_main():
197ace
         parsed_ifaces = parser.parse_dbus_xml(xml_data)
197ace
         all_ifaces.extend(parsed_ifaces)
197ace
 
197ace
-    if args.annotate != None:
197ace
+    if args.annotate is not None:
197ace
         apply_annotations(all_ifaces, args.annotate)
197ace
 
197ace
     for i in all_ifaces:
197ace
-- 
197ace
2.35.1