121 lines
2.2 KiB
C
121 lines
2.2 KiB
C
#include <ctype.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
#include "ds.h"
|
|
#include "log.h"
|
|
|
|
#include "api.h"
|
|
|
|
ds_sll_t *subcmds;
|
|
|
|
int
|
|
register_subcmd(char *name, void (*cb)(void *, int argc, char *argv[]), void *data)
|
|
{
|
|
char *c;
|
|
ds_sll_t *newnode = calloc(1, sizeof(ds_sll_t));
|
|
wom_subcmd_t *newsubcmd = calloc(1, sizeof(wom_subcmd_t));
|
|
|
|
/* make sure the subcmd name doesn't contain a space */
|
|
for (c = name; *c != '\0'; c++) {
|
|
if (isspace(*c)) {
|
|
log_fatal("subcmd '%s' can't contain any whitespace characters", name);
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
/* setup data */
|
|
newsubcmd->name = name;
|
|
newsubcmd->cb = cb;
|
|
newsubcmd->data = data;
|
|
newnode->data = newsubcmd;
|
|
newnode->next = NULL;
|
|
|
|
/* if this is the first node */
|
|
if (!subcmds) {
|
|
subcmds = newnode;
|
|
return 0;
|
|
}
|
|
|
|
/* otherwise append the node to the end of the current nodes */
|
|
ds_ll_foreach(ds_sll_t, subcmds) {
|
|
if (!cur->next) {
|
|
cur->next = newnode;
|
|
break;
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
char
|
|
**list_subcmds(void)
|
|
{
|
|
int i;
|
|
char **subcmdp;
|
|
ds_sll_t *node;
|
|
wom_subcmd_t *subcmd;
|
|
|
|
/* get the number of elements in the linked list */
|
|
/* TEST: for some reason we need to allocate an extra space in the array or
|
|
* else */
|
|
for (i = 1, node = subcmds; node; node = node->next, i++)
|
|
;
|
|
|
|
subcmdp = calloc(i, sizeof(char *));
|
|
|
|
for (i = 0, node = subcmds; node; node = node->next, i++) {
|
|
subcmd = node->data;
|
|
if (subcmd->name) {
|
|
subcmdp[i] = subcmd->name;
|
|
}
|
|
}
|
|
|
|
return subcmdp;
|
|
}
|
|
|
|
void
|
|
run_subcmds(int argc, char *argv[])
|
|
{
|
|
int i, j;
|
|
char **args;
|
|
wom_subcmd_t *subcmd;
|
|
|
|
/* check for subcommands to run */
|
|
for (i = 1; i < argc; i++) {
|
|
ds_ll_foreach(ds_sll_t, subcmds) {
|
|
subcmd = cur->data;
|
|
if (strcmp(argv[i], subcmd->name) == 0) {
|
|
goto args;
|
|
}
|
|
}
|
|
}
|
|
|
|
return;
|
|
args:
|
|
args = calloc(argc - i, sizeof(char *));
|
|
for (j = 0; i < argc; i++, j++) {
|
|
args[j] = argv[i];
|
|
}
|
|
|
|
subcmd->cb(subcmd->data, j, args);
|
|
free(args);
|
|
}
|
|
|
|
int
|
|
cleanup_subcmds(void)
|
|
{
|
|
ds_sll_t *prevnode, *node;
|
|
|
|
for (node = subcmds; node;) {
|
|
free(node->data);
|
|
prevnode = node;
|
|
node = node->next;
|
|
free(prevnode);
|
|
}
|
|
|
|
free(node);
|
|
|
|
return 0;
|
|
}
|