--- mstools/samples/deb/linklist.c 2018/08/09 18:20:39 1.1.1.1 +++ mstools/samples/deb/linklist.c 2018/08/09 18:23:34 1.1.1.3 @@ -1,168 +1,178 @@ -// ************************************************************************ -// LinkList.C - Ordered Double Linked List Package -// ************************************************************************ -// PURPOSE: Provide a generalized sorted double linked list package -// -// FUNCTIONS: -// InitList - initialize/clear list -// CreateNode - allocate a new node that can be put into list + +/******************************************************************************\ +* This is a part of the Microsoft Source Code Samples. +* Copyright (C) 1993 Microsoft Corporation. +* All rights reserved. +* This source code is only intended as a supplement to +* Microsoft Development Tools and/or WinHelp documentation. +* See these sources for detailed information regarding the +* Microsoft samples programs. +\******************************************************************************/ + +// ************************************************************************ +// MODULE : LinkList.C - Ordered Double Linked List Package +// PURPOSE : Provide a general, sorted, double linked list package +// FUNCTIONS : +// CreateList - allocate memory for a new list, registers the +// ordering function +// CreateNode - allocate memory fpr a new node that can be put +// into the linked list // InsertNode - insert a new node into the list -// DeleteCurrentNode - remove a node from the list -// GetNextNode - get the next (right) node from the CurrentNode -// GetPreviousNode - get the previous (left) node from the -// CurrentNode -// GetNode - get nth Occurence of a node that matches a -// key(s) -// GetListError - get the error value +// SetCurrentNode - finds the 1st occurence of a node that matches +// a key(s) according to the match function +// and sets it as the current node +// SetCurrentNodeEx - finds the Nth occurence of a node that matches +// a key(s) according to the match function +// and sets it as the current node +// GetCurrentNode - get the current node +// GetFirstNode - get the first (left-most) node in the list +// GetLastNode - get the last (right-most) node in the list +// GetNextNode - get the next (right) node from the current +// GetPrevNode - get the previous (left) node from the current +// DeleteCurrentNode - deletes the current node from the list and +// frees the memory associated with it +// DestroyNode - deallocates the memory associated with a node +// DestroyList - deallocates the memory associated with a list, +// does not delete any of the nodes +// GetListError - gets the current list error // -// COMMENTS: The application must serialize access to the linked list +// COMMENTS : The application must serialize access to the linked list // // Format of the Ordering and Matching functions is as follows: +// ----------------------------------------------------------- // // int OrderFunc( PNODE pNodeOne, PNODE pNodeTwo ) // { -// if( (pNodeOne->NodeData).Key < (pNodeTwo->NodeData).Key ) -// return( LEFT_OF ); -// if( (pNodeOne->NodeData).Key == (pNodeTwo->NodeData).Key ) -// return( MATCH ); -// if( (pNodeOne->NodeData).Key > (pNodeTwo->NodeData).Key ) -// return( RIGHT_OF ); +// if( (pNodeOne->pNodeData).SortKey < (pNodeTwo->pNodeData).SortKey ) +// return( LIST_LEFT_OF ); +// if( (pNodeOne->pNodeData).SortKey == (pNodeTwo->pNodeData).SortKey ) +// return( LIST_MATCH ); +// if( (pNodeOne->pNodeData).SortKey > (pNodeTwo->pNodeData).SortKey ) +// return( LIST_RIGHT_OF ); // } // // ************************************************************************ #include // malloc(), free() -#include // printf() #include "LinkList.H" //-- NULL pointer dereferencing checking macro -#define CHECH_POINTER( Node ) \ - if( Node == NULL ) { \ - printf("Attempt to dereference NULL.\n"); \ - return(pList->ListError = DEREFERENCE_NULL_ERROR); \ +#define CHECK_POINTER( ppNode ) \ + if( ppNode == NULL ) { \ + return( pList->ListError = LIST_ERROR_DEREFERENCE_NULL ); \ } -//-- "member" functions that return the private data -int GetListError( PLIST pList ) { return( pList->ListError ); } -PNODE GetFirstNode( PLIST pList ) { return( pList->pFirstNode ); } -PNODE GetCurrentNode( PLIST pList ) { return( pList->pCurrentNode ); } -PNODE GetLastNode( PLIST pList ) { return( pList->pLastNode ); } - - // ************************************************************************ -// FUNCTION : InitList( PLIST pList, int (*)(PNODE, PNODE) ) -// PURPOSE : initialize/clear list, registers the ordering function -// COMMENTS : +// FUNCTION : CreateList( PLIST* ppList, int (*)(PNODE, PNODE) ) ) +// PURPOSE : allocate a new list, registers the ordering function +// COMMENTS : sets all pointers to NULL // ************************************************************************ -int -InitList( PLIST pList, int (*OrderFunc)( PNODE pNodeOne, PNODE pNodeTwo ) ) +BOOL +CreateList( PLIST* ppList, int (*OrderFunction)( PNODE pNodeOne, PNODE pNodeTwo ) ) { - PNODE pTempNode; - - //-- remove all nodes if the list is not empty - while( ( (pList->pFirstNode) != NULL) && ( (pList->ListError) == NO_ERROR_FOUND) ) { - pTempNode = (pList->pFirstNode); - if( DeleteCurrentNode( pList ) < NO_ERROR_FOUND ) { - (pList->ListError) = NO_NODE_ERROR; - return( pList->ListError ); - } + *ppList = (PLIST) malloc( sizeof(LIST) ); + if( ppList == NULL ) { + (*ppList)->ListError = LIST_NO_ERROR; + return( FALSE ); } - //-- initialize the "private" pointers to NULL - (pList->pFirstNode) = NULL; - (pList->pCurrentNode) = NULL; - (pList->pLastNode) = NULL; - //-- register the link list data ordering function - (pList->OrderFunction) = OrderFunc; + (*ppList)->OrderFunction = OrderFunction; - (pList->ListError) = NO_ERROR_FOUND; - return( pList->ListError ); + //-- initialize the general linked list node pointers to NULL + (*ppList)->pFirstNode = NULL; + (*ppList)->pCurrentNode = NULL; + (*ppList)->pLastNode = NULL; + + //-- indicate no error + (*ppList)->ListError = LIST_NO_ERROR; + + return( TRUE ); } // ************************************************************************ -// FUNCTION : CreateNode( PLIST pList, PNODE* ) +// FUNCTION : CreateNode( PNODE* ) // PURPOSE : create/allocate a new node that can be put into list // COMMENTS : // ************************************************************************ -int -CreateNode( PLIST pList, PNODE* ppNewNode ) +BOOL +CreateNode( PNODE* ppNewNode ) { - (*ppNewNode) = (PNODE) malloc(sizeof(NODE)); - if(*ppNewNode == NULL) { - printf("malloc failed.\n"); - (pList->ListError) = NO_NODE_ERROR; - return( pList->ListError ); + *ppNewNode = (PNODE) malloc( sizeof(NODE) ); + if( *ppNewNode == NULL ) { + return( FALSE ); } - ((*ppNewNode)->pRightLink) = NULL; - ((*ppNewNode)->pLeftLink) = NULL; - (pList->ListError) = NO_ERROR_FOUND; - return( pList->ListError ); + //-- initialize the node pointers to NULL + (*ppNewNode)->pRightLink = NULL; + (*ppNewNode)->pLeftLink = NULL; + + return( TRUE ); } // ************************************************************************ // FUNCTION : InsertNode( PLIST pList, PNODE ) // PURPOSE : insert a new node into the list -// COMMENTS : all nodes must have a unique key entry (from order -// function), if a match is found during an insert then the -// old node gets replaced with the new node -// NOTE: changes pList->pCurrentNode +// COMMENTS : +// All nodes must have a unique key entry (from order function), if a +// match is found during an insert then the old node gets replaced with +// the new node. +// +// NOTE: changes pList->pCurrentNode // ************************************************************************ -int +BOOL InsertNode( PLIST pList, PNODE pNewNode ) { int Position; int LastPosition; - if( (pList->pFirstNode) == NULL ) { - - (pList->pFirstNode) = pNewNode; - (pList->pLastNode) = pNewNode; - (pList->pCurrentNode) = pNewNode; - (pList->ListError) = NO_ERROR_FOUND; - - return( pList->ListError ); + //-- if this is the first node in a new list + if( pList->pFirstNode == NULL ) { + pList->pFirstNode = pNewNode; + pList->pLastNode = pNewNode; + pList->pCurrentNode = pNewNode; + pList->ListError = LIST_NO_ERROR; + return( TRUE ); } Position = (*(pList->OrderFunction))( pNewNode, pList->pCurrentNode ); //-- search for insertion point - while( (pList->pCurrentNode) != NULL ) { + while( pList->pCurrentNode != NULL ) { LastPosition = Position; Position = (*(pList->OrderFunction))(pNewNode, pList->pCurrentNode); - if( (pList->pFirstNode) == (pList->pLastNode) ) + if( pList->pFirstNode == pList->pLastNode ) break; if( Position != LastPosition ) break; - if( (pList->pCurrentNode) == (pList->pFirstNode) ) { - if( Position == RIGHT_OF ) { - (pList->pCurrentNode) = ((pList->pCurrentNode)->pRightLink); + if( pList->pCurrentNode == pList->pFirstNode ) { + if( Position == LIST_RIGHT_OF ) { + pList->pCurrentNode = pList->pCurrentNode->pRightLink; continue; } break; } - if( (pList->pCurrentNode) == (pList->pLastNode) ) { - if( Position == LEFT_OF ) { - (pList->pCurrentNode) = ((pList->pCurrentNode)->pLeftLink); + if( pList->pCurrentNode == pList->pLastNode ) { + if( Position == LIST_LEFT_OF ) { + pList->pCurrentNode = pList->pCurrentNode->pLeftLink; continue; } break; } if( Position == LastPosition ) { - if( Position == LEFT_OF) { - (pList->pCurrentNode) = ((pList->pCurrentNode)->pLeftLink); + if( Position == LIST_LEFT_OF) { + pList->pCurrentNode = pList->pCurrentNode->pLeftLink; continue; } - if( Position == RIGHT_OF ) { - (pList->pCurrentNode) = ((pList->pCurrentNode)->pRightLink); + if( Position == LIST_RIGHT_OF ) { + pList->pCurrentNode = pList->pCurrentNode->pRightLink; continue; } break; @@ -173,189 +183,337 @@ InsertNode( PLIST pList, PNODE pNewNode //-- now, insert the pNewNode switch( Position ) { - case LEFT_OF: - (pNewNode->pRightLink) = (pList->pCurrentNode); - (pNewNode->pLeftLink) = ((pList->pCurrentNode)->pLeftLink); - if( (pList->pCurrentNode) == (pList->pFirstNode) ) - (pList->pFirstNode) = pNewNode; + case LIST_LEFT_OF: + pNewNode->pRightLink = pList->pCurrentNode; + pNewNode->pLeftLink = pList->pCurrentNode->pLeftLink; + if( pList->pCurrentNode == pList->pFirstNode ) + pList->pFirstNode = pNewNode; else - (((pList->pCurrentNode)->pLeftLink)->pRightLink) = pNewNode; - ((pList->pCurrentNode)->pLeftLink) = pNewNode; + pList->pCurrentNode->pLeftLink->pRightLink = pNewNode; + pList->pCurrentNode->pLeftLink = pNewNode; break; - case RIGHT_OF: - (pNewNode->pLeftLink) = (pList->pCurrentNode); - (pNewNode->pRightLink) = ((pList->pCurrentNode)->pRightLink); - if( (pList->pCurrentNode) == (pList->pLastNode) ) - (pList->pLastNode) = pNewNode; + #if 1 // replace duplicates with new data + + case LIST_MATCH: + pNewNode->pLeftLink = pList->pCurrentNode->pLeftLink; + pNewNode->pRightLink = pList->pCurrentNode->pRightLink; + if( pList->pCurrentNode == pList->pLastNode ) + pList->pLastNode = pNewNode; + else + pList->pCurrentNode->pRightLink->pLeftLink = pNewNode; + if( pList->pCurrentNode == pList->pFirstNode ) + pList->pFirstNode = pNewNode; else - (((pList->pCurrentNode)->pRightLink)->pLeftLink) = pNewNode; - ((pList->pCurrentNode)->pRightLink) = pNewNode; + pList->pCurrentNode->pLeftLink->pRightLink = pNewNode; + // note: doesn't destroy extra data associated with the node + DestroyNode( pList->pCurrentNode ); break; - case MATCH: - (pNewNode->pLeftLink) = ((pList->pCurrentNode)->pLeftLink); - (pNewNode->pRightLink) = ((pList->pCurrentNode)->pRightLink); - DestroyNode( pList->pCurrentNode ); + #else // or allow duplicates + + case LIST_MATCH: + + #endif + + case LIST_RIGHT_OF: + pNewNode->pLeftLink = pList->pCurrentNode; + pNewNode->pRightLink = pList->pCurrentNode->pRightLink; + if( pList->pCurrentNode == pList->pLastNode ) + pList->pLastNode = pNewNode; + else + pList->pCurrentNode->pRightLink->pLeftLink = pNewNode; + pList->pCurrentNode->pRightLink = pNewNode; break; } - (pList->pCurrentNode) = pNewNode; + pList->pCurrentNode = pNewNode; + pList->ListError = LIST_NO_ERROR; - (pList->ListError) = NO_ERROR_FOUND; - return( pList->ListError ); + return( TRUE ); } // ************************************************************************ -// FUNCTION : DestroyNode( PNODE ) -// PURPOSE : deallocates a node +// FUNCTION : SetCurrentNode( PLIST pList, PNODE, int (*)(PNODE, PNODE) ) +// PURPOSE : finds the first occurence of a node from the list that matches +// a key(s) according to the match function. // COMMENTS : -// ************************************************************************ -int -DestroyNode( PNODE pNode ) +// May use the ordering function or a new matching function if not +// searching for a match based on the primary ordering key. +// NOTE: the matching and ordering functions have the same definition. +// NOTE: changes pList->pCurrentNode. +// ************************************************************************ +BOOL +SetCurrentNode( PLIST pList, PNODE pKeyNode, + int (*MatchFunction)( PNODE pNodeOne, PNODE pNodeTwo ) ) { - free( pNode ); - return( 1 ); + return( SetCurrentNodeEx( pList, pKeyNode, MatchFunction, 1 ) ); } // ************************************************************************ -// FUNCTION : DeleteCurrentNode( PLIST pList ) -// PURPOSE : delete pList->pCurrentNode from the list and deallocate it -// COMMENTS : changes pList->pCurrentNode. Typically, GetNode is called first so -// pList->pCurrentNode points to the correct node -// ************************************************************************ -int -DeleteCurrentNode( PLIST pList ) +// FUNCTION : SetCurrentNodeEx( PLIST pList, PNODE, int (*)(PNODE, PNODE), int ) +// PURPOSE : finds the Nth occurence of a node from the list that matches +// a key(s) according to the match function. +// COMMENTS : +// May use the ordering function or a new matching function if not +// searching for a match based on the primary ordering key. +// NOTE: the matching and ordering functions have the same definition. +// NOTE: changes pList->pCurrentNode. +// ************************************************************************ +BOOL +SetCurrentNodeEx( PLIST pList, PNODE pKeyNode, + int (*MatchFunction)( PNODE pNodeOne, PNODE pNodeTwo ), + int Occurence ) { - PNODE pOldCurrentNode; + int Position; - if( (pList->pCurrentNode) != NULL ) { - pOldCurrentNode = (pList->pCurrentNode); + //-- if list is empty, exit + if( pList->pCurrentNode == NULL ) { + pList->ListError = LIST_ERROR_NO_NODE; + return( FALSE ); + } - if( pOldCurrentNode == (pList->pFirstNode) ) { - (pList->pFirstNode) = (pOldCurrentNode->pRightLink); - (pList->pCurrentNode) = (pOldCurrentNode->pRightLink); + //-- if match and order are same function + if( MatchFunction == (pList->OrderFunction) ) { + int LastPosition; + + LastPosition = Position = (*MatchFunction)(pKeyNode, pList->pCurrentNode); + + while( Occurence ) { + if( ( Position == LIST_LEFT_OF ) && ( LastPosition == LIST_LEFT_OF ) + && ( pList->pCurrentNode != pList->pFirstNode ) ) + pList->pCurrentNode = pList->pCurrentNode->pLeftLink; + else if( ( Position == LIST_RIGHT_OF ) && ( LastPosition == LIST_RIGHT_OF ) + && ( pList->pCurrentNode != pList->pLastNode ) ) + pList->pCurrentNode = pList->pCurrentNode->pRightLink; + else { + Occurence--; + continue; + } + LastPosition = Position; + Position = (*MatchFunction)(pKeyNode, pList->pCurrentNode); } - else { - ((pOldCurrentNode->pLeftLink)->pRightLink) = (pOldCurrentNode->pRightLink); - (pList->pCurrentNode) = (pOldCurrentNode->pLeftLink); + + } + //-- match and order are not the same function, thus start + // the search at the front of the list + else { + pList->pCurrentNode = pList->pFirstNode; + while( (Occurence > 0) && ( (pList->pCurrentNode) != NULL ) ) { + Position = (*MatchFunction)(pKeyNode, pList->pCurrentNode); + if( Position == LIST_MATCH ) + Occurence--; + if( Occurence > 0 ) + pList->pCurrentNode = pList->pCurrentNode->pRightLink; } + } - if( pOldCurrentNode == (pList->pLastNode) ) - (pList->pLastNode) = (pOldCurrentNode->pLeftLink); - else - ((pOldCurrentNode->pRightLink)->pLeftLink) = (pOldCurrentNode->pLeftLink); + if( ( Position == LIST_MATCH ) && ( Occurence == 0 ) ) { + pList->ListError = LIST_NO_ERROR; + return( TRUE ); + } + pList->ListError = LIST_ERROR_NO_MATCH; + + return( FALSE ); +} - DestroyNode( pOldCurrentNode ); - (pList->ListError) = NO_ERROR_FOUND; - return( pList->ListError ); +// ************************************************************************ +// FUNCTION : GetCurrentNode( PLIST pList, PNODE* ) +// PURPOSE : gets the current node from the list +// COMMENTS : +// Does not change pList->pCurrentNode. +// Changes ppNode, thus do not pass in a ppNode which has additional +// memory associated with it. +// ************************************************************************ +BOOL +GetCurrentNode( PLIST pList, PNODE* ppNode ) +{ + CHECK_POINTER( ppNode ); + if( pList->pCurrentNode == NULL ) { + pList->ListError = LIST_ERROR_NO_NODE; + return( FALSE ); } + *ppNode = pList->pCurrentNode; + pList->ListError = LIST_NO_ERROR; - (pList->ListError) = NO_ERROR_FOUND; - return( pList->ListError ); + return( TRUE ); +} + + +// ************************************************************************ +// FUNCTION : GetFirstNode( PLIST pList, PNODE* ) +// PURPOSE : gets the first (left-most) node from the list +// COMMENTS : +// Does not change pList->pCurrentNode. +// Changes ppNode, thus do not pass in a ppNode which has additional +// memory associated with it. +// ************************************************************************ +BOOL +GetFirstNode( PLIST pList, PNODE* ppNode ) +{ + CHECK_POINTER( ppNode ); + if( pList->pFirstNode == NULL ) { + pList->ListError = LIST_ERROR_NO_NODE; + return( FALSE ); + } + *ppNode = pList->pFirstNode; + pList->ListError = LIST_NO_ERROR; + + return( TRUE ); +} + + +// ************************************************************************ +// FUNCTION : GetLastNode( PLIST pList, PNODE* ) +// PURPOSE : get the last (right-most) node from the List +// COMMENTS : +// Does not change pList->pCurrentNode. +// Changes ppNode, thus do not pass in a ppNode which has additional +// memory associated with it. +// ************************************************************************ +BOOL +GetLastNode( PLIST pList, PNODE* ppNode ) +{ + CHECK_POINTER( ppNode ); + if( pList->pLastNode == NULL ) { + pList->ListError = LIST_ERROR_NO_NODE; + return( FALSE ); + } + *ppNode = pList->pLastNode; + pList->ListError = LIST_NO_ERROR; + + return( TRUE ); } // ************************************************************************ // FUNCTION : GetNextNode( PLIST pList, PNODE* ) // PURPOSE : get the next (right) node from the pList->pCurrentNode -// COMMENTS : Does not change pList->pCurrentNode +// COMMENTS : +// Does not change pList->pCurrentNode. +// Changes ppNode, thus do not pass in a ppNode which has additional +// memory associated with it. // ************************************************************************ -int +BOOL GetNextNode( PLIST pList, PNODE* ppNode ) { - CHECH_POINTER( ppNode ); - if( ((*ppNode)->pRightLink) == NULL ) - return( (pList->ListError) = NO_NEXT_NODE_ERROR ); - (*ppNode) = ((*ppNode)->pRightLink); + CHECK_POINTER( ppNode ); + if( (*ppNode)->pRightLink == NULL ) { + pList->ListError = LIST_ERROR_NO_NODE; + return( FALSE ); + } + *ppNode = (*ppNode)->pRightLink; + pList->ListError = LIST_NO_ERROR; - (pList->ListError) = NO_ERROR_FOUND; - return( pList->ListError ); + return( TRUE ); } // ************************************************************************ -// FUNCTION : GetPreviousNode( PLIST pList, PNODE* ) +// FUNCTION : GetPrevNode( PLIST pList, PNODE* ) // PURPOSE : get the previous (left) node from the pList->pCurrentNode -// COMMENTS : Does not change pList->pCurrentNode +// COMMENTS : +// Does not change pList->pCurrentNode. +// Changes ppNode, thus do not pass in a ppNode which has additional +// memory associated with it. // ************************************************************************ -int -GetPreviousNode( PLIST pList, PNODE* ppNode ) +BOOL +GetPrevNode( PLIST pList, PNODE* ppNode ) { - CHECH_POINTER( ppNode ); - if( ((*ppNode)->pLeftLink) == NULL ) - return( (pList->ListError) = NO_PREV_NODE_ERROR); - (*ppNode) = ((*ppNode)->pLeftLink); + CHECK_POINTER( ppNode ); + if( (*ppNode)->pLeftLink == NULL ) { + pList->ListError = LIST_ERROR_NO_NODE; + return( FALSE ); + } + *ppNode = (*ppNode)->pLeftLink; + pList->ListError = LIST_NO_ERROR; - (pList->ListError) = NO_ERROR_FOUND; - return( pList->ListError ); + return( TRUE ); } // ************************************************************************ -// FUNCTION : GetNode( PLIST pList, PNODE*, int (*)(PNODE, PNODE), int ) -// PURPOSE : get nth Occurence of a node from the list that matches a -// key(s). -// COMMENTS : may use the ordering function or a new matching function -// if not searching for a match based on the primary -// ordering key. Note: the matching and ordering functions -// have the same definition. -// NOTE: changes pList->pCurrentNode +// FUNCTION : DeleteCurrentNode( PLIST pList ) +// PURPOSE : deletes the current node from the list and frees the memory +// associated with it +// COMMENTS : +// Changes pList->pCurrentNode. +// +// Typically, SetCurrentNode (or SetCurrentNodeEx) is called first to set +// pList->pCurrentNode. Also, any addtional memory associated with this +// node should be freed first before calling this function. // ************************************************************************ -int -GetNode( PLIST pList, PNODE* ppKeyNode, - int (*MatchFunction)( PNODE pNodeOne, PNODE pNodeTwo ), - int Occurence ) +BOOL +DeleteCurrentNode( PLIST pList ) { - int Position; + PNODE pOldCurrentNode; - //-- if match and order are same function - if( MatchFunction == (pList->OrderFunction) ) { - int LastPosition; + if( pList->pCurrentNode != NULL ) { + pOldCurrentNode = pList->pCurrentNode; - Position = (*MatchFunction)(*ppKeyNode, pList->pCurrentNode); - LastPosition = Position; - - while( Occurence ) { - if( (Position == LEFT_OF) && (LastPosition == LEFT_OF) - && ( (pList->pCurrentNode) != (pList->pFirstNode) ) ) - (pList->pCurrentNode) = ((pList->pCurrentNode)->pLeftLink); - else if( (Position == RIGHT_OF) && (LastPosition == RIGHT_OF) - && ( (pList->pCurrentNode) != (pList->pLastNode) ) ) - (pList->pCurrentNode) = ((pList->pCurrentNode)->pRightLink); - else { - Occurence--; - continue; - } - LastPosition = Position; - Position = (*MatchFunction)(*ppKeyNode, pList->pCurrentNode); + if( pOldCurrentNode == pList->pFirstNode ) { + pList->pFirstNode = pOldCurrentNode->pRightLink; + pList->pCurrentNode = pOldCurrentNode->pRightLink; } - - } - else { // match and order are not the same function, thus start - // the search at the front of the list - (pList->pCurrentNode) = (pList->pFirstNode); - - while( (Occurence > 0) && ( (pList->pCurrentNode) != NULL)) { - Position = (*MatchFunction)(*ppKeyNode, pList->pCurrentNode); - if(Position == MATCH) - Occurence--; - if(Occurence > 0 ) - (pList->pCurrentNode) = ((pList->pCurrentNode)->pRightLink); + else { + pOldCurrentNode->pLeftLink->pRightLink = pOldCurrentNode->pRightLink; + pList->pCurrentNode = pOldCurrentNode->pLeftLink; } + if( pOldCurrentNode == pList->pLastNode ) + pList->pLastNode = pOldCurrentNode->pLeftLink; + else + pOldCurrentNode->pRightLink->pLeftLink = pOldCurrentNode->pLeftLink; + + DestroyNode( pOldCurrentNode ); + pList->ListError = LIST_NO_ERROR; + return( TRUE ); } + pList->ListError = LIST_NO_ERROR; - if( (Position == MATCH) && (Occurence == 0) ) { - *ppKeyNode = (pList->pCurrentNode); + return( TRUE ); +} - (pList->ListError) = NO_ERROR_FOUND; - return( pList->ListError ); - } - (pList->ListError) = NO_MATCH_ERROR; +// ************************************************************************ +// FUNCTION : DestroyNode( PNODE pNode ) +// PURPOSE : deallocates a node +// COMMENTS : +// ************************************************************************ +BOOL +DestroyNode( PNODE pNode ) +{ + free( pNode ); + + return( TRUE ); +} + + +// ************************************************************************ +// FUNCTION : DestroyList( PLIST pList ) +// PURPOSE : deallocates a list, does not free any nodes, if present +// COMMENTS : +// ************************************************************************ +BOOL +DestroyList( PLIST pList ) +{ + free( pList ); + pList->ListError = LIST_NO_ERROR; + + return( TRUE ); +} + + +// ************************************************************************ +// FUNCTION : GetListError( PLIST pList ) +// PURPOSE : get the last linked list error +// COMMENTS : +// ************************************************************************ +int +GetListError( PLIST pList ) +{ return( pList->ListError ); }