| |
| #include <zebra.h> |
| |
| #include "ospf6_linklist.h" |
| |
| static struct linklist_node * |
| linklist_lookup_node (void *data, struct linklist *linklist) |
| { |
| struct linklist_node *node; |
| |
| for (node = linklist->head; node; node = node->next) |
| { |
| if (linklist->cmp && (*linklist->cmp) (node->data, data) == 0) |
| return node; |
| if (node->data == data) |
| return node; |
| } |
| |
| return NULL; |
| } |
| |
| void * |
| linklist_lookup (void *data, struct linklist *linklist) |
| { |
| struct linklist_node *node; |
| |
| node = linklist_lookup_node (data, linklist); |
| if (node) |
| return node->data; |
| return NULL; |
| } |
| |
| int |
| linklist_add (void *data, struct linklist *linklist) |
| { |
| struct linklist_node *node = NULL, *add; |
| |
| if (linklist_lookup_node (data, linklist)) |
| return -1; |
| |
| add = malloc (sizeof (struct linklist_node)); |
| if (add == NULL) |
| return -1; |
| memset (add, 0, sizeof (struct linklist_node)); |
| add->data = data; |
| |
| if (linklist->cmp) |
| { |
| for (node = linklist->head; node; node = node->next) |
| { |
| if ((*linklist->cmp) (node->data, add->data) > 0) |
| break; |
| } |
| } |
| |
| if (! node) |
| { |
| /* add to tail */ |
| if (linklist->tail) |
| { |
| linklist->tail->next = add; |
| add->prev = linklist->tail; |
| } |
| else |
| { |
| linklist->head = add; |
| add->prev = NULL; |
| } |
| |
| linklist->tail = add; |
| add->next = NULL; |
| } |
| else |
| { |
| /* insert just before 'node' */ |
| if (node->prev) |
| { |
| node->prev->next = add; |
| add->prev = node->prev; |
| } |
| else |
| { |
| linklist->head = add; |
| add->prev = NULL; |
| } |
| |
| add->next = node; |
| node->prev = add; |
| } |
| |
| linklist->count++; |
| return 0; |
| } |
| |
| int |
| linklist_remove (void *data, struct linklist *linklist) |
| { |
| struct linklist_node *rem; |
| |
| rem = linklist_lookup_node (data, linklist); |
| if (rem == NULL) |
| return -1; |
| |
| if (rem->prev) |
| rem->prev->next = rem->next; |
| else |
| linklist->head = rem->next; |
| |
| if (rem->next) |
| rem->next->prev = rem->prev; |
| else |
| linklist->tail = rem->prev; |
| |
| free (rem); |
| linklist->count--; |
| return 0; |
| } |
| |
| void |
| linklist_head (struct linklist *linklist, struct linklist_node *node) |
| { |
| if (linklist->head == NULL) |
| { |
| node->prev = NULL; |
| node->next = NULL; |
| node->data = NULL; |
| return; |
| } |
| |
| node->prev = linklist->head->prev; |
| node->next = linklist->head->next; |
| node->data = linklist->head->data; |
| } |
| |
| int |
| linklist_end (struct linklist_node *node) |
| { |
| if (node->data == NULL && node->next == NULL) |
| return 1; |
| return 0; |
| } |
| |
| void |
| linklist_next (struct linklist_node *node) |
| { |
| if (node->next == NULL) |
| { |
| node->prev = NULL; |
| node->next = NULL; |
| node->data = NULL; |
| return; |
| } |
| |
| node->data = node->next->data; |
| node->prev = node->next->prev; |
| node->next = node->next->next; |
| } |
| |
| struct linklist * |
| linklist_create () |
| { |
| struct linklist *linklist; |
| |
| linklist = malloc (sizeof (struct linklist)); |
| if (linklist == NULL) |
| return NULL; |
| memset (linklist, 0, sizeof (struct linklist)); |
| |
| return linklist; |
| } |
| |
| void |
| linklist_remove_all (struct linklist *linklist) |
| { |
| struct linklist_node node; |
| |
| for (linklist_head (linklist, &node); ! linklist_end (&node); |
| linklist_next (&node)) |
| linklist_remove (node.data, linklist); |
| } |
| |
| void |
| linklist_delete (struct linklist *linklist) |
| { |
| linklist_remove_all (linklist); |
| assert (linklist->count == 0); |
| assert (linklist->head == NULL); |
| assert (linklist->tail == NULL); |
| |
| free (linklist); |
| } |
| |
| |