]> git.proxmox.com Git - mirror_frr.git/blame - lib/linklist.c
*: add indent control files
[mirror_frr.git] / lib / linklist.c
CommitLineData
718e3744 1/* 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 *
896014f4
DL
16 * You should have received a copy of the GNU General Public License along
17 * with this program; see the file COPYING; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
718e3744 19 */
20
21#include <zebra.h>
22
23#include "linklist.h"
24#include "memory.h"
6b0655a2 25
4a1ab8e4
DL
26DEFINE_MTYPE_STATIC(LIB, LINK_LIST, "Link List")
27DEFINE_MTYPE_STATIC(LIB, LINK_NODE, "Link Node")
28
718e3744 29/* Allocate new list. */
30struct list *
8cc4198f 31list_new (void)
718e3744 32{
393deb9b 33 return XCALLOC (MTYPE_LINK_LIST, sizeof (struct list));
718e3744 34}
35
36/* Free list. */
37void
38list_free (struct list *l)
39{
40 XFREE (MTYPE_LINK_LIST, l);
41}
42
43/* Allocate new listnode. Internal use only. */
44static struct listnode *
8cc4198f 45listnode_new (void)
718e3744 46{
393deb9b 47 return XCALLOC (MTYPE_LINK_NODE, sizeof (struct listnode));
718e3744 48}
49
50/* Free listnode. */
51static void
52listnode_free (struct listnode *node)
53{
54 XFREE (MTYPE_LINK_NODE, node);
55}
6b0655a2 56
718e3744 57/* Add new data to the list. */
58void
59listnode_add (struct list *list, void *val)
60{
61 struct listnode *node;
5f568084
PJ
62
63 assert (val != NULL);
64
718e3744 65 node = listnode_new ();
66
67 node->prev = list->tail;
68 node->data = val;
69
70 if (list->head == NULL)
71 list->head = node;
72 else
73 list->tail->next = node;
74 list->tail = node;
75
76 list->count++;
77}
78
29760216 79/*
80 * Add a node to the list. If the list was sorted according to the
81 * cmp function, insert a new node with the given val such that the
82 * list remains sorted. The new node is always inserted; there is no
83 * notion of omitting duplicates.
84 */
718e3744 85void
86listnode_add_sort (struct list *list, void *val)
87{
88 struct listnode *n;
89 struct listnode *new;
5f568084
PJ
90
91 assert (val != NULL);
92
e90fbabd 93 new = listnode_new ();
94 new->data = val;
718e3744 95
96 if (list->cmp)
97 {
98 for (n = list->head; n; n = n->next)
99 {
47ce02a8 100 if ((*list->cmp) (val, n->data) < 0)
718e3744 101 {
102 new->next = n;
103 new->prev = n->prev;
104
105 if (n->prev)
106 n->prev->next = new;
107 else
108 list->head = new;
109 n->prev = new;
110 list->count++;
111 return;
112 }
113 }
114 }
115
116 new->prev = list->tail;
117
118 if (list->tail)
119 list->tail->next = new;
120 else
121 list->head = new;
122
123 list->tail = new;
124 list->count++;
125}
126
a8fd8202 127struct listnode *
718e3744 128listnode_add_after (struct list *list, struct listnode *pp, void *val)
129{
130 struct listnode *nn;
5f568084
PJ
131
132 assert (val != NULL);
133
718e3744 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 }
6ce80bdb 161 list->count++;
a8fd8202 162 return nn;
718e3744 163}
164
b21e9619
DL
165struct listnode *
166listnode_add_before (struct list *list, struct listnode *pp, void *val)
167{
168 struct listnode *nn;
169
170 assert (val != NULL);
171
172 nn = listnode_new ();
173 nn->data = val;
174
175 if (pp == NULL)
176 {
177 if (list->tail)
178 list->tail->next = nn;
179 else
180 list->head = nn;
181
182 nn->prev = list->tail;
183 nn->next = pp;
184
185 list->tail = nn;
186 }
187 else
188 {
189 if (pp->prev)
190 pp->prev->next = nn;
191 else
192 list->head = nn;
193
194 nn->prev = pp->prev;
195 nn->next = pp;
196
197 pp->prev = nn;
198 }
199 list->count++;
200 return nn;
201}
202
93559b99
PJ
203/* Move given listnode to tail of the list */
204void
205listnode_move_to_tail (struct list *l, struct listnode *n)
206{
207 LISTNODE_DETACH(l,n);
208 LISTNODE_ATTACH(l,n);
209}
718e3744 210
211/* Delete specific date pointer from the list. */
212void
213listnode_delete (struct list *list, void *val)
214{
215 struct listnode *node;
216
f2c80652 217 assert(list);
718e3744 218 for (node = list->head; node; node = node->next)
219 {
220 if (node->data == val)
221 {
222 if (node->prev)
223 node->prev->next = node->next;
224 else
225 list->head = node->next;
226
227 if (node->next)
228 node->next->prev = node->prev;
229 else
230 list->tail = node->prev;
231
232 list->count--;
233 listnode_free (node);
234 return;
235 }
236 }
237}
238
239/* Return first node's data if it is there. */
240void *
241listnode_head (struct list *list)
242{
243 struct listnode *node;
244
f2c80652 245 assert(list);
718e3744 246 node = list->head;
247
248 if (node)
249 return node->data;
250 return NULL;
251}
252
253/* Delete all listnode from the list. */
254void
255list_delete_all_node (struct list *list)
256{
257 struct listnode *node;
258 struct listnode *next;
259
f2c80652 260 assert(list);
718e3744 261 for (node = list->head; node; node = next)
262 {
263 next = node->next;
264 if (list->del)
265 (*list->del) (node->data);
266 listnode_free (node);
267 }
268 list->head = list->tail = NULL;
269 list->count = 0;
270}
271
272/* Delete all listnode then free list itself. */
273void
274list_delete (struct list *list)
275{
f2c80652 276 assert(list);
c024fd0c 277 list_delete_all_node (list);
718e3744 278 list_free (list);
279}
280
281/* Lookup the node which has given data. */
282struct listnode *
283listnode_lookup (struct list *list, void *data)
284{
52dc7ee6 285 struct listnode *node;
718e3744 286
f2c80652 287 assert(list);
1eb8ef25 288 for (node = listhead(list); node; node = listnextnode (node))
289 if (data == listgetdata (node))
718e3744 290 return node;
291 return NULL;
292}
6b0655a2 293
718e3744 294/* Delete the node from list. For ospfd and ospf6d. */
295void
52dc7ee6 296list_delete_node (struct list *list, struct listnode *node)
718e3744 297{
298 if (node->prev)
299 node->prev->next = node->next;
300 else
301 list->head = node->next;
302 if (node->next)
303 node->next->prev = node->prev;
304 else
305 list->tail = node->prev;
306 list->count--;
307 listnode_free (node);
308}
6b0655a2 309
718e3744 310/* ospf_spf.c */
311void
312list_add_list (struct list *l, struct list *m)
313{
314 struct listnode *n;
315
1eb8ef25 316 for (n = listhead (m); n; n = listnextnode (n))
718e3744 317 listnode_add (l, n->data);
318}