diff options
Diffstat (limited to 'src/config.c')
| -rw-r--r-- | src/config.c | 99 |
1 files changed, 99 insertions, 0 deletions
diff --git a/src/config.c b/src/config.c new file mode 100644 index 0000000..ef55387 --- /dev/null +++ b/src/config.c @@ -0,0 +1,99 @@ +#include <ctype.h> +#include <pthread.h> +#include <stdbool.h> +#include <stddef.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +// + +// . +// . +// warning: slices are not NULL-terminated, and should not be modified! +// strdup them if you need to make modifications. +typedef struct slice { + char* ref; + size_t len; +} slice_t; + +typedef struct pair { + slice_t key; + slice_t value; +} pair_t; + +pair_t* global_arg_table = NULL; +size_t args_count = 0; + +void parse_arguments(int argc, char** argv) { + if (argc <= 1) return; + + global_arg_table = calloc(argc - 1, sizeof(pair_t)); + + for (int i = 1; i < argc; i++) { + char* current = argv[ i ]; + char* eq_sign = strchr(current, '='); + if (eq_sign == NULL) { + printf( + "argument error: " + "moonpaste expects named arguments with values. example: 'foo=bar'\n" + " in '%s'", + current); + exit(1); + } + + // key + size_t key_len = eq_sign - current; + size_t key_start = 0; + while (key_start < key_len && isspace(current[ key_start ])) { // trim start + key_start++; + key_len--; + } + while (key_len > 0 && isspace(current[ key_start + key_len - 1 ])) { // trim end + key_len--; + } + + if (key_len == 0) { + printf( + "argument error: empty key\n" + " in '%s'\n", + current); + exit(1); + } + + // value + size_t value_start = eq_sign - current + 1; + size_t value_len = strlen(current) - value_start; + while (value_start < strlen(current) && isspace(current[ value_start ])) { // trim start + value_start++; + value_len--; + } + while (value_len > 0 && isspace(current[ value_start + value_len - 1 ])) { // trim end + value_len--; + } + + // store + global_arg_table[ args_count ].key.ref = current + key_start; + global_arg_table[ args_count ].key.len = key_len; + global_arg_table[ args_count ].value.ref = current + value_start; + global_arg_table[ args_count ].value.len = value_len; + args_count++; + } +} + +// get a config option's value from argv. +// if mandatory == true -> program errors +char* get_config(char* key, bool mandatory) { + size_t len = strlen(key); + for (int i = 0; i < args_count; i++) { + if (global_arg_table[ i ].key.len != len) continue; + if (strncmp(key, global_arg_table[ i ].key.ref, len) != 0) continue; + char* new_str = malloc(global_arg_table[ i ].value.len); + memcpy(new_str, global_arg_table[ i ].value.ref, global_arg_table[ i ].value.len); + return new_str; // free me! + } + + if (!mandatory) return NULL; + fprintf(stderr, "program expected argument %s but did not receive it.\n", key); + // __builtin_unreachable(); + return NULL; +}
\ No newline at end of file |
