#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; }