From d75ca4bf51484710025a672ddeee5eec60dcf025 Mon Sep 17 00:00:00 2001 From: Jim Ramsay Date: Tue, 6 Dec 2022 07:12:02 -0500 Subject: [PATCH] Refactor comand and event name parsing Signed-off-by: Jim Ramsay --- include/ctl-commands.h | 8 +++++++ meson.build | 1 + src/ctl-client.c | 35 +++++++++++++++++++++++------- src/ctl-commands.c | 49 ++++++++++++++++++++++++++++++++++++++++++ src/ctl-server.c | 33 +++++----------------------- 5 files changed, 90 insertions(+), 36 deletions(-) diff --git a/include/ctl-commands.h b/include/ctl-commands.h index de41b9e..6744e50 100644 --- a/include/ctl-commands.h +++ b/include/ctl-commands.h @@ -48,5 +48,13 @@ struct cmd_info { struct cmd_param_info params[5]; }; +enum cmd_type ctl_command_parse_name(const char* name); +struct cmd_info* ctl_command_by_type(enum cmd_type type); +struct cmd_info* ctl_command_by_name(const char* name); + +enum event_type ctl_event_parse_name(const char* name); +struct cmd_info* ctl_event_by_type(enum event_type type); +struct cmd_info* ctl_event_by_name(const char* name); + extern struct cmd_info ctl_command_list[]; extern struct cmd_info ctl_event_list[]; diff --git a/meson.build b/meson.build index cd226f6..157b368 100644 --- a/meson.build +++ b/meson.build @@ -119,6 +119,7 @@ ctlsources = [ 'src/util.c', 'src/json-ipc.c', 'src/ctl-client.c', + 'src/ctl-commands.c', 'src/strlcpy.c', 'src/option-parser.c', ] diff --git a/src/ctl-client.c b/src/ctl-client.c index 50d77d5..251e4e3 100644 --- a/src/ctl-client.c +++ b/src/ctl-client.c @@ -28,6 +28,7 @@ #include "json-ipc.h" #include "ctl-client.h" +#include "ctl-commands.h" #include "ctl-server.h" #include "strlcpy.h" #include "util.h" @@ -438,17 +439,30 @@ static void pretty_output_list(json_t* data) static void pretty_print(json_t* data, struct jsonipc_request* request) { - const char* method = request->method; - if (strcmp(method, "help") == 0) + enum cmd_type cmd = ctl_command_parse_name(request->method); + switch (cmd) { + case CMD_HELP: print_help(data, request->params); - else if (strcmp(method, "version") == 0) + break; + case CMD_VERSION: pretty_version(data); - else if (strcmp(method, "get-clients") == 0) + break; + case CMD_GET_CLIENTS: pretty_client_list(data); - else if (strcmp(method, "get-outputs") == 0) + break; + case CMD_GET_OUTPUTS: pretty_output_list(data); - else + break; + case CMD_DISCONNECT_CLIENT: + case CMD_SET_OUTPUT: + case CMD_WAYVNC_EXIT: + printf("Ok\n"); + break; + case CMD_EVENT_RECEIVE: + abort(); // Event loop code handles this one + case CMD_UNKNOWN: json_dumpf(data, stdout, JSON_INDENT(2)); + } } static void print_compact_json(json_t* data) @@ -710,10 +724,15 @@ int ctl_client_run_command(struct ctl_client* self, if (!request) goto parse_failure; - if (strcmp(request->method, "event-receive") == 0) + enum cmd_type cmd = ctl_command_parse_name(request->method); + switch (cmd) { + case CMD_EVENT_RECEIVE: result = ctl_client_event_loop(self, request); - else + break; + default: result = ctl_client_print_single_command(self, request); + break; + } jsonipc_request_destroy(request); parse_failure: diff --git a/src/ctl-commands.c b/src/ctl-commands.c index 910783e..92ae554 100644 --- a/src/ctl-commands.c +++ b/src/ctl-commands.c @@ -17,6 +17,7 @@ #include "ctl-commands.h" #include +#include struct cmd_info ctl_command_list[] = { [CMD_HELP] = { "help", @@ -90,3 +91,51 @@ struct cmd_info ctl_event_list[] = { }, }; + +enum cmd_type ctl_command_parse_name(const char* name) +{ + if (!name || name[0] == '\0') + return CMD_UNKNOWN; + for (size_t i = 0; i < CMD_LIST_LEN; ++i) { + if (strcmp(name, ctl_command_list[i].name) == 0) { + return i; + } + } + return CMD_UNKNOWN; +} + +enum event_type ctl_event_parse_name(const char* name) +{ + if (!name || name[0] == '\0') + return EVT_UNKNOWN; + for (size_t i = 0; i < EVT_LIST_LEN; ++i) { + if (strcmp(name, ctl_event_list[i].name) == 0) { + return i; + } + } + return EVT_UNKNOWN; +} + +struct cmd_info* ctl_command_by_type(enum cmd_type cmd) +{ + if (cmd == CMD_UNKNOWN) + return NULL; + return &ctl_command_list[cmd]; +} + +struct cmd_info* ctl_command_by_name(const char* name) +{ + return ctl_command_by_type(ctl_command_parse_name(name)); +} + +struct cmd_info* ctl_event_by_type(enum event_type evt) +{ + if (evt == EVT_UNKNOWN) + return NULL; + return &ctl_event_list[evt]; +} + +struct cmd_info* ctl_event_by_name(const char* name) +{ + return ctl_event_by_type(ctl_event_parse_name(name)); +} diff --git a/src/ctl-server.c b/src/ctl-server.c index c4b89d6..6e38b90 100644 --- a/src/ctl-server.c +++ b/src/ctl-server.c @@ -105,18 +105,6 @@ static void cmd_response_destroy(struct cmd_response* self) free(self); } -static enum cmd_type parse_command_name(const char* name) -{ - if (!name || name[0] == '\0') - return CMD_UNKNOWN; - for (int i = 0; i < CMD_LIST_LEN; ++i) { - if (strcmp(name, ctl_command_list[i].name) == 0) { - return i; - } - } - return CMD_UNKNOWN; -} - static struct cmd_help* cmd_help_new(json_t* args, struct jsonipc_error* err) { @@ -218,7 +206,7 @@ static struct cmd* parse_command(struct jsonipc_request* ipc, struct jsonipc_error* err) { nvnc_trace("Parsing command %s", ipc->method); - enum cmd_type cmd_type = parse_command_name(ipc->method); + enum cmd_type cmd_type = ctl_command_parse_name(ipc->method); struct cmd* cmd = NULL; switch (cmd_type) { case CMD_HELP: @@ -323,22 +311,11 @@ static json_t* client_next_object(struct ctl_client* self, struct cmd_response** return root; } -static struct cmd_info* find_info(const char* id, struct cmd_info (*list)[], - size_t len) -{ - for (size_t i = 0; i < len; ++i) { - struct cmd_info* info = &(*list)[i]; - if (strcmp(info->name, id) == 0) - return info; - } - return NULL; -} - static struct cmd_response* generate_help_object(const char* id, bool id_is_command) { struct cmd_info* info = id_is_command ? - find_info(id, &ctl_command_list, CMD_LIST_LEN) : - find_info(id, &ctl_event_list, EVT_LIST_LEN); + ctl_command_by_name(id) : + ctl_event_by_name(id); json_t* data; if (!info) { data = json_pack("{s:o, s:o}", @@ -416,8 +393,8 @@ static struct cmd_response* generate_output_list(struct ctl* self) static struct cmd_response* ctl_server_dispatch_cmd(struct ctl* self, struct ctl_client* client, struct cmd* cmd) { - assert(cmd->type != CMD_UNKNOWN); - const struct cmd_info* info = &ctl_command_list[cmd->type]; + const struct cmd_info* info = ctl_command_by_type(cmd->type); + assert(info); nvnc_log(NVNC_LOG_INFO, "Dispatching control client command '%s'", info->name); struct cmd_response* response = NULL; switch (cmd->type) {