diff options
-rwxr-xr-x | lib9p/idl.gen | 34 |
1 files changed, 26 insertions, 8 deletions
diff --git a/lib9p/idl.gen b/lib9p/idl.gen index 9f8f307..adb15ce 100755 --- a/lib9p/idl.gen +++ b/lib9p/idl.gen @@ -84,7 +84,7 @@ def c_typename(typ: idl.Type, parent: idl.StructMember | None = None) -> str: raise ValueError(f"not a type: {typ.__class__.__name__}") -def c_expr(expr: idl.Expr) -> str: +def c_expr(expr: idl.Expr, lookup_sym: typing.Callable[[str], str]) -> str: ret: list[str] = [] for tok in expr.tokens: match tok: @@ -92,14 +92,14 @@ def c_expr(expr: idl.Expr) -> str: ret.append(tok.op) case idl.ExprLit(): ret.append(str(tok.val)) - case idl.ExprSym(name="end"): - ret.append("ctx->net_offset") case idl.ExprSym(name="s32_max"): ret.append("INT32_MAX") case idl.ExprSym(name="s64_max"): ret.append("INT64_MAX") case idl.ExprSym(): - ret.append(f"_{tok.name[1:]}_offset") + ret.append(lookup_sym(tok.name)) + case _: + assert False return " ".join(ret) @@ -573,17 +573,26 @@ LM_ALWAYS_INLINE static bool validate_8(struct _validate_ctx *ctx) { return _val # Pass 4 - validate ,max= and ,val= constraints for member in typ.members: + + def lookup_sym(sym: str) -> str: + match sym: + case "end": + return "ctx->net_offset" + case _: + assert sym.startswith("&") + return f"_{sym[1:]}_offset" + if member.max: assert member.static_size nbits = member.static_size * 8 ret += ifdef_push(2, c_ver_ifdef(member.in_versions)) - ret += f"\t || ({{ uint{nbits}_t max = {c_expr(member.max)}; (((uint{nbits}_t){member.name}) > max) &&\n" + ret += f"\t || ({{ uint{nbits}_t max = {c_expr(member.max, lookup_sym)}; (((uint{nbits}_t){member.name}) > max) &&\n" ret += f'\t lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "{member.name} value is too large (%"PRIu{nbits}" > %"PRIu{nbits}")", {member.name}, max); }})\n' if member.val: assert member.static_size nbits = member.static_size * 8 ret += ifdef_push(2, c_ver_ifdef(member.in_versions)) - ret += f"\t || ({{ uint{nbits}_t exp = {c_expr(member.val)}; (((uint{nbits}_t){member.name}) != exp) &&\n" + ret += f"\t || ({{ uint{nbits}_t exp = {c_expr(member.val, lookup_sym)}; (((uint{nbits}_t){member.name}) != exp) &&\n" ret += f'\t lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "{member.name} value is wrong (actual:%"PRIu{nbits}" != correct:%"PRIu{nbits}")", (uint{nbits}_t){member.name}, exp); }})\n' ret += ifdef_pop(1) @@ -775,10 +784,19 @@ LM_ALWAYS_INLINE static bool marshal_8(struct _marshal_ctx *ctx, uint64_t *val) if member.val: assert member.static_size ret += ifdef_push(2, c_ver_ifdef(member.in_versions)) + + def lookup_sym(sym: str) -> str: + match sym: + case "end": + return "ctx->net_offset" + case _: + assert sym.startswith("&") + return f"_{sym[1:]}_offset" + if member.static_size == 1: - ret += f"\t || ({{ ctx->net_bytes[_{member.name}_offset] = {c_expr(member.val)}; false; }})\n" + ret += f"\t || ({{ ctx->net_bytes[_{member.name}_offset] = {c_expr(member.val, lookup_sym)}; false; }})\n" else: - ret += f"\t || ({{ uint{member.static_size*8}le_encode(&ctx->net_bytes[_{member.name}_offset], {c_expr(member.val)}); false; }})\n" + ret += f"\t || ({{ uint{member.static_size*8}le_encode(&ctx->net_bytes[_{member.name}_offset], {c_expr(member.val, lookup_sym)}); false; }})\n" ret += ifdef_pop(1) ret += "\t ;\n" |