1 /* $NetBSD: stree.c,v 1.14 2009/10/17 20:46:03 christos Exp $ */
4 * Copyright (c) 1992 Carnegie Mellon University
7 * Permission to use, copy, modify and distribute this software and its
8 * documentation is hereby granted, provided that both the copyright
9 * notice and this permission notice appear in all copies of the
10 * software, derivative works or modified versions, and any portions
11 * thereof, and that both notices appear in supporting documentation.
13 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
14 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
15 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
17 * Carnegie Mellon requests users of this software to return to
19 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
20 * School of Computer Science
21 * Carnegie Mellon University
22 * Pittsburgh PA 15213-3890
24 * any improvements or extensions that they make and grant Carnegie Mellon
25 * the rights to redistribute these changes.
28 * stree.c -- SUP Tree Routines
30 **********************************************************************
32 * Revision 1.4 92/08/11 12:06:32 mrt
33 * Added copyright. Delinted
37 * Revision 1.3 89/08/15 15:30:57 bww
38 * Changed code in Tlookup to Tsearch for each subpart of path.
39 * Added indent formatting code to Tprint.
40 * From "[89/06/24 gm0w]" at CMU.
43 * 20-May-87 Glenn Marcy (gm0w) at Carnegie-Mellon University
44 * Added code to please lint.
46 * 29-Dec-85 Glenn Marcy (gm0w) at Carnegie-Mellon University
47 * Added code to initialize new fields. Added Tfree routine.
49 * 27-Sep-85 Glenn Marcy (gm0w) at Carnegie-Mellon University
52 **********************************************************************
55 #include <sys/param.h>
58 #include "supextern.h"
62 static TREE
*Tmake(const char *);
63 static TREE
*Trotll(TREE
*, TREE
*);
64 static TREE
*Trotlh(TREE
*, TREE
*);
65 static TREE
*Trothl(TREE
*, TREE
*);
66 static TREE
*Trothh(TREE
*, TREE
*);
67 static void Tbalance(TREE
**);
68 static TREE
*Tinsertavl(TREE
**, const char *, int, int *);
69 static int Tsubprocess(TREE
*, int, int (*f
) (TREE
*, void *), void *);
70 static int Tprintone(TREE
*, void *);
73 /*************************************************************
74 *** T R E E P R O C E S S I N G R O U T I N E S ***
75 *************************************************************/
82 Tfree(&((*t
)->Tlink
));
83 Tfree(&((*t
)->Texec
));
100 t
= (TREE
*) malloc(sizeof(TREE
));
102 goaway("Cannot allocate memory");
103 t
->Tname
= (p
== NULL
) ? NULL
: estrdup(p
);
121 Trotll(TREE
* tp
, TREE
* tl
)
125 tp
->Tbf
= tl
->Tbf
= 0;
130 Trotlh(TREE
* tp
, TREE
* tl
)
139 tp
->Tbf
= tl
->Tbf
= 0;
142 else if (th
->Tbf
== -1)
149 Trothl(TREE
* tp
, TREE
* th
)
158 tp
->Tbf
= th
->Tbf
= 0;
161 else if (tl
->Tbf
== 1)
168 Trothh(TREE
* tp
, TREE
* th
)
172 tp
->Tbf
= th
->Tbf
= 0;
179 if ((*t
)->Tbf
< 2 && (*t
)->Tbf
> -2)
182 if ((*t
)->Tlo
->Tbf
> 0)
183 *t
= Trotll(*t
, (*t
)->Tlo
);
185 *t
= Trotlh(*t
, (*t
)->Tlo
);
187 if ((*t
)->Thi
->Tbf
> 0)
188 *t
= Trothl(*t
, (*t
)->Thi
);
190 *t
= Trothh(*t
, (*t
)->Thi
);
195 Tinsertavl(TREE
** t
, const char *p
, int find
, int *dh
)
206 if ((cmp
= strcmp(p
, (*t
)->Tname
)) == 0) {
208 return (NULL
); /* node already exists */
211 } else if (cmp
< 0) {
212 if ((newt
= Tinsertavl(&((*t
)->Tlo
), p
, find
, &deltah
)) == NULL
)
216 if ((newt
= Tinsertavl(&((*t
)->Thi
), p
, find
, &deltah
)) == NULL
)
228 Tinsert(TREE
** t
, const char *p
, int find
)
232 if (p
!= NULL
&& p
[0] == '.' && p
[1] == '/') {
239 return (Tinsertavl(t
, p
, find
, &deltah
));
243 Tsearch(TREE
* t
, const char *p
)
250 cmp
= strcmp(p
, x
->Tname
);
262 Tlookup(TREE
* t
, const char *p
)
265 char buf
[MAXPATHLEN
+ 1];
270 if (p
[0] == '.' && p
[1] == '/') {
277 if ((x
= Tsearch(t
, p
)) != NULL
)
279 if (*p
!= '/' && (x
= Tsearch(t
, ".")) != NULL
)
281 (void) strncpy(buf
, p
, sizeof(buf
) - 1);
282 buf
[MAXPATHLEN
] = '\0';
283 while ((q
= strrchr(buf
, '/')) != NULL
) {
284 while (q
>= buf
&& *(q
- 1) == '/')
290 if ((x
= Tsearch(t
, buf
)) != NULL
)
298 static int process_level
;
301 Tsubprocess(TREE
* t
, int reverse
, int (*f
) (TREE
*, void *), void *argp
)
305 if (reverse
? t
->Thi
: t
->Tlo
)
306 x
= Tsubprocess(reverse
? t
->Thi
: t
->Tlo
,
311 if (reverse
? t
->Tlo
: t
->Thi
)
312 x
= Tsubprocess(reverse
? t
->Tlo
: t
->Thi
,
322 Trprocess(TREE
* t
, int (*f
) (TREE
*, void *), void *args
)
327 return (Tsubprocess(t
, TRUE
, f
, args
));
332 Tprocess(TREE
* t
, int (*f
) (TREE
*, void *), void *args
)
337 return (Tsubprocess(t
, FALSE
, f
, args
));
342 Tprintone(TREE
* t
, void *v __unused
)
345 for (i
= 0; i
< (process_level
* 2); i
++)
347 printf("Node at %p name '%s' flags %o hi %p lo %p\n", t
, t
->Tname
, t
->Tflags
, t
->Thi
, t
->Tlo
);
352 Tprint(TREE
* t
, char *p
)
353 { /* print tree -- for debugging */
355 (void) Tprocess(t
, Tprintone
, NULL
);
356 printf("End of tree\n");
357 (void) fflush(stdout
);