view src/ploki/variable.c @ 12292:d51f2100210c draft

<kspalaiologos> `` cat <<<"asmbf && bfi output.b" > /hackenv/ibin/asmbf
author HackEso <hackeso@esolangs.org>
date Thu, 02 Jan 2020 15:38:21 +0000
parents ac0403686959
children
line wrap: on
line source

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