summaryrefslogtreecommitdiff
path: root/lib9p/core_gen
diff options
context:
space:
mode:
Diffstat (limited to 'lib9p/core_gen')
-rw-r--r--lib9p/core_gen/c.py9
-rw-r--r--lib9p/core_gen/c9util.py4
-rw-r--r--lib9p/core_gen/c_fmt_print.py2
-rw-r--r--lib9p/core_gen/c_marshal.py39
-rw-r--r--lib9p/core_gen/c_validate.py28
-rw-r--r--lib9p/core_gen/h.py7
6 files changed, 47 insertions, 42 deletions
diff --git a/lib9p/core_gen/c.py b/lib9p/core_gen/c.py
index 60ceb70..ab34387 100644
--- a/lib9p/core_gen/c.py
+++ b/lib9p/core_gen/c.py
@@ -23,17 +23,16 @@ def gen_c(versions: set[str], typs: list[idl.UserType]) -> str:
ret = f"""/* Generated by `{' '.join(sys.argv)}`. DO NOT EDIT! */
-#include <stddef.h> /* for size_t */
-#include <inttypes.h> /* for PRI* macros */
-#include <string.h> /* for memset() */
+#include <stddef.h> /* for size_t */
+#include <string.h> /* for memset() */
#include <libmisc/assert.h>
#include <libmisc/endian.h>
+#include <libmisc/utf8.h>
#include <lib9p/core.h>
#include "core_tables.h"
-#include "core_utf8.h"
"""
# utilities ################################################################
ret += """
@@ -176,7 +175,7 @@ def gen_c(versions: set[str], typs: list[idl.UserType]) -> str:
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) {{
+LM_FLATTEN size_t_or_error {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);
}}
LM_FLATTEN void {c9util.ident('_stat_unmarshal')}(struct lib9p_ctx *ctx, uint8_t *net_bytes, void *out) {{
diff --git a/lib9p/core_gen/c9util.py b/lib9p/core_gen/c9util.py
index 84fdee4..7e1e41d 100644
--- a/lib9p/core_gen/c9util.py
+++ b/lib9p/core_gen/c9util.py
@@ -91,7 +91,9 @@ def typename(typ: idl.Type, parent: idl.StructMember | None = None) -> str:
match typ:
case idl.Primitive():
if typ.value == 1 and parent and parent.cnt: # SPECIAL (string)
- return "[[gnu::nonstring]] char"
+ if parent.membname == "utf8":
+ return "[[gnu::nonstring]] const char"
+ return "const void"
return f"uint{typ.value*8}_t"
case idl.Number():
return f"{basename(typ)}_t"
diff --git a/lib9p/core_gen/c_fmt_print.py b/lib9p/core_gen/c_fmt_print.py
index eaacddb..7a0a9d3 100644
--- a/lib9p/core_gen/c_fmt_print.py
+++ b/lib9p/core_gen/c_fmt_print.py
@@ -112,7 +112,7 @@ def gen_c_fmt_print(versions: set[str], typs: list[idl.UserType]) -> str:
cnt_str = f"self->{member.cnt.membname}"
cnt_typ = c9util.typename(member.cnt.typ)
if member.typ.static_size == 1: # SPECIAL (data)
- ret += f"\tif (is_valid_utf8_without_nul((uint8_t *)self->{member.membname}, (size_t){cnt_str})) {{\n"
+ ret += f"\tif (utf8_is_valid_without_nul((uint8_t *)self->{member.membname}, (size_t){cnt_str})) {{\n"
ret += f'\t\tfmt_print_str(w, " {member.membname}=");\n'
ret += f"\t\tfmt_print_qmem(w, self->{member.membname}, {cnt_str} < 50 ? {cnt_str} : 50);\n"
ret += f"\t\tif ({cnt_str} > 50)\n"
diff --git a/lib9p/core_gen/c_marshal.py b/lib9p/core_gen/c_marshal.py
index bddf55f..2747ce8 100644
--- a/lib9p/core_gen/c_marshal.py
+++ b/lib9p/core_gen/c_marshal.py
@@ -193,46 +193,46 @@ def gen_c_marshal(versions: set[str], typs: list[idl.UserType]) -> str:
"#define MARSHAL_BYTES_ZEROCOPY(ctx, data, len)\n"
"\tif (ret->net_iov[ret->net_iov_cnt-1].iov_len)\n"
"\t\tret->net_iov_cnt++;\n"
- "\tret->net_iov[ret->net_iov_cnt-1].iov_base = data;\n"
+ "\tret->net_iov[ret->net_iov_cnt-1].iov_write_from = data;\n"
"\tret->net_iov[ret->net_iov_cnt-1].iov_len = len;\n"
"\tret->net_iov_cnt++;\n"
)
ret += cutil.macro(
"#define MARSHAL_BYTES(ctx, data, len)\n"
- "\tif (!ret->net_iov[ret->net_iov_cnt-1].iov_base)\n"
- "\t\tret->net_iov[ret->net_iov_cnt-1].iov_base = &ret->net_copied[ret->net_copied_size];\n"
+ "\tif (!ret->net_iov[ret->net_iov_cnt-1].iov_write_from)\n"
+ "\t\tret->net_iov[ret->net_iov_cnt-1].iov_write_from = &ret->net_copied[ret->net_copied_size];\n"
"\tmemcpy(&ret->net_copied[ret->net_copied_size], data, len);\n"
"\tret->net_copied_size += len;\n"
"\tret->net_iov[ret->net_iov_cnt-1].iov_len += len;\n"
)
ret += cutil.macro(
"#define MARSHAL_U8LE(ctx, val)\n"
- "\tif (!ret->net_iov[ret->net_iov_cnt-1].iov_base)\n"
- "\t\tret->net_iov[ret->net_iov_cnt-1].iov_base = &ret->net_copied[ret->net_copied_size];\n"
+ "\tif (!ret->net_iov[ret->net_iov_cnt-1].iov_write_from)\n"
+ "\t\tret->net_iov[ret->net_iov_cnt-1].iov_write_from = &ret->net_copied[ret->net_copied_size];\n"
"\tret->net_copied[ret->net_copied_size] = val;\n"
"\tret->net_copied_size += 1;\n"
"\tret->net_iov[ret->net_iov_cnt-1].iov_len += 1;\n"
)
ret += cutil.macro(
"#define MARSHAL_U16LE(ctx, val)\n"
- "\tif (!ret->net_iov[ret->net_iov_cnt-1].iov_base)\n"
- "\t\tret->net_iov[ret->net_iov_cnt-1].iov_base = &ret->net_copied[ret->net_copied_size];\n"
+ "\tif (!ret->net_iov[ret->net_iov_cnt-1].iov_write_from)\n"
+ "\t\tret->net_iov[ret->net_iov_cnt-1].iov_write_from = &ret->net_copied[ret->net_copied_size];\n"
"\tuint16le_encode(&ret->net_copied[ret->net_copied_size], val);\n"
"\tret->net_copied_size += 2;\n"
"\tret->net_iov[ret->net_iov_cnt-1].iov_len += 2;\n"
)
ret += cutil.macro(
"#define MARSHAL_U32LE(ctx, val)\n"
- "\tif (!ret->net_iov[ret->net_iov_cnt-1].iov_base)\n"
- "\t\tret->net_iov[ret->net_iov_cnt-1].iov_base = &ret->net_copied[ret->net_copied_size];\n"
+ "\tif (!ret->net_iov[ret->net_iov_cnt-1].iov_write_from)\n"
+ "\t\tret->net_iov[ret->net_iov_cnt-1].iov_write_from = &ret->net_copied[ret->net_copied_size];\n"
"\tuint32le_encode(&ret->net_copied[ret->net_copied_size], val);\n"
"\tret->net_copied_size += 4;\n"
"\tret->net_iov[ret->net_iov_cnt-1].iov_len += 4;\n"
)
ret += cutil.macro(
"#define MARSHAL_U64LE(ctx, val)\n"
- "\tif (!ret->net_iov[ret->net_iov_cnt-1].iov_base)\n"
- "\t\tret->net_iov[ret->net_iov_cnt-1].iov_base = &ret->net_copied[ret->net_copied_size];\n"
+ "\tif (!ret->net_iov[ret->net_iov_cnt-1].iov_write_from)\n"
+ "\t\tret->net_iov[ret->net_iov_cnt-1].iov_write_from = &ret->net_copied[ret->net_copied_size];\n"
"\tuint64le_encode(&ret->net_copied[ret->net_copied_size], val);\n"
"\tret->net_copied_size += 8;\n"
"\tret->net_iov[ret->net_iov_cnt-1].iov_len += 8;\n"
@@ -365,7 +365,10 @@ def gen_c_marshal(versions: set[str], typs: list[idl.UserType]) -> str:
assert isinstance(typ, idl.Struct)
ret += "\n"
ret += cutil.ifdef_push(1, c9util.ver_ifdef(typ.in_versions))
- ret += f"static bool marshal_{typ.typname}(struct lib9p_ctx *ctx, {c9util.typename(typ)} *val, struct _marshal_ret *ret) {{\n"
+ if not isinstance(typ, idl.Message): # SPECIAL (bool for stat)
+ ret += f"static bool marshal_{typ.typname}(struct lib9p_ctx *ctx, {c9util.typename(typ)} *val, struct _marshal_ret *ret) {{\n"
+ else:
+ ret += f"static error marshal_{typ.typname}(struct lib9p_ctx *ctx, {c9util.typename(typ)} *val, struct _marshal_ret *ret) {{\n"
# Pass 1 - check size
max_size = max(typ.max_size(v) for v in typ.in_versions)
@@ -380,11 +383,12 @@ def gen_c_marshal(versions: set[str], typs: list[idl.UserType]) -> str:
ret += "\tif (needed_size > (uint64_t)(ctx->max_msg_size)) {\n"
else:
ret += "\tif (needed_size > ctx->max_msg_size) {\n"
- if isinstance(typ, idl.Message): # SPECIAL (disable for stat)
- ret += f'\t\tlib9p_error(ctx, {c9util.IDENT("ERRNO_L_ERANGE")}, "{typ.typname} message too large to marshal into ",\n'
+ if not isinstance(typ, idl.Message): # SPECIAL (bool for stat)
+ ret += "\t\treturn true;\n"
+ else:
+ ret += f'\t\treturn error_new(E_POSIX_ERANGE, "{typ.typname} message too large to marshal into ",\n'
ret += f'\t\t\tctx->version ? "negotiated" : "{'client' if typ.msgid % 2 == 0 else 'server'}", " limit",\n'
ret += '\t\t\t" (", needed_size, " > ", ctx->max_msg_size, ")");\n'
- ret += "\t\treturn true;\n"
ret += "\t}\n"
# Pass 2 - write data
@@ -396,7 +400,10 @@ def gen_c_marshal(versions: set[str], typs: list[idl.UserType]) -> str:
ret += cutil.ifdef_pop(ifdef_lvl())
# Return
- ret += "\treturn false;\n"
+ if not isinstance(typ, idl.Message): # SPECIAL (bool for stat)
+ ret += "\treturn false;\n"
+ else:
+ ret += "\treturn ERROR_NULL;\n"
ret += "}\n"
ret += cutil.ifdef_pop(0)
return ret
diff --git a/lib9p/core_gen/c_validate.py b/lib9p/core_gen/c_validate.py
index 9c55d8d..1bfe329 100644
--- a/lib9p/core_gen/c_validate.py
+++ b/lib9p/core_gen/c_validate.py
@@ -57,26 +57,26 @@ def gen_c_validate(versions: set[str], typs: list[idl.UserType]) -> str:
"\t\t/* If needed-net-size overflowed uint32_t, then\n"
"\t\t * there's no way that actual-net-size will live up to\n"
"\t\t * that. */\n"
- f'\t\treturn lib9p_error(ctx, {c9util.IDENT("ERRNO_L_EBADMSG")}, "message is too short for content");\n'
+ '\t\treturn ERROR_NEW_ERR(size_t, error_new(E_POSIX_EBADMSG, "message is too short for content"));\n'
"\tif (net_offset > net_size)\n"
- f'\t\treturn lib9p_error(ctx, {c9util.IDENT("ERRNO_L_EBADMSG")}, "message is too short for content (", net_offset, " > ", net_size, ")");\n'
+ '\t\treturn ERROR_NEW_ERR(size_t, error_new(E_POSIX_EBADMSG, "message is too short for content (", net_offset, " > ", net_size, ")"));\n'
)
ret += cutil.macro(
"#define VALIDATE_NET_UTF8(n)\n"
"\t{\n"
"\t\tsize_t len = n;\n"
"\t\tVALIDATE_NET_BYTES(len);\n"
- "\t\tif (!is_valid_utf8_without_nul(&net_bytes[net_offset-len], len))\n"
- f'\t\t\treturn lib9p_error(ctx, {c9util.IDENT("ERRNO_L_EBADMSG")}, "message contains invalid UTF-8");\n'
+ "\t\tif (!utf8_is_valid_without_nul(&net_bytes[net_offset-len], len))\n"
+ '\t\t\treturn ERROR_NEW_ERR(size_t, error_new(E_POSIX_EILSEQ, "message contains invalid UTF-8"));\n'
"\t}\n"
)
ret += cutil.macro(
"#define RESERVE_HOST_BYTES(n)\n"
"\tif (__builtin_add_overflow(host_size, n, &host_size))\n"
- "\t\t/* If needed-host-size overflowed ssize_t, then there's\n"
+ "\t\t/* If needed-host-size overflowed size_t, then there's\n"
"\t\t * no way that actual-net-size will live up to\n"
"\t\t * that. */\n"
- f'\t\treturn lib9p_error(ctx, {c9util.IDENT("ERRNO_L_EBADMSG")}, "message is too short for content");\n'
+ '\t\treturn ERROR_NEW_ERR(size_t, error_new(E_POSIX_EBADMSG, "message is too short for content"));\n'
)
ret += "#define GET_U8LE(off) (net_bytes[off])\n"
@@ -193,7 +193,7 @@ def gen_c_validate(versions: set[str], typs: list[idl.UserType]) -> str:
act = f"GET_U{nbits}LE({lookup_sym(f'&{child.membname}')})"
exp = f"{c9util.idl_expr(child.val, lookup_sym)}"
ret += f"{'\t'*indent_lvl()}if ({act} != {exp})\n"
- ret += f'{"\t"*(indent_lvl()+1)}return lib9p_error(ctx, {c9util.IDENT("ERRNO_L_EBADMSG")}, "{path} value is wrong: actual:", (base10, {act}), " != correct:", (base10, {exp}));\n'
+ ret += f'{"\t"*(indent_lvl()+1)}return ERROR_NEW_ERR(size_t, error_new(E_POSIX_EBADMSG, "{path} value is wrong: actual:", (base10, {act}), " != correct:", (base10, {exp})));\n'
if child.max:
incr_flush()
assert child.typ.static_size
@@ -207,15 +207,15 @@ def gen_c_validate(versions: set[str], typs: list[idl.UserType]) -> str:
act = f"GET_U{nbits}LE({lookup_sym(f'&{child.membname}')})"
exp = f"{c9util.idl_expr(child.max, lookup_sym)}"
ret += f"{'\t'*indent_lvl()}if ({act} > {exp})\n"
- ret += f'{"\t"*(indent_lvl()+1)}return lib9p_error(ctx, {c9util.IDENT("ERRNO_L_EBADMSG")}, "{path} value is too large: ", (base10, {act}), " > ", (base10, {exp}));\n'
+ ret += f'{"\t"*(indent_lvl()+1)}return ERROR_NEW_ERR(size_t, error_new(E_POSIX_EBADMSG, "{path} value is too large: ", (base10, {act}), " > ", (base10, {exp})));\n'
if isinstance(child.typ, idl.Bitfield):
incr_flush()
nbytes = child.typ.static_size
nbits = nbytes * 8
act = f"GET_U{nbits}LE({lookup_sym(f'&{child.membname}')})"
ret += f"{'\t'*indent_lvl()}if ({act} & ~{child.typ.typname}_masks[ctx->version])\n"
- ret += f'{"\t"*(indent_lvl()+1)}return lib9p_error(ctx, {c9util.IDENT("ERRNO_L_EBADMSG")}, "unknown bits in {child.typ.typname} bitfield: ",\n'
- ret += f"{'\t'*(indent_lvl()+2)}(base16_u{nbits}_, {act} & ~{child.typ.typname}_masks[ctx->version]));\n"
+ ret += f'{"\t"*(indent_lvl()+1)}return ERROR_NEW_ERR(size_t, error_new(E_POSIX_EBADMSG, "unknown bits in {child.typ.typname} bitfield: ",\n'
+ ret += f"{'\t'*(indent_lvl()+2)}(base16_u{nbits}_, {act} & ~{child.typ.typname}_masks[ctx->version])));\n"
def handle(
path: idlutil.Path,
@@ -271,12 +271,12 @@ def gen_c_validate(versions: set[str], typs: list[idl.UserType]) -> str:
ret += "\n"
ret += cutil.ifdef_push(1, c9util.ver_ifdef(typ.in_versions))
if typ.typname == "stat": # SPECIAL (stat)
- ret += f"static ssize_t validate_{typ.typname}(struct lib9p_ctx *ctx, uint32_t net_size, uint8_t *net_bytes, uint32_t *ret_net_size) {{\n"
+ ret += f"static size_t_or_error validate_{typ.typname}(struct lib9p_ctx *ctx, uint32_t net_size, uint8_t *net_bytes, uint32_t *ret_net_size) {{\n"
else:
- ret += f"static ssize_t validate_{typ.typname}(struct lib9p_ctx *ctx, uint32_t net_size, uint8_t *net_bytes) {{\n"
+ ret += f"static size_t_or_error validate_{typ.typname}([[maybe_unused]] struct lib9p_ctx *ctx, uint32_t net_size, uint8_t *net_bytes) {{\n"
ret += "\tuint32_t net_offset = 0;\n"
- ret += f"\tssize_t host_size = sizeof({c9util.typename(typ)});\n"
+ ret += f"\tsize_t host_size = sizeof({c9util.typename(typ)});\n"
incr_buf = 0
indent_stack = [IndentLevel(ifdef=True)]
@@ -291,7 +291,7 @@ def gen_c_validate(versions: set[str], typs: list[idl.UserType]) -> str:
if typ.typname == "stat": # SPECIAL (stat)
ret += "\tif (ret_net_size)\n"
ret += "\t\t*ret_net_size = net_offset;\n"
- ret += "\treturn (ssize_t)host_size;\n"
+ ret += "\treturn ERROR_NEW_VAL(size_t, host_size);\n"
ret += "}\n"
ret += cutil.ifdef_pop(0)
return ret
diff --git a/lib9p/core_gen/h.py b/lib9p/core_gen/h.py
index acf8415..eba1492 100644
--- a/lib9p/core_gen/h.py
+++ b/lib9p/core_gen/h.py
@@ -162,7 +162,6 @@ def gen_h(versions: set[str], typs: list[idl.UserType]) -> str:
#ifndef _LIB9P_CORE_H_
\t#error Do not include <lib9p/_core_generated.h> directly; include <lib9p/core.h> instead
#endif
-
"""
id2typ: dict[int, idl.Message] = {}
for msg in [msg for msg in typs if isinstance(msg, idl.Message)]:
@@ -170,8 +169,6 @@ def gen_h(versions: set[str], typs: list[idl.UserType]) -> str:
ret += """
/* config *********************************************************************/
-
-#include "config.h"
"""
for ver in sorted(versions):
ret += "\n"
@@ -348,14 +345,14 @@ enum {c9util.ident('version')} {{
ret += "\n"
ret += f"struct {c9util.ident('Tmsg_send_buf')} {{\n"
ret += "\tsize_t iov_cnt;\n"
- ret += f"\tstruct iovec iov[{c9util.IDENT('TMSG_MAX_IOV')}];\n"
+ ret += f"\tstruct wr_iovec iov[{c9util.IDENT('TMSG_MAX_IOV')}];\n"
ret += f"\tuint8_t copied[{c9util.IDENT('TMSG_MAX_COPY')}];\n"
ret += "};\n"
ret += "\n"
ret += f"struct {c9util.ident('Rmsg_send_buf')} {{\n"
ret += "\tsize_t iov_cnt;\n"
- ret += f"\tstruct iovec iov[{c9util.IDENT('RMSG_MAX_IOV')}];\n"
+ ret += f"\tstruct wr_iovec iov[{c9util.IDENT('RMSG_MAX_IOV')}];\n"
ret += f"\tuint8_t copied[{c9util.IDENT('RMSG_MAX_COPY')}];\n"
ret += "};\n"