/srv/mercurial-server/detachablepurple: f95fde65c3e3: Added a DB...

Gilles Bedel gillux at cpw.pidgin.im
Fri Jun 15 22:01:29 EDT 2012


Changeset: f95fde65c3e3e4eca03bb2f41143029633aa4700
Author:	 Gilles Bedel <gillux at cpw.pidgin.im>
Date:	 2011-05-19 18:39 +0000
Branch:	 cpw.gillux.detachablepurple
URL: http://hg.pidgin.im/srv/mercurial-server/detachablepurple/rev/f95fde65c3e3

Description:

Added a DBus code generation script.
Actually, it only generates the DBus interface information data in
C source form. It?s mainly copied from glib?s gdbus-codegen code script.
We needed our own script, because the code generated by gdbus-codegen
doesn?t suit our needs. It?s good if you have DBus-dedicated gobjects,
but not if you want e.g. to directly export the existing properties and
methods of your gobjects.
But it still worth to have such a script to keep the XML DBus interface
information in static C structures instead of generating it at runtime
from hardcoded XML strings, so here it is.

diffstat:

 libpurple/Makefile.am          |   81 ++++--------
 libpurple/dbus/codegen.py      |  218 +++++++++++++++++++++++++++++++++
 libpurple/dbus/dbusxml-to-c.py |   41 ++++++
 libpurple/dbus/parser.py       |  264 +++++++++++++++++++++++++++++++++++++++++
 4 files changed, 550 insertions(+), 54 deletions(-)

diffs (truncated from 644 to 300 lines):

diff --git a/libpurple/Makefile.am b/libpurple/Makefile.am
--- a/libpurple/Makefile.am
+++ b/libpurple/Makefile.am
@@ -207,15 +207,15 @@
 
 purple_builtheaders = \
 	purple.h version.h marshallers.h enums.h \
-	dbus/account-server.h dbus/account-client.h \
-	dbus/blist-server.h dbus/blist-client.h \
-	dbus/buddy-server.h dbus/buddy-client.h \
-	dbus/chat-server.h dbus/chat-client.h \
-	dbus/connection-server.h dbus/connection-client.h \
-	dbus/contact-server.h dbus/contact-client.h \
-	dbus/group-server.h dbus/group-client.h \
-	dbus/constructor-server.h dbus/constructor-client.h \
-	dbus/callback-server.h dbus/callback-client.h
+	dbus/account.xml.h \
+	dbus/blist.xml.h \
+	dbus/buddy.xml.h \
+	dbus/callback.xml.h \
+	dbus/chat.xml.h \
+	dbus/connection.xml.h \
+	dbus/constructor.xml.h \
+	dbus/contact.xml.h \
+	dbus/group.xml.h
 
 purple_enumheaders = \
 	account.h \
@@ -264,59 +264,32 @@
 
 if ENABLE_DBUS
 
-dbus/constructor-server.h: dbus/constructor.xml
-	$(AM_V_GEN)dbus-binding-tool --prefix=DBUS_purple_constructor --mode=glib-server --output=$@ $<
+dbus/constructor.xml.h: dbus/constructor.xml
+	$(AM_V_GEN)dbus/dbusxml-to-c.py $< purple_constructor $@
 
-dbus/constructor-client.h: dbus/constructor.xml
-	$(AM_V_GEN)dbus-binding-tool --prefix=DBUS_purple_constructor --mode=glib-client --output=$@ $<
+dbus/callback.xml.h: dbus/callback.xml
+	$(AM_V_GEN)dbus/dbusxml-to-c.py $< purple_callback $@
 
-dbus/callback-server.h: dbus/callback.xml
-	$(AM_V_GEN)dbus-binding-tool --prefix=DBUS_purple_callback --mode=glib-server --output=$@ $<
+dbus/account.xml.h: dbus/account.xml
+	$(AM_V_GEN)dbus/dbusxml-to-c.py $< purple_account $@
 
