summary refs log tree commit diff
path: root/util.c
diff options
context:
space:
mode:
authorQuentin Carbonneaux <quentin.carbonneaux@yale.edu>2016-08-14 21:57:27 -0700
committerQuentin Carbonneaux <quentin.carbonneaux@yale.edu>2016-08-15 22:55:08 -0700
commit3f8af2ba7b8f79bd577ca4f2fef5fb922494042d (patch)
treea24214b9ad4e601182cf75e947893c0f93367ef3 /util.c
parent5ad8a2c6fe90554bb6ad425597be732328fe0e41 (diff)
downloadroux-3f8af2ba7b8f79bd577ca4f2fef5fb922494042d.tar.gz
specify the allocation function in vnew
Diffstat (limited to 'util.c')
-rw-r--r--util.c20
1 files changed, 18 insertions, 2 deletions
diff --git a/util.c b/util.c
index 527f214..a99e2dd 100644
--- a/util.c
+++ b/util.c
@@ -6,6 +6,7 @@ typedef struct Vec Vec;
 
 struct Vec {
 	ulong mag;
+	void *(*alloc)();
 	size_t esz;
 	ulong cap;
 	union {
@@ -159,7 +160,7 @@ icpy(Ins *d, Ins *s, ulong n)
 }
 
 void *
-vnew(ulong len, size_t esz)
+vnew(ulong len, size_t esz, void *alloc(size_t))
 {
 	ulong cap;
 	Vec *v;
@@ -170,10 +171,24 @@ vnew(ulong len, size_t esz)
 	v->mag = VMag;
 	v->cap = cap;
 	v->esz = esz;
+	v->alloc = alloc;
 	return v + 1;
 }
 
 void
+vfree(void *p)
+{
+	Vec *v;
+
+	v = (Vec *)p - 1;
+	assert(v->mag == VMag);
+	if (v->alloc == emalloc) {
+		v->mag = 0;
+		free(v);
+	}
+}
+
+void
 vgrow(void *vp, ulong len)
 {
 	Vec *v;
@@ -183,8 +198,9 @@ vgrow(void *vp, ulong len)
 	assert(v+1 && v->mag == VMag);
 	if (v->cap >= len)
 		return;
-	v1 = vnew(len, v->esz);
+	v1 = vnew(len, v->esz, v->alloc);
 	memcpy(v1, v+1, v->cap * v->esz);
+	vfree(v+1);
 	*(Vec **)vp = v1;
 }