1 /*
2  * Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
3  * All rights reserved.
4  *
5  * This code is derived from software contributed to Berkeley by
6  * Adam de Boor.
7  *
8  * Redistribution and use in source and binary forms are permitted
9  * provided that the above copyright notice and this paragraph are
10  * duplicated in all such forms and that any documentation,
11  * advertising materials, and other materials related to such
12  * distribution and use acknowledge that the software was developed
13  * by the University of California, Berkeley.  The name of the
14  * University may not be used to endorse or promote products derived
15  * from this software without specific prior written permission.
16  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
17  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
18  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
19  */
20 
21 #ifndef lint
22 static char sccsid[] = "@(#)lstForEachFrom.c	5.2 (Berkeley) 03/11/90";
23 #endif /* not lint */
24 
25 /*-
26  * lstForEachFrom.c --
27  *	Perform a given function on all elements of a list starting from
28  *	a given point.
29  */
30 
31 #include	"lstInt.h"
32 
33 /*-
34  *-----------------------------------------------------------------------
35  * Lst_ForEachFrom --
36  *	Apply the given function to each element of the given list. The
37  *	function should return 0 if traversal should continue and non-
38  *	zero if it should abort.
39  *
40  * Results:
41  *	None.
42  *
43  * Side Effects:
44  *	Only those created by the passed-in function.
45  *
46  *-----------------------------------------------------------------------
47  */
48 /*VARARGS2*/
49 void
50 Lst_ForEachFrom (l, ln, proc, d)
51     Lst	    	    	l;
52     LstNode    	  	ln;
53     register int	(*proc)();
54     register ClientData	d;
55 {
56     register ListNode	tln = (ListNode)ln;
57     register List 	list = (List)l;
58     register ListNode	next;
59     Boolean 	    	done;
60     int     	    	result;
61 
62     if (!LstValid (list) || LstIsEmpty (list)) {
63 	return;
64     }
65 
66     do {
67 	/*
68 	 * Take care of having the current element deleted out from under
69 	 * us.
70 	 */
71 
72 	next = tln->nextPtr;
73 
74 	tln->useCount++;
75 	result = (*proc) (tln->datum, d);
76 	tln->useCount--;
77 
78 	/*
79 	 * We're done with the traversal if
80 	 *  - nothing's been added after the current node and
81 	 *  - the next node to examine is the first in the queue or
82 	 *    doesn't exist.
83 	 */
84 	done = (next == tln->nextPtr &&
85 		(next == NilListNode || next == list->firstPtr));
86 
87 	next = tln->nextPtr;
88 
89 	if (tln->flags & LN_DELETED) {
90 	    free((char *)tln);
91 	}
92 	tln = next;
93     } while (!result && !LstIsEmpty(list) && !done);
94 
95 }
96 
97