From f030ed758ecbebda34c5577c8ec94b5f7358d1fe Mon Sep 17 00:00:00 2001 From: Michel Pollet Date: Sat, 28 Oct 2023 06:28:53 +0100 Subject: [PATCH] libmish: Reworked to add a 'kind' to commands Quest to remove any globals from mii Signed-off-by: Michel Pollet --- libmish/src/mish.h | 57 +++++++++++++++++++++++++++++++++++++----- libmish/src/mish_cmd.c | 25 ++++++++++++++---- 2 files changed, 71 insertions(+), 11 deletions(-) diff --git a/libmish/src/mish.h b/libmish/src/mish.h index d12e4d4..cbe4a33 100644 --- a/libmish/src/mish.h +++ b/libmish/src/mish.h @@ -44,6 +44,14 @@ void mish_terminate( struct mish_t * m); +/* Currently only one flag is used */ +typedef union mish_cmd_flags_t { + struct { + unsigned int safe : 1; + }; + unsigned int raw; +} mish_cmd_flags_t; + /* * Register a command; please use the macros, don't call this directly. * @@ -51,14 +59,35 @@ mish_terminate( * without having to drag libmish into programs that use it; the commands * won't register, but if you then link with a program that uses libmish, * they will. + * Same but allows grouping command by an arbitrary 'kind' value. */ void -mish_register_cmd( +mish_register_cmd_kind( const char ** cmd_names, const char ** cmd_help, mish_cmd_handler_p cmd_handler, void * handler_param, - int safe) __attribute__((weak)); + mish_cmd_flags_t flags, + unsigned int kind) __attribute__((weak)); + +#define mish_register_cmd(__named, __help, __handler, __param, __safe) \ + mish_register_cmd_kind(__named, __help, __handler, __param, \ + (mish_cmd_flags_t){.safe = __safe}, 0) + +/* + * There is some provision for command-specific parameters, but it's not + * used yet. Instead we use a global one. If 'kind' is zero, ALL parameters + * for every command is set to 'param'. If 'kind' is non-zero, only the + * commands that have been registered with MISH_CMD_REGISTER_KIND() and + * the matchinf 'kind' will have their parameter set to 'param'. + * + * This allows grouping commands by 'kind' and have them share a parameter. + */ +void +mish_set_command_parameter( + unsigned int kind, + void * param); + /*! * Poll the mish threads for pending commands, and call their handlers. * This is only necessary for 'safe' commands that needs to be run on the @@ -99,15 +128,31 @@ static inline int _gcc_warning_false_pos_workaround(void * func) { #define MISH_CMD_REGISTER(_d, _handler) \ __attribute__((constructor,used)) \ static void _mish_register_##_d() { \ - if (_gcc_warning_false_pos_workaround(mish_register_cmd)) \ - mish_register_cmd(_cmd_##_d,_help_##_d,_handler,0,0);\ + if (_gcc_warning_false_pos_workaround(mish_register_cmd_kind)) \ + mish_register_cmd_kind(_cmd_##_d,_help_##_d,_handler,0,\ + (mish_cmd_flags_t){},0);\ + } + +#ifndef MISH_FCC +// create a four character constant, not necessary, just for convenience +#define MISH_FCC(_a,_b,_c,_d) (((_a)<<24)|((_b)<<16)|((_c)<<8)|(_d)) +#endif + +#define MISH_CMD_REGISTER_KIND(_d, _handler, _safe, _kind) \ + __attribute__((constructor,used)) \ + static void _mish_register_##_d() { \ + if (_gcc_warning_false_pos_workaround(mish_register_cmd_kind)) \ + mish_register_cmd_kind(_cmd_##_d,_help_##_d,\ + _handler,0,\ + (mish_cmd_flags_t){.safe=_safe},_kind);\ } //! These are called when the main program calls mish_cmd_poll() #define MISH_CMD_REGISTER_SAFE(_d, _handler) \ __attribute__((constructor,used)) \ static void _mish_register_##_d() { \ - if (_gcc_warning_false_pos_workaround(mish_register_cmd)) \ - mish_register_cmd(_cmd_##_d,_help_##_d,_handler,0,1);\ + if (_gcc_warning_false_pos_workaround(mish_register_cmd_kind)) \ + mish_register_cmd_kind(_cmd_##_d,_help_##_d,_handler,0, \ + (mish_cmd_flags_t){.safe=1},0);\ } #endif /* LIBMISH_SRC_MISH_H_ */ diff --git a/libmish/src/mish_cmd.c b/libmish/src/mish_cmd.c index a4c9eed..ad0ddc2 100644 --- a/libmish/src/mish_cmd.c +++ b/libmish/src/mish_cmd.c @@ -29,7 +29,8 @@ typedef struct mish_cmd_t { TAILQ_ENTRY(mish_cmd_t) self; mish_cmd_handler_p cmd_cb; void * param_cb; - uint32_t safe : 1; + uint32_t kind; // optional, for your own use + mish_cmd_flags_t flags; const char ** names; // list of aliases for the command const char ** help; @@ -48,12 +49,13 @@ static TAILQ_HEAD(,mish_cmd_t) _cmd_list = TAILQ_HEAD_INITIALIZER(_cmd_list); static mish_call_queue_t _cmd_fifo = {0}; void __attribute__((weak)) -mish_register_cmd( +mish_register_cmd_kind( const char ** cmd_names, const char ** cmd_help, mish_cmd_handler_p cmd_handler, void * handler_param, - int safe) + mish_cmd_flags_t flags, + uint32_t kind) { if (!cmd_names || !cmd_help || !cmd_handler) { fprintf(stderr, "%s invalid parameters\n", __func__); @@ -65,7 +67,8 @@ mish_register_cmd( cmd->help = cmd_help; cmd->cmd_cb = cmd_handler; cmd->param_cb = handler_param; - cmd->safe = safe; + cmd->kind = kind; + cmd->flags = flags; // keep the list roughtly sorted mish_cmd_p c, s; @@ -78,6 +81,18 @@ mish_register_cmd( TAILQ_INSERT_TAIL(&_cmd_list, cmd, self); } +void +mish_set_command_parameter( + unsigned int kind, + void * param) +{ + mish_cmd_p cmd; + TAILQ_FOREACH(cmd, &_cmd_list, self) { + if (!kind || cmd->kind == kind) + cmd->param_cb = param; + } +} + /* * Returns the length of the first word of cmd_line */ @@ -216,7 +231,7 @@ mish_cmd_call( int ac = 0; char ** av = mish_argv_make(cmd_line, &ac); - if (cmd->safe) { + if (cmd->flags.safe) { if (!mish_call_queue_isfull(&_cmd_fifo)) { mish_cmd_call_t fe = { .cmd = cmd,