]>
git.proxmox.com Git - mirror_frr.git/blob - lib/linklist.c
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
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 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
26 DEFINE_MTYPE_STATIC(LIB
, LINK_LIST
, "Link List")
27 DEFINE_MTYPE_STATIC(LIB
, LINK_NODE
, "Link Node")
29 /* Allocate new list. */
30 struct list
*list_new(void)
32 return XCALLOC(MTYPE_LINK_LIST
, sizeof(struct list
));
36 static void list_free_internal(struct list
*l
)
38 XFREE(MTYPE_LINK_LIST
, l
);
41 /* Allocate new listnode. Internal use only. */
42 static struct listnode
*listnode_new(void)
44 return XCALLOC(MTYPE_LINK_NODE
, sizeof(struct listnode
));
48 static void listnode_free(struct listnode
*node
)
50 XFREE(MTYPE_LINK_NODE
, node
);
53 /* Add new data to the list. */
54 void listnode_add(struct list
*list
, void *val
)
56 struct listnode
*node
;
60 node
= listnode_new();
62 node
->prev
= list
->tail
;
65 if (list
->head
== NULL
)
68 list
->tail
->next
= node
;
75 * Add a node to the list. If the list was sorted according to the
76 * cmp function, insert a new node with the given val such that the
77 * list remains sorted. The new node is always inserted; there is no
78 * notion of omitting duplicates.
80 void listnode_add_sort(struct list
*list
, void *val
)
91 for (n
= list
->head
; n
; n
= n
->next
) {
92 if ((*list
->cmp
)(val
, n
->data
) < 0) {
107 new->prev
= list
->tail
;
110 list
->tail
->next
= new;
118 struct listnode
*listnode_add_after(struct list
*list
, struct listnode
*pp
,
130 list
->head
->prev
= nn
;
134 nn
->next
= list
->head
;
153 struct listnode
*listnode_add_before(struct list
*list
, struct listnode
*pp
,
165 list
->tail
->next
= nn
;
169 nn
->prev
= list
->tail
;
188 /* Move given listnode to tail of the list */
189 void listnode_move_to_tail(struct list
*l
, struct listnode
*n
)
191 LISTNODE_DETACH(l
, n
);
192 LISTNODE_ATTACH(l
, n
);
195 /* Delete specific date pointer from the list. */
196 void listnode_delete(struct list
*list
, void *val
)
198 struct listnode
*node
;
201 for (node
= list
->head
; node
; node
= node
->next
) {
202 if (node
->data
== val
) {
204 node
->prev
->next
= node
->next
;
206 list
->head
= node
->next
;
209 node
->next
->prev
= node
->prev
;
211 list
->tail
= node
->prev
;
220 /* Return first node's data if it is there. */
221 void *listnode_head(struct list
*list
)
223 struct listnode
*node
;
233 /* Delete all listnode from the list. */
234 void list_delete_all_node(struct list
*list
)
236 struct listnode
*node
;
237 struct listnode
*next
;
240 for (node
= list
->head
; node
; node
= next
) {
243 (*list
->del
)(node
->data
);
246 list
->head
= list
->tail
= NULL
;
250 /* Delete all listnode then free list itself. */
251 void list_delete_and_null(struct list
**list
)
254 list_delete_all_node(*list
);
255 list_free_internal(*list
);
259 void list_delete_original(struct list
*list
)
261 list_delete_and_null(&list
);
264 /* Lookup the node which has given data. */
265 struct listnode
*listnode_lookup(struct list
*list
, void *data
)
267 struct listnode
*node
;
270 for (node
= listhead(list
); node
; node
= listnextnode(node
))
271 if (data
== listgetdata(node
))
276 /* Delete the node from list. For ospfd and ospf6d. */
277 void list_delete_node(struct list
*list
, struct listnode
*node
)
280 node
->prev
->next
= node
->next
;
282 list
->head
= node
->next
;
284 node
->next
->prev
= node
->prev
;
286 list
->tail
= node
->prev
;
292 void list_add_list(struct list
*l
, struct list
*m
)
296 for (n
= listhead(m
); n
; n
= listnextnode(n
))
297 listnode_add(l
, n
->data
);