sdbus++: use consistent typenames for properties
Previously, the generated code was assuming C++ names, but the example
(Calculator.interface.yaml) used an arbitrary name ('integer'). This
commit defines a consistent typename scheme and validates it when
interfaces are generated.
Use English typenames from the DBus protocol in interface files
rather than the C++ name or a single-letter DBus name. Use
square-bracket ([]) to identify sub-types for containers.
Examples: 'int64', 'path', 'array[dict[string, byte]]'
Change-Id: I38abe84c9cd3d5f839968349d2d3cfa0b8796cd0
Signed-off-by: Patrick Williams <patrick@stwcx.xyz>
diff --git a/tools/example/net/poettering/Calculator.interface.yaml b/tools/example/net/poettering/Calculator.interface.yaml
index 2c288b6..4167c36 100644
--- a/tools/example/net/poettering/Calculator.interface.yaml
+++ b/tools/example/net/poettering/Calculator.interface.yaml
@@ -8,17 +8,17 @@
Multiplies two integers 'x' and 'y' and returns the result.
parameters:
- name: x
- type: integer
+ type: int64
description: >
The first integer to multiply.
- name: y
- type: integer
+ type: int64
description: >
The second integer to multiply.
default: 1
returns:
- name: z
- type: integer
+ type: int64
description: >
The result of (x*y).
- name: Divide
@@ -26,17 +26,17 @@
Divides two integers 'x' and 'y' and returns the result.
parameters:
- name: x
- type: integer
+ type: int64
description: >
The first integer to divide.
- name: y
- type: integer
+ type: int64
description: >
The second integer to divide.
default: 1
returns:
- name: z
- type: integer
+ type: int64
description: >
The result of (x/y).
errors:
@@ -46,7 +46,7 @@
Reset the LastResult property to zero.
properties:
- name: LastResult
- type: integer
+ type: int64
default: 0
description: >
The result of the most recent calculation.
@@ -56,7 +56,7 @@
Signal indicating the LastReset property has been set to zero by the
'Clear' method.
properties:
- - type: integer
+ - type: int64
description: >
Value of LastReset prior to Clear.
diff --git a/tools/sdbusplus/property.py b/tools/sdbusplus/property.py
index 2c35b63..bdff93d 100644
--- a/tools/sdbusplus/property.py
+++ b/tools/sdbusplus/property.py
@@ -1,14 +1,86 @@
from .namedelement import NamedElement
from .renderer import Renderer
+import yaml
class Property(NamedElement, Renderer):
def __init__(self, **kwargs):
self.typeName = kwargs.pop('type', None)
+ self.cppTypeName = self.parse_cpp_type(self.typeName)
self.defaultValue = kwargs.pop('default', None)
super(Property, self).__init__(**kwargs)
+ def parse_cpp_type(self, typeName):
+ if not typeName:
+ return None
+
+ """ typeNames are _almost_ valid YAML. Insert a , before each [
+ and then wrap it in a [ ] and it becomes valid YAML. (assuming
+ the user gave us a valid typename)
+ """
+ parse = yaml.safe_load("[" + ",[".join(typeName.split("[")) + "]")
+ return self.__parse_cpp_type__(parse)
+
+ """ Take a list of dbus types and perform validity checking, such as:
+ [ variant [ dict [ int32, int32 ], double ] ]
+ This function then converts the type-list into a C++ type string.
+ """
+ def __parse_cpp_type__(self, typeArray):
+ propertyMap = {
+ 'byte': {'cppName': 'uint8_t', 'params': 0},
+ 'boolean': {'cppName': 'bool', 'params': 0},
+ 'int16': {'cppName': 'int16_t', 'params': 0},
+ 'uint16': {'cppName': 'uint16_t', 'params': 0},
+ 'int32': {'cppName': 'int32_t', 'params': 0},
+ 'uint32': {'cppName': 'uint32_t', 'params': 0},
+ 'int64': {'cppName': 'int64_t', 'params': 0},
+ 'uint64': {'cppName': 'uint64_t', 'params': 0},
+ 'double': {'cppName': 'double', 'params': 0},
+ 'string': {'cppName': 'std::string', 'params': 0},
+ 'path': {'cppName': 'std::string', 'params': 0},
+ 'signature': {'cppName': 'std::string', 'params': 0},
+ 'array': {'cppName': 'std::vector', 'params': 1},
+ 'struct': {'cppName': 'std::tuple', 'params': -1},
+ 'variant': {'cppName': 'sdbusplus::variant', 'params': -1},
+ 'dict': {'cppName': 'std::map', 'params': 2},
+ 'enum': {'cppName': 'enum', 'params': 1, 'noparse': True}}
+
+ first = typeArray.pop(0)
+ entry = propertyMap[first]
+
+ result = entry['cppName']
+
+ # Handle 0-entry parameter lists.
+ if (entry['params'] == 0):
+ if (len(typeArray) != 0):
+ raise RuntimeError("Invalid typeArray %s" % typeArray)
+ else:
+ return result
+
+ # Get remainder of the parameter list, which should be the last
+ # element.
+ rest = typeArray.pop(0)
+ if (len(typeArray) != 0):
+ raise RuntimeError("Invalid typeArray %s" % typeArray)
+
+ # Confirm parameter count matches.
+ if (entry['params'] != -1) and (entry['params'] != len(rest)):
+ raise RuntimeError("Invalid entry count for %s : %s" %
+ (first, rest))
+
+ # Parse each parameter entry, if appropriate, and create C++ template
+ # syntax.
+ result += '<'
+ if entry.get('noparse'):
+ result += ", ".join(rest)
+ else:
+ result += ", ".join(map(lambda e: self.__parse_cpp_type__([e]),
+ rest))
+ result += '>'
+
+ return result
+
def markdown(self, loader):
return self.render(loader, "property.mako.md", property=self,
post=str.strip)
diff --git a/tools/sdbusplus/templates/interface.mako.server.cpp b/tools/sdbusplus/templates/interface.mako.server.cpp
index cc0d900..6f74ff5 100644
--- a/tools/sdbusplus/templates/interface.mako.server.cpp
+++ b/tools/sdbusplus/templates/interface.mako.server.cpp
@@ -35,7 +35,7 @@
% endfor
% for p in interface.properties:
-${p.typeName} ${classname}::${p.camelCase}() const
+${p.cppTypeName} ${classname}::${p.camelCase}() const
{
return _${p.camelCase};
}
@@ -53,7 +53,7 @@
return 0;
}
-${p.typeName} ${classname}::${p.camelCase}(${p.typeName} value)
+${p.cppTypeName} ${classname}::${p.camelCase}(${p.cppTypeName} value)
{
if (_${p.camelCase} != value)
{
@@ -86,7 +86,7 @@
{
static const auto _property_${p.name} =
utility::tuple_to_array(message::types::type_id<
- ${p.typeName}>());
+ ${p.cppTypeName}>());
}
}
% endfor
diff --git a/tools/sdbusplus/templates/interface.mako.server.hpp b/tools/sdbusplus/templates/interface.mako.server.hpp
index 795205b..954742d 100644
--- a/tools/sdbusplus/templates/interface.mako.server.hpp
+++ b/tools/sdbusplus/templates/interface.mako.server.hpp
@@ -49,9 +49,9 @@
% for p in interface.properties:
/** Get value of ${p.name} */
- virtual ${p.typeName} ${p.camelCase}() const;
+ virtual ${p.cppTypeName} ${p.camelCase}() const;
/** Set value of ${p.name} */
- virtual ${p.typeName} ${p.camelCase}(${p.typeName} value);
+ virtual ${p.cppTypeName} ${p.camelCase}(${p.cppTypeName} value);
% endfor
private:
@@ -78,9 +78,9 @@
% for p in interface.properties:
% if p.defaultValue:
- ${p.typeName} _${p.camelCase} = ${p.defaultValue};
+ ${p.cppTypeName} _${p.camelCase} = ${p.defaultValue};
% else:
- ${p.typeName} _${p.camelCase}{};
+ ${p.cppTypeName} _${p.camelCase}{};
% endif
% endfor
diff --git a/tools/sdbusplus/templates/method.mako.prototype.hpp b/tools/sdbusplus/templates/method.mako.prototype.hpp
index db056ff..20a4373 100644
--- a/tools/sdbusplus/templates/method.mako.prototype.hpp
+++ b/tools/sdbusplus/templates/method.mako.prototype.hpp
@@ -3,7 +3,7 @@
if len(method.returns) == 0:
return "void"
elif len(method.returns) == 1:
- return method.returns[0].typeName
+ return method.returns[0].cppTypeName
else:
return "std::tuple<" + \
returns_as_list() + \
@@ -20,16 +20,16 @@
return ", ".join([ p.camelCase for p in method.parameters ])
def parameters_types_as_list():
- return ", ".join([ p.typeName for p in method.parameters ])
+ return ", ".join([ p.cppTypeName for p in method.parameters ])
def parameter(p, defaultValue=False):
- r = "%s %s" % (p.typeName, p.camelCase)
+ r = "%s %s" % (p.cppTypeName, p.camelCase)
if defaultValue:
r += default_value(p)
return r
def returns_as_list():
- return ", ".join([ r.typeName for r in method.returns ])
+ return ", ".join([ r.cppTypeName for r in method.returns ])
def returns_as_tuple_index(tuple):
return ", ".join([ "std::move(std::get<%d>(%s))" % (i,tuple) \
@@ -73,7 +73,7 @@
% if len(method.returns) != 0:
*
% for r in method.returns:
- * @return ${r.camelCase}[${r.typeName}] - ${r.description.strip()}
+ * @return ${r.camelCase}[${r.cppTypeName}] - ${r.description.strip()}
% endfor
% endif
*/
diff --git a/tools/sdbusplus/templates/signal.mako.prototype.hpp b/tools/sdbusplus/templates/signal.mako.prototype.hpp
index 8dfaf81..7050ec3 100644
--- a/tools/sdbusplus/templates/signal.mako.prototype.hpp
+++ b/tools/sdbusplus/templates/signal.mako.prototype.hpp
@@ -4,7 +4,7 @@
join([ parameter(p, defaultValue) for p in signal.properties ])
def parameter(p, defaultValue=False):
- r = "%s %s" % (p.typeName, p.camelCase)
+ r = "%s %s" % (p.cppTypeName, p.camelCase)
if defaultValue:
r += default_value(p)
return r
@@ -13,7 +13,7 @@
return ", ".join([ p.camelCase for p in signal.properties ])
def parameters_types_as_list():
- return ", ".join([ p.typeName for p in signal.properties ])
+ return ", ".join([ p.cppTypeName for p in signal.properties ])
def default_value(p):
if p.defaultValue != None: