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 | * | |
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) %G%"; | |
23 | #endif /* not lint */ | |
24 | ||
c65fedcf KB |
25 | /*- |
26 | * lstForEachFrom.c -- | |
27 | * Perform a given function on all elements of a list starting from | |
28 | * a given point. | |
c65fedcf | 29 | */ |
c65fedcf KB |
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 |