summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xnet9p_defs.gen239
1 files changed, 184 insertions, 55 deletions
diff --git a/net9p_defs.gen b/net9p_defs.gen
index dcfb33b..53235df 100755
--- a/net9p_defs.gen
+++ b/net9p_defs.gen
@@ -175,21 +175,25 @@ def gen_h(structs: list[Struct], msgs: list[Message]) -> str:
ret += "#ifndef _NET9P_DEFS_H_\n"
ret += "#define _NET9P_DEFS_H_\n"
ret += "\n"
+ ret += "#define V9FS_EWRONGSIZE 7\n"
+ ret += "#define V9FS_EBADTYPE 4\n"
+ ret += "\n"
for struct in structs:
ret += c_typename(struct) + " {\n"
typewidth = max(len(c_typename(member.typ)) for member in struct.members)
for member in struct.members:
ret += f"\t{c_typename(member.typ).ljust(typewidth)} {member.name};\n"
ret += "};\n"
- ret += "\n"
+ ret += "\n"
ret += "enum v9fs_msg_type {\n"
namewidth = max(len(msg.name) for msg in msgs)
for msg in msgs:
ret += f"\tV9FS_TYP_{msg.name.ljust(namewidth)} = {msg.id},\n"
ret += "};\n"
+ ret += "\n"
for msg in msgs:
if not msg.members:
ret += c_typename(msg) + " {};\n"
@@ -199,8 +203,34 @@ def gen_h(structs: list[Struct], msgs: list[Message]) -> str:
for member in msg.members:
ret += f"\t{c_typename(member.typ).ljust(typewidth)} {member.name};\n"
ret += "};\n"
- ret += "\n"
+ ret += """
+/**
+ * @param net_bytes : the complete request, starting with the "size[4]"
+ * @param out_tag : the message-ID tag
+ * @param out_body : a pointer that get set to the parsed body, whose
+ * type is known by the return value, will need to
+ * be free()d
+ * @return -V9FS_E{error} on errors, V9FS_TYP_{type} on success
+ */
+int v9fs_unmarshal_msg(uint8_t *net_bytes, uint16_t *out_tag, void **out_body);
+"""
+
+ ret += """
+/**
+ * @param uint16_t in_msgid : the message-ID tag
+ * @param struct v9fs_msg_{type} in_msg : the message to encode
+ * @param uint8_t *out_buf : the buffer to encode to
+ * @return uint32_t : the encoded length
+ */
+#define v9fs_marshal_msg(in_msgid, in_msg, out_buf) _Generic((in_msg)"""
+ for msg in msgs:
+ ret += f", \\\n\t\t{c_typename(msg)}: _v9fs_marshal_{shortname(msg)}(in_msgid, in_msg, out_buf)"
+ ret += "\\\n\t)(in_msg)\n"
+ for msg in msgs:
+ ret += f"uint32_t _v9fs_marshal_{shortname(msg)}(uint16_t in_msgid, {c_typename(msg)} in_msg, uint8_t *out_buf);\n"
+
+ ret += "\n"
ret += "#endif /* _NET9P_DEFS_H_ */\n"
return ret
@@ -209,7 +239,8 @@ def gen_c(structs: list[Struct], msgs: list[Message]) -> str:
ret = """
/* Generated by ./net9p_defs.gen. DO NOT EDIT! */
-#include <stdint.h> /* for size_t, uint{n}_t */
+#include <stdbool.h>
+#include <stdint.h>
#include <stdlib.h> /* for malloc() */
#include "net9p_defs.h"
@@ -221,58 +252,64 @@ def gen_c(structs: list[Struct], msgs: list[Message]) -> str:
#define UNUSED __attribute__ ((unused))
-static inline uint16_t decode_u16le(uint8_t *bytes) {
- return (((uint16_t)(bytes[0])) << 0)
- | (((uint16_t)(bytes[1])) << 8)
- ;
+static inline uint8_t decode_u8le(uint8_t *in) {
+ return in[0];
+}
+static inline uint16_t decode_u16le(uint8_t *in) {
+ return (((uint16_t)(in[0])) << 0)
+ | (((uint16_t)(in[1])) << 8)
+ ;
}
-static inline uint32_t decode_u32le(uint8_t *bytes) {
- return (((uint16_t)(bytes[0])) << 0)
- | (((uint16_t)(bytes[1])) << 8)
- | (((uint16_t)(bytes[2])) << 16)
- | (((uint16_t)(bytes[3])) << 24)
- ;
+static inline uint32_t decode_u32le(uint8_t *in) {
+ return (((uint32_t)(in[0])) << 0)
+ | (((uint32_t)(in[1])) << 8)
+ | (((uint32_t)(in[2])) << 16)
+ | (((uint32_t)(in[3])) << 24)
+ ;
}
-static inline uint64_t decode_u64le(uint8_t *bytes) {
- return (((uint16_t)(bytes[0])) << 0)
- | (((uint16_t)(bytes[1])) << 8)
- | (((uint16_t)(bytes[2])) << 16)
- | (((uint16_t)(bytes[3])) << 24)
- | (((uint16_t)(bytes[4])) << 32)
- | (((uint16_t)(bytes[5])) << 40)
- | (((uint16_t)(bytes[6])) << 48)
- | (((uint16_t)(bytes[7])) << 56)
- ;
+static inline uint64_t decode_u64le(uint8_t *in) {
+ return (((uint64_t)(in[0])) << 0)
+ | (((uint64_t)(in[1])) << 8)
+ | (((uint64_t)(in[2])) << 16)
+ | (((uint64_t)(in[3])) << 24)
+ | (((uint64_t)(in[4])) << 32)
+ | (((uint64_t)(in[5])) << 40)
+ | (((uint64_t)(in[6])) << 48)
+ | (((uint64_t)(in[7])) << 56)
+ ;
}
-static inline void decode_u16le(val uint16_t, uint8_t *bytes) {
- bytes[0] = (uint8_t)((val >> 0) & 0xFF);
- bytes[1] = (uint8_t)((val >> 8) & 0xFF);
+static inline void encode_u8le(uint8_t in, uint8_t *out) {
+ out[0] = in;
}
-static inline void decode_u32le(val uint32_t, uint8_t *bytes) {
- bytes[0] = (uint8_t)((val >> 0) & 0xFF);
- bytes[1] = (uint8_t)((val >> 8) & 0xFF);
- bytes[2] = (uint8_t)((val >> 16) & 0xFF);
- bytes[3] = (uint8_t)((val >> 24) & 0xFF);
+static inline void encode_u16le(uint16_t in, uint8_t *out) {
+ out[0] = (uint8_t)((in >> 0) & 0xFF);
+ out[1] = (uint8_t)((in >> 8) & 0xFF);
}
-static inline void decode_u64le(val uint64_t, uint8_t *bytes) {
- bytes[0] = (uint8_t)((val >> 0) & 0xFF);
- bytes[1] = (uint8_t)((val >> 8) & 0xFF);
- bytes[2] = (uint8_t)((val >> 16) & 0xFF);
- bytes[3] = (uint8_t)((val >> 24) & 0xFF);
- bytes[4] = (uint8_t)((val >> 32) & 0xFF);
- bytes[5] = (uint8_t)((val >> 40) & 0xFF);
- bytes[6] = (uint8_t)((val >> 48) & 0xFF);
- bytes[7] = (uint8_t)((val >> 56) & 0xFF);
+static inline void encode_u32le(uint32_t in, uint8_t *out) {
+ out[0] = (uint8_t)((in >> 0) & 0xFF);
+ out[1] = (uint8_t)((in >> 8) & 0xFF);
+ out[2] = (uint8_t)((in >> 16) & 0xFF);
+ out[3] = (uint8_t)((in >> 24) & 0xFF);
+}
+static inline void encode_u64le(uint64_t in, uint8_t *out) {
+ out[0] = (uint8_t)((in >> 0) & 0xFF);
+ out[1] = (uint8_t)((in >> 8) & 0xFF);
+ out[2] = (uint8_t)((in >> 16) & 0xFF);
+ out[3] = (uint8_t)((in >> 24) & 0xFF);
+ out[4] = (uint8_t)((in >> 32) & 0xFF);
+ out[5] = (uint8_t)((in >> 40) & 0xFF);
+ out[6] = (uint8_t)((in >> 48) & 0xFF);
+ out[7] = (uint8_t)((in >> 56) & 0xFF);
}
"""
- # checksize ################################################################
+ # checksize_* ##############################################################
ret += """
-/* checksize ******************************************************************/
+/* checksize_* ****************************************************************/
typedef bool (*_checksize_fn_t)(uint32_t net_len, uint8_t *net_bytes, uint32_t *mut_net_offset, size_t *mut_host_extra);
-static inline bool _checksize_list(size_t cnt, checksize_fn_t fn, size_t host_size,
+static inline bool _checksize_list(size_t cnt, _checksize_fn_t fn, size_t host_size,
uint32_t net_len, uint8_t *net_bytes, uint32_t *mut_net_offset, size_t *mut_host_extra) {
for (size_t i = 0; i < cnt; i++)
if (__builtin_add_overflow(*mut_host_extra, host_size, mut_host_extra)
@@ -295,15 +332,16 @@ static inline bool checksize_8(uint32_t net_len, uint8_t *net_bytes UNUSED, uint
"""
for struct in structs + msgs:
argattr = ' UNUSED' if len(struct.members) == 0 else ''
- ret += f"static inline bool checksize_{shortname(struct)}(uint32_t net_len{argattr}, uint8_t *net_bytes{argattr}, uint32_t *mut_net_offset{argattr}, size_t mut_host_extra{argattr}) {{"
+ ret += f"static inline bool checksize_{shortname(struct)}(uint32_t net_len{argattr}, uint8_t *net_bytes{argattr}, uint32_t *mut_net_offset{argattr}, size_t *mut_host_extra{argattr}) {{\n"
if len(struct.members) == 0:
+ ret += "\treturn false;\n"
ret += "}\n"
continue
prefix0 = "\treturn "
prefix1 = "\t || "
prefix2 = "\t "
prefix = prefix0
- prev_size = 0
+ prev_size: int|None = None
for member in struct.members:
if isinstance(member.typ, List):
ret += f"\n{prefix }_checksize_list(decode_u{prev_size*8}le(&net_bytes[(*mut_net_offset)-{prev_size}]), checksize_{shortname(member.typ.typ)}, sizeof({c_typename(member.typ.typ)}),"
@@ -311,48 +349,139 @@ static inline bool checksize_8(uint32_t net_len, uint8_t *net_bytes UNUSED, uint
else:
ret += f"\n{prefix}checksize_{shortname(member.typ)}(net_len, net_bytes, mut_net_offset, mut_host_extra)"
prefix = prefix1
+ prev_size = static_size(member.typ)
if struct.name == 's':
ret += f"\n{prefix}__builtin_add_overflow(*mut_host_extra, 1, mut_host_extra)"
ret += ";\n}\n"
- # unmarshal ################################################################
+ # unmarshal_* ##############################################################
ret += """
-/* unmarshal ******************************************************************/
+/* unmarshal_* ****************************************************************/
/* checksize_XXX() should be called before unmarshal_XXX(). */
-static inline void unmarshal_1(uint32_t net_len, uint8_t *net_bytes UNUSED, uint32_t *mut_net_offset, void *mut_host_extra UNUSED, uint8_t *out) {
+static inline void unmarshal_1(uint8_t *net_bytes, uint32_t *mut_net_offset, void **mut_host_extra UNUSED, uint8_t *out) {
*out = decode_u8le(&net_bytes[*mut_net_offset]);
*mut_net_offset += 1;
}
-static inline void unmarshal_2(uint32_t net_len, uint8_t *net_bytes UNUSED, uint32_t *mut_net_offset, void *mut_host_extra UNUSED, uint16_t *out) {
+static inline void unmarshal_2(uint8_t *net_bytes, uint32_t *mut_net_offset, void **mut_host_extra UNUSED, uint16_t *out) {
*out = decode_u16le(&net_bytes[*mut_net_offset]);
*mut_net_offset += 2;
}
-static inline void unmarshal_4(uint32_t net_len, uint8_t *net_bytes UNUSED, uint32_t *mut_net_offset, void *mut_host_extra UNUSED, uint32_t *out) {
+static inline void unmarshal_4(uint8_t *net_bytes, uint32_t *mut_net_offset, void **mut_host_extra UNUSED, uint32_t *out) {
*out = decode_u32le(&net_bytes[*mut_net_offset]);
*mut_net_offset += 4;
}
-static inline void unmarshal_8(uint32_t net_len, uint8_t *net_bytes UNUSED, uint32_t *mut_net_offset, void *mut_host_extra UNUSED, uint64_t *out) {
+static inline void unmarshal_8(uint8_t *net_bytes, uint32_t *mut_net_offset, void **mut_host_extra UNUSED, uint64_t *out) {
*out = decode_u64le(&net_bytes[*mut_net_offset]);
*mut_net_offset += 8;
}
"""
for struct in structs + msgs:
- ret += f"static inline void unmarshal_{shortname(struct)}(uint32_t net_len, uint8_t *net_bytes, uint32_t *mut_net_offset, void *mut_host_extra, {c_typename(struct)} *out) {{"
+ argattr = ' UNUSED' if len(struct.members) == 0 else ''
+ ret += f"static inline void unmarshal_{shortname(struct)}(uint8_t *net_bytes{argattr}, uint32_t *mut_net_offset{argattr}, void **mut_host_extra{argattr}, {c_typename(struct)} *out{argattr}) {{"
if len(struct.members) == 0:
ret += "}\n"
continue
ret += "\n"
for member in struct.members:
if isinstance(member.typ, List):
- ret += f"\tout->{member.name} = mut_host_extra;\n"
+ ret += f"\tout->{member.name} = *mut_host_extra;\n"
ret += f"\t*mut_host_extra += sizeof(out->{member.name}) * out->{member.typ.cnt};\n"
ret += f"\tfor (typeof(out->{member.typ.cnt}) i = 0; i < out->{member.typ.cnt}; i++)\n"
- ret += f"\t\tunmarshal_{shortname(member.typ.typ)}(net_len, net_bytes, mut_net_offset, mut_host_extra, &(out->{member.name}[i]));\n"
+ ret += f"\t\tunmarshal_{shortname(member.typ.typ)}(net_bytes, mut_net_offset, mut_host_extra, &(out->{member.name}[i]));\n"
else:
- ret += f"\tunmarshal_{shortname(member.typ)}(net_len, net_bytes, mut_net_offset, mut_host_extra, &(out->{member.name}));\n"
+ ret += f"\tunmarshal_{shortname(member.typ)}(net_bytes, mut_net_offset, mut_host_extra, &(out->{member.name}));\n"
ret += "}\n"
+ # v9fs_unmarshal_msg #######################################################
+ ret += """
+/* v9fs_unmarshal_msg *********************************************************/
+
+int v9fs_unmarshal_msg(uint8_t *net_bytes, uint16_t *out_tag, void **out_body) {
+ uint32_t net_len = decode_u32le(net_bytes);
+ if (net_len < 7)
+ return -V9FS_EWRONGSIZE;
+ uint8_t typ = net_bytes[4];
+ *out_tag = decode_u16le(&net_bytes[5]);
+
+ uint32_t net_offset = 7;
+ size_t host_size;
+ void *host_extra;
+ switch (typ) {
+"""
+ for msg in msgs:
+ ret += f"\tcase V9FS_TYP_{msg.name}:\n"
+ ret += f"\t\thost_size = sizeof({c_typename(msg)});\n"
+ ret += f"\t\tif (checksize_{shortname(msg)}(net_len, net_bytes, &net_offset, &host_size))\n"
+ ret += "\t\t\treturn -V9FS_EWRONGSIZE;\n"
+ ret += "\n"
+ ret += "\t\t*out_body = malloc(host_size);"
+ ret += "\n"
+ ret += "\t\tnet_offset = 7;\n"
+ ret += f"\t\thost_extra = *out_body + sizeof({c_typename(msg)});\n"
+ ret += f"\t\tunmarshal_{shortname(msg)}(net_bytes, &net_offset, &host_extra, *out_body);\n"
+ ret += "\n"
+ ret += "\t\tbreak;\n"
+ ret += """
+ default:
+ return -V9FS_EBADTYPE;
+ }
+ return typ;
+}
+"""
+
+ # marshal_* ################################################################
+ ret += """
+/* marshal_* ******************************************************************/
+
+static inline void marshal_1(uint8_t val, uint8_t *out_net_bytes, uint32_t *mut_net_offset) {
+ out_net_bytes[*mut_net_offset] = val;
+ *mut_net_offset += 1;
+}
+static inline void marshal_2(uint16_t val, uint8_t *out_net_bytes, uint32_t *mut_net_offset) {
+ encode_u16le(val, &out_net_bytes[*mut_net_offset]);
+ *mut_net_offset += 2;
+}
+static inline void marshal_4(uint32_t val, uint8_t *out_net_bytes, uint32_t *mut_net_offset) {
+ encode_u32le(val, &out_net_bytes[*mut_net_offset]);
+ *mut_net_offset += 4;
+}
+static inline void marshal_8(uint64_t val, uint8_t *out_net_bytes, uint32_t *mut_net_offset) {
+ encode_u64le(val, &out_net_bytes[*mut_net_offset]);
+ *mut_net_offset += 8;
+}
+"""
+ for struct in structs + msgs:
+ argattr = ' UNUSED' if len(struct.members) == 0 else ''
+ ret += f"static inline void marshal_{shortname(struct)}({c_typename(struct)} val{argattr}, uint8_t *out_net_bytes{argattr}, uint32_t *mut_net_offset{argattr}) {{"
+ if len(struct.members) == 0:
+ ret += "}\n"
+ continue
+ ret += "\n"
+ for member in struct.members:
+ if isinstance(member.typ, List):
+ ret += f"\tfor (typeof(val.{member.typ.cnt}) i = 0; i < val.{member.typ.cnt}; i++)\n"
+ ret += f"\t\tmarshal_{shortname(member.typ.typ)}(val.{member.name}[i], out_net_bytes, mut_net_offset);\n"
+ else:
+ ret += f"\tmarshal_{shortname(member.typ)}(val.{member.name}, out_net_bytes, mut_net_offset);\n"
+ ret += "}\n"
+
+ # _v9fs_marshal_msg_* ######################################################
+ ret += """
+/* _v9fs_marshal_msg_* ********************************************************/
+
+"""
+ for msg in msgs:
+ ret += f"uint32_t _v9fs_marshal_{shortname(msg)}(uint16_t in_msgid, {c_typename(msg)} in_msg, uint8_t *out_buf) {{\n"
+ ret += "\tuint32_t offset = 4;\n"
+ ret += f"\tmarshal_1(V9FS_TYP_{msg.name}, out_buf, &offset);\n"
+ ret += "\tmarshal_2(in_msgid, out_buf, &offset);\n"
+ ret += f"\tmarshal_{shortname(msg)}(in_msg, out_buf, &offset);\n"
+ ret += "\tencode_u32le(offset, out_buf);\n"
+ ret += "\treturn offset;\n"
+ ret += "}\n"
+ ret += "\n"
+
############################################################################
return ret