Blame telepathy-account-widgets/tools/glib-ginterface-gen.py

Packit Service c6b9b0
#!/usr/bin/python
Packit Service c6b9b0
Packit Service c6b9b0
# glib-ginterface-gen.py: service-side interface generator
Packit Service c6b9b0
#
Packit Service c6b9b0
# Generate dbus-glib 0.x service GInterfaces from the Telepathy specification.
Packit Service c6b9b0
# The master copy of this program is in the telepathy-glib repository -
Packit Service c6b9b0
# please make any changes there.
Packit Service c6b9b0
#
Packit Service c6b9b0
# Copyright (C) 2006, 2007 Collabora Limited
Packit Service c6b9b0
#
Packit Service c6b9b0
# This library is free software; you can redistribute it and/or
Packit Service c6b9b0
# modify it under the terms of the GNU Lesser General Public
Packit Service c6b9b0
# License as published by the Free Software Foundation; either
Packit Service c6b9b0
# version 2.1 of the License, or (at your option) any later version.
Packit Service c6b9b0
#
Packit Service c6b9b0
# This library is distributed in the hope that it will be useful,
Packit Service c6b9b0
# but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service c6b9b0
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit Service c6b9b0
# Lesser General Public License for more details.
Packit Service c6b9b0
#
Packit Service c6b9b0
# You should have received a copy of the GNU Lesser General Public
Packit Service c6b9b0
# License along with this library; if not, write to the Free Software
Packit Service c6b9b0
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
Packit Service c6b9b0
Packit Service c6b9b0
import sys
Packit Service c6b9b0
import os.path
Packit Service c6b9b0
import xml.dom.minidom
Packit Service c6b9b0
Packit Service c6b9b0
from libtpcodegen import file_set_contents, key_by_name, u
Packit Service c6b9b0
from libglibcodegen import Signature, type_to_gtype, \
Packit Service c6b9b0
        NS_TP, dbus_gutils_wincaps_to_uscore
Packit Service c6b9b0
Packit Service c6b9b0
Packit Service c6b9b0
NS_TP = "http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0"
Packit Service c6b9b0
Packit Service c6b9b0
def get_emits_changed(node):
Packit Service c6b9b0
    try:
Packit Service c6b9b0
        return [
Packit Service c6b9b0
            annotation.getAttribute('value')
Packit Service c6b9b0
            for annotation in node.getElementsByTagName('annotation')
Packit Service c6b9b0
            if annotation.getAttribute('name') == 'org.freedesktop.DBus.Property.EmitsChangedSignal'
Packit Service c6b9b0
            ][0]
Packit Service c6b9b0
    except IndexError:
Packit Service c6b9b0
        return None
Packit Service c6b9b0
Packit Service c6b9b0
class Generator(object):
Packit Service c6b9b0
Packit Service c6b9b0
    def __init__(self, dom, prefix, basename, signal_marshal_prefix,
Packit Service c6b9b0
                 headers, end_headers, not_implemented_func,
Packit Service c6b9b0
                 allow_havoc):
Packit Service c6b9b0
        self.dom = dom
Packit Service c6b9b0
        self.__header = []
Packit Service c6b9b0
        self.__body = []
Packit Service c6b9b0
        self.__docs = []
Packit Service c6b9b0
Packit Service c6b9b0
        assert prefix.endswith('_')
Packit Service c6b9b0
        assert not signal_marshal_prefix.endswith('_')
Packit Service c6b9b0
Packit Service c6b9b0
        # The main_prefix, sub_prefix thing is to get:
Packit Service c6b9b0
        # FOO_ -> (FOO_, _)
Packit Service c6b9b0
        # FOO_SVC_ -> (FOO_, _SVC_)
Packit Service c6b9b0
        # but
Packit Service c6b9b0
        # FOO_BAR/ -> (FOO_BAR_, _)
Packit Service c6b9b0
        # FOO_BAR/SVC_ -> (FOO_BAR_, _SVC_)
Packit Service c6b9b0
Packit Service c6b9b0
        if '/' in prefix:
Packit Service c6b9b0
            main_prefix, sub_prefix = prefix.upper().split('/', 1)
Packit Service c6b9b0
            prefix = prefix.replace('/', '_')
Packit Service c6b9b0
        else:
Packit Service c6b9b0
            main_prefix, sub_prefix = prefix.upper().split('_', 1)
Packit Service c6b9b0
Packit Service c6b9b0
        self.MAIN_PREFIX_ = main_prefix + '_'
Packit Service c6b9b0
        self._SUB_PREFIX_ = '_' + sub_prefix
Packit Service c6b9b0
Packit Service c6b9b0
        self.Prefix_ = prefix
Packit Service c6b9b0
        self.Prefix = prefix.replace('_', '')
Packit Service c6b9b0
        self.prefix_ = prefix.lower()
Packit Service c6b9b0
        self.PREFIX_ = prefix.upper()
Packit Service c6b9b0
Packit Service c6b9b0
        self.basename = basename
Packit Service c6b9b0
        self.signal_marshal_prefix = signal_marshal_prefix
Packit Service c6b9b0
        self.headers = headers
Packit Service c6b9b0
        self.end_headers = end_headers
Packit Service c6b9b0
        self.not_implemented_func = not_implemented_func
Packit Service c6b9b0
        self.allow_havoc = allow_havoc
Packit Service c6b9b0
Packit Service c6b9b0
    def h(self, s):
Packit Service c6b9b0
        self.__header.append(s)
Packit Service c6b9b0
Packit Service c6b9b0
    def b(self, s):
Packit Service c6b9b0
        self.__body.append(s)
Packit Service c6b9b0
Packit Service c6b9b0
    def d(self, s):
Packit Service c6b9b0
        self.__docs.append(s)
Packit Service c6b9b0
Packit Service c6b9b0
    def do_node(self, node):
Packit Service c6b9b0
        node_name = node.getAttribute('name').replace('/', '')
Packit Service c6b9b0
        node_name_mixed = self.node_name_mixed = node_name.replace('_', '')
Packit Service c6b9b0
        node_name_lc = self.node_name_lc = node_name.lower()
Packit Service c6b9b0
        node_name_uc = self.node_name_uc = node_name.upper()
Packit Service c6b9b0
Packit Service c6b9b0
        interfaces = node.getElementsByTagName('interface')
Packit Service c6b9b0
        assert len(interfaces) == 1, interfaces
Packit Service c6b9b0
        interface = interfaces[0]
Packit Service c6b9b0
        self.iface_name = interface.getAttribute('name')
Packit Service c6b9b0
Packit Service c6b9b0
        tmp = interface.getAttribute('tp:implement-service')
Packit Service c6b9b0
        if tmp == "no":
Packit Service c6b9b0
            return
Packit Service c6b9b0
Packit Service c6b9b0
        tmp = interface.getAttribute('tp:causes-havoc')