-dbus/callback-client.h: dbus/callback.xml
-	$(AM_V_GEN)dbus-binding-tool --prefix=DBUS_purple_callback --mode=glib-client --output=$@ $<
+dbus/blist.xml.h: dbus/blist.xml
+	$(AM_V_GEN)dbus/dbusxml-to-c.py $< purple_blist $@
 
-dbus/account-server.h: dbus/account.xml
-	$(AM_V_GEN)dbus-binding-tool --prefix=DBUS_purple_account --mode=glib-server --output=$@ $<
+dbus/buddy.xml.h: dbus/buddy.xml
+	$(AM_V_GEN)dbus/dbusxml-to-c.py $< purple_buddy $@
 
-dbus/account-client.h: dbus/account.xml
-	$(AM_V_GEN)dbus-binding-tool --prefix=DBUS_purple_account --mode=glib-client --output=$@ $<
+dbus/chat.xml.h: dbus/chat.xml
+	$(AM_V_GEN)dbus/dbusxml-to-c.py $< purple_chat $@
 
-dbus/blist-server.h: dbus/blist.xml
-	$(AM_V_GEN)dbus-binding-tool --prefix=DBUS_purple_blist --mode=glib-server --output=$@ $<
+dbus/connection.xml.h: dbus/connection.xml
+	$(AM_V_GEN)dbus/dbusxml-to-c.py $< purple_connection $@
 
-dbus/blist-client.h: dbus/blist.xml
-	$(AM_V_GEN)dbus-binding-tool --prefix=DBUS_purple_blist --mode=glib-client --output=$@ $<
+dbus/contact.xml.h: dbus/contact.xml
+	$(AM_V_GEN)dbus/dbusxml-to-c.py $< purple_contact $@
 
-dbus/buddy-server.h: dbus/buddy.xml
-	$(AM_V_GEN)dbus-binding-tool --prefix=DBUS_purple_buddy --mode=glib-server --output=$@ $<
-
-dbus/buddy-client.h: dbus/buddy.xml
-	$(AM_V_GEN)dbus-binding-tool --prefix=DBUS_purple_buddy --mode=glib-client --output=$@ $<
-
-dbus/chat-server.h: dbus/chat.xml
-	$(AM_V_GEN)dbus-binding-tool --prefix=DBUS_purple_chat --mode=glib-server --output=$@ $<
-
-dbus/chat-client.h: dbus/chat.xml
-	$(AM_V_GEN)dbus-binding-tool --prefix=DBUS_purple_chat --mode=glib-client --output=$@ $<
-
-dbus/connection-server.h: dbus/connection.xml
-	$(AM_V_GEN)dbus-binding-tool --prefix=DBUS_purple_connection --mode=glib-server --output=$@ $<
-
-dbus/connection-client.h: dbus/connection.xml
-	$(AM_V_GEN)dbus-binding-tool --prefix=DBUS_purple_connection --mode=glib-client --output=$@ $<
-
-dbus/contact-server.h: dbus/contact.xml
-	$(AM_V_GEN)dbus-binding-tool --prefix=DBUS_purple_contact --mode=glib-server --output=$@ $<
-
-dbus/contact-client.h: dbus/contact.xml
-	$(AM_V_GEN)dbus-binding-tool --prefix=DBUS_purple_contact --mode=glib-client --output=$@ $<
-
-dbus/group-server.h: dbus/group.xml
-	$(AM_V_GEN)dbus-binding-tool --prefix=DBUS_purple_group --mode=glib-server --output=$@ $<
-
-dbus/group-client.h: dbus/group.xml
-	$(AM_V_GEN)dbus-binding-tool --prefix=DBUS_purple_group --mode=glib-client --output=$@ $<
+dbus/group.xml.h: dbus/group.xml
+	$(AM_V_GEN)dbus/dbusxml-to-c.py $< purple_group $@
 
 CLEANFILES = \
 	dbus-bindings.c \
