update-dbus-docs: automatically add variablelist for introspected items

Add a <variablelist/> tag after every programlisting we auto-generate that
will be read by make-directive-index to cross-reference all dbus elements.
diff --git a/tools/update-dbus-docs.py b/tools/update-dbus-docs.py
index 4161294..6d790bc 100755
--- a/tools/update-dbus-docs.py
+++ b/tools/update-dbus-docs.py
@@ -164,6 +164,7 @@
     file = io.StringIO()
 
     declarations = collections.defaultdict(list)
+    interfaces = []
 
     print(f'''node {destination} {{''', file=file)
 
@@ -173,10 +174,13 @@
                             print_boring=print_boring,
                             only_interface=only_interface,
                             declarations=declarations)
+            name = iface.get('name')
+            if not name in BORING_INTERFACES:
+                interfaces.append(name)
 
     print(f'''}};''', file=file)
 
-    return file.getvalue(), declarations
+    return file.getvalue(), declarations, interfaces
 
 def subst_output(document, programlisting):
     try:
@@ -201,7 +205,7 @@
 
     xml = etree.fromstring(out, parser=PARSER)
 
-    new_text, declarations = xml_to_text(object_path, xml, only_interface=only_interface)
+    new_text, declarations, interfaces = xml_to_text(object_path, xml, only_interface=only_interface)
 
     programlisting.text = '\n'.join(prefix_lines) + '\n' + new_text + footer
 
@@ -212,8 +216,49 @@
         # delete old comments
         for child in parent:
             if (child.tag == etree.Comment
+                and 'Autogenerated' in child.text):
+                parent.remove(child)
+            if (child.tag == etree.Comment
                 and 'not documented' in child.text):
                 parent.remove(child)
+            if (child.tag == "variablelist"
+                and child.attrib.get("generated",False) == "True"):
+                parent.remove(child)
+
+        # insert pointer for systemd-directives generation
+        the_tail = programlisting.tail #tail is erased by addnext, so save it here.
+        prev_element = etree.Comment("Autogenerated cross-references for systemd.directives, do not edit")
+        programlisting.addnext(prev_element)
+        programlisting.tail = the_tail
+
+        for interface in interfaces:
+            variablelist = etree.Element("variablelist")
+            variablelist.attrib['class'] = 'dbus-interface'
+            variablelist.attrib['generated'] = 'True'
+            variablelist.attrib['extra-ref'] = interface
+
+            prev_element.addnext(variablelist)
+            prev_element.tail = the_tail
+            prev_element = variablelist
+
+        for decl_type,decl_list in declarations.items():
+            for declaration in decl_list:
+                variablelist = etree.Element("variablelist")
+                variablelist.attrib['class'] = 'dbus-'+decl_type
+                variablelist.attrib['generated'] = 'True'
+                if decl_type == 'method' :
+                    variablelist.attrib['extra-ref'] = declaration + '()'
+                else:
+                    variablelist.attrib['extra-ref'] = declaration
+
+                prev_element.addnext(variablelist)
+                prev_element.tail = the_tail
+                prev_element = variablelist
+
+        last_element = etree.Comment("End of Autogenerated section")
+        prev_element.addnext(last_element)
+        prev_element.tail = the_tail
+        last_element.tail = the_tail
 
         # insert comments for undocumented items
         for item in reversed(missing):