summaryrefslogtreecommitdiff
path: root/lib9p/core_gen
diff options
context:
space:
mode:
Diffstat (limited to 'lib9p/core_gen')
-rw-r--r--lib9p/core_gen/c.py44
-rw-r--r--lib9p/core_gen/c_format.py2
-rw-r--r--lib9p/core_gen/c_marshal.py16
-rw-r--r--lib9p/core_gen/h.py13
4 files changed, 37 insertions, 38 deletions
diff --git a/lib9p/core_gen/c.py b/lib9p/core_gen/c.py
index b2e856d..b0ff871 100644
--- a/lib9p/core_gen/c.py
+++ b/lib9p/core_gen/c.py
@@ -79,7 +79,9 @@ def gen_c(versions: set[str], typs: list[idl.UserType]) -> str:
if not isinstance(typ, idl.Bitfield):
continue
ret += "\n"
- ret += cutil.ifdef_push(1, c9util.ver_ifdef(typ.in_versions))
+ ret += cutil.ifdef_push( # SPECIAL (initialization)
+ 1, c9util.ver_ifdef(typ.in_versions - {"uninitialized"})
+ )
ret += f"static const {c9util.typename(typ)} {typ.typname}_masks[{c9util.ver_enum('NUM')}] = {{\n"
verwidth = max(len(ver) for ver in versions)
for ver in sorted(versions):
@@ -121,21 +123,15 @@ def gen_c(versions: set[str], typs: list[idl.UserType]) -> str:
ret += "\n"
ret += f"const struct {c9util.ident('_ver_tentry')} {c9util.ident('_table_ver')}[{c9util.ver_enum('NUM')}] = {{\n"
rerror = next(typ for typ in typs if typ.typname == "Rerror")
- for ver in ["unknown", *sorted(versions)]:
- # XXX: There are good arguments that min_msg_size should be
- # something larger than rerror.min_size().
- # srv.c:respond_error() assumes that min_msg_size is
- # rerror.min_size(); if you do change min_msg_size to
- # something larger, then be sure to update respond_error().
- if ver == "unknown":
- min_msg_size = rerror.min_size("9P2000") # SPECIAL (initialization)
- else:
- ret += cutil.ifdef_push(1, c9util.ver_ifdef({ver}))
- min_msg_size = rerror.min_size(ver)
- if ver == "9P2000.L": # SPECIAL (9P2000.L)
- rlerror = next(typ for typ in typs if typ.typname == "Rlerror")
- min_msg_size = rlerror.min_size(ver)
- ret += f'\t[{c9util.ver_enum(ver)}] = {{.name="{ver}", .min_msg_size={min_msg_size}}},\n'
+ rlerror = next(typ for typ in typs if typ.typname == "Rlerror")
+ rread = next(typ for typ in typs if typ.typname == "Rread")
+ for ver in sorted(versions):
+ ret += cutil.ifdef_push(1, c9util.ver_ifdef({ver}))
+ min_rerror_size = rerror.min_size(ver)
+ if ver == "9P2000.L": # SPECIAL (9P2000.L)
+ min_rerror_size = rlerror.min_size(ver)
+ min_rread_size = rread.min_size(ver)
+ ret += f'\t[{c9util.ver_enum(ver)}] = {{.name="{ver}", .min_Rerror_size={min_rerror_size}, .min_Rread_size={min_rread_size}}},\n'
ret += cutil.ifdef_pop(0)
ret += "};\n"
@@ -143,19 +139,14 @@ def gen_c(versions: set[str], typs: list[idl.UserType]) -> str:
cstruct: str, cname: str, each: str, _range: tuple[int, int, int]
) -> str:
ret = f"const struct {c9util.ident(cstruct)} {c9util.ident(cname)}[{c9util.ver_enum('NUM')}][{hex(len(range(*_range)))}] = {{\n"
- for ver in ["unknown", *sorted(versions)]:
- if ver != "unknown":
- ret += cutil.ifdef_push(1, c9util.ver_ifdef({ver}))
+ for ver in sorted(versions):
+ ret += cutil.ifdef_push(1, c9util.ver_ifdef({ver}))
ret += f"\t[{c9util.ver_enum(ver)}] = {{\n"
for n in range(*_range):
xmsg: idl.Message | None = id2typ.get(n, None)
if xmsg:
- if ver == "unknown": # SPECIAL (initialization)
- if xmsg.typname not in ["Tversion", "Rversion", "Rerror"]:
- xmsg = None
- else:
- if ver not in xmsg.in_versions:
- xmsg = None
+ if ver not in xmsg.in_versions:
+ xmsg = None
if xmsg:
ret += f"\t\t{each}({xmsg.typname}),\n"
ret += "\t},\n"
@@ -194,6 +185,7 @@ def gen_c(versions: set[str], typs: list[idl.UserType]) -> str:
ret += msg_table("_send_tentry", "_table_Rmsg_send", "_MSG_SEND", (1, 0x100, 2))
ret += f"""
+{cutil.ifdef_push(1, c9util.ver_ifdef(next(typ for typ in typs if typ.typname == 'stat').in_versions)).rstrip()}
LM_FLATTEN ssize_t {c9util.ident('_stat_validate')}(struct lib9p_ctx *ctx, uint32_t net_size, uint8_t *net_bytes, uint32_t *ret_net_size) {{
\treturn validate_stat(ctx, net_size, net_bytes, ret_net_size);
}}
@@ -203,7 +195,7 @@ LM_FLATTEN void {c9util.ident('_stat_unmarshal')}(struct lib9p_ctx *ctx, uint8_t
LM_FLATTEN bool {c9util.ident('_stat_marshal')}(struct lib9p_ctx *ctx, struct {c9util.ident('stat')} *val, struct _marshal_ret *ret) {{
\treturn marshal_stat(ctx, val, ret);
}}
-"""
+{cutil.ifdef_pop(0)}"""
############################################################################
return ret
diff --git a/lib9p/core_gen/c_format.py b/lib9p/core_gen/c_format.py
index f9eee90..c633fbb 100644
--- a/lib9p/core_gen/c_format.py
+++ b/lib9p/core_gen/c_format.py
@@ -105,7 +105,7 @@ def gen_c_format(versions: set[str], typs: list[idl.UserType]) -> str:
ret += "\tif (empty)\n"
ret += "\t\tfmt_state_putchar(state, '0');\n"
ret += "\tfmt_state_putchar(state, ')');\n"
- case idl.Struct(typname="s"): # SPECIAL(string)
+ case idl.Struct(typname="s"): # SPECIAL (string)
ret += ext_printf(
'\tfmt_state_printf(state, "%.*q", self->len, self->utf8);\n'
)
diff --git a/lib9p/core_gen/c_marshal.py b/lib9p/core_gen/c_marshal.py
index 620bdea..322e1ef 100644
--- a/lib9p/core_gen/c_marshal.py
+++ b/lib9p/core_gen/c_marshal.py
@@ -370,21 +370,21 @@ def gen_c_marshal(versions: set[str], typs: list[idl.UserType]) -> str:
# Pass 1 - check size
max_size = max(typ.max_size(v) for v in typ.in_versions)
+ szbits = 32
if max_size > cutil.UINT32_MAX: # SPECIAL (9P2000.e)
- ret += get_offset_expr(typ, go_to_end).gen_c(
- "uint64_t", "needed_size", "val->", 1, 0
- )
+ szbits = 64
+ ret += get_offset_expr(typ, go_to_end).gen_c(
+ f"uint{szbits}_t", "needed_size", "val->", 1, 0
+ )
+ if szbits > 32: # SPECIAL (9P2000.e)
ret += "\tif (needed_size > (uint64_t)(ctx->max_msg_size)) {\n"
else:
- ret += get_offset_expr(typ, go_to_end).gen_c(
- "uint32_t", "needed_size", "val->", 1, 0
- )
ret += "\tif (needed_size > ctx->max_msg_size) {\n"
if isinstance(typ, idl.Message): # SPECIAL (disable for stat)
- ret += f'\t\tlib9p_errorf(ctx, {c9util.IDENT("ERRNO_L_ERANGE")}, "%s message too large to marshal into %s limit (limit=%"PRIu32")",\n'
+ ret += f'\t\tlib9p_errorf(ctx, {c9util.IDENT("ERRNO_L_ERANGE")}, "%s message too large to marshal into %s limit (%"PRIu{szbits}" > %"PRIu32")",\n'
ret += f'\t\t\t"{typ.typname}",\n'
ret += f'\t\t\tctx->version ? "negotiated" : "{'client' if typ.msgid % 2 == 0 else 'server'}",\n'
- ret += "\t\t\tctx->max_msg_size);\n"
+ ret += "\t\t\tneeded_size, ctx->max_msg_size);\n"
ret += "\t\treturn true;\n"
ret += "\t}\n"
diff --git a/lib9p/core_gen/h.py b/lib9p/core_gen/h.py
index 3defcb8..3c857c1 100644
--- a/lib9p/core_gen/h.py
+++ b/lib9p/core_gen/h.py
@@ -192,14 +192,21 @@ def gen_h(versions: set[str], typs: list[idl.UserType]) -> str:
ret += "\t#endif\n"
ret += "#endif\n"
+ # SPECIAL (convenience)
+ ret += "\n"
+ ret += f"#define _LIB9P_ENABLE_stat {c9util.ver_ifdef(next(typ for typ in typs if typ.typname == 'stat').in_versions)}\n"
+
ret += f"""
/* enum version ***************************************************************/
enum {c9util.ident('version')} {{
"""
- fullversions = ["unknown = 0", *sorted(versions)]
- verwidth = max(len(v) for v in fullversions)
- for ver in fullversions:
+ xversions = [ # SPECIAL (initialization)
+ "uninitialized = 0",
+ *sorted(v for v in versions if v != "uninitialized"),
+ ]
+ verwidth = max(len(v) for v in xversions)
+ for ver in xversions:
if ver in versions:
ret += cutil.ifdef_push(1, c9util.ver_ifdef({ver}))
ret += f"\t{c9util.ver_enum(ver)},"