Packit Service c6b9b0
        if tmp and not self.allow_havoc:
Packit Service c6b9b0
            raise AssertionError('%s is %s' % (self.iface_name, tmp))
Packit Service c6b9b0
Packit Service c6b9b0
        iface_emits_changed = get_emits_changed(interface)
Packit Service c6b9b0
Packit Service c6b9b0
        self.b('static const DBusGObjectInfo _%s%s_object_info;'
Packit Service c6b9b0
               % (self.prefix_, node_name_lc))
Packit Service c6b9b0
        self.b('')
Packit Service c6b9b0
Packit Service c6b9b0
        methods = interface.getElementsByTagName('method')
Packit Service c6b9b0
        signals = interface.getElementsByTagName('signal')
Packit Service c6b9b0
        properties = interface.getElementsByTagName('property')
Packit Service c6b9b0
        # Don't put properties in dbus-glib glue
Packit Service c6b9b0
        glue_properties = []
Packit Service c6b9b0
Packit Service c6b9b0
        self.b('struct _%s%sClass {' % (self.Prefix, node_name_mixed))
Packit Service c6b9b0
        self.b('    GTypeInterface parent_class;')
Packit Service c6b9b0
        for method in methods:
Packit Service c6b9b0
            self.b('    %s %s;' % self.get_method_impl_names(method))
Packit Service c6b9b0
        self.b('};')
Packit Service c6b9b0
        self.b('')
Packit Service c6b9b0
Packit Service c6b9b0
        if signals:
Packit Service c6b9b0
            self.b('enum {')
Packit Service c6b9b0
            for signal in signals:
Packit Service c6b9b0
                self.b('    %s,' % self.get_signal_const_entry(signal))
Packit Service c6b9b0
            self.b('    N_%s_SIGNALS' % node_name_uc)
Packit Service c6b9b0
            self.b('};')
Packit Service c6b9b0
            self.b('static guint %s_signals[N_%s_SIGNALS] = {0};'
Packit Service c6b9b0
                   % (node_name_lc, node_name_uc))
Packit Service c6b9b0
            self.b('')
Packit Service c6b9b0
Packit Service c6b9b0
        self.b('static void %s%s_base_init (gpointer klass);'
Packit Service c6b9b0
               % (self.prefix_, node_name_lc))
Packit Service c6b9b0
        self.b('')
Packit Service c6b9b0
Packit Service c6b9b0
        self.b('GType')
Packit Service c6b9b0
        self.b('%s%s_get_type (void)'
Packit Service c6b9b0
               % (self.prefix_, node_name_lc))
Packit Service c6b9b0
        self.b('{')
Packit Service c6b9b0
        self.b('  static GType type = 0;')
Packit Service c6b9b0
        self.b('')
Packit Service c6b9b0
        self.b('  if (G_UNLIKELY (type == 0))')
Packit Service c6b9b0
        self.b('    {')
Packit Service c6b9b0
        self.b('      static const GTypeInfo info = {')
Packit Service c6b9b0
        self.b('        sizeof (%s%sClass),' % (self.Prefix, node_name_mixed))
Packit Service c6b9b0
        self.b('        %s%s_base_init, /* base_init */'
Packit Service c6b9b0
               % (self.prefix_, node_name_lc))
Packit Service c6b9b0
        self.b('        NULL, /* base_finalize */')
Packit Service c6b9b0
        self.b('        NULL, /* class_init */')
Packit Service c6b9b0
        self.b('        NULL, /* class_finalize */')
Packit Service c6b9b0
        self.b('        NULL, /* class_data */')
Packit Service c6b9b0
        self.b('        0,')
Packit Service c6b9b0
        self.b('        0, /* n_preallocs */')
Packit Service c6b9b0
        self.b('        NULL /* instance_init */')
Packit Service c6b9b0
        self.b('      };')
Packit Service c6b9b0
        self.b('')
Packit Service c6b9b0
        self.b('      type = g_type_register_static (G_TYPE_INTERFACE,')
Packit Service c6b9b0
        self.b('          "%s%s", &info, 0);' % (self.Prefix, node_name_mixed))
Packit Service c6b9b0
        self.b('    }')
Packit Service c6b9b0
        self.b('')
Packit Service c6b9b0
        self.b('  return type;')
Packit Service c6b9b0
        self.b('}')
Packit Service c6b9b0
        self.b('')
Packit Service c6b9b0
Packit Service c6b9b0
        self.d('/**')
Packit Service c6b9b0
        self.d(' * %s%s:' % (self.Prefix, node_name_mixed))
Packit Service c6b9b0
        self.d(' *')
Packit Service c6b9b0
        self.d(' * Dummy typedef representing any implementation of this '
Packit Service c6b9b0
               'interface.')
Packit Service c6b9b0
        self.d(' */')
Packit Service c6b9b0
Packit Service c6b9b0
        self.h('typedef struct _%s%s %s%s;'
Packit Service c6b9b0
               % (self.Prefix, node_name_mixed, self.Prefix, node_name_mixed))
Packit Service c6b9b0
        self.h('')
Packit Service c6b9b0
Packit Service c6b9b0
        self.d('/**')
Packit Service c6b9b0
        self.d(' * %s%sClass:' % (self.Prefix, node_name_mixed))
Packit Service c6b9b0
        self.d(' *')
Packit Service c6b9b0
        self.d(' * The class of %s%s.' % (self.Prefix, node_name_mixed))
Packit Service c6b9b0
Packit Service c6b9b0
        if methods:
Packit Service c6b9b0
            self.d(' *')
Packit Service c6b9b0
            self.d(' * In a full implementation of this interface (i.e. all')
Packit Service c6b9b0
            self.d(' * methods implemented), the interface initialization')
Packit Service c6b9b0
            self.d(' * function used in G_IMPLEMENT_INTERFACE() would')
Packit Service c6b9b0
            self.d(' * typically look like this:')
Packit Service c6b9b0
            self.d(' *')
Packit Service c6b9b0
            self.d(' * <programlisting>')
Packit Service c6b9b0
            self.d(' * static void')
Packit Service c6b9b0
            self.d(' * implement_%s (gpointer klass,' % self.node_name_lc)
Packit Service c6b9b0
            self.d(' *     gpointer unused G_GNUC_UNUSED)')
Packit Service c6b9b0
            self.d(' * {')
Packit Service c6b9b0
            self.d(' * #define IMPLEMENT(x) %s%s_implement_##x (\\'
Packit Service c6b9b0
                   % (self.prefix_, self.node_name_lc))
Packit Service c6b9b0
            self.d(' *   klass, my_object_##x)')
Packit Service c6b9b0
Packit Service c6b9b0
            for method in methods:
Packit Service c6b9b0
                class_member_name = method.getAttribute('tp:name-for-bindings')
