diff options
author | paul <paul> | 2002-12-13 20:15:29 +0000 |
---|---|---|
committer | paul <paul> | 2002-12-13 20:15:29 +0000 |
commit | 85f97d27207a5a29357da0c8a6abe8e48bf8ea2c (patch) | |
tree | d20e362762c4963f1150b224356643bd49df7dfb /ospf6d/ospf6_linklist.c | |
download | quagga-85f97d27207a5a29357da0c8a6abe8e48bf8ea2c.tar.bz2 quagga-85f97d27207a5a29357da0c8a6abe8e48bf8ea2c.tar.xz |
Initial revision
Diffstat (limited to 'ospf6d/ospf6_linklist.c')
-rw-r--r-- | ospf6d/ospf6_linklist.c | 193 |
1 files changed, 193 insertions, 0 deletions
diff --git a/ospf6d/ospf6_linklist.c b/ospf6d/ospf6_linklist.c new file mode 100644 index 00000000..8c179359 --- /dev/null +++ b/ospf6d/ospf6_linklist.c @@ -0,0 +1,193 @@ + +#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); +} + + |