1 /*- 2 * LstRemove.c -- 3 * Remove an element from a list 4 * 5 * Copyright (c) 1988 by University of California Regents 6 * 7 * Permission to use, copy, modify, and distribute this 8 * software and its documentation for any purpose and without 9 * fee is hereby granted, provided that the above copyright 10 * notice appears in all copies. Neither the University of California nor 11 * Adam de Boor makes any representations about the suitability of this 12 * software for any purpose. It is provided "as is" without 13 * express or implied warranty. 14 */ 15 #ifndef lint 16 static char *rcsid = 17 "$Id: lstRemove.c,v 1.7 89/06/13 15:01:51 adam Exp $ SPRITE (Berkeley)"; 18 #endif lint 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