#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); } }