2 * routines to operate on double linked circular chains
4 * chain_init() - initialise a chain
5 * chain_add() - add an item after the ref provided
6 * chain_delete() - delete the item
7 * chainins() - insert an item before the ref
8 * chainnext() - get the next item on chain returning NULL if eof
9 * chainprev() - get the previous item on chain returning NULL if eof
10 * chain_empty_test() - is the chain empty?
11 * chain_movebase() - move a chain of things onto (the end of) another base
16 * Revision 1.1 2000-03-26 00:03:30 djk
19 * Revision 1.4 1998/01/02 19:39:58 djk
20 * made various changes to cope with glibc
21 * fixed problem with extended status in etsi_router
23 * Revision 1.3 1997/01/02 18:46:46 djk
24 * Added conv.c from ETSI router
25 * Changed qerror.c to use syslog rather than qerror.log
26 * removed all the map27 stuff into a separate directory
27 * added dump.c (a debugging tool for dumping frames of data)
29 * Revision 1.1 1996/08/08 11:33:44 djk
32 * Revision 1.2 1995/04/21 16:02:51 djk
35 * Revision 1.1 1995/03/04 11:46:26 djk
38 * Revision 1.2 1995/01/24 15:09:39 djk
39 * Changed Indent to Id in rcsid
41 * Revision 1.1 1995/01/24 15:06:28 djk
44 * Revision 1.3 91/03/08 13:21:56 dlp
45 * changed the chain broken checks to dlpabort for dlperror
47 * Revision 1.2 90/09/15 22:37:39 dlp
48 * checked in with -k by dirk at 91.02.20.15.53.51.
50 * Revision 1.2 90/09/15 22:37:39 dlp
51 * *** empty log message ***
53 * Revision 1.1 90/09/15 22:18:23 dlp
60 /* chain definitions */
61 typedef struct _reft {
62 struct _reft *next, *prev;
65 static char erm[] = "chain broken in %s";
66 #define check(p, ss) if (p == (struct _reft *) 0 || p->prev->next != p || p->next->prev != p) die(erm, ss);
75 p->next = p->prev = p;
79 * chain_insert() - insert an item before the ref provided
82 void chain_insert(p, q)
92 * chain_movebase() - insert an chain of items from one base to another
95 void chain_movebase(p, q)
99 q->prev->prev = p->prev;
101 p->prev->next = q->next;
103 q->next = q->prev = q;
107 * chain_add() - add an item after the ref
119 * chain_delete() - delete an item in a chain
122 struct _reft *chain_delete(p)
126 p->prev->next = p->next;
127 p->next->prev = p->prev;
132 * chain_empty_test() - test to see if the chain is empty
135 int chain_empty_test(base)
138 check(base, "chain_empty_test")
139 return base->next == base;
143 * chainnext() - get next item in chain
146 struct _reft *chain_get_next(base, p)
147 struct _reft *base, *p;
150 check(base, "next base");
153 return (chain_empty_test(base)) ? 0 : base->next;
155 check(p, "next last ref");
159 return (struct _reft *) 0;
163 * chainprev() - get previous item in chain
166 struct _reft *chain_get_prev(base, p)
167 struct _reft *base, *p;
169 check(base, "prev base");
171 return (chain_empty_test(base)) ? 0 : base->prev;
173 check(p, "prev last ref");
177 return (struct _reft *) 0;
181 * rechain() - re-chain an item at this point (usually after the chain base)
184 void chain_rechain(base, p)
185 struct _reft *base, *p;
187 check(base, "rechain base");
188 check(p, "rechain last ref");
194 * emptychain() - remove all the elements in a chain, this frees all elements
195 * in a chain leaving just the base.
198 void chain_flush(base)
203 while (!chain_empty_test(base)) {
211 * newchain() - create a new chain base in the heap
216 reft *p = malloc(sizeof(reft));
218 die("out of room in chain_new");