/*clist.h*/
#ifndef CLIST_H_INCLUDED
#define CLIST_H_INCLUDED
#include "stdlib.h"
/*Define a struct for the circular list elements*/
typedef struct CListElmt_
{
void *data;
struct CListElmt_ *next;
}CListElmt;
/*Define a struct for the circular list*/
typedef struct CList_
{
int size;
int (*match)(const void *key1, const void *key2);
void (*destroy)(void *data);
CListElmt *head;
}CList;
#define clist_size(list) (list)->size
#define clist_head(list) (list)->head
#define clist_data(element) (element)->data
#define clist_next(element) (element)->next
/*Public interface*/
void clist_init(CList *list, void (*destroy)(void *data));
void clist_destroy(CList *list);
int clist_ins_next(CList *list, CListElmt *element, void *data);
int clist_rem_next(CList *list, CListElmt *element, void **data);
#endif // CLIST_H_INCLUDED
/*clist.c*/
#include "string.h"
#include "clist.h"
/*Init the clist*/
void clist_init(CList *list, void (*destroy)(void *data))
{
list->size = 0;
list->destroy = destroy;
list->head = NULL;
return;
}
/*Destroy the clist*/
void clist_destroy(CList *list)
{
void *data = NULL;
if (clist_size(list)>0 && NULL != list->destroy)
{
while(0 == clist_rem_next(list, list->head,(void **)& data))
{
list->destroy(data);
}
}
memset(list, 0, sizeof(CList));
return;
}
/*Insert a node after element*/
int clist_ins_next(CList *list, CListElmt *element, void *data)
{
CListElmt *new_element = NULL;
/*allocate storage for the element*/
if(NULL == (new_element = (CListElmt *)malloc(sizeof(CListElmt))))
{
return -1;
}
/*Insert the element into the list*/
new_element->data = data;
if (NULL == element)
{
new_element->next = new_element;
list->head = new_element;
}
else
{
new_element->next = element->next;
element->next = new_element;
}
/*Adjust the size of the list to account for the inserted element*/
list->size++;
return 0;
}
/*Remove element*/
int clist_rem_next(CList *list, CListElmt *element, void **data)
{
CListElmt *old_element = NULL;
if (0 == clist_size(list))
{
return -1;
}
/*Remove the next element*/
*data = element->next->data;
if (element->next == element) //modify it
{
old_element = element;
list->head = NULL;
}
else
{
old_element = element->next;
element->next = element->next->next;
if (old_element == clist_head(list))
{
list->head = old_element->next;
}
}
/*Free the storage allocated by the avstract datatype*/
free(old_element);
/*Adjust the size of the list to account for the removed element*/
list->size--;
return 0;
}