11.7Sabs/* $NetBSD: tsearch.c,v 1.7 2012/06/25 22:32:45 abs 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.7Sabs__RCSID("$NetBSD: tsearch.c,v 1.7 2012/06/25 22:32:45 abs 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.7Sabstsearch(const void *vkey, void **vrootp, 271.7Sabs int (*compar)(const void *, const void *)) 281.1Schristos{ 291.1Schristos node_t *q; 301.1Schristos node_t **rootp = (node_t **)vrootp; 311.3Slukem 321.3Slukem _DIAGASSERT(vkey != NULL); 331.3Slukem _DIAGASSERT(compar != NULL); 341.1Schristos 351.1Schristos if (rootp == NULL) 361.1Schristos return NULL; 371.1Schristos 381.1Schristos while (*rootp != NULL) { /* Knuth's T1: */ 391.1Schristos int r; 401.1Schristos 411.1Schristos if ((r = (*compar)(vkey, (*rootp)->key)) == 0) /* T2: */ 421.1Schristos return *rootp; /* we found it! */ 431.1Schristos 441.1Schristos rootp = (r < 0) ? 451.1Schristos &(*rootp)->llink : /* T3: follow left branch */ 461.1Schristos &(*rootp)->rlink; /* T4: follow right branch */ 471.1Schristos } 481.1Schristos 491.1Schristos q = malloc(sizeof(node_t)); /* T5: key not found */ 501.1Schristos if (q != 0) { /* make new node */ 511.1Schristos *rootp = q; /* link new node to old */ 521.5Schristos q->key = __UNCONST(vkey); /* initialize new node */ 531.1Schristos q->llink = q->rlink = NULL; 541.1Schristos } 551.1Schristos return q; 561.1Schristos} 57