/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