paul | 718e374 | 2002-12-13 20:15:29 +0000 | [diff] [blame] | 1 | |
| 2 | #include <zebra.h> |
| 3 | |
| 4 | #include "ospf6_linklist.h" |
| 5 | |
| 6 | static struct linklist_node * |
| 7 | linklist_lookup_node (void *data, struct linklist *linklist) |
| 8 | { |
| 9 | struct linklist_node *node; |
| 10 | |
| 11 | for (node = linklist->head; node; node = node->next) |
| 12 | { |
| 13 | if (linklist->cmp && (*linklist->cmp) (node->data, data) == 0) |
| 14 | return node; |
| 15 | if (node->data == data) |
| 16 | return node; |
| 17 | } |
| 18 | |
| 19 | return NULL; |
| 20 | } |
| 21 | |
| 22 | void * |
| 23 | linklist_lookup (void *data, struct linklist *linklist) |
| 24 | { |
| 25 | struct linklist_node *node; |
| 26 | |
| 27 | node = linklist_lookup_node (data, linklist); |
| 28 | if (node) |
| 29 | return node->data; |
| 30 | return NULL; |
| 31 | } |
| 32 | |
| 33 | int |
| 34 | linklist_add (void *data, struct linklist *linklist) |
| 35 | { |
| 36 | struct linklist_node *node = NULL, *add; |
| 37 | |
| 38 | if (linklist_lookup_node (data, linklist)) |
| 39 | return -1; |
| 40 | |
| 41 | add = malloc (sizeof (struct linklist_node)); |
| 42 | if (add == NULL) |
| 43 | return -1; |
| 44 | memset (add, 0, sizeof (struct linklist_node)); |
| 45 | add->data = data; |
| 46 | |
| 47 | if (linklist->cmp) |
| 48 | { |
| 49 | for (node = linklist->head; node; node = node->next) |
| 50 | { |
| 51 | if ((*linklist->cmp) (node->data, add->data) > 0) |
| 52 | break; |
| 53 | } |
| 54 | } |
| 55 | |
| 56 | if (! node) |
| 57 | { |
| 58 | /* add to tail */ |
| 59 | if (linklist->tail) |
| 60 | { |
| 61 | linklist->tail->next = add; |
| 62 | add->prev = linklist->tail; |
| 63 | } |
| 64 | else |
| 65 | { |
| 66 | linklist->head = add; |
| 67 | add->prev = NULL; |
| 68 | } |
| 69 | |
| 70 | linklist->tail = add; |
| 71 | add->next = NULL; |
| 72 | } |
| 73 | else |
| 74 | { |
| 75 | /* insert just before 'node' */ |
| 76 | if (node->prev) |
| 77 | { |
| 78 | node->prev->next = add; |
| 79 | add->prev = node->prev; |
| 80 | } |
| 81 | else |
| 82 | { |
| 83 | linklist->head = add; |
| 84 | add->prev = NULL; |
| 85 | } |
| 86 | |
| 87 | add->next = node; |
| 88 | node->prev = add; |
| 89 | } |
| 90 | |
| 91 | linklist->count++; |
| 92 | return 0; |
| 93 | } |
| 94 | |
| 95 | int |
| 96 | linklist_remove (void *data, struct linklist *linklist) |
| 97 | { |
| 98 | struct linklist_node *rem; |
| 99 | |
| 100 | rem = linklist_lookup_node (data, linklist); |
| 101 | if (rem == NULL) |
| 102 | return -1; |
| 103 | |
| 104 | if (rem->prev) |
| 105 | rem->prev->next = rem->next; |
| 106 | else |
| 107 | linklist->head = rem->next; |
| 108 | |
| 109 | if (rem->next) |
| 110 | rem->next->prev = rem->prev; |
| 111 | else |
| 112 | linklist->tail = rem->prev; |
| 113 | |
| 114 | free (rem); |
| 115 | linklist->count--; |
| 116 | return 0; |
| 117 | } |
| 118 | |
| 119 | void |
| 120 | linklist_head (struct linklist *linklist, struct linklist_node *node) |
| 121 | { |
| 122 | if (linklist->head == NULL) |
| 123 | { |
| 124 | node->prev = NULL; |
| 125 | node->next = NULL; |
| 126 | node->data = NULL; |
| 127 | return; |
| 128 | } |
| 129 | |
| 130 | node->prev = linklist->head->prev; |
| 131 | node->next = linklist->head->next; |
| 132 | node->data = linklist->head->data; |
| 133 | } |
| 134 | |
| 135 | int |
| 136 | linklist_end (struct linklist_node *node) |
| 137 | { |
| 138 | if (node->data == NULL && node->next == NULL) |
| 139 | return 1; |
| 140 | return 0; |
| 141 | } |
| 142 | |
| 143 | void |
| 144 | linklist_next (struct linklist_node *node) |
| 145 | { |
| 146 | if (node->next == NULL) |
| 147 | { |
| 148 | node->prev = NULL; |
| 149 | node->next = NULL; |
| 150 | node->data = NULL; |
| 151 | return; |
| 152 | } |
| 153 | |
| 154 | node->data = node->next->data; |
| 155 | node->prev = node->next->prev; |
| 156 | node->next = node->next->next; |
| 157 | } |
| 158 | |
| 159 | struct linklist * |
| 160 | linklist_create () |
| 161 | { |
| 162 | struct linklist *linklist; |
| 163 | |
| 164 | linklist = malloc (sizeof (struct linklist)); |
| 165 | if (linklist == NULL) |
| 166 | return NULL; |
| 167 | memset (linklist, 0, sizeof (struct linklist)); |
| 168 | |
| 169 | return linklist; |
| 170 | } |
| 171 | |
| 172 | void |
| 173 | linklist_remove_all (struct linklist *linklist) |
| 174 | { |
| 175 | struct linklist_node node; |
| 176 | |
| 177 | for (linklist_head (linklist, &node); ! linklist_end (&node); |
| 178 | linklist_next (&node)) |
| 179 | linklist_remove (node.data, linklist); |
| 180 | } |
| 181 | |
| 182 | void |
| 183 | linklist_delete (struct linklist *linklist) |
| 184 | { |
| 185 | linklist_remove_all (linklist); |
| 186 | assert (linklist->count == 0); |
| 187 | assert (linklist->head == NULL); |
| 188 | assert (linklist->tail == NULL); |
| 189 | |
| 190 | free (linklist); |
| 191 | } |
| 192 | |
| 193 | |