]> git.proxmox.com Git - mirror_frr.git/blob - ospf6d/ospf6_linklist.c
8c17935923120cc7de63777e4df117d48712bed0
[mirror_frr.git] / ospf6d / ospf6_linklist.c
1
2 #include <zebra.h>
3
4 #include "ospf6_linklist.h"
5
6 static struct linklist_node *
7 linklist_lookup_node (void *data, struct linklist *linklist)
8 {
9 struct linklist_node *node;
10
11 for (node = linklist->head; node; node = node->next)
12 {
13 if (linklist->cmp && (*linklist->cmp) (node->data, data) == 0)
14 return node;
15 if (node->data == data)
16 return node;
17 }
18
19 return NULL;
20 }
21
22 void *
23 linklist_lookup (void *data, struct linklist *linklist)
24 {
25 struct linklist_node *node;
26
27 node = linklist_lookup_node (data, linklist);
28 if (node)
29 return node->data;
30 return NULL;
31 }
32
33 int
34 linklist_add (void *data, struct linklist *linklist)
35 {
36 struct linklist_node *node = NULL, *add;
37
38 if (linklist_lookup_node (data, linklist))
39 return -1;
40
41 add = malloc (sizeof (struct linklist_node));
42 if (add == NULL)
43 return -1;
44 memset (add, 0, sizeof (struct linklist_node));
45 add->data = data;
46
47 if (linklist->cmp)
48 {
49 for (node = linklist->head; node; node = node->next)
50 {
51 if ((*linklist->cmp) (node->data, add->data) > 0)
52 break;
53 }
54 }
55
56 if (! node)
57 {
58 /* add to tail */
59 if (linklist->tail)
60 {
61 linklist->tail->next = add;
62 add->prev = linklist->tail;
63 }
64 else
65 {
66 linklist->head = add;
67 add->prev = NULL;
68 }
69
70 linklist->tail = add;
71 add->next = NULL;
72 }
73 else
74 {
75 /* insert just before 'node' */
76 if (node->prev)
77 {
78 node->prev->next = add;
79 add->prev = node->prev;
80 }
81 else
82 {
83 linklist->head = add;
84 add->prev = NULL;
85 }
86
87 add->next = node;
88 node->prev = add;
89 }
90
91 linklist->count++;
92 return 0;
93 }
94
95 int
96 linklist_remove (void *data, struct linklist *linklist)
97 {
98 struct linklist_node *rem;
99
100 rem = linklist_lookup_node (data, linklist);
101 if (rem == NULL)
102 return -1;
103
104 if (rem->prev)
105 rem->prev->next = rem->next;
106 else
107 linklist->head = rem->next;
108
109 if (rem->next)
110 rem->next->prev = rem->prev;
111 else
112 linklist->tail = rem->prev;
113
114 free (rem);
115 linklist->count--;
116 return 0;
117 }
118
119 void
120 linklist_head (struct linklist *linklist, struct linklist_node *node)
121 {
122 if (linklist->head == NULL)
123 {
124 node->prev = NULL;
125 node->next = NULL;
126 node->data = NULL;
127 return;
128 }
129
130 node->prev = linklist->head->prev;
131 node->next = linklist->head->next;
132 node->data = linklist->head->data;
133 }
134
135 int
136 linklist_end (struct linklist_node *node)
137 {
138 if (node->data == NULL && node->next == NULL)
139 return 1;
140 return 0;
141 }
142
143 void
144 linklist_next (struct linklist_node *node)
145 {
146 if (node->next == NULL)
147 {
148 node->prev = NULL;
149 node->next = NULL;
150 node->data = NULL;
151 return;
152 }
153
154 node->data = node->next->data;
155 node->prev = node->next->prev;
156 node->next = node->next->next;
157 }
158
159 struct linklist *
160 linklist_create ()
161 {
162 struct linklist *linklist;
163
164 linklist = malloc (sizeof (struct linklist));
165 if (linklist == NULL)
166 return NULL;
167 memset (linklist, 0, sizeof (struct linklist));
168
169 return linklist;
170 }
171
172 void
173 linklist_remove_all (struct linklist *linklist)
174 {
175 struct linklist_node node;
176
177 for (linklist_head (linklist, &node); ! linklist_end (&node);
178 linklist_next (&node))
179 linklist_remove (node.data, linklist);
180 }
181
182 void
183 linklist_delete (struct linklist *linklist)
184 {
185 linklist_remove_all (linklist);
186 assert (linklist->count == 0);
187 assert (linklist->head == NULL);
188 assert (linklist->tail == NULL);
189
190 free (linklist);
191 }
192
193