📄 list.c
字号:
/* =====================================================
*
* LIST.C
*
* This file contains functions for doubly linked list data structure.
*
* Copyright(c): Martti Ylikoski. 1991
*
* Programmer: Martti Ylikoski
* Created: 15.12.1991
* Version: 1.0
* Note add later user specified data to data structure. E.g.
* in window system we might store all kinds of extra data.
* When we do this, the user must specify functions to handle this
* data.
*
* ====================================================== */
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <string.h>
#include <memory.h>
#include "list.h" /* definitions for doubly linked lists */
/* ===================================
*
* ListInit() - Initialize doubly linked list data struct.
* Space is reserved from main memory for the
* basic list handle. If initialization fails,
* the following return code is returned:
* NULL.
* Add later actioncode !
* ===================================*/
HNDLIST *ListInit(void)
{
HNDLIST *lhandle ;
if ( (lhandle = (HNDLIST *) calloc(1, sizeof(HNDLIST))) != NULL )
{
lhandle->itemscount = 0L ;
lhandle->beginptr = NULL ;
lhandle->endptr = NULL ;
lhandle->currptr = NULL ;
lhandle->currno = 0L ;
return ( lhandle ) ;
}
else
return( NULL ) ;
}
/* ===================================
*
* ListExit() - Free memory used by doubly linked list data structure.
* This function can return one of the following error codes:
* LIST_ERR_BAD_POINTER
*
* ===================================*/
int ListExit(HNDLIST *lhandle)
{
long cnt ;
LIST_ENTRY *tmpptr1, *tmpptr2 ;
if (lhandle == NULL)
return( LIST_ERR_BAD_POINTER ) ;
/* If the list is empty, we merely free the list handle */
if (lhandle->itemscount == 0L)
{
free (lhandle) ;
return(LIST_OK) ;
}
tmpptr1 = lhandle->beginptr ; /* first entry in list */
/* loop as long as there are items in the list or until we
encounter a NULL pointer. */
for (cnt = 0 ; cnt < lhandle->itemscount && tmpptr1 != NULL ; cnt++)
{
tmpptr2 = tmpptr1->next ;
free(tmpptr1->buf) ; /* free data stored in this node */
free(tmpptr1) ; /* free this node */
tmpptr1 = tmpptr2 ;
}
free(lhandle) ; /* free the list handle */
return( LIST_OK ) ;
}
/* ===================================
*
* ListAdd() - Add an item into linked list below the current entry.
* The added entry becomes the current entry.
* This function can return one of the following error codes:
* LIST_ERR_BAD_POINTER
*
* ===================================*/
int ListAdd (HNDLIST *lhandle, void *buf, long buflen )
{
LIST_ENTRY *tmpptr ;
if (lhandle == NULL)
return( LIST_ERR_BAD_POINTER ) ;
/* reserve memory for node */
if ( (tmpptr = (LIST_ENTRY *) calloc(1, sizeof(LIST_ENTRY)) ) != NULL)
{
if ((tmpptr->buf = calloc(1, (size_t) buflen)) != NULL) /* reserve memory for actual data */
{
memcpy(tmpptr->buf, buf, (size_t) buflen) ; /* store data in node */
tmpptr->buflen = buflen ; /* set size of data */
tmpptr->next = NULL ;
tmpptr->prior = NULL ;
}
else
{
free(tmpptr) ;
return( LIST_ERR_MEMORY_ALLOCATION ) ;
}
if (lhandle->beginptr == NULL) /* this is an empty list */
{
lhandle->beginptr = lhandle->endptr = lhandle->currptr = tmpptr ;
lhandle->itemscount ++ ;
lhandle->currno = 1L ;
}
else
{
LIST_ENTRY *tmp1 ;
lhandle->itemscount ++ ;
if (lhandle->currptr == lhandle->endptr ) /* we are at the end of the list */
{
lhandle->endptr = tmpptr ; /* set end pointer to new item */
lhandle->currptr->next = tmpptr ; /* update current pointers next field */
tmpptr->prior = lhandle->currptr ; /* update inserted items prior field */
lhandle->currptr = tmpptr ; /* set current pointer to just inserted item */
lhandle->currno++ ; /* update current entrys number */
}
else
{
tmp1 = lhandle->currptr->next ; /* set temp1 to point to the next item. */
lhandle->currptr->next = tmpptr ; /* update current pointers next field */
tmpptr->prior = lhandle->currptr ; /* update inserted items prior field */
tmpptr->next = tmp1 ; /* set inserted items next field to the item that was next to currptr */
tmp1->prior = tmpptr ; /* set currptr:s next items prior field to just inserted item */
lhandle->currptr = tmpptr ; /* set current pointer to just inserted item */
lhandle->currno++ ; /* update current entrys number */
}
}
}
else
return( LIST_ERR_MEMORY_ALLOCATION ) ;
return ( LIST_OK ) ;
}
/* ===================================
*
* ListInsert() - Insert an item into linked list above the current entry.
* The added entry becomes the current entry.
* This function can return one of the following error codes:
* LIST_ERR_BAD_POINTER
*
* ===================================*/
int ListInsert(HNDLIST *lhandle, void *buf, long buflen)
{
LIST_ENTRY *tmpptr ;
if (lhandle == NULL)
return( LIST_ERR_BAD_POINTER ) ;
if (lhandle->currptr == lhandle->beginptr ) /* we are at the beginning of the list */
{
/* reserve memory for node */
if ( (tmpptr = (LIST_ENTRY *) calloc(1, sizeof(LIST_ENTRY)) ) != NULL)
{
if ((tmpptr->buf = calloc(1, (size_t) buflen)) != NULL) /* reserve memory for actual data */
{
memcpy(tmpptr->buf, buf, (size_t) buflen) ; /* store data in node */
tmpptr->buflen = buflen ; /* set size of data */
tmpptr->next = NULL ;
tmpptr->prior = NULL ;
}
else
{
free(tmpptr) ;
return( LIST_ERR_MEMORY_ALLOCATION ) ;
}
tmpptr->next = lhandle->beginptr ;
lhandle->beginptr->prior = tmpptr ;
lhandle->beginptr = tmpptr ;
lhandle->itemscount ++ ;
lhandle->currno = 1L ;
}
else
return( LIST_ERR_MEMORY_ALLOCATION ) ;
}
else
{
ListPrior(lhandle) ;
ListAdd(lhandle, buf, buflen) ;
}
}
/* ===================================
*
* ListDel() - Remove current entry from the list.
* The entry below becomes the new current entry. The number of
* the current entry does not change. At the end of the list
* the entry above becomes the current entry. The number of the
* current etnry is decremented.
* This function can return one of the following error codes:
* LIST_ERR_BAD_POINTER
* LIST_ERR_NO_CURR
*
* ===================================*/
int ListDel(HNDLIST *lhandle)
{
LIST_ENTRY *tmpl1, *tmpl2 ;
if (lhandle == NULL)
return( LIST_ERR_BAD_POINTER ) ;
if(lhandle->currptr == NULL)
return(LIST_ERR_NO_CURR) ;
if (lhandle->currptr->buflen != 0L)
free(lhandle->currptr->buf) ; /* free the actual data */
if (lhandle->itemscount == 1L) /* last entry on the list */
{
free(lhandle->currptr) ; /* free the node */
lhandle->beginptr = lhandle->endptr = lhandle->currptr = NULL ;
lhandle->itemscount = 0L ;
lhandle->currno = 0L ;
return( LIST_OK ) ;
}
else
{
lhandle->itemscount -- ; /* decrement the items count */
if (lhandle->currptr == lhandle->endptr) /* we are at the end of the list */
{
if (lhandle->beginptr->next == lhandle->endptr) /* only two items in list. We must update beginptr->next also */
lhandle->beginptr->next = NULL ;
lhandle->endptr = lhandle->currptr->prior ; /* set the end of the list to a prior item */
lhandle->endptr->next = NULL ;
free(lhandle->currptr) ; /* free the node */
lhandle->currptr = lhandle->endptr ; /* current pointer stays at the end of the list */
lhandle->currno -- ; /* update current item's number */
}
else if (lhandle->currptr == lhandle->beginptr) /* we are at the beginning of the list */
{
if (lhandle->endptr->prior == lhandle->beginptr) /* only two items in list. We must update endptr->prior also */
lhandle->endptr->prior = NULL ;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -