X-Git-Url: http://git.meshlink.io/?p=meshlink;a=blobdiff_plain;f=src%2Flist.c;h=b93ebfc5f5f59298da1e5ecd73efd5514867dd0d;hp=9b67791120c3746decab18d0d620aaacc954fd05;hb=963c5055505f2fc117cd5efa06eaa02c9b2bf85d;hpb=6dfdb323612184529b4b83c1be914dda8262de47 diff --git a/src/list.c b/src/list.c index 9b677911..b93ebfc5 100644 --- a/src/list.c +++ b/src/list.c @@ -1,7 +1,6 @@ /* list.c -- functions to deal with double linked lists - Copyright (C) 2000-2005 Ivo Timmermans - 2000-2006 Guus Sliepen + Copyright (C) 2014 Guus Sliepen This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -26,9 +25,7 @@ /* (De)constructors */ list_t *list_alloc(list_action_t delete) { - list_t *list; - - list = xmalloc_and_zero(sizeof(list_t)); + list_t *list = xzalloc(sizeof(list_t)); list->delete = delete; return list; @@ -38,13 +35,14 @@ void list_free(list_t *list) { free(list); } -list_node_t *list_alloc_node(void) { - return xmalloc_and_zero(sizeof(list_node_t)); +static list_node_t *list_alloc_node(void) { + return xzalloc(sizeof(list_node_t)); } -void list_free_node(list_t *list, list_node_t *node) { - if(node->data && list->delete) +static void list_free_node(list_t *list, list_node_t *node) { + if(node->data && list->delete) { list->delete(node->data); + } free(node); } @@ -52,19 +50,18 @@ void list_free_node(list_t *list, list_node_t *node) { /* Insertion and deletion */ list_node_t *list_insert_head(list_t *list, void *data) { - list_node_t *node; - - node = list_alloc_node(); + list_node_t *node = list_alloc_node(); node->data = data; node->prev = NULL; node->next = list->head; list->head = node; - if(node->next) + if(node->next) { node->next->prev = node; - else + } else { list->tail = node; + } list->count++; @@ -72,75 +69,40 @@ list_node_t *list_insert_head(list_t *list, void *data) { } list_node_t *list_insert_tail(list_t *list, void *data) { - list_node_t *node; - - node = list_alloc_node(); + list_node_t *node = list_alloc_node(); node->data = data; node->next = NULL; node->prev = list->tail; list->tail = node; - if(node->prev) + if(node->prev) { node->prev->next = node; - else + } else { list->head = node; + } list->count++; return node; } -list_node_t *list_insert_after(list_t *list, list_node_t *after, void *data) { - list_node_t *node; - - node = list_alloc_node(); - - node->data = data; - node->next = after->next; - node->prev = after; - after->next = node; - - if(node->next) - node->next->prev = node; - else - list->tail = node; - - list->count++; - - return node; -} - -list_node_t *list_insert_before(list_t *list, list_node_t *before, void *data) { - list_node_t *node; - - node = list_alloc_node(); - - node->data = data; - node->next = before; - node->prev = before->prev; - before->prev = node; - - if(node->prev) - node->prev->next = node; - else - list->head = node; - - list->count++; +static void list_unlink_node(list_t *list, list_node_t *node) { + assert(list->count); + assert(node->prev || list->head == node); + assert(node->next || list->tail == node); - return node; -} - -void list_unlink_node(list_t *list, list_node_t *node) { - if(node->prev) + if(node->prev) { node->prev->next = node->next; - else + } else { list->head = node->next; + } - if(node->next) + if(node->next) { node->next->prev = node->prev; - else + } else { list->tail = node->prev; + } list->count--; } @@ -158,52 +120,57 @@ void list_delete_tail(list_t *list) { list_delete_node(list, list->tail); } +void list_delete(list_t *list, const void *data) { + for(list_node_t *node = list->head, *next; next = node ? node->next : NULL, node; node = next) { + if(node->data == data) { + list_delete_node(list, node); + } + } +} + /* Head/tail lookup */ void *list_get_head(list_t *list) { - if(list->head) + if(list->head) { return list->head->data; - else + } else { return NULL; + } } void *list_get_tail(list_t *list) { - if(list->tail) + if(list->tail) { return list->tail->data; - else + } else { return NULL; + } } /* Fast list deletion */ void list_delete_list(list_t *list) { - list_node_t *node, *next; - - for(node = list->head; node; node = next) { - next = node->next; + for(list_node_t *node = list->head, *next; next = node ? node->next : NULL, node; node = next) { list_free_node(list, node); + list->count--; } + assert(!list->count); + list_free(list); } /* Traversing */ void list_foreach_node(list_t *list, list_action_node_t action) { - list_node_t *node, *next; - - for(node = list->head; node; node = next) { - next = node->next; + for(list_node_t *node = list->head, *next; next = node ? node->next : NULL, node; node = next) { action(node); } } void list_foreach(list_t *list, list_action_t action) { - list_node_t *node, *next; - - for(node = list->head; node; node = next) { - next = node->next; - if(node->data) + for(list_node_t *node = list->head, *next; next = node ? node->next : NULL, node; node = next) { + if(node->data) { action(node->data); + } } }