diff options
Diffstat (limited to 'lib9p/idl.gen')
-rwxr-xr-x | lib9p/idl.gen | 102 |
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) {{ |