From: Matthias Kruk Date: Sun, 19 Jul 2020 11:20:40 +0000 (+0900) Subject: ccc: Add assoc_array type (quick-and-dirty associative array for prototyping) X-Git-Url: https://git.corax.cc/?a=commitdiff_plain;h=46b8269f058220a2b54c9c805aab770c15848e68;p=ccc ccc: Add assoc_array type (quick-and-dirty associative array for prototyping) --- diff --git a/src/assoc_array.c b/src/assoc_array.c new file mode 100644 index 0000000..5230d5b --- /dev/null +++ b/src/assoc_array.c @@ -0,0 +1,137 @@ +#include +#include +#include +#include + +/* + * assoc_array: Possibly the slowest associative array ever written + */ + +struct item { + struct item *next; + char *key; + void *data; +}; + +struct assoc_array { + struct item *head; +}; + +struct assoc_array *assoc_array_new(void) +{ + struct assoc_array *array; + + array = malloc(sizeof(*array)); + + if(array) { + memset(array, 0, sizeof(*array)); + } + + return(array); +} + +void assoc_array_free(struct assoc_array *array) +{ + struct item *cur; + + while((cur = array->head)) { + array->head = cur->next; + + free(cur->key); + free(cur); + } + + free(array); + + return; +} + +struct item* _assoc_array_find(struct assoc_array *array, const char *key) +{ + struct item *cur; + + for(cur = array->head; cur; cur = cur->next) { + if(strcmp(cur->key, key) == 0) { + return(cur); + } + } + + return(NULL); +} + +int assoc_array_get(struct assoc_array *array, const char *key, void **dst) +{ + struct item *item; + int ret_val; + + item = _assoc_array_find(array, key); + ret_val = -ENOENT; + + if(item) { + *dst = item->data; + ret_val = 0; + } + + return(ret_val); +} + +int assoc_array_set(struct assoc_array *array, const char *key, const void *data) +{ + struct item *item; + int ret_val; + + ret_val = -ENOMEM; + item = _assoc_array_find(array, key); + + if(item) { + item->data = (void*)data; + ret_val = 0; + } else { + item = malloc(sizeof(*item)); + + if(item) { + item->key = malloc(strlen(key) + 1); + + if(item->key) { + snprintf(item->key, strlen(key) + 1, "%s", key); + + item->data = (void*)data; + item->next = array->head; + array->head = item; + + ret_val = 0; + } else { + free(item); + } + } + } + + return(ret_val); +} + +int assoc_array_drop(struct assoc_array *array, const char *key) +{ + struct item **cur; + int ret_val; + + ret_val = -ENOENT; + + for(cur = &(array->head); *cur; cur = &((*cur)->next)) { + if(strcmp((*cur)->key, key) == 0) { + struct item *del; + + del = *cur; + *cur = del->next; + + if(del->key) { + free(del->key); + } + + free(del); + ret_val = 0; + break; + } + } + + return(ret_val); +} diff --git a/src/assoc_array.h b/src/assoc_array.h new file mode 100644 index 0000000..978582a --- /dev/null +++ b/src/assoc_array.h @@ -0,0 +1,13 @@ +#ifndef ASSOC_ARRAY_H +#define ASSOC_ARRAY_H + +struct assoc_array; + +struct assoc_array* assoc_array_new(void); +void assoc_array_free(struct assoc_array*); + +int assoc_array_get(struct assoc_array*, const char*, void**); +int assoc_array_set(struct assoc_array*, const char*, const void*); +int assoc_array_drop(struct assoc_array*, const char*); + +#endif /* ASSOC_ARRAY_H */