summaryrefslogtreecommitdiff
path: root/lib9p/idl.gen
diff options
context:
space:
mode:
Diffstat (limited to 'lib9p/idl.gen')
-rwxr-xr-xlib9p/idl.gen102
1 files changed, 48 insertions, 54 deletions
diff --git a/lib9p/idl.gen b/lib9p/idl.gen
index 47ca49a..4c3103c 100755
--- a/lib9p/idl.gen
+++ b/lib9p/idl.gen
@@ -204,8 +204,6 @@ enum {idprefix}version {{
ret += ifdef_pop(0)
ret += f"\t{c_ver_enum('NUM')},\n"
ret += "};\n"
- ret += "\n"
- ret += f"const char *{idprefix}version_str(enum {idprefix}version);\n"
ret += """
/* enum msg_type **************************************************************/
@@ -330,6 +328,38 @@ def gen_c(versions: set[str], typs: list[idl.Type]) -> str:
def unused(arg: str) -> str:
return f"LM_UNUSED({arg})"
+ for v in sorted(versions):
+ ret += f"#if CONFIG_9P_ENABLE_{v.replace('.', '_')}\n"
+ ret += f"\t#define _is_ver_{v.replace('.', '_')}(v) (v == {c_ver_enum(v)})\n"
+ ret += "#else\n"
+ ret += f"\t#define _is_ver_{v.replace('.', '_')}(v) false\n"
+ ret += "#endif\n"
+ id2typ: dict[int, idl.Message] = {}
+ for msg in [msg for msg in typs if isinstance(msg, idl.Message)]:
+ id2typ[msg.msgid] = msg
+
+ def msg_table(grp: str, meth: str, tentry: str, rng: tuple[int, int, int]) -> str:
+ 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"
+ return ret
+
ret += "\n"
ret += "/**\n"
ret += f" * is_ver(ctx, ver) is essentially `(ctx->ctx->version == {idprefix.upper()}VER_##ver)`,\n"
@@ -338,18 +368,12 @@ def gen_c(versions: set[str], typs: list[idl.Type]) -> str:
ret += " * several version checks together.\n"
ret += " */\n"
ret += "#define is_ver(ctx, ver) _is_ver_##ver(ctx->ctx->version)\n"
- for v in sorted(versions):
- ret += f"#if CONFIG_9P_ENABLE_{v.replace('.', '_')}\n"
- ret += f"\t#define _is_ver_{v.replace('.', '_')}(v) (v == {c_ver_enum(v)})\n"
- ret += "#else\n"
- ret += f"\t#define _is_ver_{v.replace('.', '_')}(v) false\n"
- ret += "#endif\n"
# strings ##################################################################
ret += f"""
/* strings ********************************************************************/
-static const char *version_strs[{c_ver_enum('NUM')}] = {{
+const char *_lib9p_table_ver_name[{c_ver_enum('NUM')}] = {{
"""
for ver in ["unknown", *sorted(versions)]:
if ver in versions:
@@ -357,15 +381,10 @@ static const char *version_strs[{c_ver_enum('NUM')}] = {{
ret += f'\t[{c_ver_enum(ver)}] = "{ver}",\n'
ret += ifdef_pop(0)
ret += "};\n"
- ret += f"""
-const char *{idprefix}version_str(enum {idprefix}version ver) {{
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wtype-limits"
- assert(0 <= ver && ver < {c_ver_enum('NUM')});
-#pragma GCC diagnostic pop
- return version_strs[ver];
-}}
-"""
+
+ ret += "\n"
+ ret += f"#define _MSG_NAME(typ) [{idprefix.upper()}TYP_##typ] = #typ\n"
+ ret += msg_table("msg", "name", "char *", (0, 0x100, 1))
# bitmasks #################################################################
ret += f"""
@@ -739,15 +758,11 @@ LM_ALWAYS_INLINE static bool marshal_8(struct _marshal_ctx *ctx, uint64_t *val)
ret += "}\n"
ret += ifdef_pop(0)
- # tables / exports #########################################################
+ # function tables ##########################################################
ret += """
-/* tables / exports ***********************************************************/
-"""
- id2typ: dict[int, idl.Message] = {}
- for msg in [msg for msg in typs if isinstance(msg, idl.Message)]:
- id2typ[msg.msgid] = msg
+/* function tables ************************************************************/
- ret += f"#define _MSG_NAME(typ) [{idprefix.upper()}TYP_##typ] = #typ\n"
+"""
ret += c_macro(
f"#define _MSG_RECV(typ) [{idprefix.upper()}TYP_##typ/2] = {{",
f"\t\t.basesize = sizeof(struct {idprefix}msg_##typ),",
@@ -760,35 +775,14 @@ LM_ALWAYS_INLINE static bool marshal_8(struct _marshal_ctx *ctx, uint64_t *val)
f"\t\t.marshal = (_marshal_fn_t)marshal_##typ,",
f"\t}}",
)
-
- 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 += "\n"
+ ret += msg_table("Tmsg", "recv", f"struct _{idprefix}recv_tentry", (0, 0x100, 2))
+ ret += "\n"
+ ret += msg_table("Rmsg", "recv", f"struct _{idprefix}recv_tentry", (1, 0x100, 2))
+ ret += "\n"
+ ret += msg_table("Tmsg", "send", f"struct _{idprefix}send_tentry", (0, 0x100, 2))
+ ret += "\n"
+ ret += msg_table("Rmsg", "send", f"struct _{idprefix}send_tentry", (1, 0x100, 2))
ret += f"""
LM_FLATTEN bool _{idprefix}stat_validate(struct _validate_ctx *ctx) {{