Packit Service c6b9b0
                class_member_name = class_member_name.lower()
Packit Service c6b9b0
                self.d(' *   IMPLEMENT (%s);' % class_member_name)
Packit Service c6b9b0
Packit Service c6b9b0
            self.d(' * #undef IMPLEMENT')
Packit Service c6b9b0
            self.d(' * }')
Packit Service c6b9b0
            self.d(' * </programlisting>')
Packit Service c6b9b0
        else:
Packit Service c6b9b0
            self.d(' * This interface has no D-Bus methods, so an')
Packit Service c6b9b0
            self.d(' * implementation can typically pass %NULL to')
Packit Service c6b9b0
            self.d(' * G_IMPLEMENT_INTERFACE() as the interface')
Packit Service c6b9b0
            self.d(' * initialization function.')
Packit Service c6b9b0
Packit Service c6b9b0
        self.d(' */')
Packit Service c6b9b0
        self.d('')
Packit Service c6b9b0
Packit Service c6b9b0
        self.h('typedef struct _%s%sClass %s%sClass;'
Packit Service c6b9b0
               % (self.Prefix, node_name_mixed, self.Prefix, node_name_mixed))
Packit Service c6b9b0
        self.h('')
Packit Service c6b9b0
        self.h('GType %s%s_get_type (void);'
Packit Service c6b9b0
               % (self.prefix_, node_name_lc))
Packit Service c6b9b0
Packit Service c6b9b0
        gtype = self.current_gtype = \
Packit Service c6b9b0
                self.MAIN_PREFIX_ + 'TYPE' + self._SUB_PREFIX_ + node_name_uc
Packit Service c6b9b0
        classname = self.Prefix + node_name_mixed
Packit Service c6b9b0
Packit Service c6b9b0
        self.h('#define %s \\\n  (%s%s_get_type ())'
Packit Service c6b9b0
               % (gtype, self.prefix_, node_name_lc))
Packit Service c6b9b0
        self.h('#define %s%s(obj) \\\n'
Packit Service c6b9b0
               '  (G_TYPE_CHECK_INSTANCE_CAST((obj), %s, %s))'
Packit Service c6b9b0
               % (self.PREFIX_, node_name_uc, gtype, classname))
Packit Service c6b9b0
        self.h('#define %sIS%s%s(obj) \\\n'
Packit Service c6b9b0
               '  (G_TYPE_CHECK_INSTANCE_TYPE((obj), %s))'
Packit Service c6b9b0
               % (self.MAIN_PREFIX_, self._SUB_PREFIX_, node_name_uc, gtype))
Packit Service c6b9b0
        self.h('#define %s%s_GET_CLASS(obj) \\\n'
Packit Service c6b9b0
               '  (G_TYPE_INSTANCE_GET_INTERFACE((obj), %s, %sClass))'
Packit Service c6b9b0
               % (self.PREFIX_, node_name_uc, gtype, classname))
Packit Service c6b9b0
        self.h('')
Packit Service c6b9b0
        self.h('')
Packit Service c6b9b0
Packit Service c6b9b0
        base_init_code = []
Packit Service c6b9b0
Packit Service c6b9b0
        for method in methods:
Packit Service c6b9b0
            self.do_method(method)
Packit Service c6b9b0
Packit Service c6b9b0
        for signal in signals:
Packit Service c6b9b0
            base_init_code.extend(self.do_signal(signal))
Packit Service c6b9b0
Packit Service c6b9b0
        self.b('static inline void')
Packit Service c6b9b0
        self.b('%s%s_base_init_once (gpointer klass G_GNUC_UNUSED)'
Packit Service c6b9b0
               % (self.prefix_, node_name_lc))
Packit Service c6b9b0
        self.b('{')
Packit Service c6b9b0
Packit Service c6b9b0
        if properties:
Packit Service c6b9b0
            self.b('  static TpDBusPropertiesMixinPropInfo properties[%d] = {'
Packit Service c6b9b0
                   % (len(properties) + 1))
Packit Service c6b9b0
Packit Service c6b9b0
            for m in properties:
Packit Service c6b9b0
                access = m.getAttribute('access')
Packit Service c6b9b0
                assert access in ('read', 'write', 'readwrite')
Packit Service c6b9b0
Packit Service c6b9b0
                if access == 'read':
Packit Service c6b9b0
                    flags = 'TP_DBUS_PROPERTIES_MIXIN_FLAG_READ'
Packit Service c6b9b0
                elif access == 'write':
Packit Service c6b9b0
                    flags = 'TP_DBUS_PROPERTIES_MIXIN_FLAG_WRITE'
Packit Service c6b9b0
                else:
Packit Service c6b9b0
                    flags = ('TP_DBUS_PROPERTIES_MIXIN_FLAG_READ | '
Packit Service c6b9b0
                             'TP_DBUS_PROPERTIES_MIXIN_FLAG_WRITE')
Packit Service c6b9b0
Packit Service c6b9b0
                prop_emits_changed = get_emits_changed(m)
Packit Service c6b9b0
Packit Service c6b9b0
                if prop_emits_changed is None:
Packit Service c6b9b0
                    prop_emits_changed = iface_emits_changed
Packit Service c6b9b0
Packit Service c6b9b0
                if prop_emits_changed == 'true':
Packit Service c6b9b0
                    flags += ' | TP_DBUS_PROPERTIES_MIXIN_FLAG_EMITS_CHANGED'
Packit Service c6b9b0
                elif prop_emits_changed == 'invalidates':
Packit Service c6b9b0
                    flags += ' | TP_DBUS_PROPERTIES_MIXIN_FLAG_EMITS_INVALIDATED'
Packit Service c6b9b0
Packit Service c6b9b0
                self.b('      { 0, %s, "%s", 0, NULL, NULL }, /* %s */'
Packit Service c6b9b0
                       % (flags, m.getAttribute('type'), m.getAttribute('name')))
Packit Service c6b9b0
Packit Service c6b9b0
            self.b('      { 0, 0, NULL, 0, NULL, NULL }')
Packit Service c6b9b0
            self.b('  };')
Packit Service c6b9b0
            self.b('  static TpDBusPropertiesMixinIfaceInfo interface =')
Packit Service c6b9b0
            self.b('      { 0, properties, NULL, NULL };')
Packit Service c6b9b0
            self.b('')
Packit Service c6b9b0
Packit Service c6b9b0
Packit Service c6b9b0
        self.b('  dbus_g_object_type_install_info (%s%s_get_type (),'
Packit Service c6b9b0
               % (self.prefix_, node_name_lc))
Packit Service c6b9b0
        self.b('      &_%s%s_object_info);'
Packit Service c6b9b0
               % (self.prefix_, node_name_lc))
Packit Service c6b9b0
        self.b('')
