summaryrefslogtreecommitdiff
path: root/xpp/xtalk/xlist.c
blob: d28debdbad07562f8f94532d088481f78fa5dde6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include <xlist.h>

struct xlist_node *xlist_new(void *data)
{
	struct xlist_node	*list;

	if((list = malloc(sizeof(*list))) == NULL)
		return NULL;
	list->next = list;
	list->prev = list;
	list->data = data;
	return list;
}

void xlist_destroy(struct xlist_node *list, xlist_destructor_t destructor)
{
	struct xlist_node	*curr;
	struct xlist_node	*next;

	if (! list)
		return;
	curr = list->next;
	while(curr != list) {
		next = curr->next;
		if(destructor)
			destructor(curr->data);
		memset(curr, 0, sizeof(*curr));
		free(curr);
		curr = next;
	}
	memset(list, 0, sizeof(*list));
	free(list);
}

void xlist_append_item(struct xlist_node *list, struct xlist_node *item)
{
	assert(list);
	assert(xlist_empty(item));
	item->next = list;
	item->prev = list->prev;
	list->prev->next = item;
	list->prev = item;
}

void xlist_prepend_item(struct xlist_node *list, struct xlist_node *item)
{
	assert(list);
	assert(xlist_empty(item));
	item->prev = list;
	item->next = list->next;
	list->next->prev = item;
	list->next = item;
}

void xlist_remove_item(struct xlist_node *item)
{
	assert(item);
	item->prev->next = item->next;
	item->next->prev = item->prev;
	item->next = item->prev = item;
}

struct xlist_node *xlist_shift(struct xlist_node *list)
{
	struct xlist_node	*item;

	if(!list)
		return NULL;
	if(xlist_empty(list))
		return NULL;
	item = list->next;
	xlist_remove_item(item);
	return item;
}

int xlist_empty(const struct xlist_node *list)
{
	assert(list);
	return list->next == list && list->prev == list;
}

size_t xlist_length(const struct xlist_node *list)
{
	struct xlist_node	*curr;
	size_t			count = 0;

	for(curr = list->next; curr != list; curr = curr->next)
		count++;
	return count;
}