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