Packit Service c6b9b0
Packit Service c6b9b0
        if properties:
Packit Service c6b9b0
            self.b('  interface.dbus_interface = g_quark_from_static_string '
Packit Service c6b9b0
                   '("%s");' % self.iface_name)
Packit Service c6b9b0
Packit Service c6b9b0
            for i, m in enumerate(properties):
Packit Service c6b9b0
                self.b('  properties[%d].name = g_quark_from_static_string ("%s");'
Packit Service c6b9b0
                       % (i, m.getAttribute('name')))
Packit Service c6b9b0
                self.b('  properties[%d].type = %s;'
Packit Service c6b9b0
                           % (i, type_to_gtype(m.getAttribute('type'))[1]))
Packit Service c6b9b0
Packit Service c6b9b0
            self.b('  tp_svc_interface_set_dbus_properties_info (%s, &interface);'
Packit Service c6b9b0
                   % self.current_gtype)
Packit Service c6b9b0
Packit Service c6b9b0
            self.b('')
Packit Service c6b9b0
Packit Service c6b9b0
        for s in base_init_code:
Packit Service c6b9b0
            self.b(s)
Packit Service c6b9b0
        self.b('}')
Packit Service c6b9b0
Packit Service c6b9b0
        self.b('static void')
Packit Service c6b9b0
        self.b('%s%s_base_init (gpointer klass)'
Packit Service c6b9b0
               % (self.prefix_, node_name_lc))
Packit Service c6b9b0
        self.b('{')
Packit Service c6b9b0
        self.b('  static gboolean initialized = FALSE;')
Packit Service c6b9b0
        self.b('')
Packit Service c6b9b0
        self.b('  if (!initialized)')
Packit Service c6b9b0
        self.b('    {')
Packit Service c6b9b0
        self.b('      initialized = TRUE;')
Packit Service c6b9b0
        self.b('      %s%s_base_init_once (klass);'
Packit Service c6b9b0
               % (self.prefix_, node_name_lc))
Packit Service c6b9b0
        self.b('    }')
Packit Service c6b9b0
        # insert anything we need to do per implementation here
Packit Service c6b9b0
        self.b('}')
Packit Service c6b9b0
Packit Service c6b9b0
        self.h('')
Packit Service c6b9b0
Packit Service c6b9b0
        self.b('static const DBusGMethodInfo _%s%s_methods[] = {'
Packit Service c6b9b0
               % (self.prefix_, node_name_lc))
Packit Service c6b9b0
Packit Service c6b9b0
        method_blob, offsets = self.get_method_glue(methods)
Packit Service c6b9b0
Packit Service c6b9b0
        for method, offset in zip(methods, offsets):
Packit Service c6b9b0
            self.do_method_glue(method, offset)
Packit Service c6b9b0
Packit Service c6b9b0
        if len(methods) == 0:
Packit Service c6b9b0
            # empty arrays are a gcc extension, so put in a dummy member
Packit Service c6b9b0
            self.b("  { NULL, NULL, 0 }")
Packit Service c6b9b0
Packit Service c6b9b0
        self.b('};')
Packit Service c6b9b0
        self.b('')
Packit Service c6b9b0
Packit Service c6b9b0
        self.b('static const DBusGObjectInfo _%s%s_object_info = {'
Packit Service c6b9b0
               % (self.prefix_, node_name_lc))
Packit Service c6b9b0
        self.b('  0,')  # version
Packit Service c6b9b0
        self.b('  _%s%s_methods,' % (self.prefix_, node_name_lc))
Packit Service c6b9b0
        self.b('  %d,' % len(methods))
Packit Service c6b9b0
        self.b('"' + method_blob.replace('\0', '\\0') + '",')
Packit Service c6b9b0
        self.b('"' + self.get_signal_glue(signals).replace('\0', '\\0') + '",')
Packit Service c6b9b0
        self.b('"' +
Packit Service c6b9b0
               self.get_property_glue(glue_properties).replace('\0', '\\0') +
Packit Service c6b9b0
               '",')
Packit Service c6b9b0
        self.b('};')
Packit Service c6b9b0
        self.b('')
Packit Service c6b9b0
Packit Service c6b9b0
        self.node_name_mixed = None
Packit Service c6b9b0
        self.node_name_lc = None
Packit Service c6b9b0
        self.node_name_uc = None
Packit Service c6b9b0
Packit Service c6b9b0
    def get_method_glue(self, methods):
Packit Service c6b9b0
        info = []
Packit Service c6b9b0
        offsets = []
Packit Service c6b9b0
Packit Service c6b9b0
        for method in methods:
Packit Service c6b9b0
            offsets.append(len(''.join(info)))
Packit Service c6b9b0
Packit Service c6b9b0
            info.append(self.iface_name + '\0')
Packit Service c6b9b0
            info.append(method.getAttribute('name') + '\0')
Packit Service c6b9b0
Packit Service c6b9b0
            info.append('A\0')    # async
Packit Service c6b9b0
Packit Service c6b9b0
            counter = 0
Packit Service c6b9b0
            for arg in method.getElementsByTagName('arg'):
Packit Service c6b9b0
                out = arg.getAttribute('direction') == 'out'
Packit Service c6b9b0
Packit Service c6b9b0
                name = arg.getAttribute('name')
Packit Service c6b9b0
                if not name:
Packit Service c6b9b0
                    assert out
Packit Service c6b9b0
                    name = 'arg%u' % counter
Packit Service c6b9b0
                counter += 1
Packit Service c6b9b0
Packit Service c6b9b0
                info.append(name + '\0')
Packit Service c6b9b0
Packit Service c6b9b0
                if out:
Packit Service c6b9b0
                    info.append('O\0')
Packit Service c6b9b0
                else:
Packit Service c6b9b0
                    info.append('I\0')
Packit Service c6b9b0
Packit Service c6b9b0
                if out:
Packit Service c6b9b0
                    info.append('F\0')    # not const
Packit Service c6b9b0
                    info.append('N\0')    # not error or return
Packit Service c6b9b0
                info.append(arg.getAttribute('type') + '\0')
Packit Service c6b9b0
Packit Service c6b9b0
            info.append('\0')
Packit Service c6b9b0
Packit Service c6b9b0
        return ''.join(info) + '\0', offsets
Packit Service c6b9b0
Packit Service c6b9b0
    def do_method_glue(self, method, offset):
Packit Service c6b9b0
        lc_name = method.getAttribute('tp:name-for-bindings')
Packit Service c6b9b0
        if method.getAttribute('name') != lc_name.replace('_', ''):
Packit Service c6b9b0
            raise AssertionError('Method %s tp:name-for-bindings (%s) does '
Packit Service c6b9b0
                    'not match' % (method.getAttribute('name'), lc_name))
Packit Service c6b9b0
        lc_name = lc_name.lower()
