1 /*
2 * Copyright (c) 1988, 1989, 1990, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * This code is derived from software contributed to Berkeley by
6 * Adam de Boor.
7 *
8 * %sccs.include.redist.c%
9 */
10
11 #ifndef lint
12 static char sccsid[] = "@(#)lstForEachFrom.c 8.2 (Berkeley) 04/28/95";
13 #endif /* not lint */
14
15 /*-
16 * lstForEachFrom.c --
17 * Perform a given function on all elements of a list starting from
18 * a given point.
19 */
20
21 #include "lstInt.h"
22
23 /*-
24 *-----------------------------------------------------------------------
25 * Lst_ForEachFrom --
26 * Apply the given function to each element of the given list. The
27 * function should return 0 if traversal should continue and non-
28 * zero if it should abort.
29 *
30 * Results:
31 * None.
32 *
33 * Side Effects:
34 * Only those created by the passed-in function.
35 *
36 *-----------------------------------------------------------------------
37 */
38 /*VARARGS2*/
39 void
Lst_ForEachFrom(l,ln,proc,d)40 Lst_ForEachFrom (l, ln, proc, d)
41 Lst l;
42 LstNode ln;
43 register int (*proc)();
44 register ClientData d;
45 {
46 register ListNode tln = (ListNode)ln;
47 register List list = (List)l;
48 register ListNode next;
49 Boolean done;
50 int result;
51
52 if (!LstValid (list) || LstIsEmpty (list)) {
53 return;
54 }
55
56 do {
57 /*
58 * Take care of having the current element deleted out from under
59 * us.
60 */
61
62 next = tln->nextPtr;
63
64 (void) tln->useCount++;
65 result = (*proc) (tln->datum, d);
66 (void) tln->useCount--;
67
68 /*
69 * We're done with the traversal if
70 * - nothing's been added after the current node and
71 * - the next node to examine is the first in the queue or
72 * doesn't exist.
73 */
74 done = (next == tln->nextPtr &&
75 (next == NilListNode || next == list->firstPtr));
76
77 next = tln->nextPtr;
78
79 if (tln->flags & LN_DELETED) {
80 free((char *)tln);
81 }
82 tln = next;
83 } while (!result && !LstIsEmpty(list) && !done);
84
85 }
86