From 68a62ad356603d64d537e231f06b5d9445e79abe Mon Sep 17 00:00:00 2001 From: kartofen Date: Fri, 23 Aug 2024 19:55:13 +0300 Subject: usefull commit message --- src/env.c | 78 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) create mode 100644 src/env.c (limited to 'src/env.c') diff --git a/src/env.c b/src/env.c new file mode 100644 index 0000000..1aa452b --- /dev/null +++ b/src/env.c @@ -0,0 +1,78 @@ +#include +#include + +#include "common.h" +#include "env.h" +#include "hashtable.h" + +#define ENV_TABLE_CAP (1 << 8) + +static unsigned long str_hash(char *str) +{ + unsigned long hash = 5381; + int c; + + while ((c = *str++)) + hash = ((hash << 5) + hash) + c; /* hash * 33 + c */ + + return hash; +} + +static size_t hash(void *key) +{ + return str_hash((char*)key); +} + +static bool equal(void *key1, void *key2) +{ + if(strcmp((char *)key1, (char*)key2) == 0) { + return true; + } + + return false; +} + +static void env_add_ref(env_t env); + +env_t env_create(env_t parent, env_destroy_func destroy_func) +{ + env_t env = malloc(sizeof(*env)); + env->destroy_func = destroy_func; + env->parent = parent; + env->refs = 0; + + env_add_ref(env); + + ERR_Z(env->table = hashtable_create(ENV_TABLE_CAP, hash, equal), + env_destroy(env)); + + return env; +} + +void env_destroy(env_t env) +{ + if(!env) return; + + env->refs--; + env_destroy(env->parent); + + if(env->refs > 0) return; + + + hashtable_for_each_item(env->table, item, i) { + env->destroy_func((char *)item->key, (value_t)item->data); + } + + hashtable_destroy(env->table); + free(env); +} + + +static void env_add_ref(env_t env) +{ + env->refs++; + + if(env->parent) { + env_add_ref(env->parent); + } +} -- cgit v1.2.3