sdbus++: common: generate object_paths
Signed-off-by: Patrick Williams <patrick@stwcx.xyz>
Change-Id: Iacaa65fa1063b34269d55df3c581e5921dbbc300
diff --git a/tools/meson.build b/tools/meson.build
index d290b5f..bce5559 100644
--- a/tools/meson.build
+++ b/tools/meson.build
@@ -7,6 +7,7 @@
'sdbusplus/main.py',
'sdbusplus/method.py',
'sdbusplus/namedelement.py',
+ 'sdbusplus/path.py',
'sdbusplus/property.py',
'sdbusplus/renderer.py',
'sdbusplus/signal.py',
diff --git a/tools/sdbusplus/interface.py b/tools/sdbusplus/interface.py
index 734a1fe..d6c2bac 100644
--- a/tools/sdbusplus/interface.py
+++ b/tools/sdbusplus/interface.py
@@ -5,6 +5,7 @@
from .enum import Enum
from .method import Method
from .namedelement import NamedElement
+from .path import Path
from .property import Property
from .renderer import Renderer
from .signal import Signal
@@ -28,6 +29,7 @@
self.methods = [Method(**m) for m in kwargs.pop("methods", [])]
self.signals = [Signal(**s) for s in kwargs.pop("signals", [])]
self.enums = [Enum(**e) for e in kwargs.pop("enumerations", [])]
+ self.paths = [Path(**p) for p in kwargs.pop("paths", [])]
super(Interface, self).__init__(**kwargs)
diff --git a/tools/sdbusplus/path.py b/tools/sdbusplus/path.py
new file mode 100644
index 0000000..c3a9e13
--- /dev/null
+++ b/tools/sdbusplus/path.py
@@ -0,0 +1,44 @@
+import re
+
+from .namedelement import NamedElement
+
+""" Class for parsing 'path' definition elements from an interface.
+"""
+
+
+class Path(NamedElement):
+ def __init__(self, segment=False, **kwargs):
+ if "namespace" in kwargs:
+ kwargs["name"] = "NamespacePath"
+ self.value = kwargs.pop("namespace")
+ elif "instance" in kwargs:
+ kwargs["name"] = "InstancePath"
+ self.value = kwargs.pop("instance")
+ else:
+ self.value = kwargs.pop("value", False)
+
+ # Validate path/segment format.
+ if len(self.value) == 0:
+ raise ValueError("Invalid empty path.")
+ if not segment and self.value[0] != "/":
+ raise ValueError(f"Paths must start with /: {self.value}")
+ if segment and self.value[0] == "/":
+ raise ValueError(f"Segments canot start with /: {self.value}")
+ segments = self.value.split("/")
+ if not segment:
+ segments = segments[1:]
+ for s in segments:
+ if len(s) == 0:
+ raise ValueError(
+ f"Paths cannot have consecutive /: {self.value} {s}"
+ )
+ if re.search("[^a-zA-Z0-9_]", s):
+ raise ValueError(
+ f"Path contains illegal characters: {self.value}"
+ )
+
+ self.segments = [
+ Path(segment=True, **s) for s in kwargs.pop("segments", [])
+ ]
+
+ super(Path, self).__init__(**kwargs)
diff --git a/tools/sdbusplus/templates/interface.common.hpp.mako b/tools/sdbusplus/templates/interface.common.hpp.mako
index d33fe12..6331245 100644
--- a/tools/sdbusplus/templates/interface.common.hpp.mako
+++ b/tools/sdbusplus/templates/interface.common.hpp.mako
@@ -25,6 +25,26 @@
};
% endfor
+ % for p in interface.paths:
+ % if p.description:
+ /** ${p.description.strip()} */
+ % endif
+ % if len(p.segments) == 0:
+ static constexpr auto ${p.snake_case} = "${p.value}";
+ % else:
+ struct ${p.snake_case}
+ {
+ static constexpr auto value = "${p.value}";
+ % for s in p.segments:
+ % if s.description:
+ /** ${s.description.strip()} */
+ % endif
+ static constexpr auto ${s.snake_case} = "${s.value}";
+ % endfor
+ };
+ % endif
+ % endfor
+
% for e in interface.enums:
/** @brief Convert a string to an appropriate enum value.
* @param[in] s - The string to convert in the form of