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