summaryrefslogtreecommitdiff
path: root/src/config.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/config.c')
-rw-r--r--src/config.c99
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