00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00036 #include <stdio.h>
00037 #include <stdlib.h>
00038 #include <assert.h>
00039 #include "mytypes.h"
00040
00041 #include "list.h"
00042
00043 static list_node_t *list_node_new(void *data);
00044 static void list_node_delete(list_node_t *node);
00045 static void list_node_insert_between(list_node_t *n, list_node_t *a, list_node_t *b);
00046 static void list_node_unlink(list_node_t *n);
00047 static bool_t list_node_present(list_t *list, list_node_t *node);
00048
00053 void list_init(list_t *list)
00054 {
00055 list->head.prev = &list->head;
00056 list->head.next = &list->head;
00057 }
00058
00063 void list_fini(list_t *list)
00064 {
00065 assert(list_is_empty(list));
00066
00067 list->head.prev = NULL;
00068 list->head.next = NULL;
00069 }
00070
00078 void list_append(list_t *list, void *data)
00079 {
00080 list_node_t *node;
00081
00082 node = list_node_new(data);
00083 list_node_insert_between(node, list->head.prev, &list->head);
00084 }
00085
00093 void list_prepend(list_t *list, void *data)
00094 {
00095 list_node_t *node;
00096
00097 node = list_node_new(data);
00098 list_node_insert_between(node, list->head.prev, &list->head);
00099 }
00100
00110 void list_remove(list_t *list, list_node_t *node)
00111 {
00112
00113 assert(list_node_present(list, node));
00114 list_node_unlink(node);
00115 node->data = NULL;
00116 list_node_delete(node);
00117 }
00118
00124 list_node_t *list_first(list_t *list)
00125 {
00126 list_node_t *node;
00127
00128 assert(list != NULL);
00129 node = list->head.next;
00130
00131 return (node != &list->head) ? node : NULL;
00132 }
00133
00139 list_node_t *list_last(list_t *list)
00140 {
00141 list_node_t *node;
00142
00143 assert(list != NULL);
00144 node = list->head.prev;
00145
00146 return (node != &list->head) ? node : NULL;
00147 }
00148
00155 list_node_t *list_next(list_t *list, list_node_t *node)
00156 {
00157 (void) list;
00158 assert(list != NULL);
00159 assert(node != NULL);
00160
00161 return (node->next != &list->head) ? node->next : NULL;
00162 }
00163
00170 list_node_t *list_prev(list_t *list, list_node_t *node)
00171 {
00172 (void) list;
00173 assert(list != NULL);
00174 assert(node != NULL);
00175
00176 return (node->prev != &list->head) ? node->prev : NULL;
00177 }
00178
00184 bool_t list_is_empty(list_t *list)
00185 {
00186 return (list_first(list) == NULL);
00187 }
00188
00196 void list_node_setdata(list_node_t *node, void *data)
00197 {
00198 node->data = data;
00199 }
00200
00206 static list_node_t *list_node_new(void *data)
00207 {
00208 list_node_t *node;
00209
00210 node = malloc(sizeof(list_node_t));
00211 if (node == NULL) {
00212 printf("Memory allocation failed.\n");
00213 exit(1);
00214 }
00215
00216 node->prev = NULL;
00217 node->next = NULL;
00218 node->data = data;
00219
00220 return node;
00221 }
00222
00227 static void list_node_delete(list_node_t *node)
00228 {
00229 assert(node->prev == NULL);
00230 assert(node->next == NULL);
00231 assert(node->data == NULL);
00232 free(node);
00233 }
00234
00243 static void list_node_insert_between(list_node_t *n, list_node_t *a,
00244 list_node_t *b)
00245 {
00246 assert(n->prev == NULL);
00247 assert(n->next == NULL);
00248 n->prev = a;
00249 n->next = b;
00250
00251 assert(a->next == b);
00252 assert(b->prev == a);
00253 a->next = n;
00254 b->prev = n;
00255 }
00256
00263 static void list_node_unlink(list_node_t *n)
00264 {
00265 list_node_t *a, *b;
00266 assert(n->prev != NULL);
00267 assert(n->next != NULL);
00268
00269 a = n->prev;
00270 b = n->next;
00271
00272 assert(a->next == n);
00273 assert(b->prev == n);
00274
00275 a->next = b;
00276 b->prev = a;
00277
00278 n->prev = NULL;
00279 n->next = NULL;
00280 }
00281
00288 static bool_t list_node_present(list_t *list, list_node_t *node)
00289 {
00290 list_node_t *m;
00291
00292 m = list->head.next;
00293 while (m != &list->head) {
00294 if (m == node)
00295 return b_true;
00296 m = m->next;
00297 }
00298
00299 return b_false;
00300 }