⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 list.c

📁 At can be given its arguments in a file. You can comment out lines by preceding them with either #
💻 C
📖 第 1 页 / 共 2 页
字号:
/* =====================================================
*
* 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 + -