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