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