Packit Service c6b9b0
Packit Service c6b9b0
        marshaller = 'g_cclosure_marshal_generic'
Packit Service c6b9b0
        wrapper = self.prefix_ + self.node_name_lc + '_' + lc_name
Packit Service c6b9b0
Packit Service c6b9b0
        self.b("  { (GCallback) %s, %s, %d }," % (wrapper, marshaller, offset))
Packit Service c6b9b0
Packit Service c6b9b0
    def get_signal_glue(self, signals):
Packit Service c6b9b0
        info = []
Packit Service c6b9b0
Packit Service c6b9b0
        for signal in signals:
Packit Service c6b9b0
            info.append(self.iface_name)
Packit Service c6b9b0
            info.append(signal.getAttribute('name'))
Packit Service c6b9b0
Packit Service c6b9b0
        return '\0'.join(info) + '\0\0'
Packit Service c6b9b0
Packit Service c6b9b0
    # the implementation can be the same
Packit Service c6b9b0
    get_property_glue = get_signal_glue
Packit Service c6b9b0
Packit Service c6b9b0
    def get_method_impl_names(self, method):
Packit Service c6b9b0
        dbus_method_name = method.getAttribute('name')
Packit Service c6b9b0
Packit Service c6b9b0
        class_member_name = method.getAttribute('tp:name-for-bindings')
Packit Service c6b9b0
        if dbus_method_name != class_member_name.replace('_', ''):
Packit Service c6b9b0
            raise AssertionError('Method %s tp:name-for-bindings (%s) does '
Packit Service c6b9b0
                    'not match' % (dbus_method_name, class_member_name))
Packit Service c6b9b0
        class_member_name = class_member_name.lower()
Packit Service c6b9b0
Packit Service c6b9b0
        stub_name = (self.prefix_ + self.node_name_lc + '_' +
Packit Service c6b9b0
                     class_member_name)
Packit Service c6b9b0
        return (stub_name + '_impl', class_member_name + '_cb')
Packit Service c6b9b0
Packit Service c6b9b0
    def do_method(self, method):
Packit Service c6b9b0
        assert self.node_name_mixed is not None
Packit Service c6b9b0
Packit Service c6b9b0
        in_class = []
Packit Service c6b9b0
Packit Service c6b9b0
        # Examples refer to Thing.DoStuff (su) -> ii
Packit Service c6b9b0
Packit Service c6b9b0
        # DoStuff
Packit Service c6b9b0
        dbus_method_name = method.getAttribute('name')
Packit Service c6b9b0
        # do_stuff
Packit Service c6b9b0
        class_member_name = method.getAttribute('tp:name-for-bindings')
Packit Service c6b9b0
        if dbus_method_name != class_member_name.replace('_', ''):
Packit Service c6b9b0
            raise AssertionError('Method %s tp:name-for-bindings (%s) does '
Packit Service c6b9b0
                    'not match' % (dbus_method_name, class_member_name))
Packit Service c6b9b0
        class_member_name = class_member_name.lower()
Packit Service c6b9b0
Packit Service c6b9b0
        # void tp_svc_thing_do_stuff (TpSvcThing *, const char *, guint,
Packit Service c6b9b0
        #   DBusGMethodInvocation *);
Packit Service c6b9b0
        stub_name = (self.prefix_ + self.node_name_lc + '_' +
Packit Service c6b9b0
                     class_member_name)
Packit Service c6b9b0
        # typedef void (*tp_svc_thing_do_stuff_impl) (TpSvcThing *,
Packit Service c6b9b0
        #   const char *, guint, DBusGMethodInvocation);
Packit Service c6b9b0
        impl_name = stub_name + '_impl'
Packit Service c6b9b0
        # void tp_svc_thing_return_from_do_stuff (DBusGMethodInvocation *,
Packit Service c6b9b0
        #   gint, gint);
Packit Service c6b9b0
        ret_name = (self.prefix_ + self.node_name_lc + '_return_from_' +
Packit Service c6b9b0
                    class_member_name)
Packit Service c6b9b0
Packit Service c6b9b0
        # Gather arguments
Packit Service c6b9b0
        in_args = []
Packit Service c6b9b0
        out_args = []
Packit Service c6b9b0
        for i in method.getElementsByTagName('arg'):
Packit Service c6b9b0
            name = i.getAttribute('name')
Packit Service c6b9b0
            direction = i.getAttribute('direction') or 'in'
Packit Service c6b9b0
            dtype = i.getAttribute('type')
Packit Service c6b9b0
Packit Service c6b9b0
            assert direction in ('in', 'out')
Packit Service c6b9b0
Packit Service c6b9b0
            if name:
Packit Service c6b9b0
                name = direction + '_' + name
Packit Service c6b9b0
            elif direction == 'in':
Packit Service c6b9b0
                name = direction + str(len(in_args))
Packit Service c6b9b0
            else:
Packit Service c6b9b0
                name = direction + str(len(out_args))
Packit Service c6b9b0
Packit Service c6b9b0
            ctype, gtype, marshaller, pointer = type_to_gtype(dtype)
Packit Service c6b9b0
Packit Service c6b9b0
            if pointer:
Packit Service c6b9b0
                ctype = 'const ' + ctype
Packit Service c6b9b0
Packit Service c6b9b0
            struct = (ctype, name)
Packit Service c6b9b0
Packit Service c6b9b0
            if direction == 'in':
Packit Service c6b9b0
                in_args.append(struct)
Packit Service c6b9b0
            else:
Packit Service c6b9b0
                out_args.append(struct)
Packit Service c6b9b0
Packit Service c6b9b0
        # Implementation type declaration (in header, docs separated)
Packit Service c6b9b0
        self.d('/**')
Packit Service c6b9b0
        self.d(' * %s:' % impl_name)
Packit Service c6b9b0
        self.d(' * @self: The object implementing this interface')
Packit Service c6b9b0
        for (ctype, name) in in_args:
Packit Service c6b9b0
            self.d(' * @%s: %s (FIXME, generate documentation)'
Packit Service c6b9b0
                   % (name, ctype))
Packit Service c6b9b0
        self.d(' * @context: Used to return values or throw an error')
Packit Service c6b9b0
        self.d(' *')
Packit Service c6b9b0
        self.d(' * The signature of an implementation of the D-Bus method')
Packit Service c6b9b0
        self.d(' * %s on interface %s.' % (dbus_method_name, self.iface_name))
Packit Service c6b9b0
        self.d(' */')
Packit Service c6b9b0
Packit Service c6b9b0
        self.h('typedef void (*%s) (%s%s *self,'
Packit Service c6b9b0
          % (impl_name, self.Prefix, self.node_name_mixed))
Packit Service c6b9b0
        for (ctype, name) in in_args:
Packit Service c6b9b0
            self.h('    %s%s,' % (ctype, name))
