blob: 71c4db8202e26d7142c67c229db22e2130d40cce [file] [log] [blame]
paul718e3742002-12-13 20:15:29 +00001/* Generic linked list routine.
2 * Copyright (C) 1997, 2000 Kunihiro Ishiguro
3 *
4 * This file is part of GNU Zebra.
5 *
6 * GNU Zebra is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2, or (at your option) any
9 * later version.
10 *
11 * GNU Zebra is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with GNU Zebra; see the file COPYING. If not, write to the Free
18 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
19 * 02111-1307, USA.
20 */
21
22#include <zebra.h>
23
24#include "linklist.h"
25#include "memory.h"
26
27/* Allocate new list. */
28struct list *
paul8cc41982005-05-06 21:25:49 +000029list_new (void)
paul718e3742002-12-13 20:15:29 +000030{
31 struct list *new;
32
33 new = XMALLOC (MTYPE_LINK_LIST, sizeof (struct list));
34 memset (new, 0, sizeof (struct list));
35 return new;
36}
37
38/* Free list. */
39void
40list_free (struct list *l)
41{
42 XFREE (MTYPE_LINK_LIST, l);
43}
44
45/* Allocate new listnode. Internal use only. */
46static struct listnode *
paul8cc41982005-05-06 21:25:49 +000047listnode_new (void)
paul718e3742002-12-13 20:15:29 +000048{
49 struct listnode *node;
50
51 node = XMALLOC (MTYPE_LINK_NODE, sizeof (struct listnode));
52 memset (node, 0, sizeof (struct listnode));
53 return node;
54}
55
56/* Free listnode. */
57static void
58listnode_free (struct listnode *node)
59{
60 XFREE (MTYPE_LINK_NODE, node);
61}
62
63/* Add new data to the list. */
64void
65listnode_add (struct list *list, void *val)
66{
67 struct listnode *node;
68
69 node = listnode_new ();
70
71 node->prev = list->tail;
72 node->data = val;
73
74 if (list->head == NULL)
75 list->head = node;
76 else
77 list->tail->next = node;
78 list->tail = node;
79
80 list->count++;
81}
82
gdt29760212003-12-22 15:56:00 +000083/*
84 * Add a node to the list. If the list was sorted according to the
85 * cmp function, insert a new node with the given val such that the
86 * list remains sorted. The new node is always inserted; there is no
87 * notion of omitting duplicates.
88 */
paul718e3742002-12-13 20:15:29 +000089void
90listnode_add_sort (struct list *list, void *val)
91{
92 struct listnode *n;
93 struct listnode *new;
94
hassoe90fbab2003-12-21 09:51:42 +000095 new = listnode_new ();
96 new->data = val;
paul718e3742002-12-13 20:15:29 +000097
98 if (list->cmp)
99 {
100 for (n = list->head; n; n = n->next)
101 {
hasso47ce02a2003-12-22 16:49:15 +0000102 if ((*list->cmp) (val, n->data) < 0)
paul718e3742002-12-13 20:15:29 +0000103 {
104 new->next = n;
105 new->prev = n->prev;
106
107 if (n->prev)
108 n->prev->next = new;
109 else
110 list->head = new;
111 n->prev = new;
112 list->count++;
113 return;
114 }
115 }
116 }
117
118 new->prev = list->tail;
119
120 if (list->tail)
121 list->tail->next = new;
122 else
123 list->head = new;
124
125 list->tail = new;
126 list->count++;
127}
128
129void
130listnode_add_after (struct list *list, struct listnode *pp, void *val)
131{
132 struct listnode *nn;
133
134 nn = listnode_new ();
135 nn->data = val;
136
137 if (pp == NULL)
138 {
139 if (list->head)
140 list->head->prev = nn;
141 else
142 list->tail = nn;
143
144 nn->next = list->head;
145 nn->prev = pp;
146
147 list->head = nn;
148 }
149 else
150 {
151 if (pp->next)
152 pp->next->prev = nn;
153 else
154 list->tail = nn;
155
156 nn->next = pp->next;
157 nn->prev = pp;
158
159 pp->next = nn;
160 }
161}
162
163
164/* Delete specific date pointer from the list. */
165void
166listnode_delete (struct list *list, void *val)
167{
168 struct listnode *node;
169
paulf2c80652002-12-13 21:44:27 +0000170 assert(list);
paul718e3742002-12-13 20:15:29 +0000171 for (node = list->head; node; node = node->next)
172 {
173 if (node->data == val)
174 {
175 if (node->prev)
176 node->prev->next = node->next;
177 else
178 list->head = node->next;
179
180 if (node->next)
181 node->next->prev = node->prev;
182 else
183 list->tail = node->prev;
184
185 list->count--;
186 listnode_free (node);
187 return;
188 }
189 }
190}
191
192/* Return first node's data if it is there. */
193void *
194listnode_head (struct list *list)
195{
196 struct listnode *node;
197
paulf2c80652002-12-13 21:44:27 +0000198 assert(list);
paul718e3742002-12-13 20:15:29 +0000199 node = list->head;
200
201 if (node)
202 return node->data;
203 return NULL;
204}
205
206/* Delete all listnode from the list. */
207void
208list_delete_all_node (struct list *list)
209{
210 struct listnode *node;
211 struct listnode *next;
212
paulf2c80652002-12-13 21:44:27 +0000213 assert(list);
paul718e3742002-12-13 20:15:29 +0000214 for (node = list->head; node; node = next)
215 {
216 next = node->next;
217 if (list->del)
218 (*list->del) (node->data);
219 listnode_free (node);
220 }
221 list->head = list->tail = NULL;
222 list->count = 0;
223}
224
225/* Delete all listnode then free list itself. */
226void
227list_delete (struct list *list)
228{
229 struct listnode *node;
230 struct listnode *next;
231
paulf2c80652002-12-13 21:44:27 +0000232 assert(list);
paul718e3742002-12-13 20:15:29 +0000233 for (node = list->head; node; node = next)
234 {
235 next = node->next;
236 if (list->del)
237 (*list->del) (node->data);
238 listnode_free (node);
239 }
240 list_free (list);
241}
242
243/* Lookup the node which has given data. */
244struct listnode *
245listnode_lookup (struct list *list, void *data)
246{
hasso52dc7ee2004-09-23 19:18:23 +0000247 struct listnode *node;
paul718e3742002-12-13 20:15:29 +0000248
paulf2c80652002-12-13 21:44:27 +0000249 assert(list);
paul1eb8ef22005-04-07 07:30:20 +0000250 for (node = listhead(list); node; node = listnextnode (node))
251 if (data == listgetdata (node))
paul718e3742002-12-13 20:15:29 +0000252 return node;
253 return NULL;
254}
255
256/* Delete the node from list. For ospfd and ospf6d. */
257void
hasso52dc7ee2004-09-23 19:18:23 +0000258list_delete_node (struct list *list, struct listnode *node)
paul718e3742002-12-13 20:15:29 +0000259{
260 if (node->prev)
261 node->prev->next = node->next;
262 else
263 list->head = node->next;
264 if (node->next)
265 node->next->prev = node->prev;
266 else
267 list->tail = node->prev;
268 list->count--;
269 listnode_free (node);
270}
271
272/* ospf_spf.c */
273void
hasso52dc7ee2004-09-23 19:18:23 +0000274list_add_node_prev (struct list *list, struct listnode *current, void *val)
paul718e3742002-12-13 20:15:29 +0000275{
276 struct listnode *node;
277
278 node = listnode_new ();
279 node->next = current;
280 node->data = val;
281
282 if (current->prev == NULL)
283 list->head = node;
284 else
285 current->prev->next = node;
286
287 node->prev = current->prev;
288 current->prev = node;
289
290 list->count++;
291}
292
293/* ospf_spf.c */
294void
hasso52dc7ee2004-09-23 19:18:23 +0000295list_add_node_next (struct list *list, struct listnode *current, void *val)
paul718e3742002-12-13 20:15:29 +0000296{
297 struct listnode *node;
298
299 node = listnode_new ();
300 node->prev = current;
301 node->data = val;
302
303 if (current->next == NULL)
304 list->tail = node;
305 else
306 current->next->prev = node;
307
308 node->next = current->next;
309 current->next = node;
310
311 list->count++;
312}
313
314/* ospf_spf.c */
315void
316list_add_list (struct list *l, struct list *m)
317{
318 struct listnode *n;
319
paul1eb8ef22005-04-07 07:30:20 +0000320 for (n = listhead (m); n; n = listnextnode (n))
paul718e3742002-12-13 20:15:29 +0000321 listnode_add (l, n->data);
322}