feat(console): add command user context support

Current implementation implicitly forces the developer to use global variables
to enter its context during the command invocation, this change enables each
module to register a context for command to find without the need to manage
global variables.

No API breakage.

Fields added:
   esp_console_cmd_t::func_w_context    - (*)(int argc, char **argv, void *context)

Functions added:
   esp_err_t esp_console_cmd_set_context(const char *cmd, void *context)

Usage:

   esp_console_cmd_register(&cmd));
   esp_console_cmd_set_context(cmd.command, (void *)"context"));

Signed-off-by: Alon Bar-Lev <alon.barlev@gmail.com>
This commit is contained in:
Alon Bar-Lev
2023-10-20 20:48:52 +03:00
committed by Jakob Hasse
parent 142218c2eb
commit bccb2873bd
5 changed files with 196 additions and 6 deletions

View File

@@ -32,9 +32,11 @@ typedef struct cmd_item_ {
* May be NULL.
*/
char *hint;
esp_console_cmd_func_t func; //!< pointer to the command handler
void *argtable; //!< optional pointer to arg table
SLIST_ENTRY(cmd_item_) next; //!< next command in the list
esp_console_cmd_func_t func; //!< pointer to the command handler (without user context)
esp_console_cmd_func_with_context_t func_w_context; //!< pointer to the command handler (with user context)
void *argtable; //!< optional pointer to arg table
void *context; //!< optional pointer to user context
SLIST_ENTRY(cmd_item_) next; //!< next command in the list
} cmd_item_t;
/** linked list of command structures */
@@ -97,6 +99,10 @@ esp_err_t esp_console_cmd_register(const esp_console_cmd_t *cmd)
if (strchr(cmd->command, ' ') != NULL) {
return ESP_ERR_INVALID_ARG;
}
if ((cmd->func == NULL && cmd->func_w_context == NULL)
|| (cmd->func != NULL && cmd->func_w_context != NULL)) {
return ESP_ERR_INVALID_ARG;
}
item = (cmd_item_t *)find_command_by_name(cmd->command);
if (!item) {
// not registered before
@@ -130,6 +136,7 @@ esp_err_t esp_console_cmd_register(const esp_console_cmd_t *cmd)
}
item->argtable = cmd->argtable;
item->func = cmd->func;
item->func_w_context = cmd->func_w_context;
cmd_item_t *last = NULL;
cmd_item_t *it;
SLIST_FOREACH(it, &s_cmd_list, next) {
@@ -146,6 +153,22 @@ esp_err_t esp_console_cmd_register(const esp_console_cmd_t *cmd)
return ESP_OK;
}
esp_err_t esp_console_cmd_set_context(const char *cmd, void *context)
{
if (cmd == NULL ) {
return ESP_ERR_INVALID_ARG;
}
cmd_item_t *it;
SLIST_FOREACH(it, &s_cmd_list, next) {
if (strcmp(cmd, it->command) == 0) {
it->context = context;
return ESP_OK;
}
}
return ESP_ERR_NOT_FOUND;
}
void esp_console_get_completion(const char *buf, linenoiseCompletions *lc)
{
size_t len = strlen(buf);
@@ -213,7 +236,12 @@ esp_err_t esp_console_run(const char *cmdline, int *cmd_ret)
free(argv);
return ESP_ERR_NOT_FOUND;
}
*cmd_ret = (*cmd->func)(argc, argv);
if (cmd->func) {
*cmd_ret = (*cmd->func)(argc, argv);
}
if (cmd->func_w_context) {
*cmd_ret = (*cmd->func_w_context)(cmd->context, argc, argv);
}
free(argv);
return ESP_OK;
}