[lib] remove autogenerated file, update .cvsignore
[jleu-quagga.git] / lib / linklist.c
blob11e16a8a4af61e505aef4461d2e1e4bee203db79
1 /* Generic linked list routine.
2 * Copyright (C) 1997, 2000 Kunihiro Ishiguro
4 * This file is part of GNU Zebra.
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.
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.
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.
22 #include <zebra.h>
24 #include "linklist.h"
25 #include "memory.h"
27 /* Allocate new list. */
28 struct list *
29 list_new (void)
31 struct list *new;
33 new = XMALLOC (MTYPE_LINK_LIST, sizeof (struct list));
34 memset (new, 0, sizeof (struct list));
35 return new;
38 /* Free list. */
39 void
40 list_free (struct list *l)
42 XFREE (MTYPE_LINK_LIST, l);
45 /* Allocate new listnode. Internal use only. */
46 static struct listnode *
47 listnode_new (void)
49 struct listnode *node;
51 node = XMALLOC (MTYPE_LINK_NODE, sizeof (struct listnode));
52 memset (node, 0, sizeof (struct listnode));
53 return node;
56 /* Free listnode. */
57 static void
58 listnode_free (struct listnode *node)
60 XFREE (MTYPE_LINK_NODE, node);
63 /* Add new data to the list. */
64 void
65 listnode_add (struct list *list, void *val)
67 struct listnode *node;
69 node = listnode_new ();
71 node->prev = list->tail;
72 node->data = val;
74 if (list->head == NULL)
75 list->head = node;
76 else
77 list->tail->next = node;
78 list->tail = node;
80 list->count++;
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.
89 void
90 listnode_add_sort (struct list *list, void *val)
92 struct listnode *n;
93 struct listnode *new;
95 new = listnode_new ();
96 new->data = val;
98 if (list->cmp)
100 for (n = list->head; n; n = n->next)
102 if ((*list->cmp) (val, n->data) < 0)
104 new->next = n;
105 new->prev = n->prev;
107 if (n->prev)
108 n->prev->next = new;
109 else
110 list->head = new;
111 n->prev = new;
112 list->count++;
113 return;
118 new->prev = list->tail;
120 if (list->tail)
121 list->tail->next = new;
122 else
123 list->head = new;
125 list->tail = new;
126 list->count++;
129 void
130 listnode_add_after (struct list *list, struct listnode *pp, void *val)
132 struct listnode *nn;
134 nn = listnode_new ();
135 nn->data = val;
137 if (pp == NULL)
139 if (list->head)
140 list->head->prev = nn;
141 else
142 list->tail = nn;
144 nn->next = list->head;
145 nn->prev = pp;
147 list->head = nn;
149 else
151 if (pp->next)
152 pp->next->prev = nn;
153 else
154 list->tail = nn;
156 nn->next = pp->next;
157 nn->prev = pp;
159 pp->next = nn;
164 /* Delete specific date pointer from the list. */
165 void
166 listnode_delete (struct list *list, void *val)
168 struct listnode *node;
170 assert(list);
171 for (node = list->head; node; node = node->next)
173 if (node->data == val)
175 if (node->prev)
176 node->prev->next = node->next;
177 else
178 list->head = node->next;
180 if (node->next)
181 node->next->prev = node->prev;
182 else
183 list->tail = node->prev;
185 list->count--;
186 listnode_free (node);
187 return;
192 /* Return first node's data if it is there. */
193 void *
194 listnode_head (struct list *list)
196 struct listnode *node;
198 assert(list);
199 node = list->head;
201 if (node)
202 return node->data;
203 return NULL;
206 /* Delete all listnode from the list. */
207 void
208 list_delete_all_node (struct list *list)
210 struct listnode *node;
211 struct listnode *next;
213 assert(list);
214 for (node = list->head; node; node = next)
216 next = node->next;
217 if (list->del)
218 (*list->del) (node->data);
219 listnode_free (node);
221 list->head = list->tail = NULL;
222 list->count = 0;
225 /* Delete all listnode then free list itself. */
226 void
227 list_delete (struct list *list)
229 assert(list);
230 list_delete_all_node (list);
231 list_free (list);
234 /* Lookup the node which has given data. */
235 struct listnode *
236 listnode_lookup (struct list *list, void *data)
238 struct listnode *node;
240 assert(list);
241 for (node = listhead(list); node; node = listnextnode (node))
242 if (data == listgetdata (node))
243 return node;
244 return NULL;
247 /* Delete the node from list. For ospfd and ospf6d. */
248 void
249 list_delete_node (struct list *list, struct listnode *node)
251 if (node->prev)
252 node->prev->next = node->next;
253 else
254 list->head = node->next;
255 if (node->next)
256 node->next->prev = node->prev;
257 else
258 list->tail = node->prev;
259 list->count--;
260 listnode_free (node);
263 /* ospf_spf.c */
264 void
265 list_add_node_prev (struct list *list, struct listnode *current, void *val)
267 struct listnode *node;
269 node = listnode_new ();
270 node->next = current;
271 node->data = val;
273 if (current->prev == NULL)
274 list->head = node;
275 else
276 current->prev->next = node;
278 node->prev = current->prev;
279 current->prev = node;
281 list->count++;
284 /* ospf_spf.c */
285 void
286 list_add_node_next (struct list *list, struct listnode *current, void *val)
288 struct listnode *node;
290 node = listnode_new ();
291 node->prev = current;
292 node->data = val;
294 if (current->next == NULL)
295 list->tail = node;
296 else
297 current->next->prev = node;
299 node->next = current->next;
300 current->next = node;
302 list->count++;
305 /* ospf_spf.c */
306 void
307 list_add_list (struct list *l, struct list *m)
309 struct listnode *n;
311 for (n = listhead (m); n; n = listnextnode (n))
312 listnode_add (l, n->data);