From 0f657e6d8316869fba3bd6218fd6910c84fee3f5 Mon Sep 17 00:00:00 2001 From: Kubat <mael.martin31@gmail.com> Date: Sun, 23 May 2021 15:18:42 +0200 Subject: [PATCH] CMD: Add the 'exec from trie' function, to use functions registered inside it --- src/net/listen.c | 76 ++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 74 insertions(+), 2 deletions(-) diff --git a/src/net/listen.c b/src/net/listen.c index dbbd5853..229055fa 100644 --- a/src/net/listen.c +++ b/src/net/listen.c @@ -43,6 +43,10 @@ struct cmd_trie_node { struct cmd_trie_node *children[CHARS_MAX]; /* Childrens, a byte is 256 possible values */ }; +/* The cmd_trie root for all the liblektor, it's OK because we have only one + * list of possible commands. */ +static struct cmd_trie_node *cmd_trie_root = NULL; + PRIVATE_FUNCTION struct cmd_trie_node * cmd_trie_new(void) { @@ -92,6 +96,76 @@ cmd_trie_insert(struct cmd_trie_node *root, const char *signed_cmd_name, } } +PRIVATE_FUNCTION struct cmd_trie_node * +cmd_trie_find(struct cmd_trie_node *root, const char *signed_cmd_name) +{ + FAIL_UNLESS(root, "Passing an empty trie root"); + unsigned const char *cmd_name = (unsigned const char *)signed_cmd_name; + size_t cmd_name_index = 0; + size_t current_char = cmd_name[cmd_name_index]; + + while (current_char) { + /* No node for the command */ + if (root->children[current_char] == NULL) { + LOG_WARN("CMD_TRIE", "Failed to find the command: %s", signed_cmd_name); + return NULL; + } + + cmd_name_index += 1; + root = root->children[current_char]; + current_char = cmd_name[cmd_name_index]; + } + + if (root->type == LKT_COMMAND_NULL) { + LOG_WARN("CMD_TRIE", "Failed to find the command: %s", signed_cmd_name); + return NULL; + } + + LOG_INFO("CMD_TRIE", "Found command: %s", signed_cmd_name); + return root; +} + +PRIVATE_FUNCTION bool +cmd_trie_exec(struct cmd_trie_node *root, const char *signed_cmd_name, va_list *args_list) +{ + FAIL_UNLESS(root, "Passing an empty trie root"); + struct cmd_trie_node *node = cmd_trie_find(root, signed_cmd_name); + if (node == NULL) + return false; + + /* Possibly used variables */ + struct lkt_state *srv; + size_t c; + char **args; + int arg_int; + + union { + void (*base)(void); + bool (*type_simple)(struct lkt_state *, size_t, char *[LKT_MESSAGE_ARGS_MAX]); + bool (*type_int)(struct lkt_state *, size_t, char *[LKT_MESSAGE_ARGS_MAX], int); + } cmd; + + cmd.base = node->cmd_ptr; + + switch (node->type) { + case LKT_COMMAND_SIMPLE: + srv = (struct lkt_state *)va_arg(*args_list, struct lkt_state *); + c = (size_t)va_arg(*args_list, size_t); + args = (char **)va_arg(*args_list, char *[LKT_MESSAGE_MAX]); + return cmd.type_simple(srv, c, args); + + case LKT_COMMAND_INTEGER: + srv = (struct lkt_state *)va_arg(*args_list, struct lkt_state *); + c = (size_t)va_arg(*args_list, size_t); + args = (char **)va_arg(*args_list, char *[LKT_MESSAGE_MAX]); + arg_int = (int)va_arg(*args_list, int); + return cmd.type_int(srv, c, args, arg_int); + + case LKT_COMMAND_NULL: + return false; + } +} + PRIVATE_FUNCTION void ___cmd_trie_print(struct cmd_trie_node *root, char *old_prefix, const size_t length) { @@ -127,8 +201,6 @@ cmd_trie_print(struct cmd_trie_node *root) ___cmd_trie_print(root, NULL, 0); } -struct cmd_trie_node *cmd_trie_root = NULL; - CONSTRUCTOR_FUNCTION ___cmd_trie_init(void) { -- GitLab