summaryrefslogtreecommitdiff
path: root/lib/linklist.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/linklist.c')
-rw-r--r--lib/linklist.c61
1 files changed, 42 insertions, 19 deletions
diff --git a/lib/linklist.c b/lib/linklist.c
index 2306dd6d00..2cfa3e7482 100644
--- a/lib/linklist.c
+++ b/lib/linklist.c
@@ -19,6 +19,7 @@
*/
#include <zebra.h>
+#include <stdlib.h>
#include "linklist.h"
#include "memory.h"
@@ -26,7 +27,6 @@
DEFINE_MTYPE_STATIC(LIB, LINK_LIST, "Link List")
DEFINE_MTYPE_STATIC(LIB, LINK_NODE, "Link Node")
-/* Allocate new list. */
struct list *list_new(void)
{
return XCALLOC(MTYPE_LINK_LIST, sizeof(struct list));
@@ -50,7 +50,6 @@ static void listnode_free(struct listnode *node)
XFREE(MTYPE_LINK_NODE, node);
}
-/* Add new data to the list. */
void listnode_add(struct list *list, void *val)
{
struct listnode *node;
@@ -71,12 +70,6 @@ void listnode_add(struct list *list, void *val)
list->count++;
}
-/*
- * Add a node to the list. If the list was sorted according to the
- * cmp function, insert a new node with the given val such that the
- * list remains sorted. The new node is always inserted; there is no
- * notion of omitting duplicates.
- */
void listnode_add_sort(struct list *list, void *val)
{
struct listnode *n;
@@ -185,14 +178,12 @@ struct listnode *listnode_add_before(struct list *list, struct listnode *pp,
return nn;
}
-/* Move given listnode to tail of the list */
void listnode_move_to_tail(struct list *l, struct listnode *n)
{
LISTNODE_DETACH(l, n);
LISTNODE_ATTACH(l, n);
}
-/* Delete specific date pointer from the list. */
void listnode_delete(struct list *list, void *val)
{
struct listnode *node;
@@ -217,7 +208,6 @@ void listnode_delete(struct list *list, void *val)
}
}
-/* Return first node's data if it is there. */
void *listnode_head(struct list *list)
{
struct listnode *node;
@@ -230,7 +220,6 @@ void *listnode_head(struct list *list)
return NULL;
}
-/* Delete all listnode from the list. */
void list_delete_all_node(struct list *list)
{
struct listnode *node;
@@ -247,7 +236,6 @@ void list_delete_all_node(struct list *list)
list->count = 0;
}
-/* Delete all listnode then free list itself. */
void list_delete_and_null(struct list **list)
{
assert(*list);
@@ -261,7 +249,6 @@ void list_delete_original(struct list *list)
list_delete_and_null(&list);
}
-/* Lookup the node which has given data. */
struct listnode *listnode_lookup(struct list *list, void *data)
{
struct listnode *node;
@@ -273,7 +260,6 @@ struct listnode *listnode_lookup(struct list *list, void *data)
return NULL;
}
-/* Delete the node from list. For ospfd and ospf6d. */
void list_delete_node(struct list *list, struct listnode *node)
{
if (node->prev)
@@ -288,11 +274,48 @@ void list_delete_node(struct list *list, struct listnode *node)
listnode_free(node);
}
-/* ospf_spf.c */
-void list_add_list(struct list *l, struct list *m)
+void list_add_list(struct list *list, struct list *add)
{
struct listnode *n;
- for (n = listhead(m); n; n = listnextnode(n))
- listnode_add(l, n->data);
+ for (n = listhead(add); n; n = listnextnode(n))
+ listnode_add(list, n->data);
+}
+
+struct list *list_dup(struct list *list)
+{
+ struct list *new = list_new();
+ struct listnode *ln;
+ void *data;
+
+ new->cmp = list->cmp;
+ new->del = list->del;
+
+ for (ALL_LIST_ELEMENTS_RO(list, ln, data))
+ listnode_add(new, data);
+
+ return new;
+}
+
+void list_sort(struct list *list, int (*cmp)(const void **, const void **))
+{
+ struct listnode *ln, *nn;
+ int i = -1;
+ void *data;
+ size_t n = list->count;
+ void **items = XCALLOC(MTYPE_TMP, (sizeof(void *)) * n);
+ int (*realcmp)(const void *, const void *) =
+ (int (*)(const void *, const void *))cmp;
+
+ for (ALL_LIST_ELEMENTS(list, ln, nn, data)) {
+ items[++i] = data;
+ list_delete_node(list, ln);
+ }
+
+ qsort(items, n, sizeof(void *), realcmp);
+
+ for (unsigned int i = 0; i < n; ++i)
+ listnode_add(list, items[i]);
+
+ XFREE(MTYPE_TMP, items);
}