1 /*- 2 * lstForEachFrom.c -- 3 * Perform a given function on all elements of a list starting from 4 * a given point. 5 * 6 * Copyright (c) 1988 by University of California Regents 7 * 8 * Permission to use, copy, modify, and distribute this 9 * software and its documentation for any purpose and without 10 * fee is hereby granted, provided that the above copyright 11 * notice appears in all copies. Neither the University of California nor 12 * Adam de Boor makes any representations about the suitability of this 13 * software for any purpose. It is provided "as is" without 14 * express or implied warranty. 15 */ 16 #ifndef lint 17 static char *rcsid = 18 "$Id: lstForEachFrom.c,v 1.8 89/07/13 13:55:55 adam Exp $ SPRITE (Berkeley)"; 19 #endif lint 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