#ifndef HS_LLIST_H
#define HS_LLIST_H
#define LLIST_FORWARD 1
#define LLIST_BACKWARD 2
struct llist_node_st {
struct llist_node_st *prev;
struct llist_node_st *next;
char data[0];
};
typedef struct {
int size;
struct llist_node_st head;
} LLIST;
typedef int llist_cmp(const void *, const void *);
typedef void llist_op(void *);
typedef void llist_node_op(void *);
LLIST *llist_creat(int size);
void llist_destroy(LLIST *, llist_node_op *);
int llist_insert(LLIST *, const void *data, int mode);
void llist_delet(LLIST *, const void *key, llist_cmp *);
void *llist_find(LLIST *, const void *key, llist_cmp *);
void llist_travel(LLIST *, llist_op *);
int llist_fetch(LLIST *, void *data, const void *key, llist_cmp *);
int llist_getnum(LLIST *);
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "llist.h"
LLIST *llist_creat(int size)
{
LLIST *new;
new = malloc(sizeof(*new));
if (new == NULL) {
return NULL;
}
new->size = size;
new->head.prev = new->head.next = &new->head;
return new;
}
void llist_destroy(LLIST *ptr, llist_node_op *node_op)
{
struct llist_node_st *cur, *save;
for (cur = ptr->head.next; cur != &ptr->head; cur = save) {
save = cur->next;
if (node_op)
node_op(cur->data);
free(cur);
}
free(ptr);
}
void llist_clear(LLIST *ptr, llist_node_op *node_op)
{
struct llist_node_st *cur, *save;
for (cur = ptr->head.next; cur != &ptr->head; cur = save) {
save = cur->next;
if (node_op)
node_op(cur->data);
free(cur);
}
ptr->head.prev = ptr->head.next = cur;
}
int llist_insert(LLIST *ptr, const void *data, int mode)
{
struct llist_node_st *newnode;
newnode = malloc(sizeof(*newnode) + ptr->size);
if (newnode == NULL) {
return -1;
}
memcpy(newnode->data, data, ptr->size);
if (mode == LLIST_FORWARD) {
newnode->next = ptr->head.next;
newnode->prev = &ptr->head;
} else if (mode == LLIST_BACKWARD) {
newnode->next = &ptr->head;
newnode->prev = ptr->head.prev;
}
newnode->next->prev = newnode;
newnode->prev->next = newnode;
return 0;
}
static struct llist_node_st *find__(LLIST *ptr, const void *key, llist_cmp *cmp)
{
struct llist_node_st *cur;
for (cur = ptr->head.next; cur != &ptr->head; cur = cur->next) {
if (!cmp(key, cur->data)) {
break;
}
}
return cur;
}
void llist_delet(LLIST *ptr, const void *key, llist_cmp *cmp)
{
struct llist_node_st *node;
node = find__(ptr, key, cmp);
if (node == &ptr->head) {
return;
}
node->next->prev = node->prev;
node->prev->next = node->next;
free(node);
}
void *llist_find(LLIST *ptr, const void *key, llist_cmp *cmp)
{
struct llist_node_st *node;
node = find__(ptr, key, cmp);
if (node == &ptr->head) {
return NULL;
}
return node->data;
}
void llist_travel(LLIST *ptr, llist_op *op)
{
struct llist_node_st *cur;
for (cur = ptr->head.next; cur != &ptr->head; cur = cur->next) {
op(cur->data);
}
}
int llist_fetch(LLIST *ptr, void *data, const void *key, llist_cmp *cmp)
{
struct llist_node_st *node;
node = find__(ptr, key, cmp);
if (node == &ptr->head) {
return -1;
}
memcpy(data, node->data, ptr->size);
node->prev->next = node->next;
node->next->prev = node->prev;
free(node);
return 0;
}
int llist_getnum(LLIST *ptr)
{
int i;
struct llist_node_st *cur;
for (i = 0, cur = ptr->head.next; \
cur != &ptr->head; \
cur = cur->next, i++)
;
return i;
}