Blame list.c

Packit 400c17
#include "list.h"
Packit 400c17
Packit 400c17
#include <stdlib.h>
Packit 400c17
Packit 400c17
#include "utils.h"
Packit 400c17
Packit 400c17
struct list *list_new(void (*free)(void *))
Packit 400c17
{
Packit 400c17
	struct list *list = safe_zmalloc(sizeof(*list));
Packit 400c17
Packit 400c17
	list_init(list, free);
Packit 400c17
Packit 400c17
	return list;
Packit 400c17
}
Packit 400c17
Packit 400c17
void list_init(struct list *list, void (*free)(void *))
Packit 400c17
{
Packit 400c17
	list->free = free;
Packit 400c17
	list->first = NULL;
Packit 400c17
	list->last = NULL;
Packit 400c17
	list->len = 0;
Packit 400c17
}
Packit 400c17
Packit 400c17
void list_clear(struct list *list)
Packit 400c17
{
Packit 400c17
	struct list_node *next;
Packit 400c17
Packit 400c17
	next = list->first;
Packit 400c17
	while (next != NULL) {
Packit 400c17
		struct list_node *curr;
Packit 400c17
Packit 400c17
		curr = next;
Packit 400c17
		next = next->next;
Packit 400c17
Packit 400c17
		if (list->free && curr->data)
Packit 400c17
			list->free(curr->data);
Packit 400c17
Packit 400c17
		free(curr);
Packit 400c17
	}
Packit 400c17
Packit 400c17
	list->first = NULL;
Packit 400c17
	list->last = NULL;
Packit 400c17
	list->len = 0;
Packit 400c17
}
Packit 400c17
Packit 400c17
void list_free(struct list *list)
Packit 400c17
{
Packit 400c17
	list_clear(list);
Packit 400c17
	free(list);
Packit 400c17
}
Packit 400c17
Packit 400c17
struct list_node *list_add(struct list *list, void *data)
Packit 400c17
{
Packit 400c17
	struct list_node *node = safe_zmalloc(sizeof(*node));
Packit 400c17
Packit 400c17
	node->data = data;
Packit 400c17
	node->next = NULL;
Packit 400c17
	node->prev = list->last;
Packit 400c17
	node->list = list;
Packit 400c17
Packit 400c17
	if (list_len(list) == 0)
Packit 400c17
		list->first = node;
Packit 400c17
	else
Packit 400c17
		list->last->next = node;
Packit 400c17
	list->last = node;
Packit 400c17
	list->len++;
Packit 400c17
Packit 400c17
	return node;
Packit 400c17
}
Packit 400c17
Packit 400c17
void list_del(struct list_node *node)
Packit 400c17
{
Packit 400c17
	struct list *list;
Packit 400c17
	struct list_node *next_temp;
Packit 400c17
Packit 400c17
	list = node->list;
Packit 400c17
	if (list->first == node)
Packit 400c17
		list->first = node->next;
Packit 400c17
	if (list->last == node)
Packit 400c17
		list->last = node->prev;
Packit 400c17
Packit 400c17
	next_temp = node->next;
Packit 400c17
	if (node->next)
Packit 400c17
		node->next->prev = node->prev;
Packit 400c17
	if (node->prev)
Packit 400c17
		node->prev->next = next_temp;
Packit 400c17
Packit 400c17
	list->len--;
Packit 400c17
Packit 400c17
	free(node);
Packit 400c17
}
Packit 400c17
Packit 400c17
void list_concat(struct list *dst, struct list *src)
Packit 400c17
{
Packit 400c17
	struct list_node *iter;
Packit 400c17
Packit 400c17
	if (list_len(src) == 0)
Packit 400c17
		return;
Packit 400c17
Packit 400c17
	LIST_FOR_EACH(src, iter)
Packit 400c17
		iter->list = dst;
Packit 400c17
Packit 400c17
	if (dst->len == 0) {
Packit 400c17
		dst->first = src->first;
Packit 400c17
		dst->last = src->last;
Packit 400c17
		dst->len = src->len;
Packit 400c17
	} else {
Packit 400c17
		dst->last->next = src->first;
Packit 400c17
		src->first->prev = dst->last;
Packit 400c17
		dst->last = src->last;
Packit 400c17
		dst->len += src->len;
Packit 400c17
	}
Packit 400c17
Packit 400c17
	src->first = NULL;
Packit 400c17
	src->last = NULL;
Packit 400c17
	src->len = 0;
Packit 400c17
}