7 /* assorted token tree operators
11 /* TOK822 *tok822_append(t1, t2)
15 /* TOK822 *tok822_prepend(t1, t2)
19 /* TOK822 *tok822_cut_before(tp)
22 /* TOK822 *tok822_cut_after(tp)
25 /* TOK822 *tok822_unlink(tp)
28 /* TOK822 *tok822_sub_append(t1, t2)
31 /* TOK822 *tok822_sub_prepend(t1, t2)
35 /* TOK822 *tok822_sub_keep_before(t1, t2)
38 /* TOK822 *tok822_sub_keep_after(t1, t2)
41 /* int tok822_apply(list, type, action)
44 /* int (*action)(TOK822 *token);
46 /* int tok822_grep(list, type)
50 /* TOK822 *tok822_free_tree(tp)
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
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
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
101 /* tok822_free_tree() destroys a tree of token structures and
102 /* conveniently returns a null pointer.
106 /* The Secure Mailer license must be distributed with this software.
109 /* IBM T.J. Watson Research
111 /* Yorktown Heights, NY 10598, USA
114 /* System library. */
116 #include <sys_defs.h>
118 /* Utility library. */
120 #include <mymalloc.h>
123 /* Global library. */
127 /* tok822_append - insert token list, return end of inserted list */
129 TOK822
*tok822_append(TOK822
*t1
, TOK822
*t2
)
131 TOK822
*next
= t1
->next
;
136 t2
->owner
= t1
->owner
;
138 (t2
= t2
->next
)->owner
= t1
->owner
;
146 /* tok822_prepend - insert token list, return end of inserted list */
148 TOK822
*tok822_prepend(TOK822
*t1
, TOK822
*t2
)
150 TOK822
*prev
= t1
->prev
;
156 t2
->owner
= t1
->owner
;
158 (t2
= t2
->next
)->owner
= t1
->owner
;
165 /* tok822_cut_before - split list before token, return predecessor token */
167 TOK822
*tok822_cut_before(TOK822
*tp
)
169 TOK822
*prev
= tp
->prev
;
178 /* tok822_cut_after - split list after token, return successor token */
180 TOK822
*tok822_cut_after(TOK822
*tp
)
182 TOK822
*next
= tp
->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
;
202 tp
->prev
= tp
->next
= 0;
206 /* tok822_sub_append - append sublist, return end of appended list */
208 TOK822
*tok822_sub_append(TOK822
*t1
, TOK822
*t2
)
211 return (t1
->tail
= tok822_append(t1
->tail
, t2
));
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
)
227 tp
= tok822_prepend(t1
->head
, t2
);
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)
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)
260 /* tok822_free_tree - destroy token tree */
262 TOK822
*tok822_free_tree(TOK822
*tp
)
266 tok822_free_tree(tp
->next
);
268 tok822_free_tree(tp
->head
);
274 /* tok822_apply - apply action to specified tokens */
276 int tok822_apply(TOK822
*tree
, int type
, TOK822_ACTION action
)
281 for (tp
= tree
; tp
; tp
= tp
->next
) {
282 if (type
== 0 || tp
->type
== type
)
283 if ((result
= action(tp
)) != 0)
289 /* tok822_grep - list matching tokens */
291 TOK822
**tok822_grep(TOK822
*tree
, int type
)
297 for (count
= 0, tp
= tree
; tp
; tp
= tp
->next
)
298 if (type
== 0 || tp
->type
== type
)
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
)