*/
#include <zebra.h>
+#include <stdlib.h>
#include "linklist.h"
#include "memory.h"
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));
XFREE(MTYPE_LINK_NODE, node);
}
-/* Add new data to the list. */
void listnode_add(struct list *list, void *val)
{
struct listnode *node;
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_head(struct list *list, void *val)
+{
+ struct listnode *node;
+
+ assert(val != NULL);
+
+ node = listnode_new();
+
+ node->next = list->head;
+ node->data = val;
+
+ if (list->head == NULL)
+ list->head = node;
+ else
+ list->head->prev = node;
+ list->head = node;
+
+ list->count++;
+}
+
void listnode_add_sort(struct list *list, void *val)
{
struct listnode *n;
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;
+ struct listnode *node = listnode_lookup(list, val);
- assert(list);
- for (node = list->head; node; node = node->next) {
- if (node->data == val) {
- if (node->prev)
- node->prev->next = node->next;
- else
- list->head = node->next;
-
- if (node->next)
- node->next->prev = node->prev;
- else
- list->tail = node->prev;
-
- list->count--;
- listnode_free(node);
- return;
- }
- }
+ if (node)
+ list_delete_node(list, node);
}
-/* Return first node's data if it is there. */
void *listnode_head(struct list *list)
{
struct listnode *node;
return NULL;
}
-/* Delete all listnode from the list. */
void list_delete_all_node(struct list *list)
{
struct listnode *node;
list->count = 0;
}
-/* Delete all listnode then free list itself. */
-void list_delete_and_null(struct list **list)
+void list_delete(struct list **list)
{
assert(*list);
list_delete_all_node(*list);
*list = NULL;
}
-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;
return NULL;
}
-/* Delete the node from list. For ospfd and ospf6d. */
void list_delete_node(struct list *list, struct listnode *node)
{
if (node->prev)
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 j = 0; j < n; ++j)
+ listnode_add(list, items[j]);
+
+ XFREE(MTYPE_TMP, items);
}