162321Salfred/*	$NetBSD: tsearch.c,v 1.3 1999/09/16 11:45:37 lukem Exp $	*/
262321Salfred
362321Salfred/*
462321Salfred * Tree search generalized from Knuth (6.2.2) Algorithm T just like
562321Salfred * the AT&T man page says.
662321Salfred *
762321Salfred * The node_t structure is for internal use only, lint doesn't grok it.
862321Salfred *
962321Salfred * Written by reading the System V Interface Definition, not the code.
1062321Salfred *
1162321Salfred * Totally public domain.
1262321Salfred */
1362321Salfred
1462321Salfred#include <sys/cdefs.h>
1592986Sobrien#if 0
1662321Salfred#if defined(LIBC_SCCS) && !defined(lint)
1762321Salfred__RCSID("$NetBSD: tsearch.c,v 1.3 1999/09/16 11:45:37 lukem Exp $");
1862321Salfred#endif /* LIBC_SCCS and not lint */
1992986Sobrien#endif
2092986Sobrien__FBSDID("$FreeBSD$");
2162321Salfred
2262321Salfred#define _SEARCH_PRIVATE
2362321Salfred#include <search.h>
2462321Salfred#include <stdlib.h>
2562321Salfred
2662321Salfred/* find or insert datum into search tree */
2762321Salfredvoid *
2862321Salfredtsearch(vkey, vrootp, compar)
2962321Salfred	const void *vkey;		/* key to be located */
3062321Salfred	void **vrootp;			/* address of tree root */
3192905Sobrien	int (*compar)(const void *, const void *);
3262321Salfred{
3362321Salfred	node_t *q;
3462321Salfred	node_t **rootp = (node_t **)vrootp;
3562321Salfred
3662321Salfred	if (rootp == NULL)
3762321Salfred		return NULL;
3862321Salfred
3962321Salfred	while (*rootp != NULL) {	/* Knuth's T1: */
4062321Salfred		int r;
4162321Salfred
4262321Salfred		if ((r = (*compar)(vkey, (*rootp)->key)) == 0)	/* T2: */
4362321Salfred			return *rootp;		/* we found it! */
4462321Salfred
4562321Salfred		rootp = (r < 0) ?
4662321Salfred		    &(*rootp)->llink :		/* T3: follow left branch */
4762321Salfred		    &(*rootp)->rlink;		/* T4: follow right branch */
4862321Salfred	}
4962321Salfred
5062321Salfred	q = malloc(sizeof(node_t));		/* T5: key not found */
5162321Salfred	if (q != 0) {				/* make new node */
5262321Salfred		*rootp = q;			/* link new node to old */
5362321Salfred		/* LINTED const castaway ok */
5462321Salfred		q->key = (void *)vkey;		/* initialize new node */
5562321Salfred		q->llink = q->rlink = NULL;
5662321Salfred	}
5762321Salfred	return q;
5862321Salfred}
59