diff options
author | Jakub Kicinski <kuba@kernel.org> | 2025-05-15 16:16:46 -0700 |
---|---|---|
committer | Jakub Kicinski <kuba@kernel.org> | 2025-05-16 16:32:05 -0700 |
commit | 6366d267788fd9dba20d6dff61e3e05d48ddb0b8 (patch) | |
tree | 7b98b7d077e1a9c2081b7dc20b4d770f5852bb0c | |
parent | 3186a8e55ae3428ec1e06af09075e20885376e4e (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-x | tools/net/ynl/pyynl/ynl_gen_c.py | 46 |
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 |