2 #define _XOPEN_SOURCE 700
16 static struct e tab[100];
17 static struct e *cur = tab;
19 static int cmp(const void *a, const void *b)
21 return strcmp(((struct e*)a)->k, ((struct e*)b)->k);
24 static int wantc = 'a';
25 static void act(const void *node, VISIT v, int d)
27 struct e *e = *(void**)node;
31 t_error("preorder visited node \"%s\" before \"%c\"\n", e->k, wantc);
34 t_error("endorder visited node \"%s\" after \"%c\"\n", e->k, wantc);
37 t_error("postorder visited node \"%s\", wanted \"%c\"\n", e->k, wantc);
40 t_error("visited leaf node \"%s\", wanted \"%c\"\n", e->k, wantc);
41 if (v == postorder || v == leaf)
45 static const void *parent;
46 static char *searchkey;
47 static void getparent(const void *node, VISIT v, int d)
50 struct e *e = *(void**)node;
52 if (v == preorder || v == leaf)
53 if (strcmp(searchkey, e->k) == 0)
55 if (v == preorder || v == postorder)
59 struct e *get(char *k)
61 void **p = tfind(&(struct e){.k = k}, &root, cmp);
66 struct e *set(char *k, int v)
73 p = tsearch(cur++, &root, cmp);
74 if (!p || strcmp(((struct e*)*p)->k, k) != 0)
75 t_error("tsearch %s %d failed\n", k, v);
85 void *p = tdelete(&(struct e){.k = k}, &root, cmp);
106 t_error("tfind a failed\n");
108 t_error("tfind z should fail\n");
111 t_error("tsearch g 9 returned data %d, wanted 7\n", e->v);
114 t_error("tsearch g 9 returned data %d, wanted 7\n", e->v);
117 t_error("tsearch i 9 returned data %d, wanted 9\n", e->v);
119 t_error("tdelete foobar should fail\n");
123 t_error("twalk did not visit all nodes (wanted 'j' got '%c')\n", wantc);
125 twalk(root, getparent);
127 t_error("twalk search for key \"%s\" failed\n", searchkey);
130 t_error("tdelete h failed to return parent (got %p wanted %p)\n", p, parent);
134 t_error("tdelete root \"%s\" failed (returned 0)\n", e->k);
136 for (; count; count--) {
138 if (!tdelete(e, &root, cmp))
139 t_error("tdelete k=%s failed during destruction\n", e->k);
142 t_error("tree destruction failed: root is nonzero %p\n", root);