1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
|
#include "commands.h"
#include "list.h"
#include <assert.h>
#include <stdio.h>
#include <string.h>
struct imv_commands {
struct list *command_list;
};
struct command {
char* command;
void (*handler)(struct list *args, const char *argstr, void *data);
char* alias;
};
struct imv_commands *imv_commands_create(void)
{
struct imv_commands *cmds = malloc(sizeof *cmds);
cmds->command_list = list_create();
return cmds;
}
void imv_commands_free(struct imv_commands *cmds)
{
for(size_t i = 0; i < cmds->command_list->len; ++i) {
struct command *cmd = cmds->command_list->items[i];
free(cmd->command);
if(cmd->alias) {
free(cmd->alias);
}
free(cmd);
}
list_free(cmds->command_list);
free(cmds);
}
void imv_command_register(struct imv_commands *cmds, const char *command, void (*handler)(struct list*, const char*, void*))
{
struct command *cmd = malloc(sizeof *cmd);
cmd->command = strdup(command);
cmd->handler = handler;
cmd->alias = NULL;
list_append(cmds->command_list, cmd);
}
void imv_command_alias(struct imv_commands *cmds, const char *command, const char *alias)
{
struct command *cmd = malloc(sizeof *cmd);
cmd->command = strdup(command);
cmd->handler = NULL;
cmd->alias = strdup(alias);
list_append(cmds->command_list, cmd);
}
int imv_command_exec(struct imv_commands *cmds, const char *command, void *data)
{
struct list *args = list_from_string(command, ' ');
int ret = 1;
if(args->len > 0) {
for(size_t i = 0; i < cmds->command_list->len; ++i) {
struct command *cmd = cmds->command_list->items[i];
if(!strcmp(cmd->command, args->items[0])) {
if(cmd->handler) {
/* argstr = all args as a single string */
const char *argstr = command + strlen(cmd->command) + 1;
cmd->handler(args, argstr, data);
ret = 0;
} else if(cmd->alias) {
char *new_args = list_to_string(args, " ", 1);
size_t cmd_len = strlen(cmd->alias) + 1 + strlen(new_args) + 1;
char *new_cmd = malloc(cmd_len);
snprintf(new_cmd, cmd_len, "%s %s", cmd->alias, new_args);
ret = imv_command_exec(cmds, new_cmd, data);
free(new_args);
free(new_cmd);
}
break;
}
}
}
list_deep_free(args);
return ret;
}
int imv_command_exec_list(struct imv_commands *cmds, struct list *commands, void *data)
{
int ret = 0;
for(size_t i = 0; i < commands->len; ++i) {
const char *command = commands->items[i];
ret += imv_command_exec(cmds, command, data);
}
return ret;
}
/* vim:set ts=2 sts=2 sw=2 et: */
|