sbus_codegen revision 58229439447d5617913a5a2e173b78105c694842
10e22ebcc3629be94d37bf408157e2c5ee5740e0Andreas Gustafsson#!/usr/bin/python
253f774e358dba38742a484426a4cadf4f248817Brian Wellington
253f774e358dba38742a484426a4cadf4f248817Brian Wellington#
253f774e358dba38742a484426a4cadf4f248817Brian Wellington# Authors:
2de31518c3da27092120b40fc373cecf600d64e6Brian Wellington# Stef Walter <stefw@redhat.com>
2de31518c3da27092120b40fc373cecf600d64e6Brian Wellington#
2de31518c3da27092120b40fc373cecf600d64e6Brian Wellington# Copyright (C) 2014 Red Hat
4ae3a03bb7dbb050adddc051a5df6f3de057eb27Andreas Gustafsson#
4ae3a03bb7dbb050adddc051a5df6f3de057eb27Andreas Gustafsson# This program is free software; you can redistribute it and/or modify
4ae3a03bb7dbb050adddc051a5df6f3de057eb27Andreas Gustafsson# it under the terms of the GNU General Public License as published by
4ae3a03bb7dbb050adddc051a5df6f3de057eb27Andreas Gustafsson# the Free Software Foundation; either version 3 of the License, or
10e22ebcc3629be94d37bf408157e2c5ee5740e0Andreas Gustafsson# (at your option) any later version.
10e22ebcc3629be94d37bf408157e2c5ee5740e0Andreas Gustafsson#
2732332fe53d00592109ef69c0075fcc2ad09db9Brian Wellington# This program is distributed in the hope that it will be useful,
2732332fe53d00592109ef69c0075fcc2ad09db9Brian Wellington# but WITHOUT ANY WARRANTY; without even the implied warranty of
2732332fe53d00592109ef69c0075fcc2ad09db9Brian Wellington# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
8fa78d9ad5f5ab6c69d1d52b00b1ffcdf1bd5bebMichael Sawyer# GNU General Public License for more details.
8fa78d9ad5f5ab6c69d1d52b00b1ffcdf1bd5bebMichael Sawyer#
8fa78d9ad5f5ab6c69d1d52b00b1ffcdf1bd5bebMichael Sawyer# You should have received a copy of the GNU General Public License
e544b507b8019a62c5d2716281f6832519a8791dDavid Lawrence# along with this program. If not, see <http://www.gnu.org/licenses/>.
e544b507b8019a62c5d2716281f6832519a8791dDavid Lawrence#
e544b507b8019a62c5d2716281f6832519a8791dDavid Lawrence
09de21079e902c7356d936ef4f2a31060b36e5f3Brian Wellington#
09de21079e902c7356d936ef4f2a31060b36e5f3Brian Wellington# Some parser code from GLib
09de21079e902c7356d936ef4f2a31060b36e5f3Brian Wellington#
ee4429e13e08f30c366cdc5d10585388b8a9f212Michael Sawyer# Copyright (C) 2008-2011 Red Hat, Inc.
ee4429e13e08f30c366cdc5d10585388b8a9f212Michael Sawyer#
b8b9fa222645f250a0f09eb30da5af752941660cDavid Lawrence# This library is free software; you can redistribute it and/or
b8b9fa222645f250a0f09eb30da5af752941660cDavid Lawrence# modify it under the terms of the GNU Lesser General Public
3c7ce471aa8a1a9c5bc0ca9e41f406bdc9f0b2aeAndreas Gustafsson# License as published by the Free Software Foundation; either
8aff41ca8ac8dbd9671f3da824406a8783db49d1Brian Wellington# version 2 of the License, or (at your option) any later version.
8aff41ca8ac8dbd9671f3da824406a8783db49d1Brian Wellington#
8aff41ca8ac8dbd9671f3da824406a8783db49d1Brian Wellington# This library is distributed in the hope that it will be useful,
c9d7e543d0da2996d1cc52d3c5920141df49a4ecBrian Wellington# but WITHOUT ANY WARRANTY; without even the implied warranty of
c9d7e543d0da2996d1cc52d3c5920141df49a4ecBrian Wellington# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
6dbf9cbe6a39a00de910ef843b9f864abf68bc40Brian Wellington# Lesser General Public License for more details.
6dbf9cbe6a39a00de910ef843b9f864abf68bc40Brian Wellington#
6dbf9cbe6a39a00de910ef843b9f864abf68bc40Brian Wellington# You should have received a copy of the GNU Lesser General
17aac384e029f5dd3314876058c7501f4d84b90bBrian Wellington# Public License along with this library; if not, write to the
17aac384e029f5dd3314876058c7501f4d84b90bBrian Wellington# Free Software Foundation, Inc., 59 Temple Place, Suite 330,
833535ea78ec7a15376b862fd288ffd00f808666Brian Wellington# Boston, MA 02111-1307, USA.
17aac384e029f5dd3314876058c7501f4d84b90bBrian Wellington#
23f64ea0dcd7f5b7094ae6ade2a002fb7dde1466Brian Wellington# Portions by: David Zeuthen <davidz@redhat.com>
23f64ea0dcd7f5b7094ae6ade2a002fb7dde1466Brian Wellington#
23f64ea0dcd7f5b7094ae6ade2a002fb7dde1466Brian Wellington
3c7ce471aa8a1a9c5bc0ca9e41f406bdc9f0b2aeAndreas Gustafsson#
3c7ce471aa8a1a9c5bc0ca9e41f406bdc9f0b2aeAndreas Gustafsson# DBus interfaces are defined here:
3c7ce471aa8a1a9c5bc0ca9e41f406bdc9f0b2aeAndreas Gustafsson#
3c7ce471aa8a1a9c5bc0ca9e41f406bdc9f0b2aeAndreas Gustafsson# http://dbus.freedesktop.org/doc/dbus-specification.html#introspection-format
3562c9dc12f06eb964ccefd3291a012f4e6b1743Brian Wellington#
3562c9dc12f06eb964ccefd3291a012f4e6b1743Brian Wellington# The introspection data format has become the standard way to represent a
3562c9dc12f06eb964ccefd3291a012f4e6b1743Brian Wellington# DBus interface. For many examples see /usr/share/dbus-1/interfaces/ on a
4d5c668a91c6e5a26653031dd137292bfc03da52Andreas Gustafsson# typical linux machine.
f437f6ffae28f88334cf47ce8f948cbf40331ffaAndreas Gustafsson#
f437f6ffae28f88334cf47ce8f948cbf40331ffaAndreas Gustafsson# A word about annotations. These are extra flags or values that can be
704d6eeab1d8d6a2aeb99c37fa5a97322d9340fcBrian Wellington# assigned to anything. So far, the codegen supports this annotation:
704d6eeab1d8d6a2aeb99c37fa5a97322d9340fcBrian Wellington#
704d6eeab1d8d6a2aeb99c37fa5a97322d9340fcBrian Wellington# org.freedesktop.DBus.GLib.CSymbol
ed8ba54e644957e0ebd51601552193275299ca8dAndreas Gustafsson# - An annotation specified in the specification that tells us what C symbol
ed8ba54e644957e0ebd51601552193275299ca8dAndreas Gustafsson# to generate for a given interface or method. By default the codegen will
ed8ba54e644957e0ebd51601552193275299ca8dAndreas Gustafsson# build up a symbol name from the DBus name.
4d5c668a91c6e5a26653031dd137292bfc03da52Andreas Gustafsson#
4d5c668a91c6e5a26653031dd137292bfc03da52Andreas Gustafsson
4d5c668a91c6e5a26653031dd137292bfc03da52Andreas Gustafssonimport optparse
5a6335a8bffdcc15ab4b3bb01d070080f9bc892eMark Andrewsimport os
5a6335a8bffdcc15ab4b3bb01d070080f9bc892eMark Andrewsimport re
9c566a852f31c3a5d0b9d6eaf11463114339c01dAndreas Gustafssonimport StringIO
9c566a852f31c3a5d0b9d6eaf11463114339c01dAndreas Gustafssonimport sys
9c566a852f31c3a5d0b9d6eaf11463114339c01dAndreas Gustafssonimport xml.parsers.expat
9c566a852f31c3a5d0b9d6eaf11463114339c01dAndreas Gustafsson
9c566a852f31c3a5d0b9d6eaf11463114339c01dAndreas Gustafsson# -----------------------------------------------------------------------------
9c566a852f31c3a5d0b9d6eaf11463114339c01dAndreas Gustafsson# Objects
9c566a852f31c3a5d0b9d6eaf11463114339c01dAndreas Gustafsson
9c566a852f31c3a5d0b9d6eaf11463114339c01dAndreas Gustafssonclass DBusXmlException(Exception):
4c08b67a5f01eda472a9dfee4c73dbbac49c0065Mark Andrews line = 0
4c08b67a5f01eda472a9dfee4c73dbbac49c0065Mark Andrews file = None
f8abaa0fae7f75d9601c10b6a4af8dd907494d45Mark Andrews
f8abaa0fae7f75d9601c10b6a4af8dd907494d45Mark Andrews # Lets us print problems like a compiler would
f8abaa0fae7f75d9601c10b6a4af8dd907494d45Mark Andrews def __str__(self):
1addbb84718fdb7635459ed05f060be086e88f35Andreas Gustafsson message = Exception.__str__(self)
1addbb84718fdb7635459ed05f060be086e88f35Andreas Gustafsson if self.file and self.line:
1addbb84718fdb7635459ed05f060be086e88f35Andreas Gustafsson return "%s:%d: %s" % (self.file, self.line, message)
1addbb84718fdb7635459ed05f060be086e88f35Andreas Gustafsson elif self.file:
1addbb84718fdb7635459ed05f060be086e88f35Andreas Gustafsson return "%s: %s" % (self.file, message)
1addbb84718fdb7635459ed05f060be086e88f35Andreas Gustafsson else:
d3be9a9c6ef76a5d7671b0962785ca025b153d2bAndreas Gustafsson return message
d3be9a9c6ef76a5d7671b0962785ca025b153d2bAndreas Gustafsson
d3be9a9c6ef76a5d7671b0962785ca025b153d2bAndreas Gustafssonclass Base:
e9fce1415f8be4cd38d528950c92c481bd105254Mark Andrews def __init__(self, name):
e9fce1415f8be4cd38d528950c92c481bd105254Mark Andrews if not name:
e9fce1415f8be4cd38d528950c92c481bd105254Mark Andrews raise DBusXmlException('No name on element')
483958540f0034d543f0564beb7877326f15a45bMark Andrews self.name = name
483958540f0034d543f0564beb7877326f15a45bMark Andrews self.annotations = { }
59e1a928bc4253b91ead0f7c46be7d3984cb3016Bob Halley def validate(self):
90cd33e0baf23574a88a4c967afec8b95a1801deAndreas Gustafsson pass
90cd33e0baf23574a88a4c967afec8b95a1801deAndreas Gustafsson def c_name(self):
90cd33e0baf23574a88a4c967afec8b95a1801deAndreas Gustafsson return self.annotations.get("org.freedesktop.DBus.GLib.CSymbol", self.name)
90cd33e0baf23574a88a4c967afec8b95a1801deAndreas Gustafsson
517950ae99fa271b034a5cfec1c9fbb62696f975Mark Andrews# The basic types that we support marshalling right now. These
517950ae99fa271b034a5cfec1c9fbb62696f975Mark Andrews# are the ones we can pass as basic arguments to libdbus directly.
517950ae99fa271b034a5cfec1c9fbb62696f975Mark Andrews# If the dbus and sssd types are identical we pass things directly.
f9870620b346ed267023dc98ee81adcfef2e16b7Andreas Gustafsson# otherwise some copying is necessary.
f9870620b346ed267023dc98ee81adcfef2e16b7Andreas GustafssonBASIC_TYPES = {
dfd7798d8b870abf03795d8095297a4b982ab6e9Mark Andrews 'y': ( "DBUS_TYPE_BYTE", "uint8_t", "uint8_t" ),
19ff7edc1a6388085193f5487e1599f45aa62648Mark Andrews 'b': ( "DBUS_TYPE_BOOLEAN", "dbus_bool_t", "bool" ),
19ff7edc1a6388085193f5487e1599f45aa62648Mark Andrews 'n': ( "DBUS_TYPE_INT16", "int16_t", "int16_t" ),
19ff7edc1a6388085193f5487e1599f45aa62648Mark Andrews 'q': ( "DBUS_TYPE_UINT16", "uint16_t", "uint16_t" ),
8a0ff6c15cb20c903f9e16a3d5c2cab603478bc3Mark Andrews 'i': ( "DBUS_TYPE_INT32", "int32_t", "int32_t" ),
8a0ff6c15cb20c903f9e16a3d5c2cab603478bc3Mark Andrews 'u': ( "DBUS_TYPE_UINT32", "uint32_t", "uint32_t" ),
8a0ff6c15cb20c903f9e16a3d5c2cab603478bc3Mark Andrews 'x': ( "DBUS_TYPE_INT64", "int64_t", "int64_t" ),
8a0ff6c15cb20c903f9e16a3d5c2cab603478bc3Mark Andrews 't': ( "DBUS_TYPE_UINT64", "uint64_t", "uint64_t" ),
a6dbd6b6604e27ae3c7190de20dbcaaa6e5a1fd8Andreas Gustafsson 'd': ( "DBUS_TYPE_DOUBLE", "double", "double" ),
42928d936e79dbda7ea00bbcab6e5d8034a95bf8Andreas Gustafsson 's': ( "DBUS_TYPE_STRING", "const char *", "const char *" ),
0c0619cc1983ff58e855c5159d8892e46dddac5eBrian Wellington 'o': ( "DBUS_TYPE_OBJECT_PATH", "const char *", "const char *" ),
0c0619cc1983ff58e855c5159d8892e46dddac5eBrian Wellington}
c472ead4a932f93251eddaa41e120c3bfc4f95a4Andreas Gustafsson
c472ead4a932f93251eddaa41e120c3bfc4f95a4Andreas Gustafssonclass Typed(Base):
c472ead4a932f93251eddaa41e120c3bfc4f95a4Andreas Gustafsson def __init__(self, name, type):
d7e77a9b59138e8a94d3dfa4e41e1852ad51ac25Andreas Gustafsson Base.__init__(self, name)
c472ead4a932f93251eddaa41e120c3bfc4f95a4Andreas Gustafsson self.type = type
a6dbd6b6604e27ae3c7190de20dbcaaa6e5a1fd8Andreas Gustafsson self.is_basic = False
a6dbd6b6604e27ae3c7190de20dbcaaa6e5a1fd8Andreas Gustafsson self.is_array = False
a6dbd6b6604e27ae3c7190de20dbcaaa6e5a1fd8Andreas Gustafsson self.dbus_constant = None
383665e42ad838046472e847b16c4e0d3f1aaf76Bob Halley self.dbus_type = None
383665e42ad838046472e847b16c4e0d3f1aaf76Bob Halley self.sssd_type = None
383665e42ad838046472e847b16c4e0d3f1aaf76Bob Halley if type[0] == 'a':
383665e42ad838046472e847b16c4e0d3f1aaf76Bob Halley type = type[1:]
383665e42ad838046472e847b16c4e0d3f1aaf76Bob Halley self.is_array = True
383665e42ad838046472e847b16c4e0d3f1aaf76Bob Halley if type in BASIC_TYPES:
383665e42ad838046472e847b16c4e0d3f1aaf76Bob Halley (self.dbus_constant, self.dbus_type, self.sssd_type) = BASIC_TYPES[type]
6b5a6fbe1cc0ceb7e2b516aaada596b79360a5b8Bob Halley # If types are not identical, we can't do array (yet)
6b5a6fbe1cc0ceb7e2b516aaada596b79360a5b8Bob Halley if self.is_array:
6b5a6fbe1cc0ceb7e2b516aaada596b79360a5b8Bob Halley self.is_basic = (self.dbus_type == self.sssd_type)
5bbed85a33186db4e629e98f45ca702ac6b09127Brian Wellington else:
ba6fd2580863759baedd9c47153602b19006a324Andreas Gustafsson self.is_basic = True
ba6fd2580863759baedd9c47153602b19006a324Andreas Gustafsson
ba6fd2580863759baedd9c47153602b19006a324Andreas Gustafssonclass Arg(Typed):
ba6fd2580863759baedd9c47153602b19006a324Andreas Gustafsson def __init__(self, method, name, type):
ba6fd2580863759baedd9c47153602b19006a324Andreas Gustafsson Typed.__init__(self, name, type)
ba6fd2580863759baedd9c47153602b19006a324Andreas Gustafsson self.method = method
86a4d80e0624a10b1824d25018246e1ea63f55d2Andreas Gustafsson
86a4d80e0624a10b1824d25018246e1ea63f55d2Andreas Gustafssonclass Method(Base):
850d70818503ca1b0f98c9c70b16b51e789fd705Andreas Gustafsson def __init__(self, iface, name):
dd16d9d9e77c2d906ee5ffa3dd9f71cacfbcb081Brian Wellington Base.__init__(self, name)
dd16d9d9e77c2d906ee5ffa3dd9f71cacfbcb081Brian Wellington self.iface = iface
d3a86da2e8f09e2c3f55721aae537b9cacc7e537Andreas Gustafsson self.in_args = []
d3a86da2e8f09e2c3f55721aae537b9cacc7e537Andreas Gustafsson self.out_args = []
d3a86da2e8f09e2c3f55721aae537b9cacc7e537Andreas Gustafsson def validate(self):
d3a86da2e8f09e2c3f55721aae537b9cacc7e537Andreas Gustafsson if not self.only_basic_args() and not self.use_raw_handler():
850d70818503ca1b0f98c9c70b16b51e789fd705Andreas Gustafsson raise DBusXmlException("Method has complex arguments and requires " +
850d70818503ca1b0f98c9c70b16b51e789fd705Andreas Gustafsson "the 'org.freedesktop.sssd.RawHandler' annotation")
3c82f274bd880a33fdaf211af4fe8f6b3d6ca556David Lawrence def fq_c_name(self):
3c82f274bd880a33fdaf211af4fe8f6b3d6ca556David Lawrence return "%s_%s" % (self.iface.c_name(), self.c_name())
3c82f274bd880a33fdaf211af4fe8f6b3d6ca556David Lawrence def use_raw_handler(self):
3c82f274bd880a33fdaf211af4fe8f6b3d6ca556David Lawrence anno = 'org.freedesktop.sssd.RawHandler'
3c82f274bd880a33fdaf211af4fe8f6b3d6ca556David Lawrence return self.annotations.get(anno, self.iface.annotations.get(anno)) == 'true'
3c82f274bd880a33fdaf211af4fe8f6b3d6ca556David Lawrence def in_signature(self):
3c82f274bd880a33fdaf211af4fe8f6b3d6ca556David Lawrence return "".join([arg.type for arg in self.in_args])
3c82f274bd880a33fdaf211af4fe8f6b3d6ca556David Lawrence def only_basic_args(self):
3c82f274bd880a33fdaf211af4fe8f6b3d6ca556David Lawrence for arg in self.in_args + self.out_args:
3c82f274bd880a33fdaf211af4fe8f6b3d6ca556David Lawrence if not arg.is_basic:
3c82f274bd880a33fdaf211af4fe8f6b3d6ca556David Lawrence return False
3c82f274bd880a33fdaf211af4fe8f6b3d6ca556David Lawrence return True
3c82f274bd880a33fdaf211af4fe8f6b3d6ca556David Lawrence
3c82f274bd880a33fdaf211af4fe8f6b3d6ca556David Lawrenceclass Signal(Base):
5afc10d6d8278c9ab34b9f6c82ef7bb3bfefd0efAndreas Gustafsson def __init__(self, iface, name):
78d78f05d91205cbde33ca87d24b8d13aa2d8d66Brian Wellington Base.__init__(self, name)
78d78f05d91205cbde33ca87d24b8d13aa2d8d66Brian Wellington self.iface = iface
78d78f05d91205cbde33ca87d24b8d13aa2d8d66Brian Wellington self.args = []
78d78f05d91205cbde33ca87d24b8d13aa2d8d66Brian Wellington def fq_c_name(self):
5afc10d6d8278c9ab34b9f6c82ef7bb3bfefd0efAndreas Gustafsson return "%s_%s" % (self.iface.c_name(), self.c_name())
5afc10d6d8278c9ab34b9f6c82ef7bb3bfefd0efAndreas Gustafsson
5afc10d6d8278c9ab34b9f6c82ef7bb3bfefd0efAndreas Gustafssonclass Property(Typed):
5afc10d6d8278c9ab34b9f6c82ef7bb3bfefd0efAndreas Gustafsson def __init__(self, iface, name, type, access):
3f01dde0bd24561fc3a6c2f7e259a58af4457a86Brian Wellington Typed.__init__(self, name, type)
3f01dde0bd24561fc3a6c2f7e259a58af4457a86Brian Wellington self.iface = iface
3f01dde0bd24561fc3a6c2f7e259a58af4457a86Brian Wellington self.readable = False
626b221f7113479a0709f0bb0a8193c0ab0dcf84Andreas Gustafsson self.writable = False
626b221f7113479a0709f0bb0a8193c0ab0dcf84Andreas Gustafsson if access == 'readwrite':
626b221f7113479a0709f0bb0a8193c0ab0dcf84Andreas Gustafsson self.readable = True
626b221f7113479a0709f0bb0a8193c0ab0dcf84Andreas Gustafsson self.writable = True
733e928f714c848aa394c2d12b6239bc7780101bMark Andrews elif access == 'read':
733e928f714c848aa394c2d12b6239bc7780101bMark Andrews self.readable = True
c379c1bddb2d84c9219ab6c394b33aa866b9f3bfAndreas Gustafsson elif access == 'write':
febaa091847ab004f40500cc475a819f2c73fcddAndreas Gustafsson self.writable = True
febaa091847ab004f40500cc475a819f2c73fcddAndreas Gustafsson else:
ebfcb6cf66283096ebda1503b6cc042ce86b6bedBrian Wellington raise DBusXmlException('Invalid access type %s'%self.access)
ebfcb6cf66283096ebda1503b6cc042ce86b6bedBrian Wellington def fq_c_name(self):
c379c1bddb2d84c9219ab6c394b33aa866b9f3bfAndreas Gustafsson return "%s_%s" % (self.iface.c_name(), self.c_name())
c379c1bddb2d84c9219ab6c394b33aa866b9f3bfAndreas Gustafsson def getter_name(self):
c379c1bddb2d84c9219ab6c394b33aa866b9f3bfAndreas Gustafsson return "%s_get_%s" % (self.iface.c_name(), self.c_name())
066faef1195d539f575816ccab87ff3e85b1b13eBrian Wellington def getter_invoker_name(self):
dffdc24ffd76ef3d8c8141671e89fb39428fef06Brian Wellington return "invoke_get_%s" % self.type
17442ccc2b2e9c3b3bfc337f0fdfad6186fbb123Mark Andrews def getter_signature(self, name):
17442ccc2b2e9c3b3bfc337f0fdfad6186fbb123Mark Andrews sig = "void (*%s)(struct sbus_request *, void *data, %s *" % (name, self.sssd_type)
61b0df9eb522f13aef13cc2704728e799cbc251aMichael Sawyer if self.is_array:
61b0df9eb522f13aef13cc2704728e799cbc251aMichael Sawyer sig += " *, int *"
61b0df9eb522f13aef13cc2704728e799cbc251aMichael Sawyer sig += ")"
61b0df9eb522f13aef13cc2704728e799cbc251aMichael Sawyer return sig
369bb68c2c7709c7fd8b0d6c1d1f8abc6422a7e2Michael Sawyer
369bb68c2c7709c7fd8b0d6c1d1f8abc6422a7e2Michael Sawyerclass Interface(Base):
369bb68c2c7709c7fd8b0d6c1d1f8abc6422a7e2Michael Sawyer def __init__(self, name):
369bb68c2c7709c7fd8b0d6c1d1f8abc6422a7e2Michael Sawyer Base.__init__(self, name)
3dcb97b199693012d12e978b8f577a339e434361Andreas Gustafsson self.methods = []
3dcb97b199693012d12e978b8f577a339e434361Andreas Gustafsson self.signals = []
a3e41e3c03a32b00fc243fce538a39ddc7237885Andreas Gustafsson self.properties = []
a3e41e3c03a32b00fc243fce538a39ddc7237885Andreas Gustafsson def c_name(self):
a3e41e3c03a32b00fc243fce538a39ddc7237885Andreas Gustafsson return self.annotations.get("org.freedesktop.DBus.GLib.CSymbol",
a3e41e3c03a32b00fc243fce538a39ddc7237885Andreas Gustafsson self.name.replace(".", "_"))
4ec1a96d90784f70380bdec66f8a0bd6718a5b71Mark Andrews
fa3cbea8bfba19d1c11f9a6ad20f40a2c15377f0Brian Wellington# -----------------------------------------------------------------------------
fa3cbea8bfba19d1c11f9a6ad20f40a2c15377f0Brian Wellington# Code Generation
0fc89c4ee660e825ac66774f2d4912cfc396386aMark Andrews
0fc89c4ee660e825ac66774f2d4912cfc396386aMark Andrewsdef out(format, *args, **kwargs):
e21d199dca95aff5d50f133d6b064309e209af00Brian Wellington str = format % args
e21d199dca95aff5d50f133d6b064309e209af00Brian Wellington sys.stdout.write(str)
c03298d879554fc5dc197c28fd4b686e0d880ee3Mark Andrews # NOTE: Would like to use the following syntax for this function
c03298d879554fc5dc197c28fd4b686e0d880ee3Mark Andrews # but need to wait until python3 until it is supported:
04c22ceaf2d3812eaab69d79958d0e0d62048cd2Mark Andrews # def out(format, *args, new_line=True)
04c22ceaf2d3812eaab69d79958d0e0d62048cd2Mark Andrews if kwargs.pop("new_line", True):
04c22ceaf2d3812eaab69d79958d0e0d62048cd2Mark Andrews sys.stdout.write("\n")
04c22ceaf2d3812eaab69d79958d0e0d62048cd2Mark Andrews assert not kwargs, "unknown keyword argument(s): %s" % str(kwargs)
04c22ceaf2d3812eaab69d79958d0e0d62048cd2Mark Andrews
04c22ceaf2d3812eaab69d79958d0e0d62048cd2Mark Andrewsdef method_arg_types(args, with_names=False):
04c22ceaf2d3812eaab69d79958d0e0d62048cd2Mark Andrews str = ""
6ef15459b8fd3fc8b5672da4ad72c19a755dbe45Mark Andrews for arg in args:
b65f2ab14abb4b6ef906d7d02064fba158f07b1eDavid Lawrence str += ", "
b65f2ab14abb4b6ef906d7d02064fba158f07b1eDavid Lawrence str += arg.sssd_type
b65f2ab14abb4b6ef906d7d02064fba158f07b1eDavid Lawrence if with_names:
b65f2ab14abb4b6ef906d7d02064fba158f07b1eDavid Lawrence if str[-1] != '*':
b65f2ab14abb4b6ef906d7d02064fba158f07b1eDavid Lawrence str += " "
b65f2ab14abb4b6ef906d7d02064fba158f07b1eDavid Lawrence str += "arg_"
c03bb27f0675a6e60ceea66b451548e8481bc05cMark Andrews str += arg.c_name()
c03bb27f0675a6e60ceea66b451548e8481bc05cMark Andrews if arg.is_array:
c03bb27f0675a6e60ceea66b451548e8481bc05cMark Andrews str += "[], int"
b65f2ab14abb4b6ef906d7d02064fba158f07b1eDavid Lawrence if with_names:
b65f2ab14abb4b6ef906d7d02064fba158f07b1eDavid Lawrence str += " len_"
c03bb27f0675a6e60ceea66b451548e8481bc05cMark Andrews str += arg.c_name()
c03bb27f0675a6e60ceea66b451548e8481bc05cMark Andrews return str
c03bb27f0675a6e60ceea66b451548e8481bc05cMark Andrews
389c749a5ee18f1c0d6278ae49f2aae5d5f0d2dcMark Andrewsdef method_function_pointer(meth, name, with_names=False):
389c749a5ee18f1c0d6278ae49f2aae5d5f0d2dcMark Andrews if meth.use_raw_handler():
72fa265baa3d138b43427bcb5c0838740f807045Mark Andrews return "sbus_msg_handler_fn " + name
72fa265baa3d138b43427bcb5c0838740f807045Mark Andrews else:
72fa265baa3d138b43427bcb5c0838740f807045Mark Andrews return "int (*%s)(struct sbus_request *%s, void *%s%s)" % \
4b6d5b2312d1482cc406fe58fa3269dd7a915b3fMark Andrews (name, with_names and "req" or "",
4b6d5b2312d1482cc406fe58fa3269dd7a915b3fMark Andrews with_names and "data" or "",
4b6d5b2312d1482cc406fe58fa3269dd7a915b3fMark Andrews method_arg_types(meth.in_args, with_names))
4b6d5b2312d1482cc406fe58fa3269dd7a915b3fMark Andrews
29c818c7d40fc8898b062903ec703851328a4deaMark Andrewsdef property_handlers(prop):
29c818c7d40fc8898b062903ec703851328a4deaMark Andrews return prop.getter_signature(prop.getter_name())
b1cde6bf3a8e3a77eb77caf97df0d7ec5c8450dfBrian Wellington
b1cde6bf3a8e3a77eb77caf97df0d7ec5c8450dfBrian Wellingtondef forward_method_invoker(signature, args):
b1cde6bf3a8e3a77eb77caf97df0d7ec5c8450dfBrian Wellington out("")
f8abaa0fae7f75d9601c10b6a4af8dd907494d45Mark Andrews out("/* invokes a handler with a '%s' DBus signature */", signature)
f8abaa0fae7f75d9601c10b6a4af8dd907494d45Mark Andrews out("static int invoke_%s_method(struct sbus_request *dbus_req, void *function_ptr);", signature)
f8abaa0fae7f75d9601c10b6a4af8dd907494d45Mark Andrews
f8abaa0fae7f75d9601c10b6a4af8dd907494d45Mark Andrewsdef source_method_invoker(signature, args):
28b7844ee93231da831ba3c090e1677bb1be5f18Andreas Gustafsson out("")
37d1c8ee546ae89720c3e17e57ee3a05e9cdc7b9Brian Wellington out("/* invokes a handler with a '%s' DBus signature */", signature)
37d1c8ee546ae89720c3e17e57ee3a05e9cdc7b9Brian Wellington out("static int invoke_%s_method(struct sbus_request *dbus_req, void *function_ptr)", signature)
37d1c8ee546ae89720c3e17e57ee3a05e9cdc7b9Brian Wellington out("{")
28b7844ee93231da831ba3c090e1677bb1be5f18Andreas Gustafsson for i in range(0, len(args)):
28b7844ee93231da831ba3c090e1677bb1be5f18Andreas Gustafsson arg = args[i]
28b7844ee93231da831ba3c090e1677bb1be5f18Andreas Gustafsson if arg.is_array:
28b7844ee93231da831ba3c090e1677bb1be5f18Andreas Gustafsson out(" %s *arg_%d;", arg.dbus_type, i)
28b7844ee93231da831ba3c090e1677bb1be5f18Andreas Gustafsson out(" int len_%d;", i)
28b7844ee93231da831ba3c090e1677bb1be5f18Andreas Gustafsson else:
78db9e8f4b686fde6dfa0ec85a68c06cc9d4bf28Brian Wellington out(" %s arg_%d;", arg.dbus_type, i)
78db9e8f4b686fde6dfa0ec85a68c06cc9d4bf28Brian Wellington out(" int (*handler)(struct sbus_request *, void *%s) = function_ptr;", method_arg_types(args))
78db9e8f4b686fde6dfa0ec85a68c06cc9d4bf28Brian Wellington out("")
78db9e8f4b686fde6dfa0ec85a68c06cc9d4bf28Brian Wellington out(" if (!sbus_request_parse_or_finish(dbus_req,")
78db9e8f4b686fde6dfa0ec85a68c06cc9d4bf28Brian Wellington for i in range(0, len(args)):
b20ee662a7c847c9ef7b96ab9e5e34543efe5c0dMark Andrews arg = args[i]
b20ee662a7c847c9ef7b96ab9e5e34543efe5c0dMark Andrews if arg.is_array:
b20ee662a7c847c9ef7b96ab9e5e34543efe5c0dMark Andrews out(" DBUS_TYPE_ARRAY, %s, &arg_%d, &len_%d,",
450995b90c8cb66d82c2377d4f9bd9812a132c30Andreas Gustafsson arg.dbus_constant, i, i)
450995b90c8cb66d82c2377d4f9bd9812a132c30Andreas Gustafsson else:
450995b90c8cb66d82c2377d4f9bd9812a132c30Andreas Gustafsson out(" %s, &arg_%d,", arg.dbus_constant, i)
f90fe7c8b9a3eef8968fac74905e868c8ab583a3Brian Wellington out(" DBUS_TYPE_INVALID)) {")
190fbe9738bd0c1b9b13732bb8bd56b2b7c71640David Lawrence out(" return EOK; /* request handled */")
190fbe9738bd0c1b9b13732bb8bd56b2b7c71640David Lawrence out(" }")
190fbe9738bd0c1b9b13732bb8bd56b2b7c71640David Lawrence out("")
190fbe9738bd0c1b9b13732bb8bd56b2b7c71640David Lawrence
190fbe9738bd0c1b9b13732bb8bd56b2b7c71640David Lawrence out(" return (handler)(dbus_req, dbus_req->intf->instance_data", new_line=False)
190fbe9738bd0c1b9b13732bb8bd56b2b7c71640David Lawrence for i in range(0, len(args)):
190fbe9738bd0c1b9b13732bb8bd56b2b7c71640David Lawrence arg = args[i]
c40085afa75a5eae732ec1198384dd5cb24400b6Bob Halley out(",\n arg_%d", i, new_line=False)
c40085afa75a5eae732ec1198384dd5cb24400b6Bob Halley if arg.is_array:
7b438bdb9b821f9f1c96443762072e137716048dBrian Wellington out(",\n len_%d", i, new_line=False)
c40085afa75a5eae732ec1198384dd5cb24400b6Bob Halley out(");")
c40085afa75a5eae732ec1198384dd5cb24400b6Bob Halley out("}")
c40085afa75a5eae732ec1198384dd5cb24400b6Bob Halley
7b438bdb9b821f9f1c96443762072e137716048dBrian Wellingtondef source_getter_invoker(prop):
c40085afa75a5eae732ec1198384dd5cb24400b6Bob Halley out("")
c40085afa75a5eae732ec1198384dd5cb24400b6Bob Halley if prop.is_array:
c40085afa75a5eae732ec1198384dd5cb24400b6Bob Halley out("/* invokes a getter with an array of '%s' DBus type */", prop.dbus_type)
c40085afa75a5eae732ec1198384dd5cb24400b6Bob Halley else:
7b438bdb9b821f9f1c96443762072e137716048dBrian Wellington out("/* invokes a getter with a '%s' DBus type */", prop.dbus_type)
c40085afa75a5eae732ec1198384dd5cb24400b6Bob Halley out("static int %s(struct sbus_request *dbus_req, void *function_ptr)",
86c270cbb24117976d6cd3098c3010e067915c24Andreas Gustafsson prop.getter_invoker_name())
86c270cbb24117976d6cd3098c3010e067915c24Andreas Gustafsson out("{")
10258f6b3d1ce54ffb22e6b9a31f8f001f7ee2d5Mark Andrews if prop.is_array:
b38ebe307cb2411535c79afd441870a99cc50eddMark Andrews out(" %s *prop_val;", prop.sssd_type)
b38ebe307cb2411535c79afd441870a99cc50eddMark Andrews out(" int prop_len;")
b38ebe307cb2411535c79afd441870a99cc50eddMark Andrews out(" %s *out_val;", prop.dbus_type)
c2e0aac879097f81bcd31e3d09660a71e70c5fb0Michael Sawyer else:
8217f91f8d2dd6e94a2bf893284506ea47cd294aAndreas Gustafsson out(" %s prop_val;", prop.sssd_type)
c2e0aac879097f81bcd31e3d09660a71e70c5fb0Michael Sawyer out(" %s out_val;", prop.dbus_type)
21a170a0cee1ec2df7be0ce334da309f9a892ea9Andreas Gustafsson out("")
588b63e1a86fb707172830e14897da624ed380edMark Andrews out(" %s", prop.getter_signature("handler"), new_line=False)
588b63e1a86fb707172830e14897da624ed380edMark Andrews out(" = function_ptr;")
bb17aa91c14de959b191a200df61afb6a68f110fBrian Wellington out("")
bb17aa91c14de959b191a200df61afb6a68f110fBrian Wellington
bb17aa91c14de959b191a200df61afb6a68f110fBrian Wellington out(" (handler)(dbus_req, dbus_req->intf->instance_data, &prop_val", new_line=False)
452d75b18f9d050086964fa39c326cf388517396Mark Andrews if prop.is_array:
452d75b18f9d050086964fa39c326cf388517396Mark Andrews out(", &prop_len", new_line=False)
2b4db0b6d4b5a0307cecbafdd1d34d6f61b7dbadMark Andrews out(");")
2b4db0b6d4b5a0307cecbafdd1d34d6f61b7dbadMark Andrews
6850cdd4497424c9d42ade487edfde9fb9a47de9Brian Wellington out("")
6850cdd4497424c9d42ade487edfde9fb9a47de9Brian Wellington if prop.type == "s":
6850cdd4497424c9d42ade487edfde9fb9a47de9Brian Wellington out(" out_val = prop_val == NULL ? \"\" : prop_val;")
6850cdd4497424c9d42ade487edfde9fb9a47de9Brian Wellington else:
2a37aa188c2297e0c0856c3e5740c43dd426a432Mark Andrews out(" out_val = prop_val;")
2a37aa188c2297e0c0856c3e5740c43dd426a432Mark Andrews if prop.is_array:
2a37aa188c2297e0c0856c3e5740c43dd426a432Mark Andrews 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)
6c87cf19970a9eef43c1e38227cd23b3a2f6151aMark Andrews else:
6c87cf19970a9eef43c1e38227cd23b3a2f6151aMark Andrews out(" return sbus_request_return_as_variant(dbus_req, %s, &out_val);", prop.dbus_constant)
7869b99dc815e3b863351b8095d1b71b3f583541Brian Wellington out("}")
7869b99dc815e3b863351b8095d1b71b3f583541Brian Wellington
df1e829dde71ab960545453e4ae439ae601d5a9eMark Andrewsdef forward_method_invokers(ifaces):
df1e829dde71ab960545453e4ae439ae601d5a9eMark Andrews invokers = { }
df1e829dde71ab960545453e4ae439ae601d5a9eMark Andrews for iface in ifaces:
df1e829dde71ab960545453e4ae439ae601d5a9eMark Andrews for meth in iface.methods:
df1e829dde71ab960545453e4ae439ae601d5a9eMark Andrews if meth.use_raw_handler() or not meth.in_args:
df1e829dde71ab960545453e4ae439ae601d5a9eMark Andrews continue
fb04db11ee6aad3ac3e023ab89b5f9d8a4d5674dMichael Sawyer signature = meth.in_signature()
fb04db11ee6aad3ac3e023ab89b5f9d8a4d5674dMichael Sawyer if signature in invokers:
fb04db11ee6aad3ac3e023ab89b5f9d8a4d5674dMichael Sawyer continue
fb04db11ee6aad3ac3e023ab89b5f9d8a4d5674dMichael Sawyer forward_method_invoker(signature, meth.in_args)
fb04db11ee6aad3ac3e023ab89b5f9d8a4d5674dMichael Sawyer invokers[signature] = meth
fb04db11ee6aad3ac3e023ab89b5f9d8a4d5674dMichael Sawyer return invokers
cef18335b7f37bf02bc9e9f2c8750a3a9dcd718aAndreas Gustafsson
fb04db11ee6aad3ac3e023ab89b5f9d8a4d5674dMichael Sawyerdef source_method_invokers(invokers):
fb04db11ee6aad3ac3e023ab89b5f9d8a4d5674dMichael Sawyer for (signature, meth) in invokers.items():
fb04db11ee6aad3ac3e023ab89b5f9d8a4d5674dMichael Sawyer source_method_invoker(signature, meth.in_args)
fb04db11ee6aad3ac3e023ab89b5f9d8a4d5674dMichael Sawyer
fb04db11ee6aad3ac3e023ab89b5f9d8a4d5674dMichael Sawyerdef forward_prop_invoker(prop):
fb04db11ee6aad3ac3e023ab89b5f9d8a4d5674dMichael Sawyer out("static int %s(struct sbus_request *dbus_req, void *function_ptr);",
fb04db11ee6aad3ac3e023ab89b5f9d8a4d5674dMichael Sawyer prop.getter_invoker_name())
e65fe7af00935a0a81d4b0b0ed51c7f6c89f5c3bAndreas Gustafsson
e65fe7af00935a0a81d4b0b0ed51c7f6c89f5c3bAndreas Gustafssondef forward_prop_invokers(ifaces):
e65fe7af00935a0a81d4b0b0ed51c7f6c89f5c3bAndreas Gustafsson invokers = { }
4bb3a1a63d7943564f30bf9efd312283141439a2Andreas Gustafsson for iface in ifaces:
4bb3a1a63d7943564f30bf9efd312283141439a2Andreas Gustafsson for prop in iface.properties:
4bb3a1a63d7943564f30bf9efd312283141439a2Andreas Gustafsson if not prop.is_basic:
4bb3a1a63d7943564f30bf9efd312283141439a2Andreas Gustafsson continue
cef18335b7f37bf02bc9e9f2c8750a3a9dcd718aAndreas Gustafsson if prop.type in invokers:
e2b52099918681498136fc82df192d256cc3cdd3Brian Wellington continue
cef18335b7f37bf02bc9e9f2c8750a3a9dcd718aAndreas Gustafsson forward_prop_invoker(prop)
389ec663f262cc219e986d6600eec9707ef2cb24Brian Wellington invokers[prop.type] = prop
e549eb1242b69ee050440e7205a5633cb56199b3Mark Andrews return invokers
e549eb1242b69ee050440e7205a5633cb56199b3Mark Andrews
88cef4408ab6b4c48702ed1b3ae27e20f485d864Mark Andrewsdef source_prop_invokers(invokers):
88cef4408ab6b4c48702ed1b3ae27e20f485d864Mark Andrews for (type, prop) in invokers.items():
88cef4408ab6b4c48702ed1b3ae27e20f485d864Mark Andrews if prop.readable:
88cef4408ab6b4c48702ed1b3ae27e20f485d864Mark Andrews source_getter_invoker(prop)
88cef4408ab6b4c48702ed1b3ae27e20f485d864Mark Andrews
fce9a9550e8e7a6dff4093d4815ec41fae2d7b55Mark Andrewsdef source_finisher(meth):
fce9a9550e8e7a6dff4093d4815ec41fae2d7b55Mark Andrews out("")
ff7e6f2791cc5ad7c5f401a184b88343fde5ec3cAndreas Gustafsson out("int %s_finish(struct sbus_request *req%s)",
693ddf84daa745a0ea8ca311a8154dfa03eabc43Andreas Gustafsson meth.fq_c_name(), method_arg_types(meth.out_args, with_names=True))
93d5a6b95e88f57b7619d9728f06e3aa5e2f0c65Andreas Gustafsson out("{")
693ddf84daa745a0ea8ca311a8154dfa03eabc43Andreas Gustafsson
ff7e6f2791cc5ad7c5f401a184b88343fde5ec3cAndreas Gustafsson for arg in meth.out_args:
ff7e6f2791cc5ad7c5f401a184b88343fde5ec3cAndreas Gustafsson if arg.dbus_type != arg.sssd_type:
ff7e6f2791cc5ad7c5f401a184b88343fde5ec3cAndreas Gustafsson out(" %s cast_%s = arg_%s;", arg.dbus_type, arg.c_name(), arg.c_name())
ff7e6f2791cc5ad7c5f401a184b88343fde5ec3cAndreas Gustafsson
ff7e6f2791cc5ad7c5f401a184b88343fde5ec3cAndreas Gustafsson out(" return sbus_request_return_and_finish(req,")
2bebe117bf96d7e24df4d703d6488d61a5179bcaMark Andrews for arg in meth.out_args:
2bebe117bf96d7e24df4d703d6488d61a5179bcaMark Andrews out(" ", new_line=False)
4da10bce4bf64b574b59aa4fb5be0f237d0d41edBrian Wellington if arg.is_array:
4da10bce4bf64b574b59aa4fb5be0f237d0d41edBrian Wellington out("DBUS_TYPE_ARRAY, %s, &arg_%s, len_%s,",
3f123dcc2fe5d2cd08ca91b732741d86a4036906Brian Wellington arg.dbus_constant, arg.c_name(), arg.c_name())
3f123dcc2fe5d2cd08ca91b732741d86a4036906Brian Wellington elif arg.dbus_type != arg.sssd_type:
16ea60d0dbbaf1206f4800cb16744ef568fd7be8Michael Sawyer out("%s, &cast_%s,", arg.dbus_constant, arg.c_name())
16ea60d0dbbaf1206f4800cb16744ef568fd7be8Michael Sawyer else:
16ea60d0dbbaf1206f4800cb16744ef568fd7be8Michael Sawyer out("%s, &arg_%s,", arg.dbus_constant, arg.c_name())
16ea60d0dbbaf1206f4800cb16744ef568fd7be8Michael Sawyer out(" DBUS_TYPE_INVALID);")
85b23709431b1a84924fe2844f5cf657d1689eefMichael Sawyer out("}")
85b23709431b1a84924fe2844f5cf657d1689eefMichael Sawyer
85b23709431b1a84924fe2844f5cf657d1689eefMichael Sawyerdef header_reply(meth):
85b23709431b1a84924fe2844f5cf657d1689eefMichael Sawyer for arg in meth.out_args:
d15f51c600ed29b2dc379c433fb226c3a13ac0bbAndreas Gustafsson if arg.is_array:
d15f51c600ed29b2dc379c433fb226c3a13ac0bbAndreas Gustafsson out(" %s *%s", arg.dbus_type, arg.c_name())
d15f51c600ed29b2dc379c433fb226c3a13ac0bbAndreas Gustafsson out(" int %s__len", arg.c_name())
d15f51c600ed29b2dc379c433fb226c3a13ac0bbAndreas Gustafsson else:
d15f51c600ed29b2dc379c433fb226c3a13ac0bbAndreas Gustafsson out(" %s %s;", arg.dbus_type, arg.c_name())
cef18335b7f37bf02bc9e9f2c8750a3a9dcd718aAndreas Gustafsson types = [arg.sssd_type for arg in meth.in_args]
cef18335b7f37bf02bc9e9f2c8750a3a9dcd718aAndreas Gustafsson
aa2c453d3c6e416b56b29247bedd9a0af2721e93Mark Andrewsdef source_args(parent, args, suffix):
e412ae947df6de858883564b8676a9650df70d9aMark Andrews out("")
e412ae947df6de858883564b8676a9650df70d9aMark Andrews out("/* arguments for %s.%s */", parent.iface.name, parent.name)
e412ae947df6de858883564b8676a9650df70d9aMark Andrews out("const struct sbus_arg_meta %s%s[] = {", parent.fq_c_name(), suffix)
cef18335b7f37bf02bc9e9f2c8750a3a9dcd718aAndreas Gustafsson for arg in args:
07a926724c0a91d85b85a94441938d0094e88cffMark Andrews out(" { \"%s\", \"%s\" },", arg.name, arg.type)
07a926724c0a91d85b85a94441938d0094e88cffMark Andrews out(" { NULL, }")
07a926724c0a91d85b85a94441938d0094e88cffMark Andrews out("};")
07a926724c0a91d85b85a94441938d0094e88cffMark Andrews
90023730de34721b8cd8f3b5d059a28b7a65cf04Andreas Gustafssondef source_methods(iface, methods):
90023730de34721b8cd8f3b5d059a28b7a65cf04Andreas Gustafsson for meth in methods:
90023730de34721b8cd8f3b5d059a28b7a65cf04Andreas Gustafsson if meth.in_args:
922e6a3c2ac4ef900dd9dc99f0cc137f18372583Andreas Gustafsson source_args(meth, meth.in_args, "__in")
922e6a3c2ac4ef900dd9dc99f0cc137f18372583Andreas Gustafsson if meth.out_args:
922e6a3c2ac4ef900dd9dc99f0cc137f18372583Andreas Gustafsson source_args(meth, meth.out_args, "__out")
280747fa7c1d4597d47f7be8ec5fb7c8980c1952Andreas Gustafsson
280747fa7c1d4597d47f7be8ec5fb7c8980c1952Andreas Gustafsson if not meth.use_raw_handler():
280747fa7c1d4597d47f7be8ec5fb7c8980c1952Andreas Gustafsson source_finisher(meth)
0e07026a21dfcaf57dc789e7ece20182dc36029cMark Andrews
0e07026a21dfcaf57dc789e7ece20182dc36029cMark Andrews out("")
27d725f2b0f8d176d4625dc8b2ed71269b25c9a7Andreas Gustafsson out("/* methods for %s */", iface.name)
337ca1838428c52bca3c72288342ce3dee550a04Andreas Gustafsson out("const struct sbus_method_meta %s__methods[] = {", iface.c_name())
337ca1838428c52bca3c72288342ce3dee550a04Andreas Gustafsson for meth in methods:
337ca1838428c52bca3c72288342ce3dee550a04Andreas Gustafsson out(" {")
337ca1838428c52bca3c72288342ce3dee550a04Andreas Gustafsson out(" \"%s\", /* name */", meth.name)
337ca1838428c52bca3c72288342ce3dee550a04Andreas Gustafsson if meth.in_args:
337ca1838428c52bca3c72288342ce3dee550a04Andreas Gustafsson out(" %s__in,", meth.fq_c_name())
337ca1838428c52bca3c72288342ce3dee550a04Andreas Gustafsson else:
6b0ce7d29fac9df84ed34aa2d4634e754aec750dAndreas Gustafsson out(" NULL, /* no in_args */")
6b0ce7d29fac9df84ed34aa2d4634e754aec750dAndreas Gustafsson if meth.out_args:
6b0ce7d29fac9df84ed34aa2d4634e754aec750dAndreas Gustafsson out(" %s__out,", meth.fq_c_name())
dc2e45d08d73fdaefd92dbfa4d69b4d3f3b0f249Andreas Gustafsson else:
6b0ce7d29fac9df84ed34aa2d4634e754aec750dAndreas Gustafsson out(" NULL, /* no out_args */")
27d725f2b0f8d176d4625dc8b2ed71269b25c9a7Andreas Gustafsson out(" offsetof(struct %s, %s),", iface.c_name(), meth.c_name())
27d725f2b0f8d176d4625dc8b2ed71269b25c9a7Andreas Gustafsson if meth.use_raw_handler() or not meth.in_args:
27d725f2b0f8d176d4625dc8b2ed71269b25c9a7Andreas Gustafsson out(" NULL, /* no invoker */")
27d725f2b0f8d176d4625dc8b2ed71269b25c9a7Andreas Gustafsson else:
c89ac488df58cf6a37918cd00236eedf015830f8Andreas Gustafsson out(" invoke_%s_method,", meth.in_signature())
c89ac488df58cf6a37918cd00236eedf015830f8Andreas Gustafsson out(" },")
c89ac488df58cf6a37918cd00236eedf015830f8Andreas Gustafsson out(" { NULL, }")
c89ac488df58cf6a37918cd00236eedf015830f8Andreas Gustafsson out("};")
46a7e707fee6d7ba6ca6dae200ff6e0230f4d2f1Brian Wellington
46a7e707fee6d7ba6ca6dae200ff6e0230f4d2f1Brian Wellingtondef source_signals(iface, signals):
9d3ef72b37c7d23ce3aaaaa5cd0434b4e5ed5c12Mark Andrews for sig in iface.signals:
9d3ef72b37c7d23ce3aaaaa5cd0434b4e5ed5c12Mark Andrews if sig.args:
9d3ef72b37c7d23ce3aaaaa5cd0434b4e5ed5c12Mark Andrews source_args(sig, sig.args, "__args")
a7c76f1924d5fc914c579fd3b0276ffbddd2f65aMark Andrews
a7c76f1924d5fc914c579fd3b0276ffbddd2f65aMark Andrews out("")
c50a002bd1e36d13e95d74b43ed4a2b5d6fdcec3Mark Andrews out("/* signals for %s */", iface.name)
c50a002bd1e36d13e95d74b43ed4a2b5d6fdcec3Mark Andrews out("const struct sbus_signal_meta %s__signals[] = {", iface.c_name())
c50a002bd1e36d13e95d74b43ed4a2b5d6fdcec3Mark Andrews for sig in signals:
c50a002bd1e36d13e95d74b43ed4a2b5d6fdcec3Mark Andrews out(" {")
c50a002bd1e36d13e95d74b43ed4a2b5d6fdcec3Mark Andrews out(" \"%s\", /* name */", sig.name)
c50a002bd1e36d13e95d74b43ed4a2b5d6fdcec3Mark Andrews if sig.args:
c50a002bd1e36d13e95d74b43ed4a2b5d6fdcec3Mark Andrews out(" %s__args", sig.fq_c_name())
c50a002bd1e36d13e95d74b43ed4a2b5d6fdcec3Mark Andrews else:
566155f16e43fe5f1550456e534b31b0cc36d243David Lawrence out(" NULL, /* no args */")
566155f16e43fe5f1550456e534b31b0cc36d243David Lawrence out(" },")
07a46d6dca37ef96b6e9c1fc0c2789983d91819cAndreas Gustafsson out(" { NULL, }")
566155f16e43fe5f1550456e534b31b0cc36d243David Lawrence out("};")
051beeafa6547440da17985665b31952b85ede56Brian Wellington
07a46d6dca37ef96b6e9c1fc0c2789983d91819cAndreas Gustafssondef source_properties(iface, properties):
07a46d6dca37ef96b6e9c1fc0c2789983d91819cAndreas Gustafsson out("")
07a46d6dca37ef96b6e9c1fc0c2789983d91819cAndreas Gustafsson out("/* property info for %s */", iface.name)
cd73a1c823bc9feea603803a96a9e5f5da8bf33dMichael Sawyer
6d85ebc2d2ccbb8ef01c3ac1659686d3c2be0377Brian Wellington out("const struct sbus_property_meta %s__properties[] = {", iface.c_name())
6d85ebc2d2ccbb8ef01c3ac1659686d3c2be0377Brian Wellington for prop in properties:
4a0b04961653b4153402dabd71dfd8474b6c230dAndreas Gustafsson out(" {")
4a0b04961653b4153402dabd71dfd8474b6c230dAndreas Gustafsson out(" \"%s\", /* name */", prop.name)
4a0b04961653b4153402dabd71dfd8474b6c230dAndreas Gustafsson out(" \"%s\", /* type */", prop.type)
b0796437d493ca2e083ab0ff02acf0dc0c8ad2a3David Lawrence if prop.readable and prop.writable:
98b8d49c0c0bbace27966eed5811bc81255ce297Brian Wellington out(" SBUS_PROPERTY_READABLE | SBUS_PROPERTY_WRITABLE,")
98b8d49c0c0bbace27966eed5811bc81255ce297Brian Wellington elif prop.readable:
a94948ad5b3b258ce9503b7322bdf82c0baabcabAndreas Gustafsson out(" SBUS_PROPERTY_READABLE,")
e42c402595802edceafbd3e5338dda011fbbcdb6Michael Sawyer elif prop.writable:
cc7420cb3b8eb2c48a00384784701bfee37cc96fAndreas Gustafsson out(" SBUS_PROPERTY_WRITABLE,")
8357e90fba97010a86356a41c8a961d5d602d7d0Michael Sawyer else:
3291587f23b940c986f41cf37b2e531f618ec2bdMichael Sawyer assert False, "should not be reached"
a94948ad5b3b258ce9503b7322bdf82c0baabcabAndreas Gustafsson if prop.readable:
a94948ad5b3b258ce9503b7322bdf82c0baabcabAndreas Gustafsson out(" offsetof(struct %s, %s),", iface.c_name(), prop.getter_name())
abb38b673379d6dae7cbb495f814d73a4afe5c8bAndreas Gustafsson out(" %s,", prop.getter_invoker_name())
3291587f23b940c986f41cf37b2e531f618ec2bdMichael Sawyer else:
b374727d513049b4bfcb9eb021002595fe6a7c63Mark Andrews out(" 0, /* not readable */")
b374727d513049b4bfcb9eb021002595fe6a7c63Mark Andrews out(" NULL, /* no invoker */")
b374727d513049b4bfcb9eb021002595fe6a7c63Mark Andrews out(" 0, /* not writable */")
d922e82162b4d0d2387a531ebc127abe9fe4cf2bAndreas Gustafsson out(" NULL, /* no invoker */")
d922e82162b4d0d2387a531ebc127abe9fe4cf2bAndreas Gustafsson out(" },")
b374727d513049b4bfcb9eb021002595fe6a7c63Mark Andrews out(" { NULL, }")
2868291ab5d4deba4d61c110f92dc397807702c7Mark Andrews out("};")
2868291ab5d4deba4d61c110f92dc397807702c7Mark Andrews
2868291ab5d4deba4d61c110f92dc397807702c7Mark Andrewsdef header_interface(iface):
be1d71fd17c92b0acee36ba43ebe4daa498e8014Mark Andrews out("")
b374727d513049b4bfcb9eb021002595fe6a7c63Mark Andrews out("/* interface info for %s */", iface.name)
be1d71fd17c92b0acee36ba43ebe4daa498e8014Mark Andrews out("extern const struct sbus_interface_meta %s_meta;", iface.c_name())
8e732de92e9814e3fa54e36d2154939ea6086b16Andreas Gustafsson
8e732de92e9814e3fa54e36d2154939ea6086b16Andreas Gustafssondef source_interface(iface):
8e732de92e9814e3fa54e36d2154939ea6086b16Andreas Gustafsson out("")
afd2f40b3cff8c3c307155bdc27e5b60e9115545Andreas Gustafsson out("/* interface info for %s */", iface.name)
afd2f40b3cff8c3c307155bdc27e5b60e9115545Andreas Gustafsson out("const struct sbus_interface_meta %s_meta = {", iface.c_name())
afd2f40b3cff8c3c307155bdc27e5b60e9115545Andreas Gustafsson out(" \"%s\", /* name */", iface.name)
afd2f40b3cff8c3c307155bdc27e5b60e9115545Andreas Gustafsson if iface.methods:
c605f30cd7d540243509c86cf31b01bdd4fe19feMark Andrews out(" %s__methods,", iface.c_name())
c605f30cd7d540243509c86cf31b01bdd4fe19feMark Andrews else:
c605f30cd7d540243509c86cf31b01bdd4fe19feMark Andrews out(" NULL, /* no methods */")
3302ed8d6eaef8f598338f5682477c5f6acd583cBob Halley if iface.signals:
3302ed8d6eaef8f598338f5682477c5f6acd583cBob Halley out(" %s__signals,", iface.c_name())
3302ed8d6eaef8f598338f5682477c5f6acd583cBob Halley else:
3302ed8d6eaef8f598338f5682477c5f6acd583cBob Halley out(" NULL, /* no signals */")
3302ed8d6eaef8f598338f5682477c5f6acd583cBob Halley if iface.properties:
cef18335b7f37bf02bc9e9f2c8750a3a9dcd718aAndreas Gustafsson out(" %s__properties", iface.c_name())
d03bffc40e68ddb63d278946fd9f7f1ad784f5bcMichael Sawyer else:
cef18335b7f37bf02bc9e9f2c8750a3a9dcd718aAndreas Gustafsson out(" NULL, /* no propetries */")
d03bffc40e68ddb63d278946fd9f7f1ad784f5bcMichael Sawyer out("};")
d03bffc40e68ddb63d278946fd9f7f1ad784f5bcMichael Sawyer
91ac60fe11b3ebd095c5fed0db343b2c9a97e646Mark Andrewsdef generate_source(ifaces, filename, include_header=None):
91ac60fe11b3ebd095c5fed0db343b2c9a97e646Mark Andrews basename = os.path.basename(filename)
83d2840b6f1a5ec898e441be148ddd3211f11583Bob Halley
83d2840b6f1a5ec898e441be148ddd3211f11583Bob Halley out("/* The following definitions are auto-generated from %s */", basename)
83d2840b6f1a5ec898e441be148ddd3211f11583Bob Halley out("")
83d2840b6f1a5ec898e441be148ddd3211f11583Bob Halley
42e31e6ef7689e0c0569a1f9a5c250d73870b073Michael Graff out("#include \"util/util.h\"")
42e31e6ef7689e0c0569a1f9a5c250d73870b073Michael Graff out("#include \"sbus/sssd_dbus.h\"")
42e31e6ef7689e0c0569a1f9a5c250d73870b073Michael Graff out("#include \"sbus/sssd_dbus_meta.h\"")
42e31e6ef7689e0c0569a1f9a5c250d73870b073Michael Graff if include_header:
42e31e6ef7689e0c0569a1f9a5c250d73870b073Michael Graff out("#include \"%s\"", os.path.basename(include_header))
a405a53d536521e6c93f47485aacd7c1a1ffb29eAndreas Gustafsson
a405a53d536521e6c93f47485aacd7c1a1ffb29eAndreas Gustafsson meth_invokers = forward_method_invokers(ifaces)
a405a53d536521e6c93f47485aacd7c1a1ffb29eAndreas Gustafsson prop_invokers = forward_prop_invokers(ifaces)
a405a53d536521e6c93f47485aacd7c1a1ffb29eAndreas Gustafsson
a405a53d536521e6c93f47485aacd7c1a1ffb29eAndreas Gustafsson for iface in ifaces:
53df51bf458da9b04074b6b62b5639c926a751e4Andreas Gustafsson
53df51bf458da9b04074b6b62b5639c926a751e4Andreas Gustafsson # The methods
53df51bf458da9b04074b6b62b5639c926a751e4Andreas Gustafsson if iface.methods:
ba43c53451d5c38765f376eeede457178b36951aBob Halley source_methods(iface, iface.methods)
ba43c53451d5c38765f376eeede457178b36951aBob Halley
ba43c53451d5c38765f376eeede457178b36951aBob Halley # The signals array
b9dead30b1806bcfcca9a47dfa3f5078c6377910Mark Andrews if iface.signals:
b9dead30b1806bcfcca9a47dfa3f5078c6377910Mark Andrews source_signals(iface, iface.signals)
056141f2878d1046306ef0ba035263a00de57f98Mark Andrews
056141f2878d1046306ef0ba035263a00de57f98Mark Andrews # The properties array
5126112bc3639b9dae5726c3148d6699d277e789Mark Andrews if iface.properties:
5126112bc3639b9dae5726c3148d6699d277e789Mark Andrews source_properties(iface, iface.properties)
668278867ba063995988507b6b28724ebb9f9391Mark Andrews
4440f995911810aaa98d8985ac1a8192095879f2Michael Graff # The sbus_interface structure
72c815ed1780b9039b9ad0d31faf68b3b5c05637Andreas Gustafsson source_interface(iface)
72c815ed1780b9039b9ad0d31faf68b3b5c05637Andreas Gustafsson
72c815ed1780b9039b9ad0d31faf68b3b5c05637Andreas Gustafsson source_method_invokers(meth_invokers)
72c815ed1780b9039b9ad0d31faf68b3b5c05637Andreas Gustafsson source_prop_invokers(prop_invokers)
2053a53eeac7f069311d8ed67333503c7d3a2e2bAndreas Gustafsson
72c815ed1780b9039b9ad0d31faf68b3b5c05637Andreas Gustafssondef header_finisher(iface, meth):
b7e031d5173476224027407d8e23eaa7557fc396Andreas Gustafsson if meth.use_raw_handler():
b7e031d5173476224027407d8e23eaa7557fc396Andreas Gustafsson return
b7e031d5173476224027407d8e23eaa7557fc396Andreas Gustafsson out("")
b7e031d5173476224027407d8e23eaa7557fc396Andreas Gustafsson out("/* finish function for %s */", meth.name)
b7e031d5173476224027407d8e23eaa7557fc396Andreas Gustafsson out("int %s_finish(struct sbus_request *req%s);",
b7e031d5173476224027407d8e23eaa7557fc396Andreas Gustafsson meth.fq_c_name(), method_arg_types(meth.out_args, with_names=True))
b7e031d5173476224027407d8e23eaa7557fc396Andreas Gustafsson
b7e031d5173476224027407d8e23eaa7557fc396Andreas Gustafssondef header_vtable(iface, methods):
7ec4367f3d578170a9495ff3c851b248c1656f08Andreas Gustafsson out("")
7ec4367f3d578170a9495ff3c851b248c1656f08Andreas Gustafsson out("/* vtable for %s */", iface.name)
2c9c7c5bb5975a18925c30aeb33a26094902f1c1Andreas Gustafsson out("struct %s {", iface.c_name())
cef18335b7f37bf02bc9e9f2c8750a3a9dcd718aAndreas Gustafsson out(" struct sbus_vtable vtable; /* derive from sbus_vtable */")
2c9c7c5bb5975a18925c30aeb33a26094902f1c1Andreas Gustafsson
2c9c7c5bb5975a18925c30aeb33a26094902f1c1Andreas Gustafsson # All methods
2c9c7c5bb5975a18925c30aeb33a26094902f1c1Andreas Gustafsson for meth in iface.methods:
94361d586755d4de09b717782f7002e9dd282c89Andreas Gustafsson out(" %s;", method_function_pointer(meth, meth.c_name(), with_names=True))
94361d586755d4de09b717782f7002e9dd282c89Andreas Gustafsson for prop in iface.properties:
94361d586755d4de09b717782f7002e9dd282c89Andreas Gustafsson out(" %s;", property_handlers(prop))
4440f995911810aaa98d8985ac1a8192095879f2Michael Graff
4440f995911810aaa98d8985ac1a8192095879f2Michael Graff out("};")
4440f995911810aaa98d8985ac1a8192095879f2Michael Graff
4440f995911810aaa98d8985ac1a8192095879f2Michael Graffdef header_constants(iface):
4440f995911810aaa98d8985ac1a8192095879f2Michael Graff out("")
4440f995911810aaa98d8985ac1a8192095879f2Michael Graff out("/* constants for %s */", iface.name)
4440f995911810aaa98d8985ac1a8192095879f2Michael Graff out("#define %s \"%s\"", iface.c_name().upper(), iface.name)
4440f995911810aaa98d8985ac1a8192095879f2Michael Graff for meth in iface.methods:
abaec24086f0cc3d7c0994ca9d2247b40eb6aaedBrian Wellington out("#define %s \"%s\"", meth.fq_c_name().upper(), meth.name)
abaec24086f0cc3d7c0994ca9d2247b40eb6aaedBrian Wellington for sig in iface.signals:
abaec24086f0cc3d7c0994ca9d2247b40eb6aaedBrian Wellington out("#define %s \"%s\"", sig.fq_c_name().upper(), sig.name)
abaec24086f0cc3d7c0994ca9d2247b40eb6aaedBrian Wellington for prop in iface.properties:
cef18335b7f37bf02bc9e9f2c8750a3a9dcd718aAndreas Gustafsson out("#define %s \"%s\"", prop.fq_c_name().upper(), prop.name)
3ad16d4c3a5029662d4ec804f7644739d011d03dBob Halley
3ad16d4c3a5029662d4ec804f7644739d011d03dBob Halleydef generate_header(ifaces, filename):
3ad16d4c3a5029662d4ec804f7644739d011d03dBob Halley basename = os.path.basename(filename)
3ad16d4c3a5029662d4ec804f7644739d011d03dBob Halley guard = "__%s__" % re.sub(r'([^_A-Z0-9])', "_", basename.upper())
32b2cdf212de957e3f9b0efca59f098ed4fb42deBrian Wellington
32b2cdf212de957e3f9b0efca59f098ed4fb42deBrian Wellington out("/* The following declarations are auto-generated from %s */", basename)
32b2cdf212de957e3f9b0efca59f098ed4fb42deBrian Wellington out("")
32b2cdf212de957e3f9b0efca59f098ed4fb42deBrian Wellington out("#ifndef %s", guard)
b42a7e9d80e293a5104d9de6ddabd29676918aa5Andreas Gustafsson out("#define %s", guard)
b42a7e9d80e293a5104d9de6ddabd29676918aa5Andreas Gustafsson out("")
b42a7e9d80e293a5104d9de6ddabd29676918aa5Andreas Gustafsson out("#include \"sbus/sssd_dbus.h\"")
3113e4dac81fa7b9f0ee5d663d54fbb8ed92738dBob Halley
3113e4dac81fa7b9f0ee5d663d54fbb8ed92738dBob Halley out("")
3113e4dac81fa7b9f0ee5d663d54fbb8ed92738dBob Halley out("/* ------------------------------------------------------------------------")
7f52817a92d74be0d970c33b204f8f13309eece5Andreas Gustafsson out(" * DBus Constants")
8cf8a04209c3b6c8d4f0936f1dce06b629605c81Michael Graff out(" *")
8cf8a04209c3b6c8d4f0936f1dce06b629605c81Michael Graff out(" * Various constants of interface and method names mostly for use by clients")
8cf8a04209c3b6c8d4f0936f1dce06b629605c81Michael Graff out(" */")
8cf8a04209c3b6c8d4f0936f1dce06b629605c81Michael Graff
4b809ba3464c9fb6bb08e9153b9286a8f8a37b01Brian Wellington for iface in ifaces:
1fc26319b5d69d19a7a31c8d0ab1afc2beef0c41Andreas Gustafsson header_constants(iface)
1fc26319b5d69d19a7a31c8d0ab1afc2beef0c41Andreas Gustafsson
1fc26319b5d69d19a7a31c8d0ab1afc2beef0c41Andreas Gustafsson out("")
1fc26319b5d69d19a7a31c8d0ab1afc2beef0c41Andreas Gustafsson out("/* ------------------------------------------------------------------------")
7da0286b540515c82ea83163d6cba59a64fa3eddMichael Graff out(" * DBus handlers")
7da0286b540515c82ea83163d6cba59a64fa3eddMichael Graff out(" *")
cef18335b7f37bf02bc9e9f2c8750a3a9dcd718aAndreas Gustafsson out(" * These structures are filled in by implementors of the different")
7da0286b540515c82ea83163d6cba59a64fa3eddMichael Graff out(" * dbus interfaces to handle method calls.")
7da0286b540515c82ea83163d6cba59a64fa3eddMichael Graff out(" *")
7da0286b540515c82ea83163d6cba59a64fa3eddMichael Graff out(" * Handler functions of type sbus_msg_handler_fn accept raw messages,")
c4ec2c3190175705df255aa3d5e842a96137a5a1Andreas Gustafsson out(" * other handlers are typed appropriately. If a handler that is")
c4ec2c3190175705df255aa3d5e842a96137a5a1Andreas Gustafsson out(" * set to NULL is invoked it will result in a")
8529c3cdc6abdf3514cb0127313a976bbc3b3936Andreas Gustafsson out(" * org.freedesktop.DBus.Error.NotSupported error for the caller.")
8529c3cdc6abdf3514cb0127313a976bbc3b3936Andreas Gustafsson out(" *")
87ecd67dae468cf5c9bae213c6fa321449b2ebc2Andreas Gustafsson out(" * Handlers have a matching xxx_finish() function (unless the method has")
87ecd67dae468cf5c9bae213c6fa321449b2ebc2Andreas Gustafsson out(" * accepts raw messages). These finish functions the")
f38a84ce830efefe48838425ab281e0ae2a91d0eAndreas Gustafsson out(" * sbus_request_return_and_finish() with the appropriate arguments to")
f38a84ce830efefe48838425ab281e0ae2a91d0eAndreas Gustafsson out(" * construct a valid reply. Once a finish function has been called, the")
f38a84ce830efefe48838425ab281e0ae2a91d0eAndreas Gustafsson out(" * @dbus_req it was called with is freed and no longer valid.")
f38a84ce830efefe48838425ab281e0ae2a91d0eAndreas Gustafsson out(" */")
1b32bc7da1da9059abd68d6dd15b23e8a442afa3Brian Wellington
1b32bc7da1da9059abd68d6dd15b23e8a442afa3Brian Wellington for iface in ifaces:
1b32bc7da1da9059abd68d6dd15b23e8a442afa3Brian Wellington if iface.methods or iface.properties:
1b32bc7da1da9059abd68d6dd15b23e8a442afa3Brian Wellington header_vtable(iface, iface.methods)
4187398298c1916f409b44e0457f60e551f5ea1bAndreas Gustafsson for meth in iface.methods:
4187398298c1916f409b44e0457f60e551f5ea1bAndreas Gustafsson header_finisher(iface, meth)
0d00f4bb92090ff64d49ae803a2e75b3f299f547Andreas Gustafsson
4187398298c1916f409b44e0457f60e551f5ea1bAndreas Gustafsson out("")
4b809ba3464c9fb6bb08e9153b9286a8f8a37b01Brian Wellington out("/* ------------------------------------------------------------------------")
4b809ba3464c9fb6bb08e9153b9286a8f8a37b01Brian Wellington out(" * DBus Interface Metadata")
a69cebac84ec223b908e056678fa7c1181785b20Andreas Gustafsson out(" *")
a69cebac84ec223b908e056678fa7c1181785b20Andreas Gustafsson out(" * These structure definitions are filled in with the information about")
a69cebac84ec223b908e056678fa7c1181785b20Andreas Gustafsson out(" * the interfaces, methods, properties and so on.")
d9ec31a329a14588127b0a15618dec53ca41c73eAndreas Gustafsson out(" *")
d9ec31a329a14588127b0a15618dec53ca41c73eAndreas Gustafsson out(" * The actual definitions are found in the accompanying C file next")
7d8d82cee0910a0252e1c37bace732e996789772Andreas Gustafsson out(" * to this header.")
e5d0f6d61e2349e1512c40922305b28c69cb4d3fBrian Wellington out(" */")
e5d0f6d61e2349e1512c40922305b28c69cb4d3fBrian Wellington
37a8fbab3a1fe6d513b767118cba7515152c2b9bBrian Wellington for iface in ifaces:
37a8fbab3a1fe6d513b767118cba7515152c2b9bBrian Wellington header_interface(iface)
a38f86ea5bb9f924b5912d8444862000a1323082Andreas Gustafsson
a38f86ea5bb9f924b5912d8444862000a1323082Andreas Gustafsson out("")
a38f86ea5bb9f924b5912d8444862000a1323082Andreas Gustafsson out("#endif /* %s */", guard)
7d8d82cee0910a0252e1c37bace732e996789772Andreas Gustafsson
7d8d82cee0910a0252e1c37bace732e996789772Andreas Gustafsson# -----------------------------------------------------------------------------
7d8d82cee0910a0252e1c37bace732e996789772Andreas Gustafsson# XML Interface Parsing
7d8d82cee0910a0252e1c37bace732e996789772Andreas Gustafsson
cdc2d4a065b6b1a00f0b07aae94bc7cb380d15bcAndreas GustafssonSTATE_TOP = 'top'
ec4060d3104e8bec28406232eb7338c81bb1b1c1Mark AndrewsSTATE_NODE = 'node'
735fb4ffa6a76413f85101d7d625a4776d6ee6cdAndreas GustafssonSTATE_INTERFACE = 'interface'
d70e2f3652fcbcfb2cfa0781a71e2bd2396871f3Andreas GustafssonSTATE_METHOD = 'method'
2c7097eac0aed3b0b3387082cb783db64f2d7765Andreas GustafssonSTATE_SIGNAL = 'signal'
d70e2f3652fcbcfb2cfa0781a71e2bd2396871f3Andreas GustafssonSTATE_PROPERTY = 'property'
d70e2f3652fcbcfb2cfa0781a71e2bd2396871f3Andreas GustafssonSTATE_ARG = 'arg'
9139e153da3ffa88457d3e035e2f0132c63a4a71Andreas GustafssonSTATE_ANNOTATION = 'annotation'
9139e153da3ffa88457d3e035e2f0132c63a4a71Andreas GustafssonSTATE_IGNORED = 'ignored'
9139e153da3ffa88457d3e035e2f0132c63a4a71Andreas Gustafsson
30e6ea9dedbe0738f9729833b1b59042dbebc4dfBrian Wellingtondef expect_attr(attrs, name):
30e6ea9dedbe0738f9729833b1b59042dbebc4dfBrian Wellington if name not in attrs:
1aae88078f409b39c24e2313ffdd767ed29ac787Brian Wellington raise DBusXmlException("Missing attribute '%s'" % name)
1aae88078f409b39c24e2313ffdd767ed29ac787Brian Wellington if attrs[name] == "":
17a28c1f02c5093b207a3b64201aa9e71df78ebaAndreas Gustafsson raise DBusXmlException("Empty attribute '%s'" % name)
17a28c1f02c5093b207a3b64201aa9e71df78ebaAndreas Gustafsson return attrs[name]
b5232b135db580a2c16666e74a82f11130e0731fAndreas Gustafsson
b5232b135db580a2c16666e74a82f11130e0731fAndreas Gustafssonclass DBusXMLParser:
b5232b135db580a2c16666e74a82f11130e0731fAndreas Gustafsson def __init__(self, filename):
b5232b135db580a2c16666e74a82f11130e0731fAndreas Gustafsson parser = xml.parsers.expat.ParserCreate()
cea88d887559f209ae9d993e0a8fb58d03f60e77Brian Wellington parser.CommentHandler = self.handle_comment
cea88d887559f209ae9d993e0a8fb58d03f60e77Brian Wellington parser.CharacterDataHandler = self.handle_char_data
cea88d887559f209ae9d993e0a8fb58d03f60e77Brian Wellington parser.StartElementHandler = self.handle_start_element
a7705f38e91cc6afaba0426f6b452c9ae5a4efeaAndreas Gustafsson parser.EndElementHandler = self.handle_end_element
a7705f38e91cc6afaba0426f6b452c9ae5a4efeaAndreas Gustafsson
a7705f38e91cc6afaba0426f6b452c9ae5a4efeaAndreas Gustafsson self.parsed_interfaces = []
a7705f38e91cc6afaba0426f6b452c9ae5a4efeaAndreas Gustafsson self.cur_object = None
a7705f38e91cc6afaba0426f6b452c9ae5a4efeaAndreas Gustafsson
a7705f38e91cc6afaba0426f6b452c9ae5a4efeaAndreas Gustafsson self.state = STATE_TOP
a7705f38e91cc6afaba0426f6b452c9ae5a4efeaAndreas Gustafsson self.state_stack = []
a7705f38e91cc6afaba0426f6b452c9ae5a4efeaAndreas Gustafsson self.cur_object = None
735fb4ffa6a76413f85101d7d625a4776d6ee6cdAndreas Gustafsson self.cur_object_stack = []
735fb4ffa6a76413f85101d7d625a4776d6ee6cdAndreas Gustafsson self.arg_count = 0
735fb4ffa6a76413f85101d7d625a4776d6ee6cdAndreas Gustafsson
e1368a7770744cbeadcdc27967f855196988eceaAndreas Gustafsson try:
e1368a7770744cbeadcdc27967f855196988eceaAndreas Gustafsson with open(filename, "r") as f:
c05eb51a1b9ebd156b9fec957d60c2579c968468Mark Andrews parser.ParseFile(f)
a3365e361f0066609d250005e2b1082cb2ba35fdAndreas Gustafsson except DBusXmlException, ex:
a3365e361f0066609d250005e2b1082cb2ba35fdAndreas Gustafsson ex.line = parser.CurrentLineNumber
a3365e361f0066609d250005e2b1082cb2ba35fdAndreas Gustafsson ex.file = filename
e32394a2ac3466a2235f79ee32c247a11be42a8dAndreas Gustafsson raise
e32394a2ac3466a2235f79ee32c247a11be42a8dAndreas Gustafsson except xml.parsers.expat.ExpatError, ex:
e32394a2ac3466a2235f79ee32c247a11be42a8dAndreas Gustafsson exc = DBusXmlException(str(ex))
031f9084fc1ca8b258c151f428677e7226556ad0Mark Andrews exc.line = ex.lineno
031f9084fc1ca8b258c151f428677e7226556ad0Mark Andrews exc.file = filename
031f9084fc1ca8b258c151f428677e7226556ad0Mark Andrews raise exc
031f9084fc1ca8b258c151f428677e7226556ad0Mark Andrews
031f9084fc1ca8b258c151f428677e7226556ad0Mark Andrews def handle_comment(self, data):
031f9084fc1ca8b258c151f428677e7226556ad0Mark Andrews pass
031f9084fc1ca8b258c151f428677e7226556ad0Mark Andrews
031f9084fc1ca8b258c151f428677e7226556ad0Mark Andrews def handle_char_data(self, data):
031f9084fc1ca8b258c151f428677e7226556ad0Mark Andrews pass
44215b932d4f0ce5257d794cb6f76b9282455eb1Mark Andrews
44215b932d4f0ce5257d794cb6f76b9282455eb1Mark Andrews def handle_start_element(self, name, attrs):
44215b932d4f0ce5257d794cb6f76b9282455eb1Mark Andrews old_state = self.state
44215b932d4f0ce5257d794cb6f76b9282455eb1Mark Andrews old_cur_object = self.cur_object
44215b932d4f0ce5257d794cb6f76b9282455eb1Mark Andrews if self.state == STATE_IGNORED:
405ffb1f0d2c12d199f85f03973d1a02ac12e000Andreas Gustafsson self.state = STATE_IGNORED
405ffb1f0d2c12d199f85f03973d1a02ac12e000Andreas Gustafsson elif self.cur_object and name == STATE_ANNOTATION:
405ffb1f0d2c12d199f85f03973d1a02ac12e000Andreas Gustafsson val = attrs.get('value', '')
405ffb1f0d2c12d199f85f03973d1a02ac12e000Andreas Gustafsson self.cur_object.annotations[expect_attr(attrs, 'name')] = val
405ffb1f0d2c12d199f85f03973d1a02ac12e000Andreas Gustafsson self.state = STATE_IGNORED
eea2865feca4ea56facd2ef6e7226386a3604f65Andreas Gustafsson elif self.state == STATE_TOP:
6d8568cb45240974da0ee1b653b28e3fdfffe93eAndreas Gustafsson if name == STATE_NODE:
6d8568cb45240974da0ee1b653b28e3fdfffe93eAndreas Gustafsson self.state = STATE_NODE
6d8568cb45240974da0ee1b653b28e3fdfffe93eAndreas Gustafsson else:
6d8568cb45240974da0ee1b653b28e3fdfffe93eAndreas Gustafsson self.state = STATE_IGNORED
e3402551ac9be809eeb3a4b7b30d023ba67dad28Brian Wellington elif self.state == STATE_NODE:
6d3f954c572db02159deedd444373161fda47a88Brian Wellington if name == STATE_INTERFACE:
b0f941a50f24656b3523609f86cead41b0269c7aBrian Wellington self.state = STATE_INTERFACE
b0f941a50f24656b3523609f86cead41b0269c7aBrian Wellington iface = Interface(expect_attr(attrs, 'name'))
b0f941a50f24656b3523609f86cead41b0269c7aBrian Wellington self.cur_object = iface
ea419adc4eca4c3e44f2c282035b5dce6b795fe2Andreas Gustafsson self.parsed_interfaces.append(iface)
3f31c8c2954f857e375db8e943a35f6aa5e230b4Andreas Gustafsson else:
ea419adc4eca4c3e44f2c282035b5dce6b795fe2Andreas Gustafsson self.state = STATE_IGNORED
ff59f0e4feaefb45a49427bd91775058b4b4f2d0Andreas Gustafsson
ff59f0e4feaefb45a49427bd91775058b4b4f2d0Andreas Gustafsson elif self.state == STATE_INTERFACE:
eea2865feca4ea56facd2ef6e7226386a3604f65Andreas Gustafsson if name == STATE_METHOD:
8af0b86ade4c15a7db207bd7643f8a9f6cb5a648David Lawrence self.state = STATE_METHOD
8af0b86ade4c15a7db207bd7643f8a9f6cb5a648David Lawrence method = Method(self.cur_object, expect_attr(attrs, 'name'))
886b96ebfd555cfeaf37ae46fc08421a41c61392Andreas Gustafsson self.cur_object.methods.append(method)
674f1cfb1d7dfa92e52db950dbe80e60ef8f5cddBrian Wellington self.cur_object = method
674f1cfb1d7dfa92e52db950dbe80e60ef8f5cddBrian Wellington self.arg_count = 0
674f1cfb1d7dfa92e52db950dbe80e60ef8f5cddBrian Wellington elif name == STATE_SIGNAL:
69d17bea6be937b92f3375e6249b5677c90f4fe2Andreas Gustafsson self.state = STATE_SIGNAL
69d17bea6be937b92f3375e6249b5677c90f4fe2Andreas Gustafsson signal = Signal(self.cur_object, expect_attr(attrs, 'name'))
69d17bea6be937b92f3375e6249b5677c90f4fe2Andreas Gustafsson self.cur_object.signals.append(signal)
da76a8046e01e1c1c2e6f75772afb2c4f202cc25Brian Wellington self.cur_object = signal
cd7ffa4c1286a48c10056632be3fb0b64c575c35Brian Wellington self.arg_count = 0
cd7ffa4c1286a48c10056632be3fb0b64c575c35Brian Wellington elif name == STATE_PROPERTY:
cd7ffa4c1286a48c10056632be3fb0b64c575c35Brian Wellington self.state = STATE_PROPERTY
0cff88818a96197995c3533f6cbfb1a0efc06db0Brian Wellington prop = Property(self.cur_object,
0cff88818a96197995c3533f6cbfb1a0efc06db0Brian Wellington expect_attr(attrs, 'name'),
5bba7216f3263dc49dd4db2ac64b6203a9e2b180Andreas Gustafsson expect_attr(attrs, 'type'),
5bba7216f3263dc49dd4db2ac64b6203a9e2b180Andreas Gustafsson expect_attr(attrs, 'access'))
40817ed9c13782a7844e15dde24432611c4694acDavid Lawrence self.cur_object.properties.append(prop)
40817ed9c13782a7844e15dde24432611c4694acDavid Lawrence self.cur_object = prop
e06aebbe7b5b3128f99b16d6756a074b4de28d37Mark Andrews else:
b41de87910a4c57039a4f5968e272a9aec566959Brian Wellington self.state = STATE_IGNORED
40b1b44ed65b9655a135fc867ed9f0374c247ad4Andreas Gustafsson
40b1b44ed65b9655a135fc867ed9f0374c247ad4Andreas Gustafsson elif self.state == STATE_METHOD:
40b1b44ed65b9655a135fc867ed9f0374c247ad4Andreas Gustafsson if name == STATE_ARG:
ab8668fb583a92df0698f5cdac7e7b12ead614aaBrian Wellington self.state = STATE_ARG
ab8668fb583a92df0698f5cdac7e7b12ead614aaBrian Wellington arg = Arg(self.cur_object,
ab8668fb583a92df0698f5cdac7e7b12ead614aaBrian Wellington expect_attr(attrs, 'name'),
575db903aabb08137a757d1c60ebb0d286ecff56Andreas Gustafsson expect_attr(attrs, 'type'))
575db903aabb08137a757d1c60ebb0d286ecff56Andreas Gustafsson direction = attrs.get('direction', 'in')
575db903aabb08137a757d1c60ebb0d286ecff56Andreas Gustafsson if direction == 'in':
575db903aabb08137a757d1c60ebb0d286ecff56Andreas Gustafsson self.cur_object.in_args.append(arg)
575db903aabb08137a757d1c60ebb0d286ecff56Andreas Gustafsson elif direction == 'out':
575db903aabb08137a757d1c60ebb0d286ecff56Andreas Gustafsson self.cur_object.out_args.append(arg)
a4c55a3d0813e00e3d7846cc9736110c61d0a2baAndreas Gustafsson else:
a4c55a3d0813e00e3d7846cc9736110c61d0a2baAndreas Gustafsson raise DBusXmlException('Invalid direction "%s"' % direction)
d403e27f2b1c94f2b9349ddb68f50a141ae8d26dAndreas Gustafsson self.cur_object = arg
c851f1cc2187b59687af94725fbacac022987d05Andreas Gustafsson else:
c851f1cc2187b59687af94725fbacac022987d05Andreas Gustafsson self.state = STATE_IGNORED
91614f2bc498ef7eea22e449c91951f4598c8223Andreas Gustafsson
91614f2bc498ef7eea22e449c91951f4598c8223Andreas Gustafsson elif self.state == STATE_SIGNAL:
91614f2bc498ef7eea22e449c91951f4598c8223Andreas Gustafsson if name == STATE_ARG:
91614f2bc498ef7eea22e449c91951f4598c8223Andreas Gustafsson self.state = STATE_ARG
e0a9b524614889ca9b75f846cb6101fc448a60dcAndreas Gustafsson arg = Arg(self.cur_object,
512661edd7d51c8c179cce89a855df6cec2fcdcdMark Andrews expect_attr(attrs, 'name'),
512661edd7d51c8c179cce89a855df6cec2fcdcdMark Andrews expect_attr(attrs, 'type'))
385a9cb48a70b329e507c39d043fa9a44c659913James Brister self.cur_object.args.append(arg)
385a9cb48a70b329e507c39d043fa9a44c659913James Brister self.cur_object = arg
385a9cb48a70b329e507c39d043fa9a44c659913James Brister else:
385a9cb48a70b329e507c39d043fa9a44c659913James Brister self.state = STATE_IGNORED
3cb0de1c667237085c6a805715c31ddc5fdc9c4dBrian Wellington
385a9cb48a70b329e507c39d043fa9a44c659913James Brister elif self.state == STATE_PROPERTY:
bd77de5fcaea4dcf2f0250ded32adfccd3a38256Brian Wellington self.state = STATE_IGNORED
bd77de5fcaea4dcf2f0250ded32adfccd3a38256Brian Wellington
bd77de5fcaea4dcf2f0250ded32adfccd3a38256Brian Wellington elif self.state == STATE_ARG:
e5f5ec73a710d21067d4721a9e82f2399f2f6c25David Lawrence self.state = STATE_IGNORED
48674819ebf9176b5d5582ae851e485c324c1159Michael Sawyer
48674819ebf9176b5d5582ae851e485c324c1159Michael Sawyer else:
e5f5ec73a710d21067d4721a9e82f2399f2f6c25David Lawrence assert False, 'Unhandled state "%s" while entering element with name "%s"' % (self.state, name)
48674819ebf9176b5d5582ae851e485c324c1159Michael Sawyer
9594482ba300a4d694162fa62ba636c7dd00d3b6Brian Wellington self.state_stack.append(old_state)
9594482ba300a4d694162fa62ba636c7dd00d3b6Brian Wellington self.cur_object_stack.append(old_cur_object)
47ddde42728034854444cf17e278cebaea06f666Michael Graff
47ddde42728034854444cf17e278cebaea06f666Michael Graff def handle_end_element(self, name):
edf8c55546efa9fb42da1c055ce02462a5c709c0David Lawrence if self.cur_object:
edf8c55546efa9fb42da1c055ce02462a5c709c0David Lawrence self.cur_object.validate()
edf8c55546efa9fb42da1c055ce02462a5c709c0David Lawrence self.state = self.state_stack.pop()
c5944292e9ebee4a39fe939b9a16fe5596808556David Lawrence self.cur_object = self.cur_object_stack.pop()
c5944292e9ebee4a39fe939b9a16fe5596808556David Lawrence
c5944292e9ebee4a39fe939b9a16fe5596808556David Lawrencedef parse_options():
c5944292e9ebee4a39fe939b9a16fe5596808556David Lawrence parser = optparse.OptionParser("usage: %prog [options] introspect.xml ...")
c5944292e9ebee4a39fe939b9a16fe5596808556David Lawrence parser.set_description("sbus_codegen generates sbus interface structures \
c5944292e9ebee4a39fe939b9a16fe5596808556David Lawrence from standard XML Introspect data.")
c5944292e9ebee4a39fe939b9a16fe5596808556David Lawrence parser.add_option("--mode",
c5944292e9ebee4a39fe939b9a16fe5596808556David Lawrence dest="mode", default="header",
c5944292e9ebee4a39fe939b9a16fe5596808556David Lawrence help="'header' or 'source' (default: header)",
c5944292e9ebee4a39fe939b9a16fe5596808556David Lawrence metavar="MODE")
36e0c379080343a0272dc076b7d7795ded04ee1dBrian Wellington parser.add_option("--output",
36e0c379080343a0272dc076b7d7795ded04ee1dBrian Wellington dest="output", default=None,
529a6b5224d751504027293a766a4c8b81241869Brian Wellington help="Set output file name (default: stdout)",
529a6b5224d751504027293a766a4c8b81241869Brian Wellington metavar="FILE")
529a6b5224d751504027293a766a4c8b81241869Brian Wellington parser.add_option("--include",
186ba80b8e391cf8421872f26771324644e45d83Andreas Gustafsson dest="include", default=None,
186ba80b8e391cf8421872f26771324644e45d83Andreas Gustafsson help="name of a header to #include",
862a026a7d752fbc8b376df6f7a9080d7c778b49Brian Wellington metavar="HEADER")
677045ed612e1c26a32b5700479e26c25bcede58Brian Wellington (options, args) = parser.parse_args()
677045ed612e1c26a32b5700479e26c25bcede58Brian Wellington
677045ed612e1c26a32b5700479e26c25bcede58Brian Wellington if not args:
febf5f8b55abb2e6e840488a29a5ef4e20654f67David Lawrence print >> sys.stderr, "sbus_codegen: no input file specified"
febf5f8b55abb2e6e840488a29a5ef4e20654f67David Lawrence sys.exit(2)
c34bdef6bd197a04990e52469ad68481532dd35aAndreas Gustafsson
c34bdef6bd197a04990e52469ad68481532dd35aAndreas Gustafsson if options.mode not in ["header", "source"]:
c34bdef6bd197a04990e52469ad68481532dd35aAndreas Gustafsson print >> sys.stderr, "sbus_codegen: specify --mode=header or --mode=source"
05f6d0c0381d19eec721e11f6fd88caef25dacd8Andreas Gustafsson
c9b176a5281c8232eec0f2056ce10ea249afc4a3Mark Andrews return options, args
dc2c974dcf954a0a238d1afb886c445d06b1aa8bBrian Wellington
a32738e3e4ed9619c8ace22cd119e6769176b22cAndreas Gustafssondef main():
a32738e3e4ed9619c8ace22cd119e6769176b22cAndreas Gustafsson options, args = parse_options()
a32738e3e4ed9619c8ace22cd119e6769176b22cAndreas Gustafsson
6dc130c7c95107748fff5f767161c2bb742f9f87Brian Wellington if options.output:
6dc130c7c95107748fff5f767161c2bb742f9f87Brian Wellington sys.stdout = buf = StringIO.StringIO()
6dc130c7c95107748fff5f767161c2bb742f9f87Brian Wellington
49855f0856a0f6f9fed80af88faddf38f3e74eefAndreas Gustafsson for filename in args:
49855f0856a0f6f9fed80af88faddf38f3e74eefAndreas Gustafsson parser = DBusXMLParser(filename)
49855f0856a0f6f9fed80af88faddf38f3e74eefAndreas Gustafsson
49855f0856a0f6f9fed80af88faddf38f3e74eefAndreas Gustafsson if options.mode == "header":
ffea7c2e73a0771c80b32df93cf4547fcea64eaeAndreas Gustafsson generate_header(parser.parsed_interfaces, filename)
dc2c974dcf954a0a238d1afb886c445d06b1aa8bBrian Wellington elif options.mode == "source":
dc2c974dcf954a0a238d1afb886c445d06b1aa8bBrian Wellington generate_source(parser.parsed_interfaces, filename, options.include)
55bfdb0a1491f0668bb279826ee864f4a7425e22Andreas Gustafsson else:
55bfdb0a1491f0668bb279826ee864f4a7425e22Andreas Gustafsson assert False, "should not be reached"
55bfdb0a1491f0668bb279826ee864f4a7425e22Andreas Gustafsson
d4ab9cd94f0fe0cf24ba36d21240215ae648c8d5James Brister # Write output at end to be nice to 'make'
cef18335b7f37bf02bc9e9f2c8750a3a9dcd718aAndreas Gustafsson if options.output:
080a4fe83c3ad208073bffbce1a2af8fe444214fMichael Sawyer output = open(options.output, "w")
36007b707f28f36864e8d76f11379b22e9737538Michael Sawyer output.write(buf.getvalue())
36007b707f28f36864e8d76f11379b22e9737538Michael Sawyer output.close()
36007b707f28f36864e8d76f11379b22e9737538Michael Sawyer
375f19cfb2f9cf5a9efbc65b557a8ce865de85c2Michael Sawyerif __name__ == "__main__":
375f19cfb2f9cf5a9efbc65b557a8ce865de85c2Michael Sawyer try:
375f19cfb2f9cf5a9efbc65b557a8ce865de85c2Michael Sawyer main()
375f19cfb2f9cf5a9efbc65b557a8ce865de85c2Michael Sawyer except DBusXmlException, ex:
375f19cfb2f9cf5a9efbc65b557a8ce865de85c2Michael Sawyer print >> sys.stderr, str(ex)
375f19cfb2f9cf5a9efbc65b557a8ce865de85c2Michael Sawyer sys.exit(1)
9bef4575d71a084edf59ac681e53e35ae1b72166Andreas Gustafsson