summaryrefslogtreecommitdiff
path: root/lib9p/idl.gen
diff options
context:
space:
mode:
Diffstat (limited to 'lib9p/idl.gen')
-rwxr-xr-xlib9p/idl.gen17
1 files changed, 7 insertions, 10 deletions
diff --git a/lib9p/idl.gen b/lib9p/idl.gen
index 4c3103c..b33ea5f 100755
--- a/lib9p/idl.gen
+++ b/lib9p/idl.gen
@@ -67,9 +67,11 @@ def c_ver_cond(versions: set[str]) -> str:
return "( " + (" || ".join(c_ver_cond({v}) for v in sorted(versions))) + " )"
-def c_typename(typ: idl.Type) -> str:
+def c_typename(typ: idl.Type, parent: idl.Type | None = None) -> str:
match typ:
case idl.Primitive():
+ if typ.value == 1 and parent and parent.name in ["d", "s"]: # SPECIAL
+ return "[[gnu::nonstring]] char"
return f"uint{typ.value*8}_t"
case idl.Number():
return f"{idprefix}{typ.name}_t"
@@ -279,16 +281,13 @@ enum {idprefix}version {{
continue
ret += "\n"
- typewidth = max(len(c_typename(m.typ)) for m in typ.members)
+ typewidth = max(len(c_typename(m.typ, typ)) for m in typ.members)
for member in typ.members:
if member.val:
continue
ret += ifdef_push(2, c_ver_ifdef(member.in_versions))
- c_type = c_typename(member.typ)
- if (typ.name in ["d", "s"]) and member.cnt: # SPECIAL
- c_type = "char"
- ret += f"\t{c_type.ljust(typewidth)} {'*' if member.cnt else ' '}{member.name};\n"
+ ret += f"\t{c_typename(member.typ, typ).ljust(typewidth)} {'*' if member.cnt else ' '}{member.name};\n"
ret += ifdef_pop(1)
ret += "};\n"
ret += ifdef_pop(0)
@@ -473,7 +472,7 @@ LM_ALWAYS_INLINE static bool _validate_list(struct _validate_ctx *ctx,
ret += "\tif (validate_2(ctx))\n"
ret += "\t\treturn true;\n"
ret += "\tuint16_t len = decode_u16le(&ctx->net_bytes[base_offset]);\n"
- ret += "\tif (_validate_size_net(ctx, len) || _validate_size_host(ctx, ((size_t)len)+1))\n"
+ ret += "\tif (_validate_size_net(ctx, len) || _validate_size_host(ctx, ((size_t)len)))\n"
ret += "\t\treturn true;\n"
ret += "\tif (!is_valid_utf8_without_nul(&ctx->net_bytes[base_offset+2], len))\n"
ret += '\t\treturn lib9p_error(ctx->ctx, LINUX_EBADMSG, "message contains invalid UTF-8");\n'
@@ -622,6 +621,7 @@ LM_ALWAYS_INLINE static void unmarshal_8(struct _unmarshal_ctx *ctx, uint64_t *o
ret += f"{prefix}ctx->extra += sizeof(out->{member.name}[0]) * out->{member.cnt};\n"
ret += f"{prefix}for (typeof(out->{member.cnt}) i = 0; i < out->{member.cnt}; i++)\n"
if typ.name in ["d", "s"]: # SPECIAL
+ # Special-case is that we cast from `char` to `uint8_t`.
ret += f"{prefix}\tunmarshal_{member.typ.name}(ctx, (uint8_t *)&out->{member.name}[i]);\n"
else:
ret += f"{prefix}\tunmarshal_{member.typ.name}(ctx, &out->{member.name}[i]);\n"
@@ -631,9 +631,6 @@ LM_ALWAYS_INLINE static void unmarshal_8(struct _unmarshal_ctx *ctx, uint64_t *o
ret += (
f"unmarshal_{member.typ.name}(ctx, &out->{member.name});\n"
)
- if typ.name == "s": # SPECIAL
- ret += "\tctx->extra++;\n"
- ret += "\tout->utf8[out->len] = '\\0';\n"
ret += ifdef_pop(1)
ret += "}\n"
ret += ifdef_pop(0)