[Libvirt-cim] [PATCH 1/3] libxkutil: Linked list helper

Eduardo Lima (Etrunko) eblima at linux.vnet.ibm.com
Tue Jan 31 21:55:34 UTC 2012


On 01/31/2012 07:39 PM, Eduardo Lima (Etrunko) wrote:
> From: "Eduardo Lima (Etrunko)" <eblima at br.ibm.com>
> 
> Signed-off-by: Eduardo Lima (Etrunko) <eblima at br.ibm.com>
> ---
>  libxkutil/Makefile.am |   51 +++++++---
>  libxkutil/list_util.c |  254 +++++++++++++++++++++++++++++++++++++++++++++++++
>  libxkutil/list_util.h |   73 ++++++++++++++
>  3 files changed, 364 insertions(+), 14 deletions(-)
>  create mode 100644 libxkutil/list_util.c
>  create mode 100644 libxkutil/list_util.h
> 
> diff --git a/libxkutil/Makefile.am b/libxkutil/Makefile.am
> index f1adc03..8d436ad 100644
> --- a/libxkutil/Makefile.am
> +++ b/libxkutil/Makefile.am
> @@ -1,21 +1,44 @@
>  # Copyright IBM Corp. 2007
> +AM_CFLAGS = \
> +	$(CFLAGS_STRICT) \
> +	-DLIBVIRTCIM_CONF=\"@sysconfdir@/@PACKAGE at .conf\"
> 
> -AM_CFLAGS = $(CFLAGS_STRICT) \
> -            -DLIBVIRTCIM_CONF=\"@sysconfdir@/@PACKAGE at .conf\"
> +noinst_HEADERS = \
> +	cs_util.h \
> +	misc_util.h \
> +	device_parsing.h \
> +	xmlgen.h \
> +	infostore.h \
> +	pool_parsing.h \
> +	acl_parsing.h \
> +	list_util.h
> 
> -noinst_HEADERS = cs_util.h misc_util.h device_parsing.h xmlgen.h infostore.h \
> -                 pool_parsing.h acl_parsing.h
> +lib_LTLIBRARIES = \
> +	libxkutil.la
> 
> -lib_LTLIBRARIES = libxkutil.la
> +libxkutil_la_SOURCES = \
> +	cs_util_instance.c \
> +	misc_util.c \
> +	device_parsing.c \
> +	xmlgen.c \
> +	infostore.c \
> +	pool_parsing.c \
> +	acl_parsing.c \
> +	list_util.c
> 
> -libxkutil_la_SOURCES = cs_util_instance.c misc_util.c device_parsing.c \
> -                       xmlgen.c infostore.c pool_parsing.c acl_parsing.c
> -libxkutil_la_LDFLAGS = -version-info @VERSION_INFO@
> -libxkutil_la_LIBADD = @LIBVIRT_LIBS@ \
> -		      @LIBUUID_LIBS@
> +libxkutil_la_LDFLAGS = \
> +	-version-info @VERSION_INFO@
> 
> -noinst_PROGRAMS = xml_parse_test
> +libxkutil_la_LIBADD = \
> +	@LIBVIRT_LIBS@ \
> +	@LIBUUID_LIBS@
> 
> -xml_parse_test_SOURCES = xml_parse_test.c
> -xml_parse_test_LDADD = libxkutil.la \
> -		       @LIBVIRT_LIBS@
> +noinst_PROGRAMS = \
> +	xml_parse_test
> +
> +xml_parse_test_SOURCES = \
> +	xml_parse_test.c
> +
> +xml_parse_test_LDADD = \
> +	libxkutil.la \
> +	@LIBVIRT_LIBS@
> diff --git a/libxkutil/list_util.c b/libxkutil/list_util.c
> new file mode 100644
> index 0000000..9b95864
> --- /dev/null
> +++ b/libxkutil/list_util.c
> @@ -0,0 +1,254 @@
> +/*
> + * Copyright IBM Corp. 2012
> + *
> + * Authors:
> + *  Eduardo Lima (Etrunko) <eblima at br.ibm.com>
> + *
> + * This library is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU Lesser General Public
> + * License as published by the Free Software Foundation; either
> + * version 2.1 of the License, or (at your option) any later version.
> + *
> + * This library is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> + * Lesser General Public License for more details.
> + *
> + * You should have received a copy of the GNU Lesser General Public
> + * License along with this library; if not, write to the Free Software
> + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
> + */
> +#ifdef HAVE_CONFIG_H
> +# include "config.h"
> +#endif
> +
> +#include <stdlib.h>
> +
> +#include "list_util.h"
> +
> +struct _list_node_t {
> +        list_node_t *prev;
> +        list_node_t *next;
> +        void *data;
> +};
> +
> +struct _list_t {
> +        unsigned int count;
> +        list_node_t *head;
> +        list_data_free_cb free_cb;
> +        list_data_cmp_cb cmp_cb;
> +};
> +
> +list_t *list_new(list_data_free_cb free_cb, list_data_cmp_cb cmp_cb)
> +{
> +        list_t *l = calloc(1, sizeof(*l));
> +        if (l == NULL)
> +                return NULL;
> +
> +        l->free_cb = free_cb;
> +        l->cmp_cb = cmp_cb;
> +        return l;
> +}
> +
> +void list_free(list_t *list)
> +{
> +        list_node_t *n, *next;
> +
> +        if (list == NULL || list->head == NULL)
> +                return;
> +
> +        n = list->head;
> +
> +        do {
> +                if (list->free_cb)
> +                        list->free_cb(n->data);
> +
> +                next = n->next;
> +                free(n);
> +                n = next;
> +        } while (n != list->head);
> +
> +        free(list);
> +}
> +
> +void list_append(list_t *list, void *data)
> +{
> +        list_node_t *n;
> +
> +        if (list == NULL)
> +                return;
> +
> +        n = calloc(1, sizeof(*n));
> +
> +        if (n == NULL)
> +                return;
> +
> +        n->data = data;
> +
> +        if (list->head == NULL) { /* empty list */
> +                n->next = n->prev = n;
> +                list->head = n;
> +                goto end;
> +        }
> +
> +        n->next = list->head;
> +        n->prev = list->head->prev;
> +
> +        list->head->prev->next = n;
> +        list->head->prev = n;
> +
> + end:
> +        list->count += 1;
> +}
> +
> +void list_prepend(list_t *list, void *data)
> +{
> +        list_append(list, data);
> +        list->head = list->head->prev;
> +}
> +
> +void *list_find(list_t *list, void *user_data)
> +{
> +        list_node_t *n = list_find_node(list, user_data);
> +        return list_node_data_get(n);
> +}
> +
> +list_node_t *list_find_node(list_t *list, void *user_data)
> +{
> +        list_node_t *n;
> +
> +        if (list == NULL || list->head == NULL || list->cmp_cb == NULL)
> +                return NULL;
> +
> +        n = list->head;
> +        do {
> +                if (list->cmp_cb(n->data, user_data) == 0)
> +                        return n;
> +
> +                n = n->next;
> +        } while (n != list->head);
> +
> +        return NULL;
> +}
> +
> +void list_remove(list_t *list, void *data)
> +{
> +        list_node_t *n = list_find_node(list, data);
> +        list_remove_node(list, n);
> +}
> +
> +void list_remove_node(list_t *list, list_node_t *node)
> +{
> +        if (list == NULL || list->head == NULL || node == NULL)
> +                return;
> +
> +        if (node->next == node) { /* only 1 item */
> +                list->head = NULL;
> +        } else {
> +                if (node == list->head) /* first node */
> +                        list->head = node->next;
> +
> +                node->prev->next = node->next;
> +                node->next->prev = node->prev;
> +        }
> +
> +        if (list->free_cb)
> +                list->free_cb(node->data);
> +
> +        free(node);
> +        list->count -= 1;
> +}
> +
> +bool list_foreach(list_t *list, list_foreach_cb cb, void *user_data)
> +{
> +        list_node_t *node;
> +
> +        if (list == NULL || list->head == NULL)
> +                return true; /* nothing to do */
> +
> +        node = list->head;
> +        do {
> +                if (cb(node->data, user_data) == false)
> +                        return false;
> +
> +                node = node->next;
> +        } while (node != list->head);
> +
> +        return true;
> +}
> +
> +unsigned int list_count(list_t *list)
> +{
> +        if (list == NULL)
> +                return 0;
> +
> +        return list->count;
> +}
> +
> +void *list_node_data_get(list_node_t *node)
> +{
> +        if (node == NULL)
> +                return NULL;
> +
> +        return node->data;
> +}
> +
> +void list_node_data_set(list_node_t *node, void *data)
> +{
> +        if (node == NULL)
> +                return;
> +
> +        node->data = data;
> +}
> +
> +void *list_first(list_t *list)
> +{
> +        return list_node_data_get(list->head);


I am very sorry. I should pay more attention to the details, but I just
saw another potential NULL dereference here. It should actually be the
same as list_last()

+        return list_node_data_get(list_first_node(list));


-- 
Eduardo de Barros Lima
Software Engineer, Open Virtualization
Linux Technology Center - IBM/Brazil
eblima at br.ibm.com




More information about the Libvirt-cim mailing list