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