aboutsummaryrefslogtreecommitdiff
path: root/lib/arg/arg.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/arg/arg.c')
-rw-r--r--lib/arg/arg.c85
1 files changed, 85 insertions, 0 deletions
diff --git a/lib/arg/arg.c b/lib/arg/arg.c
new file mode 100644
index 0000000..271b535
--- /dev/null
+++ b/lib/arg/arg.c
@@ -0,0 +1,85 @@
+#include "arg.h"
+
+#include "../sys/sizes.h"
+#include "../cstr/cstr.h"
+
+#include "../avl_tree/avl_tree.h"
+#include "../malloc/malloc.h"
+#include "../sys/exit.h"
+#include "../io/io.h"
+#include "../aec/aec.h"
+
+typedef struct {
+ const char *name;
+ union {
+ void (*flag_func)();
+ void (*arg_func)(const char *);
+ };
+} arg_func_t;
+
+avl_tree_t *flags = 0;
+avl_tree_t *args = 0;
+void (*default_arg)(const char *) = 0;
+
+
+i8 __arg_func_compare(void *a, void *b) {
+ return cstr_compare(((arg_func_t *)a)->name, ((arg_func_t *)b)->name);
+}
+
+
+void arg_parse_arg(int argc, const char **argv)
+{
+ arg_func_t *func;
+ arg_func_t q;
+ for (int i = 1; i < argc; ++i) {
+ q.name = argv[i];
+ if (args &&
+ i < argc - 1 &&
+ argv[i + 1][0] != '-' &&
+ (func = avl_tree_search(args, &q)) != 0) {
+ func->arg_func(argv[i + 1]);
+ ++i;
+ } else if (flags && (func = avl_tree_search(flags, &q)) != 0) {
+ func->flag_func();
+
+ } else if (argv[i][0] != '-' && default_arg) {
+ default_arg(argv[i]);
+
+ } else {
+ wstdf("%S%Ferror:%S unknown flag '%s'\n", SGR_BOLD, COLOR_RED, SGR_RESET, argv[i]);
+ exit(-1);
+ }
+ }
+}
+
+
+void arg_register_arg(const char *flag, void(*func)(const char *))
+{
+ if (!args) {
+ args = new_avl_tree(&__arg_func_compare, 1);
+ }
+
+ arg_func_t *f = malloc(sizeof(arg_func_t));
+ f->name = flag;
+ f->arg_func = func;
+ avl_tree_insert(args, f);
+}
+
+
+void arg_register_flag(const char *flag, void(*func)(const char *))
+{
+ if (!flags) {
+ flags = new_avl_tree(&__arg_func_compare, 1);
+ }
+
+ arg_func_t *f = malloc(sizeof(arg_func_t));
+ f->name = flag;
+ f->flag_func = func;
+ avl_tree_insert(flags, f);
+}
+
+
+void arg_register_default(void (*func)(const char *))
+{
+ default_arg = func;
+}