Packit Service c6b9b0
        self.h('    DBusGMethodInvocation *context);')
Packit Service c6b9b0
Packit Service c6b9b0
        # Class member (in class definition)
Packit Service c6b9b0
        in_class.append('    %s %s;' % (impl_name, class_member_name))
Packit Service c6b9b0
Packit Service c6b9b0
        # Stub definition (in body only - it's static)
Packit Service c6b9b0
        self.b('static void')
Packit Service c6b9b0
        self.b('%s (%s%s *self,'
Packit Service c6b9b0
           % (stub_name, self.Prefix, self.node_name_mixed))
Packit Service c6b9b0
        for (ctype, name) in in_args:
Packit Service c6b9b0
            self.b('    %s%s,' % (ctype, name))
Packit Service c6b9b0
        self.b('    DBusGMethodInvocation *context)')
Packit Service c6b9b0
        self.b('{')
Packit Service c6b9b0
        self.b('  %s impl = (%s%s_GET_CLASS (self)->%s_cb);'
Packit Service c6b9b0
          % (impl_name, self.PREFIX_, self.node_name_uc, class_member_name))
Packit Service c6b9b0
        self.b('')
Packit Service c6b9b0
        self.b('  if (impl != NULL)')
Packit Service c6b9b0
        tmp = ['self'] + [name for (ctype, name) in in_args] + ['context']
Packit Service c6b9b0
        self.b('    {')
Packit Service c6b9b0
        self.b('      (impl) (%s);' % ',\n        '.join(tmp))
Packit Service c6b9b0
        self.b('    }')
Packit Service c6b9b0
        self.b('  else')
Packit Service c6b9b0
        self.b('    {')
Packit Service c6b9b0
        if self.not_implemented_func:
Packit Service c6b9b0
            self.b('      %s (context);' % self.not_implemented_func)
Packit Service c6b9b0
        else:
Packit Service c6b9b0
            self.b('      GError e = { DBUS_GERROR, ')
Packit Service c6b9b0
            self.b('           DBUS_GERROR_UNKNOWN_METHOD,')
Packit Service c6b9b0
            self.b('           "Method not implemented" };')
Packit Service c6b9b0
            self.b('')
Packit Service c6b9b0
            self.b('      dbus_g_method_return_error (context, &e);')
Packit Service c6b9b0
        self.b('    }')
Packit Service c6b9b0
        self.b('}')
Packit Service c6b9b0
        self.b('')
Packit Service c6b9b0
Packit Service c6b9b0
        # Implementation registration (in both header and body)
Packit Service c6b9b0
        self.h('void %s%s_implement_%s (%s%sClass *klass, %s impl);'
Packit Service c6b9b0
               % (self.prefix_, self.node_name_lc, class_member_name,
Packit Service c6b9b0
                  self.Prefix, self.node_name_mixed, impl_name))
Packit Service c6b9b0
Packit Service c6b9b0
        self.d('/**')
Packit Service c6b9b0
        self.d(' * %s%s_implement_%s:'
Packit Service c6b9b0
               % (self.prefix_, self.node_name_lc, class_member_name))
Packit Service c6b9b0
        self.d(' * @klass: A class whose instances implement this interface')
Packit Service c6b9b0
        self.d(' * @impl: A callback used to implement the %s D-Bus method'
Packit Service c6b9b0
               % dbus_method_name)
Packit Service c6b9b0
        self.d(' *')
Packit Service c6b9b0
        self.d(' * Register an implementation for the %s method in the vtable'
Packit Service c6b9b0
               % dbus_method_name)
Packit Service c6b9b0
        self.d(' * of an implementation of this interface. To be called from')
Packit Service c6b9b0
        self.d(' * the interface init function.')
Packit Service c6b9b0
        self.d(' */')
Packit Service c6b9b0
Packit Service c6b9b0
        self.b('void')
Packit Service c6b9b0
        self.b('%s%s_implement_%s (%s%sClass *klass, %s impl)'
Packit Service c6b9b0
               % (self.prefix_, self.node_name_lc, class_member_name,
Packit Service c6b9b0
                  self.Prefix, self.node_name_mixed, impl_name))
Packit Service c6b9b0
        self.b('{')
Packit Service c6b9b0
        self.b('  klass->%s_cb = impl;' % class_member_name)
Packit Service c6b9b0
        self.b('}')
Packit Service c6b9b0
        self.b('')
Packit Service c6b9b0
Packit Service c6b9b0
        # Return convenience function (static inline, in header)
Packit Service c6b9b0
        self.d('/**')
Packit Service c6b9b0
        self.d(' * %s:' % ret_name)
Packit Service c6b9b0
        self.d(' * @context: The D-Bus method invocation context')
Packit Service c6b9b0
        for (ctype, name) in out_args:
Packit Service c6b9b0
            self.d(' * @%s: %s (FIXME, generate documentation)'
Packit Service c6b9b0
                   % (name, ctype))
Packit Service c6b9b0
        self.d(' *')
Packit Service c6b9b0
        self.d(' * Return successfully by calling dbus_g_method_return().')
Packit Service c6b9b0
        self.d(' * This inline function exists only to provide type-safety.')
Packit Service c6b9b0
        self.d(' */')
Packit Service c6b9b0
        self.d('')
Packit Service c6b9b0
Packit Service c6b9b0
        tmp = (['DBusGMethodInvocation *context'] +
Packit Service c6b9b0
               [ctype + name for (ctype, name) in out_args])
Packit Service c6b9b0
        self.h('static inline')
Packit Service c6b9b0
        self.h('/* this comment is to stop gtkdoc realising this is static */')
Packit Service c6b9b0
        self.h(('void %s (' % ret_name) + (',\n    '.join(tmp)) + ');')
Packit Service c6b9b0
        self.h('static inline void')
Packit Service c6b9b0
        self.h(('%s (' % ret_name) + (',\n    '.join(tmp)) + ')')
Packit Service c6b9b0
        self.h('{')
Packit Service c6b9b0
        tmp = ['context'] + [name for (ctype, name) in out_args]
Packit Service c6b9b0
        self.h('  dbus_g_method_return (' + ',\n      '.join(tmp) + ');')
Packit Service c6b9b0
        self.h('}')
Packit Service c6b9b0
        self.h('')
Packit Service c6b9b0
Packit Service c6b9b0
        return in_class
Packit Service c6b9b0
Packit Service c6b9b0
    def get_signal_const_entry(self, signal):
Packit Service c6b9b0
        assert self.node_name_uc is not None
Packit Service c6b9b0
        return ('SIGNAL_%s_%s'
Packit Service c6b9b0
                % (self.node_name_uc, signal.getAttribute('name')))
Packit Service c6b9b0
Packit Service c6b9b0
    def do_signal(self, signal):
