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