initial commit
This commit is contained in:
120
src/api.c
Normal file
120
src/api.c
Normal file
@@ -0,0 +1,120 @@
|
||||
#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;
|
||||
}
|
Reference in New Issue
Block a user