diff options
Diffstat (limited to 'lib9p/idl.gen')
-rwxr-xr-x | lib9p/idl.gen | 28 |
1 files changed, 24 insertions, 4 deletions
diff --git a/lib9p/idl.gen b/lib9p/idl.gen index 27396b4..0a43583 100755 --- a/lib9p/idl.gen +++ b/lib9p/idl.gen @@ -5,8 +5,10 @@ # Copyright (C) 2024-2025 Luke T. Shumaker <lukeshu@lukeshu.com> # SPDX-License-Identifier: AGPL-3.0-or-later +import graphlib import os.path import sys +import typing sys.path.insert(0, os.path.normpath(os.path.join(__file__, ".."))) @@ -141,6 +143,24 @@ def ifdef_pop(n: int) -> str: return ret +def topo_sorted(typs: list[idl.Type]) -> typing.Iterable[idl.Type]: + ts: graphlib.TopologicalSorter[idl.Type] = graphlib.TopologicalSorter() + for typ in typs: + match typ: + case idl.Number(): + ts.add(typ) + case idl.Bitfield(): + ts.add(typ) + case idl.Struct(): # and idl.Message(): + deps = [ + member.typ + for member in typ.members + if not isinstance(member.typ, idl.Primitive) + ] + ts.add(typ, *deps) + return ts.static_order() + + # Generate .h ################################################################## @@ -201,7 +221,7 @@ enum {idprefix}version {{ ret += """ /* payload types **************************************************************/ """ - for typ in typs: + for typ in topo_sorted(typs): ret += "\n" ret += ifdef_push(1, c_ver_ifdef(typ.in_versions)) match typ: @@ -385,7 +405,7 @@ LM_ALWAYS_INLINE static bool _validate_list(struct _validate_ctx *ctx, #define validate_4(ctx) _validate_size_net(ctx, 4) #define validate_8(ctx) _validate_size_net(ctx, 8) """ - for typ in typs: + for typ in topo_sorted(typs): inline = "LM_FLATTEN" if isinstance(typ, idl.Message) else "LM_ALWAYS_INLINE" argfn = unused if (isinstance(typ, idl.Struct) and not typ.members) else used ret += "\n" @@ -525,7 +545,7 @@ LM_ALWAYS_INLINE static void unmarshal_8(struct _unmarshal_ctx *ctx, uint64_t *o \tctx->net_offset += 8; } """ - for typ in typs: + for typ in topo_sorted(typs): inline = "LM_FLATTEN" if isinstance(typ, idl.Message) else "LM_ALWAYS_INLINE" argfn = unused if (isinstance(typ, idl.Struct) and not typ.members) else used ret += "\n" @@ -618,7 +638,7 @@ LM_ALWAYS_INLINE static bool marshal_8(struct _marshal_ctx *ctx, uint64_t *val) \treturn false; } """ - for typ in typs: + for typ in topo_sorted(typs): inline = "LM_FLATTEN" if isinstance(typ, idl.Message) else "LM_ALWAYS_INLINE" argfn = unused if (isinstance(typ, idl.Struct) and not typ.members) else used ret += "\n" |