1*40412Sbostic /* 2*40412Sbostic * Copyright (c) 1988, 1989, 1990 The Regents of the University of California. 3*40412Sbostic * All rights reserved. 440411Sbostic * 5*40412Sbostic * This code is derived from software contributed to Berkeley by 6*40412Sbostic * Adam de Boor. 740411Sbostic * 8*40412Sbostic * Redistribution and use in source and binary forms are permitted 9*40412Sbostic * provided that the above copyright notice and this paragraph are 10*40412Sbostic * duplicated in all such forms and that any documentation, 11*40412Sbostic * advertising materials, and other materials related to such 12*40412Sbostic * distribution and use acknowledge that the software was developed 13*40412Sbostic * by the University of California, Berkeley. The name of the 14*40412Sbostic * University may not be used to endorse or promote products derived 15*40412Sbostic * from this software without specific prior written permission. 16*40412Sbostic * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 17*40412Sbostic * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 18*40412Sbostic * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 1940411Sbostic */ 20*40412Sbostic 2140411Sbostic #ifndef lint 22*40412Sbostic static char sccsid[] = "@(#)lstRemove.c 5.2 (Berkeley) 03/11/90"; 23*40412Sbostic #endif /* not lint */ 2440411Sbostic 25*40412Sbostic /*- 26*40412Sbostic * LstRemove.c -- 27*40412Sbostic * Remove an element from a list 28*40412Sbostic */ 29*40412Sbostic 3040411Sbostic #include "lstInt.h" 3140411Sbostic 3240411Sbostic /*- 3340411Sbostic *----------------------------------------------------------------------- 3440411Sbostic * Lst_Remove -- 3540411Sbostic * Remove the given node from the given list. 3640411Sbostic * 3740411Sbostic * Results: 3840411Sbostic * SUCCESS or FAILURE. 3940411Sbostic * 4040411Sbostic * Side Effects: 4140411Sbostic * The list's firstPtr will be set to NilListNode if ln is the last 4240411Sbostic * node on the list. firsPtr and lastPtr will be altered if ln is 4340411Sbostic * either the first or last node, respectively, on the list. 4440411Sbostic * 4540411Sbostic *----------------------------------------------------------------------- 4640411Sbostic */ 4740411Sbostic ReturnStatus 4840411Sbostic Lst_Remove (l, ln) 4940411Sbostic Lst l; 5040411Sbostic LstNode ln; 5140411Sbostic { 5240411Sbostic register List list = (List) l; 5340411Sbostic register ListNode lNode = (ListNode) ln; 5440411Sbostic 5540411Sbostic if (!LstValid (l) || 5640411Sbostic !LstNodeValid (ln, l)) { 5740411Sbostic return (FAILURE); 5840411Sbostic } 5940411Sbostic 6040411Sbostic /* 6140411Sbostic * unlink it from the list 6240411Sbostic */ 6340411Sbostic if (lNode->nextPtr != NilListNode) { 6440411Sbostic lNode->nextPtr->prevPtr = lNode->prevPtr; 6540411Sbostic } 6640411Sbostic if (lNode->prevPtr != NilListNode) { 6740411Sbostic lNode->prevPtr->nextPtr = lNode->nextPtr; 6840411Sbostic } 6940411Sbostic 7040411Sbostic /* 7140411Sbostic * if either the firstPtr or lastPtr of the list point to this node, 7240411Sbostic * adjust them accordingly 7340411Sbostic */ 7440411Sbostic if (list->firstPtr == lNode) { 7540411Sbostic list->firstPtr = lNode->nextPtr; 7640411Sbostic } 7740411Sbostic if (list->lastPtr == lNode) { 7840411Sbostic list->lastPtr = lNode->prevPtr; 7940411Sbostic } 8040411Sbostic 8140411Sbostic /* 8240411Sbostic * Sequential access stuff. If the node we're removing is the current 8340411Sbostic * node in the list, reset the current node to the previous one. If the 8440411Sbostic * previous one was non-existent (prevPtr == NilListNode), we set the 8540411Sbostic * end to be Unknown, since it is. 8640411Sbostic */ 8740411Sbostic if (list->isOpen && (list->curPtr == lNode)) { 8840411Sbostic list->curPtr = list->prevPtr; 8940411Sbostic if (list->curPtr == NilListNode) { 9040411Sbostic list->atEnd = Unknown; 9140411Sbostic } 9240411Sbostic } 9340411Sbostic 9440411Sbostic /* 9540411Sbostic * the only way firstPtr can still point to ln is if ln is the last 9640411Sbostic * node on the list (the list is circular, so lNode->nextptr == lNode in 9740411Sbostic * this case). The list is, therefore, empty and is marked as such 9840411Sbostic */ 9940411Sbostic if (list->firstPtr == lNode) { 10040411Sbostic list->firstPtr = NilListNode; 10140411Sbostic } 10240411Sbostic 10340411Sbostic /* 10440411Sbostic * note that the datum is unmolested. The caller must free it as 10540411Sbostic * necessary and as expected. 10640411Sbostic */ 10740411Sbostic if (lNode->useCount == 0) { 10840411Sbostic free ((Address)ln); 10940411Sbostic } else { 11040411Sbostic lNode->flags |= LN_DELETED; 11140411Sbostic } 11240411Sbostic 11340411Sbostic return (SUCCESS); 11440411Sbostic } 11540411Sbostic 116