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
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