diff --git a/libpurple/dbus/codegen.py b/libpurple/dbus/codegen.py
new file mode 100644
--- /dev/null
+++ b/libpurple/dbus/codegen.py
@@ -0,0 +1,218 @@
+# -*- Mode: Python -*-
+
+# GDBus - GLib D-Bus Library
+#
+# Copyright (C) 2008-2011 Red Hat, Inc.
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General
+# Public License along with this library; if not, write to the
+# Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+# Boston, MA 02111-1307, USA.
+#
+# Author: David Zeuthen <davidz at redhat.com>
+
+# Shamelessly cut and pasted from the gdbus-codegen glib tool, with minor
+# modifications. Only the GDBusInterfaceVTable generation code is here.
+
+import sys
+
+class CodeGenerator:
+    def __init__(self, ifaces, namespace, c):
+        self.ifaces = ifaces
+        self.c = c
+        self.namespace = namespace
+
+    def generate_annotations(self, prefix, annotations):
+        if annotations == None:
+            return
+
+        n = 0
+        for a in annotations:
+            # skip internal annotations
+            if a.key.startswith('org.gtk.GDBus'):
+                continue
+
+            self.c.write('static const GDBusAnnotationInfo %s_%d =\n'
+                         '{\n'
+                         '  -1,\n'
+                         '  "%s",\n'
+                         '  "%s",\n'%(prefix, n, a.key, a.value))
+            if len(a.annotations) == 0:
+                self.c.write('  NULL\n')
+            else:
+                self.c.write('  (GDBusAnnotationInfo **) &%s_%d_pointers\n'%(prefix, n))
+            self.c.write('};\n'
+                         '\n')
+            n += 1
+
+        if n > 0:
+            self.c.write('static const GDBusAnnotationInfo * const %s_pointers[] =\n'
+                             '{\n'%(prefix))
+            m = 0;
+            for a in annotations:
+                if a.key.startswith('org.gtk.GDBus'):
+                    continue
+                self.c.write('  &%s_%d,\n'%(prefix, m))
+                m += 1
+            self.c.write('  NULL\n'
+                         '};\n'
+                         '\n')
+        return n
+
+    def generate_args(self, prefix, args):
+        for a in args:
+            num_anno = self.generate_annotations('%s_arg_%s_annotation_info'%(prefix, a.name), a.annotations)
+
+            self.c.write('static const GDBusArgInfo %s_%s =\n'
+                         '{\n'
+                         '  -1,\n'
+                         '  "%s",\n'
+                         '  "%s",\n'%(prefix, a.name_lower, a.name, a.signature))
+            if num_anno == 0:
+                self.c.write('  NULL\n')
+            else:
+                self.c.write('  (GDBusAnnotationInfo **) &%s_arg_%s_annotation_info_pointers\n'%(prefix, a.name))
+            self.c.write('};\n'
+                         '\n')
+
+        if len(args) > 0:
+            self.c.write('static const GDBusArgInfo * const %s_pointers[] =\n'
+                             '{\n'%(prefix))
+            for a in args:
+                self.c.write('  &%s_%s,\n'%(prefix, a.name_lower))
+            self.c.write('  NULL\n'
+                         '};\n'
+                         '\n')
+
+    def generate_introspection_for_interface(self, i):
+            if len(i.methods) > 0:
+                for m in i.methods:
+                    self.generate_args('%s_method_info_%s_IN_ARG'%(self.namespace, m.name_lower), m.in_args)
+                    self.generate_args('%s_method_info_%s_OUT_ARG'%(self.namespace, m.name_lower), m.out_args)
+
+                    num_anno = self.generate_annotations('%s_method_%s_annotation_info'%(self.namespace, m.name_lower), m.annotations)
+
+                    self.c.write('static const GDBusMethodInfo %s_method_info_%s =\n'
+                                 '{\n'
+                                 '  -1,\n'
+                                 '  "%s",\n'%(self.namespace, m.name_lower, m.name))
+                    if len(m.in_args) == 0:
+                        self.c.write('  NULL,\n')
+                    else:
+                        self.c.write('  (GDBusArgInfo **) &%s_method_info_%s_IN_ARG_pointers,\n'%(self.namespace, m.name_lower))
+                    if len(m.out_args) == 0:
+                        self.c.write('  NULL,\n')
+                    else:
+                        self.c.write('  (GDBusArgInfo **) &%s_method_info_%s_OUT_ARG_pointers,\n'%(self.namespace, m.name_lower))
+                    if num_anno == 0:
+                        self.c.write('  NULL\n')
+                    else:
+                        self.c.write('  (GDBusAnnotationInfo **) &%s_method_%s_annotation_info_pointers\n'%(self.namespace, m.name_lower))
+                    self.c.write('};\n'
+                                 '\n')
+
+                self.c.write('static const GDBusMethodInfo * const %s_method_info_pointers[] =\n'
+                             '{\n'%(self.namespace))
+                for m in i.methods:
+                    self.c.write('  &%s_method_info_%s,\n'%(self.namespace, m.name_lower))
+                self.c.write('  NULL\n'
+                             '};\n'
+                             '\n')
+
+            if len(i.signals) > 0:
+                for s in i.signals:
+                    self.generate_args('%s_signal_info_%s_ARG'%(self.namespace, s.name_lower), s.args)
+
+                    num_anno = self.generate_annotations('%s_signal_%s_annotation_info'%(self.namespace, s.name_lower), s.annotations)
+                    self.c.write('static const GDBusSignalInfo %s_signal_info_%s =\n'
+                                 '{\n'
+                                 '  -1,\n'
+                                 '  "%s",\n'%(self.namespace, s.name_lower, s.name))
+                    if len(s.args) == 0:
+                        self.c.write('  NULL,\n')
+                    else:
+                        self.c.write('  (GDBusArgInfo **) &%s_signal_info_%s_ARG_pointers,\n'%(self.namespace, s.name_lower))
+                    if num_anno == 0:
+                        self.c.write('  NULL\n')
+                    else:
+                        self.c.write('  (GDBusAnnotationInfo **) &%s_signal_%s_annotation_info_pointers\n'%(self.namespace, s.name_lower))
+                    self.c.write('};\n'
+                                 '\n')
+
+                self.c.write('static const GDBusSignalInfo * const %s_signal_info_pointers[] =\n'
+                             '{\n'%(self.namespace))
+                for s in i.signals:
+                    self.c.write('  &%s_signal_info_%s,\n'%(self.namespace, s.name_lower))
+                self.c.write('  NULL\n'
+                             '};\n'
+                             '\n')
+
+            if len(i.properties) > 0:
+                for p in i.properties:
+                    if p.readable and p.writable:
+                        access = 'G_DBUS_PROPERTY_INFO_FLAGS_READABLE | G_DBUS_PROPERTY_INFO_FLAGS_WRITABLE'
+                    elif p.readable:
+                        access = 'G_DBUS_PROPERTY_INFO_FLAGS_READABLE'
+                    elif p.writable:
+                        access = 'G_DBUS_PROPERTY_INFO_FLAGS_WRITABLE'
+                    else:
+                        access = 'G_DBUS_PROPERTY_INFO_FLAGS_NONE'
+                    num_anno = self.generate_annotations('%s_property_%s_annotation_info'%(self.namespace, p.name_lower), p.annotations)
+                    self.c.write('static const GDBusPropertyInfo %s_property_info_%s =\n'
+                                 '{\n'
+                                 '  -1,\n'
+                                 '  "%s",\n'
+                                 '  "%s",\n'
+                                 '  %s,\n'%(self.namespace, p.name_lower, p.name, p.arg.signature, access))
+                    if num_anno == 0:
+                        self.c.write('  NULL\n')
+                    else:
+                        self.c.write('  (GDBusAnnotationInfo **) &%s_property_%s_annotation_info_pointers\n'%(self.namespace, p.name_lower))
+                    self.c.write('};\n'
+                                 '\n')
+
+                self.c.write('static const GDBusPropertyInfo * const %s_property_info_pointers[] =\n'
+                             '{\n'%(self.namespace))
+                for p in i.properties:
+                    self.c.write('  &%s_property_info_%s,\n'%(self.namespace, p.name_lower))
+                self.c.write('  NULL\n'
+                             '};\n'



More information about the Commits mailing list