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 * %sccs.include.redist.c% 9 */ 10 11 #ifndef lint 12 static char sccsid[] = "@(#)lstForEachFrom.c 5.3 (Berkeley) 06/01/90"; 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 tln->useCount++; 65 result = (*proc) (tln->datum, d); 66 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 87