/***************************************************************************** /** Microsoft LAN Manager **/ /** Copyright(c) Microsoft Corp., 1987-1990 **/ /*****************************************************************************/ /***************************************************************************** File : listhndl.cxx Title : general purpose list handler : Description : this file handles the general purpose list routines History : 16-Oct-1990 VibhasC Created 11-Dec-1990 DonnaLi Fixed include dependencies *****************************************************************************/ /**************************************************************************** *** local defines ***************************************************************************/ #define IS_AGGREGATE_TYPE(NodeType) ( (NodeType == NODE_ARRAY) || \ (NodeType == NODE_STRUCT) ) #define ADJUST_OFFSET(Offset, M, AlignFactor) \ Offset += (M = Offset % AlignFactor) ? (AlignFactor-M) : 0 /**************************************************************************** *** include files ***************************************************************************/ #include "nulldefs.h" extern "C" { #include #include #include #include typedef char far * FARPOINTER; } #include "nodeskl.hxx" #include "gramutil.hxx" /**************************************************************************** *** external procedures ***************************************************************************/ int AttrComp( void *, void *); /**************************************************************************** *** external data ***************************************************************************/ /**************************************************************************** *** local data ***************************************************************************/ /***************************************************************************** * general purpose list (iterator) control functions *****************************************************************************/ gplistmgr::gplistmgr( void ) { pCurrent = pInsert = pFirst = (struct _gplist *)NULL; cCount = 0; fIgnoreAdvance = 0; pfnAlloc = (void *(*)( void ) )NULL; pfnDeAlloc = (void (*)( void * ) )NULL; pfnComp = (int (*)( void *p, void *q) )NULL; } gplistmgr::gplistmgr( void * (*pfnA)( void ) , void (*pfnD)( void * ) ) { pCurrent = pInsert = pFirst = (struct _gplist *)NULL; cCount = 0; fIgnoreAdvance = 0; pfnAlloc = pfnA; pfnDeAlloc = pfnD; } gplistmgr::~gplistmgr( void ) { while(cCount-- && pFirst) { pCurrent = pFirst->pNext; if(pfnDeAlloc != (void (*)( void * ) )NULL) if(pFirst->pElement != (void *)NULL) pfnDeAlloc(pFirst->pElement); delete pFirst; pFirst = pCurrent; } } STATUS_T gplistmgr::Clear( void ) { while(cCount--) { pCurrent = pFirst->pNext; if(pfnDeAlloc != (void (*)( void * ) )NULL) if(pFirst->pElement != (void *)NULL) pfnDeAlloc(pFirst->pElement); delete pFirst; pFirst = pCurrent; } pCurrent = pInsert = pFirst = (struct _gplist *)NULL; cCount = 0; fIgnoreAdvance = 0; return STATUS_OK; } STATUS_T gplistmgr::Insert( void * pNewElement ) { struct _gplist *pNew = new struct _gplist; if(pNew != (struct _gplist *)NULL) { pNew->pNext = (struct _gplist *)NULL; pNew->pPrev = pInsert; pNew->pElement = pNewElement; if(pInsert != (struct _gplist *)NULL) { pInsert->pNext = pNew; } pInsert = pNew; if(pFirst == (struct _gplist *)NULL) pFirst = pNew; if(pCurrent == (struct _gplist *)NULL) pCurrent = pNew; cCount++; return STATUS_OK; } return OUT_OF_MEMORY; } STATUS_T gplistmgr::Remove( void ) { struct _gplist *pN, *pP, *pDel; if(pCurrent == (struct _gplist *)NULL) return I_ERR_NO_PEER; pN = pCurrent->pNext; pP = pCurrent->pPrev; pDel = pCurrent; if(pP) { pP->pNext = pN; pCurrent = pP; } else { pCurrent = pFirst = pN; fIgnoreAdvance = 1; } if(pN) { pN->pPrev = pP; } else { pInsert = pCurrent; } if( pfnDeAlloc != ( void(*)( void *) )NULL ) (*pfnDeAlloc)( (void *)pDel->pElement ); delete pDel; cCount--; return STATUS_OK; } STATUS_T gplistmgr::GetPrev( void **ppReturn ) { if(pCurrent != (struct _gplist *)NULL) if(pCurrent->pPrev != (struct _gplist *)NULL) { pCurrent = pCurrent->pPrev; (*ppReturn) = (void *)pCurrent->pPrev; fIgnoreAdvance = 0; return STATUS_OK; } return I_ERR_NO_PEER; } STATUS_T gplistmgr::GetNext( void **ppReturn ) { if(pCurrent != (struct _gplist *)NULL) { (*ppReturn) = pCurrent->pElement; if(pCurrent != (struct _gplist *)NULL) pCurrent = pCurrent->pNext; fIgnoreAdvance = 0; return STATUS_OK; } return I_ERR_NO_PEER; } STATUS_T gplistmgr::GetCurrent( void **ppReturn ) { if( pCurrent != (struct _gplist *)NULL ) { (*ppReturn) = pCurrent->pElement; fIgnoreAdvance = 0; return STATUS_OK; } return I_ERR_NO_PEER; } STATUS_T gplistmgr::Advance() { if(fIgnoreAdvance && pCurrent) { fIgnoreAdvance = 0; return STATUS_OK; } if(pCurrent && pCurrent->pNext) { fIgnoreAdvance = 0; pCurrent = pCurrent->pNext; return STATUS_OK; } else return I_ERR_NO_PEER; } STATUS_T gplistmgr::Init( void ) { pCurrent = pFirst; fIgnoreAdvance = 0; return STATUS_OK; } STATUS_T gplistmgr::SetAllocFn( void * (*pfn)( void ) ) { pfnAlloc = pfn; return STATUS_OK; } STATUS_T gplistmgr::SetDeAllocFn( void (*pfn)( void *) ) { pfnDeAlloc = pfn; return STATUS_OK; } STATUS_T gplistmgr::SetCompFn( int (*pfn)( void *p, void *q) ) { pfnComp = pfn; return STATUS_OK; } STATUS_T gplistmgr::Sort( void ) { short fSwapped = 1; struct _gplist *p1, *p2; void *pTemp; if( (pfnComp == ( int (*)( void *, void *)) NULL ) || (cCount == 1) ) return STATUS_OK; // bubble sort the attribute nodes while(fSwapped) { p1 = pFirst; p2 = pFirst->pNext; fSwapped = 0; while(p2) { if( (*pfnComp)( p1->pElement, p2->pElement) == 1) { pTemp = p2->pElement; p2->pElement = p1->pElement; p1->pElement = pTemp; fSwapped = 1; } p1 = p2; p2 = p2->pNext; } } return STATUS_OK; } short gplistmgr::GetCount() { return cCount; } /*************************************************************************** * DECL_LIST_MGR class functions **************************************************************************/ decl_list_mgr::decl_list_mgr( void ) { SetAllocFn( (void * (*)( void ) )NULL); SetDeAllocFn( free ); SetCompFn( (int (*)( void *, void * ) )NULL); } STATUS_T decl_list_mgr::AddElement( struct _decl_element **ppElement ) { STATUS_T uError; struct _decl_element *pElement = new struct _decl_element; pElement->pNode = (node_skl *)NULL; pElement->pInit = 0; pElement->fBitField= 0; if( (uError = Insert( (void *)pElement)) == STATUS_OK) (*ppElement) = pElement; return uError; } STATUS_T decl_list_mgr::AddElement( struct _decl_element * pElement ) { struct _decl_element * p = new struct _decl_element; p->pNode = pElement->pNode; p->pInit = pElement->pInit; p->fBitField = pElement->fBitField; Insert( (void *)p); return STATUS_OK; } STATUS_T decl_list_mgr::Merge( decl_list_mgr * pSrcList ) { struct _decl_element * p; if( pSrcList ) { pSrcList->Init(); while( p = pSrcList->GetNextDecl() ) { struct _decl_element * pElement = new struct _decl_element; pElement->pNode = p->pNode; pElement->pInit = p->pInit; pElement->fBitField = p->fBitField; Insert( pElement ); } delete pSrcList; } return STATUS_OK; } void decl_list_mgr::InitList( void ) { Init(); } struct _decl_element * decl_list_mgr::GetNextDecl( void ) { struct _decl_element *pElement; STATUS_T Status; if( (Status = GetNext( (void **) &pElement ) ) == STATUS_OK) return pElement; return (struct _decl_element *)NULL; } short decl_list_mgr::GetDeclCount( void ) { return GetCount(); } /************************************************************************** * public functions for type_node_list **************************************************************************/ type_node_list::type_node_list( void ) { SetAllocFn( (void *(*)(void))NULL ); SetDeAllocFn( (void (*)(void *))NULL ); SetCompFn( (int (*)( void *, void * ) )NULL); } type_node_list::type_node_list( node_skl * p) { SetAllocFn( (void *(*)(void))NULL ); SetDeAllocFn( (void (*)(void *))NULL ); SetCompFn( (int (*)( void *, void * ) )NULL); SetPeer( p ); } STATUS_T type_node_list::SetPeer( class node_skl *pNode ) { return Insert( (void *)pNode ); } STATUS_T type_node_list::GetPeer( class node_skl **pNode ) { return GetNext ( (void **)pNode ); } STATUS_T type_node_list::GetFirst( class node_skl **pNode ) { STATUS_T Status; if( (Status = Init()) == STATUS_OK) { Status = GetNext( (void**)pNode ); } return Status; } STATUS_T type_node_list::Merge( type_node_list *pSrcList ) { node_skl *pNode; if(pSrcList) { pSrcList->Init(); while(pSrcList->GetPeer(&pNode) == STATUS_OK) SetPeer(pNode); delete pSrcList; } return STATUS_OK; } STATUS_T type_node_list::Clone( type_node_list *pSrcList ) { node_skl *pNode; if(pSrcList) { pSrcList->Init(); while(pSrcList->GetPeer(&pNode) == STATUS_OK) SetPeer(pNode); } return STATUS_OK; }