Refactor comand and event name parsing

Signed-off-by: Jim Ramsay <i.am@jimramsay.com>
pull/201/head
Jim Ramsay 2022-12-06 07:12:02 -05:00
parent 4def8f3cb8
commit d75ca4bf51
5 changed files with 90 additions and 36 deletions

View File

@ -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[];

View File

@ -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',
]

View File

@ -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,18 +439,31 @@ 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:

View File

@ -17,6 +17,7 @@
#include "ctl-commands.h"
#include <stdlib.h>
#include <string.h>
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));
}

View File

@ -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) {