From 2f4cb88d5c60f725323739300bb49dfa8923e7d5 Mon Sep 17 00:00:00 2001 From: Albert Cervin Date: Wed, 2 Nov 2022 22:20:04 +0100 Subject: =?UTF-8?q?=F0=9F=8E=89=20And=20so=20it=20begins?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/command.c | 66 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 src/command.c (limited to 'src/command.c') diff --git a/src/command.c b/src/command.c new file mode 100644 index 0000000..4b233b2 --- /dev/null +++ b/src/command.c @@ -0,0 +1,66 @@ +#include "command.h" + +#include + +struct commands command_list_create(uint32_t capacity) { + return (struct commands){ + .commands = calloc(capacity, sizeof(struct hashed_command)), + .ncommands = 0, + .capacity = capacity, + }; +} + +void command_list_destroy(struct commands *commands) { + free(commands->commands); + commands->ncommands = 0; + commands->capacity = 0; +} + +uint32_t hash_command_name(const char *name) { + unsigned long hash = 5381; + int c; + + while ((c = *name++)) + hash = ((hash << 5) + hash) + c; /* hash * 33 + c */ + + return hash; +} + +uint32_t register_command(struct commands *commands, struct command *command) { + if (commands->ncommands == commands->capacity) { + commands->capacity *= 2; + commands->commands = realloc( + commands->commands, sizeof(struct hashed_command) * commands->capacity); + } + + uint32_t hash = hash_command_name(command->name); + commands->commands[commands->ncommands] = + (struct hashed_command){.command = command, .hash = hash}; + + ++commands->ncommands; + return hash; +} + +void register_commands(struct commands *command_list, struct command *commands, + uint32_t ncommands) { + for (uint32_t ci = 0; ci < ncommands; ++ci) { + register_command(command_list, &commands[ci]); + } +} + +struct command *lookup_command(struct commands *command_list, + const char *name) { + uint32_t needle = hash_command_name(name); + return lookup_command_by_hash(command_list, needle); +} + +struct command *lookup_command_by_hash(struct commands *commands, + uint32_t hash) { + for (uint32_t ci = 0; ci < commands->ncommands; ++ci) { + if (commands->commands[ci].hash == hash) { + return commands->commands[ci].command; + } + } + + return NULL; +} -- cgit v1.2.3