2 * routines to operate on double linked circular chains
4 * In memoriam ICL George 3
6 * Copyright (c) 1989 Dirk Koopman
8 * chain_init() - initialise a chain
9 * chain_add() - add an item after the ref provided
10 * chain_delete() - delete the item
11 * chainins() - insert an item before the ref
12 * chainnext() - get the next item on chain returning NULL if eof
13 * chainprev() - get the previous item on chain returning NULL if eof
14 * chain_empty_test() - is the chain empty?
15 * chain_movebase() - move a chain of things onto (the end of) another base
23 /* chain definitions */
24 typedef struct _reft {
25 struct _reft *next, *prev;
28 static char erm[] = "chain broken in %s";
29 #define check(p, ss) if (p == (struct _reft *) 0 || p->prev->next != p || p->next->prev != p) die(erm, ss);
38 p->next = p->prev = p;
42 * chain_insert() - insert an item before the ref provided
45 void chain_insert(p, q)
55 * chain_movebase() - insert an chain of items from one base to another
58 void chain_movebase(p, q)
62 q->prev->prev = p->prev;
64 p->prev->next = q->next;
66 q->next = q->prev = q;
70 * chain_add() - add an item after the ref
82 * chain_delete() - delete an item in a chain
85 struct _reft *chain_delete(p)
89 p->prev->next = p->next;
90 p->next->prev = p->prev;
95 * chain_empty_test() - test to see if the chain is empty
98 int chain_empty_test(base)
101 check(base, "chain_empty_test")
102 return base->next == base;
106 * chainnext() - get next item in chain
109 struct _reft *chain_get_next(base, p)
110 struct _reft *base, *p;
113 check(base, "next base");
116 return (chain_empty_test(base)) ? 0 : base->next;
118 check(p, "next last ref");
122 return (struct _reft *) 0;
126 * chainprev() - get previous item in chain
129 struct _reft *chain_get_prev(base, p)
130 struct _reft *base, *p;
132 check(base, "prev base");
134 return (chain_empty_test(base)) ? 0 : base->prev;
136 check(p, "prev last ref");
140 return (struct _reft *) 0;
144 * rechain() - re-chain an item at this point (usually after the chain base)
147 void chain_rechain(base, p)
148 struct _reft *base, *p;
150 check(base, "rechain base");
151 check(p, "rechain last ref");
157 * emptychain() - remove all the elements in a chain, this frees all elements
158 * in a chain leaving just the base.
161 void chain_flush(base)
166 while (!chain_empty_test(base)) {
174 * newchain() - create a new chain base in the heap
179 reft *p = malloc(sizeof(reft));
181 die("out of room in chain_new");
188 * Revision 1.4 2000-07-20 14:16:00 minima
189 * can use Sourceforge now!
190 * added user->qra cleaning
191 * added 4 digit qra to user broadcast dxspots if available
193 * Revision 1.3 2000/03/30 22:51:14 djk
194 * fixed connect code in client.pl so it doesn't falsely recognise /spider
195 * /src/client as a 'client' directive.
196 * Tidied up the C client a bit
198 * Revision 1.2 2000/03/26 14:22:59 djk
199 * removed some irrelevant log info
201 * Revision 1.1 2000/03/26 00:03:30 djk
202 * first cut of client
204 * Revision 1.4 1998/01/02 19:39:58 djk
205 * made various changes to cope with glibc
206 * fixed problem with extended status in etsi_router
208 * Revision 1.3 1997/01/02 18:46:46 djk
209 * Added conv.c from ETSI router
210 * Changed qerror.c to use syslog rather than qerror.log
211 * removed all the map27 stuff into a separate directory
212 * added dump.c (a debugging tool for dumping frames of data)
214 * Revision 1.1 1996/08/08 11:33:44 djk
217 * Revision 1.2 1995/04/21 16:02:51 djk
220 * Revision 1.1 1995/03/04 11:46:26 djk
223 * Revision 1.2 1995/01/24 15:09:39 djk
224 * Changed Indent to Id in rcsid
226 * Revision 1.1 1995/01/24 15:06:28 djk
229 * Revision 1.3 91/03/08 13:21:56 dlp
230 * changed the chain broken checks to dlpabort for dlperror
232 * Revision 1.2 90/09/15 22:37:39 dlp
233 * checked in with -k by dirk at 91.02.20.15.53.51.
235 * Revision 1.2 90/09/15 22:37:39 dlp
236 * *** empty log message ***
238 * Revision 1.1 90/09/15 22:18:23 dlp