1 /************************* toolbox/chain.c *************************************
3 Copyright (c) 1997 A. Krall, R. Grafl, M. Gschwind, M. Probst
5 See file COPYRIGHT for information on usage and disclaimer of warranties
7 Not documented, see chain.h.
9 Authors: Reinhard Grafl EMAIL: cacao@complang.tuwien.ac.at
11 Last Change: 1996/10/03
13 *******************************************************************************/
51 void chain_free (chain *c)
55 assert (! c->usedump);
59 chainlink *nextl = l->next;
69 void chain_addafter(chain *c, void *element)
71 chainlink *active,*newlink;
75 if (c -> usedump) newlink = DNEW (chainlink);
76 else newlink = NEW (chainlink);
78 newlink -> element = element;
81 newlink -> next = active -> next;
82 newlink -> prev = active;
84 active -> next = newlink;
85 if (newlink -> next) newlink -> next -> prev = newlink;
86 else c -> last = newlink;
89 newlink -> next = NULL;
90 newlink -> prev = NULL;
92 c -> active = newlink;
99 void chain_addbefore(chain *c, void *element)
101 chainlink *active,*newlink;
105 if (c -> usedump) newlink = DNEW (chainlink);
106 else newlink = NEW (chainlink);
108 newlink -> element = element;
111 newlink -> next = active;
112 newlink -> prev = active -> prev;
114 active -> prev = newlink;
115 if (newlink -> prev) newlink -> prev -> next = newlink;
116 else c -> first = newlink;
119 newlink -> next = NULL;
120 newlink -> prev = NULL;
122 c -> active = newlink;
123 c -> first = newlink;
128 void chain_addlast (chain *c, void *e)
131 chain_addafter (c, e);
134 void chain_addfirst (chain *c, void *e)
137 chain_addbefore (c, e);
141 void chain_remove (chain *c)
145 active = c -> active;
148 if (active -> next) {
149 active -> next -> prev = active -> prev;
152 c -> last = active -> prev;
155 if (active -> prev) {
156 active -> prev -> next = active -> next;
159 c -> first = active -> next;
164 c -> active = active->prev;
166 c -> active = active->next;
168 if (! c -> usedump) FREE (active, chainlink);
172 void *chain_remove_go_prev (chain *c)
175 return chain_this (c);
180 void chain_removespecific(chain *c, void *e)
184 ce = chain_first (c);
186 if (e == ce) { chain_remove (c); return; }
192 void *chain_next(chain *c)
196 active = c -> active;
197 if (!active) return NULL;
199 if (active -> next) {
200 c -> active = active -> next;
201 return c -> active -> element;
207 void *chain_prev(chain *c)
211 active = c -> active;
212 if (!active) return NULL;
214 if (active -> prev) {
215 c -> active = active -> prev;
216 return c -> active -> element;
223 void *chain_this(chain *c)
225 if (c -> active) return c -> active -> element;
230 void *chain_first(chain *c)
232 c -> active = c -> first;
233 if (c -> active) return c -> active -> element;
237 void *chain_last(chain *c)
239 c -> active = c -> last;
240 if (c -> active) return c -> active -> element;;