-
Notifications
You must be signed in to change notification settings - Fork 16
/
Copy pathlist.c
117 lines (90 loc) · 1.83 KB
/
list.c
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
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
#include "list.h"
#include <stdlib.h>
#include "utils.h"
struct list *list_new(void (*free)(void *))
{
struct list *list = safe_zmalloc(sizeof(*list));
list_init(list, free);
return list;
}
void list_init(struct list *list, void (*free)(void *))
{
list->free = free;
list->first = NULL;
list->last = NULL;
list->len = 0;
}
void list_clear(struct list *list)
{
struct list_node *next;
next = list->first;
while (next != NULL) {
struct list_node *curr;
curr = next;
next = next->next;
if (list->free && curr->data)
list->free(curr->data);
free(curr);
}
list->first = NULL;
list->last = NULL;
list->len = 0;
}
void list_free(struct list *list)
{
list_clear(list);
free(list);
}
struct list_node *list_add(struct list *list, void *data)
{
struct list_node *node = safe_zmalloc(sizeof(*node));
node->data = data;
node->next = NULL;
node->prev = list->last;
node->list = list;
if (list_len(list) == 0)
list->first = node;
else
list->last->next = node;
list->last = node;
list->len++;
return node;
}
void list_del(struct list_node *node)
{
struct list *list;
struct list_node *next_temp;
list = node->list;
if (list->first == node)
list->first = node->next;
if (list->last == node)
list->last = node->prev;
next_temp = node->next;
if (node->next)
node->next->prev = node->prev;
if (node->prev)
node->prev->next = next_temp;
list->len--;
free(node);
}
void list_concat(struct list *dst, struct list *src)
{
struct list_node *iter;
if (list_len(src) == 0)
return;
LIST_FOR_EACH(src, iter)
iter->list = dst;
if (dst->len == 0) {
dst->first = src->first;
dst->last = src->last;
dst->len = src->len;
} else {
dst->last->next = src->first;
src->first->prev = dst->last;
dst->last = src->last;
dst->len += src->len;
}
src->first = NULL;
src->last = NULL;
src->len = 0;
}