Commit | Line | Data |
---|---|---|
bb2109e7 | 1 | /* |
4f703748 KB |
2 | * Copyright (c) 1988, 1989, 1990, 1993 |
3 | * The Regents of the University of California. All rights reserved. | |
c65fedcf | 4 | * |
bb2109e7 KB |
5 | * This code is derived from software contributed to Berkeley by |
6 | * Adam de Boor. | |
c65fedcf | 7 | * |
f15db449 | 8 | * %sccs.include.redist.c% |
c65fedcf | 9 | */ |
bb2109e7 | 10 | |
c65fedcf | 11 | #ifndef lint |
bfdbffbb | 12 | static char sccsid[] = "@(#)lstRemove.c 8.2 (Berkeley) %G%"; |
bb2109e7 KB |
13 | #endif /* not lint */ |
14 | ||
15 | /*- | |
16 | * LstRemove.c -- | |
17 | * Remove an element from a list | |
18 | */ | |
c65fedcf KB |
19 | |
20 | #include "lstInt.h" | |
21 | ||
22 | /*- | |
23 | *----------------------------------------------------------------------- | |
24 | * Lst_Remove -- | |
25 | * Remove the given node from the given list. | |
26 | * | |
27 | * Results: | |
28 | * SUCCESS or FAILURE. | |
29 | * | |
30 | * Side Effects: | |
31 | * The list's firstPtr will be set to NilListNode if ln is the last | |
32 | * node on the list. firsPtr and lastPtr will be altered if ln is | |
33 | * either the first or last node, respectively, on the list. | |
34 | * | |
35 | *----------------------------------------------------------------------- | |
36 | */ | |
37 | ReturnStatus | |
38 | Lst_Remove (l, ln) | |
39 | Lst l; | |
40 | LstNode ln; | |
41 | { | |
42 | register List list = (List) l; | |
43 | register ListNode lNode = (ListNode) ln; | |
44 | ||
45 | if (!LstValid (l) || | |
46 | !LstNodeValid (ln, l)) { | |
47 | return (FAILURE); | |
48 | } | |
49 | ||
50 | /* | |
51 | * unlink it from the list | |
52 | */ | |
53 | if (lNode->nextPtr != NilListNode) { | |
54 | lNode->nextPtr->prevPtr = lNode->prevPtr; | |
55 | } | |
56 | if (lNode->prevPtr != NilListNode) { | |
57 | lNode->prevPtr->nextPtr = lNode->nextPtr; | |
58 | } | |
59 | ||
60 | /* | |
61 | * if either the firstPtr or lastPtr of the list point to this node, | |
62 | * adjust them accordingly | |
63 | */ | |
64 | if (list->firstPtr == lNode) { | |
65 | list->firstPtr = lNode->nextPtr; | |
66 | } | |
67 | if (list->lastPtr == lNode) { | |
68 | list->lastPtr = lNode->prevPtr; | |
69 | } | |
70 | ||
71 | /* | |
72 | * Sequential access stuff. If the node we're removing is the current | |
73 | * node in the list, reset the current node to the previous one. If the | |
74 | * previous one was non-existent (prevPtr == NilListNode), we set the | |
75 | * end to be Unknown, since it is. | |
76 | */ | |
77 | if (list->isOpen && (list->curPtr == lNode)) { | |
78 | list->curPtr = list->prevPtr; | |
79 | if (list->curPtr == NilListNode) { | |
80 | list->atEnd = Unknown; | |
81 | } | |
82 | } | |
83 | ||
84 | /* | |
85 | * the only way firstPtr can still point to ln is if ln is the last | |
86 | * node on the list (the list is circular, so lNode->nextptr == lNode in | |
87 | * this case). The list is, therefore, empty and is marked as such | |
88 | */ | |
89 | if (list->firstPtr == lNode) { | |
90 | list->firstPtr = NilListNode; | |
91 | } | |
92 | ||
93 | /* | |
94 | * note that the datum is unmolested. The caller must free it as | |
95 | * necessary and as expected. | |
96 | */ | |
97 | if (lNode->useCount == 0) { | |
98 | free ((Address)ln); | |
99 | } else { | |
100 | lNode->flags |= LN_DELETED; | |
101 | } | |
102 | ||
103 | return (SUCCESS); | |
104 | } | |
105 |