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

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


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);
+}
+
+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 */
-- 
1.7.7.6




More information about the Libvirt-cim mailing list