summaryrefslogtreecommitdiff
path: root/lib9p
diff options
context:
space:
mode:
Diffstat (limited to 'lib9p')
-rw-r--r--lib9p/9p.c153
-rw-r--r--lib9p/9p.generated.c3285
-rw-r--r--lib9p/CMakeLists.txt4
-rw-r--r--lib9p/idl/0000-README.md63
-rw-r--r--lib9p/idl/0000-TODO.md2
-rw-r--r--lib9p/idl/1992-9P0.9p.wip56
-rw-r--r--lib9p/idl/1995-9P1.9p.wip2
-rw-r--r--lib9p/idl/1996-Styx.9p.wip2
-rw-r--r--lib9p/idl/2002-9P2000.9p83
-rw-r--r--lib9p/idl/2005-9P2000.u.9p14
-rw-r--r--lib9p/idl/2010-9P2000.L.9p186
-rw-r--r--lib9p/idl/__init__.py522
-rw-r--r--lib9p/include/lib9p/9p.generated.h702
-rw-r--r--lib9p/include/lib9p/9p.h7
-rw-r--r--lib9p/internal.h100
-rw-r--r--lib9p/map.h2
-rw-r--r--lib9p/protogen/c.py125
-rw-r--r--lib9p/protogen/c9util.py47
-rw-r--r--lib9p/protogen/c_format.py142
-rw-r--r--lib9p/protogen/c_marshal.py47
-rw-r--r--lib9p/protogen/c_unmarshal.py13
-rw-r--r--lib9p/protogen/c_validate.py28
-rw-r--r--lib9p/protogen/h.py270
-rw-r--r--lib9p/srv.c45
-rw-r--r--lib9p/tables.c186
-rw-r--r--lib9p/tables.h59
-rw-r--r--lib9p/tests/test_compile.c192
-rw-r--r--lib9p/tests/test_compile_config/config.h28
-rw-r--r--lib9p/tests/test_server/config/config.h24
-rw-r--r--lib9p/utf8.h34
30 files changed, 5023 insertions, 1400 deletions
diff --git a/lib9p/9p.c b/lib9p/9p.c
index c11bcd6..e7b20b5 100644
--- a/lib9p/9p.c
+++ b/lib9p/9p.c
@@ -6,35 +6,14 @@
#include <inttypes.h> /* for PRIu{n} */
#include <stdarg.h> /* for va_* */
-#include <stdio.h> /* for vsnprintf() */
#include <string.h> /* for strncpy() */
-#define LOG_NAME 9P
-#include <libmisc/log.h> /* for const_byte_str() */
+#include <libfmt/fmt.h> /* for fmt_vsnprintf() */
#include <lib9p/9p.h>
-#include "internal.h"
-
/* strings ********************************************************************/
-const char *lib9p_version_str(enum lib9p_version ver) {
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wtype-limits"
- assert(0 <= ver && ver < LIB9P_VER_NUM);
-#pragma GCC diagnostic pop
- return _lib9p_table_ver_name[ver];
-}
-
-const char *lib9p_msgtype_str(enum lib9p_version ver, enum lib9p_msg_type typ) {
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wtype-limits"
- assert(0 <= ver && ver < LIB9P_VER_NUM);
- assert(0 <= typ && typ <= 0xFF);
-#pragma GCC diagnostic pop
- return _lib9p_table_msg_name[ver][typ] ?: const_byte_str(typ);
-}
-
struct lib9p_s lib9p_str(char *s) {
if (!s)
return (struct lib9p_s){0};
@@ -101,7 +80,7 @@ int lib9p_errorf(struct lib9p_ctx *ctx, lib9p_errno_t linux_errno, char const *f
if (lib9p_ctx_has_error(ctx))
return -1;
va_start(args, fmt);
- n = vsnprintf(ctx->err_msg, sizeof(ctx->err_msg), fmt, args);
+ n = fmt_vsnprintf(ctx->err_msg, sizeof(ctx->err_msg), fmt, args);
va_end(args);
if ((size_t)(n+1) < sizeof(ctx->err_msg))
memset(&ctx->err_msg[n+1], 0, sizeof(ctx->err_msg)-(n+1));
@@ -114,131 +93,3 @@ int lib9p_errorf(struct lib9p_ctx *ctx, lib9p_errno_t linux_errno, char const *f
return -1;
}
-
-/* main message functions *****************************************************/
-
-static
-ssize_t _lib9p_validate(uint8_t xxx_low_typ_bit,
- const char *xxx_errmsg,
- const struct _lib9p_recv_tentry xxx_table[LIB9P_VER_NUM][0x80],
- struct lib9p_ctx *ctx, uint8_t *net_bytes) {
- /* Inspect the first 5 bytes ourselves. */
- uint32_t net_size = uint32le_decode(net_bytes);
- if (net_size < 5)
- return lib9p_error(ctx, LINUX_EBADMSG, "message is impossibly short");
- uint8_t typ = net_bytes[4];
- if (typ % 2 != xxx_low_typ_bit)
- return lib9p_errorf(ctx, LINUX_EOPNOTSUPP, "%s: message_type=%s", xxx_errmsg,
- lib9p_msgtype_str(ctx->version, typ));
- struct _lib9p_recv_tentry tentry = xxx_table[ctx->version][typ/2];
- if (!tentry.validate)
- return lib9p_errorf(ctx, LINUX_EOPNOTSUPP, "unknown message type: %s (protocol_version=%s)",
- lib9p_msgtype_str(ctx->version, typ), lib9p_version_str(ctx->version));
-
- /* Now use the message-type-specific tentry to process the whole thing. */
- return tentry.validate(ctx, net_size, net_bytes);
-}
-
-ssize_t lib9p_Tmsg_validate(struct lib9p_ctx *ctx, uint8_t *net_bytes) {
- return _lib9p_validate(0, "expected a T-message but got an R-message", _lib9p_table_Tmsg_recv,
- ctx, net_bytes);
-}
-
-ssize_t lib9p_Rmsg_validate(struct lib9p_ctx *ctx, uint8_t *net_bytes) {
- return _lib9p_validate(1, "expected an R-message but got a T-message", _lib9p_table_Rmsg_recv,
- ctx, net_bytes);
-}
-
-static
-void _lib9p_unmarshal(const struct _lib9p_recv_tentry xxx_table[LIB9P_VER_NUM][0x80],
- struct lib9p_ctx *ctx, uint8_t *net_bytes,
- enum lib9p_msg_type *ret_typ, void *ret_body) {
- enum lib9p_msg_type typ = net_bytes[4];
- *ret_typ = typ;
- struct _lib9p_recv_tentry tentry = xxx_table[ctx->version][typ/2];
-
- tentry.unmarshal(ctx, net_bytes, ret_body);
-}
-
-void lib9p_Tmsg_unmarshal(struct lib9p_ctx *ctx, uint8_t *net_bytes,
- enum lib9p_msg_type *ret_typ, void *ret_body) {
- _lib9p_unmarshal(_lib9p_table_Tmsg_recv,
- ctx, net_bytes, ret_typ, ret_body);
-}
-
-void lib9p_Rmsg_unmarshal(struct lib9p_ctx *ctx, uint8_t *net_bytes,
- enum lib9p_msg_type *ret_typ, void *ret_body) {
- _lib9p_unmarshal(_lib9p_table_Rmsg_recv,
- ctx, net_bytes, ret_typ, ret_body);
-}
-
-static
-bool _lib9p_marshal(const struct _lib9p_send_tentry xxx_table[LIB9P_VER_NUM][0x80],
- struct lib9p_ctx *ctx, enum lib9p_msg_type typ, void *body,
- size_t *ret_iov_cnt, struct iovec *ret_iov, uint8_t *ret_copied) {
- struct _marshal_ret ret = {
- .net_iov_cnt = 1,
- .net_iov = ret_iov,
- .net_copied_size = 0,
- .net_copied = ret_copied,
- };
-
- struct _lib9p_send_tentry tentry = xxx_table[ctx->version][typ/2];
- bool ret_erred = tentry.marshal(ctx, body, &ret);
- if (ret_iov[ret.net_iov_cnt-1].iov_len == 0)
- ret.net_iov_cnt--;
- *ret_iov_cnt = ret.net_iov_cnt;
- return ret_erred;
-}
-
-bool lib9p_Tmsg_marshal(struct lib9p_ctx *ctx, enum lib9p_msg_type typ, void *body,
- struct lib9p_Tmsg_send_buf *ret) {
- assert(typ % 2 == 0);
- memset(ret, 0, sizeof(*ret));
- return _lib9p_marshal(_lib9p_table_Tmsg_send,
- ctx, typ, body,
- &ret->iov_cnt, ret->iov, ret->copied);
-}
-
-bool lib9p_Rmsg_marshal(struct lib9p_ctx *ctx, enum lib9p_msg_type typ, void *body,
- struct lib9p_Rmsg_send_buf *ret) {
- assert(typ % 2 == 1);
- memset(ret, 0, sizeof(*ret));
- return _lib9p_marshal(_lib9p_table_Rmsg_send,
- ctx, typ, body,
- &ret->iov_cnt, ret->iov, ret->copied);
-}
-
-/* `struct lib9p_stat` helpers ************************************************/
-
-bool lib9p_stat_validate(struct lib9p_ctx *ctx, uint32_t net_size, uint8_t *net_bytes,
- uint32_t *ret_net_size, ssize_t *ret_host_size) {
- ssize_t host_size = _lib9p_stat_validate(ctx, net_size, net_bytes, ret_net_size);
- if (host_size < 0)
- return true;
- if (ret_host_size)
- *ret_host_size = host_size;
- return false;
-}
-
-void lib9p_stat_unmarshal(struct lib9p_ctx *ctx, uint8_t *net_bytes,
- struct lib9p_stat *ret) {
- _lib9p_stat_unmarshal(ctx, net_bytes, ret);
-}
-
-uint32_t lib9p_stat_marshal(struct lib9p_ctx *ctx, uint32_t max_net_size, struct lib9p_stat *obj,
- uint8_t *ret_bytes) {
- struct lib9p_ctx _ctx = *ctx;
- _ctx.max_msg_size = max_net_size;
-
- struct iovec iov = {0};
- struct _marshal_ret ret = {
- .net_iov_cnt = 1,
- .net_iov = &iov,
- .net_copied_size = 0,
- .net_copied = ret_bytes,
- };
- if (_lib9p_stat_marshal(&_ctx, obj, &ret))
- return 0;
- return ret.net_iov[0].iov_len;
-}
diff --git a/lib9p/9p.generated.c b/lib9p/9p.generated.c
index 6726084..b58a485 100644
--- a/lib9p/9p.generated.c
+++ b/lib9p/9p.generated.c
@@ -6,10 +6,132 @@
#include <string.h> /* for memset() */
#include <libmisc/assert.h>
+#include <libmisc/endian.h>
#include <lib9p/9p.h>
-#include "internal.h"
+#include "tables.h"
+#include "utf8.h"
+
+/* libobj vtables *************************************************************/
+#if CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u
+LO_IMPLEMENTATION_C(fmt_formatter, lib9p_tag_t, lib9p_tag, static);
+LO_IMPLEMENTATION_C(fmt_formatter, lib9p_fid_t, lib9p_fid, static);
+LO_IMPLEMENTATION_C(fmt_formatter, struct lib9p_s, lib9p_s, static);
+#endif /* CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u */
+#if CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u
+LO_IMPLEMENTATION_C(fmt_formatter, lib9p_dm_t, lib9p_dm, static);
+#endif /* CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u */
+#if CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u
+LO_IMPLEMENTATION_C(fmt_formatter, lib9p_qt_t, lib9p_qt, static);
+LO_IMPLEMENTATION_C(fmt_formatter, struct lib9p_qid, lib9p_qid, static);
+#endif /* CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u */
+#if CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u
+LO_IMPLEMENTATION_C(fmt_formatter, struct lib9p_stat, lib9p_stat, static);
+LO_IMPLEMENTATION_C(fmt_formatter, lib9p_o_t, lib9p_o, static);
+#endif /* CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u */
+#if CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u
+LO_IMPLEMENTATION_C(fmt_formatter, struct lib9p_msg_Tversion, lib9p_msg_Tversion, static);
+LO_IMPLEMENTATION_C(fmt_formatter, struct lib9p_msg_Rversion, lib9p_msg_Rversion, static);
+LO_IMPLEMENTATION_C(fmt_formatter, struct lib9p_msg_Tauth, lib9p_msg_Tauth, static);
+LO_IMPLEMENTATION_C(fmt_formatter, struct lib9p_msg_Rauth, lib9p_msg_Rauth, static);
+LO_IMPLEMENTATION_C(fmt_formatter, struct lib9p_msg_Tattach, lib9p_msg_Tattach, static);
+LO_IMPLEMENTATION_C(fmt_formatter, struct lib9p_msg_Rattach, lib9p_msg_Rattach, static);
+LO_IMPLEMENTATION_C(fmt_formatter, struct lib9p_msg_Rerror, lib9p_msg_Rerror, static);
+LO_IMPLEMENTATION_C(fmt_formatter, struct lib9p_msg_Tflush, lib9p_msg_Tflush, static);
+LO_IMPLEMENTATION_C(fmt_formatter, struct lib9p_msg_Rflush, lib9p_msg_Rflush, static);
+LO_IMPLEMENTATION_C(fmt_formatter, struct lib9p_msg_Twalk, lib9p_msg_Twalk, static);
+LO_IMPLEMENTATION_C(fmt_formatter, struct lib9p_msg_Rwalk, lib9p_msg_Rwalk, static);
+#endif /* CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u */
+#if CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u
+LO_IMPLEMENTATION_C(fmt_formatter, struct lib9p_msg_Topen, lib9p_msg_Topen, static);
+LO_IMPLEMENTATION_C(fmt_formatter, struct lib9p_msg_Ropen, lib9p_msg_Ropen, static);
+LO_IMPLEMENTATION_C(fmt_formatter, struct lib9p_msg_Tcreate, lib9p_msg_Tcreate, static);
+LO_IMPLEMENTATION_C(fmt_formatter, struct lib9p_msg_Rcreate, lib9p_msg_Rcreate, static);
+#endif /* CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u */
+#if CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u
+LO_IMPLEMENTATION_C(fmt_formatter, struct lib9p_msg_Tread, lib9p_msg_Tread, static);
+LO_IMPLEMENTATION_C(fmt_formatter, struct lib9p_msg_Rread, lib9p_msg_Rread, static);
+LO_IMPLEMENTATION_C(fmt_formatter, struct lib9p_msg_Twrite, lib9p_msg_Twrite, static);
+LO_IMPLEMENTATION_C(fmt_formatter, struct lib9p_msg_Rwrite, lib9p_msg_Rwrite, static);
+LO_IMPLEMENTATION_C(fmt_formatter, struct lib9p_msg_Tclunk, lib9p_msg_Tclunk, static);
+LO_IMPLEMENTATION_C(fmt_formatter, struct lib9p_msg_Rclunk, lib9p_msg_Rclunk, static);
+LO_IMPLEMENTATION_C(fmt_formatter, struct lib9p_msg_Tremove, lib9p_msg_Tremove, static);
+LO_IMPLEMENTATION_C(fmt_formatter, struct lib9p_msg_Rremove, lib9p_msg_Rremove, static);
+#endif /* CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u */
+#if CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u
+LO_IMPLEMENTATION_C(fmt_formatter, struct lib9p_msg_Tstat, lib9p_msg_Tstat, static);
+LO_IMPLEMENTATION_C(fmt_formatter, struct lib9p_msg_Rstat, lib9p_msg_Rstat, static);
+LO_IMPLEMENTATION_C(fmt_formatter, struct lib9p_msg_Twstat, lib9p_msg_Twstat, static);
+LO_IMPLEMENTATION_C(fmt_formatter, struct lib9p_msg_Rwstat, lib9p_msg_Rwstat, static);
+#endif /* CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u */
+#if CONFIG_9P_ENABLE_9P2000_p9p
+LO_IMPLEMENTATION_C(fmt_formatter, struct lib9p_msg_Topenfd, lib9p_msg_Topenfd, static);
+LO_IMPLEMENTATION_C(fmt_formatter, struct lib9p_msg_Ropenfd, lib9p_msg_Ropenfd, static);
+#endif /* CONFIG_9P_ENABLE_9P2000_p9p */
+#if CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_u
+LO_IMPLEMENTATION_C(fmt_formatter, lib9p_nuid_t, lib9p_nuid, static);
+LO_IMPLEMENTATION_C(fmt_formatter, lib9p_errno_t, lib9p_errno, static);
+#endif /* CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_u */
+#if CONFIG_9P_ENABLE_9P2000_L
+LO_IMPLEMENTATION_C(fmt_formatter, lib9p_super_magic_t, lib9p_super_magic, static);
+LO_IMPLEMENTATION_C(fmt_formatter, lib9p_lo_t, lib9p_lo, static);
+LO_IMPLEMENTATION_C(fmt_formatter, lib9p_dt_t, lib9p_dt, static);
+LO_IMPLEMENTATION_C(fmt_formatter, lib9p_mode_t, lib9p_mode, static);
+LO_IMPLEMENTATION_C(fmt_formatter, lib9p_b4_t, lib9p_b4, static);
+LO_IMPLEMENTATION_C(fmt_formatter, lib9p_getattr_t, lib9p_getattr, static);
+LO_IMPLEMENTATION_C(fmt_formatter, lib9p_setattr_t, lib9p_setattr, static);
+LO_IMPLEMENTATION_C(fmt_formatter, lib9p_lock_type_t, lib9p_lock_type, static);
+LO_IMPLEMENTATION_C(fmt_formatter, lib9p_lock_flags_t, lib9p_lock_flags, static);
+LO_IMPLEMENTATION_C(fmt_formatter, lib9p_lock_status_t, lib9p_lock_status, static);
+LO_IMPLEMENTATION_C(fmt_formatter, struct lib9p_msg_Rlerror, lib9p_msg_Rlerror, static);
+LO_IMPLEMENTATION_C(fmt_formatter, struct lib9p_msg_Tstatfs, lib9p_msg_Tstatfs, static);
+LO_IMPLEMENTATION_C(fmt_formatter, struct lib9p_msg_Rstatfs, lib9p_msg_Rstatfs, static);
+LO_IMPLEMENTATION_C(fmt_formatter, struct lib9p_msg_Tlopen, lib9p_msg_Tlopen, static);
+LO_IMPLEMENTATION_C(fmt_formatter, struct lib9p_msg_Rlopen, lib9p_msg_Rlopen, static);
+LO_IMPLEMENTATION_C(fmt_formatter, struct lib9p_msg_Tlcreate, lib9p_msg_Tlcreate, static);
+LO_IMPLEMENTATION_C(fmt_formatter, struct lib9p_msg_Rlcreate, lib9p_msg_Rlcreate, static);
+LO_IMPLEMENTATION_C(fmt_formatter, struct lib9p_msg_Tsymlink, lib9p_msg_Tsymlink, static);
+LO_IMPLEMENTATION_C(fmt_formatter, struct lib9p_msg_Rsymlink, lib9p_msg_Rsymlink, static);
+LO_IMPLEMENTATION_C(fmt_formatter, struct lib9p_msg_Tmknod, lib9p_msg_Tmknod, static);
+LO_IMPLEMENTATION_C(fmt_formatter, struct lib9p_msg_Rmknod, lib9p_msg_Rmknod, static);
+LO_IMPLEMENTATION_C(fmt_formatter, struct lib9p_msg_Trename, lib9p_msg_Trename, static);
+LO_IMPLEMENTATION_C(fmt_formatter, struct lib9p_msg_Rrename, lib9p_msg_Rrename, static);
+LO_IMPLEMENTATION_C(fmt_formatter, struct lib9p_msg_Treadlink, lib9p_msg_Treadlink, static);
+LO_IMPLEMENTATION_C(fmt_formatter, struct lib9p_msg_Rreadlink, lib9p_msg_Rreadlink, static);
+LO_IMPLEMENTATION_C(fmt_formatter, struct lib9p_msg_Tgetattr, lib9p_msg_Tgetattr, static);
+LO_IMPLEMENTATION_C(fmt_formatter, struct lib9p_msg_Rgetattr, lib9p_msg_Rgetattr, static);
+LO_IMPLEMENTATION_C(fmt_formatter, struct lib9p_msg_Tsetattr, lib9p_msg_Tsetattr, static);
+LO_IMPLEMENTATION_C(fmt_formatter, struct lib9p_msg_Rsetattr, lib9p_msg_Rsetattr, static);
+LO_IMPLEMENTATION_C(fmt_formatter, struct lib9p_msg_Txattrwalk, lib9p_msg_Txattrwalk, static);
+LO_IMPLEMENTATION_C(fmt_formatter, struct lib9p_msg_Rxattrwalk, lib9p_msg_Rxattrwalk, static);
+LO_IMPLEMENTATION_C(fmt_formatter, struct lib9p_msg_Txattrcreate, lib9p_msg_Txattrcreate, static);
+LO_IMPLEMENTATION_C(fmt_formatter, struct lib9p_msg_Rxattrcreate, lib9p_msg_Rxattrcreate, static);
+LO_IMPLEMENTATION_C(fmt_formatter, struct lib9p_msg_Treaddir, lib9p_msg_Treaddir, static);
+LO_IMPLEMENTATION_C(fmt_formatter, struct lib9p_msg_Rreaddir, lib9p_msg_Rreaddir, static);
+LO_IMPLEMENTATION_C(fmt_formatter, struct lib9p_msg_Tfsync, lib9p_msg_Tfsync, static);
+LO_IMPLEMENTATION_C(fmt_formatter, struct lib9p_msg_Rfsync, lib9p_msg_Rfsync, static);
+LO_IMPLEMENTATION_C(fmt_formatter, struct lib9p_msg_Tlock, lib9p_msg_Tlock, static);
+LO_IMPLEMENTATION_C(fmt_formatter, struct lib9p_msg_Rlock, lib9p_msg_Rlock, static);
+LO_IMPLEMENTATION_C(fmt_formatter, struct lib9p_msg_Tgetlock, lib9p_msg_Tgetlock, static);
+LO_IMPLEMENTATION_C(fmt_formatter, struct lib9p_msg_Rgetlock, lib9p_msg_Rgetlock, static);
+LO_IMPLEMENTATION_C(fmt_formatter, struct lib9p_msg_Tlink, lib9p_msg_Tlink, static);
+LO_IMPLEMENTATION_C(fmt_formatter, struct lib9p_msg_Rlink, lib9p_msg_Rlink, static);
+LO_IMPLEMENTATION_C(fmt_formatter, struct lib9p_msg_Tmkdir, lib9p_msg_Tmkdir, static);
+LO_IMPLEMENTATION_C(fmt_formatter, struct lib9p_msg_Rmkdir, lib9p_msg_Rmkdir, static);
+LO_IMPLEMENTATION_C(fmt_formatter, struct lib9p_msg_Trenameat, lib9p_msg_Trenameat, static);
+LO_IMPLEMENTATION_C(fmt_formatter, struct lib9p_msg_Rrenameat, lib9p_msg_Rrenameat, static);
+LO_IMPLEMENTATION_C(fmt_formatter, struct lib9p_msg_Tunlinkat, lib9p_msg_Tunlinkat, static);
+LO_IMPLEMENTATION_C(fmt_formatter, struct lib9p_msg_Runlinkat, lib9p_msg_Runlinkat, static);
+#endif /* CONFIG_9P_ENABLE_9P2000_L */
+#if CONFIG_9P_ENABLE_9P2000_e
+LO_IMPLEMENTATION_C(fmt_formatter, struct lib9p_msg_Tsession, lib9p_msg_Tsession, static);
+LO_IMPLEMENTATION_C(fmt_formatter, struct lib9p_msg_Rsession, lib9p_msg_Rsession, static);
+LO_IMPLEMENTATION_C(fmt_formatter, struct lib9p_msg_Tsread, lib9p_msg_Tsread, static);
+LO_IMPLEMENTATION_C(fmt_formatter, struct lib9p_msg_Rsread, lib9p_msg_Rsread, static);
+LO_IMPLEMENTATION_C(fmt_formatter, struct lib9p_msg_Tswrite, lib9p_msg_Tswrite, static);
+LO_IMPLEMENTATION_C(fmt_formatter, struct lib9p_msg_Rswrite, lib9p_msg_Rswrite, static);
+#endif /* CONFIG_9P_ENABLE_9P2000_e */
/* utilities ******************************************************************/
#if CONFIG_9P_ENABLE_9P2000
@@ -46,248 +168,24 @@
*/
#define is_ver(ctx, ver) _is_ver_##ver((ctx)->version)
-/* strings ********************************************************************/
-
-const char *const _lib9p_table_ver_name[LIB9P_VER_NUM] = {
- [LIB9P_VER_unknown] = "unknown",
-#if CONFIG_9P_ENABLE_9P2000
- [LIB9P_VER_9P2000] = "9P2000",
-#endif /* CONFIG_9P_ENABLE_9P2000 */
-#if CONFIG_9P_ENABLE_9P2000_L
- [LIB9P_VER_9P2000_L] = "9P2000.L",
-#endif /* CONFIG_9P_ENABLE_9P2000_L */
-#if CONFIG_9P_ENABLE_9P2000_e
- [LIB9P_VER_9P2000_e] = "9P2000.e",
-#endif /* CONFIG_9P_ENABLE_9P2000_e */
-#if CONFIG_9P_ENABLE_9P2000_p9p
- [LIB9P_VER_9P2000_p9p] = "9P2000.p9p",
-#endif /* CONFIG_9P_ENABLE_9P2000_p9p */
-#if CONFIG_9P_ENABLE_9P2000_u
- [LIB9P_VER_9P2000_u] = "9P2000.u",
-#endif /* CONFIG_9P_ENABLE_9P2000_u */
-};
-
-#define _MSG_NAME(typ) [LIB9P_TYP_##typ] = #typ
-const char *const _lib9p_table_msg_name[LIB9P_VER_NUM][0x100] = {
- [LIB9P_VER_unknown] = {
- _MSG_NAME(Tversion),
- _MSG_NAME(Rversion),
- _MSG_NAME(Rerror),
- },
-#if CONFIG_9P_ENABLE_9P2000
- [LIB9P_VER_9P2000] = {
- _MSG_NAME(Tversion),
- _MSG_NAME(Rversion),
- _MSG_NAME(Tauth),
- _MSG_NAME(Rauth),
- _MSG_NAME(Tattach),
- _MSG_NAME(Rattach),
- _MSG_NAME(Rerror),
- _MSG_NAME(Tflush),
- _MSG_NAME(Rflush),
- _MSG_NAME(Twalk),
- _MSG_NAME(Rwalk),
- _MSG_NAME(Topen),
- _MSG_NAME(Ropen),
- _MSG_NAME(Tcreate),
- _MSG_NAME(Rcreate),
- _MSG_NAME(Tread),
- _MSG_NAME(Rread),
- _MSG_NAME(Twrite),
- _MSG_NAME(Rwrite),
- _MSG_NAME(Tclunk),
- _MSG_NAME(Rclunk),
- _MSG_NAME(Tremove),
- _MSG_NAME(Rremove),
- _MSG_NAME(Tstat),
- _MSG_NAME(Rstat),
- _MSG_NAME(Twstat),
- _MSG_NAME(Rwstat),
- },
-#endif /* CONFIG_9P_ENABLE_9P2000 */
-#if CONFIG_9P_ENABLE_9P2000_L
- [LIB9P_VER_9P2000_L] = {
- _MSG_NAME(Rlerror),
- _MSG_NAME(Tstatfs),
- _MSG_NAME(Rstatfs),
- _MSG_NAME(Tlopen),
- _MSG_NAME(Rlopen),
- _MSG_NAME(Tlcreate),
- _MSG_NAME(Rlcreate),
- _MSG_NAME(Tsymlink),
- _MSG_NAME(Rsymlink),
- _MSG_NAME(Tmknod),
- _MSG_NAME(Rmknod),
- _MSG_NAME(Trename),
- _MSG_NAME(Rrename),
- _MSG_NAME(Treadlink),
- _MSG_NAME(Rreadlink),
- _MSG_NAME(Tgetattr),
- _MSG_NAME(Rgetattr),
- _MSG_NAME(Tsetattr),
- _MSG_NAME(Rsetattr),
- _MSG_NAME(Txattrwalk),
- _MSG_NAME(Rxattrwalk),
- _MSG_NAME(Txattrcreate),
- _MSG_NAME(Rxattrcreate),
- _MSG_NAME(Treaddir),
- _MSG_NAME(Rreaddir),
- _MSG_NAME(Tfsync),
- _MSG_NAME(Rfsync),
- _MSG_NAME(Tlock),
- _MSG_NAME(Rlock),
- _MSG_NAME(Tgetlock),
- _MSG_NAME(Rgetlock),
- _MSG_NAME(Tlink),
- _MSG_NAME(Rlink),
- _MSG_NAME(Tmkdir),
- _MSG_NAME(Rmkdir),
- _MSG_NAME(Trenameat),
- _MSG_NAME(Rrenameat),
- _MSG_NAME(Tunlinkat),
- _MSG_NAME(Runlinkat),
- _MSG_NAME(Tversion),
- _MSG_NAME(Rversion),
- _MSG_NAME(Tauth),
- _MSG_NAME(Rauth),
- _MSG_NAME(Tattach),
- _MSG_NAME(Rattach),
- _MSG_NAME(Rerror),
- _MSG_NAME(Tflush),
- _MSG_NAME(Rflush),
- _MSG_NAME(Twalk),
- _MSG_NAME(Rwalk),
- _MSG_NAME(Tread),
- _MSG_NAME(Rread),
- _MSG_NAME(Twrite),
- _MSG_NAME(Rwrite),
- _MSG_NAME(Tclunk),
- _MSG_NAME(Rclunk),
- _MSG_NAME(Tremove),
- _MSG_NAME(Rremove),
- },
-#endif /* CONFIG_9P_ENABLE_9P2000_L */
-#if CONFIG_9P_ENABLE_9P2000_e
- [LIB9P_VER_9P2000_e] = {
- _MSG_NAME(Tversion),
- _MSG_NAME(Rversion),
- _MSG_NAME(Tauth),
- _MSG_NAME(Rauth),
- _MSG_NAME(Tattach),
- _MSG_NAME(Rattach),
- _MSG_NAME(Rerror),
- _MSG_NAME(Tflush),
- _MSG_NAME(Rflush),
- _MSG_NAME(Twalk),
- _MSG_NAME(Rwalk),
- _MSG_NAME(Topen),
- _MSG_NAME(Ropen),
- _MSG_NAME(Tcreate),
- _MSG_NAME(Rcreate),
- _MSG_NAME(Tread),
- _MSG_NAME(Rread),
- _MSG_NAME(Twrite),
- _MSG_NAME(Rwrite),
- _MSG_NAME(Tclunk),
- _MSG_NAME(Rclunk),
- _MSG_NAME(Tremove),
- _MSG_NAME(Rremove),
- _MSG_NAME(Tstat),
- _MSG_NAME(Rstat),
- _MSG_NAME(Twstat),
- _MSG_NAME(Rwstat),
- _MSG_NAME(Tsession),
- _MSG_NAME(Rsession),
- _MSG_NAME(Tsread),
- _MSG_NAME(Rsread),
- _MSG_NAME(Tswrite),
- _MSG_NAME(Rswrite),
- },
-#endif /* CONFIG_9P_ENABLE_9P2000_e */
-#if CONFIG_9P_ENABLE_9P2000_p9p
- [LIB9P_VER_9P2000_p9p] = {
- _MSG_NAME(Topenfd),
- _MSG_NAME(Ropenfd),
- _MSG_NAME(Tversion),
- _MSG_NAME(Rversion),
- _MSG_NAME(Tauth),
- _MSG_NAME(Rauth),
- _MSG_NAME(Tattach),
- _MSG_NAME(Rattach),
- _MSG_NAME(Rerror),
- _MSG_NAME(Tflush),
- _MSG_NAME(Rflush),
- _MSG_NAME(Twalk),
- _MSG_NAME(Rwalk),
- _MSG_NAME(Topen),
- _MSG_NAME(Ropen),
- _MSG_NAME(Tcreate),
- _MSG_NAME(Rcreate),
- _MSG_NAME(Tread),
- _MSG_NAME(Rread),
- _MSG_NAME(Twrite),
- _MSG_NAME(Rwrite),
- _MSG_NAME(Tclunk),
- _MSG_NAME(Rclunk),
- _MSG_NAME(Tremove),
- _MSG_NAME(Rremove),
- _MSG_NAME(Tstat),
- _MSG_NAME(Rstat),
- _MSG_NAME(Twstat),
- _MSG_NAME(Rwstat),
- },
-#endif /* CONFIG_9P_ENABLE_9P2000_p9p */
-#if CONFIG_9P_ENABLE_9P2000_u
- [LIB9P_VER_9P2000_u] = {
- _MSG_NAME(Tversion),
- _MSG_NAME(Rversion),
- _MSG_NAME(Tauth),
- _MSG_NAME(Rauth),
- _MSG_NAME(Tattach),
- _MSG_NAME(Rattach),
- _MSG_NAME(Rerror),
- _MSG_NAME(Tflush),
- _MSG_NAME(Rflush),
- _MSG_NAME(Twalk),
- _MSG_NAME(Rwalk),
- _MSG_NAME(Topen),
- _MSG_NAME(Ropen),
- _MSG_NAME(Tcreate),
- _MSG_NAME(Rcreate),
- _MSG_NAME(Tread),
- _MSG_NAME(Rread),
- _MSG_NAME(Twrite),
- _MSG_NAME(Rwrite),
- _MSG_NAME(Tclunk),
- _MSG_NAME(Rclunk),
- _MSG_NAME(Tremove),
- _MSG_NAME(Rremove),
- _MSG_NAME(Tstat),
- _MSG_NAME(Rstat),
- _MSG_NAME(Twstat),
- _MSG_NAME(Rwstat),
- },
-#endif /* CONFIG_9P_ENABLE_9P2000_u */
-};
-
/* bitmasks *******************************************************************/
#if CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u
static const lib9p_dm_t dm_masks[LIB9P_VER_NUM] = {
#if CONFIG_9P_ENABLE_9P2000
- [LIB9P_VER_9P2000] = 0b11101100000000000000000111111111,
+ [LIB9P_VER_9P2000] = 0b11111100000000000000000111111111,
#endif /* CONFIG_9P_ENABLE_9P2000 */
#if CONFIG_9P_ENABLE_9P2000_L
[LIB9P_VER_9P2000_L] = 0b00000000000000000000000000000000,
#endif /* CONFIG_9P_ENABLE_9P2000_L */
#if CONFIG_9P_ENABLE_9P2000_e
- [LIB9P_VER_9P2000_e] = 0b11101100000000000000000111111111,
+ [LIB9P_VER_9P2000_e] = 0b11111100000000000000000111111111,
#endif /* CONFIG_9P_ENABLE_9P2000_e */
#if CONFIG_9P_ENABLE_9P2000_p9p
- [LIB9P_VER_9P2000_p9p] = 0b11101100000000000000000111111111,
+ [LIB9P_VER_9P2000_p9p] = 0b11111100000000000000000111111111,
#endif /* CONFIG_9P_ENABLE_9P2000_p9p */
#if CONFIG_9P_ENABLE_9P2000_u
- [LIB9P_VER_9P2000_u] = 0b11101100101111000000000111111111,
+ [LIB9P_VER_9P2000_u] = 0b11111100101111000000000111111111,
#endif /* CONFIG_9P_ENABLE_9P2000_u */
};
@@ -295,19 +193,19 @@ static const lib9p_dm_t dm_masks[LIB9P_VER_NUM] = {
#if CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u
static const lib9p_qt_t qt_masks[LIB9P_VER_NUM] = {
#if CONFIG_9P_ENABLE_9P2000
- [LIB9P_VER_9P2000] = 0b11101100,
+ [LIB9P_VER_9P2000] = 0b11111100,
#endif /* CONFIG_9P_ENABLE_9P2000 */
#if CONFIG_9P_ENABLE_9P2000_L
- [LIB9P_VER_9P2000_L] = 0b11101100,
+ [LIB9P_VER_9P2000_L] = 0b11111100,
#endif /* CONFIG_9P_ENABLE_9P2000_L */
#if CONFIG_9P_ENABLE_9P2000_e
- [LIB9P_VER_9P2000_e] = 0b11101100,
+ [LIB9P_VER_9P2000_e] = 0b11111100,
#endif /* CONFIG_9P_ENABLE_9P2000_e */
#if CONFIG_9P_ENABLE_9P2000_p9p
- [LIB9P_VER_9P2000_p9p] = 0b11101100,
+ [LIB9P_VER_9P2000_p9p] = 0b11111100,
#endif /* CONFIG_9P_ENABLE_9P2000_p9p */
#if CONFIG_9P_ENABLE_9P2000_u
- [LIB9P_VER_9P2000_u] = 0b11101110,
+ [LIB9P_VER_9P2000_u] = 0b11111110,
#endif /* CONFIG_9P_ENABLE_9P2000_u */
};
@@ -4743,29 +4641,2930 @@ static bool marshal_Rswrite(struct lib9p_ctx *ctx, struct lib9p_msg_Rswrite *val
}
#endif /* CONFIG_9P_ENABLE_9P2000_e */
-/* function tables ************************************************************/
+/* *_format *******************************************************************/
+
+#if CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u
+static void lib9p_tag_format(lib9p_tag_t *self, struct fmt_state *state) {
+ switch (*self) {
+ case LIB9P_TAG_NOTAG:
+ fmt_state_puts(state, "NOTAG");
+ break;
+ default:
+ fmt_state_printf(state, "%"PRIu16, *self);
+ }
+}
+
+static void lib9p_fid_format(lib9p_fid_t *self, struct fmt_state *state) {
+ switch (*self) {
+ case LIB9P_FID_NOFID:
+ fmt_state_puts(state, "NOFID");
+ break;
+ default:
+ fmt_state_printf(state, "%"PRIu32, *self);
+ }
+}
+
+static void lib9p_s_format(struct lib9p_s *self, struct fmt_state *state) {
+ /* https://gcc.gnu.org/bugzilla/show_bug.cgi?id=47781 */
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wformat"
+#pragma GCC diagnostic ignored "-Wformat-extra-args"
+ fmt_state_printf(state, "%.*q", self->len, self->utf8);
+#pragma GCC diagnostic pop
+}
+
+#endif /* CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u */
+#if CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u
+static void lib9p_dm_format(lib9p_dm_t *self, struct fmt_state *state) {
+ bool empty = true;
+ fmt_state_putchar(state, '(');
+ if ((*self & ~((lib9p_dm_t)0777)) & (UINT32_C(1)<<31)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "DIR");
+ empty = false;
+ }
+ if ((*self & ~((lib9p_dm_t)0777)) & (UINT32_C(1)<<30)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "APPEND");
+ empty = false;
+ }
+ if ((*self & ~((lib9p_dm_t)0777)) & (UINT32_C(1)<<29)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "EXCL");
+ empty = false;
+ }
+ if ((*self & ~((lib9p_dm_t)0777)) & (UINT32_C(1)<<28)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "_PLAN9_MOUNT");
+ empty = false;
+ }
+ if ((*self & ~((lib9p_dm_t)0777)) & (UINT32_C(1)<<27)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "AUTH");
+ empty = false;
+ }
+ if ((*self & ~((lib9p_dm_t)0777)) & (UINT32_C(1)<<26)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "TMP");
+ empty = false;
+ }
+ if ((*self & ~((lib9p_dm_t)0777)) & (UINT32_C(1)<<25)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "1<<25");
+ empty = false;
+ }
+ if ((*self & ~((lib9p_dm_t)0777)) & (UINT32_C(1)<<24)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "1<<24");
+ empty = false;
+ }
+ if ((*self & ~((lib9p_dm_t)0777)) & (UINT32_C(1)<<23)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "DEVICE");
+ empty = false;
+ }
+ if ((*self & ~((lib9p_dm_t)0777)) & (UINT32_C(1)<<22)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "1<<22");
+ empty = false;
+ }
+ if ((*self & ~((lib9p_dm_t)0777)) & (UINT32_C(1)<<21)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "PIPE");
+ empty = false;
+ }
+ if ((*self & ~((lib9p_dm_t)0777)) & (UINT32_C(1)<<20)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "SOCKET");
+ empty = false;
+ }
+ if ((*self & ~((lib9p_dm_t)0777)) & (UINT32_C(1)<<19)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "SETUID");
+ empty = false;
+ }
+ if ((*self & ~((lib9p_dm_t)0777)) & (UINT32_C(1)<<18)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "SETGID");
+ empty = false;
+ }
+ if ((*self & ~((lib9p_dm_t)0777)) & (UINT32_C(1)<<17)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "1<<17");
+ empty = false;
+ }
+ if ((*self & ~((lib9p_dm_t)0777)) & (UINT32_C(1)<<16)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "1<<16");
+ empty = false;
+ }
+ if ((*self & ~((lib9p_dm_t)0777)) & (UINT32_C(1)<<15)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "1<<15");
+ empty = false;
+ }
+ if ((*self & ~((lib9p_dm_t)0777)) & (UINT32_C(1)<<14)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "1<<14");
+ empty = false;
+ }
+ if ((*self & ~((lib9p_dm_t)0777)) & (UINT32_C(1)<<13)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "1<<13");
+ empty = false;
+ }
+ if ((*self & ~((lib9p_dm_t)0777)) & (UINT32_C(1)<<12)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "1<<12");
+ empty = false;
+ }
+ if ((*self & ~((lib9p_dm_t)0777)) & (UINT32_C(1)<<11)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "1<<11");
+ empty = false;
+ }
+ if ((*self & ~((lib9p_dm_t)0777)) & (UINT32_C(1)<<10)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "1<<10");
+ empty = false;
+ }
+ if ((*self & ~((lib9p_dm_t)0777)) & (UINT32_C(1)<<9)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "1<<9");
+ empty = false;
+ }
+ if ((*self & ~((lib9p_dm_t)0777)) & (UINT32_C(1)<<8)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "OWNER_R");
+ empty = false;
+ }
+ if ((*self & ~((lib9p_dm_t)0777)) & (UINT32_C(1)<<7)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "OWNER_W");
+ empty = false;
+ }
+ if ((*self & ~((lib9p_dm_t)0777)) & (UINT32_C(1)<<6)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "OWNER_X");
+ empty = false;
+ }
+ if ((*self & ~((lib9p_dm_t)0777)) & (UINT32_C(1)<<5)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "GROUP_R");
+ empty = false;
+ }
+ if ((*self & ~((lib9p_dm_t)0777)) & (UINT32_C(1)<<4)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "GROUP_W");
+ empty = false;
+ }
+ if ((*self & ~((lib9p_dm_t)0777)) & (UINT32_C(1)<<3)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "GROUP_X");
+ empty = false;
+ }
+ if ((*self & ~((lib9p_dm_t)0777)) & (UINT32_C(1)<<2)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "OTHER_R");
+ empty = false;
+ }
+ if ((*self & ~((lib9p_dm_t)0777)) & (UINT32_C(1)<<1)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "OTHER_W");
+ empty = false;
+ }
+ if ((*self & ~((lib9p_dm_t)0777)) & (UINT32_C(1)<<0)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "OTHER_X");
+ empty = false;
+ }
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_printf(state, "%#04"PRIo32, *self & 0777);
+ fmt_state_putchar(state, ')');
+}
+
+#endif /* CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u */
+#if CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u
+static void lib9p_qt_format(lib9p_qt_t *self, struct fmt_state *state) {
+ bool empty = true;
+ fmt_state_putchar(state, '(');
+ if (*self & (UINT8_C(1)<<7)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "DIR");
+ empty = false;
+ }
+ if (*self & (UINT8_C(1)<<6)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "APPEND");
+ empty = false;
+ }
+ if (*self & (UINT8_C(1)<<5)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "EXCL");
+ empty = false;
+ }
+ if (*self & (UINT8_C(1)<<4)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "_PLAN9_MOUNT");
+ empty = false;
+ }
+ if (*self & (UINT8_C(1)<<3)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "AUTH");
+ empty = false;
+ }
+ if (*self & (UINT8_C(1)<<2)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "TMP");
+ empty = false;
+ }
+ if (*self & (UINT8_C(1)<<1)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "SYMLINK");
+ empty = false;
+ }
+ if (*self & (UINT8_C(1)<<0)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "1<<0");
+ empty = false;
+ }
+ if (empty)
+ fmt_state_putchar(state, '0');
+ fmt_state_putchar(state, ')');
+}
+
+static void lib9p_qid_format(struct lib9p_qid *self, struct fmt_state *state) {
+ fmt_state_putchar(state, '{');
+ fmt_state_puts(state, " type=");
+ lib9p_qt_format(&self->type, state);
+ fmt_state_puts(state, " vers=");
+ fmt_state_printf(state, "%"PRIu32, self->vers);
+ fmt_state_puts(state, " path=");
+ fmt_state_printf(state, "%"PRIu64, self->path);
+ fmt_state_puts(state, " }");
+}
+
+#endif /* CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u */
+#if CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u
+static void lib9p_stat_format(struct lib9p_stat *self, struct fmt_state *state) {
+ fmt_state_putchar(state, '{');
+ fmt_state_puts(state, " kern_type=");
+ fmt_state_printf(state, "%"PRIu16, self->kern_type);
+ fmt_state_puts(state, " kern_dev=");
+ fmt_state_printf(state, "%"PRIu32, self->kern_dev);
+ fmt_state_puts(state, " file_qid=");
+ lib9p_qid_format(&self->file_qid, state);
+ fmt_state_puts(state, " file_mode=");
+ lib9p_dm_format(&self->file_mode, state);
+ fmt_state_puts(state, " file_atime=");
+ fmt_state_printf(state, "%"PRIu32, self->file_atime);
+ fmt_state_puts(state, " file_mtime=");
+ fmt_state_printf(state, "%"PRIu32, self->file_mtime);
+ fmt_state_puts(state, " file_size=");
+ fmt_state_printf(state, "%"PRIu64, self->file_size);
+ fmt_state_puts(state, " file_name=");
+ lib9p_s_format(&self->file_name, state);
+ fmt_state_puts(state, " file_owner_uid=");
+ lib9p_s_format(&self->file_owner_uid, state);
+ fmt_state_puts(state, " file_owner_gid=");
+ lib9p_s_format(&self->file_owner_gid, state);
+ fmt_state_puts(state, " file_last_modified_uid=");
+ lib9p_s_format(&self->file_last_modified_uid, state);
+#if CONFIG_9P_ENABLE_9P2000_u
+ fmt_state_puts(state, " file_extension=");
+ lib9p_s_format(&self->file_extension, state);
+ fmt_state_puts(state, " file_owner_n_uid=");
+ lib9p_nuid_format(&self->file_owner_n_uid, state);
+ fmt_state_puts(state, " file_owner_n_gid=");
+ lib9p_nuid_format(&self->file_owner_n_gid, state);
+ fmt_state_puts(state, " file_last_modified_n_uid=");
+ lib9p_nuid_format(&self->file_last_modified_n_uid, state);
+#endif /* CONFIG_9P_ENABLE_9P2000_u */
+ fmt_state_puts(state, " }");
+}
+
+static void lib9p_o_format(lib9p_o_t *self, struct fmt_state *state) {
+ bool empty = true;
+ fmt_state_putchar(state, '(');
+ if (*self & (UINT8_C(1)<<7)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "1<<7");
+ empty = false;
+ }
+ if (*self & (UINT8_C(1)<<6)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "RCLOSE");
+ empty = false;
+ }
+ if (*self & (UINT8_C(1)<<5)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "CEXEC");
+ empty = false;
+ }
+ if (*self & (UINT8_C(1)<<4)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "TRUNC");
+ empty = false;
+ }
+ if (*self & (UINT8_C(1)<<3)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "1<<3");
+ empty = false;
+ }
+ if (*self & (UINT8_C(1)<<2)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "1<<2");
+ empty = false;
+ }
+ switch (*self & LIB9P_O_MODE_MASK) {
+ case LIB9P_O_MODE_READ:
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "MODE_READ");
+ empty = false;
+ break;
+ case LIB9P_O_MODE_WRITE:
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "MODE_WRITE");
+ empty = false;
+ break;
+ case LIB9P_O_MODE_RDWR:
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "MODE_RDWR");
+ empty = false;
+ break;
+ case LIB9P_O_MODE_EXEC:
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "MODE_EXEC");
+ empty = false;
+ break;
+ default:
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_printf(state, "%"PRIu8, *self & LIB9P_O_MODE_MASK);
+ empty = false;
+ }
+ if (empty)
+ fmt_state_putchar(state, '0');
+ fmt_state_putchar(state, ')');
+}
+
+#endif /* CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u */
+#if CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u
+static void lib9p_msg_Tversion_format(struct lib9p_msg_Tversion *self, struct fmt_state *state) {
+ fmt_state_puts(state, "Tversion {");
+ fmt_state_puts(state, " tag=");
+ lib9p_tag_format(&self->tag, state);
+ fmt_state_puts(state, " max_msg_size=");
+ fmt_state_printf(state, "%"PRIu32, self->max_msg_size);
+ fmt_state_puts(state, " version=");
+ lib9p_s_format(&self->version, state);
+ fmt_state_puts(state, " }");
+}
+
+static void lib9p_msg_Rversion_format(struct lib9p_msg_Rversion *self, struct fmt_state *state) {
+ fmt_state_puts(state, "Rversion {");
+ fmt_state_puts(state, " tag=");
+ lib9p_tag_format(&self->tag, state);
+ fmt_state_puts(state, " max_msg_size=");
+ fmt_state_printf(state, "%"PRIu32, self->max_msg_size);
+ fmt_state_puts(state, " version=");
+ lib9p_s_format(&self->version, state);
+ fmt_state_puts(state, " }");
+}
+
+static void lib9p_msg_Tauth_format(struct lib9p_msg_Tauth *self, struct fmt_state *state) {
+ fmt_state_puts(state, "Tauth {");
+ fmt_state_puts(state, " tag=");
+ lib9p_tag_format(&self->tag, state);
+ fmt_state_puts(state, " afid=");
+ lib9p_fid_format(&self->afid, state);
+ fmt_state_puts(state, " uname=");
+ lib9p_s_format(&self->uname, state);
+ fmt_state_puts(state, " aname=");
+ lib9p_s_format(&self->aname, state);
+#if CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_u
+ fmt_state_puts(state, " n_uid=");
+ lib9p_nuid_format(&self->n_uid, state);
+#endif /* CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_u */
+ fmt_state_puts(state, " }");
+}
+
+static void lib9p_msg_Rauth_format(struct lib9p_msg_Rauth *self, struct fmt_state *state) {
+ fmt_state_puts(state, "Rauth {");
+ fmt_state_puts(state, " tag=");
+ lib9p_tag_format(&self->tag, state);
+ fmt_state_puts(state, " aqid=");
+ lib9p_qid_format(&self->aqid, state);
+ fmt_state_puts(state, " }");
+}
+
+static void lib9p_msg_Tattach_format(struct lib9p_msg_Tattach *self, struct fmt_state *state) {
+ fmt_state_puts(state, "Tattach {");
+ fmt_state_puts(state, " tag=");
+ lib9p_tag_format(&self->tag, state);
+ fmt_state_puts(state, " fid=");
+ lib9p_fid_format(&self->fid, state);
+ fmt_state_puts(state, " afid=");
+ lib9p_fid_format(&self->afid, state);
+ fmt_state_puts(state, " uname=");
+ lib9p_s_format(&self->uname, state);
+ fmt_state_puts(state, " aname=");
+ lib9p_s_format(&self->aname, state);
+#if CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_u
+ fmt_state_puts(state, " n_uid=");
+ lib9p_nuid_format(&self->n_uid, state);
+#endif /* CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_u */
+ fmt_state_puts(state, " }");
+}
+
+static void lib9p_msg_Rattach_format(struct lib9p_msg_Rattach *self, struct fmt_state *state) {
+ fmt_state_puts(state, "Rattach {");
+ fmt_state_puts(state, " tag=");
+ lib9p_tag_format(&self->tag, state);
+ fmt_state_puts(state, " qid=");
+ lib9p_qid_format(&self->qid, state);
+ fmt_state_puts(state, " }");
+}
+
+static void lib9p_msg_Rerror_format(struct lib9p_msg_Rerror *self, struct fmt_state *state) {
+ fmt_state_puts(state, "Rerror {");
+ fmt_state_puts(state, " tag=");
+ lib9p_tag_format(&self->tag, state);
+ fmt_state_puts(state, " ename=");
+ lib9p_s_format(&self->ename, state);
+#if CONFIG_9P_ENABLE_9P2000_u
+ fmt_state_puts(state, " errno=");
+ lib9p_errno_format(&self->errno, state);
+#endif /* CONFIG_9P_ENABLE_9P2000_u */
+ fmt_state_puts(state, " }");
+}
+
+static void lib9p_msg_Tflush_format(struct lib9p_msg_Tflush *self, struct fmt_state *state) {
+ fmt_state_puts(state, "Tflush {");
+ fmt_state_puts(state, " tag=");
+ lib9p_tag_format(&self->tag, state);
+ fmt_state_puts(state, " oldtag=");
+ fmt_state_printf(state, "%"PRIu16, self->oldtag);
+ fmt_state_puts(state, " }");
+}
+
+static void lib9p_msg_Rflush_format(struct lib9p_msg_Rflush *self, struct fmt_state *state) {
+ fmt_state_puts(state, "Rflush {");
+ fmt_state_puts(state, " tag=");
+ lib9p_tag_format(&self->tag, state);
+ fmt_state_puts(state, " }");
+}
+
+static void lib9p_msg_Twalk_format(struct lib9p_msg_Twalk *self, struct fmt_state *state) {
+ fmt_state_puts(state, "Twalk {");
+ fmt_state_puts(state, " tag=");
+ lib9p_tag_format(&self->tag, state);
+ fmt_state_puts(state, " fid=");
+ lib9p_fid_format(&self->fid, state);
+ fmt_state_puts(state, " newfid=");
+ lib9p_fid_format(&self->newfid, state);
+ fmt_state_puts(state, " nwname=");
+ fmt_state_printf(state, "%"PRIu16, self->nwname);
+ fmt_state_puts(state, " wname=[");
+ for (uint16_t i = 0; i < self->nwname; i++) {
+ if (i)
+ fmt_state_puts(state, ", ");
+ lib9p_s_format(&self->wname[i], state);
+ }
+ fmt_state_puts(state, " ]");
+ fmt_state_puts(state, " }");
+}
+
+static void lib9p_msg_Rwalk_format(struct lib9p_msg_Rwalk *self, struct fmt_state *state) {
+ fmt_state_puts(state, "Rwalk {");
+ fmt_state_puts(state, " tag=");
+ lib9p_tag_format(&self->tag, state);
+ fmt_state_puts(state, " nwqid=");
+ fmt_state_printf(state, "%"PRIu16, self->nwqid);
+ fmt_state_puts(state, " wqid=[");
+ for (uint16_t i = 0; i < self->nwqid; i++) {
+ if (i)
+ fmt_state_puts(state, ", ");
+ lib9p_qid_format(&self->wqid[i], state);
+ }
+ fmt_state_puts(state, " ]");
+ fmt_state_puts(state, " }");
+}
+
+#endif /* CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u */
+#if CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u
+static void lib9p_msg_Topen_format(struct lib9p_msg_Topen *self, struct fmt_state *state) {
+ fmt_state_puts(state, "Topen {");
+ fmt_state_puts(state, " tag=");
+ lib9p_tag_format(&self->tag, state);
+ fmt_state_puts(state, " fid=");
+ lib9p_fid_format(&self->fid, state);
+ fmt_state_puts(state, " mode=");
+ lib9p_o_format(&self->mode, state);
+ fmt_state_puts(state, " }");
+}
+
+static void lib9p_msg_Ropen_format(struct lib9p_msg_Ropen *self, struct fmt_state *state) {
+ fmt_state_puts(state, "Ropen {");
+ fmt_state_puts(state, " tag=");
+ lib9p_tag_format(&self->tag, state);
+ fmt_state_puts(state, " qid=");
+ lib9p_qid_format(&self->qid, state);
+ fmt_state_puts(state, " iounit=");
+ fmt_state_printf(state, "%"PRIu32, self->iounit);
+ fmt_state_puts(state, " }");
+}
+
+static void lib9p_msg_Tcreate_format(struct lib9p_msg_Tcreate *self, struct fmt_state *state) {
+ fmt_state_puts(state, "Tcreate {");
+ fmt_state_puts(state, " tag=");
+ lib9p_tag_format(&self->tag, state);
+ fmt_state_puts(state, " fid=");
+ lib9p_fid_format(&self->fid, state);
+ fmt_state_puts(state, " name=");
+ lib9p_s_format(&self->name, state);
+ fmt_state_puts(state, " perm=");
+ lib9p_dm_format(&self->perm, state);
+ fmt_state_puts(state, " mode=");
+ lib9p_o_format(&self->mode, state);
+ fmt_state_puts(state, " }");
+}
+
+static void lib9p_msg_Rcreate_format(struct lib9p_msg_Rcreate *self, struct fmt_state *state) {
+ fmt_state_puts(state, "Rcreate {");
+ fmt_state_puts(state, " tag=");
+ lib9p_tag_format(&self->tag, state);
+ fmt_state_puts(state, " qid=");
+ lib9p_qid_format(&self->qid, state);
+ fmt_state_puts(state, " iounit=");
+ fmt_state_printf(state, "%"PRIu32, self->iounit);
+ fmt_state_puts(state, " }");
+}
+
+#endif /* CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u */
+#if CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u
+static void lib9p_msg_Tread_format(struct lib9p_msg_Tread *self, struct fmt_state *state) {
+ fmt_state_puts(state, "Tread {");
+ fmt_state_puts(state, " tag=");
+ lib9p_tag_format(&self->tag, state);
+ fmt_state_puts(state, " fid=");
+ lib9p_fid_format(&self->fid, state);
+ fmt_state_puts(state, " offset=");
+ fmt_state_printf(state, "%"PRIu64, self->offset);
+ fmt_state_puts(state, " count=");
+ fmt_state_printf(state, "%"PRIu32, self->count);
+ fmt_state_puts(state, " }");
+}
+
+static void lib9p_msg_Rread_format(struct lib9p_msg_Rread *self, struct fmt_state *state) {
+ fmt_state_puts(state, "Rread {");
+ fmt_state_puts(state, " tag=");
+ lib9p_tag_format(&self->tag, state);
+ fmt_state_puts(state, " count=");
+ fmt_state_printf(state, "%"PRIu32, self->count);
+ fmt_state_puts(state, " data=<bytedata>");
+ fmt_state_puts(state, " }");
+}
+
+static void lib9p_msg_Twrite_format(struct lib9p_msg_Twrite *self, struct fmt_state *state) {
+ fmt_state_puts(state, "Twrite {");
+ fmt_state_puts(state, " tag=");
+ lib9p_tag_format(&self->tag, state);
+ fmt_state_puts(state, " fid=");
+ lib9p_fid_format(&self->fid, state);
+ fmt_state_puts(state, " offset=");
+ fmt_state_printf(state, "%"PRIu64, self->offset);
+ fmt_state_puts(state, " count=");
+ fmt_state_printf(state, "%"PRIu32, self->count);
+ fmt_state_puts(state, " data=<bytedata>");
+ fmt_state_puts(state, " }");
+}
+
+static void lib9p_msg_Rwrite_format(struct lib9p_msg_Rwrite *self, struct fmt_state *state) {
+ fmt_state_puts(state, "Rwrite {");
+ fmt_state_puts(state, " tag=");
+ lib9p_tag_format(&self->tag, state);
+ fmt_state_puts(state, " count=");
+ fmt_state_printf(state, "%"PRIu32, self->count);
+ fmt_state_puts(state, " }");
+}
+
+static void lib9p_msg_Tclunk_format(struct lib9p_msg_Tclunk *self, struct fmt_state *state) {
+ fmt_state_puts(state, "Tclunk {");
+ fmt_state_puts(state, " tag=");
+ lib9p_tag_format(&self->tag, state);
+ fmt_state_puts(state, " fid=");
+ lib9p_fid_format(&self->fid, state);
+ fmt_state_puts(state, " }");
+}
+
+static void lib9p_msg_Rclunk_format(struct lib9p_msg_Rclunk *self, struct fmt_state *state) {
+ fmt_state_puts(state, "Rclunk {");
+ fmt_state_puts(state, " tag=");
+ lib9p_tag_format(&self->tag, state);
+ fmt_state_puts(state, " }");
+}
+
+static void lib9p_msg_Tremove_format(struct lib9p_msg_Tremove *self, struct fmt_state *state) {
+ fmt_state_puts(state, "Tremove {");
+ fmt_state_puts(state, " tag=");
+ lib9p_tag_format(&self->tag, state);
+ fmt_state_puts(state, " fid=");
+ lib9p_fid_format(&self->fid, state);
+ fmt_state_puts(state, " }");
+}
+
+static void lib9p_msg_Rremove_format(struct lib9p_msg_Rremove *self, struct fmt_state *state) {
+ fmt_state_puts(state, "Rremove {");
+ fmt_state_puts(state, " tag=");
+ lib9p_tag_format(&self->tag, state);
+ fmt_state_puts(state, " }");
+}
+
+#endif /* CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u */
+#if CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u
+static void lib9p_msg_Tstat_format(struct lib9p_msg_Tstat *self, struct fmt_state *state) {
+ fmt_state_puts(state, "Tstat {");
+ fmt_state_puts(state, " tag=");
+ lib9p_tag_format(&self->tag, state);
+ fmt_state_puts(state, " fid=");
+ lib9p_fid_format(&self->fid, state);
+ fmt_state_puts(state, " }");
+}
+
+static void lib9p_msg_Rstat_format(struct lib9p_msg_Rstat *self, struct fmt_state *state) {
+ fmt_state_puts(state, "Rstat {");
+ fmt_state_puts(state, " tag=");
+ lib9p_tag_format(&self->tag, state);
+ fmt_state_puts(state, " stat=");
+ lib9p_stat_format(&self->stat, state);
+ fmt_state_puts(state, " }");
+}
+
+static void lib9p_msg_Twstat_format(struct lib9p_msg_Twstat *self, struct fmt_state *state) {
+ fmt_state_puts(state, "Twstat {");
+ fmt_state_puts(state, " tag=");
+ lib9p_tag_format(&self->tag, state);
+ fmt_state_puts(state, " fid=");
+ lib9p_fid_format(&self->fid, state);
+ fmt_state_puts(state, " stat=");
+ lib9p_stat_format(&self->stat, state);
+ fmt_state_puts(state, " }");
+}
+
+static void lib9p_msg_Rwstat_format(struct lib9p_msg_Rwstat *self, struct fmt_state *state) {
+ fmt_state_puts(state, "Rwstat {");
+ fmt_state_puts(state, " tag=");
+ lib9p_tag_format(&self->tag, state);
+ fmt_state_puts(state, " }");
+}
+
+#endif /* CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u */
+#if CONFIG_9P_ENABLE_9P2000_p9p
+static void lib9p_msg_Topenfd_format(struct lib9p_msg_Topenfd *self, struct fmt_state *state) {
+ fmt_state_puts(state, "Topenfd {");
+ fmt_state_puts(state, " tag=");
+ lib9p_tag_format(&self->tag, state);
+ fmt_state_puts(state, " fid=");
+ lib9p_fid_format(&self->fid, state);
+ fmt_state_puts(state, " mode=");
+ lib9p_o_format(&self->mode, state);
+ fmt_state_puts(state, " }");
+}
+
+static void lib9p_msg_Ropenfd_format(struct lib9p_msg_Ropenfd *self, struct fmt_state *state) {
+ fmt_state_puts(state, "Ropenfd {");
+ fmt_state_puts(state, " tag=");
+ lib9p_tag_format(&self->tag, state);
+ fmt_state_puts(state, " qid=");
+ lib9p_qid_format(&self->qid, state);
+ fmt_state_puts(state, " iounit=");
+ fmt_state_printf(state, "%"PRIu32, self->iounit);
+ fmt_state_puts(state, " unixfd=");
+ fmt_state_printf(state, "%"PRIu32, self->unixfd);
+ fmt_state_puts(state, " }");
+}
+
+#endif /* CONFIG_9P_ENABLE_9P2000_p9p */
+#if CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_u
+static void lib9p_nuid_format(lib9p_nuid_t *self, struct fmt_state *state) {
+ switch (*self) {
+ case LIB9P_NUID_NONUID:
+ fmt_state_puts(state, "NONUID");
+ break;
+ default:
+ fmt_state_printf(state, "%"PRIu32, *self);
+ }
+}
+
+static void lib9p_errno_format(lib9p_errno_t *self, struct fmt_state *state) {
+ switch (*self) {
+ case LIB9P_ERRNO_NOERROR:
+ fmt_state_puts(state, "NOERROR");
+ break;
+ default:
+ fmt_state_printf(state, "%"PRIu32, *self);
+ }
+}
+
+#endif /* CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_u */
+#if CONFIG_9P_ENABLE_9P2000_L
+static void lib9p_super_magic_format(lib9p_super_magic_t *self, struct fmt_state *state) {
+ switch (*self) {
+ case LIB9P_SUPER_MAGIC_V9FS_MAGIC:
+ fmt_state_puts(state, "V9FS_MAGIC");
+ break;
+ default:
+ fmt_state_printf(state, "%"PRIu32, *self);
+ }
+}
+
+static void lib9p_lo_format(lib9p_lo_t *self, struct fmt_state *state) {
+ bool empty = true;
+ fmt_state_putchar(state, '(');
+ if (*self & (UINT32_C(1)<<31)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "1<<31");
+ empty = false;
+ }
+ if (*self & (UINT32_C(1)<<30)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "1<<30");
+ empty = false;
+ }
+ if (*self & (UINT32_C(1)<<29)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "1<<29");
+ empty = false;
+ }
+ if (*self & (UINT32_C(1)<<28)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "1<<28");
+ empty = false;
+ }
+ if (*self & (UINT32_C(1)<<27)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "1<<27");
+ empty = false;
+ }
+ if (*self & (UINT32_C(1)<<26)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "1<<26");
+ empty = false;
+ }
+ if (*self & (UINT32_C(1)<<25)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "1<<25");
+ empty = false;
+ }
+ if (*self & (UINT32_C(1)<<24)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "1<<24");
+ empty = false;
+ }
+ if (*self & (UINT32_C(1)<<23)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "1<<23");
+ empty = false;
+ }
+ if (*self & (UINT32_C(1)<<22)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "1<<22");
+ empty = false;
+ }
+ if (*self & (UINT32_C(1)<<21)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "1<<21");
+ empty = false;
+ }
+ if (*self & (UINT32_C(1)<<20)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "SYNC");
+ empty = false;
+ }
+ if (*self & (UINT32_C(1)<<19)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "CLOEXEC");
+ empty = false;
+ }
+ if (*self & (UINT32_C(1)<<18)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "NOATIME");
+ empty = false;
+ }
+ if (*self & (UINT32_C(1)<<17)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "NOFOLLOW");
+ empty = false;
+ }
+ if (*self & (UINT32_C(1)<<16)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "DIRECTORY");
+ empty = false;
+ }
+ if (*self & (UINT32_C(1)<<15)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "LARGEFILE");
+ empty = false;
+ }
+ if (*self & (UINT32_C(1)<<14)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "DIRECT");
+ empty = false;
+ }
+ if (*self & (UINT32_C(1)<<13)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "BSD_FASYNC");
+ empty = false;
+ }
+ if (*self & (UINT32_C(1)<<12)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "DSYNC");
+ empty = false;
+ }
+ if (*self & (UINT32_C(1)<<11)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "NONBLOCK");
+ empty = false;
+ }
+ if (*self & (UINT32_C(1)<<10)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "APPEND");
+ empty = false;
+ }
+ if (*self & (UINT32_C(1)<<9)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "TRUNC");
+ empty = false;
+ }
+ if (*self & (UINT32_C(1)<<8)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "NOCTTY");
+ empty = false;
+ }
+ if (*self & (UINT32_C(1)<<7)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "EXCL");
+ empty = false;
+ }
+ if (*self & (UINT32_C(1)<<6)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "CREATE");
+ empty = false;
+ }
+ if (*self & (UINT32_C(1)<<5)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "1<<5");
+ empty = false;
+ }
+ if (*self & (UINT32_C(1)<<4)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "1<<4");
+ empty = false;
+ }
+ if (*self & (UINT32_C(1)<<3)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "1<<3");
+ empty = false;
+ }
+ if (*self & (UINT32_C(1)<<2)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "1<<2");
+ empty = false;
+ }
+ switch (*self & LIB9P_LO_MODE_MASK) {
+ case LIB9P_LO_MODE_RDONLY:
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "MODE_RDONLY");
+ empty = false;
+ break;
+ case LIB9P_LO_MODE_WRONLY:
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "MODE_WRONLY");
+ empty = false;
+ break;
+ case LIB9P_LO_MODE_RDWR:
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "MODE_RDWR");
+ empty = false;
+ break;
+ case LIB9P_LO_MODE_NOACCESS:
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "MODE_NOACCESS");
+ empty = false;
+ break;
+ default:
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_printf(state, "%"PRIu32, *self & LIB9P_LO_MODE_MASK);
+ empty = false;
+ }
+ if (empty)
+ fmt_state_putchar(state, '0');
+ fmt_state_putchar(state, ')');
+}
+
+static void lib9p_dt_format(lib9p_dt_t *self, struct fmt_state *state) {
+ switch (*self) {
+ case LIB9P_DT_UNKNOWN:
+ fmt_state_puts(state, "UNKNOWN");
+ break;
+ case LIB9P_DT_PIPE:
+ fmt_state_puts(state, "PIPE");
+ break;
+ case LIB9P_DT_CHAR_DEV:
+ fmt_state_puts(state, "CHAR_DEV");
+ break;
+ case LIB9P_DT_DIRECTORY:
+ fmt_state_puts(state, "DIRECTORY");
+ break;
+ case LIB9P_DT_BLOCK_DEV:
+ fmt_state_puts(state, "BLOCK_DEV");
+ break;
+ case LIB9P_DT_REGULAR:
+ fmt_state_puts(state, "REGULAR");
+ break;
+ case LIB9P_DT_SYMLINK:
+ fmt_state_puts(state, "SYMLINK");
+ break;
+ case LIB9P_DT_SOCKET:
+ fmt_state_puts(state, "SOCKET");
+ break;
+ case _LIB9P_DT_WHITEOUT:
+ fmt_state_puts(state, "_WHITEOUT");
+ break;
+ default:
+ fmt_state_printf(state, "%"PRIu8, *self);
+ }
+}
+
+static void lib9p_mode_format(lib9p_mode_t *self, struct fmt_state *state) {
+ bool empty = true;
+ fmt_state_putchar(state, '(');
+ if (*self & (UINT32_C(1)<<31)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "1<<31");
+ empty = false;
+ }
+ if (*self & (UINT32_C(1)<<30)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "1<<30");
+ empty = false;
+ }
+ if (*self & (UINT32_C(1)<<29)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "1<<29");
+ empty = false;
+ }
+ if (*self & (UINT32_C(1)<<28)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "1<<28");
+ empty = false;
+ }
+ if (*self & (UINT32_C(1)<<27)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "1<<27");
+ empty = false;
+ }
+ if (*self & (UINT32_C(1)<<26)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "1<<26");
+ empty = false;
+ }
+ if (*self & (UINT32_C(1)<<25)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "1<<25");
+ empty = false;
+ }
+ if (*self & (UINT32_C(1)<<24)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "1<<24");
+ empty = false;
+ }
+ if (*self & (UINT32_C(1)<<23)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "1<<23");
+ empty = false;
+ }
+ if (*self & (UINT32_C(1)<<22)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "1<<22");
+ empty = false;
+ }
+ if (*self & (UINT32_C(1)<<21)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "1<<21");
+ empty = false;
+ }
+ if (*self & (UINT32_C(1)<<20)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "1<<20");
+ empty = false;
+ }
+ if (*self & (UINT32_C(1)<<19)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "1<<19");
+ empty = false;
+ }
+ if (*self & (UINT32_C(1)<<18)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "1<<18");
+ empty = false;
+ }
+ if (*self & (UINT32_C(1)<<17)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "1<<17");
+ empty = false;
+ }
+ if (*self & (UINT32_C(1)<<16)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "1<<16");
+ empty = false;
+ }
+ switch (*self & LIB9P_MODE_FMT_MASK) {
+ case LIB9P_MODE_FMT_PIPE:
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "FMT_PIPE");
+ empty = false;
+ break;
+ case LIB9P_MODE_FMT_CHAR_DEV:
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "FMT_CHAR_DEV");
+ empty = false;
+ break;
+ case LIB9P_MODE_FMT_DIRECTORY:
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "FMT_DIRECTORY");
+ empty = false;
+ break;
+ case LIB9P_MODE_FMT_BLOCK_DEV:
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "FMT_BLOCK_DEV");
+ empty = false;
+ break;
+ case LIB9P_MODE_FMT_REGULAR:
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "FMT_REGULAR");
+ empty = false;
+ break;
+ case LIB9P_MODE_FMT_SYMLINK:
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "FMT_SYMLINK");
+ empty = false;
+ break;
+ case LIB9P_MODE_FMT_SOCKET:
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "FMT_SOCKET");
+ empty = false;
+ break;
+ default:
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_printf(state, "%"PRIu32, *self & LIB9P_MODE_FMT_MASK);
+ empty = false;
+ }
+ if (*self & (UINT32_C(1)<<11)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "PERM_SETGROUP");
+ empty = false;
+ }
+ if (*self & (UINT32_C(1)<<10)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "PERM_SETUSER");
+ empty = false;
+ }
+ if (*self & (UINT32_C(1)<<9)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "PERM_STICKY");
+ empty = false;
+ }
+ if (*self & (UINT32_C(1)<<8)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "PERM_OWNER_R");
+ empty = false;
+ }
+ if (*self & (UINT32_C(1)<<7)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "PERM_OWNER_W");
+ empty = false;
+ }
+ if (*self & (UINT32_C(1)<<6)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "PERM_OWNER_X");
+ empty = false;
+ }
+ if (*self & (UINT32_C(1)<<5)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "PERM_GROUP_R");
+ empty = false;
+ }
+ if (*self & (UINT32_C(1)<<4)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "PERM_GROUP_W");
+ empty = false;
+ }
+ if (*self & (UINT32_C(1)<<3)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "PERM_GROUP_X");
+ empty = false;
+ }
+ if (*self & (UINT32_C(1)<<2)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "PERM_OTHER_R");
+ empty = false;
+ }
+ if (*self & (UINT32_C(1)<<1)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "PERM_OTHER_W");
+ empty = false;
+ }
+ if (*self & (UINT32_C(1)<<0)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "PERM_OTHER_X");
+ empty = false;
+ }
+ if (empty)
+ fmt_state_putchar(state, '0');
+ fmt_state_putchar(state, ')');
+}
+
+static void lib9p_b4_format(lib9p_b4_t *self, struct fmt_state *state) {
+ switch (*self) {
+ case LIB9P_B4_FALSE:
+ fmt_state_puts(state, "FALSE");
+ break;
+ case LIB9P_B4_TRUE:
+ fmt_state_puts(state, "TRUE");
+ break;
+ default:
+ fmt_state_printf(state, "%"PRIu32, *self);
+ }
+}
+
+static void lib9p_getattr_format(lib9p_getattr_t *self, struct fmt_state *state) {
+ bool empty = true;
+ fmt_state_putchar(state, '(');
+ if (*self & (UINT64_C(1)<<63)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "1<<63");
+ empty = false;
+ }
+ if (*self & (UINT64_C(1)<<62)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "1<<62");
+ empty = false;
+ }
+ if (*self & (UINT64_C(1)<<61)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "1<<61");
+ empty = false;
+ }
+ if (*self & (UINT64_C(1)<<60)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "1<<60");
+ empty = false;
+ }
+ if (*self & (UINT64_C(1)<<59)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "1<<59");
+ empty = false;
+ }
+ if (*self & (UINT64_C(1)<<58)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "1<<58");
+ empty = false;
+ }
+ if (*self & (UINT64_C(1)<<57)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "1<<57");
+ empty = false;
+ }
+ if (*self & (UINT64_C(1)<<56)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "1<<56");
+ empty = false;
+ }
+ if (*self & (UINT64_C(1)<<55)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "1<<55");
+ empty = false;
+ }
+ if (*self & (UINT64_C(1)<<54)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "1<<54");
+ empty = false;
+ }
+ if (*self & (UINT64_C(1)<<53)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "1<<53");
+ empty = false;
+ }
+ if (*self & (UINT64_C(1)<<52)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "1<<52");
+ empty = false;
+ }
+ if (*self & (UINT64_C(1)<<51)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "1<<51");
+ empty = false;
+ }
+ if (*self & (UINT64_C(1)<<50)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "1<<50");
+ empty = false;
+ }
+ if (*self & (UINT64_C(1)<<49)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "1<<49");
+ empty = false;
+ }
+ if (*self & (UINT64_C(1)<<48)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "1<<48");
+ empty = false;
+ }
+ if (*self & (UINT64_C(1)<<47)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "1<<47");
+ empty = false;
+ }
+ if (*self & (UINT64_C(1)<<46)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "1<<46");
+ empty = false;
+ }
+ if (*self & (UINT64_C(1)<<45)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "1<<45");
+ empty = false;
+ }
+ if (*self & (UINT64_C(1)<<44)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "1<<44");
+ empty = false;
+ }
+ if (*self & (UINT64_C(1)<<43)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "1<<43");
+ empty = false;
+ }
+ if (*self & (UINT64_C(1)<<42)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "1<<42");
+ empty = false;
+ }
+ if (*self & (UINT64_C(1)<<41)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "1<<41");
+ empty = false;
+ }
+ if (*self & (UINT64_C(1)<<40)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "1<<40");
+ empty = false;
+ }
+ if (*self & (UINT64_C(1)<<39)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "1<<39");
+ empty = false;
+ }
+ if (*self & (UINT64_C(1)<<38)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "1<<38");
+ empty = false;
+ }
+ if (*self & (UINT64_C(1)<<37)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "1<<37");
+ empty = false;
+ }
+ if (*self & (UINT64_C(1)<<36)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "1<<36");
+ empty = false;
+ }
+ if (*self & (UINT64_C(1)<<35)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "1<<35");
+ empty = false;
+ }
+ if (*self & (UINT64_C(1)<<34)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "1<<34");
+ empty = false;
+ }
+ if (*self & (UINT64_C(1)<<33)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "1<<33");
+ empty = false;
+ }
+ if (*self & (UINT64_C(1)<<32)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "1<<32");
+ empty = false;
+ }
+ if (*self & (UINT64_C(1)<<31)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "1<<31");
+ empty = false;
+ }
+ if (*self & (UINT64_C(1)<<30)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "1<<30");
+ empty = false;
+ }
+ if (*self & (UINT64_C(1)<<29)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "1<<29");
+ empty = false;
+ }
+ if (*self & (UINT64_C(1)<<28)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "1<<28");
+ empty = false;
+ }
+ if (*self & (UINT64_C(1)<<27)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "1<<27");
+ empty = false;
+ }
+ if (*self & (UINT64_C(1)<<26)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "1<<26");
+ empty = false;
+ }
+ if (*self & (UINT64_C(1)<<25)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "1<<25");
+ empty = false;
+ }
+ if (*self & (UINT64_C(1)<<24)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "1<<24");
+ empty = false;
+ }
+ if (*self & (UINT64_C(1)<<23)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "1<<23");
+ empty = false;
+ }
+ if (*self & (UINT64_C(1)<<22)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "1<<22");
+ empty = false;
+ }
+ if (*self & (UINT64_C(1)<<21)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "1<<21");
+ empty = false;
+ }
+ if (*self & (UINT64_C(1)<<20)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "1<<20");
+ empty = false;
+ }
+ if (*self & (UINT64_C(1)<<19)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "1<<19");
+ empty = false;
+ }
+ if (*self & (UINT64_C(1)<<18)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "1<<18");
+ empty = false;
+ }
+ if (*self & (UINT64_C(1)<<17)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "1<<17");
+ empty = false;
+ }
+ if (*self & (UINT64_C(1)<<16)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "1<<16");
+ empty = false;
+ }
+ if (*self & (UINT64_C(1)<<15)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "1<<15");
+ empty = false;
+ }
+ if (*self & (UINT64_C(1)<<14)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "1<<14");
+ empty = false;
+ }
+ if (*self & (UINT64_C(1)<<13)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "DATA_VERSION");
+ empty = false;
+ }
+ if (*self & (UINT64_C(1)<<12)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "GEN");
+ empty = false;
+ }
+ if (*self & (UINT64_C(1)<<11)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "BTIME");
+ empty = false;
+ }
+ if (*self & (UINT64_C(1)<<10)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "BLOCKS");
+ empty = false;
+ }
+ if (*self & (UINT64_C(1)<<9)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "SIZE");
+ empty = false;
+ }
+ if (*self & (UINT64_C(1)<<8)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "INO");
+ empty = false;
+ }
+ if (*self & (UINT64_C(1)<<7)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "CTIME");
+ empty = false;
+ }
+ if (*self & (UINT64_C(1)<<6)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "MTIME");
+ empty = false;
+ }
+ if (*self & (UINT64_C(1)<<5)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "ATIME");
+ empty = false;
+ }
+ if (*self & (UINT64_C(1)<<4)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "RDEV");
+ empty = false;
+ }
+ if (*self & (UINT64_C(1)<<3)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "GID");
+ empty = false;
+ }
+ if (*self & (UINT64_C(1)<<2)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "UID");
+ empty = false;
+ }
+ if (*self & (UINT64_C(1)<<1)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "NLINK");
+ empty = false;
+ }
+ if (*self & (UINT64_C(1)<<0)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "MODE");
+ empty = false;
+ }
+ if (empty)
+ fmt_state_putchar(state, '0');
+ fmt_state_putchar(state, ')');
+}
+
+static void lib9p_setattr_format(lib9p_setattr_t *self, struct fmt_state *state) {
+ bool empty = true;
+ fmt_state_putchar(state, '(');
+ if (*self & (UINT32_C(1)<<31)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "1<<31");
+ empty = false;
+ }
+ if (*self & (UINT32_C(1)<<30)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "1<<30");
+ empty = false;
+ }
+ if (*self & (UINT32_C(1)<<29)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "1<<29");
+ empty = false;
+ }
+ if (*self & (UINT32_C(1)<<28)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "1<<28");
+ empty = false;
+ }
+ if (*self & (UINT32_C(1)<<27)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "1<<27");
+ empty = false;
+ }
+ if (*self & (UINT32_C(1)<<26)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "1<<26");
+ empty = false;
+ }
+ if (*self & (UINT32_C(1)<<25)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "1<<25");
+ empty = false;
+ }
+ if (*self & (UINT32_C(1)<<24)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "1<<24");
+ empty = false;
+ }
+ if (*self & (UINT32_C(1)<<23)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "1<<23");
+ empty = false;
+ }
+ if (*self & (UINT32_C(1)<<22)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "1<<22");
+ empty = false;
+ }
+ if (*self & (UINT32_C(1)<<21)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "1<<21");
+ empty = false;
+ }
+ if (*self & (UINT32_C(1)<<20)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "1<<20");
+ empty = false;
+ }
+ if (*self & (UINT32_C(1)<<19)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "1<<19");
+ empty = false;
+ }
+ if (*self & (UINT32_C(1)<<18)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "1<<18");
+ empty = false;
+ }
+ if (*self & (UINT32_C(1)<<17)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "1<<17");
+ empty = false;
+ }
+ if (*self & (UINT32_C(1)<<16)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "1<<16");
+ empty = false;
+ }
+ if (*self & (UINT32_C(1)<<15)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "1<<15");
+ empty = false;
+ }
+ if (*self & (UINT32_C(1)<<14)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "1<<14");
+ empty = false;
+ }
+ if (*self & (UINT32_C(1)<<13)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "1<<13");
+ empty = false;
+ }
+ if (*self & (UINT32_C(1)<<12)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "1<<12");
+ empty = false;
+ }
+ if (*self & (UINT32_C(1)<<11)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "1<<11");
+ empty = false;
+ }
+ if (*self & (UINT32_C(1)<<10)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "1<<10");
+ empty = false;
+ }
+ if (*self & (UINT32_C(1)<<9)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "1<<9");
+ empty = false;
+ }
+ if (*self & (UINT32_C(1)<<8)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "MTIME_SET");
+ empty = false;
+ }
+ if (*self & (UINT32_C(1)<<7)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "ATIME_SET");
+ empty = false;
+ }
+ if (*self & (UINT32_C(1)<<6)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "CTIME");
+ empty = false;
+ }
+ if (*self & (UINT32_C(1)<<5)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "MTIME");
+ empty = false;
+ }
+ if (*self & (UINT32_C(1)<<4)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "ATIME");
+ empty = false;
+ }
+ if (*self & (UINT32_C(1)<<3)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "SIZE");
+ empty = false;
+ }
+ if (*self & (UINT32_C(1)<<2)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "GID");
+ empty = false;
+ }
+ if (*self & (UINT32_C(1)<<1)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "UID");
+ empty = false;
+ }
+ if (*self & (UINT32_C(1)<<0)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "MODE");
+ empty = false;
+ }
+ if (empty)
+ fmt_state_putchar(state, '0');
+ fmt_state_putchar(state, ')');
+}
+
+static void lib9p_lock_type_format(lib9p_lock_type_t *self, struct fmt_state *state) {
+ switch (*self) {
+ case LIB9P_LOCK_TYPE_RDLCK:
+ fmt_state_puts(state, "RDLCK");
+ break;
+ case LIB9P_LOCK_TYPE_WRLCK:
+ fmt_state_puts(state, "WRLCK");
+ break;
+ case LIB9P_LOCK_TYPE_UNLCK:
+ fmt_state_puts(state, "UNLCK");
+ break;
+ default:
+ fmt_state_printf(state, "%"PRIu8, *self);
+ }
+}
+
+static void lib9p_lock_flags_format(lib9p_lock_flags_t *self, struct fmt_state *state) {
+ bool empty = true;
+ fmt_state_putchar(state, '(');
+ if (*self & (UINT32_C(1)<<31)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "1<<31");
+ empty = false;
+ }
+ if (*self & (UINT32_C(1)<<30)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "1<<30");
+ empty = false;
+ }
+ if (*self & (UINT32_C(1)<<29)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "1<<29");
+ empty = false;
+ }
+ if (*self & (UINT32_C(1)<<28)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "1<<28");
+ empty = false;
+ }
+ if (*self & (UINT32_C(1)<<27)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "1<<27");
+ empty = false;
+ }
+ if (*self & (UINT32_C(1)<<26)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "1<<26");
+ empty = false;
+ }
+ if (*self & (UINT32_C(1)<<25)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "1<<25");
+ empty = false;
+ }
+ if (*self & (UINT32_C(1)<<24)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "1<<24");
+ empty = false;
+ }
+ if (*self & (UINT32_C(1)<<23)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "1<<23");
+ empty = false;
+ }
+ if (*self & (UINT32_C(1)<<22)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "1<<22");
+ empty = false;
+ }
+ if (*self & (UINT32_C(1)<<21)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "1<<21");
+ empty = false;
+ }
+ if (*self & (UINT32_C(1)<<20)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "1<<20");
+ empty = false;
+ }
+ if (*self & (UINT32_C(1)<<19)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "1<<19");
+ empty = false;
+ }
+ if (*self & (UINT32_C(1)<<18)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "1<<18");
+ empty = false;
+ }
+ if (*self & (UINT32_C(1)<<17)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "1<<17");
+ empty = false;
+ }
+ if (*self & (UINT32_C(1)<<16)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "1<<16");
+ empty = false;
+ }
+ if (*self & (UINT32_C(1)<<15)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "1<<15");
+ empty = false;
+ }
+ if (*self & (UINT32_C(1)<<14)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "1<<14");
+ empty = false;
+ }
+ if (*self & (UINT32_C(1)<<13)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "1<<13");
+ empty = false;
+ }
+ if (*self & (UINT32_C(1)<<12)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "1<<12");
+ empty = false;
+ }
+ if (*self & (UINT32_C(1)<<11)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "1<<11");
+ empty = false;
+ }
+ if (*self & (UINT32_C(1)<<10)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "1<<10");
+ empty = false;
+ }
+ if (*self & (UINT32_C(1)<<9)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "1<<9");
+ empty = false;
+ }
+ if (*self & (UINT32_C(1)<<8)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "1<<8");
+ empty = false;
+ }
+ if (*self & (UINT32_C(1)<<7)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "1<<7");
+ empty = false;
+ }
+ if (*self & (UINT32_C(1)<<6)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "1<<6");
+ empty = false;
+ }
+ if (*self & (UINT32_C(1)<<5)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "1<<5");
+ empty = false;
+ }
+ if (*self & (UINT32_C(1)<<4)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "1<<4");
+ empty = false;
+ }
+ if (*self & (UINT32_C(1)<<3)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "1<<3");
+ empty = false;
+ }
+ if (*self & (UINT32_C(1)<<2)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "1<<2");
+ empty = false;
+ }
+ if (*self & (UINT32_C(1)<<1)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "RECLAIM");
+ empty = false;
+ }
+ if (*self & (UINT32_C(1)<<0)) {
+ if (!empty)
+ fmt_state_putchar(state, '|');
+ fmt_state_puts(state, "BLOCK");
+ empty = false;
+ }
+ if (empty)
+ fmt_state_putchar(state, '0');
+ fmt_state_putchar(state, ')');
+}
+
+static void lib9p_lock_status_format(lib9p_lock_status_t *self, struct fmt_state *state) {
+ switch (*self) {
+ case LIB9P_LOCK_STATUS_SUCCESS:
+ fmt_state_puts(state, "SUCCESS");
+ break;
+ case LIB9P_LOCK_STATUS_BLOCKED:
+ fmt_state_puts(state, "BLOCKED");
+ break;
+ case LIB9P_LOCK_STATUS_ERROR:
+ fmt_state_puts(state, "ERROR");
+ break;
+ case LIB9P_LOCK_STATUS_GRACE:
+ fmt_state_puts(state, "GRACE");
+ break;
+ default:
+ fmt_state_printf(state, "%"PRIu8, *self);
+ }
+}
+
+static void lib9p_msg_Rlerror_format(struct lib9p_msg_Rlerror *self, struct fmt_state *state) {
+ fmt_state_puts(state, "Rlerror {");
+ fmt_state_puts(state, " tag=");
+ lib9p_tag_format(&self->tag, state);
+ fmt_state_puts(state, " ecode=");
+ lib9p_errno_format(&self->ecode, state);
+ fmt_state_puts(state, " }");
+}
+
+static void lib9p_msg_Tstatfs_format(struct lib9p_msg_Tstatfs *self, struct fmt_state *state) {
+ fmt_state_puts(state, "Tstatfs {");
+ fmt_state_puts(state, " tag=");
+ lib9p_tag_format(&self->tag, state);
+ fmt_state_puts(state, " fid=");
+ lib9p_fid_format(&self->fid, state);
+ fmt_state_puts(state, " }");
+}
+
+static void lib9p_msg_Rstatfs_format(struct lib9p_msg_Rstatfs *self, struct fmt_state *state) {
+ fmt_state_puts(state, "Rstatfs {");
+ fmt_state_puts(state, " tag=");
+ lib9p_tag_format(&self->tag, state);
+ fmt_state_puts(state, " type=");
+ lib9p_super_magic_format(&self->type, state);
+ fmt_state_puts(state, " bsize=");
+ fmt_state_printf(state, "%"PRIu32, self->bsize);
+ fmt_state_puts(state, " blocks=");
+ fmt_state_printf(state, "%"PRIu64, self->blocks);
+ fmt_state_puts(state, " bfree=");
+ fmt_state_printf(state, "%"PRIu64, self->bfree);
+ fmt_state_puts(state, " bavail=");
+ fmt_state_printf(state, "%"PRIu64, self->bavail);
+ fmt_state_puts(state, " files=");
+ fmt_state_printf(state, "%"PRIu64, self->files);
+ fmt_state_puts(state, " ffree=");
+ fmt_state_printf(state, "%"PRIu64, self->ffree);
+ fmt_state_puts(state, " fsid=");
+ fmt_state_printf(state, "%"PRIu64, self->fsid);
+ fmt_state_puts(state, " namelen=");
+ fmt_state_printf(state, "%"PRIu32, self->namelen);
+ fmt_state_puts(state, " }");
+}
+
+static void lib9p_msg_Tlopen_format(struct lib9p_msg_Tlopen *self, struct fmt_state *state) {
+ fmt_state_puts(state, "Tlopen {");
+ fmt_state_puts(state, " tag=");
+ lib9p_tag_format(&self->tag, state);
+ fmt_state_puts(state, " fid=");
+ lib9p_fid_format(&self->fid, state);
+ fmt_state_puts(state, " flags=");
+ lib9p_lo_format(&self->flags, state);
+ fmt_state_puts(state, " }");
+}
+
+static void lib9p_msg_Rlopen_format(struct lib9p_msg_Rlopen *self, struct fmt_state *state) {
+ fmt_state_puts(state, "Rlopen {");
+ fmt_state_puts(state, " tag=");
+ lib9p_tag_format(&self->tag, state);
+ fmt_state_puts(state, " qid=");
+ lib9p_qid_format(&self->qid, state);
+ fmt_state_puts(state, " iounit=");
+ fmt_state_printf(state, "%"PRIu32, self->iounit);
+ fmt_state_puts(state, " }");
+}
+
+static void lib9p_msg_Tlcreate_format(struct lib9p_msg_Tlcreate *self, struct fmt_state *state) {
+ fmt_state_puts(state, "Tlcreate {");
+ fmt_state_puts(state, " tag=");
+ lib9p_tag_format(&self->tag, state);
+ fmt_state_puts(state, " fid=");
+ lib9p_fid_format(&self->fid, state);
+ fmt_state_puts(state, " name=");
+ lib9p_s_format(&self->name, state);
+ fmt_state_puts(state, " flags=");
+ lib9p_lo_format(&self->flags, state);
+ fmt_state_puts(state, " mode=");
+ lib9p_mode_format(&self->mode, state);
+ fmt_state_puts(state, " gid=");
+ lib9p_nuid_format(&self->gid, state);
+ fmt_state_puts(state, " }");
+}
+
+static void lib9p_msg_Rlcreate_format(struct lib9p_msg_Rlcreate *self, struct fmt_state *state) {
+ fmt_state_puts(state, "Rlcreate {");
+ fmt_state_puts(state, " tag=");
+ lib9p_tag_format(&self->tag, state);
+ fmt_state_puts(state, " qid=");
+ lib9p_qid_format(&self->qid, state);
+ fmt_state_puts(state, " iounit=");
+ fmt_state_printf(state, "%"PRIu32, self->iounit);
+ fmt_state_puts(state, " }");
+}
+
+static void lib9p_msg_Tsymlink_format(struct lib9p_msg_Tsymlink *self, struct fmt_state *state) {
+ fmt_state_puts(state, "Tsymlink {");
+ fmt_state_puts(state, " tag=");
+ lib9p_tag_format(&self->tag, state);
+ fmt_state_puts(state, " fid=");
+ lib9p_fid_format(&self->fid, state);
+ fmt_state_puts(state, " name=");
+ lib9p_s_format(&self->name, state);
+ fmt_state_puts(state, " symtgt=");
+ lib9p_s_format(&self->symtgt, state);
+ fmt_state_puts(state, " gid=");
+ lib9p_nuid_format(&self->gid, state);
+ fmt_state_puts(state, " }");
+}
+
+static void lib9p_msg_Rsymlink_format(struct lib9p_msg_Rsymlink *self, struct fmt_state *state) {
+ fmt_state_puts(state, "Rsymlink {");
+ fmt_state_puts(state, " tag=");
+ lib9p_tag_format(&self->tag, state);
+ fmt_state_puts(state, " qid=");
+ lib9p_qid_format(&self->qid, state);
+ fmt_state_puts(state, " }");
+}
+
+static void lib9p_msg_Tmknod_format(struct lib9p_msg_Tmknod *self, struct fmt_state *state) {
+ fmt_state_puts(state, "Tmknod {");
+ fmt_state_puts(state, " tag=");
+ lib9p_tag_format(&self->tag, state);
+ fmt_state_puts(state, " dfid=");
+ lib9p_fid_format(&self->dfid, state);
+ fmt_state_puts(state, " name=");
+ lib9p_s_format(&self->name, state);
+ fmt_state_puts(state, " mode=");
+ lib9p_mode_format(&self->mode, state);
+ fmt_state_puts(state, " major=");
+ fmt_state_printf(state, "%"PRIu32, self->major);
+ fmt_state_puts(state, " minor=");
+ fmt_state_printf(state, "%"PRIu32, self->minor);
+ fmt_state_puts(state, " gid=");
+ lib9p_nuid_format(&self->gid, state);
+ fmt_state_puts(state, " }");
+}
+
+static void lib9p_msg_Rmknod_format(struct lib9p_msg_Rmknod *self, struct fmt_state *state) {
+ fmt_state_puts(state, "Rmknod {");
+ fmt_state_puts(state, " tag=");
+ lib9p_tag_format(&self->tag, state);
+ fmt_state_puts(state, " qid=");
+ lib9p_qid_format(&self->qid, state);
+ fmt_state_puts(state, " }");
+}
+
+static void lib9p_msg_Trename_format(struct lib9p_msg_Trename *self, struct fmt_state *state) {
+ fmt_state_puts(state, "Trename {");
+ fmt_state_puts(state, " tag=");
+ lib9p_tag_format(&self->tag, state);
+ fmt_state_puts(state, " fid=");
+ lib9p_fid_format(&self->fid, state);
+ fmt_state_puts(state, " dfid=");
+ lib9p_fid_format(&self->dfid, state);
+ fmt_state_puts(state, " name=");
+ lib9p_s_format(&self->name, state);
+ fmt_state_puts(state, " }");
+}
+
+static void lib9p_msg_Rrename_format(struct lib9p_msg_Rrename *self, struct fmt_state *state) {
+ fmt_state_puts(state, "Rrename {");
+ fmt_state_puts(state, " tag=");
+ lib9p_tag_format(&self->tag, state);
+ fmt_state_puts(state, " }");
+}
+
+static void lib9p_msg_Treadlink_format(struct lib9p_msg_Treadlink *self, struct fmt_state *state) {
+ fmt_state_puts(state, "Treadlink {");
+ fmt_state_puts(state, " tag=");
+ lib9p_tag_format(&self->tag, state);
+ fmt_state_puts(state, " fid=");
+ lib9p_fid_format(&self->fid, state);
+ fmt_state_puts(state, " }");
+}
+
+static void lib9p_msg_Rreadlink_format(struct lib9p_msg_Rreadlink *self, struct fmt_state *state) {
+ fmt_state_puts(state, "Rreadlink {");
+ fmt_state_puts(state, " tag=");
+ lib9p_tag_format(&self->tag, state);
+ fmt_state_puts(state, " target=");
+ lib9p_s_format(&self->target, state);
+ fmt_state_puts(state, " }");
+}
+
+static void lib9p_msg_Tgetattr_format(struct lib9p_msg_Tgetattr *self, struct fmt_state *state) {
+ fmt_state_puts(state, "Tgetattr {");
+ fmt_state_puts(state, " tag=");
+ lib9p_tag_format(&self->tag, state);
+ fmt_state_puts(state, " fid=");
+ lib9p_fid_format(&self->fid, state);
+ fmt_state_puts(state, " request_mask=");
+ lib9p_getattr_format(&self->request_mask, state);
+ fmt_state_puts(state, " }");
+}
+
+static void lib9p_msg_Rgetattr_format(struct lib9p_msg_Rgetattr *self, struct fmt_state *state) {
+ fmt_state_puts(state, "Rgetattr {");
+ fmt_state_puts(state, " tag=");
+ lib9p_tag_format(&self->tag, state);
+ fmt_state_puts(state, " valid=");
+ lib9p_getattr_format(&self->valid, state);
+ fmt_state_puts(state, " qid=");
+ lib9p_qid_format(&self->qid, state);
+ fmt_state_puts(state, " mode=");
+ lib9p_mode_format(&self->mode, state);
+ fmt_state_puts(state, " uid=");
+ lib9p_nuid_format(&self->uid, state);
+ fmt_state_puts(state, " gid=");
+ lib9p_nuid_format(&self->gid, state);
+ fmt_state_puts(state, " nlink=");
+ fmt_state_printf(state, "%"PRIu64, self->nlink);
+ fmt_state_puts(state, " rdev=");
+ fmt_state_printf(state, "%"PRIu64, self->rdev);
+ fmt_state_puts(state, " filesize=");
+ fmt_state_printf(state, "%"PRIu64, self->filesize);
+ fmt_state_puts(state, " blksize=");
+ fmt_state_printf(state, "%"PRIu64, self->blksize);
+ fmt_state_puts(state, " blocks=");
+ fmt_state_printf(state, "%"PRIu64, self->blocks);
+ fmt_state_puts(state, " atime_sec=");
+ fmt_state_printf(state, "%"PRIu64, self->atime_sec);
+ fmt_state_puts(state, " atime_nsec=");
+ fmt_state_printf(state, "%"PRIu64, self->atime_nsec);
+ fmt_state_puts(state, " mtime_sec=");
+ fmt_state_printf(state, "%"PRIu64, self->mtime_sec);
+ fmt_state_puts(state, " mtime_nsec=");
+ fmt_state_printf(state, "%"PRIu64, self->mtime_nsec);
+ fmt_state_puts(state, " ctime_sec=");
+ fmt_state_printf(state, "%"PRIu64, self->ctime_sec);
+ fmt_state_puts(state, " ctime_nsec=");
+ fmt_state_printf(state, "%"PRIu64, self->ctime_nsec);
+ fmt_state_puts(state, " btime_sec=");
+ fmt_state_printf(state, "%"PRIu64, self->btime_sec);
+ fmt_state_puts(state, " btime_nsec=");
+ fmt_state_printf(state, "%"PRIu64, self->btime_nsec);
+ fmt_state_puts(state, " gen=");
+ fmt_state_printf(state, "%"PRIu64, self->gen);
+ fmt_state_puts(state, " data_version=");
+ fmt_state_printf(state, "%"PRIu64, self->data_version);
+ fmt_state_puts(state, " }");
+}
+
+static void lib9p_msg_Tsetattr_format(struct lib9p_msg_Tsetattr *self, struct fmt_state *state) {
+ fmt_state_puts(state, "Tsetattr {");
+ fmt_state_puts(state, " tag=");
+ lib9p_tag_format(&self->tag, state);
+ fmt_state_puts(state, " fid=");
+ lib9p_fid_format(&self->fid, state);
+ fmt_state_puts(state, " valid=");
+ lib9p_setattr_format(&self->valid, state);
+ fmt_state_puts(state, " mode=");
+ lib9p_mode_format(&self->mode, state);
+ fmt_state_puts(state, " uid=");
+ lib9p_nuid_format(&self->uid, state);
+ fmt_state_puts(state, " gid=");
+ lib9p_nuid_format(&self->gid, state);
+ fmt_state_puts(state, " filesize=");
+ fmt_state_printf(state, "%"PRIu64, self->filesize);
+ fmt_state_puts(state, " atime_sec=");
+ fmt_state_printf(state, "%"PRIu64, self->atime_sec);
+ fmt_state_puts(state, " atime_nsec=");
+ fmt_state_printf(state, "%"PRIu64, self->atime_nsec);
+ fmt_state_puts(state, " mtime_sec=");
+ fmt_state_printf(state, "%"PRIu64, self->mtime_sec);
+ fmt_state_puts(state, " mtime_nsec=");
+ fmt_state_printf(state, "%"PRIu64, self->mtime_nsec);
+ fmt_state_puts(state, " }");
+}
+
+static void lib9p_msg_Rsetattr_format(struct lib9p_msg_Rsetattr *self, struct fmt_state *state) {
+ fmt_state_puts(state, "Rsetattr {");
+ fmt_state_puts(state, " tag=");
+ lib9p_tag_format(&self->tag, state);
+ fmt_state_puts(state, " }");
+}
+
+static void lib9p_msg_Txattrwalk_format(struct lib9p_msg_Txattrwalk *self, struct fmt_state *state) {
+ fmt_state_puts(state, "Txattrwalk {");
+ fmt_state_puts(state, " tag=");
+ lib9p_tag_format(&self->tag, state);
+ fmt_state_puts(state, " fid=");
+ lib9p_fid_format(&self->fid, state);
+ fmt_state_puts(state, " newfid=");
+ lib9p_fid_format(&self->newfid, state);
+ fmt_state_puts(state, " name=");
+ lib9p_s_format(&self->name, state);
+ fmt_state_puts(state, " }");
+}
+
+static void lib9p_msg_Rxattrwalk_format(struct lib9p_msg_Rxattrwalk *self, struct fmt_state *state) {
+ fmt_state_puts(state, "Rxattrwalk {");
+ fmt_state_puts(state, " tag=");
+ lib9p_tag_format(&self->tag, state);
+ fmt_state_puts(state, " attr_size=");
+ fmt_state_printf(state, "%"PRIu64, self->attr_size);
+ fmt_state_puts(state, " }");
+}
+
+static void lib9p_msg_Txattrcreate_format(struct lib9p_msg_Txattrcreate *self, struct fmt_state *state) {
+ fmt_state_puts(state, "Txattrcreate {");
+ fmt_state_puts(state, " tag=");
+ lib9p_tag_format(&self->tag, state);
+ fmt_state_puts(state, " fid=");
+ lib9p_fid_format(&self->fid, state);
+ fmt_state_puts(state, " name=");
+ lib9p_s_format(&self->name, state);
+ fmt_state_puts(state, " attr_size=");
+ fmt_state_printf(state, "%"PRIu64, self->attr_size);
+ fmt_state_puts(state, " flags=");
+ fmt_state_printf(state, "%"PRIu32, self->flags);
+ fmt_state_puts(state, " }");
+}
+
+static void lib9p_msg_Rxattrcreate_format(struct lib9p_msg_Rxattrcreate *self, struct fmt_state *state) {
+ fmt_state_puts(state, "Rxattrcreate {");
+ fmt_state_puts(state, " tag=");
+ lib9p_tag_format(&self->tag, state);
+ fmt_state_puts(state, " }");
+}
+
+static void lib9p_msg_Treaddir_format(struct lib9p_msg_Treaddir *self, struct fmt_state *state) {
+ fmt_state_puts(state, "Treaddir {");
+ fmt_state_puts(state, " tag=");
+ lib9p_tag_format(&self->tag, state);
+ fmt_state_puts(state, " fid=");
+ lib9p_fid_format(&self->fid, state);
+ fmt_state_puts(state, " offset=");
+ fmt_state_printf(state, "%"PRIu64, self->offset);
+ fmt_state_puts(state, " count=");
+ fmt_state_printf(state, "%"PRIu32, self->count);
+ fmt_state_puts(state, " }");
+}
+
+static void lib9p_msg_Rreaddir_format(struct lib9p_msg_Rreaddir *self, struct fmt_state *state) {
+ fmt_state_puts(state, "Rreaddir {");
+ fmt_state_puts(state, " tag=");
+ lib9p_tag_format(&self->tag, state);
+ fmt_state_puts(state, " count=");
+ fmt_state_printf(state, "%"PRIu32, self->count);
+ fmt_state_puts(state, " data=<bytedata>");
+ fmt_state_puts(state, " }");
+}
+
+static void lib9p_msg_Tfsync_format(struct lib9p_msg_Tfsync *self, struct fmt_state *state) {
+ fmt_state_puts(state, "Tfsync {");
+ fmt_state_puts(state, " tag=");
+ lib9p_tag_format(&self->tag, state);
+ fmt_state_puts(state, " fid=");
+ lib9p_fid_format(&self->fid, state);
+ fmt_state_puts(state, " datasync=");
+ lib9p_b4_format(&self->datasync, state);
+ fmt_state_puts(state, " }");
+}
+
+static void lib9p_msg_Rfsync_format(struct lib9p_msg_Rfsync *self, struct fmt_state *state) {
+ fmt_state_puts(state, "Rfsync {");
+ fmt_state_puts(state, " tag=");
+ lib9p_tag_format(&self->tag, state);
+ fmt_state_puts(state, " }");
+}
+
+static void lib9p_msg_Tlock_format(struct lib9p_msg_Tlock *self, struct fmt_state *state) {
+ fmt_state_puts(state, "Tlock {");
+ fmt_state_puts(state, " tag=");
+ lib9p_tag_format(&self->tag, state);
+ fmt_state_puts(state, " fid=");
+ lib9p_fid_format(&self->fid, state);
+ fmt_state_puts(state, " type=");
+ lib9p_lock_type_format(&self->type, state);
+ fmt_state_puts(state, " flags=");
+ lib9p_lock_flags_format(&self->flags, state);
+ fmt_state_puts(state, " start=");
+ fmt_state_printf(state, "%"PRIu64, self->start);
+ fmt_state_puts(state, " length=");
+ fmt_state_printf(state, "%"PRIu64, self->length);
+ fmt_state_puts(state, " proc_id=");
+ fmt_state_printf(state, "%"PRIu32, self->proc_id);
+ fmt_state_puts(state, " client_id=");
+ lib9p_s_format(&self->client_id, state);
+ fmt_state_puts(state, " }");
+}
+
+static void lib9p_msg_Rlock_format(struct lib9p_msg_Rlock *self, struct fmt_state *state) {
+ fmt_state_puts(state, "Rlock {");
+ fmt_state_puts(state, " tag=");
+ lib9p_tag_format(&self->tag, state);
+ fmt_state_puts(state, " status=");
+ lib9p_lock_status_format(&self->status, state);
+ fmt_state_puts(state, " }");
+}
+
+static void lib9p_msg_Tgetlock_format(struct lib9p_msg_Tgetlock *self, struct fmt_state *state) {
+ fmt_state_puts(state, "Tgetlock {");
+ fmt_state_puts(state, " tag=");
+ lib9p_tag_format(&self->tag, state);
+ fmt_state_puts(state, " fid=");
+ lib9p_fid_format(&self->fid, state);
+ fmt_state_puts(state, " type=");
+ lib9p_lock_type_format(&self->type, state);
+ fmt_state_puts(state, " start=");
+ fmt_state_printf(state, "%"PRIu64, self->start);
+ fmt_state_puts(state, " length=");
+ fmt_state_printf(state, "%"PRIu64, self->length);
+ fmt_state_puts(state, " proc_id=");
+ fmt_state_printf(state, "%"PRIu32, self->proc_id);
+ fmt_state_puts(state, " client_id=");
+ lib9p_s_format(&self->client_id, state);
+ fmt_state_puts(state, " }");
+}
+
+static void lib9p_msg_Rgetlock_format(struct lib9p_msg_Rgetlock *self, struct fmt_state *state) {
+ fmt_state_puts(state, "Rgetlock {");
+ fmt_state_puts(state, " tag=");
+ lib9p_tag_format(&self->tag, state);
+ fmt_state_puts(state, " type=");
+ lib9p_lock_type_format(&self->type, state);
+ fmt_state_puts(state, " start=");
+ fmt_state_printf(state, "%"PRIu64, self->start);
+ fmt_state_puts(state, " length=");
+ fmt_state_printf(state, "%"PRIu64, self->length);
+ fmt_state_puts(state, " proc_id=");
+ fmt_state_printf(state, "%"PRIu32, self->proc_id);
+ fmt_state_puts(state, " client_id=");
+ lib9p_s_format(&self->client_id, state);
+ fmt_state_puts(state, " }");
+}
+
+static void lib9p_msg_Tlink_format(struct lib9p_msg_Tlink *self, struct fmt_state *state) {
+ fmt_state_puts(state, "Tlink {");
+ fmt_state_puts(state, " tag=");
+ lib9p_tag_format(&self->tag, state);
+ fmt_state_puts(state, " dfid=");
+ lib9p_fid_format(&self->dfid, state);
+ fmt_state_puts(state, " fid=");
+ lib9p_fid_format(&self->fid, state);
+ fmt_state_puts(state, " name=");
+ lib9p_s_format(&self->name, state);
+ fmt_state_puts(state, " }");
+}
+
+static void lib9p_msg_Rlink_format(struct lib9p_msg_Rlink *self, struct fmt_state *state) {
+ fmt_state_puts(state, "Rlink {");
+ fmt_state_puts(state, " tag=");
+ lib9p_tag_format(&self->tag, state);
+ fmt_state_puts(state, " }");
+}
+
+static void lib9p_msg_Tmkdir_format(struct lib9p_msg_Tmkdir *self, struct fmt_state *state) {
+ fmt_state_puts(state, "Tmkdir {");
+ fmt_state_puts(state, " tag=");
+ lib9p_tag_format(&self->tag, state);
+ fmt_state_puts(state, " dfid=");
+ lib9p_fid_format(&self->dfid, state);
+ fmt_state_puts(state, " name=");
+ lib9p_s_format(&self->name, state);
+ fmt_state_puts(state, " mode=");
+ lib9p_mode_format(&self->mode, state);
+ fmt_state_puts(state, " gid=");
+ lib9p_nuid_format(&self->gid, state);
+ fmt_state_puts(state, " }");
+}
+
+static void lib9p_msg_Rmkdir_format(struct lib9p_msg_Rmkdir *self, struct fmt_state *state) {
+ fmt_state_puts(state, "Rmkdir {");
+ fmt_state_puts(state, " tag=");
+ lib9p_tag_format(&self->tag, state);
+ fmt_state_puts(state, " qid=");
+ lib9p_qid_format(&self->qid, state);
+ fmt_state_puts(state, " }");
+}
+
+static void lib9p_msg_Trenameat_format(struct lib9p_msg_Trenameat *self, struct fmt_state *state) {
+ fmt_state_puts(state, "Trenameat {");
+ fmt_state_puts(state, " tag=");
+ lib9p_tag_format(&self->tag, state);
+ fmt_state_puts(state, " olddirfid=");
+ lib9p_fid_format(&self->olddirfid, state);
+ fmt_state_puts(state, " oldname=");
+ lib9p_s_format(&self->oldname, state);
+ fmt_state_puts(state, " newdirfid=");
+ lib9p_fid_format(&self->newdirfid, state);
+ fmt_state_puts(state, " newname=");
+ lib9p_s_format(&self->newname, state);
+ fmt_state_puts(state, " }");
+}
+
+static void lib9p_msg_Rrenameat_format(struct lib9p_msg_Rrenameat *self, struct fmt_state *state) {
+ fmt_state_puts(state, "Rrenameat {");
+ fmt_state_puts(state, " tag=");
+ lib9p_tag_format(&self->tag, state);
+ fmt_state_puts(state, " }");
+}
+
+static void lib9p_msg_Tunlinkat_format(struct lib9p_msg_Tunlinkat *self, struct fmt_state *state) {
+ fmt_state_puts(state, "Tunlinkat {");
+ fmt_state_puts(state, " tag=");
+ lib9p_tag_format(&self->tag, state);
+ fmt_state_puts(state, " dirfd=");
+ lib9p_fid_format(&self->dirfd, state);
+ fmt_state_puts(state, " name=");
+ lib9p_s_format(&self->name, state);
+ fmt_state_puts(state, " flags=");
+ fmt_state_printf(state, "%"PRIu32, self->flags);
+ fmt_state_puts(state, " }");
+}
+
+static void lib9p_msg_Runlinkat_format(struct lib9p_msg_Runlinkat *self, struct fmt_state *state) {
+ fmt_state_puts(state, "Runlinkat {");
+ fmt_state_puts(state, " tag=");
+ lib9p_tag_format(&self->tag, state);
+ fmt_state_puts(state, " }");
+}
+
+#endif /* CONFIG_9P_ENABLE_9P2000_L */
+#if CONFIG_9P_ENABLE_9P2000_e
+static void lib9p_msg_Tsession_format(struct lib9p_msg_Tsession *self, struct fmt_state *state) {
+ fmt_state_puts(state, "Tsession {");
+ fmt_state_puts(state, " tag=");
+ lib9p_tag_format(&self->tag, state);
+ fmt_state_puts(state, " key=");
+ fmt_state_printf(state, "%"PRIu64, self->key);
+ fmt_state_puts(state, " }");
+}
+
+static void lib9p_msg_Rsession_format(struct lib9p_msg_Rsession *self, struct fmt_state *state) {
+ fmt_state_puts(state, "Rsession {");
+ fmt_state_puts(state, " tag=");
+ lib9p_tag_format(&self->tag, state);
+ fmt_state_puts(state, " }");
+}
+
+static void lib9p_msg_Tsread_format(struct lib9p_msg_Tsread *self, struct fmt_state *state) {
+ fmt_state_puts(state, "Tsread {");
+ fmt_state_puts(state, " tag=");
+ lib9p_tag_format(&self->tag, state);
+ fmt_state_puts(state, " fid=");
+ fmt_state_printf(state, "%"PRIu32, self->fid);
+ fmt_state_puts(state, " nwname=");
+ fmt_state_printf(state, "%"PRIu16, self->nwname);
+ fmt_state_puts(state, " wname=[");
+ for (uint16_t i = 0; i < self->nwname; i++) {
+ if (i)
+ fmt_state_puts(state, ", ");
+ lib9p_s_format(&self->wname[i], state);
+ }
+ fmt_state_puts(state, " ]");
+ fmt_state_puts(state, " }");
+}
+
+static void lib9p_msg_Rsread_format(struct lib9p_msg_Rsread *self, struct fmt_state *state) {
+ fmt_state_puts(state, "Rsread {");
+ fmt_state_puts(state, " tag=");
+ lib9p_tag_format(&self->tag, state);
+ fmt_state_puts(state, " count=");
+ fmt_state_printf(state, "%"PRIu32, self->count);
+ fmt_state_puts(state, " data=<bytedata>");
+ fmt_state_puts(state, " }");
+}
+
+static void lib9p_msg_Tswrite_format(struct lib9p_msg_Tswrite *self, struct fmt_state *state) {
+ fmt_state_puts(state, "Tswrite {");
+ fmt_state_puts(state, " tag=");
+ lib9p_tag_format(&self->tag, state);
+ fmt_state_puts(state, " fid=");
+ fmt_state_printf(state, "%"PRIu32, self->fid);
+ fmt_state_puts(state, " nwname=");
+ fmt_state_printf(state, "%"PRIu16, self->nwname);
+ fmt_state_puts(state, " wname=[");
+ for (uint16_t i = 0; i < self->nwname; i++) {
+ if (i)
+ fmt_state_puts(state, ", ");
+ lib9p_s_format(&self->wname[i], state);
+ }
+ fmt_state_puts(state, " ]");
+ fmt_state_puts(state, " count=");
+ fmt_state_printf(state, "%"PRIu32, self->count);
+ fmt_state_puts(state, " data=<bytedata>");
+ fmt_state_puts(state, " }");
+}
+
+static void lib9p_msg_Rswrite_format(struct lib9p_msg_Rswrite *self, struct fmt_state *state) {
+ fmt_state_puts(state, "Rswrite {");
+ fmt_state_puts(state, " tag=");
+ lib9p_tag_format(&self->tag, state);
+ fmt_state_puts(state, " count=");
+ fmt_state_printf(state, "%"PRIu32, self->count);
+ fmt_state_puts(state, " }");
+}
+#endif /* CONFIG_9P_ENABLE_9P2000_e */
+
+/* tables.h *******************************************************************/
+
+const struct _lib9p_ver_tentry _lib9p_table_ver[LIB9P_VER_NUM] = {
+ [LIB9P_VER_unknown] = {.name="unknown", .min_msg_size=9},
+#if CONFIG_9P_ENABLE_9P2000
+ [LIB9P_VER_9P2000] = {.name="9P2000", .min_msg_size=9},
+#endif /* CONFIG_9P_ENABLE_9P2000 */
+#if CONFIG_9P_ENABLE_9P2000_L
+ [LIB9P_VER_9P2000_L] = {.name="9P2000.L", .min_msg_size=9},
+#endif /* CONFIG_9P_ENABLE_9P2000_L */
+#if CONFIG_9P_ENABLE_9P2000_e
+ [LIB9P_VER_9P2000_e] = {.name="9P2000.e", .min_msg_size=9},
+#endif /* CONFIG_9P_ENABLE_9P2000_e */
+#if CONFIG_9P_ENABLE_9P2000_p9p
+ [LIB9P_VER_9P2000_p9p] = {.name="9P2000.p9p", .min_msg_size=9},
+#endif /* CONFIG_9P_ENABLE_9P2000_p9p */
+#if CONFIG_9P_ENABLE_9P2000_u
+ [LIB9P_VER_9P2000_u] = {.name="9P2000.u", .min_msg_size=13},
+#endif /* CONFIG_9P_ENABLE_9P2000_u */
+};
-const uint32_t _lib9p_table_msg_min_size[LIB9P_VER_NUM] = {
- [LIB9P_VER_unknown] = 9,
+#define _MSG(typ) [LIB9P_TYP_##typ] = { \
+ .name = #typ, \
+ .box_as_fmt_formatter = (_box_as_fmt_formatter_fn_t)lo_box_lib9p_msg_##typ##_as_fmt_formatter, \
+ }
+const struct _lib9p_msg_tentry _lib9p_table_msg[LIB9P_VER_NUM][0x100] = {
+ [LIB9P_VER_unknown] = {
+ _MSG(Tversion),
+ _MSG(Rversion),
+ _MSG(Rerror),
+ },
#if CONFIG_9P_ENABLE_9P2000
- [LIB9P_VER_9P2000] = 9,
+ [LIB9P_VER_9P2000] = {
+ _MSG(Tversion),
+ _MSG(Rversion),
+ _MSG(Tauth),
+ _MSG(Rauth),
+ _MSG(Tattach),
+ _MSG(Rattach),
+ _MSG(Rerror),
+ _MSG(Tflush),
+ _MSG(Rflush),
+ _MSG(Twalk),
+ _MSG(Rwalk),
+ _MSG(Topen),
+ _MSG(Ropen),
+ _MSG(Tcreate),
+ _MSG(Rcreate),
+ _MSG(Tread),
+ _MSG(Rread),
+ _MSG(Twrite),
+ _MSG(Rwrite),
+ _MSG(Tclunk),
+ _MSG(Rclunk),
+ _MSG(Tremove),
+ _MSG(Rremove),
+ _MSG(Tstat),
+ _MSG(Rstat),
+ _MSG(Twstat),
+ _MSG(Rwstat),
+ },
#endif /* CONFIG_9P_ENABLE_9P2000 */
#if CONFIG_9P_ENABLE_9P2000_L
- [LIB9P_VER_9P2000_L] = 9,
+ [LIB9P_VER_9P2000_L] = {
+ _MSG(Rlerror),
+ _MSG(Tstatfs),
+ _MSG(Rstatfs),
+ _MSG(Tlopen),
+ _MSG(Rlopen),
+ _MSG(Tlcreate),
+ _MSG(Rlcreate),
+ _MSG(Tsymlink),
+ _MSG(Rsymlink),
+ _MSG(Tmknod),
+ _MSG(Rmknod),
+ _MSG(Trename),
+ _MSG(Rrename),
+ _MSG(Treadlink),
+ _MSG(Rreadlink),
+ _MSG(Tgetattr),
+ _MSG(Rgetattr),
+ _MSG(Tsetattr),
+ _MSG(Rsetattr),
+ _MSG(Txattrwalk),
+ _MSG(Rxattrwalk),
+ _MSG(Txattrcreate),
+ _MSG(Rxattrcreate),
+ _MSG(Treaddir),
+ _MSG(Rreaddir),
+ _MSG(Tfsync),
+ _MSG(Rfsync),
+ _MSG(Tlock),
+ _MSG(Rlock),
+ _MSG(Tgetlock),
+ _MSG(Rgetlock),
+ _MSG(Tlink),
+ _MSG(Rlink),
+ _MSG(Tmkdir),
+ _MSG(Rmkdir),
+ _MSG(Trenameat),
+ _MSG(Rrenameat),
+ _MSG(Tunlinkat),
+ _MSG(Runlinkat),
+ _MSG(Tversion),
+ _MSG(Rversion),
+ _MSG(Tauth),
+ _MSG(Rauth),
+ _MSG(Tattach),
+ _MSG(Rattach),
+ _MSG(Rerror),
+ _MSG(Tflush),
+ _MSG(Rflush),
+ _MSG(Twalk),
+ _MSG(Rwalk),
+ _MSG(Tread),
+ _MSG(Rread),
+ _MSG(Twrite),
+ _MSG(Rwrite),
+ _MSG(Tclunk),
+ _MSG(Rclunk),
+ _MSG(Tremove),
+ _MSG(Rremove),
+ },
#endif /* CONFIG_9P_ENABLE_9P2000_L */
#if CONFIG_9P_ENABLE_9P2000_e
- [LIB9P_VER_9P2000_e] = 9,
+ [LIB9P_VER_9P2000_e] = {
+ _MSG(Tversion),
+ _MSG(Rversion),
+ _MSG(Tauth),
+ _MSG(Rauth),
+ _MSG(Tattach),
+ _MSG(Rattach),
+ _MSG(Rerror),
+ _MSG(Tflush),
+ _MSG(Rflush),
+ _MSG(Twalk),
+ _MSG(Rwalk),
+ _MSG(Topen),
+ _MSG(Ropen),
+ _MSG(Tcreate),
+ _MSG(Rcreate),
+ _MSG(Tread),
+ _MSG(Rread),
+ _MSG(Twrite),
+ _MSG(Rwrite),
+ _MSG(Tclunk),
+ _MSG(Rclunk),
+ _MSG(Tremove),
+ _MSG(Rremove),
+ _MSG(Tstat),
+ _MSG(Rstat),
+ _MSG(Twstat),
+ _MSG(Rwstat),
+ _MSG(Tsession),
+ _MSG(Rsession),
+ _MSG(Tsread),
+ _MSG(Rsread),
+ _MSG(Tswrite),
+ _MSG(Rswrite),
+ },
#endif /* CONFIG_9P_ENABLE_9P2000_e */
#if CONFIG_9P_ENABLE_9P2000_p9p
- [LIB9P_VER_9P2000_p9p] = 9,
+ [LIB9P_VER_9P2000_p9p] = {
+ _MSG(Topenfd),
+ _MSG(Ropenfd),
+ _MSG(Tversion),
+ _MSG(Rversion),
+ _MSG(Tauth),
+ _MSG(Rauth),
+ _MSG(Tattach),
+ _MSG(Rattach),
+ _MSG(Rerror),
+ _MSG(Tflush),
+ _MSG(Rflush),
+ _MSG(Twalk),
+ _MSG(Rwalk),
+ _MSG(Topen),
+ _MSG(Ropen),
+ _MSG(Tcreate),
+ _MSG(Rcreate),
+ _MSG(Tread),
+ _MSG(Rread),
+ _MSG(Twrite),
+ _MSG(Rwrite),
+ _MSG(Tclunk),
+ _MSG(Rclunk),
+ _MSG(Tremove),
+ _MSG(Rremove),
+ _MSG(Tstat),
+ _MSG(Rstat),
+ _MSG(Twstat),
+ _MSG(Rwstat),
+ },
#endif /* CONFIG_9P_ENABLE_9P2000_p9p */
#if CONFIG_9P_ENABLE_9P2000_u
- [LIB9P_VER_9P2000_u] = 13,
+ [LIB9P_VER_9P2000_u] = {
+ _MSG(Tversion),
+ _MSG(Rversion),
+ _MSG(Tauth),
+ _MSG(Rauth),
+ _MSG(Tattach),
+ _MSG(Rattach),
+ _MSG(Rerror),
+ _MSG(Tflush),
+ _MSG(Rflush),
+ _MSG(Twalk),
+ _MSG(Rwalk),
+ _MSG(Topen),
+ _MSG(Ropen),
+ _MSG(Tcreate),
+ _MSG(Rcreate),
+ _MSG(Tread),
+ _MSG(Rread),
+ _MSG(Twrite),
+ _MSG(Rwrite),
+ _MSG(Tclunk),
+ _MSG(Rclunk),
+ _MSG(Tremove),
+ _MSG(Rremove),
+ _MSG(Tstat),
+ _MSG(Rstat),
+ _MSG(Twstat),
+ _MSG(Rwstat),
+ },
#endif /* CONFIG_9P_ENABLE_9P2000_u */
};
#define _MSG_RECV(typ) [LIB9P_TYP_##typ/2] = { \
- .basesize = sizeof(struct lib9p_msg_##typ), \
.validate = validate_##typ, \
.unmarshal = (_unmarshal_fn_t)unmarshal_##typ, \
}
diff --git a/lib9p/CMakeLists.txt b/lib9p/CMakeLists.txt
index 707308e..11a58ba 100644
--- a/lib9p/CMakeLists.txt
+++ b/lib9p/CMakeLists.txt
@@ -8,12 +8,14 @@ target_include_directories(lib9p SYSTEM INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/in
target_sources(lib9p INTERFACE
9p.generated.c
9p.c
+ tables.c
srv.c
)
target_link_libraries(lib9p INTERFACE
libcr_ipc
- libmisc
+ libfmt
libhw_generic
+ libmisc
)
if (ENABLE_TESTS)
diff --git a/lib9p/idl/0000-README.md b/lib9p/idl/0000-README.md
index e19a1e8..84cf865 100644
--- a/lib9p/idl/0000-README.md
+++ b/lib9p/idl/0000-README.md
@@ -17,35 +17,62 @@ client->server requests, and R-messages are server->client responses
type of a message is represented by a u8 ID; T-messages are even and
R-messages are odd.
-Messages are made up of the primitives; unsigned little-endian
-integers, identified with the following single-character mnemonics:
+9P messages are exchanged over a reliable bidirectional in-order octet
+stream. Messages are made up of the primitives; unsigned
+little-endian integers, identified with the following single-character
+mnemonics:
- 1 = u8
- 2 = u16le
- 4 = u32le
- 8 = u16le
-Out of these primitives, we can make other numeric types,
+Out of these primitives, we can make more complex types:
+
+## User-defined types
+
+### Numeric types
num NUMNAME = PRIMITIVE_TYPE
+ "NAME=VAL"...
+
+Besides just being an alias for a primitive type, a numeric type may
+define 0 or more named constants of that type, each wrapped in
+"quotes".
+
+### Bitfields
-bitfields,
+ bitfield BFNAME = PRIMITIVE_TYPE
+ "bit NBIT=NAME"...
+ "bit NBIT=reserved(NAME)"...
+ "bit NBIT=num(NUMNAME)"...
+ "alias NAME=VAL"...
+ "mask NAME=VAL"...
+ "num(NUMNAME) NAME=VAL"...
- bitfield BFNAME = PRIMITIVE_TYPE "NBIT=NAME... ALIAS=VAL..."
+The same NBIT may not be defined multiple times. The same NAME may
+not be defined multiple times.
-structures,
+ - A `reserved(...)` bit indicates that the bit is named but is not
+ allowed to be used.
+ - `num(...)` bits embed a numeric/enumerated field within a set of
+ bits. Once several bits have been allocated to a numeric field
+ with `bit NBIT=num(NUMNAME)`, constant values for that field may be
+ declared with `num(NUMNAME) NAME=VAL`. For each numeric field, a
+ `mask NUMNAME=BITMASK` is automatically declared.
+ - A `mask` defines a bitmask that selects several bits.
+ - An `alias` defines a convenience alias for a bit or set of bits.
+
+### Structures
struct STRUCTNAME = "FIELDNAME[FIELDTYPE]..."
-and messages (which are a special-case of structures).
+Or a special-case for structs that are messages; `msg` has the same
+syntax as `struct`, but has restrictions on the STRUCTNAME and the
+first 3 fields must all be declared in the same way:
msg Tname = "size[4,val=end-&size] typ[1,val=TYP] tag[tag] REST..."
-Bitfield bit names may be wrapped in `reserved(...)` or
-`subfield(...)`; reserved indicates that the bit is named but is not
-allowed to be used, and subfield indicates that the bit is part of a
-num/enum that is handled by an alias.
-
Struct fields that have numeric types (either primitives or `num`
types) can add to their type `,val=` and/or `,max=` to specify what
the exact value must be and/or what the maximum (inclusive) value is.
@@ -59,11 +86,13 @@ can be
- `&fieldname` to refer to the offset of a field name in that struct,
- the special value `end` to refer to the offset of the end of the
struct,
- - the special value `s32_max` to refer to the constant value
- `(1<<31)-1`, or
- - the special value `s64_max` to refer to the constant value
- `(1<<63)-1`
+ - the special value `u{8,16,32,64}_max` to refer to the constant
+ value `(1<<{n})-1`, or
+ - the special value `s{8,16,32,64}_max` to refer to the constant value
+ `(1<<({n}-1))-1`.
+
+## Parser
A parser for this syntax is given in `__init__.py`. However,
`__init__.py` places the somewhat arbitrary undocumented restrictions
-on fields referenced as the count for a repeated field.
+on fields referenced as the count of a repeated field.
diff --git a/lib9p/idl/0000-TODO.md b/lib9p/idl/0000-TODO.md
index 81cafe5..e52902f 100644
--- a/lib9p/idl/0000-TODO.md
+++ b/lib9p/idl/0000-TODO.md
@@ -9,5 +9,3 @@
- Decide how to handle duplicate type names from different versions
- Decide how to handle duplicate `enum lib9p_msg_type` names and
values
-- Clean up the iterate-over-all-msgids-in-a-version code
-- Allow for const `.cnt` instead of only having previous-member `.cnt`
diff --git a/lib9p/idl/1992-9P0.9p.wip b/lib9p/idl/1992-9P0.9p.wip
index 086e8e4..a434ba2 100644
--- a/lib9p/idl/1992-9P0.9p.wip
+++ b/lib9p/idl/1992-9P0.9p.wip
@@ -37,40 +37,40 @@ struct errstr = "64*(txt[1])"
# "O"pen flags (flags to pass to Topen and Tcreate)
# Unused bits are *ignored*.
bitfield o = 1
- "0=mode_0" # low bit of the 2-bit READ/WRITE/RDWR/EXEC enum
- "1=mode_1" # high bit of the 2-bit READ/WRITE/RDWR/EXEC enum
- #"2=unused"
- #"3=unused"
- "4=TRUNC"
- #"5=_reserved_CEXEC" # close-on-exec
- "6=RCLOSE" # remove-on-close
- #"7=unused"
+ "bit 0=num(MODE)" # low bit of the 2-bit READ/WRITE/RDWR/EXEC enum
+ "bit 1=num(MODE)" # high bit of the 2-bit READ/WRITE/RDWR/EXEC enum
+ #"bit 2=unused"
+ #"bit 3=unused"
+ "bit 4=TRUNC"
+ "bit 5=reserved(CEXEC)" # close-on-exec
+ "bit 6=RCLOSE" # remove-on-close
+ #"bit 7=unused"
- "READ = 0" # make available for this FID: Tread()
- "WRITE = 1" # make available for this FID: Twrite()
- "RDWR = 2" # make available for this FID: Tread() and Twrite()
- "EXEC = 3" # make available for this FID: Tread()
+ "num(MODE) READ = 0" # make available for this FID: Tread()
+ "num(MODE) WRITE = 1" # make available for this FID: Twrite()
+ "num(MODE) RDWR = 2" # make available for this FID: Tread() and Twrite()
+ "num(MODE) EXEC = 3" # make available for this FID: Tread()
- "MODE_MASK = 0b00000011"
- "FLAG_MASK = 0b11111100"
+ "mask FLAG = 0b11111100"
-# "C"??? "H"??? - file permissions and attributes
+# "CH"annel flags - file permissions and attributes (a "channel" is
+# what a file handle is called inside of the Plan 9 kernel).
bitfield ch = 4
- "31=DIR"
- "30=APPEND"
- "29=EXCL"
+ "bit 31=DIR"
+ "bit 30=APPEND"
+ "bit 29=EXCL"
#...
- "8=OWNER_R"
- "7=OWNER_W"
- "6=OWNER_X"
- "5=GROUP_R"
- "4=GROUP_W"
- "3=GROUP_X"
- "2=OTHER_R"
- "1=OTHER_W"
- "0=OTHER_X"
+ "bit 8=OWNER_R"
+ "bit 7=OWNER_W"
+ "bit 6=OWNER_X"
+ "bit 5=GROUP_R"
+ "bit 4=GROUP_W"
+ "bit 3=GROUP_X"
+ "bit 2=OTHER_R"
+ "bit 1=OTHER_W"
+ "bit 0=OTHER_X"
- "PERM_MASK=0777" # {OWNER,GROUP,OTHER}_{R,W,X}
+ "mask PERM=0777" # {OWNER,GROUP,OTHER}_{R,W,X}
struct stat = "file_name[name]"
"file_owner[name]"
diff --git a/lib9p/idl/1995-9P1.9p.wip b/lib9p/idl/1995-9P1.9p.wip
index 2caf39d..660e24a 100644
--- a/lib9p/idl/1995-9P1.9p.wip
+++ b/lib9p/idl/1995-9P1.9p.wip
@@ -43,7 +43,7 @@ from ./1992-9P0.9p import tag, fid, qid, name, errstr, o, ch, stat
# draft RFC). As I understand it, CHMOUNT indicates that the file is
# mounted by the kernel as a 9P transport; that the kernel has a lock
# on doing I/O on it, so userspace can't do I/O on it.
-bitfield ch += "28=MOUNT"
+bitfield ch += "bit 28=_PLAN9_MOUNT"
# Authentication uses DES encryption. The client obtains a ticket and
# a nonce-key from a separate auth-server; how it does this is beyond
diff --git a/lib9p/idl/1996-Styx.9p.wip b/lib9p/idl/1996-Styx.9p.wip
index 6ba4509..3cb3774 100644
--- a/lib9p/idl/1996-Styx.9p.wip
+++ b/lib9p/idl/1996-Styx.9p.wip
@@ -40,7 +40,7 @@ msg Ropen = "typ[1,val=11] tag[tag] fid[fid] qid[qid]"
msg Tcreate = "typ[1,val=12] tag[tag] fid[fid] name[name] perm[ch] mode[o]"
msg Rcreate = "typ[1,val=13] tag[tag] fid[fid] qid[qid]"
# For `offset:max`, see `fs.c` `f_read()` and `f_write()`.
-# For `count:max`, see `styx.h:MAXFDATA'.
+# For `count:max`, see `styx.h:MAXFDATA`.
msg Tread = "typ[1,val=14] tag[tag] fid[fid] offset[8,max=s64_max] count[2,max=8192]"
msg Rread = "typ[1,val=15] tag[tag] fid[fid] count[2,max=8192] pad[1] count*(data[1])"
msg Twrite = "typ[1,val=16] tag[tag] fid[fid] offset[8,max=s64_max] count[2,max=8192] pad[1] count*(data[1])"
diff --git a/lib9p/idl/2002-9P2000.9p b/lib9p/idl/2002-9P2000.9p
index 2a4f7ed..2b51612 100644
--- a/lib9p/idl/2002-9P2000.9p
+++ b/lib9p/idl/2002-9P2000.9p
@@ -22,64 +22,64 @@ version "9P2000"
# tag - identify a request/response pair
num tag = 2
- "NOTAG = ~0"
+ "NOTAG = u16_max"
# file identifier - like a UNIX file-descriptor
num fid = 4
- "NOFID = ~0"
+ "NOFID = u32_max"
# string - u16le `n`, then `n` bytes of UTF-8, without any nul-bytes
struct s = "len[2] len*(utf8[1])"
# "D"ir-entry "M"ode - file permissions and attributes
bitfield dm = 4
- "31=DIR"
- "30=APPEND"
- "29=EXCL"
- # DMMOUNT has been around in Plan 9 forever (CHMOUNT in <4e),
+ "bit 31=DIR"
+ "bit 30=APPEND"
+ "bit 29=EXCL"
+ # DMMOUNT has been around in Plan 9 since 2e (CHMOUNT in <4e),
# but is undocumented, and is explicitly excluded from the
# 9P2000 draft RFC. As I understand it, DMMOUNT indicates
# that the file is mounted by the kernel as a 9P transport;
# that the kernel has a lock on doing I/O on it, so userspace
# can't do I/O on it.
- "28=reserved(PLAN9_MOUNT)"
- "27=AUTH"
- "26=TMP"
+ "bit 28=_PLAN9_MOUNT"
+ "bit 27=AUTH"
+ "bit 26=TMP"
#...
- "8=OWNER_R"
- "7=OWNER_W"
- "6=OWNER_X"
- "5=GROUP_R"
- "4=GROUP_W"
- "3=GROUP_X"
- "2=OTHER_R"
- "1=OTHER_W"
- "0=OTHER_X"
+ "bit 8=OWNER_R"
+ "bit 7=OWNER_W"
+ "bit 6=OWNER_X"
+ "bit 5=GROUP_R"
+ "bit 4=GROUP_W"
+ "bit 3=GROUP_X"
+ "bit 2=OTHER_R"
+ "bit 1=OTHER_W"
+ "bit 0=OTHER_X"
- "PERM_MASK=0777" # {OWNER,GROUP,OTHER}_{R,W,X}
+ "mask PERM=0777" # {OWNER,GROUP,OTHER}_{R,W,X}
# QID Type - see `struct qid` below
bitfield qt = 1
- "7=DIR"
- "6=APPEND"
- "5=EXCL"
- "4=reserved(PLAN9_MOUNT)" # See "PLAN9_MOUNT" in "dm" above.
- "3=AUTH"
+ "bit 7=DIR"
+ "bit 6=APPEND"
+ "bit 5=EXCL"
+ "bit 4=_PLAN9_MOUNT" # See "_PLAN9_MOUNT" in "dm" above.
+ "bit 3=AUTH"
# Fun historical fact: QTTMP was a relatively late addition to
# Plan 9, in 2003-12.
- "2=TMP"
- #"1=unused"
+ "bit 2=TMP"
+ #"bit 1=unused"
# "The name QTFILE, defined to be zero, identifies the value
# of the type for a plain file."
- "FILE=0"
+ "alias FILE=0"
# uni"Q"ue "ID"entification - "two files on the same server hierarchy
# are the same if and only if their qids are the same"
#
# - "path" is a unique uint64_t that does most of the work in the
# above statement about files being the same if their QIDs are the
-# same; " If a file is deleted and recreated with the same name in
+# same; "If a file is deleted and recreated with the same name in
# the same directory, the old and new path components of the qids
# should be different"
#
@@ -107,22 +107,21 @@ struct stat = "stat_size[2,val=end-&kern_type]"
# "O"pen flags (flags to pass to Topen and Tcreate)
# Unused bits *must* be 0.
bitfield o = 1
- "0=subfield(mode)" # low bit of the 2-bit READ/WRITE/RDWR/EXEC enum
- "1=subfield(mode)" # high bit of the 2-bit READ/WRITE/RDWR/EXEC enum
- #"2=unused"
- #"3=unused"
- "4=TRUNC"
- "5=reserved(CEXEC)" # close-on-exec
- "6=RCLOSE" # remove-on-close
- #"7=unused"
+ "bit 0=num(MODE)" # low bit of the 2-bit READ/WRITE/RDWR/EXEC enum
+ "bit 1=num(MODE)" # high bit of the 2-bit READ/WRITE/RDWR/EXEC enum
+ #"bit 2=unused"
+ #"bit 3=unused"
+ "bit 4=TRUNC"
+ "bit 5=reserved(CEXEC)" # close-on-exec
+ "bit 6=RCLOSE" # remove-on-close
+ #"bit 7=unused"
- "READ = 0" # make available for this FID: Tread()
- "WRITE = 1" # make available for this FID: Twrite()
- "RDWR = 2" # make available for this FID: Tread() and Twrite()
- "EXEC = 3" # make available for this FID: Tread()
+ "num(MODE) READ = 0" # make available for this FID: Tread()
+ "num(MODE) WRITE = 1" # make available for this FID: Twrite()
+ "num(MODE) RDWR = 2" # make available for this FID: Tread() and Twrite()
+ "num(MODE) EXEC = 3" # make available for this FID: Tread()
- "MODE_MASK = 0b00000011"
- "FLAG_MASK = 0b11111100"
+ "mask FLAG = 0b11111100"
# A 9P2000 session goes:
#
diff --git a/lib9p/idl/2005-9P2000.u.9p b/lib9p/idl/2005-9P2000.u.9p
index fefe3e9..6c2f2dc 100644
--- a/lib9p/idl/2005-9P2000.u.9p
+++ b/lib9p/idl/2005-9P2000.u.9p
@@ -12,7 +12,7 @@ from ./2002-9P2000.9p import *
# numeric user ID
num nuid = 4
- "NONUID = ~0"
+ "NONUID = u32_max"
num errno = 4
"NOERROR = 0"
@@ -27,10 +27,10 @@ msg Tattach += "n_uid[nuid]"
msg Rerror += "errno[errno]"
-bitfield dm += "23=DEVICE"
- "21=NAMEDPIPE"
- "20=SOCKET"
- "19=SETUID"
- "18=SETGID"
+bitfield dm += "bit 23=DEVICE"
+ "bit 21=PIPE"
+ "bit 20=SOCKET"
+ "bit 19=SETUID"
+ "bit 18=SETGID"
-bitfield qt += "1=SYMLINK"
+bitfield qt += "bit 1=SYMLINK"
diff --git a/lib9p/idl/2010-9P2000.L.9p b/lib9p/idl/2010-9P2000.L.9p
index 7ac86a6..d81a15b 100644
--- a/lib9p/idl/2010-9P2000.L.9p
+++ b/lib9p/idl/2010-9P2000.L.9p
@@ -39,49 +39,48 @@ num super_magic = 4
# protocol.h (and are different than the Linux kernel's values, which
# vary by architecture).
bitfield lo = 4
- "0=subfield(mode)" # low bit of the 2-bit RDONLY/WRONLY/RDWR/NOACCESS enum
- "1=subfield(mode)" # high bit of the 2-bit RDONLY/WRONLY/RDWR/NOACCESS enum
- #"2=unused"
- #"3=unused"
- #"4=unused"
- #"5=unused"
- "6=CREATE"
- "7=EXCL"
- "8=NOCTTY"
- "9=TRUNC"
- "10=APPEND"
- "11=NONBLOCK"
- "12=DSYNC"
- "13=BSD_FASYNC"
- "14=DIRECT"
- "15=LARGEFILE"
- "16=DIRECTORY"
- "17=NOFOLLOW"
- "18=NOATIME"
- "19=CLOEXEC"
- "20=SYNC"
-
- "RDONLY = 0"
- "WRONLY = 1"
- "RDWR = 2"
- "NOACCESS = 3"
-
- "MODE_MASK = 0b000000000000000000011"
- "FLAG_MASK = 0b111111111111111000000"
+ "bit 0=num(MODE)" # low bit of the 2-bit RDONLY/WRONLY/RDWR/NOACCESS enum
+ "bit 1=num(MODE)" # high bit of the 2-bit RDONLY/WRONLY/RDWR/NOACCESS enum
+ #"bit 2=unused"
+ #"bit 3=unused"
+ #"bit 4=unused"
+ #"bit 5=unused"
+ "bit 6=CREATE"
+ "bit 7=EXCL"
+ "bit 8=NOCTTY"
+ "bit 9=TRUNC"
+ "bit 10=APPEND"
+ "bit 11=NONBLOCK"
+ "bit 12=DSYNC"
+ "bit 13=BSD_FASYNC"
+ "bit 14=DIRECT"
+ "bit 15=LARGEFILE"
+ "bit 16=DIRECTORY"
+ "bit 17=NOFOLLOW"
+ "bit 18=NOATIME"
+ "bit 19=CLOEXEC"
+ "bit 20=SYNC"
+
+ "num(MODE) RDONLY = 0"
+ "num(MODE) WRONLY = 1"
+ "num(MODE) RDWR = 2"
+ "num(MODE) NOACCESS = 3"
+
+ "mask FLAG = 0b111111111111111000000"
# "D"irentry "T"ype
#
# These match the Linux kernel's values.
num dt = 1
- "UNKNOWN = 0"
- "NAMED_PIPE = 1"
- "CHAR_DEV = 2"
- "DIRECTORY = 4"
- "BLOCK_DEV = 6"
- "REGULAR = 8"
- "SYMLINK = 10"
- "SOCKET = 12"
- "WHITEOUT = 14"
+ "UNKNOWN = 0"
+ "PIPE = 1"
+ "CHAR_DEV = 2"
+ "DIRECTORY = 4"
+ "BLOCK_DEV = 6" # proof it's not a bitfield
+ "REGULAR = 8"
+ "SYMLINK = 10" # proof it's not a bitfield
+ "SOCKET = 12" # proof it's not a bitfield
+ "_WHITEOUT = 14" # proof it's not a bitfield
# Mode
#
@@ -89,34 +88,33 @@ num dt = 1
# instead of just 16? Who knows?
bitfield mode = 4
#...
- "15=subfield(fmt)" # bit of the 4-bit FMT_ enum
- "14=subfield(fmt)" # bit of the 4-bit FMT_ enum
- "13=subfield(fmt)" # bit of the 4-bit FMT_ enum
- "12=subfield(fmt)" # bit of the 4-bit FMT_ enum
+ "bit 15=num(FMT)" # bit of the 4-bit FMT_ enum
+ "bit 14=num(FMT)" # bit of the 4-bit FMT_ enum
+ "bit 13=num(FMT)" # bit of the 4-bit FMT_ enum
+ "bit 12=num(FMT)" # bit of the 4-bit FMT_ enum
#...
- "11=PERM_SETGROUP"
- "10=PERM_SETUSER"
- "9=PERM_STICKY"
- "8=PERM_OWNER_R"
- "7=PERM_OWNER_W"
- "6=PERM_OWNER_X"
- "5=PERM_GROUP_R"
- "4=PERM_GROUP_W"
- "3=PERM_GROUP_X"
- "2=PERM_OTHER_R"
- "1=PERM_OTHER_W"
- "0=PERM_OTHER_X"
-
- "FMT_NAMED_PIPE = LIB9P_DT_NAMED_PIPE<<12"
- "FMT_CHAR_DEV = LIB9P_DT_CHAR_DEV<<12"
- "FMT_DIRECTORY = LIB9P_DT_DIRECTORY<<12"
- "FMT_BLOCK_DEV = LIB9P_DT_BLOCK_DEV<<12"
- "FMT_REGULAR = LIB9P_DT_REGULAR<<12"
- "FMT_SYMLINK = LIB9P_DT_SYMLINK<<12"
- "FMT_SOCKET = LIB9P_DT_SOCKET<<12"
-
- "PERM_MASK = 0000777" # PERM_*
- "FMT_MASK = 0170000" # _fmt_*
+ "bit 11=PERM_SETGROUP"
+ "bit 10=PERM_SETUSER"
+ "bit 9=PERM_STICKY"
+ "bit 8=PERM_OWNER_R"
+ "bit 7=PERM_OWNER_W"
+ "bit 6=PERM_OWNER_X"
+ "bit 5=PERM_GROUP_R"
+ "bit 4=PERM_GROUP_W"
+ "bit 3=PERM_GROUP_X"
+ "bit 2=PERM_OTHER_R"
+ "bit 1=PERM_OTHER_W"
+ "bit 0=PERM_OTHER_X"
+
+ "num(FMT) PIPE = dt.PIPE<<12"
+ "num(FMT) CHAR_DEV = dt.CHAR_DEV<<12"
+ "num(FMT) DIRECTORY = dt.DIRECTORY<<12"
+ "num(FMT) BLOCK_DEV = dt.BLOCK_DEV<<12"
+ "num(FMT) REGULAR = dt.REGULAR<<12"
+ "num(FMT) SYMLINK = dt.SYMLINK<<12"
+ "num(FMT) SOCKET = dt.SOCKET<<12"
+
+ "mask PERM = 07777" # PERM_*
# A boolean value that is for some reason 4 bytes wide.
num b4 = 4
@@ -125,35 +123,35 @@ num b4 = 4
# all other values are true also
bitfield getattr = 8
- "0=MODE"
- "1=NLINK"
- "2=UID"
- "3=GID"
- "4=RDEV"
- "5=ATIME"
- "6=MTIME"
- "7=CTIME"
- "8=INO"
- "9=SIZE"
- "10=BLOCKS"
-
- "11=BTIME"
- "12=GEN"
- "13=DATA_VERSION"
-
- "BASIC=0x000007ff" # Mask for fields up to BLOCKS
- "ALL =0x00003fff" # Mask for All fields above
+ "bit 0=MODE"
+ "bit 1=NLINK"
+ "bit 2=UID"
+ "bit 3=GID"
+ "bit 4=RDEV"
+ "bit 5=ATIME"
+ "bit 6=MTIME"
+ "bit 7=CTIME"
+ "bit 8=INO"
+ "bit 9=SIZE"
+ "bit 10=BLOCKS"
+
+ "bit 11=BTIME"
+ "bit 12=GEN"
+ "bit 13=DATA_VERSION"
+
+ "alias BASIC=0x000007ff" # Mask for fields up to BLOCKS
+ "alias ALL =0x00003fff" # Mask for All fields above
bitfield setattr = 4
- "0=MODE"
- "1=UID"
- "2=GID"
- "3=SIZE"
- "4=ATIME"
- "5=MTIME"
- "6=CTIME"
- "7=ATIME_SET"
- "8=MTIME_SET"
+ "bit 0=MODE"
+ "bit 1=UID"
+ "bit 2=GID"
+ "bit 3=SIZE"
+ "bit 4=ATIME"
+ "bit 5=MTIME"
+ "bit 6=CTIME"
+ "bit 7=ATIME_SET"
+ "bit 8=MTIME_SET"
num lock_type = 1
"RDLCK=0"
@@ -161,8 +159,8 @@ num lock_type = 1
"UNLCK=2"
bitfield lock_flags = 4
- "0=BLOCK"
- "1=RECLAIM"
+ "bit 0=BLOCK"
+ "bit 1=RECLAIM"
num lock_status = 1
"SUCCESS=0"
diff --git a/lib9p/idl/__init__.py b/lib9p/idl/__init__.py
index e7b3670..2d09217 100644
--- a/lib9p/idl/__init__.py
+++ b/lib9p/idl/__init__.py
@@ -15,14 +15,27 @@ __all__ = [
# types
"Type",
"Primitive",
+ *["Expr", "ExprTok", "ExprOp", "ExprLit", "ExprSym", "ExprOff", "ExprNum"],
"Number",
- *["Bitfield", "Bit", "BitCat", "BitAlias"],
- *["Struct", "StructMember", "Expr", "ExprOp", "ExprSym", "ExprLit"],
+ *["Bitfield", "Bit", "BitCat", "BitNum", "BitAlias"],
+ *["Struct", "StructMember"],
"Message",
]
# The syntax that this parses is described in `./0000-README.md`.
+# Utilities ####################################################################
+
+
+def get_type(env: dict[str, "Type"], name: str, tc: type["T"]) -> "T":
+ if name not in env:
+ raise NameError(f"Unknown type {name!r}")
+ ret = env[name]
+ if (not isinstance(ret, tc)) or (ret.__class__.__name__ != tc.__name__):
+ raise NameError(f"Type {ret.typname!r} is not a {tc.__name__}")
+ return ret
+
+
# Types ########################################################################
@@ -51,13 +64,129 @@ class Primitive(enum.Enum):
return self.value
+class ExprOp:
+ op: typing.Literal["-", "+", "<<"]
+
+ def __init__(self, op: typing.Literal["-", "+", "<<"]) -> None:
+ self.op = op
+
+
+class ExprLit:
+ val: int
+
+ def __init__(self, val: int) -> None:
+ self.val = val
+
+
+class ExprSym:
+ symname: str
+
+ def __init__(self, name: str) -> None:
+ self.symname = name
+
+
+class ExprOff:
+ membname: str
+
+ def __init__(self, name: str) -> None:
+ self.membname = name
+
+
+class ExprNum:
+ numname: str
+ valname: str
+
+ def __init__(self, numname: str, valname: str) -> None:
+ self.numname = numname
+ self.valname = valname
+
+
+type ExprTok = ExprOp | ExprLit | ExprSym | ExprOff | ExprNum
+
+
+class Expr:
+ tokens: typing.Sequence[ExprTok]
+ const: int | None
+
+ def __init__(
+ self, env: dict[str, "Type"], tokens: typing.Sequence[ExprTok] = ()
+ ) -> None:
+ self.tokens = tokens
+ self.const = self._const(env, tokens)
+
+ def _const(
+ self, env: dict[str, "Type"], toks: typing.Sequence[ExprTok]
+ ) -> int | None:
+ if not toks:
+ return None
+
+ def read_val() -> int | None:
+ nonlocal toks
+ assert toks
+ neg = False
+ match toks[0]:
+ case ExprOp(op="-"):
+ neg = True
+ toks = toks[1:]
+ assert not isinstance(toks[0], ExprOp)
+ val: int
+ match toks[0]:
+ case ExprLit():
+ val = toks[0].val
+ case ExprSym():
+ if m := re.fullmatch(r"^u(8|16|32|64)_max$", toks[0].symname):
+ n = int(m.group(1))
+ val = (1 << n) - 1
+ elif m := re.fullmatch(r"^s(8|16|32|64)_max$", toks[0].symname):
+ n = int(m.group(1))
+ val = (1 << (n - 1)) - 1
+ else:
+ return None
+ case ExprOff():
+ return None
+ case ExprNum():
+ num = get_type(env, toks[0].numname, Number)
+ if toks[0].valname not in num.vals:
+ raise NameError(
+ f"Type {toks[0].numname!r} does not have a value {toks[0].valname!r}"
+ )
+ _val = num.vals[toks[0].valname].const
+ if _val is None:
+ return None
+ val = _val
+ toks = toks[1:]
+ return -val if neg else val
+
+ ret = read_val()
+ if ret is None:
+ return None
+ while toks:
+ assert isinstance(toks[0], ExprOp)
+ op = toks[0].op
+ toks = toks[1:]
+ operand = read_val()
+ if operand is None:
+ return None
+ match op:
+ case "+":
+ ret = ret + operand
+ case "-":
+ ret = ret - operand
+ case "<<":
+ ret = ret << operand
+ return ret
+
+ def __bool__(self) -> bool:
+ return len(self.tokens) > 0
+
+
class Number:
typname: str
in_versions: set[str]
prim: Primitive
- vals: dict[str, str]
+ vals: dict[str, Expr]
def __init__(self) -> None:
self.in_versions = set()
@@ -74,11 +203,31 @@ class Number:
return self.static_size
-class BitCat(enum.Enum):
- UNUSED = 1
- USED = 2
- RESERVED = 3
- SUBFIELD = 4
+class BitAlias:
+ bitname: str
+ in_versions: set[str]
+ val: Expr
+
+ def __init__(self, name: str, val: Expr) -> None:
+ if val.const is None:
+ raise ValueError(f"{name!r} value is not constant")
+ self.bitname = name
+ self.in_versions = set()
+ self.val = val
+
+
+class BitNum:
+ numname: str
+ mask: int
+ vals: dict[str, BitAlias]
+
+ def __init__(self, name: str) -> None:
+ self.numname = name
+ self.mask = 0
+ self.vals = {}
+
+
+type BitCat = typing.Literal["UNUSED", "USED", "RESERVED"] | BitNum
class Bit:
@@ -91,33 +240,32 @@ class Bit:
self.bitname = ""
self.in_versions = set()
self.num = num
- self.cat = BitCat.UNUSED
-
-
-class BitAlias:
- bitname: str
- in_versions: set[str]
- val: str # FIXME: Don't have bitfield aliases be raw C expressions
-
- def __init__(self, name: str, val: str) -> None:
- self.bitname = name
- self.in_versions = set()
- self.val = val
+ self.cat = "UNUSED"
class Bitfield:
typname: str
in_versions: set[str]
prim: Primitive
+
bits: list[Bit]
- names: dict[str, Bit | BitAlias]
+ nums: dict[str, BitNum]
+ masks: dict[str, BitAlias]
+ aliases: dict[str, BitAlias]
+
+ names: set[str]
def __init__(self, name: str, prim: Primitive) -> None:
self.typname = name
self.in_versions = set()
self.prim = prim
+
self.bits = [Bit(i) for i in range(prim.static_size * 8)]
- self.names = {}
+ self.nums = {}
+ self.masks = {}
+ self.aliases = {}
+
+ self.names = set()
@property
def static_size(self) -> int:
@@ -130,40 +278,9 @@ class Bitfield:
return self.static_size
-class ExprLit:
- val: int
-
- def __init__(self, val: int) -> None:
- self.val = val
-
-
-class ExprSym:
- symname: str
-
- def __init__(self, name: str) -> None:
- self.symname = name
-
-
-class ExprOp:
- op: typing.Literal["-", "+"]
-
- def __init__(self, op: typing.Literal["-", "+"]) -> None:
- self.op = op
-
-
-class Expr:
- tokens: list[ExprLit | ExprSym | ExprOp]
-
- def __init__(self) -> None:
- self.tokens = []
-
- def __bool__(self) -> bool:
- return len(self.tokens) > 0
-
-
class StructMember:
# from left-to-right when parsing
- cnt: "StructMember | None" = None
+ cnt: "StructMember| int | None" = None
membname: str
typ: "Type"
max: Expr
@@ -174,6 +291,8 @@ class StructMember:
@property
def min_cnt(self) -> int:
assert self.cnt
+ if isinstance(self.cnt, int):
+ return self.cnt
if not isinstance(self.cnt.typ, Primitive):
raise ValueError(
f"list count must be an integer type: {self.cnt.membname!r}"
@@ -185,6 +304,8 @@ class StructMember:
@property
def max_cnt(self) -> int:
assert self.cnt
+ if isinstance(self.cnt, int):
+ return self.cnt
if not isinstance(self.cnt.typ, Primitive):
raise ValueError(
f"list count must be an integer type: {self.cnt.membname!r}"
@@ -193,21 +314,12 @@ class StructMember:
raise ValueError(f"list count may not have ,val=: {self.cnt.membname!r}")
if self.cnt.max:
# TODO: be more flexible?
- if len(self.cnt.max.tokens) != 1:
+ val = self.cnt.max.const
+ if val is None:
raise ValueError(
- f"list count ,max= may only have 1 token: {self.cnt.membname!r}"
+ f"list count ,max= must be a constant value: {self.cnt.membname!r}"
)
- match tok := self.cnt.max.tokens[0]:
- case ExprLit():
- return tok.val
- case ExprSym(symname="s32_max"):
- return (1 << 31) - 1
- case ExprSym(symname="s64_max"):
- return (1 << 63) - 1
- case _:
- raise ValueError(
- f'list count ,max= only allows literal, "s32_max", and "s64_max" tokens: {self.cnt.membname!r}'
- )
+ return val
return (1 << (self.cnt.typ.value * 8)) - 1
@property
@@ -279,6 +391,8 @@ T = typing.TypeVar("T", Number, Bitfield, Struct, Message)
# Parse ########################################################################
+# common elements ######################
+
re_priname = "(?:1|2|4|8)" # primitive names
re_symname = "(?:[a-zA-Z_][a-zA-Z_0-9]*)" # "symbol" names; most *.9p-defined names
re_symname_u = "(?:[A-Z_][A-Z_0-9]*)" # upper-case "symbol" names; bit names
@@ -288,99 +402,186 @@ re_msgname = r"(?:[TR][a-zA-Z_0-9]*)" # names a message can be
re_memtype = f"(?:{re_symname}|{re_priname})" # typenames that a struct member can be
-re_expr = f"(?:(?:-|\\+|[0-9]+|&?{re_symname})+)"
+valid_syms = [
+ "end",
+ "u8_max",
+ "u16_max",
+ "u32_max",
+ "u64_max",
+ "s8_max",
+ "s16_max",
+ "s32_max",
+ "s64_max",
+]
-re_numspec = f"(?P<name>{re_symname})\\s*=\\s*(?P<val>\\S+)"
+_re_expr_op = r"(?:-|\+|<<)"
-re_bitspec_bit = (
- "(?P<bitnum>[0-9]+)\\s*=\\s*(?:"
+_res_expr_val = {
+ "lit_2": r"0b[01]+",
+ "lit_8": r"0[0-7]+",
+ "lit_10": r"0(?![0-9bxX])|[1-9][0-9]*",
+ "lit_16": r"0[xX][0-9a-fA-F]+",
+ "sym": "|".join(valid_syms), # pre-defined symbols
+ "off": f"&{re_symname}", # offset of a field this struct
+ "num": f"{re_symname}\\.{re_symname}", # `num` values
+}
+
+re_expr_tok = (
+ "(?:"
+ "|".join(
[
- f"(?P<name_used>{re_symname_u})",
- f"reserved\\((?P<name_reserved>{re_symname_u})\\)",
- f"subfield\\((?P<name_subfield>{re_symname_l})\\)",
+ f"(?P<op>{_re_expr_op})",
+ *[f"(?P<{k}>{v})" for k, v in _res_expr_val.items()],
]
)
+ ")"
)
-re_bitspec_alias = f"(?P<name>{re_symname_u})\\s*=\\s*(?P<val>\\S+)"
-re_memberspec = f"(?:(?P<cnt>{re_symname})\\*\\()?(?P<name>{re_symname})\\[(?P<typ>{re_memtype})(?:,max=(?P<max>{re_expr})|,val=(?P<val>{re_expr}))*\\]\\)?"
+_re_expr_val = "(?:" + "|".join(_res_expr_val.values()) + ")"
+re_expr = f"(?:\\s*(?:-\\s*)?{_re_expr_val}\\s*(?:{_re_expr_op}\\s*(?:-\\s*)?{_re_expr_val}\\s*)*)"
-def parse_numspec(ver: str, n: Number, spec: str) -> None:
+
+def parse_expr(env: dict[str, Type], expr: str) -> Expr:
+ assert re.fullmatch(re_expr, expr)
+ tokens: list[ExprTok] = []
+ for m in re.finditer(re_expr_tok, expr):
+ if tok := m.group("op"):
+ tokens.append(ExprOp(typing.cast(typing.Literal["-", "+", "<<"], tok)))
+ elif tok := m.group("lit_2"):
+ tokens.append(ExprLit(int(tok[2:], 2)))
+ elif tok := m.group("lit_8"):
+ tokens.append(ExprLit(int(tok[1:], 8)))
+ elif tok := m.group("lit_10"):
+ tokens.append(ExprLit(int(tok, 10)))
+ elif tok := m.group("lit_16"):
+ tokens.append(ExprLit(int(tok[2:], 16)))
+ elif tok := m.group("sym"):
+ tokens.append(ExprSym(tok))
+ elif tok := m.group("off"):
+ tokens.append(ExprOff(tok[1:]))
+ elif tok := m.group("num"):
+ [numname, valname] = tok.split(".", 1)
+ tokens.append(ExprNum(numname, valname))
+ else:
+ assert False
+ return Expr(env, tokens)
+
+
+# numspec ##############################
+
+re_numspec = f"(?P<name>{re_symname})\\s*=\\s*(?P<val>{re_expr})"
+
+
+def parse_numspec(env: dict[str, Type], ver: str, n: Number, spec: str) -> None:
spec = spec.strip()
if m := re.fullmatch(re_numspec, spec):
name = m.group("name")
- val = m.group("val")
if name in n.vals:
raise ValueError(f"{n.typname}: name {name!r} already assigned")
+ val = parse_expr(env, m.group("val"))
+ if val is None:
+ raise ValueError(
+ f"{n.typname}: {name!r} value is not constant: {m.group('val')!r}"
+ )
n.vals[name] = val
else:
raise SyntaxError(f"invalid num spec {spec!r}")
-def parse_bitspec(ver: str, bf: Bitfield, spec: str) -> None:
+# bitspec ##############################
+
+re_bitspec_bit = (
+ "bit\\s+(?P<bitnum>[0-9]+)\\s*=\\s*(?:"
+ + "|".join(
+ [
+ f"(?P<name_used>{re_symname_u})",
+ f"reserved\\((?P<name_reserved>{re_symname_u})\\)",
+ f"num\\((?P<name_num>{re_symname_u})\\)",
+ ]
+ )
+ + ")"
+)
+re_bitspec_mask = f"mask\\s+(?P<name>{re_symname_u})\\s*=\\s*(?P<val>{re_expr})"
+re_bitspec_alias = f"alias\\s+(?P<name>{re_symname_u})\\s*=\\s*(?P<val>{re_expr})"
+re_bitspec_num = f"num\\((?P<num>{re_symname_u})\\)\\s+(?P<name>{re_symname_u})\\s*=\\s*(?P<val>{re_expr})"
+
+
+def parse_bitspec(env: dict[str, Type], ver: str, bf: Bitfield, spec: str) -> None:
spec = spec.strip()
+ def check_name(name: str, is_num: bool = False) -> None:
+ if name == "MASK":
+ raise ValueError(f"{bf.typname}: bit name may not be {'MASK'!r}: {name!r}")
+ if name.endswith("_MASK"):
+ raise ValueError(
+ f"{bf.typname}: bit name may not end with {'_MASK'!r}: {name!r}"
+ )
+ if name in bf.names and not (is_num and name in bf.nums):
+ raise ValueError(f"{bf.typname}: bit name already assigned: {name!r}")
+
if m := re.fullmatch(re_bitspec_bit, spec):
bitnum = int(m.group("bitnum"))
if bitnum < 0 or bitnum >= len(bf.bits):
raise ValueError(f"{bf.typname}: bit num {bitnum} out-of-bounds")
bit = bf.bits[bitnum]
- if bit.cat != BitCat.UNUSED:
+ if bit.cat != "UNUSED":
raise ValueError(f"{bf.typname}: bit num {bitnum} already assigned")
if name := m.group("name_used"):
bit.bitname = name
- bit.cat = BitCat.USED
+ bit.cat = "USED"
bit.in_versions.add(ver)
elif name := m.group("name_reserved"):
bit.bitname = name
- bit.cat = BitCat.RESERVED
+ bit.cat = "RESERVED"
bit.in_versions.add(ver)
- elif name := m.group("name_subfield"):
+ elif name := m.group("name_num"):
bit.bitname = name
- bit.cat = BitCat.SUBFIELD
+ if name not in bf.nums:
+ bf.nums[name] = BitNum(name)
+ bf.nums[name].mask |= 1 << bit.num
+ bit.cat = bf.nums[name]
bit.in_versions.add(ver)
if bit.bitname:
- if bit.bitname in bf.names:
- other = bf.names[bit.bitname]
- if (
- isinstance(other, Bit)
- and other.cat == bit.cat
- and bit.cat == BitCat.SUBFIELD
- ):
- return
- raise ValueError(
- f"{bf.typname}: bit name {bit.bitname!r} already assigned"
- )
- bf.names[bit.bitname] = bit
+ check_name(name, isinstance(bit.cat, BitNum))
+ bf.names.add(bit.bitname)
+ elif m := re.fullmatch(re_bitspec_mask, spec):
+ mask = BitAlias(m.group("name"), parse_expr(env, m.group("val")))
+ mask.in_versions.add(ver)
+ check_name(mask.bitname)
+ bf.masks[mask.bitname] = mask
+ bf.names.add(mask.bitname)
elif m := re.fullmatch(re_bitspec_alias, spec):
- alias = BitAlias(m.group("name"), m.group("val"))
+ alias = BitAlias(m.group("name"), parse_expr(env, m.group("val")))
alias.in_versions.add(ver)
- if alias.bitname in bf.names:
+ check_name(alias.bitname)
+ bf.aliases[alias.bitname] = alias
+ bf.names.add(alias.bitname)
+ elif m := re.fullmatch(re_bitspec_num, spec):
+ numname = m.group("num")
+ alias = BitAlias(m.group("name"), parse_expr(env, m.group("val")))
+ alias.in_versions.add(ver)
+ check_name(alias.bitname)
+ if numname not in bf.nums:
+ raise NameError(
+ f"{bf.typname}: nested num not allocated any bits: {numname!r}"
+ )
+ assert alias.val.const is not None
+ if alias.val.const & ~bf.nums[numname].mask:
raise ValueError(
- f"{bf.typname}: bit name {alias.bitname!r} already assigned"
+ f"{bf.typname}: {alias.bitname!r} does not fit within bitmask: val={alias.val.const:b} mask={bf.nums[numname].mask}"
)
- bf.names[alias.bitname] = alias
+ bf.nums[numname].vals[alias.bitname] = alias
+ bf.names.add(alias.bitname)
else:
raise SyntaxError(f"invalid bitfield spec {spec!r}")
-def parse_expr(expr: str) -> Expr:
- assert re.fullmatch(re_expr, expr)
- ret = Expr()
- for tok in re.split("([-+])", expr):
- if tok in ("-", "+"):
- # I, for the life of me, do not understand why I need this
- # typing.cast() to keep mypy happy.
- ret.tokens += [ExprOp(typing.cast(typing.Literal["-", "+"], tok))]
- elif re.fullmatch("[0-9]+", tok):
- ret.tokens += [ExprLit(int(tok))]
- else:
- ret.tokens += [ExprSym(tok)]
- return ret
+# struct members #######################
+
+
+re_memberspec = f"(?:(?P<cnt>{re_symname}|[1-9][0-9]*)\\*\\()?(?P<name>{re_symname})\\[(?P<typ>{re_memtype})(?:,max=(?P<max>{re_expr})|,val=(?P<val>{re_expr}))*\\]\\)?"
def parse_members(ver: str, env: dict[str, Type], struct: Struct, specs: str) -> None:
@@ -401,29 +602,44 @@ def parse_members(ver: str, env: dict[str, Type], struct: Struct, specs: str) ->
member.typ = env[m.group("typ")]
if cnt := m.group("cnt"):
- if len(struct.members) == 0 or struct.members[-1].membname != cnt:
- raise ValueError(f"list count must be previous item: {cnt!r}")
- cnt_mem = struct.members[-1]
- member.cnt = cnt_mem
- _ = member.max_cnt # force validation
+ if cnt.isnumeric():
+ member.cnt = int(cnt)
+ else:
+ if len(struct.members) == 0 or struct.members[-1].membname != cnt:
+ raise ValueError(f"list count must be previous item: {cnt!r}")
+ member.cnt = struct.members[-1]
+ _ = member.max_cnt # force validation
if maxstr := m.group("max"):
- if (not isinstance(member.typ, Primitive)) or member.cnt:
- raise ValueError("',max=' may only be specified on a non-repeated atom")
- member.max = parse_expr(maxstr)
+ if (
+ not isinstance(member.typ, Primitive)
+ and not isinstance(member.typ, Number)
+ ) or member.cnt:
+ raise ValueError(
+ "',max=' may only be specified on a non-repeated numeric type"
+ )
+ member.max = parse_expr(env, maxstr)
else:
- member.max = Expr()
+ member.max = Expr(env)
if valstr := m.group("val"):
- if (not isinstance(member.typ, Primitive)) or member.cnt:
- raise ValueError("',val=' may only be specified on a non-repeated atom")
- member.val = parse_expr(valstr)
+ if (
+ not isinstance(member.typ, Primitive)
+ and not isinstance(member.typ, Number)
+ ) or member.cnt:
+ raise ValueError(
+ "',val=' may only be specified on a non-repeated numeric type"
+ )
+ member.val = parse_expr(env, valstr)
else:
- member.val = Expr()
+ member.val = Expr(env)
struct.members += [member]
+# main parser ##########################
+
+
def re_string(grpname: str) -> str:
return f'"(?P<{grpname}>[^"]*)"'
@@ -455,15 +671,6 @@ def parse_file(
"8": Primitive.u64,
}
- def get_type(name: str, tc: type[T]) -> T:
- nonlocal env
- if name not in env:
- raise NameError(f"Unknown type {name!r}")
- ret = env[name]
- if (not isinstance(ret, tc)) or (ret.__class__.__name__ != tc.__name__):
- raise NameError(f"Type {ret.typname!r} is not a {tc.__name__}")
- return ret
-
with open(filename, "r", encoding="utf-8") as fh:
prev: Type | None = None
for lineno, line in enumerate(fh):
@@ -494,12 +701,19 @@ def parse_file(
typ.in_versions.add(version)
case Bitfield():
typ.in_versions.add(version)
- for bit in typ.bits:
- if other_version in bit.in_versions:
- bit.in_versions.add(version)
- for val in typ.names.values():
- if other_version in val.in_versions:
- val.in_versions.add(version)
+ for bf_bit in typ.bits:
+ if other_version in bf_bit.in_versions:
+ bf_bit.in_versions.add(version)
+ for bf_num in typ.nums.values():
+ for bf_val in bf_num.vals.values():
+ if other_version in bf_val.in_versions:
+ bf_val.in_versions.add(version)
+ for bf_mask in typ.masks.values():
+ if other_version in bf_mask.in_versions:
+ bf_mask.in_versions.add(version)
+ for bf_alias in typ.aliases.values():
+ if other_version in bf_alias.in_versions:
+ bf_alias.in_versions.add(version)
case Struct(): # and Message()
typ.in_versions.add(version)
for member in typ.members:
@@ -539,8 +753,8 @@ def parse_file(
env[bf.typname] = bf
prev = bf
elif m := re.fullmatch(re_line_bitfield_, line):
- bf = get_type(m.group("name"), Bitfield)
- parse_bitspec(version, bf, m.group("member"))
+ bf = get_type(env, m.group("name"), Bitfield)
+ parse_bitspec(env, version, bf, m.group("member"))
prev = bf
elif m := re.fullmatch(re_line_struct, line):
@@ -559,7 +773,7 @@ def parse_file(
env[struct.typname] = struct
prev = struct
case "+=":
- struct = get_type(m.group("name"), Struct)
+ struct = get_type(env, m.group("name"), Struct)
parse_members(version, env, struct, m.group("members"))
prev = struct
@@ -577,16 +791,16 @@ def parse_file(
env[msg.typname] = msg
prev = msg
case "+=":
- msg = get_type(m.group("name"), Message)
+ msg = get_type(env, m.group("name"), Message)
parse_members(version, env, msg, m.group("members"))
prev = msg
elif m := re.fullmatch(re_line_cont, line):
match prev:
case Bitfield():
- parse_bitspec(version, prev, m.group("specs"))
+ parse_bitspec(env, version, prev, m.group("specs"))
case Number():
- parse_numspec(version, prev, m.group("specs"))
+ parse_numspec(env, version, prev, m.group("specs"))
case Struct(): # and Message()
parse_members(version, env, prev, m.group("specs"))
case _:
@@ -607,12 +821,6 @@ def parse_file(
typs: list[UserType] = [x for x in env.values() if not isinstance(x, Primitive)]
for typ in [typ for typ in typs if isinstance(typ, Struct)]:
- valid_syms = [
- "end",
- "s32_max",
- "s64_max",
- *["&" + m.membname for m in typ.members],
- ]
for member in typ.members:
if (
not isinstance(member.typ, Primitive)
@@ -622,9 +830,11 @@ def parse_file(
f"{typ.typname}.{member.membname}: type {member.typ.typname} does not exist in {member.in_versions.difference(member.typ.in_versions)}"
)
for tok in [*member.max.tokens, *member.val.tokens]:
- if isinstance(tok, ExprSym) and tok.symname not in valid_syms:
- raise ValueError(
- f"{typ.typname}.{member.membname}: invalid sym: {tok.symname}"
+ if isinstance(tok, ExprOff) and not any(
+ m.membname == tok.membname for m in typ.members
+ ):
+ raise NameError(
+ f"{typ.typname}.{member.membname}: invalid offset: &{tok.membname}"
)
return version, typs
diff --git a/lib9p/include/lib9p/9p.generated.h b/lib9p/include/lib9p/9p.generated.h
index 7a50537..7e901a3 100644
--- a/lib9p/include/lib9p/9p.generated.h
+++ b/lib9p/include/lib9p/9p.generated.h
@@ -6,6 +6,7 @@
#include <stdint.h> /* for uint{n}_t types */
+#include <libfmt/fmt.h> /* for fmt_formatter */
#include <libhw/generic/net.h> /* for struct iovec */
/* config *********************************************************************/
@@ -60,6 +61,7 @@ enum lib9p_version {
#endif /* CONFIG_9P_ENABLE_9P2000_u */
LIB9P_VER_NUM,
};
+LO_IMPLEMENTATION_H(fmt_formatter, enum lib9p_version, lib9p_version);
/* enum msg_type **************************************************************/
@@ -153,386 +155,408 @@ enum lib9p_msg_type { /* uint8_t */
LIB9P_TYP_Rswrite = 155,
#endif /* CONFIG_9P_ENABLE_9P2000_e */
};
+LO_IMPLEMENTATION_H(fmt_formatter, enum lib9p_msg_type, lib9p_msg_type);
/* payload types **************************************************************/
#if CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u
/* size = 2 ; max_iov = 1 ; max_copy = 2 */
typedef uint16_t lib9p_tag_t;
-#define LIB9P_TAG_NOTAG ((lib9p_tag_t)UINT16_C(~0))
+LO_IMPLEMENTATION_H(fmt_formatter, lib9p_tag_t, lib9p_tag);
+#define LIB9P_TAG_NOTAG ((lib9p_tag_t)(UINT16_MAX))
/* size = 4 ; max_iov = 1 ; max_copy = 4 */
typedef uint32_t lib9p_fid_t;
-#define LIB9P_FID_NOFID ((lib9p_fid_t)UINT32_C(~0))
+LO_IMPLEMENTATION_H(fmt_formatter, lib9p_fid_t, lib9p_fid);
+#define LIB9P_FID_NOFID ((lib9p_fid_t)(UINT32_MAX))
/* min_size = 2 ; exp_size = 29 ; max_size = 65,537 ; max_iov = 2 ; max_copy = 2 */
struct lib9p_s {
uint16_t len;
[[gnu::nonstring]] char *utf8;
};
+LO_IMPLEMENTATION_H(fmt_formatter, struct lib9p_s, lib9p_s);
#endif /* CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u */
#if CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u
/* size = 4 ; max_iov = 1 ; max_copy = 4 */
typedef uint32_t lib9p_dm_t;
-
-#define LIB9P_DM_DIR ((lib9p_dm_t)(1<<31))
-#define LIB9P_DM_APPEND ((lib9p_dm_t)(1<<30))
-#define LIB9P_DM_EXCL ((lib9p_dm_t)(1<<29))
-#define _LIB9P_DM_RESERVED_PLAN9_MOUNT ((lib9p_dm_t)(1<<28))
-#define LIB9P_DM_AUTH ((lib9p_dm_t)(1<<27))
-#define LIB9P_DM_TMP ((lib9p_dm_t)(1<<26))
-/* unused ((lib9p_dm_t)(1<<25)) */
-/* unused ((lib9p_dm_t)(1<<24)) */
+LO_IMPLEMENTATION_H(fmt_formatter, lib9p_dm_t, lib9p_dm);
+/* bits */
+#define LIB9P_DM_DIR ((lib9p_dm_t)(UINT32_C(1)<<31))
+#define LIB9P_DM_APPEND ((lib9p_dm_t)(UINT32_C(1)<<30))
+#define LIB9P_DM_EXCL ((lib9p_dm_t)(UINT32_C(1)<<29))
+#define _LIB9P_DM_PLAN9_MOUNT ((lib9p_dm_t)(UINT32_C(1)<<28))
+#define LIB9P_DM_AUTH ((lib9p_dm_t)(UINT32_C(1)<<27))
+#define LIB9P_DM_TMP ((lib9p_dm_t)(UINT32_C(1)<<26))
+#define _LIB9P_DM_UNUSED_25 ((lib9p_dm_t)(UINT32_C(1)<<25))
+#define _LIB9P_DM_UNUSED_24 ((lib9p_dm_t)(UINT32_C(1)<<24))
#if CONFIG_9P_ENABLE_9P2000_u
-# define LIB9P_DM_DEVICE ((lib9p_dm_t)(1<<23))
+# define LIB9P_DM_DEVICE ((lib9p_dm_t)(UINT32_C(1)<<23))
#endif /* CONFIG_9P_ENABLE_9P2000_u */
-/* unused ((lib9p_dm_t)(1<<22)) */
+#define _LIB9P_DM_UNUSED_22 ((lib9p_dm_t)(UINT32_C(1)<<22))
#if CONFIG_9P_ENABLE_9P2000_u
-# define LIB9P_DM_NAMEDPIPE ((lib9p_dm_t)(1<<21))
-# define LIB9P_DM_SOCKET ((lib9p_dm_t)(1<<20))
-# define LIB9P_DM_SETUID ((lib9p_dm_t)(1<<19))
-# define LIB9P_DM_SETGID ((lib9p_dm_t)(1<<18))
+# define LIB9P_DM_PIPE ((lib9p_dm_t)(UINT32_C(1)<<21))
+# define LIB9P_DM_SOCKET ((lib9p_dm_t)(UINT32_C(1)<<20))
+# define LIB9P_DM_SETUID ((lib9p_dm_t)(UINT32_C(1)<<19))
+# define LIB9P_DM_SETGID ((lib9p_dm_t)(UINT32_C(1)<<18))
#endif /* CONFIG_9P_ENABLE_9P2000_u */
-/* unused ((lib9p_dm_t)(1<<17)) */
-/* unused ((lib9p_dm_t)(1<<16)) */
-/* unused ((lib9p_dm_t)(1<<15)) */
-/* unused ((lib9p_dm_t)(1<<14)) */
-/* unused ((lib9p_dm_t)(1<<13)) */
-/* unused ((lib9p_dm_t)(1<<12)) */
-/* unused ((lib9p_dm_t)(1<<11)) */
-/* unused ((lib9p_dm_t)(1<<10)) */
-/* unused ((lib9p_dm_t)(1<<9)) */
-#define LIB9P_DM_OWNER_R ((lib9p_dm_t)(1<<8))
-#define LIB9P_DM_OWNER_W ((lib9p_dm_t)(1<<7))
-#define LIB9P_DM_OWNER_X ((lib9p_dm_t)(1<<6))
-#define LIB9P_DM_GROUP_R ((lib9p_dm_t)(1<<5))
-#define LIB9P_DM_GROUP_W ((lib9p_dm_t)(1<<4))
-#define LIB9P_DM_GROUP_X ((lib9p_dm_t)(1<<3))
-#define LIB9P_DM_OTHER_R ((lib9p_dm_t)(1<<2))
-#define LIB9P_DM_OTHER_W ((lib9p_dm_t)(1<<1))
-#define LIB9P_DM_OTHER_X ((lib9p_dm_t)(1<<0))
-
-#define LIB9P_DM_PERM_MASK ((lib9p_dm_t)(0777))
+#define _LIB9P_DM_UNUSED_17 ((lib9p_dm_t)(UINT32_C(1)<<17))
+#define _LIB9P_DM_UNUSED_16 ((lib9p_dm_t)(UINT32_C(1)<<16))
+#define _LIB9P_DM_UNUSED_15 ((lib9p_dm_t)(UINT32_C(1)<<15))
+#define _LIB9P_DM_UNUSED_14 ((lib9p_dm_t)(UINT32_C(1)<<14))
+#define _LIB9P_DM_UNUSED_13 ((lib9p_dm_t)(UINT32_C(1)<<13))
+#define _LIB9P_DM_UNUSED_12 ((lib9p_dm_t)(UINT32_C(1)<<12))
+#define _LIB9P_DM_UNUSED_11 ((lib9p_dm_t)(UINT32_C(1)<<11))
+#define _LIB9P_DM_UNUSED_10 ((lib9p_dm_t)(UINT32_C(1)<<10))
+#define _LIB9P_DM_UNUSED_9 ((lib9p_dm_t)(UINT32_C(1)<<9))
+#define LIB9P_DM_OWNER_R ((lib9p_dm_t)(UINT32_C(1)<<8))
+#define LIB9P_DM_OWNER_W ((lib9p_dm_t)(UINT32_C(1)<<7))
+#define LIB9P_DM_OWNER_X ((lib9p_dm_t)(UINT32_C(1)<<6))
+#define LIB9P_DM_GROUP_R ((lib9p_dm_t)(UINT32_C(1)<<5))
+#define LIB9P_DM_GROUP_W ((lib9p_dm_t)(UINT32_C(1)<<4))
+#define LIB9P_DM_GROUP_X ((lib9p_dm_t)(UINT32_C(1)<<3))
+#define LIB9P_DM_OTHER_R ((lib9p_dm_t)(UINT32_C(1)<<2))
+#define LIB9P_DM_OTHER_W ((lib9p_dm_t)(UINT32_C(1)<<1))
+#define LIB9P_DM_OTHER_X ((lib9p_dm_t)(UINT32_C(1)<<0))
+/* masks */
+#define LIB9P_DM_PERM_MASK ((lib9p_dm_t)(0b000000000000000000000111111111))
#endif /* CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u */
#if CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u
/* size = 1 ; max_iov = 1 ; max_copy = 1 */
typedef uint8_t lib9p_qt_t;
-
-#define LIB9P_QT_DIR ((lib9p_qt_t)(1<<7))
-#define LIB9P_QT_APPEND ((lib9p_qt_t)(1<<6))
-#define LIB9P_QT_EXCL ((lib9p_qt_t)(1<<5))
-#define _LIB9P_QT_RESERVED_PLAN9_MOUNT ((lib9p_qt_t)(1<<4))
-#define LIB9P_QT_AUTH ((lib9p_qt_t)(1<<3))
-#define LIB9P_QT_TMP ((lib9p_qt_t)(1<<2))
+LO_IMPLEMENTATION_H(fmt_formatter, lib9p_qt_t, lib9p_qt);
+/* bits */
+#define LIB9P_QT_DIR ((lib9p_qt_t)(UINT8_C(1)<<7))
+#define LIB9P_QT_APPEND ((lib9p_qt_t)(UINT8_C(1)<<6))
+#define LIB9P_QT_EXCL ((lib9p_qt_t)(UINT8_C(1)<<5))
+#define _LIB9P_QT_PLAN9_MOUNT ((lib9p_qt_t)(UINT8_C(1)<<4))
+#define LIB9P_QT_AUTH ((lib9p_qt_t)(UINT8_C(1)<<3))
+#define LIB9P_QT_TMP ((lib9p_qt_t)(UINT8_C(1)<<2))
#if CONFIG_9P_ENABLE_9P2000_u
-# define LIB9P_QT_SYMLINK ((lib9p_qt_t)(1<<1))
+# define LIB9P_QT_SYMLINK ((lib9p_qt_t)(UINT8_C(1)<<1))
#endif /* CONFIG_9P_ENABLE_9P2000_u */
-/* unused ((lib9p_qt_t)(1<<0)) */
-
-#define LIB9P_QT_FILE ((lib9p_qt_t)(0))
+#define _LIB9P_QT_UNUSED_0 ((lib9p_qt_t)(UINT8_C(1)<<0))
+/* aliases */
+#define LIB9P_QT_FILE ((lib9p_qt_t)(0))
#endif /* CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u */
#if CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_u
/* size = 4 ; max_iov = 1 ; max_copy = 4 */
typedef uint32_t lib9p_nuid_t;
-#define LIB9P_NUID_NONUID ((lib9p_nuid_t)UINT32_C(~0))
+LO_IMPLEMENTATION_H(fmt_formatter, lib9p_nuid_t, lib9p_nuid);
+#define LIB9P_NUID_NONUID ((lib9p_nuid_t)(UINT32_MAX))
#endif /* CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_u */
#if CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u
/* size = 1 ; max_iov = 1 ; max_copy = 1 */
typedef uint8_t lib9p_o_t;
-
-/* unused ((lib9p_o_t)(1<<7)) */
-#define LIB9P_O_RCLOSE ((lib9p_o_t)(1<<6))
-#define _LIB9P_O_RESERVED_CEXEC ((lib9p_o_t)(1<<5))
-#define LIB9P_O_TRUNC ((lib9p_o_t)(1<<4))
-/* unused ((lib9p_o_t)(1<<3)) */
-/* unused ((lib9p_o_t)(1<<2)) */
-#define _LIB9P_O_mode_1 ((lib9p_o_t)(1<<1))
-#define _LIB9P_O_mode_0 ((lib9p_o_t)(1<<0))
-
-#define LIB9P_O_READ ((lib9p_o_t)(0))
-#define LIB9P_O_WRITE ((lib9p_o_t)(1))
-#define LIB9P_O_RDWR ((lib9p_o_t)(2))
-#define LIB9P_O_EXEC ((lib9p_o_t)(3))
-#define LIB9P_O_MODE_MASK ((lib9p_o_t)(0b00000011))
+LO_IMPLEMENTATION_H(fmt_formatter, lib9p_o_t, lib9p_o);
+/* bits */
+#define _LIB9P_O_UNUSED_7 ((lib9p_o_t)(UINT8_C(1)<<7))
+#define LIB9P_O_RCLOSE ((lib9p_o_t)(UINT8_C(1)<<6))
+#define _LIB9P_O_RESERVED_CEXEC ((lib9p_o_t)(UINT8_C(1)<<5))
+#define LIB9P_O_TRUNC ((lib9p_o_t)(UINT8_C(1)<<4))
+#define _LIB9P_O_UNUSED_3 ((lib9p_o_t)(UINT8_C(1)<<3))
+#define _LIB9P_O_UNUSED_2 ((lib9p_o_t)(UINT8_C(1)<<2))
+/* number LIB9P_O_MODE_* ((lib9p_o_t)(UINT8_C(1)<<1)) */
+/* number LIB9P_O_MODE_* ((lib9p_o_t)(UINT8_C(1)<<0)) */
+/* masks */
#define LIB9P_O_FLAG_MASK ((lib9p_o_t)(0b11111100))
+/* number: MODE */
+#define LIB9P_O_MODE_READ ((lib9p_o_t)(0))
+#define LIB9P_O_MODE_WRITE ((lib9p_o_t)(1))
+#define LIB9P_O_MODE_RDWR ((lib9p_o_t)(2))
+#define LIB9P_O_MODE_EXEC ((lib9p_o_t)(3))
+#define LIB9P_O_MODE_MASK ((lib9p_o_t)(0b000011))
#endif /* CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u */
#if CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_u
/* size = 4 ; max_iov = 1 ; max_copy = 4 */
typedef uint32_t lib9p_errno_t;
-#define LIB9P_ERRNO_NOERROR ((lib9p_errno_t)UINT32_C(0))
+LO_IMPLEMENTATION_H(fmt_formatter, lib9p_errno_t, lib9p_errno);
+#define LIB9P_ERRNO_NOERROR ((lib9p_errno_t)(0))
#endif /* CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_u */
#if CONFIG_9P_ENABLE_9P2000_L
/* size = 4 ; max_iov = 1 ; max_copy = 4 */
typedef uint32_t lib9p_super_magic_t;
-#define LIB9P_SUPER_MAGIC_V9FS_MAGIC ((lib9p_super_magic_t)UINT32_C(0x01021997))
+LO_IMPLEMENTATION_H(fmt_formatter, lib9p_super_magic_t, lib9p_super_magic);
+#define LIB9P_SUPER_MAGIC_V9FS_MAGIC ((lib9p_super_magic_t)(16914839))
/* size = 4 ; max_iov = 1 ; max_copy = 4 */
typedef uint32_t lib9p_lo_t;
-
-/* unused ((lib9p_lo_t)(1<<31)) */
-/* unused ((lib9p_lo_t)(1<<30)) */
-/* unused ((lib9p_lo_t)(1<<29)) */
-/* unused ((lib9p_lo_t)(1<<28)) */
-/* unused ((lib9p_lo_t)(1<<27)) */
-/* unused ((lib9p_lo_t)(1<<26)) */
-/* unused ((lib9p_lo_t)(1<<25)) */
-/* unused ((lib9p_lo_t)(1<<24)) */
-/* unused ((lib9p_lo_t)(1<<23)) */
-/* unused ((lib9p_lo_t)(1<<22)) */
-/* unused ((lib9p_lo_t)(1<<21)) */
-#define LIB9P_LO_SYNC ((lib9p_lo_t)(1<<20))
-#define LIB9P_LO_CLOEXEC ((lib9p_lo_t)(1<<19))
-#define LIB9P_LO_NOATIME ((lib9p_lo_t)(1<<18))
-#define LIB9P_LO_NOFOLLOW ((lib9p_lo_t)(1<<17))
-#define LIB9P_LO_DIRECTORY ((lib9p_lo_t)(1<<16))
-#define LIB9P_LO_LARGEFILE ((lib9p_lo_t)(1<<15))
-#define LIB9P_LO_DIRECT ((lib9p_lo_t)(1<<14))
-#define LIB9P_LO_BSD_FASYNC ((lib9p_lo_t)(1<<13))
-#define LIB9P_LO_DSYNC ((lib9p_lo_t)(1<<12))
-#define LIB9P_LO_NONBLOCK ((lib9p_lo_t)(1<<11))
-#define LIB9P_LO_APPEND ((lib9p_lo_t)(1<<10))
-#define LIB9P_LO_TRUNC ((lib9p_lo_t)(1<<9))
-#define LIB9P_LO_NOCTTY ((lib9p_lo_t)(1<<8))
-#define LIB9P_LO_EXCL ((lib9p_lo_t)(1<<7))
-#define LIB9P_LO_CREATE ((lib9p_lo_t)(1<<6))
-/* unused ((lib9p_lo_t)(1<<5)) */
-/* unused ((lib9p_lo_t)(1<<4)) */
-/* unused ((lib9p_lo_t)(1<<3)) */
-/* unused ((lib9p_lo_t)(1<<2)) */
-#define _LIB9P_LO_mode_1 ((lib9p_lo_t)(1<<1))
-#define _LIB9P_LO_mode_0 ((lib9p_lo_t)(1<<0))
-
-#define LIB9P_LO_RDONLY ((lib9p_lo_t)(0))
-#define LIB9P_LO_WRONLY ((lib9p_lo_t)(1))
-#define LIB9P_LO_RDWR ((lib9p_lo_t)(2))
-#define LIB9P_LO_NOACCESS ((lib9p_lo_t)(3))
-#define LIB9P_LO_MODE_MASK ((lib9p_lo_t)(0b000000000000000000011))
-#define LIB9P_LO_FLAG_MASK ((lib9p_lo_t)(0b111111111111111000000))
+LO_IMPLEMENTATION_H(fmt_formatter, lib9p_lo_t, lib9p_lo);
+/* bits */
+#define _LIB9P_LO_UNUSED_31 ((lib9p_lo_t)(UINT32_C(1)<<31))
+#define _LIB9P_LO_UNUSED_30 ((lib9p_lo_t)(UINT32_C(1)<<30))
+#define _LIB9P_LO_UNUSED_29 ((lib9p_lo_t)(UINT32_C(1)<<29))
+#define _LIB9P_LO_UNUSED_28 ((lib9p_lo_t)(UINT32_C(1)<<28))
+#define _LIB9P_LO_UNUSED_27 ((lib9p_lo_t)(UINT32_C(1)<<27))
+#define _LIB9P_LO_UNUSED_26 ((lib9p_lo_t)(UINT32_C(1)<<26))
+#define _LIB9P_LO_UNUSED_25 ((lib9p_lo_t)(UINT32_C(1)<<25))
+#define _LIB9P_LO_UNUSED_24 ((lib9p_lo_t)(UINT32_C(1)<<24))
+#define _LIB9P_LO_UNUSED_23 ((lib9p_lo_t)(UINT32_C(1)<<23))
+#define _LIB9P_LO_UNUSED_22 ((lib9p_lo_t)(UINT32_C(1)<<22))
+#define _LIB9P_LO_UNUSED_21 ((lib9p_lo_t)(UINT32_C(1)<<21))
+#define LIB9P_LO_SYNC ((lib9p_lo_t)(UINT32_C(1)<<20))
+#define LIB9P_LO_CLOEXEC ((lib9p_lo_t)(UINT32_C(1)<<19))
+#define LIB9P_LO_NOATIME ((lib9p_lo_t)(UINT32_C(1)<<18))
+#define LIB9P_LO_NOFOLLOW ((lib9p_lo_t)(UINT32_C(1)<<17))
+#define LIB9P_LO_DIRECTORY ((lib9p_lo_t)(UINT32_C(1)<<16))
+#define LIB9P_LO_LARGEFILE ((lib9p_lo_t)(UINT32_C(1)<<15))
+#define LIB9P_LO_DIRECT ((lib9p_lo_t)(UINT32_C(1)<<14))
+#define LIB9P_LO_BSD_FASYNC ((lib9p_lo_t)(UINT32_C(1)<<13))
+#define LIB9P_LO_DSYNC ((lib9p_lo_t)(UINT32_C(1)<<12))
+#define LIB9P_LO_NONBLOCK ((lib9p_lo_t)(UINT32_C(1)<<11))
+#define LIB9P_LO_APPEND ((lib9p_lo_t)(UINT32_C(1)<<10))
+#define LIB9P_LO_TRUNC ((lib9p_lo_t)(UINT32_C(1)<<9))
+#define LIB9P_LO_NOCTTY ((lib9p_lo_t)(UINT32_C(1)<<8))
+#define LIB9P_LO_EXCL ((lib9p_lo_t)(UINT32_C(1)<<7))
+#define LIB9P_LO_CREATE ((lib9p_lo_t)(UINT32_C(1)<<6))
+#define _LIB9P_LO_UNUSED_5 ((lib9p_lo_t)(UINT32_C(1)<<5))
+#define _LIB9P_LO_UNUSED_4 ((lib9p_lo_t)(UINT32_C(1)<<4))
+#define _LIB9P_LO_UNUSED_3 ((lib9p_lo_t)(UINT32_C(1)<<3))
+#define _LIB9P_LO_UNUSED_2 ((lib9p_lo_t)(UINT32_C(1)<<2))
+/* number LIB9P_LO_MODE_* ((lib9p_lo_t)(UINT32_C(1)<<1)) */
+/* number LIB9P_LO_MODE_* ((lib9p_lo_t)(UINT32_C(1)<<0)) */
+/* masks */
+#define LIB9P_LO_FLAG_MASK ((lib9p_lo_t)(0b000000000111111111111111000000))
+/* number: MODE */
+#define LIB9P_LO_MODE_RDONLY ((lib9p_lo_t)(0))
+#define LIB9P_LO_MODE_WRONLY ((lib9p_lo_t)(1))
+#define LIB9P_LO_MODE_RDWR ((lib9p_lo_t)(2))
+#define LIB9P_LO_MODE_NOACCESS ((lib9p_lo_t)(3))
+#define LIB9P_LO_MODE_MASK ((lib9p_lo_t)(0b000000000000000000000000000011))
/* size = 1 ; max_iov = 1 ; max_copy = 1 */
typedef uint8_t lib9p_dt_t;
-#define LIB9P_DT_UNKNOWN ((lib9p_dt_t)UINT8_C(0))
-#define LIB9P_DT_NAMED_PIPE ((lib9p_dt_t)UINT8_C(1))
-#define LIB9P_DT_CHAR_DEV ((lib9p_dt_t)UINT8_C(2))
-#define LIB9P_DT_DIRECTORY ((lib9p_dt_t)UINT8_C(4))
-#define LIB9P_DT_BLOCK_DEV ((lib9p_dt_t)UINT8_C(6))
-#define LIB9P_DT_REGULAR ((lib9p_dt_t)UINT8_C(8))
-#define LIB9P_DT_SYMLINK ((lib9p_dt_t)UINT8_C(10))
-#define LIB9P_DT_SOCKET ((lib9p_dt_t)UINT8_C(12))
-#define LIB9P_DT_WHITEOUT ((lib9p_dt_t)UINT8_C(14))
+LO_IMPLEMENTATION_H(fmt_formatter, lib9p_dt_t, lib9p_dt);
+#define LIB9P_DT_UNKNOWN ((lib9p_dt_t)(0))
+#define LIB9P_DT_PIPE ((lib9p_dt_t)(1))
+#define LIB9P_DT_CHAR_DEV ((lib9p_dt_t)(2))
+#define LIB9P_DT_DIRECTORY ((lib9p_dt_t)(4))
+#define LIB9P_DT_BLOCK_DEV ((lib9p_dt_t)(6))
+#define LIB9P_DT_REGULAR ((lib9p_dt_t)(8))
+#define LIB9P_DT_SYMLINK ((lib9p_dt_t)(10))
+#define LIB9P_DT_SOCKET ((lib9p_dt_t)(12))
+#define _LIB9P_DT_WHITEOUT ((lib9p_dt_t)(14))
/* size = 4 ; max_iov = 1 ; max_copy = 4 */
typedef uint32_t lib9p_mode_t;
-
-/* unused ((lib9p_mode_t)(1<<31)) */
-/* unused ((lib9p_mode_t)(1<<30)) */
-/* unused ((lib9p_mode_t)(1<<29)) */
-/* unused ((lib9p_mode_t)(1<<28)) */
-/* unused ((lib9p_mode_t)(1<<27)) */
-/* unused ((lib9p_mode_t)(1<<26)) */
-/* unused ((lib9p_mode_t)(1<<25)) */
-/* unused ((lib9p_mode_t)(1<<24)) */
-/* unused ((lib9p_mode_t)(1<<23)) */
-/* unused ((lib9p_mode_t)(1<<22)) */
-/* unused ((lib9p_mode_t)(1<<21)) */
-/* unused ((lib9p_mode_t)(1<<20)) */
-/* unused ((lib9p_mode_t)(1<<19)) */
-/* unused ((lib9p_mode_t)(1<<18)) */
-/* unused ((lib9p_mode_t)(1<<17)) */
-/* unused ((lib9p_mode_t)(1<<16)) */
-#define _LIB9P_MODE_fmt_3 ((lib9p_mode_t)(1<<15))
-#define _LIB9P_MODE_fmt_2 ((lib9p_mode_t)(1<<14))
-#define _LIB9P_MODE_fmt_1 ((lib9p_mode_t)(1<<13))
-#define _LIB9P_MODE_fmt_0 ((lib9p_mode_t)(1<<12))
-#define LIB9P_MODE_PERM_SETGROUP ((lib9p_mode_t)(1<<11))
-#define LIB9P_MODE_PERM_SETUSER ((lib9p_mode_t)(1<<10))
-#define LIB9P_MODE_PERM_STICKY ((lib9p_mode_t)(1<<9))
-#define LIB9P_MODE_PERM_OWNER_R ((lib9p_mode_t)(1<<8))
-#define LIB9P_MODE_PERM_OWNER_W ((lib9p_mode_t)(1<<7))
-#define LIB9P_MODE_PERM_OWNER_X ((lib9p_mode_t)(1<<6))
-#define LIB9P_MODE_PERM_GROUP_R ((lib9p_mode_t)(1<<5))
-#define LIB9P_MODE_PERM_GROUP_W ((lib9p_mode_t)(1<<4))
-#define LIB9P_MODE_PERM_GROUP_X ((lib9p_mode_t)(1<<3))
-#define LIB9P_MODE_PERM_OTHER_R ((lib9p_mode_t)(1<<2))
-#define LIB9P_MODE_PERM_OTHER_W ((lib9p_mode_t)(1<<1))
-#define LIB9P_MODE_PERM_OTHER_X ((lib9p_mode_t)(1<<0))
-
-#define LIB9P_MODE_FMT_NAMED_PIPE ((lib9p_mode_t)(LIB9P_DT_NAMED_PIPE<<12))
-#define LIB9P_MODE_FMT_CHAR_DEV ((lib9p_mode_t)(LIB9P_DT_CHAR_DEV<<12))
-#define LIB9P_MODE_FMT_DIRECTORY ((lib9p_mode_t)(LIB9P_DT_DIRECTORY<<12))
-#define LIB9P_MODE_FMT_BLOCK_DEV ((lib9p_mode_t)(LIB9P_DT_BLOCK_DEV<<12))
-#define LIB9P_MODE_FMT_REGULAR ((lib9p_mode_t)(LIB9P_DT_REGULAR<<12))
-#define LIB9P_MODE_FMT_SYMLINK ((lib9p_mode_t)(LIB9P_DT_SYMLINK<<12))
-#define LIB9P_MODE_FMT_SOCKET ((lib9p_mode_t)(LIB9P_DT_SOCKET<<12))
-#define LIB9P_MODE_PERM_MASK ((lib9p_mode_t)(0000777))
-#define LIB9P_MODE_FMT_MASK ((lib9p_mode_t)(0170000))
+LO_IMPLEMENTATION_H(fmt_formatter, lib9p_mode_t, lib9p_mode);
+/* bits */
+#define _LIB9P_MODE_UNUSED_31 ((lib9p_mode_t)(UINT32_C(1)<<31))
+#define _LIB9P_MODE_UNUSED_30 ((lib9p_mode_t)(UINT32_C(1)<<30))
+#define _LIB9P_MODE_UNUSED_29 ((lib9p_mode_t)(UINT32_C(1)<<29))
+#define _LIB9P_MODE_UNUSED_28 ((lib9p_mode_t)(UINT32_C(1)<<28))
+#define _LIB9P_MODE_UNUSED_27 ((lib9p_mode_t)(UINT32_C(1)<<27))
+#define _LIB9P_MODE_UNUSED_26 ((lib9p_mode_t)(UINT32_C(1)<<26))
+#define _LIB9P_MODE_UNUSED_25 ((lib9p_mode_t)(UINT32_C(1)<<25))
+#define _LIB9P_MODE_UNUSED_24 ((lib9p_mode_t)(UINT32_C(1)<<24))
+#define _LIB9P_MODE_UNUSED_23 ((lib9p_mode_t)(UINT32_C(1)<<23))
+#define _LIB9P_MODE_UNUSED_22 ((lib9p_mode_t)(UINT32_C(1)<<22))
+#define _LIB9P_MODE_UNUSED_21 ((lib9p_mode_t)(UINT32_C(1)<<21))
+#define _LIB9P_MODE_UNUSED_20 ((lib9p_mode_t)(UINT32_C(1)<<20))
+#define _LIB9P_MODE_UNUSED_19 ((lib9p_mode_t)(UINT32_C(1)<<19))
+#define _LIB9P_MODE_UNUSED_18 ((lib9p_mode_t)(UINT32_C(1)<<18))
+#define _LIB9P_MODE_UNUSED_17 ((lib9p_mode_t)(UINT32_C(1)<<17))
+#define _LIB9P_MODE_UNUSED_16 ((lib9p_mode_t)(UINT32_C(1)<<16))
+/* number LIB9P_MODE_FMT_* ((lib9p_mode_t)(UINT32_C(1)<<15)) */
+/* number LIB9P_MODE_FMT_* ((lib9p_mode_t)(UINT32_C(1)<<14)) */
+/* number LIB9P_MODE_FMT_* ((lib9p_mode_t)(UINT32_C(1)<<13)) */
+/* number LIB9P_MODE_FMT_* ((lib9p_mode_t)(UINT32_C(1)<<12)) */
+#define LIB9P_MODE_PERM_SETGROUP ((lib9p_mode_t)(UINT32_C(1)<<11))
+#define LIB9P_MODE_PERM_SETUSER ((lib9p_mode_t)(UINT32_C(1)<<10))
+#define LIB9P_MODE_PERM_STICKY ((lib9p_mode_t)(UINT32_C(1)<<9))
+#define LIB9P_MODE_PERM_OWNER_R ((lib9p_mode_t)(UINT32_C(1)<<8))
+#define LIB9P_MODE_PERM_OWNER_W ((lib9p_mode_t)(UINT32_C(1)<<7))
+#define LIB9P_MODE_PERM_OWNER_X ((lib9p_mode_t)(UINT32_C(1)<<6))
+#define LIB9P_MODE_PERM_GROUP_R ((lib9p_mode_t)(UINT32_C(1)<<5))
+#define LIB9P_MODE_PERM_GROUP_W ((lib9p_mode_t)(UINT32_C(1)<<4))
+#define LIB9P_MODE_PERM_GROUP_X ((lib9p_mode_t)(UINT32_C(1)<<3))
+#define LIB9P_MODE_PERM_OTHER_R ((lib9p_mode_t)(UINT32_C(1)<<2))
+#define LIB9P_MODE_PERM_OTHER_W ((lib9p_mode_t)(UINT32_C(1)<<1))
+#define LIB9P_MODE_PERM_OTHER_X ((lib9p_mode_t)(UINT32_C(1)<<0))
+/* masks */
+#define LIB9P_MODE_PERM_MASK ((lib9p_mode_t)(0b000000000000000000111111111111))
+/* number: FMT */
+#define LIB9P_MODE_FMT_PIPE ((lib9p_mode_t)(LIB9P_DT_PIPE << 12))
+#define LIB9P_MODE_FMT_CHAR_DEV ((lib9p_mode_t)(LIB9P_DT_CHAR_DEV << 12))
+#define LIB9P_MODE_FMT_DIRECTORY ((lib9p_mode_t)(LIB9P_DT_DIRECTORY << 12))
+#define LIB9P_MODE_FMT_BLOCK_DEV ((lib9p_mode_t)(LIB9P_DT_BLOCK_DEV << 12))
+#define LIB9P_MODE_FMT_REGULAR ((lib9p_mode_t)(LIB9P_DT_REGULAR << 12))
+#define LIB9P_MODE_FMT_SYMLINK ((lib9p_mode_t)(LIB9P_DT_SYMLINK << 12))
+#define LIB9P_MODE_FMT_SOCKET ((lib9p_mode_t)(LIB9P_DT_SOCKET << 12))
+#define LIB9P_MODE_FMT_MASK ((lib9p_mode_t)(0b000000000000001111000000000000))
/* size = 4 ; max_iov = 1 ; max_copy = 4 */
typedef uint32_t lib9p_b4_t;
-#define LIB9P_B4_FALSE ((lib9p_b4_t)UINT32_C(0))
-#define LIB9P_B4_TRUE ((lib9p_b4_t)UINT32_C(1))
+LO_IMPLEMENTATION_H(fmt_formatter, lib9p_b4_t, lib9p_b4);
+#define LIB9P_B4_FALSE ((lib9p_b4_t)(0))
+#define LIB9P_B4_TRUE ((lib9p_b4_t)(1))
/* size = 8 ; max_iov = 1 ; max_copy = 8 */
typedef uint64_t lib9p_getattr_t;
-
-/* unused ((lib9p_getattr_t)(1<<63)) */
-/* unused ((lib9p_getattr_t)(1<<62)) */
-/* unused ((lib9p_getattr_t)(1<<61)) */
-/* unused ((lib9p_getattr_t)(1<<60)) */
-/* unused ((lib9p_getattr_t)(1<<59)) */
-/* unused ((lib9p_getattr_t)(1<<58)) */
-/* unused ((lib9p_getattr_t)(1<<57)) */
-/* unused ((lib9p_getattr_t)(1<<56)) */
-/* unused ((lib9p_getattr_t)(1<<55)) */
-/* unused ((lib9p_getattr_t)(1<<54)) */
-/* unused ((lib9p_getattr_t)(1<<53)) */
-/* unused ((lib9p_getattr_t)(1<<52)) */
-/* unused ((lib9p_getattr_t)(1<<51)) */
-/* unused ((lib9p_getattr_t)(1<<50)) */
-/* unused ((lib9p_getattr_t)(1<<49)) */
-/* unused ((lib9p_getattr_t)(1<<48)) */
-/* unused ((lib9p_getattr_t)(1<<47)) */
-/* unused ((lib9p_getattr_t)(1<<46)) */
-/* unused ((lib9p_getattr_t)(1<<45)) */
-/* unused ((lib9p_getattr_t)(1<<44)) */
-/* unused ((lib9p_getattr_t)(1<<43)) */
-/* unused ((lib9p_getattr_t)(1<<42)) */
-/* unused ((lib9p_getattr_t)(1<<41)) */
-/* unused ((lib9p_getattr_t)(1<<40)) */
-/* unused ((lib9p_getattr_t)(1<<39)) */
-/* unused ((lib9p_getattr_t)(1<<38)) */
-/* unused ((lib9p_getattr_t)(1<<37)) */
-/* unused ((lib9p_getattr_t)(1<<36)) */
-/* unused ((lib9p_getattr_t)(1<<35)) */
-/* unused ((lib9p_getattr_t)(1<<34)) */
-/* unused ((lib9p_getattr_t)(1<<33)) */
-/* unused ((lib9p_getattr_t)(1<<32)) */
-/* unused ((lib9p_getattr_t)(1<<31)) */
-/* unused ((lib9p_getattr_t)(1<<30)) */
-/* unused ((lib9p_getattr_t)(1<<29)) */
-/* unused ((lib9p_getattr_t)(1<<28)) */
-/* unused ((lib9p_getattr_t)(1<<27)) */
-/* unused ((lib9p_getattr_t)(1<<26)) */
-/* unused ((lib9p_getattr_t)(1<<25)) */
-/* unused ((lib9p_getattr_t)(1<<24)) */
-/* unused ((lib9p_getattr_t)(1<<23)) */
-/* unused ((lib9p_getattr_t)(1<<22)) */
-/* unused ((lib9p_getattr_t)(1<<21)) */
-/* unused ((lib9p_getattr_t)(1<<20)) */
-/* unused ((lib9p_getattr_t)(1<<19)) */
-/* unused ((lib9p_getattr_t)(1<<18)) */
-/* unused ((lib9p_getattr_t)(1<<17)) */
-/* unused ((lib9p_getattr_t)(1<<16)) */
-/* unused ((lib9p_getattr_t)(1<<15)) */
-/* unused ((lib9p_getattr_t)(1<<14)) */
-#define LIB9P_GETATTR_DATA_VERSION ((lib9p_getattr_t)(1<<13))
-#define LIB9P_GETATTR_GEN ((lib9p_getattr_t)(1<<12))
-#define LIB9P_GETATTR_BTIME ((lib9p_getattr_t)(1<<11))
-#define LIB9P_GETATTR_BLOCKS ((lib9p_getattr_t)(1<<10))
-#define LIB9P_GETATTR_SIZE ((lib9p_getattr_t)(1<<9))
-#define LIB9P_GETATTR_INO ((lib9p_getattr_t)(1<<8))
-#define LIB9P_GETATTR_CTIME ((lib9p_getattr_t)(1<<7))
-#define LIB9P_GETATTR_MTIME ((lib9p_getattr_t)(1<<6))
-#define LIB9P_GETATTR_ATIME ((lib9p_getattr_t)(1<<5))
-#define LIB9P_GETATTR_RDEV ((lib9p_getattr_t)(1<<4))
-#define LIB9P_GETATTR_GID ((lib9p_getattr_t)(1<<3))
-#define LIB9P_GETATTR_UID ((lib9p_getattr_t)(1<<2))
-#define LIB9P_GETATTR_NLINK ((lib9p_getattr_t)(1<<1))
-#define LIB9P_GETATTR_MODE ((lib9p_getattr_t)(1<<0))
-
-#define LIB9P_GETATTR_BASIC ((lib9p_getattr_t)(0x000007ff))
-#define LIB9P_GETATTR_ALL ((lib9p_getattr_t)(0x00003fff))
+LO_IMPLEMENTATION_H(fmt_formatter, lib9p_getattr_t, lib9p_getattr);
+/* bits */
+#define _LIB9P_GETATTR_UNUSED_63 ((lib9p_getattr_t)(UINT64_C(1)<<63))
+#define _LIB9P_GETATTR_UNUSED_62 ((lib9p_getattr_t)(UINT64_C(1)<<62))
+#define _LIB9P_GETATTR_UNUSED_61 ((lib9p_getattr_t)(UINT64_C(1)<<61))
+#define _LIB9P_GETATTR_UNUSED_60 ((lib9p_getattr_t)(UINT64_C(1)<<60))
+#define _LIB9P_GETATTR_UNUSED_59 ((lib9p_getattr_t)(UINT64_C(1)<<59))
+#define _LIB9P_GETATTR_UNUSED_58 ((lib9p_getattr_t)(UINT64_C(1)<<58))
+#define _LIB9P_GETATTR_UNUSED_57 ((lib9p_getattr_t)(UINT64_C(1)<<57))
+#define _LIB9P_GETATTR_UNUSED_56 ((lib9p_getattr_t)(UINT64_C(1)<<56))
+#define _LIB9P_GETATTR_UNUSED_55 ((lib9p_getattr_t)(UINT64_C(1)<<55))
+#define _LIB9P_GETATTR_UNUSED_54 ((lib9p_getattr_t)(UINT64_C(1)<<54))
+#define _LIB9P_GETATTR_UNUSED_53 ((lib9p_getattr_t)(UINT64_C(1)<<53))
+#define _LIB9P_GETATTR_UNUSED_52 ((lib9p_getattr_t)(UINT64_C(1)<<52))
+#define _LIB9P_GETATTR_UNUSED_51 ((lib9p_getattr_t)(UINT64_C(1)<<51))
+#define _LIB9P_GETATTR_UNUSED_50 ((lib9p_getattr_t)(UINT64_C(1)<<50))
+#define _LIB9P_GETATTR_UNUSED_49 ((lib9p_getattr_t)(UINT64_C(1)<<49))
+#define _LIB9P_GETATTR_UNUSED_48 ((lib9p_getattr_t)(UINT64_C(1)<<48))
+#define _LIB9P_GETATTR_UNUSED_47 ((lib9p_getattr_t)(UINT64_C(1)<<47))
+#define _LIB9P_GETATTR_UNUSED_46 ((lib9p_getattr_t)(UINT64_C(1)<<46))
+#define _LIB9P_GETATTR_UNUSED_45 ((lib9p_getattr_t)(UINT64_C(1)<<45))
+#define _LIB9P_GETATTR_UNUSED_44 ((lib9p_getattr_t)(UINT64_C(1)<<44))
+#define _LIB9P_GETATTR_UNUSED_43 ((lib9p_getattr_t)(UINT64_C(1)<<43))
+#define _LIB9P_GETATTR_UNUSED_42 ((lib9p_getattr_t)(UINT64_C(1)<<42))
+#define _LIB9P_GETATTR_UNUSED_41 ((lib9p_getattr_t)(UINT64_C(1)<<41))
+#define _LIB9P_GETATTR_UNUSED_40 ((lib9p_getattr_t)(UINT64_C(1)<<40))
+#define _LIB9P_GETATTR_UNUSED_39 ((lib9p_getattr_t)(UINT64_C(1)<<39))
+#define _LIB9P_GETATTR_UNUSED_38 ((lib9p_getattr_t)(UINT64_C(1)<<38))
+#define _LIB9P_GETATTR_UNUSED_37 ((lib9p_getattr_t)(UINT64_C(1)<<37))
+#define _LIB9P_GETATTR_UNUSED_36 ((lib9p_getattr_t)(UINT64_C(1)<<36))
+#define _LIB9P_GETATTR_UNUSED_35 ((lib9p_getattr_t)(UINT64_C(1)<<35))
+#define _LIB9P_GETATTR_UNUSED_34 ((lib9p_getattr_t)(UINT64_C(1)<<34))
+#define _LIB9P_GETATTR_UNUSED_33 ((lib9p_getattr_t)(UINT64_C(1)<<33))
+#define _LIB9P_GETATTR_UNUSED_32 ((lib9p_getattr_t)(UINT64_C(1)<<32))
+#define _LIB9P_GETATTR_UNUSED_31 ((lib9p_getattr_t)(UINT64_C(1)<<31))
+#define _LIB9P_GETATTR_UNUSED_30 ((lib9p_getattr_t)(UINT64_C(1)<<30))
+#define _LIB9P_GETATTR_UNUSED_29 ((lib9p_getattr_t)(UINT64_C(1)<<29))
+#define _LIB9P_GETATTR_UNUSED_28 ((lib9p_getattr_t)(UINT64_C(1)<<28))
+#define _LIB9P_GETATTR_UNUSED_27 ((lib9p_getattr_t)(UINT64_C(1)<<27))
+#define _LIB9P_GETATTR_UNUSED_26 ((lib9p_getattr_t)(UINT64_C(1)<<26))
+#define _LIB9P_GETATTR_UNUSED_25 ((lib9p_getattr_t)(UINT64_C(1)<<25))
+#define _LIB9P_GETATTR_UNUSED_24 ((lib9p_getattr_t)(UINT64_C(1)<<24))
+#define _LIB9P_GETATTR_UNUSED_23 ((lib9p_getattr_t)(UINT64_C(1)<<23))
+#define _LIB9P_GETATTR_UNUSED_22 ((lib9p_getattr_t)(UINT64_C(1)<<22))
+#define _LIB9P_GETATTR_UNUSED_21 ((lib9p_getattr_t)(UINT64_C(1)<<21))
+#define _LIB9P_GETATTR_UNUSED_20 ((lib9p_getattr_t)(UINT64_C(1)<<20))
+#define _LIB9P_GETATTR_UNUSED_19 ((lib9p_getattr_t)(UINT64_C(1)<<19))
+#define _LIB9P_GETATTR_UNUSED_18 ((lib9p_getattr_t)(UINT64_C(1)<<18))
+#define _LIB9P_GETATTR_UNUSED_17 ((lib9p_getattr_t)(UINT64_C(1)<<17))
+#define _LIB9P_GETATTR_UNUSED_16 ((lib9p_getattr_t)(UINT64_C(1)<<16))
+#define _LIB9P_GETATTR_UNUSED_15 ((lib9p_getattr_t)(UINT64_C(1)<<15))
+#define _LIB9P_GETATTR_UNUSED_14 ((lib9p_getattr_t)(UINT64_C(1)<<14))
+#define LIB9P_GETATTR_DATA_VERSION ((lib9p_getattr_t)(UINT64_C(1)<<13))
+#define LIB9P_GETATTR_GEN ((lib9p_getattr_t)(UINT64_C(1)<<12))
+#define LIB9P_GETATTR_BTIME ((lib9p_getattr_t)(UINT64_C(1)<<11))
+#define LIB9P_GETATTR_BLOCKS ((lib9p_getattr_t)(UINT64_C(1)<<10))
+#define LIB9P_GETATTR_SIZE ((lib9p_getattr_t)(UINT64_C(1)<<9))
+#define LIB9P_GETATTR_INO ((lib9p_getattr_t)(UINT64_C(1)<<8))
+#define LIB9P_GETATTR_CTIME ((lib9p_getattr_t)(UINT64_C(1)<<7))
+#define LIB9P_GETATTR_MTIME ((lib9p_getattr_t)(UINT64_C(1)<<6))
+#define LIB9P_GETATTR_ATIME ((lib9p_getattr_t)(UINT64_C(1)<<5))
+#define LIB9P_GETATTR_RDEV ((lib9p_getattr_t)(UINT64_C(1)<<4))
+#define LIB9P_GETATTR_GID ((lib9p_getattr_t)(UINT64_C(1)<<3))
+#define LIB9P_GETATTR_UID ((lib9p_getattr_t)(UINT64_C(1)<<2))
+#define LIB9P_GETATTR_NLINK ((lib9p_getattr_t)(UINT64_C(1)<<1))
+#define LIB9P_GETATTR_MODE ((lib9p_getattr_t)(UINT64_C(1)<<0))
+/* aliases */
+#define LIB9P_GETATTR_BASIC ((lib9p_getattr_t)(2047))
+#define LIB9P_GETATTR_ALL ((lib9p_getattr_t)(16383))
/* size = 4 ; max_iov = 1 ; max_copy = 4 */
typedef uint32_t lib9p_setattr_t;
-
-/* unused ((lib9p_setattr_t)(1<<31)) */
-/* unused ((lib9p_setattr_t)(1<<30)) */
-/* unused ((lib9p_setattr_t)(1<<29)) */
-/* unused ((lib9p_setattr_t)(1<<28)) */
-/* unused ((lib9p_setattr_t)(1<<27)) */
-/* unused ((lib9p_setattr_t)(1<<26)) */
-/* unused ((lib9p_setattr_t)(1<<25)) */
-/* unused ((lib9p_setattr_t)(1<<24)) */
-/* unused ((lib9p_setattr_t)(1<<23)) */
-/* unused ((lib9p_setattr_t)(1<<22)) */
-/* unused ((lib9p_setattr_t)(1<<21)) */
-/* unused ((lib9p_setattr_t)(1<<20)) */
-/* unused ((lib9p_setattr_t)(1<<19)) */
-/* unused ((lib9p_setattr_t)(1<<18)) */
-/* unused ((lib9p_setattr_t)(1<<17)) */
-/* unused ((lib9p_setattr_t)(1<<16)) */
-/* unused ((lib9p_setattr_t)(1<<15)) */
-/* unused ((lib9p_setattr_t)(1<<14)) */
-/* unused ((lib9p_setattr_t)(1<<13)) */
-/* unused ((lib9p_setattr_t)(1<<12)) */
-/* unused ((lib9p_setattr_t)(1<<11)) */
-/* unused ((lib9p_setattr_t)(1<<10)) */
-/* unused ((lib9p_setattr_t)(1<<9)) */
-#define LIB9P_SETATTR_MTIME_SET ((lib9p_setattr_t)(1<<8))
-#define LIB9P_SETATTR_ATIME_SET ((lib9p_setattr_t)(1<<7))
-#define LIB9P_SETATTR_CTIME ((lib9p_setattr_t)(1<<6))
-#define LIB9P_SETATTR_MTIME ((lib9p_setattr_t)(1<<5))
-#define LIB9P_SETATTR_ATIME ((lib9p_setattr_t)(1<<4))
-#define LIB9P_SETATTR_SIZE ((lib9p_setattr_t)(1<<3))
-#define LIB9P_SETATTR_GID ((lib9p_setattr_t)(1<<2))
-#define LIB9P_SETATTR_UID ((lib9p_setattr_t)(1<<1))
-#define LIB9P_SETATTR_MODE ((lib9p_setattr_t)(1<<0))
+LO_IMPLEMENTATION_H(fmt_formatter, lib9p_setattr_t, lib9p_setattr);
+/* bits */
+#define _LIB9P_SETATTR_UNUSED_31 ((lib9p_setattr_t)(UINT32_C(1)<<31))
+#define _LIB9P_SETATTR_UNUSED_30 ((lib9p_setattr_t)(UINT32_C(1)<<30))
+#define _LIB9P_SETATTR_UNUSED_29 ((lib9p_setattr_t)(UINT32_C(1)<<29))
+#define _LIB9P_SETATTR_UNUSED_28 ((lib9p_setattr_t)(UINT32_C(1)<<28))
+#define _LIB9P_SETATTR_UNUSED_27 ((lib9p_setattr_t)(UINT32_C(1)<<27))
+#define _LIB9P_SETATTR_UNUSED_26 ((lib9p_setattr_t)(UINT32_C(1)<<26))
+#define _LIB9P_SETATTR_UNUSED_25 ((lib9p_setattr_t)(UINT32_C(1)<<25))
+#define _LIB9P_SETATTR_UNUSED_24 ((lib9p_setattr_t)(UINT32_C(1)<<24))
+#define _LIB9P_SETATTR_UNUSED_23 ((lib9p_setattr_t)(UINT32_C(1)<<23))
+#define _LIB9P_SETATTR_UNUSED_22 ((lib9p_setattr_t)(UINT32_C(1)<<22))
+#define _LIB9P_SETATTR_UNUSED_21 ((lib9p_setattr_t)(UINT32_C(1)<<21))
+#define _LIB9P_SETATTR_UNUSED_20 ((lib9p_setattr_t)(UINT32_C(1)<<20))
+#define _LIB9P_SETATTR_UNUSED_19 ((lib9p_setattr_t)(UINT32_C(1)<<19))
+#define _LIB9P_SETATTR_UNUSED_18 ((lib9p_setattr_t)(UINT32_C(1)<<18))
+#define _LIB9P_SETATTR_UNUSED_17 ((lib9p_setattr_t)(UINT32_C(1)<<17))
+#define _LIB9P_SETATTR_UNUSED_16 ((lib9p_setattr_t)(UINT32_C(1)<<16))
+#define _LIB9P_SETATTR_UNUSED_15 ((lib9p_setattr_t)(UINT32_C(1)<<15))
+#define _LIB9P_SETATTR_UNUSED_14 ((lib9p_setattr_t)(UINT32_C(1)<<14))
+#define _LIB9P_SETATTR_UNUSED_13 ((lib9p_setattr_t)(UINT32_C(1)<<13))
+#define _LIB9P_SETATTR_UNUSED_12 ((lib9p_setattr_t)(UINT32_C(1)<<12))
+#define _LIB9P_SETATTR_UNUSED_11 ((lib9p_setattr_t)(UINT32_C(1)<<11))
+#define _LIB9P_SETATTR_UNUSED_10 ((lib9p_setattr_t)(UINT32_C(1)<<10))
+#define _LIB9P_SETATTR_UNUSED_9 ((lib9p_setattr_t)(UINT32_C(1)<<9))
+#define LIB9P_SETATTR_MTIME_SET ((lib9p_setattr_t)(UINT32_C(1)<<8))
+#define LIB9P_SETATTR_ATIME_SET ((lib9p_setattr_t)(UINT32_C(1)<<7))
+#define LIB9P_SETATTR_CTIME ((lib9p_setattr_t)(UINT32_C(1)<<6))
+#define LIB9P_SETATTR_MTIME ((lib9p_setattr_t)(UINT32_C(1)<<5))
+#define LIB9P_SETATTR_ATIME ((lib9p_setattr_t)(UINT32_C(1)<<4))
+#define LIB9P_SETATTR_SIZE ((lib9p_setattr_t)(UINT32_C(1)<<3))
+#define LIB9P_SETATTR_GID ((lib9p_setattr_t)(UINT32_C(1)<<2))
+#define LIB9P_SETATTR_UID ((lib9p_setattr_t)(UINT32_C(1)<<1))
+#define LIB9P_SETATTR_MODE ((lib9p_setattr_t)(UINT32_C(1)<<0))
/* size = 1 ; max_iov = 1 ; max_copy = 1 */
typedef uint8_t lib9p_lock_type_t;
-#define LIB9P_LOCK_TYPE_RDLCK ((lib9p_lock_type_t)UINT8_C(0))
-#define LIB9P_LOCK_TYPE_WRLCK ((lib9p_lock_type_t)UINT8_C(1))
-#define LIB9P_LOCK_TYPE_UNLCK ((lib9p_lock_type_t)UINT8_C(2))
+LO_IMPLEMENTATION_H(fmt_formatter, lib9p_lock_type_t, lib9p_lock_type);
+#define LIB9P_LOCK_TYPE_RDLCK ((lib9p_lock_type_t)(0))
+#define LIB9P_LOCK_TYPE_WRLCK ((lib9p_lock_type_t)(1))
+#define LIB9P_LOCK_TYPE_UNLCK ((lib9p_lock_type_t)(2))
/* size = 4 ; max_iov = 1 ; max_copy = 4 */
typedef uint32_t lib9p_lock_flags_t;
-
-/* unused ((lib9p_lock_flags_t)(1<<31)) */
-/* unused ((lib9p_lock_flags_t)(1<<30)) */
-/* unused ((lib9p_lock_flags_t)(1<<29)) */
-/* unused ((lib9p_lock_flags_t)(1<<28)) */
-/* unused ((lib9p_lock_flags_t)(1<<27)) */
-/* unused ((lib9p_lock_flags_t)(1<<26)) */
-/* unused ((lib9p_lock_flags_t)(1<<25)) */
-/* unused ((lib9p_lock_flags_t)(1<<24)) */
-/* unused ((lib9p_lock_flags_t)(1<<23)) */
-/* unused ((lib9p_lock_flags_t)(1<<22)) */
-/* unused ((lib9p_lock_flags_t)(1<<21)) */
-/* unused ((lib9p_lock_flags_t)(1<<20)) */
-/* unused ((lib9p_lock_flags_t)(1<<19)) */
-/* unused ((lib9p_lock_flags_t)(1<<18)) */
-/* unused ((lib9p_lock_flags_t)(1<<17)) */
-/* unused ((lib9p_lock_flags_t)(1<<16)) */
-/* unused ((lib9p_lock_flags_t)(1<<15)) */
-/* unused ((lib9p_lock_flags_t)(1<<14)) */
-/* unused ((lib9p_lock_flags_t)(1<<13)) */
-/* unused ((lib9p_lock_flags_t)(1<<12)) */
-/* unused ((lib9p_lock_flags_t)(1<<11)) */
-/* unused ((lib9p_lock_flags_t)(1<<10)) */
-/* unused ((lib9p_lock_flags_t)(1<<9)) */
-/* unused ((lib9p_lock_flags_t)(1<<8)) */
-/* unused ((lib9p_lock_flags_t)(1<<7)) */
-/* unused ((lib9p_lock_flags_t)(1<<6)) */
-/* unused ((lib9p_lock_flags_t)(1<<5)) */
-/* unused ((lib9p_lock_flags_t)(1<<4)) */
-/* unused ((lib9p_lock_flags_t)(1<<3)) */
-/* unused ((lib9p_lock_flags_t)(1<<2)) */
-#define LIB9P_LOCK_FLAGS_RECLAIM ((lib9p_lock_flags_t)(1<<1))
-#define LIB9P_LOCK_FLAGS_BLOCK ((lib9p_lock_flags_t)(1<<0))
+LO_IMPLEMENTATION_H(fmt_formatter, lib9p_lock_flags_t, lib9p_lock_flags);
+/* bits */
+#define _LIB9P_LOCK_FLAGS_UNUSED_31 ((lib9p_lock_flags_t)(UINT32_C(1)<<31))
+#define _LIB9P_LOCK_FLAGS_UNUSED_30 ((lib9p_lock_flags_t)(UINT32_C(1)<<30))
+#define _LIB9P_LOCK_FLAGS_UNUSED_29 ((lib9p_lock_flags_t)(UINT32_C(1)<<29))
+#define _LIB9P_LOCK_FLAGS_UNUSED_28 ((lib9p_lock_flags_t)(UINT32_C(1)<<28))
+#define _LIB9P_LOCK_FLAGS_UNUSED_27 ((lib9p_lock_flags_t)(UINT32_C(1)<<27))
+#define _LIB9P_LOCK_FLAGS_UNUSED_26 ((lib9p_lock_flags_t)(UINT32_C(1)<<26))
+#define _LIB9P_LOCK_FLAGS_UNUSED_25 ((lib9p_lock_flags_t)(UINT32_C(1)<<25))
+#define _LIB9P_LOCK_FLAGS_UNUSED_24 ((lib9p_lock_flags_t)(UINT32_C(1)<<24))
+#define _LIB9P_LOCK_FLAGS_UNUSED_23 ((lib9p_lock_flags_t)(UINT32_C(1)<<23))
+#define _LIB9P_LOCK_FLAGS_UNUSED_22 ((lib9p_lock_flags_t)(UINT32_C(1)<<22))
+#define _LIB9P_LOCK_FLAGS_UNUSED_21 ((lib9p_lock_flags_t)(UINT32_C(1)<<21))
+#define _LIB9P_LOCK_FLAGS_UNUSED_20 ((lib9p_lock_flags_t)(UINT32_C(1)<<20))
+#define _LIB9P_LOCK_FLAGS_UNUSED_19 ((lib9p_lock_flags_t)(UINT32_C(1)<<19))
+#define _LIB9P_LOCK_FLAGS_UNUSED_18 ((lib9p_lock_flags_t)(UINT32_C(1)<<18))
+#define _LIB9P_LOCK_FLAGS_UNUSED_17 ((lib9p_lock_flags_t)(UINT32_C(1)<<17))
+#define _LIB9P_LOCK_FLAGS_UNUSED_16 ((lib9p_lock_flags_t)(UINT32_C(1)<<16))
+#define _LIB9P_LOCK_FLAGS_UNUSED_15 ((lib9p_lock_flags_t)(UINT32_C(1)<<15))
+#define _LIB9P_LOCK_FLAGS_UNUSED_14 ((lib9p_lock_flags_t)(UINT32_C(1)<<14))
+#define _LIB9P_LOCK_FLAGS_UNUSED_13 ((lib9p_lock_flags_t)(UINT32_C(1)<<13))
+#define _LIB9P_LOCK_FLAGS_UNUSED_12 ((lib9p_lock_flags_t)(UINT32_C(1)<<12))
+#define _LIB9P_LOCK_FLAGS_UNUSED_11 ((lib9p_lock_flags_t)(UINT32_C(1)<<11))
+#define _LIB9P_LOCK_FLAGS_UNUSED_10 ((lib9p_lock_flags_t)(UINT32_C(1)<<10))
+#define _LIB9P_LOCK_FLAGS_UNUSED_9 ((lib9p_lock_flags_t)(UINT32_C(1)<<9))
+#define _LIB9P_LOCK_FLAGS_UNUSED_8 ((lib9p_lock_flags_t)(UINT32_C(1)<<8))
+#define _LIB9P_LOCK_FLAGS_UNUSED_7 ((lib9p_lock_flags_t)(UINT32_C(1)<<7))
+#define _LIB9P_LOCK_FLAGS_UNUSED_6 ((lib9p_lock_flags_t)(UINT32_C(1)<<6))
+#define _LIB9P_LOCK_FLAGS_UNUSED_5 ((lib9p_lock_flags_t)(UINT32_C(1)<<5))
+#define _LIB9P_LOCK_FLAGS_UNUSED_4 ((lib9p_lock_flags_t)(UINT32_C(1)<<4))
+#define _LIB9P_LOCK_FLAGS_UNUSED_3 ((lib9p_lock_flags_t)(UINT32_C(1)<<3))
+#define _LIB9P_LOCK_FLAGS_UNUSED_2 ((lib9p_lock_flags_t)(UINT32_C(1)<<2))
+#define LIB9P_LOCK_FLAGS_RECLAIM ((lib9p_lock_flags_t)(UINT32_C(1)<<1))
+#define LIB9P_LOCK_FLAGS_BLOCK ((lib9p_lock_flags_t)(UINT32_C(1)<<0))
/* size = 1 ; max_iov = 1 ; max_copy = 1 */
typedef uint8_t lib9p_lock_status_t;
-#define LIB9P_LOCK_STATUS_SUCCESS ((lib9p_lock_status_t)UINT8_C(0))
-#define LIB9P_LOCK_STATUS_BLOCKED ((lib9p_lock_status_t)UINT8_C(1))
-#define LIB9P_LOCK_STATUS_ERROR ((lib9p_lock_status_t)UINT8_C(2))
-#define LIB9P_LOCK_STATUS_GRACE ((lib9p_lock_status_t)UINT8_C(3))
+LO_IMPLEMENTATION_H(fmt_formatter, lib9p_lock_status_t, lib9p_lock_status);
+#define LIB9P_LOCK_STATUS_SUCCESS ((lib9p_lock_status_t)(0))
+#define LIB9P_LOCK_STATUS_BLOCKED ((lib9p_lock_status_t)(1))
+#define LIB9P_LOCK_STATUS_ERROR ((lib9p_lock_status_t)(2))
+#define LIB9P_LOCK_STATUS_GRACE ((lib9p_lock_status_t)(3))
#endif /* CONFIG_9P_ENABLE_9P2000_L */
#if CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u
@@ -541,11 +565,13 @@ struct lib9p_msg_Tflush {
lib9p_tag_t tag;
uint16_t oldtag;
};
+LO_IMPLEMENTATION_H(fmt_formatter, struct lib9p_msg_Tflush, lib9p_msg_Tflush);
/* size = 7 ; max_iov = 1 ; max_copy = 7 */
struct lib9p_msg_Rflush {
lib9p_tag_t tag;
};
+LO_IMPLEMENTATION_H(fmt_formatter, struct lib9p_msg_Rflush, lib9p_msg_Rflush);
/* min_size = 11 ; exp_size = 8,203 ; max_size = 2,147,483,658 ; max_iov = 2 ; max_copy = 11 */
struct lib9p_msg_Rread {
@@ -553,22 +579,26 @@ struct lib9p_msg_Rread {
uint32_t count;
[[gnu::nonstring]] char *data;
};
+LO_IMPLEMENTATION_H(fmt_formatter, struct lib9p_msg_Rread, lib9p_msg_Rread);
/* size = 11 ; max_iov = 1 ; max_copy = 11 */
struct lib9p_msg_Rwrite {
lib9p_tag_t tag;
uint32_t count;
};
+LO_IMPLEMENTATION_H(fmt_formatter, struct lib9p_msg_Rwrite, lib9p_msg_Rwrite);
/* size = 7 ; max_iov = 1 ; max_copy = 7 */
struct lib9p_msg_Rclunk {
lib9p_tag_t tag;
};
+LO_IMPLEMENTATION_H(fmt_formatter, struct lib9p_msg_Rclunk, lib9p_msg_Rclunk);
/* size = 7 ; max_iov = 1 ; max_copy = 7 */
struct lib9p_msg_Rremove {
lib9p_tag_t tag;
};
+LO_IMPLEMENTATION_H(fmt_formatter, struct lib9p_msg_Rremove, lib9p_msg_Rremove);
#endif /* CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u */
#if CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u
@@ -576,6 +606,7 @@ struct lib9p_msg_Rremove {
struct lib9p_msg_Rwstat {
lib9p_tag_t tag;
};
+LO_IMPLEMENTATION_H(fmt_formatter, struct lib9p_msg_Rwstat, lib9p_msg_Rwstat);
#endif /* CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u */
#if CONFIG_9P_ENABLE_9P2000_L
@@ -583,22 +614,26 @@ struct lib9p_msg_Rwstat {
struct lib9p_msg_Rrename {
lib9p_tag_t tag;
};
+LO_IMPLEMENTATION_H(fmt_formatter, struct lib9p_msg_Rrename, lib9p_msg_Rrename);
/* size = 7 ; max_iov = 1 ; max_copy = 7 */
struct lib9p_msg_Rsetattr {
lib9p_tag_t tag;
};
+LO_IMPLEMENTATION_H(fmt_formatter, struct lib9p_msg_Rsetattr, lib9p_msg_Rsetattr);
/* size = 15 ; max_iov = 1 ; max_copy = 15 */
struct lib9p_msg_Rxattrwalk {
lib9p_tag_t tag;
uint64_t attr_size;
};
+LO_IMPLEMENTATION_H(fmt_formatter, struct lib9p_msg_Rxattrwalk, lib9p_msg_Rxattrwalk);
/* size = 7 ; max_iov = 1 ; max_copy = 7 */
struct lib9p_msg_Rxattrcreate {
lib9p_tag_t tag;
};
+LO_IMPLEMENTATION_H(fmt_formatter, struct lib9p_msg_Rxattrcreate, lib9p_msg_Rxattrcreate);
/* min_size = 11 ; exp_size = 8,203 ; max_size = 4,294,967,306 (warning: >UINT32_MAX) ; max_iov = 2 ; max_copy = 11 */
struct lib9p_msg_Rreaddir {
@@ -606,26 +641,31 @@ struct lib9p_msg_Rreaddir {
uint32_t count;
[[gnu::nonstring]] char *data;
};
+LO_IMPLEMENTATION_H(fmt_formatter, struct lib9p_msg_Rreaddir, lib9p_msg_Rreaddir);
/* size = 7 ; max_iov = 1 ; max_copy = 7 */
struct lib9p_msg_Rfsync {
lib9p_tag_t tag;
};
+LO_IMPLEMENTATION_H(fmt_formatter, struct lib9p_msg_Rfsync, lib9p_msg_Rfsync);
/* size = 7 ; max_iov = 1 ; max_copy = 7 */
struct lib9p_msg_Rlink {
lib9p_tag_t tag;
};
+LO_IMPLEMENTATION_H(fmt_formatter, struct lib9p_msg_Rlink, lib9p_msg_Rlink);
/* size = 7 ; max_iov = 1 ; max_copy = 7 */
struct lib9p_msg_Rrenameat {
lib9p_tag_t tag;
};
+LO_IMPLEMENTATION_H(fmt_formatter, struct lib9p_msg_Rrenameat, lib9p_msg_Rrenameat);
/* size = 7 ; max_iov = 1 ; max_copy = 7 */
struct lib9p_msg_Runlinkat {
lib9p_tag_t tag;
};
+LO_IMPLEMENTATION_H(fmt_formatter, struct lib9p_msg_Runlinkat, lib9p_msg_Runlinkat);
#endif /* CONFIG_9P_ENABLE_9P2000_L */
#if CONFIG_9P_ENABLE_9P2000_e
@@ -634,11 +674,13 @@ struct lib9p_msg_Tsession {
lib9p_tag_t tag;
uint64_t key;
};
+LO_IMPLEMENTATION_H(fmt_formatter, struct lib9p_msg_Tsession, lib9p_msg_Tsession);
/* size = 7 ; max_iov = 1 ; max_copy = 7 */
struct lib9p_msg_Rsession {
lib9p_tag_t tag;
};
+LO_IMPLEMENTATION_H(fmt_formatter, struct lib9p_msg_Rsession, lib9p_msg_Rsession);
/* min_size = 11 ; exp_size = 8,203 ; max_size = 4,294,967,306 (warning: >UINT32_MAX) ; max_iov = 2 ; max_copy = 11 */
struct lib9p_msg_Rsread {
@@ -646,12 +688,14 @@ struct lib9p_msg_Rsread {
uint32_t count;
[[gnu::nonstring]] char *data;
};
+LO_IMPLEMENTATION_H(fmt_formatter, struct lib9p_msg_Rsread, lib9p_msg_Rsread);
/* size = 11 ; max_iov = 1 ; max_copy = 11 */
struct lib9p_msg_Rswrite {
lib9p_tag_t tag;
uint32_t count;
};
+LO_IMPLEMENTATION_H(fmt_formatter, struct lib9p_msg_Rswrite, lib9p_msg_Rswrite);
#endif /* CONFIG_9P_ENABLE_9P2000_e */
#if CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u
@@ -662,6 +706,7 @@ struct lib9p_msg_Tread {
uint64_t offset;
uint32_t count;
};
+LO_IMPLEMENTATION_H(fmt_formatter, struct lib9p_msg_Tread, lib9p_msg_Tread);
/* min_size = 23 ; exp_size = 8,215 ; max_size = 2,147,483,670 ; max_iov = 2 ; max_copy = 23 */
struct lib9p_msg_Twrite {
@@ -671,18 +716,21 @@ struct lib9p_msg_Twrite {
uint32_t count;
[[gnu::nonstring]] char *data;
};
+LO_IMPLEMENTATION_H(fmt_formatter, struct lib9p_msg_Twrite, lib9p_msg_Twrite);
/* size = 11 ; max_iov = 1 ; max_copy = 11 */
struct lib9p_msg_Tclunk {
lib9p_tag_t tag;
lib9p_fid_t fid;
};
+LO_IMPLEMENTATION_H(fmt_formatter, struct lib9p_msg_Tclunk, lib9p_msg_Tclunk);
/* size = 11 ; max_iov = 1 ; max_copy = 11 */
struct lib9p_msg_Tremove {
lib9p_tag_t tag;
lib9p_fid_t fid;
};
+LO_IMPLEMENTATION_H(fmt_formatter, struct lib9p_msg_Tremove, lib9p_msg_Tremove);
#endif /* CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u */
#if CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u
@@ -691,6 +739,7 @@ struct lib9p_msg_Tstat {
lib9p_tag_t tag;
lib9p_fid_t fid;
};
+LO_IMPLEMENTATION_H(fmt_formatter, struct lib9p_msg_Tstat, lib9p_msg_Tstat);
#endif /* CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u */
#if CONFIG_9P_ENABLE_9P2000_L
@@ -699,12 +748,14 @@ struct lib9p_msg_Tstatfs {
lib9p_tag_t tag;
lib9p_fid_t fid;
};
+LO_IMPLEMENTATION_H(fmt_formatter, struct lib9p_msg_Tstatfs, lib9p_msg_Tstatfs);
/* size = 11 ; max_iov = 1 ; max_copy = 11 */
struct lib9p_msg_Treadlink {
lib9p_tag_t tag;
lib9p_fid_t fid;
};
+LO_IMPLEMENTATION_H(fmt_formatter, struct lib9p_msg_Treadlink, lib9p_msg_Treadlink);
/* size = 23 ; max_iov = 1 ; max_copy = 23 */
struct lib9p_msg_Treaddir {
@@ -713,6 +764,7 @@ struct lib9p_msg_Treaddir {
uint64_t offset;
uint32_t count;
};
+LO_IMPLEMENTATION_H(fmt_formatter, struct lib9p_msg_Treaddir, lib9p_msg_Treaddir);
#endif /* CONFIG_9P_ENABLE_9P2000_L */
#if CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u
@@ -722,6 +774,7 @@ struct lib9p_msg_Tversion {
uint32_t max_msg_size;
struct lib9p_s version;
};
+LO_IMPLEMENTATION_H(fmt_formatter, struct lib9p_msg_Tversion, lib9p_msg_Tversion);
/* min_size = 13 ; exp_size = 40 ; max_size = 65,548 ; max_iov = 2 ; max_copy = 13 */
struct lib9p_msg_Rversion {
@@ -729,6 +782,7 @@ struct lib9p_msg_Rversion {
uint32_t max_msg_size;
struct lib9p_s version;
};
+LO_IMPLEMENTATION_H(fmt_formatter, struct lib9p_msg_Rversion, lib9p_msg_Rversion);
/* min_size = 17 ; exp_size = 481 ; max_size = 1,048,609 ; max_iov = 32 ; max_copy = 49 */
struct lib9p_msg_Twalk {
@@ -738,6 +792,7 @@ struct lib9p_msg_Twalk {
uint16_t nwname;
struct lib9p_s *wname;
};
+LO_IMPLEMENTATION_H(fmt_formatter, struct lib9p_msg_Twalk, lib9p_msg_Twalk);
#endif /* CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u */
#if CONFIG_9P_ENABLE_9P2000_L
@@ -748,12 +803,14 @@ struct lib9p_msg_Trename {
lib9p_fid_t dfid;
struct lib9p_s name;
};
+LO_IMPLEMENTATION_H(fmt_formatter, struct lib9p_msg_Trename, lib9p_msg_Trename);
/* min_size = 9 ; exp_size = 36 ; max_size = 65,544 ; max_iov = 2 ; max_copy = 9 */
struct lib9p_msg_Rreadlink {
lib9p_tag_t tag;
struct lib9p_s target;
};
+LO_IMPLEMENTATION_H(fmt_formatter, struct lib9p_msg_Rreadlink, lib9p_msg_Rreadlink);
/* min_size = 17 ; exp_size = 44 ; max_size = 65,552 ; max_iov = 2 ; max_copy = 17 */
struct lib9p_msg_Txattrwalk {
@@ -762,6 +819,7 @@ struct lib9p_msg_Txattrwalk {
lib9p_fid_t newfid;
struct lib9p_s name;
};
+LO_IMPLEMENTATION_H(fmt_formatter, struct lib9p_msg_Txattrwalk, lib9p_msg_Txattrwalk);
/* min_size = 25 ; exp_size = 52 ; max_size = 65,560 ; max_iov = 3 ; max_copy = 25 */
struct lib9p_msg_Txattrcreate {
@@ -771,6 +829,7 @@ struct lib9p_msg_Txattrcreate {
uint64_t attr_size;
uint32_t flags;
};
+LO_IMPLEMENTATION_H(fmt_formatter, struct lib9p_msg_Txattrcreate, lib9p_msg_Txattrcreate);
/* min_size = 17 ; exp_size = 44 ; max_size = 65,552 ; max_iov = 2 ; max_copy = 17 */
struct lib9p_msg_Tlink {
@@ -779,6 +838,7 @@ struct lib9p_msg_Tlink {
lib9p_fid_t fid;
struct lib9p_s name;
};
+LO_IMPLEMENTATION_H(fmt_formatter, struct lib9p_msg_Tlink, lib9p_msg_Tlink);
/* min_size = 19 ; exp_size = 73 ; max_size = 131,089 ; max_iov = 4 ; max_copy = 19 */
struct lib9p_msg_Trenameat {
@@ -788,6 +848,7 @@ struct lib9p_msg_Trenameat {
lib9p_fid_t newdirfid;
struct lib9p_s newname;
};
+LO_IMPLEMENTATION_H(fmt_formatter, struct lib9p_msg_Trenameat, lib9p_msg_Trenameat);
/* min_size = 17 ; exp_size = 44 ; max_size = 65,552 ; max_iov = 3 ; max_copy = 17 */
struct lib9p_msg_Tunlinkat {
@@ -796,6 +857,7 @@ struct lib9p_msg_Tunlinkat {
struct lib9p_s name;
uint32_t flags;
};
+LO_IMPLEMENTATION_H(fmt_formatter, struct lib9p_msg_Tunlinkat, lib9p_msg_Tunlinkat);
#endif /* CONFIG_9P_ENABLE_9P2000_L */
#if CONFIG_9P_ENABLE_9P2000_e
@@ -806,6 +868,7 @@ struct lib9p_msg_Tsread {
uint16_t nwname;
struct lib9p_s *wname;
};
+LO_IMPLEMENTATION_H(fmt_formatter, struct lib9p_msg_Tsread, lib9p_msg_Tsread);
/* min_size = 17 ; exp_size = 8,673 ; max_size = 8,589,934,607 (warning: >UINT32_MAX) ; max_iov = 2 + (CONFIG_9P_MAX_9P2000_e_WELEM * 2) ; max_copy = 17 + (CONFIG_9P_MAX_9P2000_e_WELEM * 2) */
struct lib9p_msg_Tswrite {
@@ -816,6 +879,7 @@ struct lib9p_msg_Tswrite {
uint32_t count;
[[gnu::nonstring]] char *data;
};
+LO_IMPLEMENTATION_H(fmt_formatter, struct lib9p_msg_Tswrite, lib9p_msg_Tswrite);
#endif /* CONFIG_9P_ENABLE_9P2000_e */
#if CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u
@@ -825,6 +889,7 @@ struct lib9p_qid {
uint32_t vers;
uint64_t path;
};
+LO_IMPLEMENTATION_H(fmt_formatter, struct lib9p_qid, lib9p_qid);
/* LIB9P_VER_9P2000 : min_size = 15 ; exp_size = 69 ; max_size = 131,085 ; max_iov = 4 ; max_copy = 15 */
/* LIB9P_VER_9P2000_L : min_size = 19 ; exp_size = 73 ; max_size = 131,089 ; max_iov = 5 ; max_copy = 19 */
@@ -840,6 +905,7 @@ struct lib9p_msg_Tauth {
lib9p_nuid_t n_uid;
#endif /* CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_u */
};
+LO_IMPLEMENTATION_H(fmt_formatter, struct lib9p_msg_Tauth, lib9p_msg_Tauth);
/* LIB9P_VER_9P2000 : min_size = 19 ; exp_size = 73 ; max_size = 131,089 ; max_iov = 4 ; max_copy = 19 */
/* LIB9P_VER_9P2000_L : min_size = 23 ; exp_size = 77 ; max_size = 131,093 ; max_iov = 5 ; max_copy = 23 */
@@ -856,6 +922,7 @@ struct lib9p_msg_Tattach {
lib9p_nuid_t n_uid;
#endif /* CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_u */
};
+LO_IMPLEMENTATION_H(fmt_formatter, struct lib9p_msg_Tattach, lib9p_msg_Tattach);
#endif /* CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u */
#if CONFIG_9P_ENABLE_9P2000_L
@@ -867,6 +934,7 @@ struct lib9p_msg_Tsymlink {
struct lib9p_s symtgt;
lib9p_nuid_t gid;
};
+LO_IMPLEMENTATION_H(fmt_formatter, struct lib9p_msg_Tsymlink, lib9p_msg_Tsymlink);
#endif /* CONFIG_9P_ENABLE_9P2000_L */
#if CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u
@@ -876,6 +944,7 @@ struct lib9p_msg_Topen {
lib9p_fid_t fid;
lib9p_o_t mode;
};
+LO_IMPLEMENTATION_H(fmt_formatter, struct lib9p_msg_Topen, lib9p_msg_Topen);
/* min_size = 18 ; exp_size = 45 ; max_size = 65,553 ; max_iov = 3 ; max_copy = 18 */
struct lib9p_msg_Tcreate {
@@ -885,6 +954,7 @@ struct lib9p_msg_Tcreate {
lib9p_dm_t perm;
lib9p_o_t mode;
};
+LO_IMPLEMENTATION_H(fmt_formatter, struct lib9p_msg_Tcreate, lib9p_msg_Tcreate);
#endif /* CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u */
#if CONFIG_9P_ENABLE_9P2000_p9p
@@ -894,6 +964,7 @@ struct lib9p_msg_Topenfd {
lib9p_fid_t fid;
lib9p_o_t mode;
};
+LO_IMPLEMENTATION_H(fmt_formatter, struct lib9p_msg_Topenfd, lib9p_msg_Topenfd);
#endif /* CONFIG_9P_ENABLE_9P2000_p9p */
#if CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u
@@ -909,6 +980,7 @@ struct lib9p_msg_Rerror {
lib9p_errno_t errno;
#endif /* CONFIG_9P_ENABLE_9P2000_u */
};
+LO_IMPLEMENTATION_H(fmt_formatter, struct lib9p_msg_Rerror, lib9p_msg_Rerror);
#endif /* CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u */
#if CONFIG_9P_ENABLE_9P2000_L
@@ -917,6 +989,7 @@ struct lib9p_msg_Rlerror {
lib9p_tag_t tag;
lib9p_errno_t ecode;
};
+LO_IMPLEMENTATION_H(fmt_formatter, struct lib9p_msg_Rlerror, lib9p_msg_Rlerror);
/* size = 67 ; max_iov = 1 ; max_copy = 67 */
struct lib9p_msg_Rstatfs {
@@ -931,6 +1004,7 @@ struct lib9p_msg_Rstatfs {
uint64_t fsid;
uint32_t namelen;
};
+LO_IMPLEMENTATION_H(fmt_formatter, struct lib9p_msg_Rstatfs, lib9p_msg_Rstatfs);
/* size = 15 ; max_iov = 1 ; max_copy = 15 */
struct lib9p_msg_Tlopen {
@@ -938,6 +1012,7 @@ struct lib9p_msg_Tlopen {
lib9p_fid_t fid;
lib9p_lo_t flags;
};
+LO_IMPLEMENTATION_H(fmt_formatter, struct lib9p_msg_Tlopen, lib9p_msg_Tlopen);
/* min_size = 25 ; exp_size = 52 ; max_size = 65,560 ; max_iov = 3 ; max_copy = 25 */
struct lib9p_msg_Tlcreate {
@@ -948,6 +1023,7 @@ struct lib9p_msg_Tlcreate {
lib9p_mode_t mode;
lib9p_nuid_t gid;
};
+LO_IMPLEMENTATION_H(fmt_formatter, struct lib9p_msg_Tlcreate, lib9p_msg_Tlcreate);
/* min_size = 29 ; exp_size = 56 ; max_size = 65,564 ; max_iov = 3 ; max_copy = 29 */
struct lib9p_msg_Tmknod {
@@ -959,6 +1035,7 @@ struct lib9p_msg_Tmknod {
uint32_t minor;
lib9p_nuid_t gid;
};
+LO_IMPLEMENTATION_H(fmt_formatter, struct lib9p_msg_Tmknod, lib9p_msg_Tmknod);
/* min_size = 21 ; exp_size = 48 ; max_size = 65,556 ; max_iov = 3 ; max_copy = 21 */
struct lib9p_msg_Tmkdir {
@@ -968,6 +1045,7 @@ struct lib9p_msg_Tmkdir {
lib9p_mode_t mode;
lib9p_nuid_t gid;
};
+LO_IMPLEMENTATION_H(fmt_formatter, struct lib9p_msg_Tmkdir, lib9p_msg_Tmkdir);
/* size = 15 ; max_iov = 1 ; max_copy = 15 */
struct lib9p_msg_Tfsync {
@@ -975,6 +1053,7 @@ struct lib9p_msg_Tfsync {
lib9p_fid_t fid;
lib9p_b4_t datasync;
};
+LO_IMPLEMENTATION_H(fmt_formatter, struct lib9p_msg_Tfsync, lib9p_msg_Tfsync);
/* size = 19 ; max_iov = 1 ; max_copy = 19 */
struct lib9p_msg_Tgetattr {
@@ -982,6 +1061,7 @@ struct lib9p_msg_Tgetattr {
lib9p_fid_t fid;
lib9p_getattr_t request_mask;
};
+LO_IMPLEMENTATION_H(fmt_formatter, struct lib9p_msg_Tgetattr, lib9p_msg_Tgetattr);
/* size = 67 ; max_iov = 1 ; max_copy = 67 */
struct lib9p_msg_Tsetattr {
@@ -997,6 +1077,7 @@ struct lib9p_msg_Tsetattr {
uint64_t mtime_sec;
uint64_t mtime_nsec;
};
+LO_IMPLEMENTATION_H(fmt_formatter, struct lib9p_msg_Tsetattr, lib9p_msg_Tsetattr);
/* min_size = 34 ; exp_size = 61 ; max_size = 65,569 ; max_iov = 2 ; max_copy = 34 */
struct lib9p_msg_Tgetlock {
@@ -1008,6 +1089,7 @@ struct lib9p_msg_Tgetlock {
uint32_t proc_id;
struct lib9p_s client_id;
};
+LO_IMPLEMENTATION_H(fmt_formatter, struct lib9p_msg_Tgetlock, lib9p_msg_Tgetlock);
/* min_size = 30 ; exp_size = 57 ; max_size = 65,565 ; max_iov = 2 ; max_copy = 30 */
struct lib9p_msg_Rgetlock {
@@ -1018,6 +1100,7 @@ struct lib9p_msg_Rgetlock {
uint32_t proc_id;
struct lib9p_s client_id;
};
+LO_IMPLEMENTATION_H(fmt_formatter, struct lib9p_msg_Rgetlock, lib9p_msg_Rgetlock);
/* min_size = 38 ; exp_size = 65 ; max_size = 65,573 ; max_iov = 2 ; max_copy = 38 */
struct lib9p_msg_Tlock {
@@ -1030,12 +1113,14 @@ struct lib9p_msg_Tlock {
uint32_t proc_id;
struct lib9p_s client_id;
};
+LO_IMPLEMENTATION_H(fmt_formatter, struct lib9p_msg_Tlock, lib9p_msg_Tlock);
/* size = 8 ; max_iov = 1 ; max_copy = 8 */
struct lib9p_msg_Rlock {
lib9p_tag_t tag;
lib9p_lock_status_t status;
};
+LO_IMPLEMENTATION_H(fmt_formatter, struct lib9p_msg_Rlock, lib9p_msg_Rlock);
#endif /* CONFIG_9P_ENABLE_9P2000_L */
#if CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u
@@ -1062,6 +1147,7 @@ struct lib9p_stat {
lib9p_nuid_t file_last_modified_n_uid;
#endif /* CONFIG_9P_ENABLE_9P2000_u */
};
+LO_IMPLEMENTATION_H(fmt_formatter, struct lib9p_stat, lib9p_stat);
#endif /* CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u */
#if CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u
@@ -1070,12 +1156,14 @@ struct lib9p_msg_Rauth {
lib9p_tag_t tag;
struct lib9p_qid aqid;
};
+LO_IMPLEMENTATION_H(fmt_formatter, struct lib9p_msg_Rauth, lib9p_msg_Rauth);
/* size = 20 ; max_iov = 1 ; max_copy = 20 */
struct lib9p_msg_Rattach {
lib9p_tag_t tag;
struct lib9p_qid qid;
};
+LO_IMPLEMENTATION_H(fmt_formatter, struct lib9p_msg_Rattach, lib9p_msg_Rattach);
/* min_size = 9 ; exp_size = 217 ; max_size = 217 ; max_iov = 1 ; max_copy = 217 */
struct lib9p_msg_Rwalk {
@@ -1083,6 +1171,7 @@ struct lib9p_msg_Rwalk {
uint16_t nwqid;
struct lib9p_qid *wqid;
};
+LO_IMPLEMENTATION_H(fmt_formatter, struct lib9p_msg_Rwalk, lib9p_msg_Rwalk);
#endif /* CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u */
#if CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u
@@ -1092,6 +1181,7 @@ struct lib9p_msg_Ropen {
struct lib9p_qid qid;
uint32_t iounit;
};
+LO_IMPLEMENTATION_H(fmt_formatter, struct lib9p_msg_Ropen, lib9p_msg_Ropen);
/* size = 24 ; max_iov = 1 ; max_copy = 24 */
struct lib9p_msg_Rcreate {
@@ -1099,6 +1189,7 @@ struct lib9p_msg_Rcreate {
struct lib9p_qid qid;
uint32_t iounit;
};
+LO_IMPLEMENTATION_H(fmt_formatter, struct lib9p_msg_Rcreate, lib9p_msg_Rcreate);
#endif /* CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u */
#if CONFIG_9P_ENABLE_9P2000_p9p
@@ -1109,6 +1200,7 @@ struct lib9p_msg_Ropenfd {
uint32_t iounit;
uint32_t unixfd;
};
+LO_IMPLEMENTATION_H(fmt_formatter, struct lib9p_msg_Ropenfd, lib9p_msg_Ropenfd);
#endif /* CONFIG_9P_ENABLE_9P2000_p9p */
#if CONFIG_9P_ENABLE_9P2000_L
@@ -1118,6 +1210,7 @@ struct lib9p_msg_Rlopen {
struct lib9p_qid qid;
uint32_t iounit;
};
+LO_IMPLEMENTATION_H(fmt_formatter, struct lib9p_msg_Rlopen, lib9p_msg_Rlopen);
/* size = 24 ; max_iov = 1 ; max_copy = 24 */
struct lib9p_msg_Rlcreate {
@@ -1125,18 +1218,21 @@ struct lib9p_msg_Rlcreate {
struct lib9p_qid qid;
uint32_t iounit;
};
+LO_IMPLEMENTATION_H(fmt_formatter, struct lib9p_msg_Rlcreate, lib9p_msg_Rlcreate);
/* size = 20 ; max_iov = 1 ; max_copy = 20 */
struct lib9p_msg_Rsymlink {
lib9p_tag_t tag;
struct lib9p_qid qid;
};
+LO_IMPLEMENTATION_H(fmt_formatter, struct lib9p_msg_Rsymlink, lib9p_msg_Rsymlink);
/* size = 20 ; max_iov = 1 ; max_copy = 20 */
struct lib9p_msg_Rmknod {
lib9p_tag_t tag;
struct lib9p_qid qid;
};
+LO_IMPLEMENTATION_H(fmt_formatter, struct lib9p_msg_Rmknod, lib9p_msg_Rmknod);
/* size = 160 ; max_iov = 1 ; max_copy = 160 */
struct lib9p_msg_Rgetattr {
@@ -1162,12 +1258,14 @@ struct lib9p_msg_Rgetattr {
uint64_t gen;
uint64_t data_version;
};
+LO_IMPLEMENTATION_H(fmt_formatter, struct lib9p_msg_Rgetattr, lib9p_msg_Rgetattr);
/* size = 20 ; max_iov = 1 ; max_copy = 20 */
struct lib9p_msg_Rmkdir {
lib9p_tag_t tag;
struct lib9p_qid qid;
};
+LO_IMPLEMENTATION_H(fmt_formatter, struct lib9p_msg_Rmkdir, lib9p_msg_Rmkdir);
#endif /* CONFIG_9P_ENABLE_9P2000_L */
#if CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u
@@ -1179,6 +1277,7 @@ struct lib9p_msg_Rstat {
lib9p_tag_t tag;
struct lib9p_stat stat;
};
+LO_IMPLEMENTATION_H(fmt_formatter, struct lib9p_msg_Rstat, lib9p_msg_Rstat);
/* LIB9P_VER_9P2000 : min_size = 62 ; exp_size = 170 ; max_size = 262,202 ; max_iov = 8 ; max_copy = 62 */
/* LIB9P_VER_9P2000_e : min_size = 62 ; exp_size = 170 ; max_size = 262,202 ; max_iov = 8 ; max_copy = 62 */
@@ -1189,6 +1288,7 @@ struct lib9p_msg_Twstat {
lib9p_fid_t fid;
struct lib9p_stat stat;
};
+LO_IMPLEMENTATION_H(fmt_formatter, struct lib9p_msg_Twstat, lib9p_msg_Twstat);
#endif /* CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u */
/* containers *****************************************************************/
diff --git a/lib9p/include/lib9p/9p.h b/lib9p/include/lib9p/9p.h
index ffac453..5919260 100644
--- a/lib9p/include/lib9p/9p.h
+++ b/lib9p/include/lib9p/9p.h
@@ -18,6 +18,7 @@
#ifndef CONFIG_9P_MAX_ERR_SIZE
#error config.h must define CONFIG_9P_MAX_ERR_SIZE
#endif
+static_assert(CONFIG_9P_MAX_ERR_SIZE <= UINT16_MAX);
/* constants ******************************************************************/
@@ -60,6 +61,12 @@ int lib9p_error(struct lib9p_ctx *ctx, lib9p_errno_t linux_errno, char const *ms
/** Write a printf-style error into ctx, return -1. */
int lib9p_errorf(struct lib9p_ctx *ctx, lib9p_errno_t linux_errno, char const *fmt, ...) [[gnu::format(printf, 3, 4)]];
+/* misc utilities *************************************************************/
+
+uint32_t lib9p_version_min_msg_size(enum lib9p_version);
+
+lo_interface fmt_formatter lo_box_lib9p_msg_as_fmt_formatter(struct lib9p_ctx *ctx, enum lib9p_msg_type typ, void *body);
+
/* main T-message functions ***************************************************/
/**
diff --git a/lib9p/internal.h b/lib9p/internal.h
deleted file mode 100644
index 92340a5..0000000
--- a/lib9p/internal.h
+++ /dev/null
@@ -1,100 +0,0 @@
-/* lib9p/internal.h - Internal machinery shared between parts of lib9p
- *
- * Copyright (C) 2024-2025 Luke T. Shumaker <lukeshu@lukeshu.com>
- * SPDX-License-Identifier: AGPL-3.0-or-later
- */
-
-#ifndef _LIB9P_INTERNAL_H_
-#define _LIB9P_INTERNAL_H_
-
-#include <stddef.h> /* for size_t */
-#include <limits.h> /* for SSIZE_MAX, not set by newlib */
-#ifndef SSIZE_MAX
-#define SSIZE_MAX (SIZE_MAX >> 1)
-#endif
-
-#include <libmisc/endian.h>
-#include <libmisc/macro.h>
-
-#include <lib9p/9p.h>
-
-/* configuration **************************************************************/
-
-#include "config.h"
-
-#ifndef CONFIG_9P_MAX_MSG_SIZE
- #error config.h must define CONFIG_9P_MAX_MSG_SIZE
-#endif
-#ifndef CONFIG_9P_MAX_HOSTMSG_SIZE
- #error config.h must define CONFIG_9P_MAX_HOSTMSG_SIZE
-#endif
-#ifndef CONFIG_9P_MAX_ERR_SIZE
- #error config.h must define CONFIG_9P_MAX_ERR_SIZE
-#endif
-
-static_assert(CONFIG_9P_MAX_ERR_SIZE <= UINT16_MAX);
-static_assert(CONFIG_9P_MAX_MSG_SIZE <= CONFIG_9P_MAX_HOSTMSG_SIZE);
-static_assert(CONFIG_9P_MAX_HOSTMSG_SIZE <= SSIZE_MAX);
-
-/* tables / exports ***********************************************************/
-
-typedef ssize_t (*_validate_fn_t)(struct lib9p_ctx *ctx, uint32_t net_size, uint8_t *net_bytes);
-typedef void (*_unmarshal_fn_t)(struct lib9p_ctx *ctx, uint8_t *net_bytes, void *out);
-
-struct _marshal_ret {
- size_t net_iov_cnt;
- struct iovec *net_iov;
- size_t net_copied_size;
- uint8_t *net_copied;
-};
-typedef bool (*_marshal_fn_t)(struct lib9p_ctx *ctx, void *host_val, struct _marshal_ret *ret);
-
-struct _lib9p_recv_tentry {
- size_t basesize;
- _validate_fn_t validate;
- _unmarshal_fn_t unmarshal;
-};
-
-struct _lib9p_send_tentry {
- _marshal_fn_t marshal;
-};
-
-extern const char *const _lib9p_table_ver_name[LIB9P_VER_NUM];
-extern const char *const _lib9p_table_msg_name[LIB9P_VER_NUM][0x100];
-extern const uint32_t _lib9p_table_msg_min_size[LIB9P_VER_NUM];
-extern const struct _lib9p_recv_tentry _lib9p_table_Tmsg_recv[LIB9P_VER_NUM][0x80];
-extern const struct _lib9p_recv_tentry _lib9p_table_Rmsg_recv[LIB9P_VER_NUM][0x80];
-extern const struct _lib9p_send_tentry _lib9p_table_Tmsg_send[LIB9P_VER_NUM][0x80];
-extern const struct _lib9p_send_tentry _lib9p_table_Rmsg_send[LIB9P_VER_NUM][0x80];
-
-ssize_t _lib9p_stat_validate(struct lib9p_ctx *ctx, uint32_t net_size, uint8_t *net_bytes, uint32_t *ret_net_size);
-void _lib9p_stat_unmarshal(struct lib9p_ctx *ctx, uint8_t *net_bytes, void *out);
-bool _lib9p_stat_marshal(struct lib9p_ctx *ctx, struct lib9p_stat *val, struct _marshal_ret *ret);
-
-/* unmarshal utilities ********************************************************/
-
-static inline bool _is_valid_utf8(uint8_t *str, size_t len, bool forbid_nul) {
- uint32_t ch;
- uint8_t chlen;
- assert(str);
- for (size_t pos = 0; pos < len;) {
- if ((str[pos] & 0b10000000) == 0b00000000) { ch = str[pos] & 0b01111111; chlen = 1; }
- else if ((str[pos] & 0b11100000) == 0b11000000) { ch = str[pos] & 0b00011111; chlen = 2; }
- else if ((str[pos] & 0b11110000) == 0b11100000) { ch = str[pos] & 0b00001111; chlen = 3; }
- else if ((str[pos] & 0b11111000) == 0b11110000) { ch = str[pos] & 0b00000111; chlen = 4; }
- else return false;
- if ((ch == 0 && (chlen != 1 || forbid_nul)) || pos + chlen > len) return false;
- for (uint8_t i = 1; i < chlen; i++) {
- if ((str[pos+i] & 0b11000000) != 0b10000000) return false;
- ch = (ch << 6) | (str[pos+i] & 0b00111111);
- }
- if (ch > 0x10FFFF) return false;
- pos += chlen;
- }
- return true;
-}
-
-#define is_valid_utf8(str, len) _is_valid_utf8(str, len, false)
-#define is_valid_utf8_without_nul(str, len) _is_valid_utf8(str, len, true)
-
-#endif /* _LIB9P_INTERNAL_H_ */
diff --git a/lib9p/map.h b/lib9p/map.h
index ab9564f..c5eab0f 100644
--- a/lib9p/map.h
+++ b/lib9p/map.h
@@ -4,8 +4,6 @@
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
-#include "internal.h"
-
/**
* `#define` `NAME`, `KEY_T`, `VAL_T`, and `CAP`; then `#include
* "map.h".
diff --git a/lib9p/protogen/c.py b/lib9p/protogen/c.py
index 5e67939..a6824ce 100644
--- a/lib9p/protogen/c.py
+++ b/lib9p/protogen/c.py
@@ -7,7 +7,7 @@ import sys
import idl
-from . import c9util, c_marshal, c_unmarshal, c_validate, cutil
+from . import c9util, c_format, c_marshal, c_unmarshal, c_validate, cutil
# This strives to be "general-purpose" in that it just acts on the
# *.9p inputs; but (unfortunately?) there are a few special-cases in
@@ -29,11 +29,21 @@ def gen_c(versions: set[str], typs: list[idl.UserType]) -> str:
#include <string.h> /* for memset() */
#include <libmisc/assert.h>
+#include <libmisc/endian.h>
#include <lib9p/9p.h>
-#include "internal.h"
+#include "tables.h"
+#include "utf8.h"
"""
+ # libobj vtables ###########################################################
+ ret += """
+/* libobj vtables *************************************************************/
+"""
+ for typ in typs:
+ ret += cutil.ifdef_push(1, c9util.ver_ifdef(typ.in_versions))
+ ret += f"LO_IMPLEMENTATION_C(fmt_formatter, {c9util.typename(typ)}, {c9util.basename(typ)}, static);\n"
+ ret += cutil.ifdef_pop(0)
# utilities ################################################################
ret += """
@@ -44,28 +54,6 @@ def gen_c(versions: set[str], typs: list[idl.UserType]) -> str:
for msg in [msg for msg in typs if isinstance(msg, idl.Message)]:
id2typ[msg.msgid] = msg
- def msg_table(grp: str, meth: str, tentry: str, rng: tuple[int, int, int]) -> str:
- ret = f"const {tentry} {c9util.ident(f'_table_{grp}_{meth}')}[{c9util.ver_enum('NUM')}][{hex(len(range(*rng)))}] = {{\n"
- for ver in ["unknown", *sorted(versions)]:
- if ver != "unknown":
- ret += cutil.ifdef_push(1, c9util.ver_ifdef({ver}))
- ret += f"\t[{c9util.ver_enum(ver)}] = {{\n"
- for n in range(*rng):
- 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 xmsg:
- ret += f"\t\t_MSG_{meth.upper()}({xmsg.typname}),\n"
- ret += "\t},\n"
- ret += cutil.ifdef_pop(0)
- ret += "};\n"
- return ret
-
for v in sorted(versions):
ret += f"#if CONFIG_9P_ENABLE_{v.replace('.', '_')}\n"
ret += (
@@ -83,23 +71,6 @@ def gen_c(versions: set[str], typs: list[idl.UserType]) -> str:
ret += " */\n"
ret += "#define is_ver(ctx, ver) _is_ver_##ver((ctx)->version)\n"
- # strings ##################################################################
- ret += f"""
-/* strings ********************************************************************/
-
-const char *const {c9util.ident('_table_ver_name')}[{c9util.ver_enum('NUM')}] = {{
-"""
- for ver in ["unknown", *sorted(versions)]:
- if ver in versions:
- ret += cutil.ifdef_push(1, c9util.ver_ifdef({ver}))
- ret += f'\t[{c9util.ver_enum(ver)}] = "{ver}",\n'
- ret += cutil.ifdef_pop(0)
- ret += "};\n"
-
- ret += "\n"
- ret += f"#define _MSG_NAME(typ) [{c9util.Ident('TYP_')}##typ] = #typ\n"
- ret += msg_table("msg", "name", "char *const", (0, 0x100, 1))
-
# bitmasks #################################################################
ret += """
/* bitmasks *******************************************************************/
@@ -118,7 +89,7 @@ const char *const {c9util.ident('_table_ver_name')}[{c9util.ver_enum('NUM')}] =
+ "".join(
(
"1"
- if bit.cat in (idl.BitCat.USED, idl.BitCat.SUBFIELD)
+ if (bit.cat == "USED" or isinstance(bit.cat, idl.BitNum))
and ver in bit.in_versions
else "0"
)
@@ -139,25 +110,63 @@ const char *const {c9util.ident('_table_ver_name')}[{c9util.ver_enum('NUM')}] =
# marshal_* ################################################################
ret += c_marshal.gen_c_marshal(versions, typs)
- # function tables ##########################################################
+ # *_format #################################################################
+ ret += c_format.gen_c_format(versions, typs)
+
+ # tables.h #################################################################
ret += """
-/* function tables ************************************************************/
+/* tables.h *******************************************************************/
"""
ret += "\n"
- ret += f"const uint32_t {c9util.ident('_table_msg_min_size')}[{c9util.ver_enum('NUM')}] = {{\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")
- ret += f"\t[{c9util.ver_enum('unknown')}] = {rerror.min_size('9P2000')},\n" # SPECIAL (initialization)
- for ver in sorted(versions):
- ret += cutil.ifdef_push(1, c9util.ver_ifdef({ver}))
- ret += f"\t[{c9util.ver_enum(ver)}] = {rerror.min_size(ver)},\n"
+ for ver in ["unknown", *sorted(versions)]:
+ 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)
+ ret += f'\t[{c9util.ver_enum(ver)}] = {{.name="{ver}", .min_msg_size={min_msg_size}}},\n'
ret += cutil.ifdef_pop(0)
ret += "};\n"
+ def msg_table(
+ 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}))
+ 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 xmsg:
+ ret += f"\t\t{each}({xmsg.typname}),\n"
+ ret += "\t},\n"
+ ret += cutil.ifdef_pop(0)
+ ret += "};\n"
+ return ret
+
+ ret += "\n"
+ ret += cutil.macro(
+ f"#define _MSG(typ) [{c9util.Ident('TYP_')}##typ] = {{\n"
+ f"\t\t.name = #typ,\n"
+ f"\t\t.box_as_fmt_formatter = (_box_as_fmt_formatter_fn_t)lo_box_{c9util.ident('msg_')}##typ##_as_fmt_formatter,\n"
+ f"\t}}\n"
+ )
+ ret += msg_table("_msg_tentry", "_table_msg", "_MSG", (0, 0x100, 1))
+
ret += "\n"
ret += cutil.macro(
f"#define _MSG_RECV(typ) [{c9util.Ident('TYP_')}##typ/2] = {{\n"
- f"\t\t.basesize = sizeof(struct {c9util.ident('msg_')}##typ),\n"
f"\t\t.validate = validate_##typ,\n"
f"\t\t.unmarshal = (_unmarshal_fn_t)unmarshal_##typ,\n"
f"\t}}\n"
@@ -168,21 +177,13 @@ const char *const {c9util.ident('_table_ver_name')}[{c9util.ver_enum('NUM')}] =
f"\t}}\n"
)
ret += "\n"
- ret += msg_table(
- "Tmsg", "recv", f"struct {c9util.ident('_recv_tentry')}", (0, 0x100, 2)
- )
+ ret += msg_table("_recv_tentry", "_table_Tmsg_recv", "_MSG_RECV", (0, 0x100, 2))
ret += "\n"
- ret += msg_table(
- "Rmsg", "recv", f"struct {c9util.ident('_recv_tentry')}", (1, 0x100, 2)
- )
+ ret += msg_table("_recv_tentry", "_table_Rmsg_recv", "_MSG_RECV", (1, 0x100, 2))
ret += "\n"
- ret += msg_table(
- "Tmsg", "send", f"struct {c9util.ident('_send_tentry')}", (0, 0x100, 2)
- )
+ ret += msg_table("_send_tentry", "_table_Tmsg_send", "_MSG_SEND", (0, 0x100, 2))
ret += "\n"
- ret += msg_table(
- "Rmsg", "send", f"struct {c9util.ident('_send_tentry')}", (1, 0x100, 2)
- )
+ ret += msg_table("_send_tentry", "_table_Rmsg_send", "_MSG_SEND", (1, 0x100, 2))
ret += f"""
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) {{
diff --git a/lib9p/protogen/c9util.py b/lib9p/protogen/c9util.py
index e7ad999..cf91951 100644
--- a/lib9p/protogen/c9util.py
+++ b/lib9p/protogen/c9util.py
@@ -3,6 +3,7 @@
# Copyright (C) 2024-2025 Luke T. Shumaker <lukeshu@lukeshu.com>
# SPDX-License-Identifier: AGPL-3.0-or-later
+import re
import typing
import idl
@@ -72,6 +73,20 @@ def ver_cond(versions: typing.Collection[str]) -> str:
# misc #########################################################################
+def basename(typ: idl.UserType) -> str:
+ match typ:
+ case idl.Number():
+ return ident(typ.typname)
+ case idl.Bitfield():
+ return ident(typ.typname)
+ case idl.Message():
+ return ident(f"msg_{typ.typname}")
+ case idl.Struct():
+ return ident(typ.typname)
+ case _:
+ raise ValueError(f"not a defined type: {typ.__class__.__name__}")
+
+
def typename(typ: idl.Type, parent: idl.StructMember | None = None) -> str:
match typ:
case idl.Primitive():
@@ -79,31 +94,41 @@ def typename(typ: idl.Type, parent: idl.StructMember | None = None) -> str:
return "[[gnu::nonstring]] char"
return f"uint{typ.value*8}_t"
case idl.Number():
- return ident(f"{typ.typname}_t")
+ return f"{basename(typ)}_t"
case idl.Bitfield():
- return ident(f"{typ.typname}_t")
+ return f"{basename(typ)}_t"
case idl.Message():
- return f"struct {ident(f'msg_{typ.typname}')}"
+ return f"struct {basename(typ)}"
case idl.Struct():
- return f"struct {ident(typ.typname)}"
+ return f"struct {basename(typ)}"
case _:
raise ValueError(f"not a type: {typ.__class__.__name__}")
-def idl_expr(expr: idl.Expr, lookup_sym: typing.Callable[[str], str]) -> str:
+def idl_expr(
+ expr: idl.Expr, lookup_sym: typing.Callable[[str], str], bitwidth: int = 0
+) -> str:
ret: list[str] = []
for tok in expr.tokens:
match tok:
case idl.ExprOp():
ret.append(tok.op)
case idl.ExprLit():
- ret.append(str(tok.val))
- case idl.ExprSym(symname="s32_max"):
- ret.append("INT32_MAX")
- case idl.ExprSym(symname="s64_max"):
- ret.append("INT64_MAX")
+ if bitwidth:
+ ret.append(f"{tok.val:#0{bitwidth}b}")
+ else:
+ ret.append(str(tok.val))
case idl.ExprSym():
- ret.append(lookup_sym(tok.symname))
+ if m := re.fullmatch(r"^u(8|16|32|64)_max$", tok.symname):
+ ret.append(f"UINT{m.group(1)}_MAX")
+ elif m := re.fullmatch(r"^s(8|16|32|64)_max$", tok.symname):
+ ret.append(f"INT{m.group(1)}_MAX")
+ else:
+ ret.append(lookup_sym(tok.symname))
+ case idl.ExprOff():
+ ret.append(lookup_sym("&" + tok.membname))
+ case idl.ExprNum():
+ ret.append(Ident(add_prefix(f"{tok.numname}_".upper(), tok.valname)))
case _:
assert False
return " ".join(ret)
diff --git a/lib9p/protogen/c_format.py b/lib9p/protogen/c_format.py
new file mode 100644
index 0000000..a1bcbf3
--- /dev/null
+++ b/lib9p/protogen/c_format.py
@@ -0,0 +1,142 @@
+# lib9p/protogen/c_format.py - Generate C pretty-print functions
+#
+# Copyright (C) 2024-2025 Luke T. Shumaker <lukeshu@lukeshu.com>
+# SPDX-License-Identifier: AGPL-3.0-or-later
+
+
+import idl
+
+from . import c9util, cutil
+
+# This strives to be "general-purpose" in that it just acts on the
+# *.9p inputs; but (unfortunately?) there are a few special-cases in
+# this script, marked with "SPECIAL".
+
+# pylint: disable=unused-variable
+__all__ = ["gen_c_format"]
+
+
+def bf_numname(typ: idl.Bitfield, num: idl.BitNum, base: str) -> str:
+ prefix = f"{typ.typname}_{num.numname}_".upper()
+ return c9util.Ident(c9util.add_prefix(prefix, base))
+
+
+def gen_c_format(versions: set[str], typs: list[idl.UserType]) -> str:
+ ret = """
+/* *_format *******************************************************************/
+"""
+ for typ in typs:
+ ret += "\n"
+ ret += cutil.ifdef_push(1, c9util.ver_ifdef(typ.in_versions))
+ ret += f"static void {c9util.basename(typ)}_format({c9util.typename(typ)} *self, struct fmt_state *state) {{\n"
+ match typ:
+ case idl.Number():
+ if typ.vals:
+ ret += "\tswitch (*self) {\n"
+ for name in typ.vals:
+ ret += f"\tcase {c9util.Ident(c9util.add_prefix(f'{typ.typname}_'.upper(), name))}:\n"
+ ret += f'\t\tfmt_state_puts(state, "{name}");\n'
+ ret += "\t\tbreak;\n"
+ ret += "\tdefault:\n"
+ ret += f'\t\tfmt_state_printf(state, "%"PRIu{typ.static_size*8}, *self);\n'
+ ret += "\t}\n"
+ else:
+ ret += f'\t\tfmt_state_printf(state, "%"PRIu{typ.static_size*8}, *self);\n'
+ case idl.Bitfield():
+ val = "*self"
+ if typ.typname == "dm": # SPECIAL (pretty file permissions)
+ val = f"(*self & ~(({c9util.typename(typ)})0777))"
+ ret += "\tbool empty = true;\n"
+ ret += "\tfmt_state_putchar(state, '(');\n"
+ nums: set[str] = set()
+
+ for bit in reversed(typ.bits):
+ match bit.cat:
+ case "UNUSED" | "USED" | "RESERVED":
+ if bit.cat == "UNUSED":
+ bitname = f"1<<{bit.num}"
+ else:
+ bitname = bit.bitname
+ ret += f"\tif ({val} & (UINT{typ.static_size*8}_C(1)<<{bit.num})) {{\n"
+ ret += "\t\tif (!empty)\n"
+ ret += "\t\t\tfmt_state_putchar(state, '|');\n"
+ ret += f'\t\tfmt_state_puts(state, "{bitname}");\n'
+ ret += "\t\tempty = false;\n"
+ ret += "\t}\n"
+ case idl.BitNum():
+ if bit.cat.numname in nums:
+ continue
+ ret += f"\tswitch ({val} & {bf_numname(typ, bit.cat, 'MASK')}) {{\n"
+ for name in bit.cat.vals:
+ ret += f"\tcase {bf_numname(typ, bit.cat, name)}:\n"
+ bitname = c9util.add_prefix(
+ f"{bit.cat.numname}_".upper(), name
+ )
+ ret += "\t\tif (!empty)\n"
+ ret += "\t\t\tfmt_state_putchar(state, '|');\n"
+ ret += f'\t\tfmt_state_puts(state, "{bitname}");\n'
+ ret += "\t\tempty = false;\n"
+ ret += "\t\tbreak;\n"
+ ret += "\tdefault:\n"
+ ret += "\t\tif (!empty)\n"
+ ret += "\t\t\tfmt_state_putchar(state, '|');\n"
+ ret += f'\t\tfmt_state_printf(state, "%"PRIu{typ.static_size*8}, {val} & {bf_numname(typ, bit.cat, 'MASK')});\n'
+ ret += "\t\tempty = false;\n"
+ ret += "\t}\n"
+ nums.add(bit.cat.numname)
+ if typ.typname == "dm": # SPECIAL (pretty file permissions)
+ ret += "\tif (!empty)\n"
+ ret += "\t\tfmt_state_putchar(state, '|');\n"
+ ret += f'\tfmt_state_printf(state, "%#04"PRIo{typ.static_size*8}, *self & 0777);\n'
+ else:
+ 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)
+ ret += "\t/* https://gcc.gnu.org/bugzilla/show_bug.cgi?id=47781 */\n"
+ ret += "#pragma GCC diagnostic push\n"
+ ret += '#pragma GCC diagnostic ignored "-Wformat"\n'
+ ret += '#pragma GCC diagnostic ignored "-Wformat-extra-args"\n'
+ ret += '\tfmt_state_printf(state, "%.*q", self->len, self->utf8);\n'
+ ret += "#pragma GCC diagnostic pop\n"
+ case idl.Struct(): # and idl.Message():
+ if isinstance(typ, idl.Message):
+ ret += f'\tfmt_state_puts(state, "{typ.typname} {{");\n'
+ else:
+ ret += "\tfmt_state_putchar(state, '{');\n"
+ for member in typ.members:
+ if member.val:
+ continue
+ ret += cutil.ifdef_push(2, c9util.ver_ifdef(member.in_versions))
+ if member.cnt:
+ if member.typ.static_size == 1: # SPECIAL (data)
+ ret += f'\tfmt_state_puts(state, " {member.membname}=<bytedata>");\n'
+ continue
+ if isinstance(member.cnt, int):
+ cnt_str = str(member.cnt)
+ cnt_typ = "size_t"
+ else:
+ cnt_str = f"self->{member.cnt.membname}"
+ cnt_typ = c9util.typename(member.cnt.typ)
+ ret += f'\tfmt_state_puts(state, " {member.membname}=[");\n'
+ ret += f"\tfor ({cnt_typ} i = 0; i < {cnt_str}; i++) {{\n"
+ ret += "\t\tif (i)\n"
+ ret += '\t\t\tfmt_state_puts(state, ", ");\n'
+ if isinstance(member.typ, idl.Primitive):
+ ret += f'\t\tfmt_state_printf(state, "%"PRIu{member.typ.static_size*8}, self->{member.membname}[i]);\n'
+ else:
+ ret += f"\t\t{c9util.basename(member.typ)}_format(&self->{member.membname}[i], state);\n"
+ ret += "\t}\n"
+ ret += '\tfmt_state_puts(state, " ]");\n'
+ else:
+ ret += f'\tfmt_state_puts(state, " {member.membname}=");\n'
+ if isinstance(member.typ, idl.Primitive):
+ ret += f'\tfmt_state_printf(state, "%"PRIu{member.typ.static_size*8}, self->{member.membname});\n'
+ else:
+ ret += f"\t{c9util.basename(member.typ)}_format(&self->{member.membname}, state);\n"
+ ret += cutil.ifdef_pop(1)
+ ret += '\tfmt_state_puts(state, " }");\n'
+ ret += "}\n"
+ ret += cutil.ifdef_pop(0)
+
+ return ret
diff --git a/lib9p/protogen/c_marshal.py b/lib9p/protogen/c_marshal.py
index 74b64f5..4dab864 100644
--- a/lib9p/protogen/c_marshal.py
+++ b/lib9p/protogen/c_marshal.py
@@ -23,7 +23,7 @@ __all__ = ["gen_c_marshal"]
class OffsetExpr:
static: int
cond: dict[frozenset[str], "OffsetExpr"]
- rep: list[tuple[idlutil.Path, "OffsetExpr"]]
+ rep: list[tuple[idlutil.Path | int, "OffsetExpr"]]
def __init__(self) -> None:
self.static = 0
@@ -52,14 +52,20 @@ class OffsetExpr:
if self.static:
oneline.append(str(self.static))
for cnt, sub in self.rep:
+ if isinstance(cnt, int):
+ cnt_str = str(cnt)
+ cnt_typ = "size_t"
+ else:
+ cnt_str = cnt.c_str(root)
+ cnt_typ = c9util.typename(cnt.elems[-1].typ)
if not sub.cond and not sub.rep:
if sub.static == 1:
- oneline.append(cnt.c_str(root))
+ oneline.append(cnt_str)
else:
- oneline.append(f"({cnt.c_str(root)})*{sub.static}")
+ oneline.append(f"({cnt_str})*{sub.static}")
continue
loopvar = chr(ord("i") + loop_depth)
- multiline += f"{'\t'*indent_depth}for ({c9util.typename(cnt.elems[-1].typ)} {loopvar} = 0; {loopvar} < {cnt.c_str(root)}; {loopvar}++) {{\n"
+ multiline += f"{'\t'*indent_depth}for ({cnt_typ} {loopvar} = 0; {loopvar} < {cnt_str}; {loopvar}++) {{\n"
multiline += sub.gen_c("", dstvar, root, indent_depth + 1, loop_depth + 1)
multiline += f"{'\t'*indent_depth}}}\n"
for vers, sub in self.cond.items():
@@ -113,8 +119,12 @@ def get_offset_expr(typ: idl.UserType, recurse: OffsetExprRecursion) -> OffsetEx
member_path = expr_stack[-1].path
member = member_path.elems[-1]
assert member.cnt
- cnt_path = member_path.parent().add(member.cnt)
- expr_stack[-2].expr.rep.append((cnt_path, expr_stack[-1].expr))
+ cnt: idlutil.Path | int
+ if isinstance(member.cnt, int):
+ cnt = member.cnt
+ else:
+ cnt = member_path.parent().add(member.cnt)
+ expr_stack[-2].expr.rep.append((cnt, expr_stack[-1].expr))
expr_stack = expr_stack[:-1]
def handle(
@@ -268,11 +278,13 @@ def gen_c_marshal(versions: set[str], typs: list[idl.UserType]) -> str:
if not member.val:
continue
for tok in member.val.tokens:
- if not isinstance(tok, idl.ExprSym):
- continue
- if tok.symname == "end" or tok.symname.startswith("&"):
- if tok.symname not in offsets:
- offsets.append(tok.symname)
+ match tok:
+ case idl.ExprSym(symname="end"):
+ if tok.symname not in offsets:
+ offsets.append(tok.symname)
+ case idl.ExprOff():
+ if f"&{tok.membname}" not in offsets:
+ offsets.append(f"&{tok.membname}")
for name in offsets:
name_prefix = f"offsetof{''.join('_'+m.membname for m in path.elems)}_"
if name == "end":
@@ -313,15 +325,20 @@ def gen_c_marshal(versions: set[str], typs: list[idl.UserType]) -> str:
)
indent_stack.append(IndentLevel(ifdef=True))
if child.cnt:
- cnt_path = path.parent().add(child.cnt)
+ if isinstance(child.cnt, int):
+ cnt_str = str(child.cnt)
+ cnt_typ = "size_t"
+ else:
+ cnt_str = path.parent().add(child.cnt).c_str("val->")
+ cnt_typ = c9util.typename(child.cnt.typ)
if child.typ.static_size == 1: # SPECIAL (zerocopy)
if path.root.typname == "stat": # SPECIAL (stat)
- ret += f"{'\t'*indent_lvl()}MARSHAL_BYTES(ctx, {path.c_str('val->')[:-3]}, {cnt_path.c_str('val->')});\n"
+ ret += f"{'\t'*indent_lvl()}MARSHAL_BYTES(ctx, {path.c_str('val->')[:-3]}, {cnt_str});\n"
else:
- ret += f"{'\t'*indent_lvl()}MARSHAL_BYTES_ZEROCOPY(ctx, {path.c_str('val->')[:-3]}, {cnt_path.c_str('val->')});\n"
+ ret += f"{'\t'*indent_lvl()}MARSHAL_BYTES_ZEROCOPY(ctx, {path.c_str('val->')[:-3]}, {cnt_str});\n"
return idlutil.WalkCmd.KEEP_GOING, pop
loopvar = chr(ord("i") + loopdepth - 1)
- ret += f"{'\t'*indent_lvl()}for ({c9util.typename(child.cnt.typ)} {loopvar} = 0; {loopvar} < {cnt_path.c_str('val->')}; {loopvar}++) {{\n"
+ ret += f"{'\t'*indent_lvl()}for ({cnt_typ} {loopvar} = 0; {loopvar} < {cnt_str}; {loopvar}++) {{\n"
indent_stack.append(IndentLevel(ifdef=False))
if not isinstance(child.typ, idl.Struct):
if child.val:
diff --git a/lib9p/protogen/c_unmarshal.py b/lib9p/protogen/c_unmarshal.py
index 018d750..34635f9 100644
--- a/lib9p/protogen/c_unmarshal.py
+++ b/lib9p/protogen/c_unmarshal.py
@@ -93,15 +93,20 @@ def gen_c_unmarshal(versions: set[str], typs: list[idl.UserType]) -> str:
)
indent_stack.append(IndentLevel(ifdef=True))
if child.cnt:
- cnt_path = path.parent().add(child.cnt)
+ if isinstance(child.cnt, int):
+ cnt_str = str(child.cnt)
+ cnt_typ = "size_t"
+ else:
+ cnt_str = path.parent().add(child.cnt).c_str("out->")
+ cnt_typ = c9util.typename(child.cnt.typ)
if child.typ.static_size == 1: # SPECIAL (zerocopy)
- ret += f"{'\t'*indent_lvl()}UNMARSHAL_BYTES(ctx, {path.c_str('out->')[:-3]}, {cnt_path.c_str('out->')});\n"
+ ret += f"{'\t'*indent_lvl()}UNMARSHAL_BYTES(ctx, {path.c_str('out->')[:-3]}, {cnt_str});\n"
return idlutil.WalkCmd.KEEP_GOING, pop
ret += f"{'\t'*indent_lvl()}{path.c_str('out->')[:-3]} = extra;\n"
- ret += f"{'\t'*indent_lvl()}extra += sizeof({path.c_str('out->')[:-3]}[0]) * {cnt_path.c_str('out->')};\n"
+ ret += f"{'\t'*indent_lvl()}extra += sizeof({path.c_str('out->')[:-3]}[0]) * {cnt_str};\n"
loopdepth = sum(1 for elem in path.elems if elem.cnt)
loopvar = chr(ord("i") + loopdepth - 1)
- ret += f"{'\t'*indent_lvl()}for ({c9util.typename(child.cnt.typ)} {loopvar} = 0; {loopvar} < {cnt_path.c_str('out->')}; {loopvar}++) {{\n"
+ ret += f"{'\t'*indent_lvl()}for ({cnt_typ} {loopvar} = 0; {loopvar} < {cnt_str}; {loopvar}++) {{\n"
indent_stack.append(IndentLevel(ifdef=False))
if not isinstance(child.typ, idl.Struct):
if child.val:
diff --git a/lib9p/protogen/c_validate.py b/lib9p/protogen/c_validate.py
index e315b60..535a750 100644
--- a/lib9p/protogen/c_validate.py
+++ b/lib9p/protogen/c_validate.py
@@ -24,11 +24,11 @@ def should_save_offset(parent: idl.Struct, child: idl.StructMember) -> bool:
for sibling in parent.members:
if sibling.val:
for tok in sibling.val.tokens:
- if isinstance(tok, idl.ExprSym) and tok.symname == f"&{child.membname}":
+ if isinstance(tok, idl.ExprOff) and tok.membname == child.membname:
return True
if sibling.max:
for tok in sibling.max.tokens:
- if isinstance(tok, idl.ExprSym) and tok.symname == f"&{child.membname}":
+ if isinstance(tok, idl.ExprOff) and tok.membname == child.membname:
return True
return False
@@ -132,21 +132,33 @@ def gen_c_validate(versions: set[str], typs: list[idl.UserType]) -> str:
if should_save_offset(parent, child):
ret += f"{'\t'*indent_lvl()}uint32_t offsetof{''.join('_'+m.membname for m in path.elems)} = net_offset + {incr_buf};\n"
if child.cnt:
- assert child.cnt.typ.static_size
- cnt_path = path.parent().add(child.cnt)
- incr_flush()
+ if isinstance(child.cnt, int):
+ cnt_str = str(child.cnt)
+ cnt_typ = "size_t"
+ else:
+ assert child.cnt.typ.static_size
+ incr_flush()
+ cnt_str = f"LAST_U{child.cnt.typ.static_size*8}LE()"
+ cnt_typ = c9util.typename(child.cnt.typ)
if child.membname == "utf8": # SPECIAL (string)
+ assert child.typ.static_size == 1
# Yes, this is content-validation and "belongs" in
# gen_validate_content(), not here. But it's just
# easier this way.
- ret += f"{'\t'*indent_lvl()}VALIDATE_NET_UTF8(LAST_U{child.cnt.typ.static_size*8}LE());\n"
+ incr_flush()
+ ret += f"{'\t'*indent_lvl()}VALIDATE_NET_UTF8({cnt_str});\n"
return
if child.typ.static_size == 1: # SPECIAL (zerocopy)
- ret += f"{'\t'*indent_lvl()}VALIDATE_NET_BYTES(LAST_U{child.cnt.typ.static_size*8}LE());\n"
+ if isinstance(child.cnt, int):
+ incr_buf += child.cnt
+ return
+ incr_flush()
+ ret += f"{'\t'*indent_lvl()}VALIDATE_NET_BYTES({cnt_str});\n"
return
loopdepth = sum(1 for elem in path.elems if elem.cnt)
loopvar = chr(ord("i") + loopdepth - 1)
- ret += f"{'\t'*indent_lvl()}for ({c9util.typename(child.cnt.typ)} {loopvar} = 0, cnt = LAST_U{child.cnt.typ.static_size*8}LE(); {loopvar} < cnt; {loopvar}++) {{\n"
+ incr_flush()
+ ret += f"{'\t'*indent_lvl()}for ({cnt_typ} {loopvar} = 0, cnt = {cnt_str}; {loopvar} < cnt; {loopvar}++) {{\n"
indent_stack.append(IndentLevel(ifdef=False))
ret += f"{'\t'*indent_lvl()}RESERVE_HOST_BYTES(sizeof({c9util.typename(child.typ)}));\n"
if not isinstance(child.typ, idl.Struct):
diff --git a/lib9p/protogen/h.py b/lib9p/protogen/h.py
index 7785ca1..3b33419 100644
--- a/lib9p/protogen/h.py
+++ b/lib9p/protogen/h.py
@@ -165,6 +165,7 @@ def gen_h(versions: set[str], typs: list[idl.UserType]) -> str:
#include <stdint.h> /* for uint{{n}}_t types */
+#include <libfmt/fmt.h> /* for fmt_formatter */
#include <libhw/generic/net.h> /* for struct iovec */
"""
@@ -206,6 +207,7 @@ enum {c9util.ident('version')} {{
ret += cutil.ifdef_pop(0)
ret += f"\t{c9util.ver_enum('NUM')},\n"
ret += "};\n"
+ ret += f"LO_IMPLEMENTATION_H(fmt_formatter, enum {c9util.ident('version')}, {c9util.ident('version')});\n"
ret += """
/* enum msg_type **************************************************************/
@@ -221,6 +223,7 @@ enum {c9util.ident('version')} {{
ret += f"\t{c9util.Ident(f'TYP_{msg.typname:<{namewidth}}')} = {msg.msgid},\n"
ret += cutil.ifdef_pop(0)
ret += "};\n"
+ ret += f"LO_IMPLEMENTATION_H(fmt_formatter, enum {c9util.ident('msg_type')}, {c9util.ident('msg_type')});\n"
ret += """
/* payload types **************************************************************/
@@ -268,99 +271,11 @@ enum {c9util.ident('version')} {{
match typ:
case idl.Number():
- ret += f"typedef {c9util.typename(typ.prim)} {c9util.typename(typ)};\n"
- prefix = f"{c9util.IDENT(typ.typname)}_"
- namewidth = max(len(name) for name in typ.vals)
- for name, val in typ.vals.items():
- ret += f"#define {prefix}{name:<{namewidth}} (({c9util.typename(typ)})UINT{typ.static_size*8}_C({val}))\n"
+ ret += gen_number(typ)
case idl.Bitfield():
- ret += f"typedef {c9util.typename(typ.prim)} {c9util.typename(typ)};\n"
-
- def bitname(val: idl.Bit | idl.BitAlias) -> str:
- s = val.bitname
- match val:
- case idl.Bit(cat=idl.BitCat.RESERVED):
- s = "_RESERVED_" + s
- case idl.Bit(cat=idl.BitCat.SUBFIELD):
- assert isinstance(typ, idl.Bitfield)
- n = sum(
- 1
- for b in typ.bits[: val.num]
- if b.cat == idl.BitCat.SUBFIELD
- and b.bitname == val.bitname
- )
- s = f"_{s}_{n}"
- case idl.Bit(cat=idl.BitCat.UNUSED):
- return ""
- return c9util.Ident(c9util.add_prefix(typ.typname.upper() + "_", s))
-
- namewidth = max(
- len(bitname(val)) for val in [*typ.bits, *typ.names.values()]
- )
-
- ret += "\n"
- for bit in reversed(typ.bits):
- vers = bit.in_versions
- if bit.cat == idl.BitCat.UNUSED:
- vers = typ.in_versions
- ret += cutil.ifdef_push(2, c9util.ver_ifdef(vers))
-
- # It is important all of the `beg` strings have
- # the same length.
- end = ""
- match bit.cat:
- case (
- idl.BitCat.USED | idl.BitCat.RESERVED | idl.BitCat.SUBFIELD
- ):
- if cutil.ifdef_leaf_is_noop():
- beg = "#define "
- else:
- beg = "# define"
- case idl.BitCat.UNUSED:
- beg = "/* unused"
- end = " */"
-
- c_name = bitname(bit)
- c_val = f"1<<{bit.num}"
- ret += f"{beg} {c_name:<{namewidth}} (({c9util.typename(typ)})({c_val})){end}\n"
- if aliases := [
- alias
- for alias in typ.names.values()
- if isinstance(alias, idl.BitAlias)
- ]:
- ret += "\n"
-
- for alias in aliases:
- ret += cutil.ifdef_push(2, c9util.ver_ifdef(alias.in_versions))
-
- end = ""
- if cutil.ifdef_leaf_is_noop():
- beg = "#define "
- else:
- beg = "# define"
-
- c_name = bitname(alias)
- c_val = alias.val
- ret += f"{beg} {c_name:<{namewidth}} (({c9util.typename(typ)})({c_val})){end}\n"
- ret += cutil.ifdef_pop(1)
- del bitname
+ ret += gen_bitfield(typ)
case idl.Struct(): # and idl.Message():
- ret += c9util.typename(typ) + " {"
- if not typ.members:
- ret += "};\n"
- continue
- ret += "\n"
-
- typewidth = max(len(c9util.typename(m.typ, m)) for m in typ.members)
-
- for member in typ.members:
- if member.val:
- continue
- ret += cutil.ifdef_push(2, c9util.ver_ifdef(member.in_versions))
- ret += f"\t{c9util.typename(member.typ, member):<{typewidth}} {'*' if member.cnt else ' '}{member.membname};\n"
- ret += cutil.ifdef_pop(1)
- ret += "};\n"
- del typ
+ ret += gen_struct(typ)
ret += cutil.ifdef_pop(0)
ret += """
@@ -445,3 +360,176 @@ enum {c9util.ident('version')} {{
ret += "};\n"
return ret
+
+
+def gen_number(typ: idl.Number) -> str:
+ ret = f"typedef {c9util.typename(typ.prim)} {c9util.typename(typ)};\n"
+ ret += f"LO_IMPLEMENTATION_H(fmt_formatter, {c9util.typename(typ)}, {c9util.basename(typ)});\n"
+
+ def lookup_sym(sym: str) -> str:
+ assert False
+
+ def cname(base: str) -> str:
+ prefix = f"{typ.typname}_".upper()
+ return c9util.Ident(c9util.add_prefix(prefix, base))
+
+ namewidth = max(len(cname(name)) for name in typ.vals)
+ for name, val in typ.vals.items():
+ c_name = cname(name)
+ c_val = c9util.idl_expr(val, lookup_sym)
+ ret += f"#define {c_name:<{namewidth}} (({c9util.typename(typ)})({c_val}))\n"
+ return ret
+
+
+def gen_bitfield(typ: idl.Bitfield) -> str:
+ ret = f"typedef {c9util.typename(typ.prim)} {c9util.typename(typ)};\n"
+ ret += f"LO_IMPLEMENTATION_H(fmt_formatter, {c9util.typename(typ)}, {c9util.basename(typ)});\n"
+
+ def lookup_sym(sym: str) -> str:
+ assert False
+
+ # There are 4 parts here: bits, aliases, masks, and numbers.
+
+ # 1. bits
+
+ def bitname(bit: idl.Bit) -> str:
+ prefix = f"{typ.typname}_".upper()
+ base = bit.bitname
+ match bit:
+ case idl.Bit(cat="RESERVED"):
+ base = "_RESERVED_" + base
+ case idl.Bit(cat=idl.BitNum()):
+ base += "_*"
+ case idl.Bit(cat="UNUSED"):
+ base = f"_UNUSED_{bit.num}"
+ return c9util.Ident(c9util.add_prefix(prefix, base))
+
+ namewidth = max(len(bitname(bit)) for bit in typ.bits)
+
+ ret += "/* bits */\n"
+ for bit in reversed(typ.bits):
+ vers = bit.in_versions
+ if bit.cat == "UNUSED":
+ vers = typ.in_versions
+ ret += cutil.ifdef_push(2, c9util.ver_ifdef(vers))
+
+ # It is important all of the `beg` strings have
+ # the same length.
+ end = ""
+ match bit.cat:
+ case "USED" | "RESERVED" | "UNUSED":
+ if cutil.ifdef_leaf_is_noop():
+ beg = "#define "
+ else:
+ beg = "# define"
+ case idl.BitNum():
+ beg = "/* number"
+ end = " */"
+
+ c_name = bitname(bit)
+ c_val = f"UINT{typ.static_size*8}_C(1)<<{bit.num}"
+ ret += (
+ f"{beg} {c_name:<{namewidth}} (({c9util.typename(typ)})({c_val})){end}\n"
+ )
+ ret += cutil.ifdef_pop(1)
+
+ # 2. aliases
+ if typ.aliases:
+
+ def aliasname(alias: idl.BitAlias) -> str:
+ prefix = f"{typ.typname}_".upper()
+ base = alias.bitname
+ return c9util.Ident(c9util.add_prefix(prefix, base))
+
+ ret += "/* aliases */\n"
+ for alias in typ.aliases.values():
+ ret += cutil.ifdef_push(2, c9util.ver_ifdef(alias.in_versions))
+
+ end = ""
+ if cutil.ifdef_leaf_is_noop():
+ beg = "#define "
+ else:
+ beg = "# define"
+
+ c_name = aliasname(alias)
+ c_val = c9util.idl_expr(alias.val, lookup_sym)
+ ret += f"{beg} {c_name:<{namewidth}} (({c9util.typename(typ)})({c_val})){end}\n"
+
+ ret += cutil.ifdef_pop(1)
+
+ # 3. masks
+ if typ.masks:
+
+ def maskname(mask: idl.BitAlias) -> str:
+ prefix = f"{typ.typname}_".upper()
+ base = mask.bitname
+ return c9util.Ident(c9util.add_prefix(prefix, base) + "_MASK")
+
+ ret += "/* masks */\n"
+ for mask in typ.masks.values():
+ ret += cutil.ifdef_push(2, c9util.ver_ifdef(mask.in_versions))
+
+ end = ""
+ if cutil.ifdef_leaf_is_noop():
+ beg = "#define "
+ else:
+ beg = "# define"
+
+ c_name = maskname(mask)
+ c_val = c9util.idl_expr(mask.val, lookup_sym, bitwidth=typ.static_size * 8)
+ ret += f"{beg} {c_name:<{namewidth}} (({c9util.typename(typ)})({c_val})){end}\n"
+
+ ret += cutil.ifdef_pop(1)
+
+ # 4. numbers
+ def numname(num: idl.BitNum, base: str) -> str:
+ prefix = f"{typ.typname}_{num.numname}_".upper()
+ return c9util.Ident(c9util.add_prefix(prefix, base))
+
+ for num in typ.nums.values():
+ namewidth = max(
+ len(numname(num, base))
+ for base in [
+ *[alias.bitname for alias in num.vals.values()],
+ "MASK",
+ ]
+ )
+ ret += f"/* number: {num.numname} */\n"
+ for alias in num.vals.values():
+ ret += cutil.ifdef_push(2, c9util.ver_ifdef(alias.in_versions))
+
+ end = ""
+ if cutil.ifdef_leaf_is_noop():
+ beg = "#define "
+ else:
+ beg = "# define"
+
+ c_name = numname(num, alias.bitname)
+ c_val = c9util.idl_expr(alias.val, lookup_sym)
+ ret += f"{beg} {c_name:<{namewidth}} (({c9util.typename(typ)})({c_val})){end}\n"
+ ret += cutil.ifdef_pop(1)
+ c_name = numname(num, "MASK")
+ c_val = f"{num.mask:#0{typ.static_size*8}b}"
+ ret += (
+ f"{beg} {c_name:<{namewidth}} (({c9util.typename(typ)})({c_val})){end}\n"
+ )
+
+ return ret
+
+
+def gen_struct(typ: idl.Struct) -> str: # and idl.Message
+ ret = c9util.typename(typ) + " {"
+ if typ.members:
+ ret += "\n"
+
+ typewidth = max(len(c9util.typename(m.typ, m)) for m in typ.members)
+
+ for member in typ.members:
+ if member.val:
+ continue
+ ret += cutil.ifdef_push(2, c9util.ver_ifdef(member.in_versions))
+ ret += f"\t{c9util.typename(member.typ, member):<{typewidth}} {'*' if member.cnt else ' '}{member.membname};\n"
+ ret += cutil.ifdef_pop(1)
+ ret += "};\n"
+ ret += f"LO_IMPLEMENTATION_H(fmt_formatter, {c9util.typename(typ)}, {c9util.basename(typ)});\n"
+ return ret
diff --git a/lib9p/srv.c b/lib9p/srv.c
index 50d0b78..bfeb06f 100644
--- a/lib9p/srv.c
+++ b/lib9p/srv.c
@@ -6,12 +6,18 @@
#include <alloca.h>
#include <inttypes.h> /* for PRI* */
+#include <stddef.h> /* for size_t */
+#include <limits.h> /* for SSIZE_MAX, not set by newlib */
+#ifndef SSIZE_MAX
+#define SSIZE_MAX (SIZE_MAX >> 1)
+#endif
#include <libcr/coroutine.h>
#include <libcr_ipc/chan.h>
#include <libcr_ipc/mutex.h>
#include <libcr_ipc/select.h>
#include <libmisc/assert.h>
+#include <libmisc/endian.h>
#include <libhw/generic/net.h>
#define LOG_NAME 9P_SRV
@@ -20,7 +26,9 @@
#define IMPLEMENTATION_FOR_LIB9P_SRV_H YES
#include <lib9p/srv.h>
-#include "internal.h"
+/* config *********************************************************************/
+
+#include "config.h"
#ifndef CONFIG_9P_SRV_MAX_FIDS
#error config.h must define CONFIG_9P_SRV_MAX_FIDS
@@ -32,6 +40,14 @@
/* 1=just the root dir, 2=just files in the root dir, 3=1 subdir, ... */
#error config.h must define CONFIG_9P_SRV_MAX_DEPTH
#endif
+#ifndef CONFIG_9P_SRV_MAX_MSG_SIZE
+ #error config.h must define CONFIG_9P_SRV_MAX_MSG_SIZE
+#endif
+#ifndef CONFIG_9P_SRV_MAX_HOSTMSG_SIZE
+ #error config.h must define CONFIG_9P_SRV_MAX_HOSTMSG_SIZE
+#endif
+static_assert(CONFIG_9P_SRV_MAX_MSG_SIZE <= CONFIG_9P_SRV_MAX_HOSTMSG_SIZE);
+static_assert(CONFIG_9P_SRV_MAX_HOSTMSG_SIZE <= SSIZE_MAX);
/* context ********************************************************************/
@@ -183,6 +199,7 @@ static void respond_error(struct _lib9p_srv_req *req) {
LIB9P_TYP_Rerror, &host,
&net);
+ infof("< %v", lo_box_lib9p_msg_Rerror_as_fmt_formatter(&host));
r = write_Rmsg(req, &net);
if (r < 0)
nonrespond_errorf("write: %s", net_strerror(-r));
@@ -218,7 +235,7 @@ static void handle_message(struct _lib9p_srv_req *ctx);
srv->readers++;
- uint32_t initial_rerror_overhead = _lib9p_table_msg_min_size[LIB9P_VER_unknown];
+ uint32_t initial_rerror_overhead = lib9p_version_min_msg_size(LIB9P_VER_unknown);
for (;;) {
struct _srv_conn conn = {
@@ -238,7 +255,7 @@ static void handle_message(struct _lib9p_srv_req *ctx);
struct _srv_sess sess = {
.parent_conn = &conn,
.version = LIB9P_VER_unknown,
- .max_msg_size = CONFIG_9P_MAX_MSG_SIZE,
+ .max_msg_size = CONFIG_9P_SRV_MAX_MSG_SIZE,
.rerror_overhead = initial_rerror_overhead,
.initialized = false,
};
@@ -397,17 +414,18 @@ static tmessage_handler tmessage_handlers[0x100] = {
static void handle_message(struct _lib9p_srv_req *ctx) {
uint8_t *host_req = NULL;
- uint8_t host_resp[CONFIG_9P_MAX_HOSTMSG_SIZE];
+ uint8_t host_resp[CONFIG_9P_SRV_MAX_HOSTMSG_SIZE];
/* Unmarshal it. */
ssize_t host_size = lib9p_Tmsg_validate(&ctx->ctx.basectx, ctx->net_bytes);
if (host_size < 0)
goto write;
- host_req = malloc(host_size);
+ host_req = calloc(1, host_size);
assert(host_req);
enum lib9p_msg_type typ;
lib9p_Tmsg_unmarshal(&ctx->ctx.basectx, ctx->net_bytes,
&typ, host_req);
+ infof("> %v", lo_box_lib9p_msg_as_fmt_formatter(&ctx->ctx.basectx, typ, host_req));
/* Handle it. */
tmessage_handlers[typ](ctx, (void *)host_req, (void *)host_resp);
@@ -421,6 +439,7 @@ static void handle_message(struct _lib9p_srv_req *ctx) {
typ+1, host_resp,
&net_resp))
goto write;
+ infof("< %v", lo_box_lib9p_msg_as_fmt_formatter(&ctx->ctx.basectx, typ+1, &host_resp));
write_Rmsg(ctx, &net_resp);
}
if (host_req)
@@ -573,7 +592,7 @@ static void handle_Tversion(struct _lib9p_srv_req *ctx,
#endif
}
- uint32_t min_msg_size = _lib9p_table_msg_min_size[version];
+ uint32_t min_msg_size = lib9p_version_min_msg_size(version);
if (req->max_msg_size < min_msg_size) {
lib9p_errorf(&ctx->ctx.basectx,
LINUX_EDOM, "requested max_msg_size is less than minimum for %s (%"PRIu32" < %"PRIu32")",
@@ -582,8 +601,8 @@ static void handle_Tversion(struct _lib9p_srv_req *ctx,
}
resp->version = lib9p_str((char *)lib9p_version_str(version)); /* cast to discard "const" qualifier */
- resp->max_msg_size = (CONFIG_9P_MAX_MSG_SIZE < req->max_msg_size)
- ? CONFIG_9P_MAX_MSG_SIZE
+ resp->max_msg_size = (CONFIG_9P_SRV_MAX_MSG_SIZE < req->max_msg_size)
+ ? CONFIG_9P_SRV_MAX_MSG_SIZE
: req->max_msg_size;
/* Close the old session. */
@@ -822,7 +841,7 @@ static void handle_Topen(struct _lib9p_srv_req *ctx,
struct srv_pathinfo *pathinfo = pathmap_load(&ctx->parent_sess->paths, fidinfo->path);
assert(pathinfo);
if (srv_util_pathisdir(pathinfo)) {
- if ( ((req->mode & LIB9P_O_MODE_MASK) != LIB9P_O_READ) ||
+ if ( ((req->mode & LIB9P_O_MODE_MASK) != LIB9P_O_MODE_READ) ||
(req->mode & LIB9P_O_TRUNC) ||
(req->mode & LIB9P_O_RCLOSE) ) {
lib9p_error(&ctx->ctx.basectx,
@@ -864,19 +883,19 @@ static void handle_Topen(struct _lib9p_srv_req *ctx,
uint8_t perm_bits = 0;
bool rd = false, wr = false;
switch (reqmode & LIB9P_O_MODE_MASK) {
- case LIB9P_O_READ:
+ case LIB9P_O_MODE_READ:
perm_bits = 0b100;
rd = true;
break;
- case LIB9P_O_WRITE:
+ case LIB9P_O_MODE_WRITE:
perm_bits = 0b010;
wr = true;
break;
- case LIB9P_O_RDWR:
+ case LIB9P_O_MODE_RDWR:
perm_bits = 0b110;
rd = wr = true;
break;
- case LIB9P_O_EXEC:
+ case LIB9P_O_MODE_EXEC:
perm_bits = 0b001;
rd = true;
break;
diff --git a/lib9p/tables.c b/lib9p/tables.c
new file mode 100644
index 0000000..271b17b
--- /dev/null
+++ b/lib9p/tables.c
@@ -0,0 +1,186 @@
+/* lib9p/tables.c - Access tables of version and message information
+ *
+ * Copyright (C) 2024-2025 Luke T. Shumaker <lukeshu@lukeshu.com>
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+
+#include <string.h>
+
+#include <libmisc/endian.h>
+#include <libmisc/log.h> /* for const_byte_str() */
+
+#include "tables.h"
+
+/* bounds checks **************************************************************/
+
+static inline void assert_ver(enum lib9p_version ver) {
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wtype-limits"
+ assert(0 <= ver && ver < LIB9P_VER_NUM);
+#pragma GCC diagnostic pop
+}
+
+static inline void assert_typ(enum lib9p_msg_type typ) {
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wtype-limits"
+ assert(0 <= typ && typ < 0xFF);
+#pragma GCC diagnostic pop
+}
+
+/* simple lookups *************************************************************/
+
+const char *lib9p_version_str(enum lib9p_version ver) {
+ assert_ver(ver);
+ return _lib9p_table_ver[ver].name;
+}
+
+uint32_t lib9p_version_min_msg_size(enum lib9p_version ver) {
+ assert_ver(ver);
+ return _lib9p_table_ver[ver].min_msg_size;
+}
+
+const char *lib9p_msgtype_str(enum lib9p_version ver, enum lib9p_msg_type typ) {
+ assert_ver(ver);
+ assert_typ(typ);
+ return _lib9p_table_msg[ver][typ].name ?: const_byte_str(typ);
+}
+
+lo_interface fmt_formatter lo_box_lib9p_msg_as_fmt_formatter(struct lib9p_ctx *ctx, enum lib9p_msg_type typ, void *body) {
+ assert(ctx);
+ assert_ver(ctx->version);
+ assert_typ(typ);
+ assert(_lib9p_table_msg[ctx->version][typ].box_as_fmt_formatter);
+ return _lib9p_table_msg[ctx->version][typ].box_as_fmt_formatter(body);
+}
+
+/* main message functions *****************************************************/
+
+static
+ssize_t _lib9p_validate(uint8_t xxx_low_typ_bit,
+ const char *xxx_errmsg,
+ const struct _lib9p_recv_tentry xxx_table[LIB9P_VER_NUM][0x80],
+ struct lib9p_ctx *ctx, uint8_t *net_bytes) {
+ assert_ver(ctx->version);
+ /* Inspect the first 5 bytes ourselves. */
+ uint32_t net_size = uint32le_decode(net_bytes);
+ if (net_size < 5)
+ return lib9p_error(ctx, LINUX_EBADMSG, "message is impossibly short");
+ uint8_t typ = net_bytes[4];
+ if (typ % 2 != xxx_low_typ_bit)
+ return lib9p_errorf(ctx, LINUX_EOPNOTSUPP, "%s: message_type=%s", xxx_errmsg,
+ lib9p_msgtype_str(ctx->version, typ));
+ struct _lib9p_recv_tentry tentry = xxx_table[ctx->version][typ/2];
+ if (!tentry.validate)
+ return lib9p_errorf(ctx, LINUX_EOPNOTSUPP, "unknown message type: %s (protocol_version=%s)",
+ lib9p_msgtype_str(ctx->version, typ), lib9p_version_str(ctx->version));
+
+ /* Now use the message-type-specific tentry to process the whole thing. */
+ return tentry.validate(ctx, net_size, net_bytes);
+}
+
+ssize_t lib9p_Tmsg_validate(struct lib9p_ctx *ctx, uint8_t *net_bytes) {
+ return _lib9p_validate(0, "expected a T-message but got an R-message", _lib9p_table_Tmsg_recv,
+ ctx, net_bytes);
+}
+
+ssize_t lib9p_Rmsg_validate(struct lib9p_ctx *ctx, uint8_t *net_bytes) {
+ return _lib9p_validate(1, "expected an R-message but got a T-message", _lib9p_table_Rmsg_recv,
+ ctx, net_bytes);
+}
+
+static
+void _lib9p_unmarshal(const struct _lib9p_recv_tentry xxx_table[LIB9P_VER_NUM][0x80],
+ struct lib9p_ctx *ctx, uint8_t *net_bytes,
+ enum lib9p_msg_type *ret_typ, void *ret_body) {
+ assert_ver(ctx->version);
+ enum lib9p_msg_type typ = net_bytes[4];
+ *ret_typ = typ;
+ struct _lib9p_recv_tentry tentry = xxx_table[ctx->version][typ/2];
+
+ tentry.unmarshal(ctx, net_bytes, ret_body);
+}
+
+void lib9p_Tmsg_unmarshal(struct lib9p_ctx *ctx, uint8_t *net_bytes,
+ enum lib9p_msg_type *ret_typ, void *ret_body) {
+ _lib9p_unmarshal(_lib9p_table_Tmsg_recv,
+ ctx, net_bytes, ret_typ, ret_body);
+}
+
+void lib9p_Rmsg_unmarshal(struct lib9p_ctx *ctx, uint8_t *net_bytes,
+ enum lib9p_msg_type *ret_typ, void *ret_body) {
+ _lib9p_unmarshal(_lib9p_table_Rmsg_recv,
+ ctx, net_bytes, ret_typ, ret_body);
+}
+
+static
+bool _lib9p_marshal(const struct _lib9p_send_tentry xxx_table[LIB9P_VER_NUM][0x80],
+ struct lib9p_ctx *ctx, enum lib9p_msg_type typ, void *body,
+ size_t *ret_iov_cnt, struct iovec *ret_iov, uint8_t *ret_copied) {
+ assert_ver(ctx->version);
+ assert_typ(typ);
+ struct _marshal_ret ret = {
+ .net_iov_cnt = 1,
+ .net_iov = ret_iov,
+ .net_copied_size = 0,
+ .net_copied = ret_copied,
+ };
+
+ struct _lib9p_send_tentry tentry = xxx_table[ctx->version][typ/2];
+ bool ret_erred = tentry.marshal(ctx, body, &ret);
+ if (ret_iov[ret.net_iov_cnt-1].iov_len == 0)
+ ret.net_iov_cnt--;
+ *ret_iov_cnt = ret.net_iov_cnt;
+ return ret_erred;
+}
+
+bool lib9p_Tmsg_marshal(struct lib9p_ctx *ctx, enum lib9p_msg_type typ, void *body,
+ struct lib9p_Tmsg_send_buf *ret) {
+ assert(typ % 2 == 0);
+ memset(ret, 0, sizeof(*ret));
+ return _lib9p_marshal(_lib9p_table_Tmsg_send,
+ ctx, typ, body,
+ &ret->iov_cnt, ret->iov, ret->copied);
+}
+
+bool lib9p_Rmsg_marshal(struct lib9p_ctx *ctx, enum lib9p_msg_type typ, void *body,
+ struct lib9p_Rmsg_send_buf *ret) {
+ assert(typ % 2 == 1);
+ memset(ret, 0, sizeof(*ret));
+ return _lib9p_marshal(_lib9p_table_Rmsg_send,
+ ctx, typ, body,
+ &ret->iov_cnt, ret->iov, ret->copied);
+}
+
+/* `struct lib9p_stat` helpers ************************************************/
+
+bool lib9p_stat_validate(struct lib9p_ctx *ctx, uint32_t net_size, uint8_t *net_bytes,
+ uint32_t *ret_net_size, ssize_t *ret_host_size) {
+ ssize_t host_size = _lib9p_stat_validate(ctx, net_size, net_bytes, ret_net_size);
+ if (host_size < 0)
+ return true;
+ if (ret_host_size)
+ *ret_host_size = host_size;
+ return false;
+}
+
+void lib9p_stat_unmarshal(struct lib9p_ctx *ctx, uint8_t *net_bytes,
+ struct lib9p_stat *ret) {
+ _lib9p_stat_unmarshal(ctx, net_bytes, ret);
+}
+
+uint32_t lib9p_stat_marshal(struct lib9p_ctx *ctx, uint32_t max_net_size, struct lib9p_stat *obj,
+ uint8_t *ret_bytes) {
+ struct lib9p_ctx _ctx = *ctx;
+ _ctx.max_msg_size = max_net_size;
+
+ struct iovec iov = {0};
+ struct _marshal_ret ret = {
+ .net_iov_cnt = 1,
+ .net_iov = &iov,
+ .net_copied_size = 0,
+ .net_copied = ret_bytes,
+ };
+ if (_lib9p_stat_marshal(&_ctx, obj, &ret))
+ return 0;
+ return ret.net_iov[0].iov_len;
+}
diff --git a/lib9p/tables.h b/lib9p/tables.h
new file mode 100644
index 0000000..edb402a
--- /dev/null
+++ b/lib9p/tables.h
@@ -0,0 +1,59 @@
+/* lib9p/tables.h - Declare tables of version and message information
+ *
+ * Copyright (C) 2024-2025 Luke T. Shumaker <lukeshu@lukeshu.com>
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+
+#ifndef _LIB9P_TABLES_H_
+#define _LIB9P_TABLES_H_
+
+#include <lib9p/9p.h>
+
+/* version ********************************************************************/
+
+struct _lib9p_ver_tentry {
+ const char *name;
+ uint32_t min_msg_size;
+};
+
+extern const struct _lib9p_ver_tentry _lib9p_table_ver[LIB9P_VER_NUM];
+
+/* message ********************************************************************/
+
+typedef lo_interface fmt_formatter (*_box_as_fmt_formatter_fn_t)(void *host_val);
+struct _lib9p_msg_tentry {
+ const char *name;
+ _box_as_fmt_formatter_fn_t box_as_fmt_formatter;
+};
+
+typedef ssize_t (*_validate_fn_t)(struct lib9p_ctx *ctx, uint32_t net_size, uint8_t *net_bytes);
+typedef void (*_unmarshal_fn_t)(struct lib9p_ctx *ctx, uint8_t *net_bytes, void *out);
+struct _lib9p_recv_tentry {
+ _validate_fn_t validate;
+ _unmarshal_fn_t unmarshal;
+};
+
+struct _marshal_ret {
+ size_t net_iov_cnt;
+ struct iovec *net_iov;
+ size_t net_copied_size;
+ uint8_t *net_copied;
+};
+typedef bool (*_marshal_fn_t)(struct lib9p_ctx *ctx, void *host_val, struct _marshal_ret *ret);
+struct _lib9p_send_tentry {
+ _marshal_fn_t marshal;
+};
+
+extern const struct _lib9p_msg_tentry _lib9p_table_msg[LIB9P_VER_NUM][0x100];
+extern const struct _lib9p_recv_tentry _lib9p_table_Tmsg_recv[LIB9P_VER_NUM][0x80];
+extern const struct _lib9p_recv_tentry _lib9p_table_Rmsg_recv[LIB9P_VER_NUM][0x80];
+extern const struct _lib9p_send_tentry _lib9p_table_Tmsg_send[LIB9P_VER_NUM][0x80];
+extern const struct _lib9p_send_tentry _lib9p_table_Rmsg_send[LIB9P_VER_NUM][0x80];
+
+/* stat ***********************************************************************/
+
+ssize_t _lib9p_stat_validate(struct lib9p_ctx *ctx, uint32_t net_size, uint8_t *net_bytes, uint32_t *ret_net_size);
+void _lib9p_stat_unmarshal(struct lib9p_ctx *ctx, uint8_t *net_bytes, void *out);
+bool _lib9p_stat_marshal(struct lib9p_ctx *ctx, struct lib9p_stat *val, struct _marshal_ret *ret);
+
+#endif /* _LIB9P_TABLES_H_ */
diff --git a/lib9p/tests/test_compile.c b/lib9p/tests/test_compile.c
index 6abee05..8f2445d 100644
--- a/lib9p/tests/test_compile.c
+++ b/lib9p/tests/test_compile.c
@@ -8,14 +8,26 @@ int main(void) {
x = LIB9P_DM_DIR;
x = LIB9P_DM_APPEND;
x = LIB9P_DM_EXCL;
- x = _LIB9P_DM_RESERVED_PLAN9_MOUNT;
+ x = _LIB9P_DM_PLAN9_MOUNT;
x = LIB9P_DM_AUTH;
x = LIB9P_DM_TMP;
+ x = _LIB9P_DM_UNUSED_25;
+ x = _LIB9P_DM_UNUSED_24;
x = LIB9P_DM_DEVICE;
- x = LIB9P_DM_NAMEDPIPE;
+ x = _LIB9P_DM_UNUSED_22;
+ x = LIB9P_DM_PIPE;
x = LIB9P_DM_SOCKET;
x = LIB9P_DM_SETUID;
x = LIB9P_DM_SETGID;
+ x = _LIB9P_DM_UNUSED_17;
+ x = _LIB9P_DM_UNUSED_16;
+ x = _LIB9P_DM_UNUSED_15;
+ x = _LIB9P_DM_UNUSED_14;
+ x = _LIB9P_DM_UNUSED_13;
+ x = _LIB9P_DM_UNUSED_12;
+ x = _LIB9P_DM_UNUSED_11;
+ x = _LIB9P_DM_UNUSED_10;
+ x = _LIB9P_DM_UNUSED_9;
x = LIB9P_DM_OWNER_R;
x = LIB9P_DM_OWNER_W;
x = LIB9P_DM_OWNER_X;
@@ -29,25 +41,38 @@ int main(void) {
x = LIB9P_QT_DIR;
x = LIB9P_QT_APPEND;
x = LIB9P_QT_EXCL;
- x = _LIB9P_QT_RESERVED_PLAN9_MOUNT;
+ x = _LIB9P_QT_PLAN9_MOUNT;
x = LIB9P_QT_AUTH;
x = LIB9P_QT_TMP;
x = LIB9P_QT_SYMLINK;
+ x = _LIB9P_QT_UNUSED_0;
x = LIB9P_QT_FILE;
x = LIB9P_NUID_NONUID;
+ x = _LIB9P_O_UNUSED_7;
x = LIB9P_O_RCLOSE;
x = _LIB9P_O_RESERVED_CEXEC;
x = LIB9P_O_TRUNC;
- x = _LIB9P_O_mode_1;
- x = _LIB9P_O_mode_0;
- x = LIB9P_O_READ;
- x = LIB9P_O_WRITE;
- x = LIB9P_O_RDWR;
- x = LIB9P_O_EXEC;
- x = LIB9P_O_MODE_MASK;
+ x = _LIB9P_O_UNUSED_3;
+ x = _LIB9P_O_UNUSED_2;
x = LIB9P_O_FLAG_MASK;
+ x = LIB9P_O_MODE_READ;
+ x = LIB9P_O_MODE_WRITE;
+ x = LIB9P_O_MODE_RDWR;
+ x = LIB9P_O_MODE_EXEC;
+ x = LIB9P_O_MODE_MASK;
x = LIB9P_ERRNO_NOERROR;
x = LIB9P_SUPER_MAGIC_V9FS_MAGIC;
+ x = _LIB9P_LO_UNUSED_31;
+ x = _LIB9P_LO_UNUSED_30;
+ x = _LIB9P_LO_UNUSED_29;
+ x = _LIB9P_LO_UNUSED_28;
+ x = _LIB9P_LO_UNUSED_27;
+ x = _LIB9P_LO_UNUSED_26;
+ x = _LIB9P_LO_UNUSED_25;
+ x = _LIB9P_LO_UNUSED_24;
+ x = _LIB9P_LO_UNUSED_23;
+ x = _LIB9P_LO_UNUSED_22;
+ x = _LIB9P_LO_UNUSED_21;
x = LIB9P_LO_SYNC;
x = LIB9P_LO_CLOEXEC;
x = LIB9P_LO_NOATIME;
@@ -63,27 +88,41 @@ int main(void) {
x = LIB9P_LO_NOCTTY;
x = LIB9P_LO_EXCL;
x = LIB9P_LO_CREATE;
- x = _LIB9P_LO_mode_1;
- x = _LIB9P_LO_mode_0;
- x = LIB9P_LO_RDONLY;
- x = LIB9P_LO_WRONLY;
- x = LIB9P_LO_RDWR;
- x = LIB9P_LO_NOACCESS;
- x = LIB9P_LO_MODE_MASK;
+ x = _LIB9P_LO_UNUSED_5;
+ x = _LIB9P_LO_UNUSED_4;
+ x = _LIB9P_LO_UNUSED_3;
+ x = _LIB9P_LO_UNUSED_2;
x = LIB9P_LO_FLAG_MASK;
+ x = LIB9P_LO_MODE_RDONLY;
+ x = LIB9P_LO_MODE_WRONLY;
+ x = LIB9P_LO_MODE_RDWR;
+ x = LIB9P_LO_MODE_NOACCESS;
+ x = LIB9P_LO_MODE_MASK;
x = LIB9P_DT_UNKNOWN;
- x = LIB9P_DT_NAMED_PIPE;
+ x = LIB9P_DT_PIPE;
x = LIB9P_DT_CHAR_DEV;
x = LIB9P_DT_DIRECTORY;
x = LIB9P_DT_BLOCK_DEV;
x = LIB9P_DT_REGULAR;
x = LIB9P_DT_SYMLINK;
x = LIB9P_DT_SOCKET;
- x = LIB9P_DT_WHITEOUT;
- x = _LIB9P_MODE_fmt_3;
- x = _LIB9P_MODE_fmt_2;
- x = _LIB9P_MODE_fmt_1;
- x = _LIB9P_MODE_fmt_0;
+ x = _LIB9P_DT_WHITEOUT;
+ x = _LIB9P_MODE_UNUSED_31;
+ x = _LIB9P_MODE_UNUSED_30;
+ x = _LIB9P_MODE_UNUSED_29;
+ x = _LIB9P_MODE_UNUSED_28;
+ x = _LIB9P_MODE_UNUSED_27;
+ x = _LIB9P_MODE_UNUSED_26;
+ x = _LIB9P_MODE_UNUSED_25;
+ x = _LIB9P_MODE_UNUSED_24;
+ x = _LIB9P_MODE_UNUSED_23;
+ x = _LIB9P_MODE_UNUSED_22;
+ x = _LIB9P_MODE_UNUSED_21;
+ x = _LIB9P_MODE_UNUSED_20;
+ x = _LIB9P_MODE_UNUSED_19;
+ x = _LIB9P_MODE_UNUSED_18;
+ x = _LIB9P_MODE_UNUSED_17;
+ x = _LIB9P_MODE_UNUSED_16;
x = LIB9P_MODE_PERM_SETGROUP;
x = LIB9P_MODE_PERM_SETUSER;
x = LIB9P_MODE_PERM_STICKY;
@@ -96,17 +135,67 @@ int main(void) {
x = LIB9P_MODE_PERM_OTHER_R;
x = LIB9P_MODE_PERM_OTHER_W;
x = LIB9P_MODE_PERM_OTHER_X;
- x = LIB9P_MODE_FMT_NAMED_PIPE;
+ x = LIB9P_MODE_PERM_MASK;
+ x = LIB9P_MODE_FMT_PIPE;
x = LIB9P_MODE_FMT_CHAR_DEV;
x = LIB9P_MODE_FMT_DIRECTORY;
x = LIB9P_MODE_FMT_BLOCK_DEV;
x = LIB9P_MODE_FMT_REGULAR;
x = LIB9P_MODE_FMT_SYMLINK;
x = LIB9P_MODE_FMT_SOCKET;
- x = LIB9P_MODE_PERM_MASK;
x = LIB9P_MODE_FMT_MASK;
x = LIB9P_B4_FALSE;
x = LIB9P_B4_TRUE;
+ x = _LIB9P_GETATTR_UNUSED_63;
+ x = _LIB9P_GETATTR_UNUSED_62;
+ x = _LIB9P_GETATTR_UNUSED_61;
+ x = _LIB9P_GETATTR_UNUSED_60;
+ x = _LIB9P_GETATTR_UNUSED_59;
+ x = _LIB9P_GETATTR_UNUSED_58;
+ x = _LIB9P_GETATTR_UNUSED_57;
+ x = _LIB9P_GETATTR_UNUSED_56;
+ x = _LIB9P_GETATTR_UNUSED_55;
+ x = _LIB9P_GETATTR_UNUSED_54;
+ x = _LIB9P_GETATTR_UNUSED_53;
+ x = _LIB9P_GETATTR_UNUSED_52;
+ x = _LIB9P_GETATTR_UNUSED_51;
+ x = _LIB9P_GETATTR_UNUSED_50;
+ x = _LIB9P_GETATTR_UNUSED_49;
+ x = _LIB9P_GETATTR_UNUSED_48;
+ x = _LIB9P_GETATTR_UNUSED_47;
+ x = _LIB9P_GETATTR_UNUSED_46;
+ x = _LIB9P_GETATTR_UNUSED_45;
+ x = _LIB9P_GETATTR_UNUSED_44;
+ x = _LIB9P_GETATTR_UNUSED_43;
+ x = _LIB9P_GETATTR_UNUSED_42;
+ x = _LIB9P_GETATTR_UNUSED_41;
+ x = _LIB9P_GETATTR_UNUSED_40;
+ x = _LIB9P_GETATTR_UNUSED_39;
+ x = _LIB9P_GETATTR_UNUSED_38;
+ x = _LIB9P_GETATTR_UNUSED_37;
+ x = _LIB9P_GETATTR_UNUSED_36;
+ x = _LIB9P_GETATTR_UNUSED_35;
+ x = _LIB9P_GETATTR_UNUSED_34;
+ x = _LIB9P_GETATTR_UNUSED_33;
+ x = _LIB9P_GETATTR_UNUSED_32;
+ x = _LIB9P_GETATTR_UNUSED_31;
+ x = _LIB9P_GETATTR_UNUSED_30;
+ x = _LIB9P_GETATTR_UNUSED_29;
+ x = _LIB9P_GETATTR_UNUSED_28;
+ x = _LIB9P_GETATTR_UNUSED_27;
+ x = _LIB9P_GETATTR_UNUSED_26;
+ x = _LIB9P_GETATTR_UNUSED_25;
+ x = _LIB9P_GETATTR_UNUSED_24;
+ x = _LIB9P_GETATTR_UNUSED_23;
+ x = _LIB9P_GETATTR_UNUSED_22;
+ x = _LIB9P_GETATTR_UNUSED_21;
+ x = _LIB9P_GETATTR_UNUSED_20;
+ x = _LIB9P_GETATTR_UNUSED_19;
+ x = _LIB9P_GETATTR_UNUSED_18;
+ x = _LIB9P_GETATTR_UNUSED_17;
+ x = _LIB9P_GETATTR_UNUSED_16;
+ x = _LIB9P_GETATTR_UNUSED_15;
+ x = _LIB9P_GETATTR_UNUSED_14;
x = LIB9P_GETATTR_DATA_VERSION;
x = LIB9P_GETATTR_GEN;
x = LIB9P_GETATTR_BTIME;
@@ -123,6 +212,29 @@ int main(void) {
x = LIB9P_GETATTR_MODE;
x = LIB9P_GETATTR_BASIC;
x = LIB9P_GETATTR_ALL;
+ x = _LIB9P_SETATTR_UNUSED_31;
+ x = _LIB9P_SETATTR_UNUSED_30;
+ x = _LIB9P_SETATTR_UNUSED_29;
+ x = _LIB9P_SETATTR_UNUSED_28;
+ x = _LIB9P_SETATTR_UNUSED_27;
+ x = _LIB9P_SETATTR_UNUSED_26;
+ x = _LIB9P_SETATTR_UNUSED_25;
+ x = _LIB9P_SETATTR_UNUSED_24;
+ x = _LIB9P_SETATTR_UNUSED_23;
+ x = _LIB9P_SETATTR_UNUSED_22;
+ x = _LIB9P_SETATTR_UNUSED_21;
+ x = _LIB9P_SETATTR_UNUSED_20;
+ x = _LIB9P_SETATTR_UNUSED_19;
+ x = _LIB9P_SETATTR_UNUSED_18;
+ x = _LIB9P_SETATTR_UNUSED_17;
+ x = _LIB9P_SETATTR_UNUSED_16;
+ x = _LIB9P_SETATTR_UNUSED_15;
+ x = _LIB9P_SETATTR_UNUSED_14;
+ x = _LIB9P_SETATTR_UNUSED_13;
+ x = _LIB9P_SETATTR_UNUSED_12;
+ x = _LIB9P_SETATTR_UNUSED_11;
+ x = _LIB9P_SETATTR_UNUSED_10;
+ x = _LIB9P_SETATTR_UNUSED_9;
x = LIB9P_SETATTR_MTIME_SET;
x = LIB9P_SETATTR_ATIME_SET;
x = LIB9P_SETATTR_CTIME;
@@ -135,6 +247,36 @@ int main(void) {
x = LIB9P_LOCK_TYPE_RDLCK;
x = LIB9P_LOCK_TYPE_WRLCK;
x = LIB9P_LOCK_TYPE_UNLCK;
+ x = _LIB9P_LOCK_FLAGS_UNUSED_31;
+ x = _LIB9P_LOCK_FLAGS_UNUSED_30;
+ x = _LIB9P_LOCK_FLAGS_UNUSED_29;
+ x = _LIB9P_LOCK_FLAGS_UNUSED_28;
+ x = _LIB9P_LOCK_FLAGS_UNUSED_27;
+ x = _LIB9P_LOCK_FLAGS_UNUSED_26;
+ x = _LIB9P_LOCK_FLAGS_UNUSED_25;
+ x = _LIB9P_LOCK_FLAGS_UNUSED_24;
+ x = _LIB9P_LOCK_FLAGS_UNUSED_23;
+ x = _LIB9P_LOCK_FLAGS_UNUSED_22;
+ x = _LIB9P_LOCK_FLAGS_UNUSED_21;
+ x = _LIB9P_LOCK_FLAGS_UNUSED_20;
+ x = _LIB9P_LOCK_FLAGS_UNUSED_19;
+ x = _LIB9P_LOCK_FLAGS_UNUSED_18;
+ x = _LIB9P_LOCK_FLAGS_UNUSED_17;
+ x = _LIB9P_LOCK_FLAGS_UNUSED_16;
+ x = _LIB9P_LOCK_FLAGS_UNUSED_15;
+ x = _LIB9P_LOCK_FLAGS_UNUSED_14;
+ x = _LIB9P_LOCK_FLAGS_UNUSED_13;
+ x = _LIB9P_LOCK_FLAGS_UNUSED_12;
+ x = _LIB9P_LOCK_FLAGS_UNUSED_11;
+ x = _LIB9P_LOCK_FLAGS_UNUSED_10;
+ x = _LIB9P_LOCK_FLAGS_UNUSED_9;
+ x = _LIB9P_LOCK_FLAGS_UNUSED_8;
+ x = _LIB9P_LOCK_FLAGS_UNUSED_7;
+ x = _LIB9P_LOCK_FLAGS_UNUSED_6;
+ x = _LIB9P_LOCK_FLAGS_UNUSED_5;
+ x = _LIB9P_LOCK_FLAGS_UNUSED_4;
+ x = _LIB9P_LOCK_FLAGS_UNUSED_3;
+ x = _LIB9P_LOCK_FLAGS_UNUSED_2;
x = LIB9P_LOCK_FLAGS_RECLAIM;
x = LIB9P_LOCK_FLAGS_BLOCK;
x = LIB9P_LOCK_STATUS_SUCCESS;
diff --git a/lib9p/tests/test_compile_config/config.h b/lib9p/tests/test_compile_config/config.h
index 38ab0c0..cc8eec1 100644
--- a/lib9p/tests/test_compile_config/config.h
+++ b/lib9p/tests/test_compile_config/config.h
@@ -9,20 +9,20 @@
/* 9P *************************************************************************/
-#define CONFIG_9P_MAX_MSG_SIZE ((4*1024)+24)
-#define CONFIG_9P_MAX_HOSTMSG_SIZE CONFIG_9P_MAX_MSG_SIZE+16
-#define CONFIG_9P_MAX_ERR_SIZE 128
-#define CONFIG_9P_MAX_9P2000_e_WELEM 16
-
-#define CONFIG_9P_SRV_MAX_FIDS 16
-#define CONFIG_9P_SRV_MAX_REQS 2
-#define CONFIG_9P_SRV_MAX_DEPTH 3
-
-#define CONFIG_9P_ENABLE_9P2000 1 /* bool */
-#define CONFIG_9P_ENABLE_9P2000_u 1 /* bool */
-#define CONFIG_9P_ENABLE_9P2000_e 1 /* bool */
-#define CONFIG_9P_ENABLE_9P2000_L 1 /* bool */
-#define CONFIG_9P_ENABLE_9P2000_p9p 1 /* bool */
+#define CONFIG_9P_MAX_ERR_SIZE 128
+#define CONFIG_9P_MAX_9P2000_e_WELEM 16
+
+#define CONFIG_9P_SRV_MAX_MSG_SIZE ((4*1024)+24)
+#define CONFIG_9P_SRV_MAX_HOSTMSG_SIZE CONFIG_9P_SRV_MAX_MSG_SIZE+16
+#define CONFIG_9P_SRV_MAX_FIDS 16
+#define CONFIG_9P_SRV_MAX_REQS 2
+#define CONFIG_9P_SRV_MAX_DEPTH 3
+
+#define CONFIG_9P_ENABLE_9P2000 1 /* bool */
+#define CONFIG_9P_ENABLE_9P2000_u 1 /* bool */
+#define CONFIG_9P_ENABLE_9P2000_e 1 /* bool */
+#define CONFIG_9P_ENABLE_9P2000_L 1 /* bool */
+#define CONFIG_9P_ENABLE_9P2000_p9p 1 /* bool */
/* COROUTINE ******************************************************************/
diff --git a/lib9p/tests/test_server/config/config.h b/lib9p/tests/test_server/config/config.h
index afe6dc0..03143e1 100644
--- a/lib9p/tests/test_server/config/config.h
+++ b/lib9p/tests/test_server/config/config.h
@@ -12,6 +12,8 @@
/* 9P *************************************************************************/
+#define CONFIG_9P_MAX_ERR_SIZE 128 /* 128 is what Plan 9 4e uses */
+
/**
* This max-msg-size is sized so that a Twrite message can return
* 8KiB of data.
@@ -29,22 +31,22 @@
* negotiated. In Plan 9 1e it was (8*1024)+128, and was bumped to
* (8*1024)+160 in 2e and 3e.
*/
-#define CONFIG_9P_MAX_MSG_SIZE ((4*1024)+24)
+#define CONFIG_9P_SRV_MAX_MSG_SIZE ((4*1024)+24)
/**
* Maximum host-data-structure size. A message may be larger in
* unmarshaled-host-structures than marshaled-net-bytes due to (1)
* struct padding, (2) array pointers.
*/
-#define CONFIG_9P_MAX_HOSTMSG_SIZE CONFIG_9P_MAX_MSG_SIZE+16
-#define CONFIG_9P_MAX_ERR_SIZE 128 /* 128 is what Plan 9 4e uses */
-#define CONFIG_9P_SRV_MAX_FIDS 16
-#define CONFIG_9P_SRV_MAX_REQS 2
-#define CONFIG_9P_SRV_MAX_DEPTH 3
-#define CONFIG_9P_ENABLE_9P2000 1 /* bool */
-#define CONFIG_9P_ENABLE_9P2000_u 1 /* bool */
-#define CONFIG_9P_ENABLE_9P2000_e 0 /* bool */
-#define CONFIG_9P_ENABLE_9P2000_L 0 /* bool */
-#define CONFIG_9P_ENABLE_9P2000_p9p 0 /* bool */
+#define CONFIG_9P_SRV_MAX_HOSTMSG_SIZE CONFIG_9P_SRV_MAX_MSG_SIZE+16
+#define CONFIG_9P_SRV_MAX_FIDS 16
+#define CONFIG_9P_SRV_MAX_REQS 2
+#define CONFIG_9P_SRV_MAX_DEPTH 3
+
+#define CONFIG_9P_ENABLE_9P2000 1 /* bool */
+#define CONFIG_9P_ENABLE_9P2000_u 1 /* bool */
+#define CONFIG_9P_ENABLE_9P2000_e 0 /* bool */
+#define CONFIG_9P_ENABLE_9P2000_L 0 /* bool */
+#define CONFIG_9P_ENABLE_9P2000_p9p 0 /* bool */
/* COROUTINE ******************************************************************/
diff --git a/lib9p/utf8.h b/lib9p/utf8.h
new file mode 100644
index 0000000..5ffd674
--- /dev/null
+++ b/lib9p/utf8.h
@@ -0,0 +1,34 @@
+/* lib9p/utf8.h - Internal UTF-8 validation
+ *
+ * Copyright (C) 2024-2025 Luke T. Shumaker <lukeshu@lukeshu.com>
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+
+#ifndef _LIB9P_UTF8_H_
+#define _LIB9P_UTF8_H_
+
+static inline bool _is_valid_utf8(uint8_t *str, size_t len, bool forbid_nul) {
+ uint32_t ch;
+ uint8_t chlen;
+ assert(str);
+ for (size_t pos = 0; pos < len;) {
+ if ((str[pos] & 0b10000000) == 0b00000000) { ch = str[pos] & 0b01111111; chlen = 1; }
+ else if ((str[pos] & 0b11100000) == 0b11000000) { ch = str[pos] & 0b00011111; chlen = 2; }
+ else if ((str[pos] & 0b11110000) == 0b11100000) { ch = str[pos] & 0b00001111; chlen = 3; }
+ else if ((str[pos] & 0b11111000) == 0b11110000) { ch = str[pos] & 0b00000111; chlen = 4; }
+ else return false;
+ if ((ch == 0 && (chlen != 1 || forbid_nul)) || pos + chlen > len) return false;
+ for (uint8_t i = 1; i < chlen; i++) {
+ if ((str[pos+i] & 0b11000000) != 0b10000000) return false;
+ ch = (ch << 6) | (str[pos+i] & 0b00111111);
+ }
+ if (ch > 0x10FFFF) return false;
+ pos += chlen;
+ }
+ return true;
+}
+
+#define is_valid_utf8(str, len) _is_valid_utf8(str, len, false)
+#define is_valid_utf8_without_nul(str, len) _is_valid_utf8(str, len, true)
+
+#endif /* _LIB9P_UTF8_H_ */