Expand PMF_FN_* macros.
[netbsd-mini2440.git] / external / ibm-public / postfix / dist / src / global / tok822_tree.c
blob2533a5c22049ed3296838303a0e52a27acdecb7a
1 /* $NetBSD$ */
3 /*++
4 /* NAME
5 /* tok822_tree 3
6 /* SUMMARY
7 /* assorted token tree operators
8 /* SYNOPSIS
9 /* #include <tok822.h>
11 /* TOK822 *tok822_append(t1, t2)
12 /* TOK822 *t1;
13 /* TOK822 *t2;
15 /* TOK822 *tok822_prepend(t1, t2)
16 /* TOK822 *t1;
17 /* TOK822 *t2;
19 /* TOK822 *tok822_cut_before(tp)
20 /* TOK822 *tp;
22 /* TOK822 *tok822_cut_after(tp)
23 /* TOK822 *tp;
25 /* TOK822 *tok822_unlink(tp)
26 /* TOK822 *tp;
28 /* TOK822 *tok822_sub_append(t1, t2)
29 /* TOK822 *t1;
31 /* TOK822 *tok822_sub_prepend(t1, t2)
32 /* TOK822 *t1;
33 /* TOK822 *t2;
35 /* TOK822 *tok822_sub_keep_before(t1, t2)
36 /* TOK822 *tp;
38 /* TOK822 *tok822_sub_keep_after(t1, t2)
39 /* TOK822 *tp;
41 /* int tok822_apply(list, type, action)
42 /* TOK822 *list;
43 /* int type;
44 /* int (*action)(TOK822 *token);
46 /* int tok822_grep(list, type)
47 /* TOK822 *list;
48 /* int type;
50 /* TOK822 *tok822_free_tree(tp)
51 /* TOK822 *tp;
52 /* DESCRIPTION
53 /* This module manipulates trees of token structures. Trees grow
54 /* to the right or downwards. Operators are provided to cut and
55 /* combine trees in various manners.
57 /* tok822_append() appends the token list \fIt2\fR to the right
58 /* of token list \fIt1\fR. The result is the last token in \fIt2\fR.
59 /* The appended list inherits the \fIowner\fR attribute from \fIt1\fR.
60 /* The parent node, if any, is not updated.
62 /* tok822_prepend() inserts the token list \fIt2\fR to the left
63 /* of token \fIt1\fR. The result is the last token in \fIt2\fR.
64 /* The appended list inherits the \fIowner\fR attribute from \fIt1\fR.
65 /* The parent node, if any, is not updated.
67 /* tok822_cut_before() breaks a token list on the left side of \fItp\fR
68 /* and returns the left neighbor of \tItp\fR.
70 /* tok822_cut_after() breaks a token list on the right side of \fItp\fR
71 /* and returns the right neighbor of \tItp\fR.
73 /* tok822_unlink() disconnects a token from its left and right neighbors
74 /* and returns the left neighbor of \tItp\fR.
76 /* tok822_sub_append() appends the token list \fIt2\fR to the right
77 /* of the token list below \fIt1\fR. The result is the last token
78 /* in \fIt2\fR.
80 /* tok822_sub_prepend() prepends the token list \fIt2\fR to the left
81 /* of the token list below \fIt1\fR. The result is the last token
82 /* in \fIt2\fR.
84 /* tok822_sub_keep_before() keeps the token list below \fIt1\fR on the
85 /* left side of \fIt2\fR and returns the tail of the disconnected list.
87 /* tok822_sub_keep_after() keeps the token list below \fIt1\fR on the
88 /* right side of \fIt2\fR and returns the head of the disconnected list.
90 /* tok822_apply() applies the specified action routine to all tokens
91 /* matching the given type (to all tokens when a null type is given).
92 /* Processing terminates when the action routine returns a non-zero
93 /* value. The result is the last result returned by the action routine.
94 /* tok822_apply() does not traverse vertical links.
96 /* tok822_grep() returns a null-terminated array of pointers to tokens
97 /* matching the specified type (all tokens when a null type is given).
98 /* tok822_grep() does not traverse vertical links. The result must be
99 /* given to myfree().
101 /* tok822_free_tree() destroys a tree of token structures and
102 /* conveniently returns a null pointer.
103 /* LICENSE
104 /* .ad
105 /* .fi
106 /* The Secure Mailer license must be distributed with this software.
107 /* AUTHOR(S)
108 /* Wietse Venema
109 /* IBM T.J. Watson Research
110 /* P.O. Box 704
111 /* Yorktown Heights, NY 10598, USA
112 /*--*/
114 /* System library. */
116 #include <sys_defs.h>
118 /* Utility library. */
120 #include <mymalloc.h>
121 #include <vstring.h>
123 /* Global library. */
125 #include "tok822.h"
127 /* tok822_append - insert token list, return end of inserted list */
129 TOK822 *tok822_append(TOK822 *t1, TOK822 *t2)
131 TOK822 *next = t1->next;
133 t1->next = t2;
134 t2->prev = t1;
136 t2->owner = t1->owner;
137 while (t2->next)
138 (t2 = t2->next)->owner = t1->owner;
140 t2->next = next;
141 if (next)
142 next->prev = t2;
143 return (t2);
146 /* tok822_prepend - insert token list, return end of inserted list */
148 TOK822 *tok822_prepend(TOK822 *t1, TOK822 *t2)
150 TOK822 *prev = t1->prev;
152 if (prev)
153 prev->next = t2;
154 t2->prev = prev;
156 t2->owner = t1->owner;
157 while (t2->next)
158 (t2 = t2->next)->owner = t1->owner;
160 t2->next = t1;
161 t1->prev = t2;
162 return (t2);
165 /* tok822_cut_before - split list before token, return predecessor token */
167 TOK822 *tok822_cut_before(TOK822 *tp)
169 TOK822 *prev = tp->prev;
171 if (prev) {
172 prev->next = 0;
173 tp->prev = 0;
175 return (prev);
178 /* tok822_cut_after - split list after token, return successor token */
180 TOK822 *tok822_cut_after(TOK822 *tp)
182 TOK822 *next = tp->next;
184 if (next) {
185 next->prev = 0;
186 tp->next = 0;
188 return (next);
191 /* tok822_unlink - take token away from list, return predecessor token */
193 TOK822 *tok822_unlink(TOK822 *tp)
195 TOK822 *prev = tp->prev;
196 TOK822 *next = tp->next;
198 if (prev)
199 prev->next = next;
200 if (next)
201 next->prev = prev;
202 tp->prev = tp->next = 0;
203 return (prev);
206 /* tok822_sub_append - append sublist, return end of appended list */
208 TOK822 *tok822_sub_append(TOK822 *t1, TOK822 *t2)
210 if (t1->head) {
211 return (t1->tail = tok822_append(t1->tail, t2));
212 } else {
213 t1->head = t2;
214 while (t2->next)
215 (t2 = t2->next)->owner = t1;
216 return (t1->tail = t2);
220 /* tok822_sub_prepend - prepend sublist, return end of prepended list */
222 TOK822 *tok822_sub_prepend(TOK822 *t1, TOK822 *t2)
224 TOK822 *tp;
226 if (t1->head) {
227 tp = tok822_prepend(t1->head, t2);
228 t1->head = t2;
229 return (tp);
230 } else {
231 t1->head = t2;
232 while (t2->next)
233 (t2 = t2->next)->owner = t1;
234 return (t1->tail = t2);
238 /* tok822_sub_keep_before - cut sublist, return tail of disconnected list */
240 TOK822 *tok822_sub_keep_before(TOK822 *t1, TOK822 *t2)
242 TOK822 *tail = t1->tail;
244 if ((t1->tail = tok822_cut_before(t2)) == 0)
245 t1->head = 0;
246 return (tail);
249 /* tok822_sub_keep_after - cut sublist, return head of disconnected list */
251 TOK822 *tok822_sub_keep_after(TOK822 *t1, TOK822 *t2)
253 TOK822 *head = t1->head;
255 if ((t1->head = tok822_cut_after(t2)) == 0)
256 t1->tail = 0;
257 return (head);
260 /* tok822_free_tree - destroy token tree */
262 TOK822 *tok822_free_tree(TOK822 *tp)
264 if (tp) {
265 if (tp->next)
266 tok822_free_tree(tp->next);
267 if (tp->head)
268 tok822_free_tree(tp->head);
269 tok822_free(tp);
271 return (0);
274 /* tok822_apply - apply action to specified tokens */
276 int tok822_apply(TOK822 *tree, int type, TOK822_ACTION action)
278 TOK822 *tp;
279 int result = 0;
281 for (tp = tree; tp; tp = tp->next) {
282 if (type == 0 || tp->type == type)
283 if ((result = action(tp)) != 0)
284 break;
286 return (result);
289 /* tok822_grep - list matching tokens */
291 TOK822 **tok822_grep(TOK822 *tree, int type)
293 TOK822 **list;
294 TOK822 *tp;
295 int count;
297 for (count = 0, tp = tree; tp; tp = tp->next)
298 if (type == 0 || tp->type == type)
299 count++;
301 list = (TOK822 **) mymalloc(sizeof(*list) * (count + 1));
303 for (count = 0, tp = tree; tp; tp = tp->next)
304 if (type == 0 || tp->type == type)
305 list[count++] = tp;
307 list[count] = 0;
308 return (list);