summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuke T. Shumaker <lukeshu@lukeshu.com>2025-05-12 15:31:09 -0600
committerLuke T. Shumaker <lukeshu@lukeshu.com>2025-05-15 14:39:30 -0600
commit2ae702af39d370cede1b32a4b507df75b3438ddb (patch)
tree0330f2e3da80db5fc930b20b7005672ed2869397
parenta226a1adf5e07f4281fcf95d3a69b7964159a95a (diff)
lib9p: Adjust _lib9p_{validate,unmarshal,marshal} to be macros, not functions
-rw-r--r--build-aux/measurestack/app_plugins.py62
-rw-r--r--lib9p/core.c129
2 files changed, 79 insertions, 112 deletions
diff --git a/build-aux/measurestack/app_plugins.py b/build-aux/measurestack/app_plugins.py
index f9dfe40..1fb0355 100644
--- a/build-aux/measurestack/app_plugins.py
+++ b/build-aux/measurestack/app_plugins.py
@@ -255,13 +255,7 @@ class LibCRIPCPlugin:
class Lib9PPlugin:
- re_lib9p_msg_entry = re.compile(r"^\s*_MSG_(?:[A-Z]+)\((?P<typ>\S+)\),$")
- re_lib9p_caller = re.compile(
- r"^lib9p_(?P<grp>[TR])msg_(?P<meth>validate|unmarshal|marshal)$"
- )
- re_lib9p_callee = re.compile(
- r"^(?P<meth>validate|unmarshal|marshal)_(?P<msg>(?P<grp>[TR]).*)$"
- )
+ re_lib9p_msg_entry = re.compile(r"^\s*_MSG\((?P<typ>\S+)\),$")
lib9p_msgs: set[str]
_CONFIG_9P_MAX_CONNS: int | None
@@ -297,7 +291,7 @@ class Lib9PPlugin:
)
lib9p_generated_c_fname = util.get_zero_or_one(
- lambda fname: fname.endswith("lib9p/_core_generated.c"), arg_c_fnames
+ lambda fname: fname.endswith("lib9p/core_generated.c"), arg_c_fnames
)
# Read config ##########################################################
@@ -350,45 +344,35 @@ class Lib9PPlugin:
def extra_nodes(self) -> typing.Collection[Node]:
return []
+ re_table_call = re.compile(
+ r"\s*_lib9p_(?P<meth>validate|unmarshal|marshal)\(.*(?P<grp>[RT])msg.*\);\s*"
+ )
+ re_print_call = re.compile(r".*lib9p_table_msg.*\.box_as_fmt_formatter\(.*")
+
def indirect_callees(
self, loc: str, line: str
) -> tuple[typing.Collection[QName], bool] | None:
if "/3rd-party/" in loc:
return None
- if self.lib9p_msgs and "/9p.c:" in loc:
- for meth in ["validate", "unmarshal", "marshal"]:
- if line.startswith(f"tentry.{meth}("):
- # Functions for disabled protocol extensions will be missing.
- return [QName(f"{meth}_{msg}") for msg in self.lib9p_msgs], True
+ if self.lib9p_msgs and "lib9p/core.c:" in loc:
+ if m := self.re_table_call.fullmatch(line):
+ meth = m.group("meth")
+ grp = m.group("grp")
+ # Functions for disabled protocol extensions will be missing.
+ return [
+ QName(f"{meth}_{msg}")
+ for msg in self.lib9p_msgs
+ if msg.startswith(grp)
+ ], True
+ if self.re_print_call.fullmatch(line):
+ # Functions for disabled protocol extensions will be missing.
+ return [
+ QName(f"lib9p_msg_{msg}_format") for msg in self.lib9p_msgs
+ ], True
return None
def skipmodels(self) -> dict[BaseName, analyze.SkipModel]:
- ret: dict[BaseName, analyze.SkipModel] = {
- BaseName("_lib9p_validate"): analyze.SkipModel(
- 1,
- self._skipmodel__lib9p_validate_unmarshal_marshal,
- ),
- BaseName("_lib9p_unmarshal"): analyze.SkipModel(
- 1,
- self._skipmodel__lib9p_validate_unmarshal_marshal,
- ),
- BaseName("_lib9p_marshal"): analyze.SkipModel(
- 1,
- self._skipmodel__lib9p_validate_unmarshal_marshal,
- ),
- }
- return ret
-
- def _skipmodel__lib9p_validate_unmarshal_marshal(
- self, chain: typing.Sequence[QName], node: Node, call: QName
- ) -> bool:
- m_caller = self.re_lib9p_caller.fullmatch(str(chain[-1].base()))
- assert m_caller
-
- m_callee = self.re_lib9p_callee.fullmatch(str(call.base()))
- if not m_callee:
- return False
- return m_caller.group("grp") != m_callee.group("grp")
+ return {}
class PicoFmtPlugin:
diff --git a/lib9p/core.c b/lib9p/core.c
index c777741..a44bab6 100644
--- a/lib9p/core.c
+++ b/lib9p/core.c
@@ -151,102 +151,85 @@ lo_interface fmt_formatter lo_box_lib9p_msg_as_fmt_formatter(struct lib9p_ctx *c
/* 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, LIB9P_ERRNO_L_EBADMSG, "message is impossibly short");
- uint8_t typ = net_bytes[4];
- if (typ % 2 != xxx_low_typ_bit)
- return lib9p_errorf(ctx, LIB9P_ERRNO_L_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, LIB9P_ERRNO_L_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);
-}
+#define _lib9p_validate(LOW_TYP_BIT, ERRMSG, TABLE) do { \
+ 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, LIB9P_ERRNO_L_EBADMSG, "message is impossibly short"); \
+ uint8_t typ = net_bytes[4]; \
+ if (typ % 2 != LOW_TYP_BIT) \
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EOPNOTSUPP, ERRMSG ": message_type=%s", \
+ lib9p_msgtype_str(ctx->version, typ)); \
+ struct _lib9p_recv_tentry tentry = TABLE[ctx->version][typ/2]; \
+ if (!tentry.validate) \
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_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); \
+} while (0)
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);
+ _lib9p_validate(0, "expected a T-message but got an R-message", _lib9p_table_Tmsg_recv);
}
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);
+ _lib9p_validate(1, "expected an R-message but got a T-message", _lib9p_table_Rmsg_recv);
}
-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];
- assert(tentry.unmarshal);
-
- tentry.unmarshal(ctx, net_bytes, ret_body);
-}
+#define _lib9p_unmarshal(TABLE) do { \
+ assert_ver(ctx->version); \
+ enum lib9p_msg_type typ = net_bytes[4]; \
+ *ret_typ = typ; \
+ struct _lib9p_recv_tentry tentry = TABLE[ctx->version][typ/2]; \
+ assert(tentry.unmarshal); \
+ \
+ tentry.unmarshal(ctx, net_bytes, ret_body); \
+} while (0)
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);
+ _lib9p_unmarshal(_lib9p_table_Tmsg_recv);
}
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);
+ _lib9p_unmarshal(_lib9p_table_Rmsg_recv);
}
-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];
- assert(tentry.marshal);
-
- 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;
-}
+#define _lib9p_marshal(LOW_TYP_BIT, TABLE) do { \
+ assert_ver(ctx->version); \
+ assert(typ % 2 == LOW_TYP_BIT); \
+ assert_typ(typ); \
+ \
+ memset(ret, 0, sizeof(*ret)); \
+ \
+ 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 = TABLE[ctx->version][typ/2]; \
+ assert(tentry.marshal); \
+ \
+ bool ret_erred = tentry.marshal(ctx, body, &_ret); \
+ if (_ret.net_iov[_ret.net_iov_cnt-1].iov_len == 0) \
+ _ret.net_iov_cnt--; \
+ \
+ ret->iov_cnt = _ret.net_iov_cnt; \
+ return ret_erred; \
+} while (0)
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);
+ _lib9p_marshal(0, _lib9p_table_Tmsg_send);
}
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);
+ _lib9p_marshal(1, _lib9p_table_Rmsg_send);
}
/* `struct lib9p_stat` helpers ************************************************/