mirror of
https://github.com/buserror/mii_emu.git
synced 2024-11-22 01:30:51 +00:00
libmish: Reworked to add a 'kind' to commands
Quest to remove any globals from mii Signed-off-by: Michel Pollet <buserror@gmail.com>
This commit is contained in:
parent
2f2cf15576
commit
f030ed758e
@ -44,6 +44,14 @@ void
|
|||||||
mish_terminate(
|
mish_terminate(
|
||||||
struct mish_t * m);
|
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.
|
* 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
|
* 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,
|
* won't register, but if you then link with a program that uses libmish,
|
||||||
* they will.
|
* they will.
|
||||||
|
* Same but allows grouping command by an arbitrary 'kind' value.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
mish_register_cmd(
|
mish_register_cmd_kind(
|
||||||
const char ** cmd_names,
|
const char ** cmd_names,
|
||||||
const char ** cmd_help,
|
const char ** cmd_help,
|
||||||
mish_cmd_handler_p cmd_handler,
|
mish_cmd_handler_p cmd_handler,
|
||||||
void * handler_param,
|
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.
|
* 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
|
* 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) \
|
#define MISH_CMD_REGISTER(_d, _handler) \
|
||||||
__attribute__((constructor,used)) \
|
__attribute__((constructor,used)) \
|
||||||
static void _mish_register_##_d() { \
|
static void _mish_register_##_d() { \
|
||||||
if (_gcc_warning_false_pos_workaround(mish_register_cmd)) \
|
if (_gcc_warning_false_pos_workaround(mish_register_cmd_kind)) \
|
||||||
mish_register_cmd(_cmd_##_d,_help_##_d,_handler,0,0);\
|
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()
|
//! These are called when the main program calls mish_cmd_poll()
|
||||||
#define MISH_CMD_REGISTER_SAFE(_d, _handler) \
|
#define MISH_CMD_REGISTER_SAFE(_d, _handler) \
|
||||||
__attribute__((constructor,used)) \
|
__attribute__((constructor,used)) \
|
||||||
static void _mish_register_##_d() { \
|
static void _mish_register_##_d() { \
|
||||||
if (_gcc_warning_false_pos_workaround(mish_register_cmd)) \
|
if (_gcc_warning_false_pos_workaround(mish_register_cmd_kind)) \
|
||||||
mish_register_cmd(_cmd_##_d,_help_##_d,_handler,0,1);\
|
mish_register_cmd_kind(_cmd_##_d,_help_##_d,_handler,0, \
|
||||||
|
(mish_cmd_flags_t){.safe=1},0);\
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* LIBMISH_SRC_MISH_H_ */
|
#endif /* LIBMISH_SRC_MISH_H_ */
|
||||||
|
@ -29,7 +29,8 @@ typedef struct mish_cmd_t {
|
|||||||
TAILQ_ENTRY(mish_cmd_t) self;
|
TAILQ_ENTRY(mish_cmd_t) self;
|
||||||
mish_cmd_handler_p cmd_cb;
|
mish_cmd_handler_p cmd_cb;
|
||||||
void * param_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 ** names; // list of aliases for the command
|
||||||
const char ** help;
|
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};
|
static mish_call_queue_t _cmd_fifo = {0};
|
||||||
|
|
||||||
void __attribute__((weak))
|
void __attribute__((weak))
|
||||||
mish_register_cmd(
|
mish_register_cmd_kind(
|
||||||
const char ** cmd_names,
|
const char ** cmd_names,
|
||||||
const char ** cmd_help,
|
const char ** cmd_help,
|
||||||
mish_cmd_handler_p cmd_handler,
|
mish_cmd_handler_p cmd_handler,
|
||||||
void * handler_param,
|
void * handler_param,
|
||||||
int safe)
|
mish_cmd_flags_t flags,
|
||||||
|
uint32_t kind)
|
||||||
{
|
{
|
||||||
if (!cmd_names || !cmd_help || !cmd_handler) {
|
if (!cmd_names || !cmd_help || !cmd_handler) {
|
||||||
fprintf(stderr, "%s invalid parameters\n", __func__);
|
fprintf(stderr, "%s invalid parameters\n", __func__);
|
||||||
@ -65,7 +67,8 @@ mish_register_cmd(
|
|||||||
cmd->help = cmd_help;
|
cmd->help = cmd_help;
|
||||||
cmd->cmd_cb = cmd_handler;
|
cmd->cmd_cb = cmd_handler;
|
||||||
cmd->param_cb = handler_param;
|
cmd->param_cb = handler_param;
|
||||||
cmd->safe = safe;
|
cmd->kind = kind;
|
||||||
|
cmd->flags = flags;
|
||||||
|
|
||||||
// keep the list roughtly sorted
|
// keep the list roughtly sorted
|
||||||
mish_cmd_p c, s;
|
mish_cmd_p c, s;
|
||||||
@ -78,6 +81,18 @@ mish_register_cmd(
|
|||||||
TAILQ_INSERT_TAIL(&_cmd_list, cmd, self);
|
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
|
* Returns the length of the first word of cmd_line
|
||||||
*/
|
*/
|
||||||
@ -216,7 +231,7 @@ mish_cmd_call(
|
|||||||
int ac = 0;
|
int ac = 0;
|
||||||
char ** av = mish_argv_make(cmd_line, &ac);
|
char ** av = mish_argv_make(cmd_line, &ac);
|
||||||
|
|
||||||
if (cmd->safe) {
|
if (cmd->flags.safe) {
|
||||||
if (!mish_call_queue_isfull(&_cmd_fifo)) {
|
if (!mish_call_queue_isfull(&_cmd_fifo)) {
|
||||||
mish_cmd_call_t fe = {
|
mish_cmd_call_t fe = {
|
||||||
.cmd = cmd,
|
.cmd = cmd,
|
||||||
|
Loading…
Reference in New Issue
Block a user