|
Szabolcs Nagy |
54f9b9 |
#ifndef _XOPEN_SOURCE
|
|
Szabolcs Nagy |
54f9b9 |
#define _XOPEN_SOURCE 700
|
|
Szabolcs Nagy |
54f9b9 |
#endif
|
|
Szabolcs Nagy |
132e38 |
#include <stdlib.h>
|
|
Szabolcs Nagy |
132e38 |
#include <string.h>
|
|
Szabolcs Nagy |
132e38 |
#include <search.h>
|
|
Szabolcs Nagy |
132e38 |
#include "test.h"
|
|
Szabolcs Nagy |
132e38 |
|
|
Szabolcs Nagy |
132e38 |
struct e {
|
|
Szabolcs Nagy |
132e38 |
char *k;
|
|
Szabolcs Nagy |
132e38 |
int v;
|
|
Szabolcs Nagy |
132e38 |
};
|
|
Szabolcs Nagy |
132e38 |
|
|
Szabolcs Nagy |
132e38 |
static void *root;
|
|
Szabolcs Nagy |
132e38 |
static struct e tab[100];
|
|
Szabolcs Nagy |
132e38 |
static struct e *cur = tab;
|
|
Szabolcs Nagy |
132e38 |
|
|
Szabolcs Nagy |
132e38 |
static int cmp(const void *a, const void *b)
|
|
Szabolcs Nagy |
132e38 |
{
|
|
Szabolcs Nagy |
132e38 |
return strcmp(((struct e*)a)->k, ((struct e*)b)->k);
|
|
Szabolcs Nagy |
132e38 |
}
|
|
Szabolcs Nagy |
132e38 |
|
|
Szabolcs Nagy |
132e38 |
static int wantc = 'a';
|
|
Szabolcs Nagy |
132e38 |
static void act(const void *node, VISIT v, int d)
|
|
Szabolcs Nagy |
132e38 |
{
|
|
Szabolcs Nagy |
132e38 |
struct e *e = *(struct e **)node;
|
|
Szabolcs Nagy |
132e38 |
|
|
Szabolcs Nagy |
132e38 |
if (v == preorder)
|
|
Szabolcs Nagy |
132e38 |
if (e->k[0] < wantc)
|
|
Szabolcs Nagy |
132e38 |
t_error("preorder visited node \"%s\" before \"%c\"\n", e->k, wantc);
|
|
Szabolcs Nagy |
132e38 |
if (v == endorder)
|
|
Szabolcs Nagy |
132e38 |
if (e->k[0] > wantc)
|
|
Szabolcs Nagy |
132e38 |
t_error("endorder visited node \"%s\" after \"%c\"\n", e->k, wantc);
|
|
Szabolcs Nagy |
132e38 |
if (v == postorder)
|
|
Szabolcs Nagy |
132e38 |
if (e->k[0] != wantc)
|
|
Szabolcs Nagy |
132e38 |
t_error("postorder visited node \"%s\", wanted \"%c\"\n", e->k, wantc);
|
|
Szabolcs Nagy |
132e38 |
if (v == leaf)
|
|
Szabolcs Nagy |
132e38 |
if (e->k[0] != wantc)
|
|
Szabolcs Nagy |
132e38 |
t_error("visited leaf node \"%s\", wanted \"%c\"\n", e->k, wantc);
|
|
Szabolcs Nagy |
132e38 |
if (v == postorder || v == leaf)
|
|
Szabolcs Nagy |
132e38 |
wantc++;
|
|
Szabolcs Nagy |
132e38 |
}
|
|
Szabolcs Nagy |
132e38 |
|
|
Szabolcs Nagy |
132e38 |
static const void *parent;
|
|
Szabolcs Nagy |
132e38 |
static char *searchkey;
|
|
Szabolcs Nagy |
132e38 |
static void getparent(const void *node, VISIT v, int d)
|
|
Szabolcs Nagy |
132e38 |
{
|
|
Szabolcs Nagy |
132e38 |
static const void *p;
|
|
Szabolcs Nagy |
132e38 |
struct e *e = *(struct e **)node;
|
|
Szabolcs Nagy |
132e38 |
|
|
Szabolcs Nagy |
132e38 |
if (v == preorder || v == leaf)
|
|
Szabolcs Nagy |
132e38 |
if (strcmp(searchkey, e->k) == 0)
|
|
Szabolcs Nagy |
132e38 |
parent = p;
|
|
Szabolcs Nagy |
132e38 |
if (v == preorder || v == postorder)
|
|
Szabolcs Nagy |
132e38 |
p = node;
|
|
Szabolcs Nagy |
132e38 |
}
|
|
Szabolcs Nagy |
132e38 |
|
|
Szabolcs Nagy |
132e38 |
struct e *set(char *k, int v)
|
|
Szabolcs Nagy |
132e38 |
{
|
|
Szabolcs Nagy |
132e38 |
struct e **p;
|
|
Szabolcs Nagy |
132e38 |
cur->k = k;
|
|
Szabolcs Nagy |
132e38 |
cur->v = v;
|
|
Szabolcs Nagy |
132e38 |
p = tsearch(cur++, &root, cmp);
|
|
Szabolcs Nagy |
132e38 |
if (!p || strcmp((*p)->k, k) != 0)
|
|
Szabolcs Nagy |
132e38 |
t_error("tsearch %s %d failed\n", k, v);
|
|
Szabolcs Nagy |
132e38 |
if (!p)
|
|
Szabolcs Nagy |
132e38 |
return 0;
|
|
Szabolcs Nagy |
132e38 |
return *p;
|
|
Szabolcs Nagy |
132e38 |
}
|
|
Szabolcs Nagy |
132e38 |
|
|
Szabolcs Nagy |
132e38 |
struct e **get(char *k)
|
|
Szabolcs Nagy |
132e38 |
{
|
|
Szabolcs Nagy |
132e38 |
return tfind(&(struct e){.k = k}, &root, cmp);
|
|
Szabolcs Nagy |
132e38 |
}
|
|
Szabolcs Nagy |
132e38 |
|
|
Szabolcs Nagy |
132e38 |
struct e **del(char *k)
|
|
Szabolcs Nagy |
132e38 |
{
|
|
Szabolcs Nagy |
132e38 |
return tdelete(&(struct e){.k = k}, &root, cmp);
|
|
Szabolcs Nagy |
132e38 |
}
|
|
Szabolcs Nagy |
132e38 |
|
|
Szabolcs Nagy |
132e38 |
int main() {
|
|
Szabolcs Nagy |
132e38 |
struct e *e;
|
|
Szabolcs Nagy |
132e38 |
struct e **p;
|
|
Szabolcs Nagy |
132e38 |
|
|
Szabolcs Nagy |
132e38 |
set("f", 6);
|
|
Szabolcs Nagy |
132e38 |
set("b", 2);
|
|
Szabolcs Nagy |
132e38 |
set("c", 3);
|
|
Szabolcs Nagy |
132e38 |
set("e", 5);
|
|
Szabolcs Nagy |
132e38 |
set("h", 8);
|
|
Szabolcs Nagy |
132e38 |
set("g", 7);
|
|
Szabolcs Nagy |
132e38 |
set("a", 1);
|
|
Szabolcs Nagy |
132e38 |
set("d", 4);
|
|
Szabolcs Nagy |
132e38 |
|
|
Szabolcs Nagy |
132e38 |
p = get("a");
|
|
Szabolcs Nagy |
132e38 |
if (!p || (*p)->v != 1)
|
|
Szabolcs Nagy |
132e38 |
t_error("tfind a failed\n");
|
|
Szabolcs Nagy |
132e38 |
if (get("z"))
|
|
Szabolcs Nagy |
132e38 |
t_error("tfind z should fail\n");
|
|
Szabolcs Nagy |
132e38 |
e = set("g", 9);
|
|
Szabolcs Nagy |
132e38 |
if (e && e->v != 7)
|
|
Szabolcs Nagy |
132e38 |
t_error("tsearch g 9 returned data %d, wanted 7\n", e->v);
|
|
Szabolcs Nagy |
132e38 |
e = set("g", 9);
|
|
Szabolcs Nagy |
132e38 |
if (e && e->v != 7)
|
|
Szabolcs Nagy |
132e38 |
t_error("tsearch g 9 returned data %d, wanted 7\n", e->v);
|
|
Szabolcs Nagy |
132e38 |
e = set("i", 9);
|
|
Szabolcs Nagy |
132e38 |
if (e && e->v != 9)
|
|
Szabolcs Nagy |
132e38 |
t_error("tsearch i 9 returned data %d, wanted 9\n", e->v);
|
|
Szabolcs Nagy |
132e38 |
if (del("foobar"))
|
|
Szabolcs Nagy |
132e38 |
t_error("tdelete foobar should fail\n");
|
|
Szabolcs Nagy |
132e38 |
|
|
Szabolcs Nagy |
132e38 |
twalk(root, act);
|
|
Szabolcs Nagy |
132e38 |
if (wantc!='j')
|
|
Szabolcs Nagy |
132e38 |
t_error("twalk did not visit all nodes (wanted 'j' got '%c')\n", wantc);
|
|
Szabolcs Nagy |
132e38 |
searchkey = "h";
|
|
Szabolcs Nagy |
132e38 |
twalk(root, getparent);
|
|
Szabolcs Nagy |
132e38 |
if (parent == 0)
|
|
Szabolcs Nagy |
132e38 |
t_error("twalk search for key \"%s\" failed\n", searchkey);
|
|
Szabolcs Nagy |
132e38 |
p = del("h");
|
|
Szabolcs Nagy |
132e38 |
if (p != parent)
|
|
Szabolcs Nagy |
132e38 |
t_error("tdelete h failed to return parent (got %p wanted %p)\n", p, parent);
|
|
Szabolcs Nagy |
132e38 |
|
|
Szabolcs Nagy |
132e38 |
p = root;
|
|
Szabolcs Nagy |
132e38 |
if (!del((*p)->k))
|
|
Szabolcs Nagy |
132e38 |
t_error("tdelete root \"%s\" failed (returned 0)\n", (*p)->k);
|
|
Szabolcs Nagy |
132e38 |
|
|
Szabolcs Nagy |
132e38 |
return t_status;
|
|
Szabolcs Nagy |
132e38 |
}
|