tsearch.c revision 1.5
11.5Schristos/*	$NetBSD: tsearch.c,v 1.5 2005/11/29 03:12:00 christos Exp $	*/
21.1Schristos
31.1Schristos/*
41.1Schristos * Tree search generalized from Knuth (6.2.2) Algorithm T just like
51.1Schristos * the AT&T man page says.
61.1Schristos *
71.1Schristos * The node_t structure is for internal use only, lint doesn't grok it.
81.1Schristos *
91.1Schristos * Written by reading the System V Interface Definition, not the code.
101.1Schristos *
111.1Schristos * Totally public domain.
121.1Schristos */
131.1Schristos
141.1Schristos#include <sys/cdefs.h>
151.1Schristos#if defined(LIBC_SCCS) && !defined(lint)
161.5Schristos__RCSID("$NetBSD: tsearch.c,v 1.5 2005/11/29 03:12:00 christos Exp $");
171.1Schristos#endif /* LIBC_SCCS and not lint */
181.1Schristos
191.3Slukem#include <assert.h>
201.1Schristos#define _SEARCH_PRIVATE
211.1Schristos#include <search.h>
221.1Schristos#include <stdlib.h>
231.1Schristos
241.1Schristos/* find or insert datum into search tree */
251.1Schristosvoid *
261.1Schristostsearch(vkey, vrootp, compar)
271.1Schristos	const void *vkey;		/* key to be located */
281.1Schristos	void **vrootp;			/* address of tree root */
291.1Schristos	int (*compar) __P((const void *, const void *));
301.1Schristos{
311.1Schristos	node_t *q;
321.1Schristos	node_t **rootp = (node_t **)vrootp;
331.3Slukem
341.3Slukem	_DIAGASSERT(vkey != NULL);
351.3Slukem	_DIAGASSERT(compar != NULL);
361.1Schristos
371.1Schristos	if (rootp == NULL)
381.1Schristos		return NULL;
391.1Schristos
401.1Schristos	while (*rootp != NULL) {	/* Knuth's T1: */
411.1Schristos		int r;
421.1Schristos
431.1Schristos		if ((r = (*compar)(vkey, (*rootp)->key)) == 0)	/* T2: */
441.1Schristos			return *rootp;		/* we found it! */
451.1Schristos
461.1Schristos		rootp = (r < 0) ?
471.1Schristos		    &(*rootp)->llink :		/* T3: follow left branch */
481.1Schristos		    &(*rootp)->rlink;		/* T4: follow right branch */
491.1Schristos	}
501.1Schristos
511.1Schristos	q = malloc(sizeof(node_t));		/* T5: key not found */
521.1Schristos	if (q != 0) {				/* make new node */
531.1Schristos		*rootp = q;			/* link new node to old */
541.5Schristos		q->key = __UNCONST(vkey);	/* initialize new node */
551.1Schristos		q->llink = q->rlink = NULL;
561.1Schristos	}
571.1Schristos	return q;
581.1Schristos}
59