Mercurial > repo
diff src/ploki/variable.c @ 4223:ac0403686959
<oerjan> rm -rf src/ploki; mv ploki src
author | HackBot |
---|---|
date | Fri, 20 Dec 2013 22:18:50 +0000 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/ploki/variable.c Fri Dec 20 22:18:50 2013 +0000 @@ -0,0 +1,72 @@ +#include "config.h" +#include "Str.h" +#include "strhash.h" +#include "variable.h" +#include "xmalloc.h" + +#include <assert.h> + +enum {MAGIC = 23}; + +static void delcookie(void *c) { + xfree(c); +} + +t_vr_container *vr_new(void (*del)(void *)) { + t_vr_container *v = xmalloc(1, sizeof *v); + v->data = xmalloc(v->size = MAGIC, sizeof *v->data); + v->length = 0; + v->del = del; + v->hash = sh_new(delcookie); + return v; +} + +void vr_delete(t_vr_container *v) { + assert(v != NULL); + if (v->hash) { + vr_freeze(v); + } + while (v->length) { + --v->length; + if (v->del) { + v->del(v->data[v->length]); + } + } + xfree(v->data); + xfree(v); +} + +t_vr_cookie vr_exists(const t_vr_container *v, const char *key, size_t len) { + t_vr_cookie *c; + assert(v->hash != NULL); + return (c = sh_get(v->hash, key, len)) ? *c : VR_NO_COOKIE; +} + +t_vr_cookie vr_register(t_vr_container *v, const char *key, size_t len, void *val) { + t_vr_cookie *cookie; + + assert(v->hash != NULL); + assert(sh_get(v->hash, key, len) == NULL); + + if (v->length >= v->size) { + v->data = xrealloc(v->data, v->size *= 2); + } + + cookie = xmalloc(1, sizeof *cookie); + v->data[*cookie = v->length++] = val; + sh_put(v->hash, key, len, cookie); + + return *cookie; +} + +void vr_freeze(t_vr_container *v) { + assert(v->hash != NULL); + sh_delete(v->hash); + v->hash = NULL; +} + +void *(vr_data)(const t_vr_container *v, t_vr_cookie c) { + assert(v->hash == NULL); + assert(c < v->length); + return v->data[c]; +}