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