Wild Life  2.30
 All Data Structures Files Functions Variables Typedefs Macros
list.c
Go to the documentation of this file.
1 
9 /*
10  * Copyright 1991 Digital Equipment Corporation.
11  * All Rights Reserved.
12  */
13 
14 #include "defs.h"
15 
25 {
26  header->First = NULL;
27  header->Last = NULL;
28 
29 #ifdef prlDEBUG
30  header->Lock = 0;
31 #endif
32 
33  header->GetLinks = getLinks;
34 }
35 
44 void List_InsertAhead (RefListHeader header, Ref atom)
45 {
46  RefListGetLinksProc getLinks = header->GetLinks;
47 
48  /* Update links of atom to insert */
49 
50  (*getLinks)(atom)->Next = header->First;
51  (*getLinks)(atom)->Prev = NULL;
52 
53  /* Link to the head of list */
54 
55  if (header->First != NULL)
56  (*getLinks)(header->First)->Prev = atom;
57 
58  else /* The list is empty */
59  header->Last = atom;
60 
61  header->First = atom;
62 }
63 
71 void List_Append (RefListHeader header, Ref atom)
72 {
73  RefListGetLinksProc getLinks = header->GetLinks;
74 
75  /* Link to the end of list */
76 
77  if (header->Last != NULL)
78  (*getLinks)(header->Last)->Next = atom;
79 
80  else /* The list is empty */
81  header->First = atom;
82 
83  /* Update links of atom to insert */
84 
85  (*getLinks)(atom)->Prev = header->Last;
86  (*getLinks)(atom)->Next = NULL;
87 
88  /* Update last element of header */
89 
90  header->Last = atom;
91 }
92 
101 void List_InsertBefore (RefListHeader header, Ref atom, Ref mark)
102 {
103  RefListGetLinksProc getLinks = header->GetLinks;
104 
105  if (mark != NULL)
106  {
107  (*getLinks)(atom)->Next = mark;
108 
109  if (mark != header->First)
110  {
111  (*getLinks)(atom)->Prev = (*getLinks)(mark)->Prev;
112  (*getLinks)((*getLinks)(mark)->Prev)->Next = atom;
113  }
114  else /* Insert ahead the list */
115  {
116  (*getLinks)(atom)->Prev = NULL;
117  header->First = atom;
118  }
119 
120  (*getLinks)(mark)->Prev = atom;
121  }
122  else /* Append to the list */
123  List_Append (header, atom);
124 }
125 
134 void List_InsertAfter (RefListHeader header, Ref atom, Ref mark)
135 {
136  RefListGetLinksProc getLinks = header->GetLinks;
137 
138 #ifdef prlDEBUG
139  if (header->Lock > 1)
140  OS_PrintMessage ("List_InsertAfter: Warning insert after on recursive List_Enum call !!\n");
141 #endif
142 
143  if (mark != NULL)
144  {
145  (*getLinks)(atom)->Prev = mark;
146 
147  if (mark != header->Last)
148  {
149  (*getLinks)(atom)->Next = (*getLinks)(mark)->Next;
150  (*getLinks)((*getLinks)(mark)->Next)->Prev = atom;
151  }
152  else /* Insert at the end of the list */
153  {
154  (*getLinks)(atom)->Next = NULL;
155  header->Last = atom;
156  }
157 
158  (*getLinks)(mark)->Next = atom;
159  }
160  else /* Insert ahead the list */
161  List_InsertAhead (header, atom);
162 }
163 
172 void List_Swap (RefListHeader header, Ref first, Ref second)
173 {
174  RefListGetLinksProc getLinks = header->GetLinks;
175 
176  /* Don't swap if the input is wrong */
177 
178  if ((*getLinks)(first)->Next != second)
179  {
180 #ifdef prlDEBUG
181  OS_PrintMessage ("List_Swap: WARNING wrong input data, swap not done..\n");
182 #endif
183  return;
184  }
185 
186  /* Special Cases */
187 
188  if (header->First == first)
189  header->First = second;
190  else
191  (*getLinks)((*getLinks)(first)->Prev)->Next = second;
192 
193  if (header->Last == second)
194  header->Last = first;
195  else
196  (*getLinks)((*getLinks)(second)->Next)->Prev = first;
197 
198  /* Swap the atoms */
199 
200  (*getLinks)(second)->Prev = (*getLinks)(first)->Prev;
201  (*getLinks)(first)->Next = (*getLinks)(second)->Next;
202  (*getLinks)(first)->Prev = second;
203  (*getLinks)(second)->Next = first;
204 }
205 
213 static long List_SwapLinks (RefListHeader header, Ref atom)
214 {
215  Ref save;
216 
217  save = (*header->GetLinks)(atom)->Next;
218  (*header->GetLinks)(atom)->Next = (*header->GetLinks)(atom)->Prev;
219  (*header->GetLinks)(atom)->Prev = save;
220 
221  return TRUE;
222 }
223 
231 {
232  Ref cur, next;
233  RefListGetLinksProc getLinks = header->GetLinks;
234 
235  /* This traverse cannot be done with function List_Enum() */
236 
237  cur = header->First;
238 
239  /* Swap the headers */
240  header->First = header->Last;
241  header->Last = cur;
242 
243  while (cur != NULL)
244  {
245  next = (*getLinks)(cur)->Next;
246  (void)List_SwapLinks (header, cur);
247  cur = next;
248  }
249 }
250 
258 void List_Remove (RefListHeader header, Ref atom)
259 {
260 /*-----------------------------------------------------------------------------
261 
262 WARNING
263  - The container is 'updated' two times if the first and last atom
264  of list is the only one to remove.
265 
266 -----------------------------------------------------------------------------*/
267 
268  RefListGetLinksProc getLinks = header->GetLinks;
269 
270 #ifdef prlDEBUG
271  if (header->Lock > 1)
272  OS_PrintMessage ("List_Remove: Warning remove on recursive List_Enum call !!\n");
273 #endif
274 
275  /* Update the DownStream links */
276 
277  if ((*getLinks)(atom)->Prev != NULL)
278  {
279  (*getLinks)((*getLinks)(atom)->Prev)->Next =
280  (*getLinks)(atom)->Next;
281  }
282  else /* Atom is the first of list */
283  header->First = (*getLinks)(atom)->Next;
284 
285  /* Update the UpStream links */
286 
287  if ((*getLinks)(atom)->Next != NULL)
288  {
289  (*getLinks)((*getLinks)(atom)->Next)->Prev =
290  (*getLinks)(atom)->Prev;
291  }
292  else /* Atom is the last of list */
293  header->Last = (*getLinks)(atom)->Prev;
294 
295  /* Reset the atom links */
296 
297  (*getLinks)(atom)->Prev = NULL;
298  (*getLinks)(atom)->Next = NULL;
299 }
300 
308 void List_Concat (RefListHeader header1, RefListHeader header2)
309 {
310  RefListGetLinksProc getLinks = header1->GetLinks;
311 
312  if (header1->GetLinks == header2->GetLinks)
313  {
314 #ifdef prlDEBUG
315  OS_PrintMessage ("List_Concat: ERROR concat different lists\n");
316 #endif
317  return;
318  }
319 
320  /* Concatenate only if the second list is not empty */
321 
322  if (header2->First != NULL)
323  {
324  /* Obvious concatenate when the first list is empty */
325 
326  if (header1->First == NULL)
327  header1->First = header2->First;
328 
329  else /* Concatenate the two non empty lists */
330  {
331  (*getLinks)(header1->Last)->Next = header2->First;
332  (*getLinks)(header2->First)->Prev = header1->Last;
333  }
334  header1->Last = header2->Last;
335  }
336 }
337 
347 long List_EnumFrom (RefListHeader header, Ref atom, RefListEnumProc proc, Ref closure)
348 {
349  Ref cur, next;
350  int notInterrupted = TRUE;
351 
352 #ifdef prlDEBUG
353  header->Lock += 1;
354 #endif
355 
356  cur = atom;
357  while (cur != NULL && notInterrupted)
358  {
359  next = List_Next (header, cur);
360  notInterrupted = (*proc)(cur, closure);
361  cur = next;
362  }
363 
364 #ifdef prlDEBUG
365  header->Lock -=1;
366 #endif
367 
368  return (notInterrupted);
369 }
370 
379 long List_Enum (RefListHeader header, RefListEnumProc proc, Ref closure)
380 /*-----------------------------------------------------------------------------
381 
382 (NO) SIDE EFFECTS
383  The current atom can be modified by the function RemoveAtom () during
384  the traversing of the list. This is the reason why the current pointer
385  is managed on the header.
386 
387 -----------------------------------------------------------------------------*/
388 {
389  return (List_EnumFrom (header, header->First, proc, closure));
390 }
391 
401 long List_EnumBackFrom (RefListHeader header, Ref atom, RefListEnumProc proc, Ref closure)
402 {
403  Ref cur, prev;
404  int notInterrupted = TRUE;
405 
406 #ifdef prlDEBUG
407  header->Lock += 1;
408 #endif
409 
410  cur = atom;
411  while (cur != NULL && notInterrupted)
412  {
413  prev = List_Prev (header, cur);
414  notInterrupted = (*proc)(cur, closure);
415  cur = prev;
416  }
417 
418 #ifdef prlDEBUG
419  header->Lock -=1;
420 #endif
421 
422  return (notInterrupted);
423 }
424 
433 long List_EnumBack (RefListHeader header, RefListEnumProc proc, Ref closure)
434 {
435  return (List_EnumBackFrom (header, header->Last, proc, closure));
436 }
437 
445 /*ARGSUSED*/
446 static long List_CountAtom (Ref p, Ref nbR)
447 {
448  long *nb = (long *)nbR;
449 
450  ++*nb;
451  return TRUE;
452 }
453 
462 {
463  long n = 0;
464 
465  (void)List_Enum (header,(RefListEnumProc) List_CountAtom, &n);
466  return n;
467 }
468 
476 {
477  return (links->Next == NULL && links->Prev == NULL);
478 }
479 
488 void List_Cut (RefListHeader header, Ref atom, RefListHeader newHeader)
489 {
490  RefListGetLinksProc getLinks = header->GetLinks;
491 
492  if (atom != List_Last (header))
493  {
494  newHeader->First = List_Next (header, atom);
495  newHeader->Last = header->Last;
496 
497  header->Last = atom;
498 
499  /* Update the links */
500  (*getLinks)(atom)->Next = NULL;
501  (*getLinks)(newHeader->First)->Prev = NULL;
502  }
503 }
504 
505 /*==============================================================================*/
long List_EnumBackFrom(RefListHeader header, Ref atom, RefListEnumProc proc, Ref closure)
List_EnumBackFrom.
Definition: list.c:401
void List_Concat(RefListHeader header1, RefListHeader header2)
List_Concat.
Definition: list.c:308
void List_Swap(RefListHeader header, Ref first, Ref second)
List_Swap.
Definition: list.c:172
long List_IsUnlink(RefListLinks links)
List_IsUnlink.
Definition: list.c:475
void List_InsertAfter(RefListHeader header, Ref atom, Ref mark)
List_InsertAfter.
Definition: list.c:134
includes
#define List_Prev(header, RefAtom)
Definition: def_macro.h:162
void List_InsertBefore(RefListHeader header, Ref atom, Ref mark)
List_InsertBefore.
Definition: list.c:101
void List_Cut(RefListHeader header, Ref atom, RefListHeader newHeader)
List_Cut.
Definition: list.c:488
RefListGetLinksProc GetLinks
Definition: def_struct.h:297
static long List_SwapLinks(RefListHeader header, Ref atom)
List_SwapLinks.
Definition: list.c:213
#define NULL
Definition: def_const.h:533
void List_Reverse(RefListHeader header)
List_Reverse.
Definition: list.c:230
RefListLinks(* RefListGetLinksProc)()
Definition: def_struct.h:275
void List_InsertAhead(RefListHeader header, Ref atom)
List_InsertAhead.
Definition: list.c:44
#define List_Next(header, RefAtom)
Definition: def_macro.h:161
#define TRUE
Standard boolean.
Definition: def_const.h:268
long List_Card(RefListHeader header)
List_Card.
Definition: list.c:461
#define List_Last(header)
Definition: def_macro.h:160
void List_SetLinkProc(RefListHeader header, RefListGetLinksProc getLinks)
List_SetLinkProc.
Definition: list.c:24
long List_EnumFrom(RefListHeader header, Ref atom, RefListEnumProc proc, Ref closure)
List_EnumFrom.
Definition: list.c:347
int(* RefListEnumProc)()
Definition: def_struct.h:276
void List_Append(RefListHeader header, Ref atom)
void List_Append
Definition: list.c:71
static long List_CountAtom(Ref p, Ref nbR)
List_CountAtom.
Definition: list.c:446
long List_EnumBack(RefListHeader header, RefListEnumProc proc, Ref closure)
List_EnumBack.
Definition: list.c:433
long List_Enum(RefListHeader header, RefListEnumProc proc, Ref closure)
List_Enum.
Definition: list.c:379
struct text_buffer * next
Definition: def_struct.h:399
void * Ref
Definition: def_struct.h:272
void List_Remove(RefListHeader header, Ref atom)
List_Remove.
Definition: list.c:258