list.c

00001 /*
00002  * Copyright (c) 2011 Jiri Svoboda
00003  * All rights reserved.
00004  *
00005  * Redistribution and use in source and binary forms, with or without
00006  * modification, are permitted provided that the following conditions
00007  * are met:
00008  *
00009  * - Redistributions of source code must retain the above copyright
00010  *   notice, this list of conditions and the following disclaimer.
00011  * - Redistributions in binary form must reproduce the above copyright
00012  *   notice, this list of conditions and the following disclaimer in the
00013  *   documentation and/or other materials provided with the distribution.
00014  * - The name of the author may not be used to endorse or promote products
00015  *   derived from this software without specific prior written permission.
00016  *
00017  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
00018  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
00019  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
00020  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
00021  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
00022  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
00023  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
00024  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00025  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
00026  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
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         /* Check whether node is in the list as claimed. */
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 }

Generated on Thu Jun 2 07:45:42 2011 for HelenOS/USB by  doxygen 1.4.7