1 /* 2 * Copyright (c) 1988, 1989, 1990, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * This code is derived from software contributed to Berkeley by 6 * Adam de Boor. 7 * 8 * %sccs.include.redist.c% 9 */ 10 11 #ifndef lint 12 static char sccsid[] = "@(#)lstRemove.c 8.2 (Berkeley) 04/28/95"; 13 #endif /* not lint */ 14 15 /*- 16 * LstRemove.c -- 17 * Remove an element from a list 18 */ 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 106