sbus_codegen revision 66277b21179d95f6e96abed01a20ccbccf27ce99
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson#!/usr/bin/python2
69fe9aaafdd6a141610e86a777d325db75422070Mark Andrews
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews#
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence# Authors:
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson# Stef Walter <stefw@redhat.com>
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson#
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson# Copyright (C) 2014 Red Hat
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence#
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews# This program is free software; you can redistribute it and/or modify
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews# it under the terms of the GNU General Public License as published by
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews# the Free Software Foundation; either version 3 of the License, or
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews# (at your option) any later version.
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews#
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews# This program is distributed in the hope that it will be useful,
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews# but WITHOUT ANY WARRANTY; without even the implied warranty of
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson# GNU General Public License for more details.
261a6a1f7d95eaf0cd882f3123dcfd775517a54fMark Andrews#
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein# You should have received a copy of the GNU General Public License
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein# along with this program. If not, see <http://www.gnu.org/licenses/>.
9c3531d72aeaad6c5f01efe6a1c82023e1379e4dDavid Lawrence#
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson#
593cb00bd17e5e2ab0dcb7c635a9a81082dc5d0eAndreas Gustafsson# Some parser code from GLib
593cb00bd17e5e2ab0dcb7c635a9a81082dc5d0eAndreas Gustafsson#
9aba20edee4e704433a464ae43b070b0775de506Mark Andrews# Copyright (C) 2008-2011 Red Hat, Inc.
3e14b69d196a3ebeecc4662c426344dcfd7db678Andreas Gustafsson#
9aba20edee4e704433a464ae43b070b0775de506Mark Andrews# This library is free software; you can redistribute it and/or
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence# modify it under the terms of the GNU Lesser General Public
16a68807e13caea3183a41a5292f1b3f48b81a26Mark Andrews# License as published by the Free Software Foundation; either
d8e34837cd6c88c42b3ecdb9107a43ecf8252e79David Lawrence# version 2 of the License, or (at your option) any later version.
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence#
9aba20edee4e704433a464ae43b070b0775de506Mark Andrews# This library is distributed in the hope that it will be useful,
261a6a1f7d95eaf0cd882f3123dcfd775517a54fMark Andrews# but WITHOUT ANY WARRANTY; without even the implied warranty of
364a82f7c25b62967678027043425201a5e5171aBob Halley# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson# Lesser General Public License for more details.
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence#
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence# You should have received a copy of the GNU Lesser General
9aba20edee4e704433a464ae43b070b0775de506Mark Andrews# Public License along with this library; if not, write to the
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson# Free Software Foundation, Inc., 59 Temple Place, Suite 330,
261a6a1f7d95eaf0cd882f3123dcfd775517a54fMark Andrews# Boston, MA 02111-1307, USA.
3e14b69d196a3ebeecc4662c426344dcfd7db678Andreas Gustafsson#
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews# Portions by: David Zeuthen <davidz@redhat.com>
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence#
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson
673ce7aebbb6d01c75b95f6df1ec491d6422b951Andreas Gustafsson#
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson# DBus interfaces are defined here:
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson#
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence# http://dbus.freedesktop.org/doc/dbus-specification.html#introspection-format
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence#
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson# The introspection data format has become the standard way to represent a
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson# DBus interface. For many examples see /usr/share/dbus-1/interfaces/ on a
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson# typical linux machine.
9aba20edee4e704433a464ae43b070b0775de506Mark Andrews#
9aba20edee4e704433a464ae43b070b0775de506Mark Andrews# A word about annotations. These are extra flags or values that can be
9aba20edee4e704433a464ae43b070b0775de506Mark Andrews# assigned to anything. So far, the codegen supports this annotation:
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson#
600cfa2ba4c50017581b6c14e3a688a82ecebbe0David Lawrence# org.freedesktop.DBus.GLib.CSymbol
600cfa2ba4c50017581b6c14e3a688a82ecebbe0David Lawrence# - An annotation specified in the specification that tells us what C symbol
600cfa2ba4c50017581b6c14e3a688a82ecebbe0David Lawrence# to generate for a given interface or method. By default the codegen will
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson# build up a symbol name from the DBus name.
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson#
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafssonimport optparse
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafssonimport os
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafssonimport re
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafssonimport StringIO
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafssonimport sys
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafssonimport xml.parsers.expat
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson# -----------------------------------------------------------------------------
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson# Objects
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafssonclass DBusXmlException(Exception):
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence line = 0
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson file = None
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson # Lets us print problems like a compiler would
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson def __str__(self):
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson message = Exception.__str__(self)
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein if self.file and self.line:
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson return "%s:%d: %s" % (self.file, self.line, message)
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson elif self.file:
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson return "%s: %s" % (self.file, message)
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson else:
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson return message
0c8649cea98afc061dd2938fd315df53b8fc35caAndreas Gustafsson
0c8649cea98afc061dd2938fd315df53b8fc35caAndreas Gustafssonclass Base:
0c8649cea98afc061dd2938fd315df53b8fc35caAndreas Gustafsson def __init__(self, name):
692ae2fff922f1c072169d1ddda8e600cb572a9bMark Andrews if not name:
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson raise DBusXmlException('No name on element')
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson self.name = name
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson self.annotations = { }
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson def validate(self):
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson pass
f621719829356f27e831507b75e88e8a655e48d8Danny Mayer def c_name(self):
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson return self.annotations.get("org.freedesktop.DBus.GLib.CSymbol", self.name)
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson# The basic types that we support marshalling right now. These
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson# are the ones we can pass as basic arguments to libdbus directly.
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson# If the dbus and sssd types are identical we pass things directly.
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson# otherwise some copying is necessary.
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas GustafssonBASIC_TYPES = {
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson 'y': ( "DBUS_TYPE_BYTE", "uint8_t", "uint8_t" ),
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson 'b': ( "DBUS_TYPE_BOOLEAN", "dbus_bool_t", "bool" ),
7bf91d95eb5a49117d5080bbd03839b9de5c8423Andreas Gustafsson 'n': ( "DBUS_TYPE_INT16", "int16_t", "int16_t" ),
19f4d25fd5b35b1375b0b9f13b66770ee4a66154Brian Wellington 'q': ( "DBUS_TYPE_UINT16", "uint16_t", "uint16_t" ),
19f4d25fd5b35b1375b0b9f13b66770ee4a66154Brian Wellington 'i': ( "DBUS_TYPE_INT32", "int32_t", "int32_t" ),
d0aebc5a55b6145297d94f8aee939852357c59fcMark Andrews 'u': ( "DBUS_TYPE_UINT32", "uint32_t", "uint32_t" ),
d0aebc5a55b6145297d94f8aee939852357c59fcMark Andrews 'x': ( "DBUS_TYPE_INT64", "int64_t", "int64_t" ),
d0aebc5a55b6145297d94f8aee939852357c59fcMark Andrews 't': ( "DBUS_TYPE_UINT64", "uint64_t", "uint64_t" ),
d0aebc5a55b6145297d94f8aee939852357c59fcMark Andrews 'd': ( "DBUS_TYPE_DOUBLE", "double", "double" ),
d0aebc5a55b6145297d94f8aee939852357c59fcMark Andrews 's': ( "DBUS_TYPE_STRING", "const char *", "const char *" ),
d0aebc5a55b6145297d94f8aee939852357c59fcMark Andrews 'o': ( "DBUS_TYPE_OBJECT_PATH", "const char *", "const char *" ),
f621719829356f27e831507b75e88e8a655e48d8Danny Mayer}
19f4d25fd5b35b1375b0b9f13b66770ee4a66154Brian Wellington
19f4d25fd5b35b1375b0b9f13b66770ee4a66154Brian Wellingtonclass Typed(Base):
19f4d25fd5b35b1375b0b9f13b66770ee4a66154Brian Wellington def __init__(self, name, type):
19f4d25fd5b35b1375b0b9f13b66770ee4a66154Brian Wellington Base.__init__(self, name)
19f4d25fd5b35b1375b0b9f13b66770ee4a66154Brian Wellington self.type = type
19f4d25fd5b35b1375b0b9f13b66770ee4a66154Brian Wellington self.is_basic = False
19f4d25fd5b35b1375b0b9f13b66770ee4a66154Brian Wellington self.is_array = False
7bf91d95eb5a49117d5080bbd03839b9de5c8423Andreas Gustafsson self.dbus_constant = None
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson self.dbus_type = None
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson self.sssd_type = None
e61793f0865117ad87a19d6e245bea8f3b712d1bDanny Mayer if type[0] == 'a':
2883651930dc85cacae940fe2a81277dfc14807dBrian Wellington type = type[1:]
2883651930dc85cacae940fe2a81277dfc14807dBrian Wellington self.is_array = True
2883651930dc85cacae940fe2a81277dfc14807dBrian Wellington if type in BASIC_TYPES:
e482a1c91ecb5e47bc26617bf310d6b5c41fad91Andreas Gustafsson (self.dbus_constant, self.dbus_type, self.sssd_type) = BASIC_TYPES[type]
e482a1c91ecb5e47bc26617bf310d6b5c41fad91Andreas Gustafsson # If types are not identical, we can't do array (yet)
e482a1c91ecb5e47bc26617bf310d6b5c41fad91Andreas Gustafsson if self.is_array:
2883651930dc85cacae940fe2a81277dfc14807dBrian Wellington self.is_basic = (self.dbus_type == self.sssd_type)
2883651930dc85cacae940fe2a81277dfc14807dBrian Wellington else:
2883651930dc85cacae940fe2a81277dfc14807dBrian Wellington self.is_basic = True
459d31fa838619cee728a90984d27d18345dc18aAndreas Gustafsson
459d31fa838619cee728a90984d27d18345dc18aAndreas Gustafssonclass Arg(Typed):
c67496c94321dfb68d209019f2b5872a81289c66Michael Sawyer def __init__(self, method, name, type):
c67496c94321dfb68d209019f2b5872a81289c66Michael Sawyer Typed.__init__(self, name, type)
c67496c94321dfb68d209019f2b5872a81289c66Michael Sawyer self.method = method
c67496c94321dfb68d209019f2b5872a81289c66Michael Sawyer
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austeinclass Method(Base):
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson def __init__(self, iface, name):
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson Base.__init__(self, name)
f621719829356f27e831507b75e88e8a655e48d8Danny Mayer self.iface = iface
bfe313722d5b2eff6c80336ed1f19c2f99a53de6Andreas Gustafsson self.in_args = []
78838d3e0cd62423c23de5503910e01884d2104bBrian Wellington self.out_args = []
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson def validate(self):
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson if not self.only_basic_args() and not self.use_raw_handler():
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson raise DBusXmlException("Method has complex arguments and requires " +
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson "the 'org.freedesktop.sssd.RawHandler' annotation")
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson def fq_c_name(self):
68e4926b2262571e004b4be00b905ec776c01d9cMichael Graff return "%s_%s" % (self.iface.c_name(), self.c_name())
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson def use_raw_handler(self):
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson anno = 'org.freedesktop.sssd.RawHandler'
68e4926b2262571e004b4be00b905ec776c01d9cMichael Graff return self.annotations.get(anno, self.iface.annotations.get(anno)) == 'true'
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson def in_signature(self):
9aba20edee4e704433a464ae43b070b0775de506Mark Andrews return "".join([arg.type for arg in self.in_args])
9aba20edee4e704433a464ae43b070b0775de506Mark Andrews def only_basic_args(self):
9aba20edee4e704433a464ae43b070b0775de506Mark Andrews for arg in self.in_args + self.out_args:
9aba20edee4e704433a464ae43b070b0775de506Mark Andrews if not arg.is_basic:
9aba20edee4e704433a464ae43b070b0775de506Mark Andrews return False
9aba20edee4e704433a464ae43b070b0775de506Mark Andrews return True
9aba20edee4e704433a464ae43b070b0775de506Mark Andrews
9aba20edee4e704433a464ae43b070b0775de506Mark Andrewsclass Signal(Base):
9aba20edee4e704433a464ae43b070b0775de506Mark Andrews def __init__(self, iface, name):
9aba20edee4e704433a464ae43b070b0775de506Mark Andrews Base.__init__(self, name)
9aba20edee4e704433a464ae43b070b0775de506Mark Andrews self.iface = iface
9aba20edee4e704433a464ae43b070b0775de506Mark Andrews self.args = []
9aba20edee4e704433a464ae43b070b0775de506Mark Andrews def fq_c_name(self):
9aba20edee4e704433a464ae43b070b0775de506Mark Andrews return "%s_%s" % (self.iface.c_name(), self.c_name())
9aba20edee4e704433a464ae43b070b0775de506Mark Andrews
9aba20edee4e704433a464ae43b070b0775de506Mark Andrewsclass Property(Typed):
9aba20edee4e704433a464ae43b070b0775de506Mark Andrews def __init__(self, iface, name, type, access):
9aba20edee4e704433a464ae43b070b0775de506Mark Andrews Typed.__init__(self, name, type)
9aba20edee4e704433a464ae43b070b0775de506Mark Andrews self.iface = iface
9aba20edee4e704433a464ae43b070b0775de506Mark Andrews self.readable = False
9aba20edee4e704433a464ae43b070b0775de506Mark Andrews self.writable = False
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews if access == 'readwrite':
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews self.readable = True
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews self.writable = True
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews elif access == 'read':
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews self.readable = True
9aba20edee4e704433a464ae43b070b0775de506Mark Andrews elif access == 'write':
7ab0e69f61e61e81d489c95c7ebd981e74e7ef16Andreas Gustafsson self.writable = True
d788d738e3d29037651b42566519c9a0a66ba219Mark Andrews else:
d788d738e3d29037651b42566519c9a0a66ba219Mark Andrews raise DBusXmlException('Invalid access type %s'%self.access)
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein def fq_c_name(self):
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence return "%s_%s" % (self.iface.c_name(), self.c_name())
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson def getter_name(self):
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson return "%s_get_%s" % (self.iface.c_name(), self.c_name())
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson def getter_invoker_name(self):
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graff return "invoke_get_%s" % self.type
42a5f9c8f535fb2a6d1cbfaa38533176e1f1667aBob Halley def getter_signature(self, name):
42a5f9c8f535fb2a6d1cbfaa38533176e1f1667aBob Halley sig = "void (*%s)(struct sbus_request *, void *data, %s *" % (name, self.sssd_type)
42a5f9c8f535fb2a6d1cbfaa38533176e1f1667aBob Halley if self.is_array:
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson sig += " *, int *"
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson sig += ")"
544f5611e1fc84597db819d111c8fd98bb719de6Bob Halley return sig
544f5611e1fc84597db819d111c8fd98bb719de6Bob Halley
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafssonclass Interface(Base):
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson def __init__(self, name):
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson Base.__init__(self, name)
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson self.methods = []
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson self.signals = []
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson self.properties = []
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson def c_name(self):
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence return self.annotations.get("org.freedesktop.DBus.GLib.CSymbol",
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson self.name.replace(".", "_"))
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson# -----------------------------------------------------------------------------
6e49e91bd08778d7eae45a2229dcf41ed97cc636David Lawrence# Code Generation
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graffdef out(format, *args, **kwargs):
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson str = format % args
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence sys.stdout.write(str)
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson # NOTE: Would like to use the following syntax for this function
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson # but need to wait until python3 until it is supported:
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson # def out(format, *args, new_line=True)
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson if kwargs.pop("new_line", True):
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson sys.stdout.write("\n")
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson assert not kwargs, "unknown keyword argument(s): %s" % str(kwargs)
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafssondef method_arg_types(args, with_names=False):
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson str = ""
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson for arg in args:
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson str += ", "
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson str += arg.sssd_type
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson if with_names:
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson if str[-1] != '*':
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson str += " "
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson str += "arg_"
6e49e91bd08778d7eae45a2229dcf41ed97cc636David Lawrence str += arg.c_name()
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson if arg.is_array:
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff str += "[], int"
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson if with_names:
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson str += " len_"
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence str += arg.c_name()
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson return str
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafssondef method_function_pointer(meth, name, with_names=False):
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson if meth.use_raw_handler():
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson return "sbus_msg_handler_fn " + name
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson else:
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson return "int (*%s)(struct sbus_request *%s, void *%s%s)" % \
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson (name, with_names and "req" or "",
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence with_names and "data" or "",
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson method_arg_types(meth.in_args, with_names))
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graffdef property_handlers(prop):
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson return prop.getter_signature(prop.getter_name())
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graffdef forward_method_invoker(signature, args):
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence out("")
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graff out("/* invokes a handler with a '%s' DBus signature */", signature)
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence out("static int invoke_%s_method(struct sbus_request *dbus_req, void *function_ptr);", signature)
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson
ec7493d8d1966a3dc5f5306fc0a96519e0de6dceAndreas Gustafssondef source_method_invoker(signature, args):
ec7493d8d1966a3dc5f5306fc0a96519e0de6dceAndreas Gustafsson out("")
ec7493d8d1966a3dc5f5306fc0a96519e0de6dceAndreas Gustafsson out("/* invokes a handler with a '%s' DBus signature */", signature)
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence out("static int invoke_%s_method(struct sbus_request *dbus_req, void *function_ptr)", signature)
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson out("{")
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson for i in range(0, len(args)):
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence arg = args[i]
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence if arg.is_array:
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence out(" %s *arg_%d;", arg.dbus_type, i)
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson out(" int len_%d;", i)
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson else:
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson out(" %s arg_%d;", arg.dbus_type, i)
42a5f9c8f535fb2a6d1cbfaa38533176e1f1667aBob Halley out(" int (*handler)(struct sbus_request *, void *%s) = function_ptr;", method_arg_types(args))
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson out("")
c801dd02ed98321f3ccab93c159a1dce61961c58Bob Halley out(" if (!sbus_request_parse_or_finish(dbus_req,")
6e49e91bd08778d7eae45a2229dcf41ed97cc636David Lawrence for i in range(0, len(args)):
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence arg = args[i]
6e49e91bd08778d7eae45a2229dcf41ed97cc636David Lawrence if arg.is_array:
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson out(" DBUS_TYPE_ARRAY, %s, &arg_%d, &len_%d,",
2e715dbdc263f859c01b57a9d733c1dfbf28b90eBob Halley arg.dbus_constant, i, i)
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson else:
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson out(" %s, &arg_%d,", arg.dbus_constant, i)
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson out(" DBUS_TYPE_INVALID)) {")
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence out(" return EOK; /* request handled */")
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson out(" }")
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson out("")
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence out(" return (handler)(dbus_req, dbus_req->intf->handler_data", new_line=False)
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence for i in range(0, len(args)):
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson arg = args[i]
2e715dbdc263f859c01b57a9d733c1dfbf28b90eBob Halley out(",\n arg_%d", i, new_line=False)
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson if arg.is_array:
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff out(",\n len_%d", i, new_line=False)
2e715dbdc263f859c01b57a9d733c1dfbf28b90eBob Halley out(");")
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff out("}")
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrencedef source_prop_types(prop, type_prefix=False):
6e49e91bd08778d7eae45a2229dcf41ed97cc636David Lawrence prefix = "%s_" % prop.type if type_prefix else ""
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson if prop.is_array:
2e715dbdc263f859c01b57a9d733c1dfbf28b90eBob Halley out(" %s *%sprop_val;", prop.sssd_type, prefix)
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson out(" int %sprop_len;", prefix)
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson out(" %s *%sout_val;", prop.dbus_type, prefix)
0c8649cea98afc061dd2938fd315df53b8fc35caAndreas Gustafsson else:
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson out(" %s %sprop_val;", prop.sssd_type, prefix)
0c8649cea98afc061dd2938fd315df53b8fc35caAndreas Gustafsson out(" %s %sout_val;", prop.dbus_type, prefix)
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafssondef source_prop_handler(prop, type_prefix=False):
0c8649cea98afc061dd2938fd315df53b8fc35caAndreas Gustafsson prefix = "%s_" % prop.type if type_prefix else ""
692ae2fff922f1c072169d1ddda8e600cb572a9bMark Andrews out(" %s", prop.getter_signature("%shandler" % prefix), new_line=False)
ec7493d8d1966a3dc5f5306fc0a96519e0de6dceAndreas Gustafsson out(";")
ec7493d8d1966a3dc5f5306fc0a96519e0de6dceAndreas Gustafsson
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrencedef source_getter_invoker(prop):
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff out("")
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson if prop.is_array:
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson out("/* invokes a getter with an array of '%s' DBus type */", prop.dbus_type)
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson else:
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson out("/* invokes a getter with a '%s' DBus type */", prop.dbus_type)
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson out("static int %s(struct sbus_request *dbus_req, void *function_ptr)",
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson prop.getter_invoker_name())
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff out("{")
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson
78838d3e0cd62423c23de5503910e01884d2104bBrian Wellington source_prop_types(prop)
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson out("")
e482a1c91ecb5e47bc26617bf310d6b5c41fad91Andreas Gustafsson out(" %s", prop.getter_signature("handler"), new_line=False)
e482a1c91ecb5e47bc26617bf310d6b5c41fad91Andreas Gustafsson out(" = function_ptr;")
e482a1c91ecb5e47bc26617bf310d6b5c41fad91Andreas Gustafsson out("")
e482a1c91ecb5e47bc26617bf310d6b5c41fad91Andreas Gustafsson
e482a1c91ecb5e47bc26617bf310d6b5c41fad91Andreas Gustafsson out(" (handler)(dbus_req, dbus_req->intf->handler_data, &prop_val", new_line=False)
e482a1c91ecb5e47bc26617bf310d6b5c41fad91Andreas Gustafsson if prop.is_array:
e482a1c91ecb5e47bc26617bf310d6b5c41fad91Andreas Gustafsson out(", &prop_len", new_line=False)
e482a1c91ecb5e47bc26617bf310d6b5c41fad91Andreas Gustafsson out(");")
e482a1c91ecb5e47bc26617bf310d6b5c41fad91Andreas Gustafsson
e482a1c91ecb5e47bc26617bf310d6b5c41fad91Andreas Gustafsson out("")
e482a1c91ecb5e47bc26617bf310d6b5c41fad91Andreas Gustafsson if prop.type == "s":
e482a1c91ecb5e47bc26617bf310d6b5c41fad91Andreas Gustafsson out(" out_val = prop_val == NULL ? \"\" : prop_val;")
e482a1c91ecb5e47bc26617bf310d6b5c41fad91Andreas Gustafsson elif prop.type == "o":
e482a1c91ecb5e47bc26617bf310d6b5c41fad91Andreas Gustafsson out(" out_val = prop_val == NULL ? \"/\" : prop_val;")
e482a1c91ecb5e47bc26617bf310d6b5c41fad91Andreas Gustafsson else:
e482a1c91ecb5e47bc26617bf310d6b5c41fad91Andreas Gustafsson out(" out_val = prop_val;")
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson if prop.is_array:
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson out(" return sbus_request_return_array_as_variant(dbus_req, %s, (uint8_t*)out_val, prop_len, sizeof(%s));", prop.dbus_constant, prop.sssd_type)
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson else:
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson out(" return sbus_request_return_as_variant(dbus_req, %s, &out_val);", prop.dbus_constant)
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson out("}")
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafssondef source_getall_invoker(iface, prop_invokers):
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graff out("")
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson out("/* invokes GetAll for the '%s' interface */", iface.name)
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson out("static int invoke_%s_get_all(struct sbus_request *dbus_req, void *function_ptr)",
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson iface.c_name())
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson out("{")
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson out(" DBusMessage *reply;")
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson out(" dbus_bool_t dbret;")
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graff out(" DBusMessageIter iter;")
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson out(" DBusMessageIter iter_dict;")
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson if iface.properties:
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson out(" int ret;")
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson out(" struct sbus_interface *intf = dbus_req->intf;")
11c7a43642def4aaa2bed001ff018a0bb0b65c29Danny Mayer out(" const struct sbus_property_meta *property;")
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson iface_types = [ p.type for p in iface.properties ]
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence for prop in [ p for p in prop_invokers.values() if p.type in iface_types ]:
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson source_prop_types(prop, type_prefix=True)
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff source_prop_handler(prop, type_prefix=True)
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson out("")
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson out(" reply = dbus_message_new_method_return(dbus_req->message);")
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson out(" if (!reply) return ENOMEM;")
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson out(" dbus_message_iter_init_append(reply, &iter);")
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson out(" dbret = dbus_message_iter_open_container(")
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence out(" &iter, DBUS_TYPE_ARRAY,")
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence out(" DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING")
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence out(" DBUS_TYPE_STRING_AS_STRING")
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence out(" DBUS_TYPE_VARIANT_AS_STRING")
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson out(" DBUS_DICT_ENTRY_END_CHAR_AS_STRING,")
c801dd02ed98321f3ccab93c159a1dce61961c58Bob Halley out(" &iter_dict);")
c801dd02ed98321f3ccab93c159a1dce61961c58Bob Halley out(" if (!dbret) return ENOMEM;")
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson out("")
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson for prop in iface.properties:
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson out(" property = sbus_meta_find_property(intf->vtable->meta, \"%s\");", prop.c_name())
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson out(" if (property != NULL && property->flags & SBUS_PROPERTY_READABLE) {")
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson out(" %s_handler = VTABLE_FUNC(intf->vtable, property->vtable_offset_get);", prop.type)
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson out(" if (%s_handler) {", prop.type)
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson out(" (%s_handler)(dbus_req, dbus_req->intf->handler_data, &%s_prop_val", prop.type, prop.type, new_line=False)
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence if prop.is_array:
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence out(", &%s_prop_len", prop.type, new_line=False)
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence out(");")
b9efcf0a377381b29960137e54ecaf4db85a35c8Mark Andrews if prop.type == "s":
b9efcf0a377381b29960137e54ecaf4db85a35c8Mark Andrews out(" %s_out_val = %s_prop_val == NULL ? \"\" : %s_prop_val;",
b9efcf0a377381b29960137e54ecaf4db85a35c8Mark Andrews prop.type, prop.type, prop.type)
b9efcf0a377381b29960137e54ecaf4db85a35c8Mark Andrews elif prop.type == "o":
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson out(" %s_out_val = %s_prop_val == NULL ? \"/\" : %s_prop_val;",
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson prop.type, prop.type, prop.type)
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson else:
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson out(" %s_out_val = %s_prop_val;", prop.type, prop.type)
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson if prop.is_array:
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson out(" ret = sbus_add_array_as_variant_to_dict(&iter_dict, \"%s\", %s, (uint8_t*)%s_out_val, %s_prop_len, sizeof(%s));", prop.c_name(), prop.dbus_constant, prop.type, prop.type, prop.sssd_type)
806c235ecf533b98d068b3f8df9d7abbe1e30cf9Mark Andrews else:
806c235ecf533b98d068b3f8df9d7abbe1e30cf9Mark Andrews out(" ret = sbus_add_variant_to_dict(&iter_dict, \"%s\", %s, &%s_out_val);", prop.c_name(), prop.dbus_constant, prop.type)
f3ca27e9fe307b55e35ea8d7b37351650630e5a3Andreas Gustafsson out(" if (ret != EOK) return ret;")
6e49e91bd08778d7eae45a2229dcf41ed97cc636David Lawrence out(" }")
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson out(" }")
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff out("")
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson out(" dbret = dbus_message_iter_close_container(&iter, &iter_dict);")
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson out(" if (!dbret) return ENOMEM;")
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson out("")
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence out(" return sbus_request_finish(dbus_req, reply);")
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson out("}")
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson
c801dd02ed98321f3ccab93c159a1dce61961c58Bob Halleydef forward_method_invokers(ifaces):
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson invokers = { }
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson for iface in ifaces:
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson for meth in iface.methods:
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson if meth.use_raw_handler() or not meth.in_args:
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson continue
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence signature = meth.in_signature()
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence if signature in invokers:
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence continue
b9efcf0a377381b29960137e54ecaf4db85a35c8Mark Andrews forward_method_invoker(signature, meth.in_args)
b9efcf0a377381b29960137e54ecaf4db85a35c8Mark Andrews invokers[signature] = meth
b9efcf0a377381b29960137e54ecaf4db85a35c8Mark Andrews return invokers
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafssondef source_method_invokers(invokers):
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson for (signature, meth) in invokers.items():
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson source_method_invoker(signature, meth.in_args)
c801dd02ed98321f3ccab93c159a1dce61961c58Bob Halley
c801dd02ed98321f3ccab93c159a1dce61961c58Bob Halleydef forward_prop_invoker(prop):
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff out("static int %s(struct sbus_request *dbus_req, void *function_ptr);",
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson prop.getter_invoker_name())
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafssondef forward_prop_invokers(ifaces):
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson invokers = { }
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence for iface in ifaces:
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence for prop in iface.properties:
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence if not prop.is_basic:
e482a1c91ecb5e47bc26617bf310d6b5c41fad91Andreas Gustafsson continue
e482a1c91ecb5e47bc26617bf310d6b5c41fad91Andreas Gustafsson if prop.type in invokers:
e482a1c91ecb5e47bc26617bf310d6b5c41fad91Andreas Gustafsson continue
e482a1c91ecb5e47bc26617bf310d6b5c41fad91Andreas Gustafsson forward_prop_invoker(prop)
e482a1c91ecb5e47bc26617bf310d6b5c41fad91Andreas Gustafsson invokers[prop.type] = prop
e482a1c91ecb5e47bc26617bf310d6b5c41fad91Andreas Gustafsson return invokers
e482a1c91ecb5e47bc26617bf310d6b5c41fad91Andreas Gustafsson
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafssondef source_prop_invokers(invokers):
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson for (type, prop) in invokers.items():
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson if prop.readable:
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson source_getter_invoker(prop)
e482a1c91ecb5e47bc26617bf310d6b5c41fad91Andreas Gustafsson
e482a1c91ecb5e47bc26617bf310d6b5c41fad91Andreas Gustafssondef source_finisher(meth):
e482a1c91ecb5e47bc26617bf310d6b5c41fad91Andreas Gustafsson out("")
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff out("int %s_finish(struct sbus_request *req%s)",
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson meth.fq_c_name(), method_arg_types(meth.out_args, with_names=True))
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson out("{")
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson for arg in meth.out_args:
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence if arg.dbus_type != arg.sssd_type:
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence out(" %s cast_%s = arg_%s;", arg.dbus_type, arg.c_name(), arg.c_name())
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence
e482a1c91ecb5e47bc26617bf310d6b5c41fad91Andreas Gustafsson out(" return sbus_request_return_and_finish(req,")
e482a1c91ecb5e47bc26617bf310d6b5c41fad91Andreas Gustafsson for arg in meth.out_args:
d788d738e3d29037651b42566519c9a0a66ba219Mark Andrews out(" ", new_line=False)
d788d738e3d29037651b42566519c9a0a66ba219Mark Andrews if arg.is_array:
d788d738e3d29037651b42566519c9a0a66ba219Mark Andrews out("DBUS_TYPE_ARRAY, %s, &arg_%s, len_%s,",
d788d738e3d29037651b42566519c9a0a66ba219Mark Andrews arg.dbus_constant, arg.c_name(), arg.c_name())
e482a1c91ecb5e47bc26617bf310d6b5c41fad91Andreas Gustafsson elif arg.dbus_type != arg.sssd_type:
c03bb27f0675a6e60ceea66b451548e8481bc05cMark Andrews out("%s, &cast_%s,", arg.dbus_constant, arg.c_name())
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson else:
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson out("%s, &arg_%s,", arg.dbus_constant, arg.c_name())
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson out(" DBUS_TYPE_INVALID);")
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson out("}")
0c8649cea98afc061dd2938fd315df53b8fc35caAndreas Gustafsson
0c8649cea98afc061dd2938fd315df53b8fc35caAndreas Gustafssondef header_reply(meth):
0c8649cea98afc061dd2938fd315df53b8fc35caAndreas Gustafsson for arg in meth.out_args:
0c8649cea98afc061dd2938fd315df53b8fc35caAndreas Gustafsson if arg.is_array:
0c8649cea98afc061dd2938fd315df53b8fc35caAndreas Gustafsson out(" %s *%s", arg.dbus_type, arg.c_name())
0c8649cea98afc061dd2938fd315df53b8fc35caAndreas Gustafsson out(" int %s__len", arg.c_name())
0c8649cea98afc061dd2938fd315df53b8fc35caAndreas Gustafsson else:
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson out(" %s %s;", arg.dbus_type, arg.c_name())
6e49e91bd08778d7eae45a2229dcf41ed97cc636David Lawrence types = [arg.sssd_type for arg in meth.in_args]
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graffdef source_args(parent, args, suffix):
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson out("")
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson out("/* arguments for %s.%s */", parent.iface.name, parent.name)
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson out("const struct sbus_arg_meta %s%s[] = {", parent.fq_c_name(), suffix)
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson for arg in args:
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson out(" { \"%s\", \"%s\" },", arg.name, arg.type)
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson out(" { NULL, }")
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff out("};")
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graffdef source_methods(iface, methods):
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson for meth in methods:
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson if meth.in_args:
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson source_args(meth, meth.in_args, "__in")
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson if meth.out_args:
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence source_args(meth, meth.out_args, "__out")
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson if not meth.use_raw_handler():
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence source_finisher(meth)
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson out("")
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson out("/* methods for %s */", iface.name)
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson out("const struct sbus_method_meta %s__methods[] = {", iface.c_name())
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson for meth in methods:
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff out(" {")
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson out(" \"%s\", /* name */", meth.name)
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson if meth.in_args:
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson out(" %s__in,", meth.fq_c_name())
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson else:
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson out(" NULL, /* no in_args */")
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson if meth.out_args:
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson out(" %s__out,", meth.fq_c_name())
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graff else:
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson out(" NULL, /* no out_args */")
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson out(" offsetof(struct %s, %s),", iface.c_name(), meth.c_name())
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson if meth.use_raw_handler() or not meth.in_args:
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson out(" NULL, /* no invoker */")
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson else:
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson out(" invoke_%s_method,", meth.in_signature())
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson out(" },")
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graff out(" { NULL, }")
c801dd02ed98321f3ccab93c159a1dce61961c58Bob Halley out("};")
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafssondef source_signals(iface, signals):
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson for sig in iface.signals:
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff if sig.args:
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson source_args(sig, sig.args, "__args")
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson out("")
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson out("/* signals for %s */", iface.name)
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson out("const struct sbus_signal_meta %s__signals[] = {", iface.c_name())
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson for sig in signals:
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson out(" {")
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson out(" \"%s\", /* name */", sig.name)
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson if sig.args:
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson out(" %s__args", sig.fq_c_name())
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson else:
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson out(" NULL, /* no args */")
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson out(" },")
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson out(" { NULL, }")
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson out("};")
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafssondef source_properties(iface, properties):
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson out("")
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff out("/* property info for %s */", iface.name)
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson out("const struct sbus_property_meta %s__properties[] = {", iface.c_name())
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson for prop in properties:
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson out(" {")
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson out(" \"%s\", /* name */", prop.name)
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson out(" \"%s\", /* type */", prop.type)
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson if prop.readable and prop.writable:
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson out(" SBUS_PROPERTY_READABLE | SBUS_PROPERTY_WRITABLE,")
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson elif prop.readable:
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson out(" SBUS_PROPERTY_READABLE,")
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff elif prop.writable:
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson out(" SBUS_PROPERTY_WRITABLE,")
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson else:
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson assert False, "should not be reached"
c801dd02ed98321f3ccab93c159a1dce61961c58Bob Halley if prop.readable:
6e49e91bd08778d7eae45a2229dcf41ed97cc636David Lawrence out(" offsetof(struct %s, %s),", iface.c_name(), prop.getter_name())
c801dd02ed98321f3ccab93c159a1dce61961c58Bob Halley out(" %s,", prop.getter_invoker_name())
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff else:
c801dd02ed98321f3ccab93c159a1dce61961c58Bob Halley out(" 0, /* not readable */")
c801dd02ed98321f3ccab93c159a1dce61961c58Bob Halley out(" NULL, /* no invoker */")
c801dd02ed98321f3ccab93c159a1dce61961c58Bob Halley out(" 0, /* not writable */")
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff out(" NULL, /* no invoker */")
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson out(" },")
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson out(" { NULL, }")
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graff out("};")
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafssondef header_interface(iface):
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson out("")
421551db8a61283420b0b6aed4ac28f9d76b9770Andreas Gustafsson out("/* interface info for %s */", iface.name)
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson out("extern const struct sbus_interface_meta %s_meta;", iface.c_name())
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafssondef source_interface(iface):
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graff out("")
bfe313722d5b2eff6c80336ed1f19c2f99a53de6Andreas Gustafsson out("/* interface info for %s */", iface.name)
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff out("const struct sbus_interface_meta %s_meta = {", iface.c_name())
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson out(" \"%s\", /* name */", iface.name)
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson if iface.methods:
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff out(" %s__methods,", iface.c_name())
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson else:
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson out(" NULL, /* no methods */")
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson if iface.signals:
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson out(" %s__signals,", iface.c_name())
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson else:
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson out(" NULL, /* no signals */")
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson if iface.properties:
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson out(" %s__properties,", iface.c_name())
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson else:
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson out(" NULL, /* no properties */")
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence out(" invoke_%s_get_all, /* GetAll invoker */", iface.c_name())
421551db8a61283420b0b6aed4ac28f9d76b9770Andreas Gustafsson out("};")
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafssondef generate_source(ifaces, filename, include_header=None):
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson basename = os.path.basename(filename)
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson out("/* The following definitions are auto-generated from %s */", basename)
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson out("")
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson
421551db8a61283420b0b6aed4ac28f9d76b9770Andreas Gustafsson out("#include \"util/util.h\"")
421551db8a61283420b0b6aed4ac28f9d76b9770Andreas Gustafsson out("#include \"sbus/sssd_dbus.h\"")
421551db8a61283420b0b6aed4ac28f9d76b9770Andreas Gustafsson out("#include \"sbus/sssd_dbus_meta.h\"")
421551db8a61283420b0b6aed4ac28f9d76b9770Andreas Gustafsson if include_header:
421551db8a61283420b0b6aed4ac28f9d76b9770Andreas Gustafsson out("#include \"%s\"", os.path.basename(include_header))
421551db8a61283420b0b6aed4ac28f9d76b9770Andreas Gustafsson
421551db8a61283420b0b6aed4ac28f9d76b9770Andreas Gustafsson meth_invokers = forward_method_invokers(ifaces)
421551db8a61283420b0b6aed4ac28f9d76b9770Andreas Gustafsson prop_invokers = forward_prop_invokers(ifaces)
421551db8a61283420b0b6aed4ac28f9d76b9770Andreas Gustafsson
421551db8a61283420b0b6aed4ac28f9d76b9770Andreas Gustafsson for iface in ifaces:
421551db8a61283420b0b6aed4ac28f9d76b9770Andreas Gustafsson
421551db8a61283420b0b6aed4ac28f9d76b9770Andreas Gustafsson # The methods
421551db8a61283420b0b6aed4ac28f9d76b9770Andreas Gustafsson if iface.methods:
421551db8a61283420b0b6aed4ac28f9d76b9770Andreas Gustafsson source_methods(iface, iface.methods)
421551db8a61283420b0b6aed4ac28f9d76b9770Andreas Gustafsson
421551db8a61283420b0b6aed4ac28f9d76b9770Andreas Gustafsson # The signals array
421551db8a61283420b0b6aed4ac28f9d76b9770Andreas Gustafsson if iface.signals:
421551db8a61283420b0b6aed4ac28f9d76b9770Andreas Gustafsson source_signals(iface, iface.signals)
421551db8a61283420b0b6aed4ac28f9d76b9770Andreas Gustafsson
421551db8a61283420b0b6aed4ac28f9d76b9770Andreas Gustafsson # The properties array
421551db8a61283420b0b6aed4ac28f9d76b9770Andreas Gustafsson if iface.properties:
421551db8a61283420b0b6aed4ac28f9d76b9770Andreas Gustafsson source_properties(iface, iface.properties)
bed7a352934efc8055902d83c750dca2d0cd6aaaAndreas Gustafsson
421551db8a61283420b0b6aed4ac28f9d76b9770Andreas Gustafsson # always generate getall, for interfaces without properties
421551db8a61283420b0b6aed4ac28f9d76b9770Andreas Gustafsson # let's return an empty array
bed7a352934efc8055902d83c750dca2d0cd6aaaAndreas Gustafsson source_getall_invoker(iface, prop_invokers)
bed7a352934efc8055902d83c750dca2d0cd6aaaAndreas Gustafsson # The sbus_interface structure
bed7a352934efc8055902d83c750dca2d0cd6aaaAndreas Gustafsson source_interface(iface)
bed7a352934efc8055902d83c750dca2d0cd6aaaAndreas Gustafsson
bed7a352934efc8055902d83c750dca2d0cd6aaaAndreas Gustafsson source_method_invokers(meth_invokers)
bed7a352934efc8055902d83c750dca2d0cd6aaaAndreas Gustafsson source_prop_invokers(prop_invokers)
bed7a352934efc8055902d83c750dca2d0cd6aaaAndreas Gustafsson
bed7a352934efc8055902d83c750dca2d0cd6aaaAndreas Gustafssondef header_finisher(iface, meth):
bed7a352934efc8055902d83c750dca2d0cd6aaaAndreas Gustafsson if meth.use_raw_handler():
bed7a352934efc8055902d83c750dca2d0cd6aaaAndreas Gustafsson return
421551db8a61283420b0b6aed4ac28f9d76b9770Andreas Gustafsson out("")
421551db8a61283420b0b6aed4ac28f9d76b9770Andreas Gustafsson out("/* finish function for %s */", meth.name)
421551db8a61283420b0b6aed4ac28f9d76b9770Andreas Gustafsson out("int %s_finish(struct sbus_request *req%s);",
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson meth.fq_c_name(), method_arg_types(meth.out_args, with_names=True))
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrencedef header_vtable(iface, methods):
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson out("")
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson out("/* vtable for %s */", iface.name)
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson out("struct %s {", iface.c_name())
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson out(" struct sbus_vtable vtable; /* derive from sbus_vtable */")
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graff
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson # All methods
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence for meth in iface.methods:
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson out(" %s;", method_function_pointer(meth, meth.c_name(), with_names=True))
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson for prop in iface.properties:
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson out(" %s;", property_handlers(prop))
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graff
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence out("};")
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafssondef header_constants(iface):
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence out("")
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence out("/* constants for %s */", iface.name)
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence out("#define %s \"%s\"", iface.c_name().upper(), iface.name)
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence for meth in iface.methods:
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson out("#define %s \"%s\"", meth.fq_c_name().upper(), meth.name)
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson for sig in iface.signals:
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson out("#define %s \"%s\"", sig.fq_c_name().upper(), sig.name)
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson for prop in iface.properties:
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson out("#define %s \"%s\"", prop.fq_c_name().upper(), prop.name)
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafssondef generate_header(ifaces, filename):
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson basename = os.path.basename(filename)
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson guard = "__%s__" % re.sub(r'([^_A-Z0-9])', "_", basename.upper())
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff
6e49e91bd08778d7eae45a2229dcf41ed97cc636David Lawrence out("/* The following declarations are auto-generated from %s */", basename)
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson out("")
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson out("#ifndef %s", guard)
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson out("#define %s", guard)
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson out("")
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson out("#include \"sbus/sssd_dbus.h\"")
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson out("")
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson out("/* ------------------------------------------------------------------------")
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson out(" * DBus Constants")
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence out(" *")
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson out(" * Various constants of interface and method names mostly for use by clients")
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson out(" */")
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson for iface in ifaces:
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson header_constants(iface)
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson out("")
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson out("/* ------------------------------------------------------------------------")
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson out(" * DBus handlers")
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson out(" *")
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson out(" * These structures are filled in by implementors of the different")
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff out(" * dbus interfaces to handle method calls.")
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson out(" *")
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson out(" * Handler functions of type sbus_msg_handler_fn accept raw messages,")
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson out(" * other handlers are typed appropriately. If a handler that is")
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson out(" * set to NULL is invoked it will result in a")
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson out(" * org.freedesktop.DBus.Error.NotSupported error for the caller.")
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff out(" *")
4e57d3ff7d92abdef4b0b6aebc23a9dfae2ba040Andreas Gustafsson out(" * Handlers have a matching xxx_finish() function (unless the method has")
6e49e91bd08778d7eae45a2229dcf41ed97cc636David Lawrence out(" * accepts raw messages). These finish functions the")
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson out(" * sbus_request_return_and_finish() with the appropriate arguments to")
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff out(" * construct a valid reply. Once a finish function has been called, the")
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson out(" * @dbus_req it was called with is freed and no longer valid.")
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson out(" */")
d8e34837cd6c88c42b3ecdb9107a43ecf8252e79David Lawrence
d8e34837cd6c88c42b3ecdb9107a43ecf8252e79David Lawrence for iface in ifaces:
d8e34837cd6c88c42b3ecdb9107a43ecf8252e79David Lawrence if iface.methods or iface.properties:
6e49e91bd08778d7eae45a2229dcf41ed97cc636David Lawrence header_vtable(iface, iface.methods)
d8e34837cd6c88c42b3ecdb9107a43ecf8252e79David Lawrence for meth in iface.methods:
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson header_finisher(iface, meth)
d8e34837cd6c88c42b3ecdb9107a43ecf8252e79David Lawrence
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson out("")
c0d0a59d1b665423b8a0d1829d0f0da121cb3473Andreas Gustafsson out("/* ------------------------------------------------------------------------")
d8e34837cd6c88c42b3ecdb9107a43ecf8252e79David Lawrence out(" * DBus Interface Metadata")
d8e34837cd6c88c42b3ecdb9107a43ecf8252e79David Lawrence out(" *")
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson out(" * These structure definitions are filled in with the information about")
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence out(" * the interfaces, methods, properties and so on.")
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff out(" *")
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson out(" * The actual definitions are found in the accompanying C file next")
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson out(" * to this header.")
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson out(" */")
593cb00bd17e5e2ab0dcb7c635a9a81082dc5d0eAndreas Gustafsson
593cb00bd17e5e2ab0dcb7c635a9a81082dc5d0eAndreas Gustafsson for iface in ifaces:
593cb00bd17e5e2ab0dcb7c635a9a81082dc5d0eAndreas Gustafsson header_interface(iface)
593cb00bd17e5e2ab0dcb7c635a9a81082dc5d0eAndreas Gustafsson
593cb00bd17e5e2ab0dcb7c635a9a81082dc5d0eAndreas Gustafsson out("")
593cb00bd17e5e2ab0dcb7c635a9a81082dc5d0eAndreas Gustafsson out("#endif /* %s */", guard)
593cb00bd17e5e2ab0dcb7c635a9a81082dc5d0eAndreas Gustafsson
593cb00bd17e5e2ab0dcb7c635a9a81082dc5d0eAndreas Gustafsson# -----------------------------------------------------------------------------
593cb00bd17e5e2ab0dcb7c635a9a81082dc5d0eAndreas Gustafsson# XML Interface Parsing
593cb00bd17e5e2ab0dcb7c635a9a81082dc5d0eAndreas Gustafsson
593cb00bd17e5e2ab0dcb7c635a9a81082dc5d0eAndreas GustafssonSTATE_TOP = 'top'
593cb00bd17e5e2ab0dcb7c635a9a81082dc5d0eAndreas GustafssonSTATE_NODE = 'node'
93d6dfaf66258337985427c86181f01fc51f0bb4Mark AndrewsSTATE_INTERFACE = 'interface'
593cb00bd17e5e2ab0dcb7c635a9a81082dc5d0eAndreas GustafssonSTATE_METHOD = 'method'
593cb00bd17e5e2ab0dcb7c635a9a81082dc5d0eAndreas GustafssonSTATE_SIGNAL = 'signal'
593cb00bd17e5e2ab0dcb7c635a9a81082dc5d0eAndreas GustafssonSTATE_PROPERTY = 'property'
593cb00bd17e5e2ab0dcb7c635a9a81082dc5d0eAndreas GustafssonSTATE_ARG = 'arg'
593cb00bd17e5e2ab0dcb7c635a9a81082dc5d0eAndreas GustafssonSTATE_ANNOTATION = 'annotation'
593cb00bd17e5e2ab0dcb7c635a9a81082dc5d0eAndreas GustafssonSTATE_IGNORED = 'ignored'
593cb00bd17e5e2ab0dcb7c635a9a81082dc5d0eAndreas Gustafsson
593cb00bd17e5e2ab0dcb7c635a9a81082dc5d0eAndreas Gustafssondef expect_attr(attrs, name):
593cb00bd17e5e2ab0dcb7c635a9a81082dc5d0eAndreas Gustafsson if name not in attrs:
593cb00bd17e5e2ab0dcb7c635a9a81082dc5d0eAndreas Gustafsson raise DBusXmlException("Missing attribute '%s'" % name)
593cb00bd17e5e2ab0dcb7c635a9a81082dc5d0eAndreas Gustafsson if attrs[name] == "":
593cb00bd17e5e2ab0dcb7c635a9a81082dc5d0eAndreas Gustafsson raise DBusXmlException("Empty attribute '%s'" % name)
593cb00bd17e5e2ab0dcb7c635a9a81082dc5d0eAndreas Gustafsson return attrs[name]
593cb00bd17e5e2ab0dcb7c635a9a81082dc5d0eAndreas Gustafsson
593cb00bd17e5e2ab0dcb7c635a9a81082dc5d0eAndreas Gustafssonclass DBusXMLParser:
593cb00bd17e5e2ab0dcb7c635a9a81082dc5d0eAndreas Gustafsson def __init__(self, filename):
593cb00bd17e5e2ab0dcb7c635a9a81082dc5d0eAndreas Gustafsson parser = xml.parsers.expat.ParserCreate()
593cb00bd17e5e2ab0dcb7c635a9a81082dc5d0eAndreas Gustafsson parser.CommentHandler = self.handle_comment
593cb00bd17e5e2ab0dcb7c635a9a81082dc5d0eAndreas Gustafsson parser.CharacterDataHandler = self.handle_char_data
593cb00bd17e5e2ab0dcb7c635a9a81082dc5d0eAndreas Gustafsson parser.StartElementHandler = self.handle_start_element
593cb00bd17e5e2ab0dcb7c635a9a81082dc5d0eAndreas Gustafsson parser.EndElementHandler = self.handle_end_element
593cb00bd17e5e2ab0dcb7c635a9a81082dc5d0eAndreas Gustafsson
e694d4e2016c0ab1f3c2bbe493c45379770e830dDavid Lawrence self.parsed_interfaces = []
e694d4e2016c0ab1f3c2bbe493c45379770e830dDavid Lawrence self.cur_object = None
593cb00bd17e5e2ab0dcb7c635a9a81082dc5d0eAndreas Gustafsson
593cb00bd17e5e2ab0dcb7c635a9a81082dc5d0eAndreas Gustafsson self.state = STATE_TOP
593cb00bd17e5e2ab0dcb7c635a9a81082dc5d0eAndreas Gustafsson self.state_stack = []
593cb00bd17e5e2ab0dcb7c635a9a81082dc5d0eAndreas Gustafsson self.cur_object = None
593cb00bd17e5e2ab0dcb7c635a9a81082dc5d0eAndreas Gustafsson self.cur_object_stack = []
593cb00bd17e5e2ab0dcb7c635a9a81082dc5d0eAndreas Gustafsson self.arg_count = 0
593cb00bd17e5e2ab0dcb7c635a9a81082dc5d0eAndreas Gustafsson
593cb00bd17e5e2ab0dcb7c635a9a81082dc5d0eAndreas Gustafsson try:
593cb00bd17e5e2ab0dcb7c635a9a81082dc5d0eAndreas Gustafsson with open(filename, "r") as f:
593cb00bd17e5e2ab0dcb7c635a9a81082dc5d0eAndreas Gustafsson parser.ParseFile(f)
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson except DBusXmlException, ex:
593cb00bd17e5e2ab0dcb7c635a9a81082dc5d0eAndreas Gustafsson ex.line = parser.CurrentLineNumber
593cb00bd17e5e2ab0dcb7c635a9a81082dc5d0eAndreas Gustafsson ex.file = filename
593cb00bd17e5e2ab0dcb7c635a9a81082dc5d0eAndreas Gustafsson raise
1ae369c9d24269c3723e9c76be5fc636f34fc8afAndreas Gustafsson except xml.parsers.expat.ExpatError, ex:
e482a1c91ecb5e47bc26617bf310d6b5c41fad91Andreas Gustafsson exc = DBusXmlException(str(ex))
e482a1c91ecb5e47bc26617bf310d6b5c41fad91Andreas Gustafsson exc.line = ex.lineno
e482a1c91ecb5e47bc26617bf310d6b5c41fad91Andreas Gustafsson exc.file = filename
e482a1c91ecb5e47bc26617bf310d6b5c41fad91Andreas Gustafsson raise exc
e482a1c91ecb5e47bc26617bf310d6b5c41fad91Andreas Gustafsson
e482a1c91ecb5e47bc26617bf310d6b5c41fad91Andreas Gustafsson def handle_comment(self, data):
e482a1c91ecb5e47bc26617bf310d6b5c41fad91Andreas Gustafsson pass
e482a1c91ecb5e47bc26617bf310d6b5c41fad91Andreas Gustafsson
e482a1c91ecb5e47bc26617bf310d6b5c41fad91Andreas Gustafsson def handle_char_data(self, data):
e482a1c91ecb5e47bc26617bf310d6b5c41fad91Andreas Gustafsson pass
e482a1c91ecb5e47bc26617bf310d6b5c41fad91Andreas Gustafsson
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graff def handle_start_element(self, name, attrs):
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews old_state = self.state
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews old_cur_object = self.cur_object
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews if self.state == STATE_IGNORED:
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson self.state = STATE_IGNORED
593cb00bd17e5e2ab0dcb7c635a9a81082dc5d0eAndreas Gustafsson elif self.cur_object and name == STATE_ANNOTATION:
692ae2fff922f1c072169d1ddda8e600cb572a9bMark Andrews val = attrs.get('value', '')
593cb00bd17e5e2ab0dcb7c635a9a81082dc5d0eAndreas Gustafsson self.cur_object.annotations[expect_attr(attrs, 'name')] = val
593cb00bd17e5e2ab0dcb7c635a9a81082dc5d0eAndreas Gustafsson self.state = STATE_IGNORED
593cb00bd17e5e2ab0dcb7c635a9a81082dc5d0eAndreas Gustafsson elif self.state == STATE_TOP:
593cb00bd17e5e2ab0dcb7c635a9a81082dc5d0eAndreas Gustafsson if name == STATE_NODE:
593cb00bd17e5e2ab0dcb7c635a9a81082dc5d0eAndreas Gustafsson self.state = STATE_NODE
593cb00bd17e5e2ab0dcb7c635a9a81082dc5d0eAndreas Gustafsson else:
593cb00bd17e5e2ab0dcb7c635a9a81082dc5d0eAndreas Gustafsson self.state = STATE_IGNORED
692ae2fff922f1c072169d1ddda8e600cb572a9bMark Andrews elif self.state == STATE_NODE:
692ae2fff922f1c072169d1ddda8e600cb572a9bMark Andrews if name == STATE_INTERFACE:
692ae2fff922f1c072169d1ddda8e600cb572a9bMark Andrews self.state = STATE_INTERFACE
692ae2fff922f1c072169d1ddda8e600cb572a9bMark Andrews iface = Interface(expect_attr(attrs, 'name'))
692ae2fff922f1c072169d1ddda8e600cb572a9bMark Andrews self.cur_object = iface
692ae2fff922f1c072169d1ddda8e600cb572a9bMark Andrews self.parsed_interfaces.append(iface)
692ae2fff922f1c072169d1ddda8e600cb572a9bMark Andrews else:
692ae2fff922f1c072169d1ddda8e600cb572a9bMark Andrews self.state = STATE_IGNORED
692ae2fff922f1c072169d1ddda8e600cb572a9bMark Andrews
593cb00bd17e5e2ab0dcb7c635a9a81082dc5d0eAndreas Gustafsson elif self.state == STATE_INTERFACE:
593cb00bd17e5e2ab0dcb7c635a9a81082dc5d0eAndreas Gustafsson if name == STATE_METHOD:
593cb00bd17e5e2ab0dcb7c635a9a81082dc5d0eAndreas Gustafsson self.state = STATE_METHOD
593cb00bd17e5e2ab0dcb7c635a9a81082dc5d0eAndreas Gustafsson method = Method(self.cur_object, expect_attr(attrs, 'name'))
593cb00bd17e5e2ab0dcb7c635a9a81082dc5d0eAndreas Gustafsson self.cur_object.methods.append(method)
593cb00bd17e5e2ab0dcb7c635a9a81082dc5d0eAndreas Gustafsson self.cur_object = method
593cb00bd17e5e2ab0dcb7c635a9a81082dc5d0eAndreas Gustafsson self.arg_count = 0
674f1cfb1d7dfa92e52db950dbe80e60ef8f5cddBrian Wellington elif name == STATE_SIGNAL:
593cb00bd17e5e2ab0dcb7c635a9a81082dc5d0eAndreas Gustafsson self.state = STATE_SIGNAL
593cb00bd17e5e2ab0dcb7c635a9a81082dc5d0eAndreas Gustafsson signal = Signal(self.cur_object, expect_attr(attrs, 'name'))
674f1cfb1d7dfa92e52db950dbe80e60ef8f5cddBrian Wellington self.cur_object.signals.append(signal)
593cb00bd17e5e2ab0dcb7c635a9a81082dc5d0eAndreas Gustafsson self.cur_object = signal
674f1cfb1d7dfa92e52db950dbe80e60ef8f5cddBrian Wellington self.arg_count = 0
593cb00bd17e5e2ab0dcb7c635a9a81082dc5d0eAndreas Gustafsson elif name == STATE_PROPERTY:
e482a1c91ecb5e47bc26617bf310d6b5c41fad91Andreas Gustafsson self.state = STATE_PROPERTY
e482a1c91ecb5e47bc26617bf310d6b5c41fad91Andreas Gustafsson prop = Property(self.cur_object,
e482a1c91ecb5e47bc26617bf310d6b5c41fad91Andreas Gustafsson expect_attr(attrs, 'name'),
5827c8e0a69304cd111c46cabe8ca8704f6274f7Andreas Gustafsson expect_attr(attrs, 'type'),
5827c8e0a69304cd111c46cabe8ca8704f6274f7Andreas Gustafsson expect_attr(attrs, 'access'))
e482a1c91ecb5e47bc26617bf310d6b5c41fad91Andreas Gustafsson self.cur_object.properties.append(prop)
e482a1c91ecb5e47bc26617bf310d6b5c41fad91Andreas Gustafsson self.cur_object = prop
e482a1c91ecb5e47bc26617bf310d6b5c41fad91Andreas Gustafsson else:
e482a1c91ecb5e47bc26617bf310d6b5c41fad91Andreas Gustafsson self.state = STATE_IGNORED
e482a1c91ecb5e47bc26617bf310d6b5c41fad91Andreas Gustafsson
e482a1c91ecb5e47bc26617bf310d6b5c41fad91Andreas Gustafsson elif self.state == STATE_METHOD:
593cb00bd17e5e2ab0dcb7c635a9a81082dc5d0eAndreas Gustafsson if name == STATE_ARG:
e482a1c91ecb5e47bc26617bf310d6b5c41fad91Andreas Gustafsson self.state = STATE_ARG
f621719829356f27e831507b75e88e8a655e48d8Danny Mayer arg = Arg(self.cur_object,
593cb00bd17e5e2ab0dcb7c635a9a81082dc5d0eAndreas Gustafsson expect_attr(attrs, 'name'),
593cb00bd17e5e2ab0dcb7c635a9a81082dc5d0eAndreas Gustafsson expect_attr(attrs, 'type'))
123a3dddc94534d3a6c6f81c118a5b63dc5994c3Andreas Gustafsson direction = attrs.get('direction', 'in')
123a3dddc94534d3a6c6f81c118a5b63dc5994c3Andreas Gustafsson if direction == 'in':
593cb00bd17e5e2ab0dcb7c635a9a81082dc5d0eAndreas Gustafsson self.cur_object.in_args.append(arg)
e482a1c91ecb5e47bc26617bf310d6b5c41fad91Andreas Gustafsson elif direction == 'out':
674f1cfb1d7dfa92e52db950dbe80e60ef8f5cddBrian Wellington self.cur_object.out_args.append(arg)
674f1cfb1d7dfa92e52db950dbe80e60ef8f5cddBrian Wellington else:
593cb00bd17e5e2ab0dcb7c635a9a81082dc5d0eAndreas Gustafsson raise DBusXmlException('Invalid direction "%s"' % direction)
593cb00bd17e5e2ab0dcb7c635a9a81082dc5d0eAndreas Gustafsson self.cur_object = arg
674f1cfb1d7dfa92e52db950dbe80e60ef8f5cddBrian Wellington else:
593cb00bd17e5e2ab0dcb7c635a9a81082dc5d0eAndreas Gustafsson self.state = STATE_IGNORED
593cb00bd17e5e2ab0dcb7c635a9a81082dc5d0eAndreas Gustafsson
593cb00bd17e5e2ab0dcb7c635a9a81082dc5d0eAndreas Gustafsson elif self.state == STATE_SIGNAL:
593cb00bd17e5e2ab0dcb7c635a9a81082dc5d0eAndreas Gustafsson if name == STATE_ARG:
593cb00bd17e5e2ab0dcb7c635a9a81082dc5d0eAndreas Gustafsson self.state = STATE_ARG
593cb00bd17e5e2ab0dcb7c635a9a81082dc5d0eAndreas Gustafsson arg = Arg(self.cur_object,
674f1cfb1d7dfa92e52db950dbe80e60ef8f5cddBrian Wellington expect_attr(attrs, 'name'),
593cb00bd17e5e2ab0dcb7c635a9a81082dc5d0eAndreas Gustafsson expect_attr(attrs, 'type'))
593cb00bd17e5e2ab0dcb7c635a9a81082dc5d0eAndreas Gustafsson self.cur_object.args.append(arg)
593cb00bd17e5e2ab0dcb7c635a9a81082dc5d0eAndreas Gustafsson self.cur_object = arg
593cb00bd17e5e2ab0dcb7c635a9a81082dc5d0eAndreas Gustafsson else:
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson self.state = STATE_IGNORED
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews elif self.state == STATE_PROPERTY:
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews self.state = STATE_IGNORED
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews elif self.state == STATE_ARG:
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews self.state = STATE_IGNORED
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews else:
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews assert False, 'Unhandled state "%s" while entering element with name "%s"' % (self.state, name)
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews self.state_stack.append(old_state)
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews self.cur_object_stack.append(old_cur_object)
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews def handle_end_element(self, name):
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews if self.cur_object:
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews self.cur_object.validate()
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews self.state = self.state_stack.pop()
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews self.cur_object = self.cur_object_stack.pop()
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrewsdef parse_options():
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews parser = optparse.OptionParser("usage: %prog [options] introspect.xml ...")
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews parser.set_description("sbus_codegen generates sbus interface structures \
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews from standard XML Introspect data.")
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews parser.add_option("--mode",
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews dest="mode", default="header",
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews help="'header' or 'source' (default: header)",
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews metavar="MODE")
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews parser.add_option("--output",
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews dest="output", default=None,
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews help="Set output file name (default: stdout)",
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews metavar="FILE")
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews parser.add_option("--include",
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews dest="include", default=None,
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews help="name of a header to #include",
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews metavar="HEADER")
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews (options, args) = parser.parse_args()
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews if not args:
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews print >> sys.stderr, "sbus_codegen: no input file specified"
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews sys.exit(2)
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews if options.mode not in ["header", "source"]:
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews print >> sys.stderr, "sbus_codegen: specify --mode=header or --mode=source"
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews return options, args
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrewsdef main():
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews options, args = parse_options()
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews if options.output:
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews sys.stdout = buf = StringIO.StringIO()
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews for filename in args:
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews parser = DBusXMLParser(filename)
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews if options.mode == "header":
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews generate_header(parser.parsed_interfaces, filename)
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews elif options.mode == "source":
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews generate_source(parser.parsed_interfaces, filename, options.include)
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews else:
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews assert False, "should not be reached"
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews # Write output at end to be nice to 'make'
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews if options.output:
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews output = open(options.output, "w")
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews output.write(buf.getvalue())
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews output.close()
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrewsif __name__ == "__main__":
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews try:
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews main()
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews except DBusXmlException, ex:
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews print >> sys.stderr, str(ex)
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews sys.exit(1)
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews