summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakub Kicinski <kuba@kernel.org>2025-05-15 16:16:46 -0700
committerJakub Kicinski <kuba@kernel.org>2025-05-16 16:32:05 -0700
commit6366d267788fd9dba20d6dff61e3e05d48ddb0b8 (patch)
tree7b98b7d077e1a9c2081b7dc20b4d770f5852bb0c
parent3186a8e55ae3428ec1e06af09075e20885376e4e (diff)
tools: ynl-gen: submsg: render the structs
The easiest (or perhaps only sane) way to support submessages in C is to treat them as if they were nests. Build fake attributes to that effect in the codegen. Render the submsg as a big nest of all possible values. With this in place the main missing part is to hook in the switch which selects how to parse based on the key. Reviewed-by: Donald Hunter <donald.hunter@gmail.com> Link: https://patch.msgid.link/20250515231650.1325372-6-kuba@kernel.org Signed-off-by: Jakub Kicinski <kuba@kernel.org>
-rwxr-xr-xtools/net/ynl/pyynl/ynl_gen_c.py46
1 files changed, 43 insertions, 3 deletions
diff --git a/tools/net/ynl/pyynl/ynl_gen_c.py b/tools/net/ynl/pyynl/ynl_gen_c.py
index 2292bbb68836..020aa34b890b 100755
--- a/tools/net/ynl/pyynl/ynl_gen_c.py
+++ b/tools/net/ynl/pyynl/ynl_gen_c.py
@@ -62,6 +62,8 @@ class Type(SpecAttr):
if 'nested-attributes' in attr:
nested = attr['nested-attributes']
+ elif 'sub-message' in attr:
+ nested = attr['sub-message']
else:
nested = None
@@ -125,7 +127,9 @@ class Type(SpecAttr):
return c_upper(value)
def resolve(self):
- if 'name-prefix' in self.attr:
+ if 'parent-sub-message' in self.attr:
+ enum_name = self.attr['parent-sub-message'].enum_name
+ elif 'name-prefix' in self.attr:
enum_name = f"{self.attr['name-prefix']}{self.name}"
else:
enum_name = f"{self.attr_set.name_prefix}{self.name}"
@@ -873,18 +877,20 @@ class TypeNestTypeValue(Type):
return get_lines, init_lines, local_vars
-class TypeSubMessage(TypeUnused):
+class TypeSubMessage(TypeNest):
pass
class Struct:
- def __init__(self, family, space_name, type_list=None, inherited=None):
+ def __init__(self, family, space_name, type_list=None,
+ inherited=None, submsg=None):
self.family = family
self.space_name = space_name
self.attr_set = family.attr_sets[space_name]
# Use list to catch comparisons with empty sets
self._inherited = inherited if inherited is not None else []
self.inherited = []
+ self.submsg = submsg
self.nested = type_list is None
if family.name == c_lower(space_name):
@@ -1250,6 +1256,8 @@ class Family(SpecFamily):
for _, spec in self.attr_sets[name].items():
if 'nested-attributes' in spec:
nested = spec['nested-attributes']
+ elif 'sub-message' in spec:
+ nested = spec.sub_message
else:
continue
@@ -1286,6 +1294,32 @@ class Family(SpecFamily):
return nested
+ def _load_nested_set_submsg(self, spec):
+ # Fake the struct type for the sub-message itself
+ # its not a attr_set but codegen wants attr_sets.
+ submsg = self.sub_msgs[spec["sub-message"]]
+ nested = submsg.name
+
+ attrs = []
+ for name, fmt in submsg.formats.items():
+ attrs.append({
+ "name": name,
+ "type": "nest",
+ "parent-sub-message": spec,
+ "nested-attributes": fmt['attribute-set']
+ })
+
+ self.attr_sets[nested] = AttrSet(self, {
+ "name": nested,
+ "name-pfx": self.name + '-' + spec.name + '-',
+ "attributes": attrs
+ })
+
+ if nested not in self.pure_nested_structs:
+ self.pure_nested_structs[nested] = Struct(self, nested, submsg=submsg)
+
+ return nested
+
def _load_nested_sets(self):
attr_set_queue = list(self.root_sets.keys())
attr_set_seen = set(self.root_sets.keys())
@@ -1295,6 +1329,8 @@ class Family(SpecFamily):
for attr, spec in self.attr_sets[a_set].items():
if 'nested-attributes' in spec:
nested = self._load_nested_set_nest(spec)
+ elif 'sub-message' in spec:
+ nested = self._load_nested_set_submsg(spec)
else:
continue
@@ -1306,6 +1342,8 @@ class Family(SpecFamily):
for attr, spec in self.attr_sets[root_set].items():
if 'nested-attributes' in spec:
nested = spec['nested-attributes']
+ elif 'sub-message' in spec:
+ nested = spec.sub_message
else:
nested = None
@@ -1329,6 +1367,8 @@ class Family(SpecFamily):
if 'nested-attributes' in spec:
child_name = spec['nested-attributes']
+ elif 'sub-message' in spec:
+ child_name = spec.sub_message
else:
continue