tsearch.c revision 1.3
11.3Slukem/*	$NetBSD: tsearch.c,v 1.3 1999/09/16 11:45:37 lukem 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.3Slukem__RCSID("$NetBSD: tsearch.c,v 1.3 1999/09/16 11:45:37 lukem 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.3Slukem#ifdef _DIAGNOSTIC
371.3Slukem	if (vkey == NULL || compar == NULL)
381.3Slukem		return (NULL);
391.3Slukem#endif
401.1Schristos
411.1Schristos	if (rootp == NULL)
421.1Schristos		return NULL;
431.1Schristos
441.1Schristos	while (*rootp != NULL) {	/* Knuth's T1: */
451.1Schristos		int r;
461.1Schristos
471.1Schristos		if ((r = (*compar)(vkey, (*rootp)->key)) == 0)	/* T2: */
481.1Schristos			return *rootp;		/* we found it! */
491.1Schristos
501.1Schristos		rootp = (r < 0) ?
511.1Schristos		    &(*rootp)->llink :		/* T3: follow left branch */
521.1Schristos		    &(*rootp)->rlink;		/* T4: follow right branch */
531.1Schristos	}
541.1Schristos
551.1Schristos	q = malloc(sizeof(node_t));		/* T5: key not found */
561.1Schristos	if (q != 0) {				/* make new node */
571.1Schristos		*rootp = q;			/* link new node to old */
581.2Schristos		/* LINTED const castaway ok */
591.1Schristos		q->key = (void *)vkey;		/* initialize new node */
601.1Schristos		q->llink = q->rlink = NULL;
611.1Schristos	}
621.1Schristos	return q;
631.1Schristos}
64