Packit Service c6b9b0
        assert self.node_name_mixed is not None
Packit Service c6b9b0
Packit Service c6b9b0
        in_base_init = []
Packit Service c6b9b0
Packit Service c6b9b0
        # for signal: Thing::StuffHappened (s, u)
Packit Service c6b9b0
        # we want to emit:
Packit Service c6b9b0
        # void tp_svc_thing_emit_stuff_happened (gpointer instance,
Packit Service c6b9b0
        #    const char *arg0, guint arg1);
Packit Service c6b9b0
Packit Service c6b9b0
        dbus_name = signal.getAttribute('name')
Packit Service c6b9b0
Packit Service c6b9b0
        ugly_name = signal.getAttribute('tp:name-for-bindings')
Packit Service c6b9b0
        if dbus_name != ugly_name.replace('_', ''):
Packit Service c6b9b0
            raise AssertionError('Signal %s tp:name-for-bindings (%s) does '
Packit Service c6b9b0
                    'not match' % (dbus_name, ugly_name))
Packit Service c6b9b0
Packit Service c6b9b0
        stub_name = (self.prefix_ + self.node_name_lc + '_emit_' +
Packit Service c6b9b0
                     ugly_name.lower())
Packit Service c6b9b0
Packit Service c6b9b0
        const_name = self.get_signal_const_entry(signal)
Packit Service c6b9b0
Packit Service c6b9b0
        # Gather arguments
Packit Service c6b9b0
        args = []
Packit Service c6b9b0
        for i in signal.getElementsByTagName('arg'):
Packit Service c6b9b0
            name = i.getAttribute('name')
Packit Service c6b9b0
            dtype = i.getAttribute('type')
Packit Service c6b9b0
            tp_type = i.getAttribute('tp:type')
Packit Service c6b9b0
Packit Service c6b9b0
            if name:
Packit Service c6b9b0
                name = 'arg_' + name
Packit Service c6b9b0
            else:
Packit Service c6b9b0
                name = 'arg' + str(len(args))
Packit Service c6b9b0
Packit Service c6b9b0
            ctype, gtype, marshaller, pointer = type_to_gtype(dtype)
Packit Service c6b9b0
Packit Service c6b9b0
            if pointer:
Packit Service c6b9b0
                ctype = 'const ' + ctype
Packit Service c6b9b0
Packit Service c6b9b0
            struct = (ctype, name, gtype)
Packit Service c6b9b0
            args.append(struct)
Packit Service c6b9b0
Packit Service c6b9b0
        tmp = (['gpointer instance'] +
Packit Service c6b9b0
               [ctype + name for (ctype, name, gtype) in args])
Packit Service c6b9b0
Packit Service c6b9b0
        self.h(('void %s (' % stub_name) + (',\n    '.join(tmp)) + ');')
Packit Service c6b9b0
Packit Service c6b9b0
        # FIXME: emit docs
Packit Service c6b9b0
Packit Service c6b9b0
        self.d('/**')
Packit Service c6b9b0
        self.d(' * %s:' % stub_name)
Packit Service c6b9b0
        self.d(' * @instance: The object implementing this interface')
Packit Service c6b9b0
        for (ctype, name, gtype) in args:
Packit Service c6b9b0
            self.d(' * @%s: %s (FIXME, generate documentation)'
Packit Service c6b9b0
                   % (name, ctype))
Packit Service c6b9b0
        self.d(' *')
Packit Service c6b9b0
        self.d(' * Type-safe wrapper around g_signal_emit to emit the')
Packit Service c6b9b0
        self.d(' * %s signal on interface %s.'
Packit Service c6b9b0
               % (dbus_name, self.iface_name))
Packit Service c6b9b0
        self.d(' */')
Packit Service c6b9b0
Packit Service c6b9b0
        self.b('void')
Packit Service c6b9b0
        self.b(('%s (' % stub_name) + (',\n    '.join(tmp)) + ')')
Packit Service c6b9b0
        self.b('{')
Packit Service c6b9b0
        self.b('  g_assert (instance != NULL);')
Packit Service c6b9b0
        self.b('  g_assert (G_TYPE_CHECK_INSTANCE_TYPE (instance, %s));'
Packit Service c6b9b0
               % (self.current_gtype))
Packit Service c6b9b0
        tmp = (['instance', '%s_signals[%s]' % (self.node_name_lc, const_name),
Packit Service c6b9b0
                '0'] + [name for (ctype, name, gtype) in args])
Packit Service c6b9b0
        self.b('  g_signal_emit (' + ',\n      '.join(tmp) + ');')
Packit Service c6b9b0
        self.b('}')
Packit Service c6b9b0
        self.b('')
Packit Service c6b9b0
Packit Service c6b9b0
        signal_name = dbus_gutils_wincaps_to_uscore(dbus_name).replace('_',
Packit Service c6b9b0
                '-')
Packit Service c6b9b0
Packit Service c6b9b0
        self.d('/**')
Packit Service c6b9b0
        self.d(' * %s%s::%s:'
Packit Service c6b9b0
                % (self.Prefix, self.node_name_mixed, signal_name))
Packit Service c6b9b0
        self.d(' * @self: an object')
Packit Service c6b9b0
        for (ctype, name, gtype) in args:
Packit Service c6b9b0
            self.d(' * @%s: %s (FIXME, generate documentation)'
Packit Service c6b9b0
                   % (name, ctype))
Packit Service c6b9b0
        self.d(' *')
Packit Service c6b9b0
        self.d(' * The %s D-Bus signal is emitted whenever '
Packit Service c6b9b0
                'this GObject signal is.' % dbus_name)
Packit Service c6b9b0
        self.d(' */')
Packit Service c6b9b0
        self.d('')
Packit Service c6b9b0
Packit Service c6b9b0
        in_base_init.append('  %s_signals[%s] ='
Packit Service c6b9b0
                            % (self.node_name_lc, const_name))
Packit Service c6b9b0
        in_base_init.append('  g_signal_new ("%s",' % signal_name)
Packit Service c6b9b0
        in_base_init.append('      G_OBJECT_CLASS_TYPE (klass),')
Packit Service c6b9b0
        in_base_init.append('      G_SIGNAL_RUN_LAST|G_SIGNAL_DETAILED,')
Packit Service c6b9b0
        in_base_init.append('      0,')
Packit Service c6b9b0
        in_base_init.append('      NULL, NULL,')
Packit Service c6b9b0
        in_base_init.append('      g_cclosure_marshal_generic,')
Packit Service c6b9b0
        in_base_init.append('      G_TYPE_NONE,')
Packit Service c6b9b0
        tmp = ['%d' % len(args)] + [gtype for (ctype, name, gtype) in args]
Packit Service c6b9b0
        in_base_init.append('      %s);' % ',\n      '.join(tmp))
