diff options
Diffstat (limited to 'lib9p/idl.gen')
-rwxr-xr-x | lib9p/idl.gen | 63 |
1 files changed, 34 insertions, 29 deletions
diff --git a/lib9p/idl.gen b/lib9p/idl.gen index 72efb7b..47aa608 100755 --- a/lib9p/idl.gen +++ b/lib9p/idl.gen @@ -2,7 +2,7 @@ # lib9p/idl.gen - Generate C marshalers/unmarshalers for .9p files # defining 9P protocol variants. # -# Copyright (C) 2024 Luke T. Shumaker <lukeshu@lukeshu.com> +# Copyright (C) 2024-2025 Luke T. Shumaker <lukeshu@lukeshu.com> # SPDX-License-Identifier: AGPL-3.0-or-later import os.path @@ -694,43 +694,48 @@ LM_ALWAYS_INLINE static bool marshal_8(struct _marshal_ctx *ctx, uint64_t *val) for msg in [msg for msg in typs if isinstance(msg, idl.Message)]: id2typ[msg.msgid] = msg - ret += "\n" + ret += f"#define _MSG_NAME(typ) [{idprefix.upper()}TYP_##typ] = #typ\n" ret += c_macro( - f"#define _MSG(typ) [{idprefix.upper()}TYP_##typ] = {{", - f"\t\t.name = #typ,", + f"#define _MSG_RECV(typ) [{idprefix.upper()}TYP_##typ/2] = {{", f"\t\t.basesize = sizeof(struct {idprefix}msg_##typ),", f"\t\t.validate = validate_##typ,", f"\t\t.unmarshal = (_unmarshal_fn_t)unmarshal_##typ,", - f"\t\t.marshal = (_marshal_fn_t)marshal_##typ,", f"\t}}", ) ret += c_macro( - f"#define _NONMSG(num) [num] = {{", f"\t\t.name = #num,", f"\t}}" + f"#define _MSG_SEND(typ) [{idprefix.upper()}TYP_##typ/2] = {{", + f"\t\t.marshal = (_marshal_fn_t)marshal_##typ,", + f"\t}}", ) - ret += "\n" - ret += f"struct _table_version _{idprefix}versions[{c_ver_enum('NUM')}] = {{\n" - for ver in ["unknown", *sorted(versions)]: - if ver != "unknown": - ret += ifdef_push(1, c_ver_ifdef({ver})) - ret += f"\t[{c_ver_enum(ver)}] = {{ .msgs = {{\n" - - for n in range(0, 0x100): - xmsg: idl.Message | None = id2typ.get(n, None) - if xmsg: - if ver == "unknown": # SPECIAL - if xmsg.name not in ["Tversion", "Rversion", "Rerror"]: - xmsg = None - else: - if ver not in xmsg.in_versions: - xmsg = None - if xmsg: - ret += f"\t\t_MSG({xmsg.name}),\n" - else: - ret += "\t\t_NONMSG(0x{:02X}),\n".format(n) - ret += "\t}},\n" - ret += ifdef_pop(0) - ret += "};\n" + tables = [ + ("msg", "name", "char *", (0, 0x100, 1)), + ("Tmsg", "recv", f"struct _{idprefix}recv_tentry", (0, 0x100, 2)), + ("Rmsg", "recv", f"struct _{idprefix}recv_tentry", (1, 0x100, 2)), + ("Tmsg", "send", f"struct _{idprefix}send_tentry", (0, 0x100, 2)), + ("Rmsg", "send", f"struct _{idprefix}send_tentry", (1, 0x100, 2)), + ] + for grp, meth, tentry, rng in tables: + ret += "\n" + ret += f"const {tentry} _{idprefix}table_{grp}_{meth}[{c_ver_enum('NUM')}][{hex(len(range(*rng)))}] = {{\n" + for ver in ["unknown", *sorted(versions)]: + if ver != "unknown": + ret += ifdef_push(1, c_ver_ifdef({ver})) + ret += f"\t[{c_ver_enum(ver)}] = {{\n" + for n in range(*rng): + xmsg: idl.Message | None = id2typ.get(n, None) + if xmsg: + if ver == "unknown": # SPECIAL + if xmsg.name not in ["Tversion", "Rversion", "Rerror"]: + xmsg = None + else: + if ver not in xmsg.in_versions: + xmsg = None + if xmsg: + ret += f"\t\t_MSG_{meth.upper()}({xmsg.name}),\n" + ret += "\t},\n" + ret += ifdef_pop(0) + ret += "};\n" ret += f""" LM_FLATTEN bool _{idprefix}validate_stat(struct _validate_ctx *ctx) {{ |