int v;
};
+static int count;
static void *root;
static struct e tab[100];
static struct e *cur = tab;
static int wantc = 'a';
static void act(const void *node, VISIT v, int d)
{
- struct e *e = *(struct e **)node;
+ struct e *e = *(void**)node;
if (v == preorder)
if (e->k[0] < wantc)
static void getparent(const void *node, VISIT v, int d)
{
static const void *p;
- struct e *e = *(struct e **)node;
+ struct e *e = *(void**)node;
if (v == preorder || v == leaf)
if (strcmp(searchkey, e->k) == 0)
p = node;
}
+struct e *get(char *k)
+{
+ void **p = tfind(&(struct e){.k = k}, &root, cmp);
+ if (!p) return 0;
+ return *p;
+}
+
struct e *set(char *k, int v)
{
- struct e **p;
+ void **p;
cur->k = k;
cur->v = v;
+ if (!get(k))
+ count++;
p = tsearch(cur++, &root, cmp);
- if (!p || strcmp((*p)->k, k) != 0)
+ if (!p || strcmp(((struct e*)*p)->k, k) != 0)
t_error("tsearch %s %d failed\n", k, v);
- if (!p)
+ if (!p) {
+ count--;
return 0;
+ }
return *p;
}
-struct e **get(char *k)
-{
- return tfind(&(struct e){.k = k}, &root, cmp);
-}
-
-struct e **del(char *k)
+void *del(char *k)
{
- return tdelete(&(struct e){.k = k}, &root, cmp);
+ void *p = tdelete(&(struct e){.k = k}, &root, cmp);
+ if (p)
+ count--;
+ return p;
}
int main() {
struct e *e;
- struct e **p;
+ void *p;
set("f", 6);
set("b", 2);
set("a", 1);
set("d", 4);
- p = get("a");
- if (!p || (*p)->v != 1)
+ e = get("a");
+ if (!e || e->v != 1)
t_error("tfind a failed\n");
if (get("z"))
t_error("tfind z should fail\n");
if (p != parent)
t_error("tdelete h failed to return parent (got %p wanted %p)\n", p, parent);
- p = root;
- if (!del((*p)->k))
- t_error("tdelete root \"%s\" failed (returned 0)\n", (*p)->k);
+ e = *(void**)root;
+ if (!del(e->k))
+ t_error("tdelete root \"%s\" failed (returned 0)\n", e->k);
+
+ for (; count; count--) {
+ e = *(void**)root;
+ if (!tdelete(e, &root, cmp))
+ t_error("tdelete k=%s failed during destruction\n", e->k);
+ }
+ if (root)
+ t_error("tree destruction failed: root is nonzero %p\n", root);
return t_status;
}