]> dxcluster.net Git - spider.git/blob - src/chain.c
treat PC61 as PC11.
[spider.git] / src / chain.c
1 /*
2  * routines to operate on double linked circular chains
3  *
4  * In memoriam ICL George 3
5  *
6  * Copyright (c) 1989 Dirk Koopman
7  *
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
16  *
17  * $Header$
18  *
19  */
20
21 #include <stdlib.h>
22
23 /* chain definitions */
24 typedef struct _reft {
25         struct _reft *next, *prev;
26 } reft;
27
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);
30
31 /*
32  * chain_init()
33  */
34
35 void chain_init(p)
36 struct _reft *p;
37 {
38         p->next = p->prev = p;
39 }
40
41 /*
42  * chain_insert() - insert an item before the ref provided
43  */
44
45 void chain_insert(p, q)
46 struct _reft *p, *q;
47 {
48         check(p, "ins");
49         q->prev = p->prev;
50         q->next = p;
51         p->prev->next = q;
52         p->prev = q;
53 }
54 /*
55  * chain_movebase() - insert an chain of items from one base to another
56  */
57
58 void chain_movebase(p, q)
59 struct _reft *p, *q;
60 {
61         check(p, "movebase");
62         q->prev->prev = p->prev;
63         q->next->next = p;
64         p->prev->next = q->next;
65         p->prev = q->prev;
66         q->next = q->prev = q;
67 }
68
69 /*
70  * chain_add() - add an item after the ref
71  */
72
73 void chain_add(p, q)
74 struct _reft *p, *q;
75 {
76         check(p, "add");
77         p = p->next;
78         chain_insert(p, q);
79 }
80
81 /*
82  * chain_delete() - delete an item in a chain
83  */
84
85 struct _reft *chain_delete(p)
86 struct _reft *p;
87 {
88         check(p, "del");
89         p->prev->next = p->next;
90         p->next->prev = p->prev;
91         return p->prev;
92 }
93
94 /*
95  * chain_empty_test() - test to see if the chain is empty
96  */
97
98 int chain_empty_test(base)
99 struct _reft *base;
100 {
101         check(base, "chain_empty_test")
102                 return base->next == base;
103 }
104
105 /*
106  * chainnext() - get next item in chain
107  */
108
109 struct _reft *chain_get_next(base, p)
110 struct _reft *base, *p;
111 {
112
113         check(base, "next base");
114         
115         if (!p)
116                 return (chain_empty_test(base)) ? 0 : base->next;
117
118         check(p, "next last ref");
119         if (p->next != base)
120                 return p->next;
121         else
122                 return (struct _reft *) 0;
123 }
124
125 /*
126  * chainprev() - get previous item in chain
127  */
128
129 struct _reft *chain_get_prev(base, p)
130 struct _reft *base, *p;
131 {
132         check(base, "prev base");
133         if (!p)
134                 return (chain_empty_test(base)) ? 0 : base->prev;
135
136         check(p, "prev last ref");
137         if (p->prev != base)
138                 return p->prev;
139         else
140                 return (struct _reft *) 0;
141 }
142
143 /*
144  * rechain() - re-chain an item at this point (usually after the chain base)
145  */
146
147 void chain_rechain(base, p)
148 struct _reft *base, *p;
149 {
150         check(base, "rechain base");
151         check(p, "rechain last ref");
152         chain_delete(p);
153         chain_add(base, p);
154 }
155
156 /*
157  * emptychain() - remove all the elements in a chain, this frees all elements
158  *                in a chain leaving just the base.
159  */
160
161 void chain_flush(base)
162 struct _reft *base;
163 {
164         struct _reft *p;
165
166         while (!chain_empty_test(base)) {
167                 p = base->next;
168                 chain_delete(p);
169                 free(p);
170         }
171 }
172
173 /*
174  * newchain() - create a new chain base in the heap
175  */
176
177 reft *chain_new()
178 {
179         reft *p = malloc(sizeof(reft));
180         if (!p)
181                 die("out of room in chain_new");
182         chain_init(p);
183         return p;
184 }
185
186 /*
187  * $Log$
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
192  *
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
197  *
198  * Revision 1.2  2000/03/26 14:22:59  djk
199  * removed some irrelevant log info
200  *
201  * Revision 1.1  2000/03/26 00:03:30  djk
202  * first cut of client
203  *
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
207  *
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)
213  *
214  * Revision 1.1  1996/08/08 11:33:44  djk
215  * Initial revision
216  *
217  * Revision 1.2  1995/04/21  16:02:51  djk
218  * remove rcs id
219  *
220  * Revision 1.1  1995/03/04  11:46:26  djk
221  * Initial revision
222  *
223  * Revision 1.2  1995/01/24  15:09:39  djk
224  * Changed Indent to Id in rcsid
225  *
226  * Revision 1.1  1995/01/24  15:06:28  djk
227  * Initial revision
228  *
229  * Revision 1.3  91/03/08  13:21:56  dlp
230  * changed the chain broken checks to dlpabort for dlperror
231  * 
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.
234  * 
235  * Revision 1.2  90/09/15  22:37:39  dlp
236  * *** empty log message ***
237  * 
238  * Revision 1.1  90/09/15  22:18:23  dlp
239  * Initial revision
240  * 
241  */