upgraded to the latest NetBSD version
[unix-history] / usr / src / usr.bin / make / lst.lib / lstForEachFrom.c
CommitLineData
bb2109e7 1/*
4f703748
KB
2 * Copyright (c) 1988, 1989, 1990, 1993
3 * The Regents of the University of California. All rights reserved.
bb2109e7
KB
4 *
5 * This code is derived from software contributed to Berkeley by
6 * Adam de Boor.
7 *
f15db449 8 * %sccs.include.redist.c%
bb2109e7
KB
9 */
10
11#ifndef lint
bfdbffbb 12static char sccsid[] = "@(#)lstForEachFrom.c 8.2 (Berkeley) %G%";
bb2109e7
KB
13#endif /* not lint */
14
c65fedcf
KB
15/*-
16 * lstForEachFrom.c --
17 * Perform a given function on all elements of a list starting from
18 * a given point.
c65fedcf 19 */
c65fedcf
KB
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
2a310187 64 (void) tln->useCount++;
c65fedcf 65 result = (*proc) (tln->datum, d);
2a310187 66 (void) tln->useCount--;
c65fedcf
KB
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}