summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPatrick Williams <patrick@stwcx.xyz>2016-10-15 07:15:12 -0500
committerPatrick Williams <patrick@stwcx.xyz>2016-10-16 18:17:20 -0500
commit04e007f17c9f21cfee922d811a4433dd11243d39 (patch)
tree75d4d42eec33b5280c8fe17f8e8cb6d09fc506b6
parente70f0e8b42627b355dc402bb0bc006d07cfef274 (diff)
downloadsdbusplus-04e007f17c9f21cfee922d811a4433dd11243d39.tar.gz
sdbusplus-04e007f17c9f21cfee922d811a4433dd11243d39.zip
sdbus++: generate header for server bindings
Add a 'server-header' command to sdbus++ that generates a class definition for the server bindings. This class defines static functions for registering as sd-bus callbacks and virtual C++ functions to implement the method behavior. It is expected that a server implementation will create a class, which inherits from this generated class, and implement all of the method behaviors. Instances of the class will then register on construction with sd-bus. Signals and properties are not yet supported. Change-Id: If0ec37b2acb6f8d528358004ec91dbe979644df7 Signed-off-by: Patrick Williams <patrick@stwcx.xyz>
-rwxr-xr-xtools/sdbus++3
-rw-r--r--tools/sdbusplus/interface.py3
-rw-r--r--tools/sdbusplus/method.py4
-rw-r--r--tools/templates/interface.mako.server.hpp37
-rw-r--r--tools/templates/method.mako.prototype.hpp57
5 files changed, 103 insertions, 1 deletions
diff --git a/tools/sdbus++ b/tools/sdbus++
index e68685d..6606d07 100755
--- a/tools/sdbus++
+++ b/tools/sdbus++
@@ -5,7 +5,8 @@ import argparse
def main():
valid_types = { 'interface': sdbusplus.Interface }
- valid_processes = { 'markdown' : "markdown" }
+ valid_processes = { 'markdown' : "markdown",
+ 'server-header' : "server_header" }
parser = argparse.ArgumentParser(description='Process sdbus++ YAML files.')
diff --git a/tools/sdbusplus/interface.py b/tools/sdbusplus/interface.py
index 0cdb1a0..fa56eb9 100644
--- a/tools/sdbusplus/interface.py
+++ b/tools/sdbusplus/interface.py
@@ -30,3 +30,6 @@ class Interface(NamedElement, Renderer):
def markdown(self, loader):
return self.render(loader, "interface.mako.md", interface=self)
+
+ def server_header(self, loader):
+ return self.render(loader, "interface.mako.server.hpp", interface=self)
diff --git a/tools/sdbusplus/method.py b/tools/sdbusplus/method.py
index f8e2efd..84d6095 100644
--- a/tools/sdbusplus/method.py
+++ b/tools/sdbusplus/method.py
@@ -14,3 +14,7 @@ class Method(NamedElement, Renderer):
def markdown(self, loader):
return self.render(loader, "method.mako.md", method=self)
+
+ def cpp_prototype(self, loader, interface, ptype):
+ return self.render(loader, "method.mako.prototype.hpp", method=self,
+ interface=interface, ptype=ptype, post=str.rstrip)
diff --git a/tools/templates/interface.mako.server.hpp b/tools/templates/interface.mako.server.hpp
new file mode 100644
index 0000000..ff18548
--- /dev/null
+++ b/tools/templates/interface.mako.server.hpp
@@ -0,0 +1,37 @@
+#pragma once
+#include <tuple>
+#include <systemd/sd-bus.h>
+#include <sdbusplus/vtable.hpp>
+ <%
+ namespaces = interface.name.split('.')
+ classname = namespaces.pop()
+ %>
+namespace sdbusplus
+{
+namespace server
+{
+ % for s in namespaces:
+namespace ${s}
+{
+ % endfor
+
+class ${classname}
+{
+ public:
+ % for m in interface.methods:
+${ m.cpp_prototype(loader, interface=interface, ptype='header') }
+ % endfor
+
+ private:
+ % for m in interface.methods:
+${ m.cpp_prototype(loader, interface=interface, ptype='callback-header') }
+ % endfor
+
+ static const sdbusplus::vtable::vtable_t _vtable[];
+};
+
+ % for s in namespaces:
+} // namespace ${s}
+ % endfor
+} // namespace server
+} // namespace sdbusplus
diff --git a/tools/templates/method.mako.prototype.hpp b/tools/templates/method.mako.prototype.hpp
new file mode 100644
index 0000000..5055dbb
--- /dev/null
+++ b/tools/templates/method.mako.prototype.hpp
@@ -0,0 +1,57 @@
+<%
+ def cpp_return_type():
+ if len(method.returns) == 0:
+ return "void"
+ elif len(method.returns) == 1:
+ return method.returns[0].typeName
+ else:
+ return "std::tuple<" + \
+ ", ".join([ r.typeName for r in method.returns ]) + \
+ ">"
+
+ def parameters(defaultValue=False):
+ return ",\n ".\
+ join([ parameter(p, defaultValue) for p in method.parameters ])
+
+ def parameter(p, defaultValue=False):
+ r = "%s %s" % (p.typeName, p.name)
+ if defaultValue:
+ r += default_value(p)
+ return r
+
+ def default_value(p):
+ if p.defaultValue != None:
+ return " = " + str(p.defaultValue)
+ else:
+ return ""
+%>
+###
+### Emit 'header'
+###
+ % if ptype == 'header':
+ /** @brief Implementation for ${ method.name }
+ * ${ method.description.strip() }
+ % if len(method.parameters) != 0:
+ *
+ % for p in method.parameters:
+ * @param[in] ${p.name} - ${p.description.strip()}
+ % endfor
+ % endif
+ % if len(method.returns) != 0:
+ *
+ % for r in method.returns:
+ * @return ${r.name}[${r.typeName}] - ${r.description.strip()}
+ % endfor
+ % endif
+ */
+ virtual ${cpp_return_type()} ${ method.name }(
+ ${ parameters() }) = 0;
+###
+### Emit 'callback-header'
+###
+ % elif ptype == 'callback-header':
+ /** @brief sd-bus callback for ${ method.name }
+ */
+ static int _callback_${ method.name }(
+ sd_bus_message*, void*, sd_bus_error*);
+ % endif
OpenPOWER on IntegriCloud