[Libvirt-cim] [PATCH 1/3] libxkutil: Linked list helper
Sharad Mishra
snmishra at linux.vnet.ibm.com
Wed Feb 1 22:11:05 UTC 2012
On Tue, 2012-01-31 at 19:58 -0200, 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..84b2ba0
> --- /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;
shouldn't you be setting the list->count to "0" here ?
> + 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)
What is the idea of this function. Isn't list_find_node doing something
very similar?
> +{
> + 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_first_node(list));
> +}
> +
> +list_node_t *list_first_node(list_t *list)
> +{
> + if (list == NULL)
> + return NULL;
> +
> + return list->head;
> +}
> +
> +void *list_last(list_t *list)
> +{
> + return list_node_data_get(list_last_node(list));
> +}
> +
> +list_node_t *list_last_node(list_t *list)
> +{
> + if (list == NULL || list->head == NULL)
> + return NULL;
> +
> + return list->head->prev;
> +}
> +
> +void *list_node_next(list_node_t *node)
> +{
> + return list_node_data_get(list_node_next_node(node));
> +}
> +
> +list_node_t *list_node_next_node(list_node_t *node)
> +{
> + if (node == NULL)
> + return NULL;
> +
> + return node->next;
> +}
> +
> +void *list_node_prev(list_node_t *node)
> +{
> + return list_node_data_get(list_node_prev_node(node));
> +}
> +
> +list_node_t *list_node_prev_node(list_node_t *node)
> +{
> + if (node == NULL)
> + return NULL;
> +
> + return node->prev;
> +}
> diff --git a/libxkutil/list_util.h b/libxkutil/list_util.h
> new file mode 100644
> index 0000000..1809c2e
> --- /dev/null
> +++ b/libxkutil/list_util.h
> @@ -0,0 +1,73 @@
> +/*
> + * 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
> + */
> +
> +#ifndef __LIST_UTIL_H
> +#define __LIST_UTIL_H
> +
> +#include <stdbool.h>
> +
> +#ifdef __cplusplus
> +extern "C" {
> +#endif
> +
> +typedef void (*list_data_free_cb)(void *data);
> +typedef int (*list_data_cmp_cb)(void *list_data, void *user_data);
> +typedef bool (*list_foreach_cb)(void *list_data, void *user_data);
> +
> +typedef struct _list_node_t list_node_t;
> +typedef struct _list_t list_t;
> +
> +list_t *list_new(list_data_free_cb free_cb, list_data_cmp_cb cmp_cb);
> +void list_free(list_t *list);
> +
> +void list_append(list_t *list, void *data);
> +void list_prepend(list_t *list, void *data);
> +
> +void *list_find(list_t *list, void *user_data);
> +list_node_t *list_find_node(list_t *list, void *user_data);
> +
> +void list_remove(list_t *list, void *data);
> +void list_remove_node(list_t *list, list_node_t *node);
> +
> +bool list_foreach(list_t *list, list_foreach_cb cb, void *user_data);
> +
> +inline unsigned int list_count(list_t *list);
> +
> +inline void *list_node_data_get(list_node_t *node);
> +inline void list_node_data_set(list_node_t *node, void *data);
> +
> +inline void *list_first(list_t *list);
> +inline list_node_t *list_first_node(list_t *list);
> +
> +inline void *list_last(list_t *list);
> +inline list_node_t *list_last_node(list_t *list);
> +
> +inline void *list_node_next(list_node_t *node);
> +inline list_node_t *list_node_next_node(list_node_t *node);
> +
> +inline void *list_node_prev(list_node_t *node);
> +inline list_node_t *list_node_prev_node(list_node_t *node);
> +
> +#ifdef __cplusplus
> +} /* extern "C" */
> +#endif
> +
> +#endif /* __LIST_UTIL_H */
More information about the Libvirt-cim
mailing list