aboutsummaryrefslogtreecommitdiff
path: root/lib/arg
diff options
context:
space:
mode:
authorNathan Reiner <nathan@nathanreiner.xyz>2023-01-15 01:13:51 +0100
committerNathan Reiner <nathan@nathanreiner.xyz>2023-01-15 01:13:51 +0100
commit3f79b7bd553a52fca7a098f5195b406ff9970491 (patch)
tree99d0399141e7894219fe7a0deed1ccadb226b9c9 /lib/arg
parent919450dc7d965c4067287e1ece3ceafdde8ff5a9 (diff)
add list and static library builder
Diffstat (limited to 'lib/arg')
-rw-r--r--lib/arg/Makefile3
-rw-r--r--lib/arg/arg.c85
-rw-r--r--lib/arg/arg.h9
3 files changed, 97 insertions, 0 deletions
diff --git a/lib/arg/Makefile b/lib/arg/Makefile
new file mode 100644
index 0000000..384f797
--- /dev/null
+++ b/lib/arg/Makefile
@@ -0,0 +1,3 @@
+unit_test:
+ gcc test.c arg.c ../io/io.c ../aec/aec.c ../malloc/malloc.c ../avl_tree/avl_tree.c ../cstr/cstr.c ../env/env.c ../sys/start.S -o test -static -nostdlib -fno-stack-protector -Wno-implicit-function-declaration -g
+ ./test
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;
+}
diff --git a/lib/arg/arg.h b/lib/arg/arg.h
new file mode 100644
index 0000000..5bffb33
--- /dev/null
+++ b/lib/arg/arg.h
@@ -0,0 +1,9 @@
+#ifndef ARG_H
+#define ARG_H
+
+void arg_parse_arg(int argc, const char **argv);
+void arg_register_flag(const char *flag, void(*func)());
+void arg_register_arg(const char *flag, void(*func)(const char *));
+void arg_register_default(void (*func)(const char *));
+
+#endif