From b54ace5cd8a873be804529f7b8221ee62600d17d Mon Sep 17 00:00:00 2001 From: David Timber Date: Tue, 15 Sep 2020 22:14:19 +0930 Subject: Add strmap --- src/strmap.c | 131 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 131 insertions(+) create mode 100644 src/strmap.c (limited to 'src/strmap.c') diff --git a/src/strmap.c b/src/strmap.c new file mode 100644 index 0000000..81d19b5 --- /dev/null +++ b/src/strmap.c @@ -0,0 +1,131 @@ +#include "strmap.h" +#include "util_rt.h" + +#include +#include + + +static int strmap_cmp_f (const void *a, const void *b) { + return strcmp( + ((const prne_strmap_tuple_t *)a)->key, + ((const prne_strmap_tuple_t *)b)->key); +} + +void prne_init_strmap (prne_strmap_t *map) { + prne_memzero(map, sizeof(prne_strmap_t)); +} + +void prne_free_strmap (prne_strmap_t *map) { + if (map == NULL) { + return; + } + prne_strmap_clear(map); +} + +void prne_strmap_clear (prne_strmap_t *map) { + for (size_t i = 0; i < map->size; i += 1) { + prne_free((void*)map->tbl[i].key); + } + prne_free(map->tbl); + + prne_memzero(map, sizeof(prne_strmap_t)); +} + +const prne_strmap_tuple_t *prne_strmap_insert ( + prne_strmap_t *map, + const char* key, + void *val) +{ + prne_strmap_tuple_t *ret; + prne_strmap_tuple_t t; + + t.key = key; + t.val = val; + ret = (prne_strmap_tuple_t*)bsearch( + &t, + map->tbl, + map->size, + sizeof(prne_strmap_tuple_t), + strmap_cmp_f); + if (ret == NULL) { + const size_t sl = strlen(key); + void *ny_tbl; + + t.key = prne_alloc_str(sl); + if (t.key == NULL) { + return NULL; + } + memcpy((void*)t.key, key, sl + 1); + ny_tbl = (prne_strmap_tuple_t*)prne_realloc( + map->tbl, + sizeof(prne_strmap_tuple_t), + map->size + 1); + if (ny_tbl == NULL) { + prne_free((void*)t.key); + return NULL; + } + map->tbl = (prne_strmap_tuple_t*)ny_tbl; + map->tbl[map->size] = t; + map->size += 1; + + qsort(map->tbl, map->size, sizeof(prne_strmap_tuple_t), strmap_cmp_f); + ret = (prne_strmap_tuple_t*)prne_strmap_lookup(map, key); + prne_dbgtrap(ret != NULL); + } + else { + ret->val = t.val; + } + + return ret; +} + +void prne_strmap_erase (prne_strmap_t *map, const char* key) { + prne_strmap_tuple_t t, *e; + + t.key = key; + t.val = NULL; + e = (prne_strmap_tuple_t*)bsearch( + &t, + map->tbl, + map->size, + sizeof(prne_strmap_tuple_t), + strmap_cmp_f); + if (e == NULL) { + return; + } + prne_free((void*)e->key); + e->key = NULL; + if (map->size == 1) { + prne_strmap_clear(map); + } + else { + void *ny; + + memmove( + e, + e + 1, + sizeof(prne_strmap_tuple_t) * (map->size - 1 - (e - map->tbl))); + map->size -= 1; + ny = prne_realloc(map->tbl, sizeof(prne_strmap_tuple_t), map->size); + if (ny != NULL) { + map->tbl = (prne_strmap_tuple_t*)ny; + } + } +} + +const prne_strmap_tuple_t *prne_strmap_lookup ( + prne_strmap_t *map, + const char* key) +{ + prne_strmap_tuple_t t; + + t.key = key; + t.val = NULL; + + return (const prne_strmap_tuple_t*)bsearch( + &t, + map->tbl, + map->size, + sizeof(prne_strmap_tuple_t), + strmap_cmp_f); +} -- cgit