summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorderaadt <>1997-06-13 23:41:37 +0000
committerderaadt <>1997-06-13 23:41:37 +0000
commit737b5724f4dd92147b79a987347fe5278fbfa6ac (patch)
treebccfd6d24168ffe9910ba192aaf5e1928cc5ac7f
parentdd2713d24981403d92672e7e2709bd887b9ad7c6 (diff)
downloadopenbsd-737b5724f4dd92147b79a987347fe5278fbfa6ac.tar.gz
openbsd-737b5724f4dd92147b79a987347fe5278fbfa6ac.tar.bz2
openbsd-737b5724f4dd92147b79a987347fe5278fbfa6ac.zip
PD tsearch as reqd by xpg; by esr
-rw-r--r--src/lib/libc/stdlib/Makefile.inc8
-rw-r--r--src/lib/libc/stdlib/bsearch.34
-rw-r--r--src/lib/libc/stdlib/tfind.c41
-rw-r--r--src/lib/libc/stdlib/tsearch.c125
4 files changed, 174 insertions, 4 deletions
diff --git a/src/lib/libc/stdlib/Makefile.inc b/src/lib/libc/stdlib/Makefile.inc
index f224baed54..4c7f9db834 100644
--- a/src/lib/libc/stdlib/Makefile.inc
+++ b/src/lib/libc/stdlib/Makefile.inc
@@ -1,4 +1,4 @@
1# $OpenBSD: Makefile.inc,v 1.6 1996/08/21 03:47:21 tholo Exp $ 1# $OpenBDS: Makefile.inc,v 1.6 1996/08/21 03:47:21 tholo Exp $
2 2
3# stdlib sources 3# stdlib sources
4.PATH: ${.CURDIR}/arch/${MACHINE_ARCH}/stdlib ${.CURDIR}/stdlib 4.PATH: ${.CURDIR}/arch/${MACHINE_ARCH}/stdlib ${.CURDIR}/stdlib
@@ -7,6 +7,7 @@ SRCS+= a64l.c abort.c atexit.c atoi.c atof.c atol.c bsearch.c calloc.c \
7 cfree.c exit.c getenv.c getopt.c heapsort.c l64a.c malloc.c merge.c \ 7 cfree.c exit.c getenv.c getopt.c heapsort.c l64a.c malloc.c merge.c \
8 multibyte.c putenv.c qsort.c radixsort.c rand.c random.c realpath.c \ 8 multibyte.c putenv.c qsort.c radixsort.c rand.c random.c realpath.c \
9 setenv.c strtod.c strtol.c strtoq.c strtoul.c strtouq.c system.c \ 9 setenv.c strtod.c strtol.c strtoq.c strtoul.c strtouq.c system.c \
10 tfind.c tsearch.c \
10 _rand48.c drand48.c erand48.c jrand48.c lcong48.c lrand48.c \ 11 _rand48.c drand48.c erand48.c jrand48.c lcong48.c lrand48.c \
11 mrand48.c nrand48.c seed48.c srand48.c qabs.c qdiv.c 12 mrand48.c nrand48.c seed48.c srand48.c qabs.c qdiv.c
12 13
@@ -34,7 +35,7 @@ SRCS+= abs.c div.c labs.c ldiv.c
34MAN+= abort.3 abs.3 alloca.3 atexit.3 atof.3 atoi.3 atol.3 bsearch.3 \ 35MAN+= abort.3 abs.3 alloca.3 atexit.3 atof.3 atoi.3 atol.3 bsearch.3 \
35 calloc.3 div.3 exit.3 getenv.3 getopt.3 labs.3 ldiv.3 malloc.3 \ 36 calloc.3 div.3 exit.3 getenv.3 getopt.3 labs.3 ldiv.3 malloc.3 \
36 memory.3 qabs.3 qdiv.3 qsort.3 radixsort.3 rand48.3 rand.3 \ 37 memory.3 qabs.3 qdiv.3 qsort.3 radixsort.3 rand48.3 rand.3 \
37 random.3 realpath.3 strtod.3 strtol.3 strtoul.3 system.3 38 random.3 realpath.3 strtod.3 strtol.3 strtoul.3 system.3 tsearch.3
38 39
39MLINKS+=getenv.3 setenv.3 getenv.3 unsetenv.3 getenv.3 putenv.3 40MLINKS+=getenv.3 setenv.3 getenv.3 unsetenv.3 getenv.3 putenv.3
40MLINKS+=malloc.3 free.3 malloc.3 realloc.3 41MLINKS+=malloc.3 free.3 malloc.3 realloc.3
@@ -47,3 +48,6 @@ MLINKS+=rand48.3 mrand48.3 rand48.3 nrand48.3 rand48.3 jrand48.3
47MLINKS+=rand48.3 srand48.3 rand48.3 seed48.3 rand48.3 lcong48.3 48MLINKS+=rand48.3 srand48.3 rand48.3 seed48.3 rand48.3 lcong48.3
48MLINKS+=strtol.3 strtoq.3 49MLINKS+=strtol.3 strtoq.3
49MLINKS+=strtoul.3 strtouq.3 50MLINKS+=strtoul.3 strtouq.3
51MLINKS+=tsearch.3 tfind.3
52MLINKS+=tsearch.3 tdelete.3
53MLINKS+=tsearch.3 twalk.3
diff --git a/src/lib/libc/stdlib/bsearch.3 b/src/lib/libc/stdlib/bsearch.3
index 7cfa7162d3..570a4227b4 100644
--- a/src/lib/libc/stdlib/bsearch.3
+++ b/src/lib/libc/stdlib/bsearch.3
@@ -33,7 +33,7 @@
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE. 34.\" SUCH DAMAGE.
35.\" 35.\"
36.\" $OpenBSD: bsearch.3,v 1.2 1996/08/10 04:52:52 tholo Exp $ 36.\" $OpenBSD: bsearch.3,v 1.3 1997/06/13 23:41:35 deraadt Exp $
37.\" 37.\"
38.Dd April 19, 1994 38.Dd April 19, 1994
39.Dt BSEARCH 3 39.Dt BSEARCH 3
@@ -82,7 +82,7 @@ If two members compare as equal, which member is matched is unspecified.
82.Xr db 3 , 82.Xr db 3 ,
83.Xr lsearch 3 , 83.Xr lsearch 3 ,
84.Xr qsort 3 , 84.Xr qsort 3 ,
85.\" .Xr tsearch 3 85.Xr tsearch 3
86.Sh STANDARDS 86.Sh STANDARDS
87The 87The
88.Fn bsearch 88.Fn bsearch
diff --git a/src/lib/libc/stdlib/tfind.c b/src/lib/libc/stdlib/tfind.c
new file mode 100644
index 0000000000..8e77527bf5
--- /dev/null
+++ b/src/lib/libc/stdlib/tfind.c
@@ -0,0 +1,41 @@
1/*
2 * Tree search generalized from Knuth (6.2.2) Algorithm T just like
3 * the AT&T man page says.
4 *
5 * The node_t structure is for internal use only, lint doesn't grok it.
6 *
7 * Written by reading the System V Interface Definition, not the code.
8 *
9 * Totally public domain.
10 */
11/*LINTLIBRARY*/
12#include <search.h>
13
14typedef struct node_t
15{
16 char *key;
17 struct node_t *llink, *rlink;
18} node;
19
20/* find a node, or return 0 */
21void *
22tfind(vkey, vrootp, compar)
23 const void *vkey; /* key to be found */
24 void **vrootp; /* address of the tree root */
25 int (*compar) __P((const void *, const void *));
26{
27 char *key = (char *)vkey;
28 node **rootp = (node **)vrootp;
29
30 if (rootp == (struct node_t **)0)
31 return ((struct node_t *)0);
32 while (*rootp != (struct node_t *)0) { /* T1: */
33 int r;
34 if ((r = (*compar)(key, (*rootp)->key)) == 0) /* T2: */
35 return (*rootp); /* key found */
36 rootp = (r < 0) ?
37 &(*rootp)->llink : /* T3: follow left branch */
38 &(*rootp)->rlink; /* T4: follow right branch */
39 }
40 return (node *)0;
41}
diff --git a/src/lib/libc/stdlib/tsearch.c b/src/lib/libc/stdlib/tsearch.c
new file mode 100644
index 0000000000..defa8a3006
--- /dev/null
+++ b/src/lib/libc/stdlib/tsearch.c
@@ -0,0 +1,125 @@
1/*
2 * Tree search generalized from Knuth (6.2.2) Algorithm T just like
3 * the AT&T man page says.
4 *
5 * The node_t structure is for internal use only, lint doesn't grok it.
6 *
7 * Written by reading the System V Interface Definition, not the code.
8 *
9 * Totally public domain.
10 */
11/*LINTLIBRARY*/
12
13#include <search.h>
14
15typedef struct node_t {
16 char *key;
17 struct node_t *left, *right;
18} node;
19
20/* find or insert datum into search tree */
21void *
22tsearch(vkey, vrootp, compar)
23 const void *vkey; /* key to be located */
24 void **vrootp; /* address of tree root */
25 int (*compar) __P((const void *, const void *));
26{
27 register node *q;
28 char *key = (char *)vkey;
29 node **rootp = (node **)vrootp;
30
31 if (rootp == (struct node_t **)0)
32 return ((void *)0);
33 while (*rootp != (struct node_t *)0) { /* Knuth's T1: */
34 int r;
35
36 if ((r = (*compar)(key, (*rootp)->key)) == 0) /* T2: */
37 return ((void *)*rootp); /* we found it! */
38 rootp = (r < 0) ?
39 &(*rootp)->left : /* T3: follow left branch */
40 &(*rootp)->right; /* T4: follow right branch */
41 }
42 q = (node *) malloc(sizeof(node)); /* T5: key not found */
43 if (q != (struct node_t *)0) { /* make new node */
44 *rootp = q; /* link new node to old */
45 q->key = key; /* initialize new node */
46 q->left = q->right = (struct node_t *)0;
47 }
48 return ((void *)q);
49}
50
51/* delete node with given key */
52void *
53tdelete(vkey, vrootp, compar)
54 const void *vkey; /* key to be deleted */
55 void **vrootp; /* address of the root of tree */
56 int (*compar) __P((const void *, const void *));
57{
58 node **rootp = (node **)vrootp;
59 char *key = (char *)vkey;
60 node *p;
61 register node *q;
62 register node *r;
63 int cmp;
64
65 if (rootp == (struct node_t **)0 || (p = *rootp) == (struct node_t *)0)
66 return ((struct node_t *)0);
67 while ((cmp = (*compar)(key, (*rootp)->key)) != 0) {
68 p = *rootp;
69 rootp = (cmp < 0) ?
70 &(*rootp)->left : /* follow left branch */
71 &(*rootp)->right; /* follow right branch */
72 if (*rootp == (struct node_t *)0)
73 return ((void *)0); /* key not found */
74 }
75 r = (*rootp)->right; /* D1: */
76 if ((q = (*rootp)->left) == (struct node_t *)0) /* Left (struct node_t *)0? */
77 q = r;
78 else if (r != (struct node_t *)0) { /* Right link is null? */
79 if (r->left == (struct node_t *)0) { /* D2: Find successor */
80 r->left = q;
81 q = r;
82 } else { /* D3: Find (struct node_t *)0 link */
83 for (q = r->left; q->left != (struct node_t *)0; q = r->left)
84 r = q;
85 r->left = q->right;
86 q->left = (*rootp)->left;
87 q->right = (*rootp)->right;
88 }
89 }
90 free((struct node_t *) *rootp); /* D4: Free node */
91 *rootp = q; /* link parent to new node */
92 return(p);
93}
94
95/* Walk the nodes of a tree */
96static void
97trecurse(root, action, level)
98 register node *root; /* Root of the tree to be walked */
99 register void (*action)(); /* Function to be called at each node */
100 register int level;
101{
102 if (root->left == (struct node_t *)0 && root->right == (struct node_t *)0)
103 (*action)(root, leaf, level);
104 else {
105 (*action)(root, preorder, level);
106 if (root->left != (struct node_t *)0)
107 trecurse(root->left, action, level + 1);
108 (*action)(root, postorder, level);
109 if (root->right != (struct node_t *)0)
110 trecurse(root->right, action, level + 1);
111 (*action)(root, endorder, level);
112 }
113}
114
115/* Walk the nodes of a tree */
116void
117twalk(vroot, action)
118 const void *vroot; /* Root of the tree to be walked */
119 void (*action) __P((const void *, VISIT, int));
120{
121 node *root = (node *)vroot;
122
123 if (root != (node *)0 && action != (void(*)())0)
124 trecurse(root, action, 0);
125}