Packit Service c6b9b0
        in_base_init.append('')
Packit Service c6b9b0
Packit Service c6b9b0
        return in_base_init
Packit Service c6b9b0
Packit Service c6b9b0
    def have_properties(self, nodes):
Packit Service c6b9b0
        for node in nodes:
Packit Service c6b9b0
            interface =  node.getElementsByTagName('interface')[0]
Packit Service c6b9b0
            if interface.getElementsByTagName('property'):
Packit Service c6b9b0
                return True
Packit Service c6b9b0
        return False
Packit Service c6b9b0
Packit Service c6b9b0
    def __call__(self):
Packit Service c6b9b0
        nodes = self.dom.getElementsByTagName('node')
Packit Service c6b9b0
        nodes.sort(key=key_by_name)
Packit Service c6b9b0
Packit Service c6b9b0
        self.h('#include <glib-object.h>')
Packit Service c6b9b0
        self.h('#include <dbus/dbus-glib.h>')
Packit Service c6b9b0
Packit Service c6b9b0
        for header in self.headers:
Packit Service c6b9b0
            self.h('#include %s' % header)
Packit Service c6b9b0
        self.h('')
Packit Service c6b9b0
Packit Service c6b9b0
        self.h('')
Packit Service c6b9b0
        self.h('G_BEGIN_DECLS')
Packit Service c6b9b0
        self.h('')
Packit Service c6b9b0
Packit Service c6b9b0
        self.b('#include "%s.h"' % self.basename)
Packit Service c6b9b0
        self.b('')
Packit Service c6b9b0
Packit Service c6b9b0
        for node in nodes:
Packit Service c6b9b0
            self.do_node(node)
Packit Service c6b9b0
Packit Service c6b9b0
        self.h('')
Packit Service c6b9b0
        self.h('G_END_DECLS')
Packit Service c6b9b0
Packit Service c6b9b0
        self.b('')
Packit Service c6b9b0
        for header in self.end_headers:
Packit Service c6b9b0
            self.b('#include %s' % header)
Packit Service c6b9b0
Packit Service c6b9b0
        self.h('')
Packit Service c6b9b0
        self.b('')
Packit Service c6b9b0
        file_set_contents(self.basename + '.h', u('\n').join(self.__header).encode('utf-8'))
Packit Service c6b9b0
        file_set_contents(self.basename + '.c', u('\n').join(self.__body).encode('utf-8'))
Packit Service c6b9b0
        file_set_contents(self.basename + '-gtk-doc.h', u('\n').join(self.__docs).encode('utf-8'))
Packit Service c6b9b0
Packit Service c6b9b0
def cmdline_error():
Packit Service c6b9b0
    print("""\
Packit Service c6b9b0
usage:
Packit Service c6b9b0
    gen-ginterface [OPTIONS] xmlfile Prefix_
Packit Service c6b9b0
options:
Packit Service c6b9b0
    --include='<header.h>' (may be repeated)
Packit Service c6b9b0
    --include='"header.h"' (ditto)
Packit Service c6b9b0
    --include-end='"header.h"' (ditto)
Packit Service c6b9b0
        Include extra headers in the generated .c file
Packit Service c6b9b0
    --signal-marshal-prefix='prefix'
Packit Service c6b9b0
        Use the given prefix on generated signal marshallers (default is
Packit Service c6b9b0
        prefix.lower()).
Packit Service c6b9b0
    --filename='BASENAME'
Packit Service c6b9b0
        Set the basename for the output files (default is prefix.lower()
Packit Service c6b9b0
        + 'ginterfaces')
Packit Service c6b9b0
    --not-implemented-func='symbol'
Packit Service c6b9b0
        Set action when methods not implemented in the interface vtable are
Packit Service c6b9b0
        called. symbol must have signature
Packit Service c6b9b0
            void symbol (DBusGMethodInvocation *context)
Packit Service c6b9b0
        and return some sort of "not implemented" error via
Packit Service c6b9b0
            dbus_g_method_return_error (context, ...)
Packit Service c6b9b0
""")
Packit Service c6b9b0
    sys.exit(1)
Packit Service c6b9b0
Packit Service c6b9b0
Packit Service c6b9b0
if __name__ == '__main__':
Packit Service c6b9b0
    from getopt import gnu_getopt
Packit Service c6b9b0
Packit Service c6b9b0
    options, argv = gnu_getopt(sys.argv[1:], '',
Packit Service c6b9b0
                               ['filename=', 'signal-marshal-prefix=',
Packit Service c6b9b0
                                'include=', 'include-end=',
Packit Service c6b9b0
                                'allow-unstable',
Packit Service c6b9b0
                                'not-implemented-func='])
Packit Service c6b9b0
Packit Service c6b9b0
    try:
Packit Service c6b9b0
        prefix = argv[1]
Packit Service c6b9b0
    except IndexError:
Packit Service c6b9b0
        cmdline_error()
Packit Service c6b9b0
Packit Service c6b9b0
    basename = prefix.lower() + 'ginterfaces'
Packit Service c6b9b0
    signal_marshal_prefix = prefix.lower().rstrip('_')
Packit Service c6b9b0
    headers = []
Packit Service c6b9b0
    end_headers = []
Packit Service c6b9b0
    not_implemented_func = ''
Packit Service c6b9b0
    allow_havoc = False
Packit Service c6b9b0
Packit Service c6b9b0
    for option, value in options:
Packit Service c6b9b0
        if option == '--filename':
Packit Service c6b9b0
            basename = value
Packit Service c6b9b0
        elif option == '--signal-marshal-prefix':
Packit Service c6b9b0
            signal_marshal_prefix = value
Packit Service c6b9b0
        elif option == '--include':
Packit Service c6b9b0
            if value[0] not in '<"':
Packit Service c6b9b0
                value = '"%s"' % value
Packit Service c6b9b0
            headers.append(value)
Packit Service c6b9b0
        elif option == '--include-end':
Packit Service c6b9b0
            if value[0] not in '<"':
Packit Service c6b9b0
                value = '"%s"' % value
Packit Service c6b9b0
            end_headers.append(value)
Packit Service c6b9b0
        elif option == '--not-implemented-func':
Packit Service c6b9b0
            not_implemented_func = value
Packit Service c6b9b0
        elif option == '--allow-unstable':
Packit Service c6b9b0
            allow_havoc = True
Packit Service c6b9b0
Packit Service c6b9b0
    try:
Packit Service c6b9b0
        dom = xml.dom.minidom.parse(argv[0])
Packit Service c6b9b0
    except IndexError:
Packit Service c6b9b0
        cmdline_error()
Packit Service c6b9b0
Packit Service c6b9b0
    Generator(dom, prefix, basename, signal_marshal_prefix, headers,
Packit Service c6b9b0
              end_headers, not_implemented_func, allow_havoc)()