Commit | Line | Data |
---|---|---|
bb2109e7 KB |
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 | * | |
f15db449 | 8 | * %sccs.include.redist.c% |
bb2109e7 KB |
9 | */ |
10 | ||
11 | #ifndef lint | |
2a310187 | 12 | static char sccsid[] = "@(#)lstForEachFrom.c 5.4 (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*/ | |
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 | ||
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 | } |