Logo Search packages:      
Sourcecode: libtelepathy version File versions  Download package

libtp-marshaller-gen.py

#!/usr/bin/python

import sys
import xml.dom.minidom
from string import ascii_letters, digits


from libglibcodegen import Signature, type_to_gtype, cmp_by_name


NS_TP = "http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0"

class Generator(object):

    def __init__(self, dom):
        self.dom = dom
        self.macros = []

    def do_signal(self, node_name, iface, signal):
        marshaller_items = []
        gtypes = []

        for i in signal.getElementsByTagName('arg'):
            name = i.getAttribute('name')
            type = i.getAttribute('type')
            info = type_to_gtype(type)
            # type, GType, STRING, is a pointer

            marshaller = info[2]
            if info[1] == 'DBUS_TYPE_G_OBJECT_PATH':
                # should really be BOXED, but libtelepathy has historically
                # used OBJECT, and if we're being pedantic, the marshaller
                # stuff is part of the ABI. The choice doesn't really matter
                # since in the calling convention they're both pointers.
                # FIXME: remove this when libtelepathy merges into tp-glib
                marshaller = 'OBJECT'
            marshaller_items.append(marshaller)

            gtype = info[1]
            if marshaller == 'BOXED':
                # dbus-glib uses the fundamental type anyway, so all BOXED
                # subtypes are equivalent
                gtype = 'G_TYPE_BOXED'
            gtypes.append(gtype)

        prefix = 'tp_ifaces_signals_marshal'

        if (len(marshaller_items) in (0, 1)
            or marshaller_items == ['UINT', 'POINTER']):
            # GLib has built-in marshallers for these
            prefix = 'g_cclosure_marshal'
        elif node_name == '/Connection':
            prefix = 'tp_conn_signals_marshal'
        elif node_name == '/Channel':
            prefix = 'tp_chan_signals_marshal'
        elif node_name == '/Connection_Manager':
            prefix = 'tp_connmgr_signals_marshal'

        print "/* %s: %s */ \\" % (node_name, signal.getAttribute('name'))
        print "dbus_g_object_register_marshaller ( \\"
        print ("    %s_VOID__" % prefix
                + '_'.join((marshaller_items or ['VOID'])) + ', \\')
        print '    G_TYPE_NONE, \\'
        for gtype in gtypes:
            print '    ' + gtype + ', \\'
        print '    G_TYPE_INVALID); \\'

    def __call__(self):
        ifaces = self.dom.getElementsByTagName('node')
        ifaces.sort(cmp_by_name)

        for iface in ifaces:
            self.do_interface(iface)

        print '#define REGISTER_ALL_MARSHALLERS G_STMT_START {\\'
        for macro in self.macros:
            print '%s; \\' % macro
        print '} G_STMT_END'

    def do_interface(self, node):
        ifaces = node.getElementsByTagName('interface')
        assert len(ifaces) == 1
        iface = ifaces[0]
        name = node.getAttribute('name')
        self.macros.append('REGISTER_MARSHALLERS_FOR_%s'
            % name.replace('/', '').upper())
        print ('#define REGISTER_MARSHALLERS_FOR_%s \\'
            % name.replace('/', '').upper())
        print 'G_STMT_START { \\'
        signals = iface.getElementsByTagName('signal')
        signals.sort(cmp_by_name)

        for signal in signals:
            self.do_signal(name, iface, signal)

        print '} G_STMT_END'
        print


def types_to_gtypes(types):
    return [type_to_gtype(t)[1] for t in types]

if __name__ == '__main__':
    argv = sys.argv[1:]
    dom = xml.dom.minidom.parse(argv[0])

    Generator(dom)()

Generated by  Doxygen 1.6.0   Back to index