initial commit

This commit is contained in:
2025-08-31 07:34:13 -04:00
commit be5007d57c
23 changed files with 1013 additions and 0 deletions

120
src/api.c Normal file
View 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;
}