release 2.1 of pmake
[unix-history] / usr / src / usr.bin / make / lst.lib / lstForEachFrom.c
CommitLineData
c65fedcf
KB
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
17static 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*/
39void
40Lst_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