1 /* $OpenBSD: lstRemove.c,v 1.4 1998/12/05 00:06:32 espie Exp $ */ 2 /* $NetBSD: lstRemove.c,v 1.5 1996/11/06 17:59:50 christos Exp $ */ 3 4 /* 5 * Copyright (c) 1988, 1989, 1990, 1993 6 * The Regents of the University of California. All rights reserved. 7 * 8 * This code is derived from software contributed to Berkeley by 9 * Adam de Boor. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions and the following disclaimer. 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in the 18 * documentation and/or other materials provided with the distribution. 19 * 3. All advertising materials mentioning features or use of this software 20 * must display the following acknowledgement: 21 * This product includes software developed by the University of 22 * California, Berkeley and its contributors. 23 * 4. Neither the name of the University nor the names of its contributors 24 * may be used to endorse or promote products derived from this software 25 * without specific prior written permission. 26 * 27 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 28 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 29 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 30 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 31 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 32 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 33 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 34 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 35 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 36 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 37 * SUCH DAMAGE. 38 */ 39 40 #ifndef lint 41 #if 0 42 static char sccsid[] = "@(#)lstRemove.c 8.1 (Berkeley) 6/6/93"; 43 #else 44 static char rcsid[] = "$OpenBSD: lstRemove.c,v 1.4 1998/12/05 00:06:32 espie Exp $"; 45 #endif 46 #endif /* not lint */ 47 48 /*- 49 * LstRemove.c -- 50 * Remove an element from a list 51 */ 52 53 #include "lstInt.h" 54 55 /*- 56 *----------------------------------------------------------------------- 57 * Lst_Remove -- 58 * Remove the given node from the given list. 59 * 60 * Results: 61 * SUCCESS or FAILURE. 62 * 63 * Side Effects: 64 * The list's firstPtr will be set to NilListNode if ln is the last 65 * node on the list. firsPtr and lastPtr will be altered if ln is 66 * either the first or last node, respectively, on the list. 67 * 68 *----------------------------------------------------------------------- 69 */ 70 ReturnStatus 71 Lst_Remove (l, ln) 72 Lst l; 73 LstNode ln; 74 { 75 register List list = (List) l; 76 register ListNode lNode = (ListNode) ln; 77 78 if (!LstValid (l) || 79 !LstNodeValid (ln, l)) { 80 return (FAILURE); 81 } 82 83 /* 84 * unlink it from the list 85 */ 86 if (lNode->nextPtr != NilListNode) { 87 lNode->nextPtr->prevPtr = lNode->prevPtr; 88 } 89 if (lNode->prevPtr != NilListNode) { 90 lNode->prevPtr->nextPtr = lNode->nextPtr; 91 } 92 93 /* 94 * if either the firstPtr or lastPtr of the list point to this node, 95 * adjust them accordingly 96 */ 97 if (list->firstPtr == lNode) { 98 list->firstPtr = lNode->nextPtr; 99 } 100 if (list->lastPtr == lNode) { 101 list->lastPtr = lNode->prevPtr; 102 } 103 104 /* 105 * Sequential access stuff. If the node we're removing is the current 106 * node in the list, reset the current node to the previous one. If the 107 * previous one was non-existent (prevPtr == NilListNode), we set the 108 * end to be Unknown, since it is. 109 */ 110 if (list->isOpen && (list->curPtr == lNode)) { 111 list->curPtr = list->prevPtr; 112 if (list->curPtr == NilListNode) { 113 list->atEnd = Unknown; 114 } 115 } 116 117 /* 118 * the only way firstPtr can still point to ln is if ln is the last 119 * node on the list (the list is circular, so lNode->nextptr == lNode in 120 * this case). The list is, therefore, empty and is marked as such 121 */ 122 if (list->firstPtr == lNode) { 123 list->firstPtr = NilListNode; 124 } 125 126 /* 127 * note that the datum is unmolested. The caller must free it as 128 * necessary and as expected. 129 */ 130 if (lNode->useCount == 0) { 131 free ((Address)ln); 132 } else { 133 lNode->flags |= LN_DELETED; 134 } 135 136 return (SUCCESS); 137 } 138 139