summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWaLyong Cho <walyong.cho@samsung.com>2016-12-14 06:17:57 (GMT)
committerWaLyong Cho <walyong.cho@samsung.com>2016-12-14 11:09:07 (GMT)
commit0164da6f9e922787826894d8377ef846b32ebafb (patch)
treeb8522cca351b9331c68fa68f867df771231db961
parent37e3c166c7079ef304f16e2233e363ce3201ac0b (diff)
downloadlibsystem-0164da6f9e922787826894d8377ef846b32ebafb.zip
libsystem-0164da6f9e922787826894d8377ef846b32ebafb.tar.gz
libsystem-0164da6f9e922787826894d8377ef846b32ebafb.tar.bz2
libsystem: glib-utils: extend glist iterate macro function
Some of additional glist iterate macro functions are added: - FOREACH_G_LIST_DATA() - FOREACH_G_LIST_REVERSE() - FOREACH_G_LIST_SAFE() - FOREACH_G_LIST_SAFE_REVERSE() Change-Id: Ie37b40aded588a4c8e725f86b2185c12c3a2e868 Signed-off-by: WaLyong Cho <walyong.cho@samsung.com>
-rw-r--r--src/Makefile.am13
-rw-r--r--src/libsystem/glib-util.h45
-rw-r--r--src/test/test-foreach-glist.c138
3 files changed, 190 insertions, 6 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index f6cbb81..0b63ea5 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -122,6 +122,19 @@ test_read_write_LDADD = \
tests += test-read-write
# ------------------------------------------------------------------------------
+test_foreach_glist_SOURCES = \
+ test/test-foreach-glist.c
+
+test_foreach_glist_CFLAGS = \
+ $(GIO_CFLAGS)
+
+test_foreach_glist_LDADD = \
+ $(GIO_LIBS) \
+ libsystem.la
+
+tests += test-foreach-glist
+
+# ------------------------------------------------------------------------------
pkgconfiglib_DATA += \
libsystem-sd/libsystem-sd.pc
diff --git a/src/libsystem/glib-util.h b/src/libsystem/glib-util.h
index 7d3c7ad..560acc4 100644
--- a/src/libsystem/glib-util.h
+++ b/src/libsystem/glib-util.h
@@ -30,9 +30,6 @@
#pragma once
#include <glib.h>
-#include <gio/gio.h>
-
-#include "libsystem.h"
#ifdef __cplusplus
extern "C" {
@@ -41,11 +38,47 @@ extern "C" {
/**
* @brief Iterate for each list nodes.
*
- * @param n each list nodes
+ * @param c current node
+ * @param l list to iterate
+ */
+#define FOREACH_G_LIST(c, l) \
+ for (c = g_list_first(l); c; c = g_list_next(c))
+
+/**
+ * @brief Reverse iterate for each list nodes.
+ *
+ * @param c current node
+ * @param l list to iterate
+ */
+#define FOREACH_G_LIST_REVERSE(c, l) \
+ for (c = g_list_last(l); c; c = g_list_previous(c))
+
+/**
+ * @brief Iterate for each list nodes. #FOREACH_G_LIST_SAFE is similar
+ * with #FOREACH_G_LIST but safe for list remove. When you are
+ * iterating a list to remove some of list nodes, you have to use
+ * #FOREACH_G_LIST_SAFE for safe iteration.
+ *
+ * @param c current node
+ * @param n next node of current iteration, this is used for safe iteration
+ * @param l list to iterate
+ */
+#define FOREACH_G_LIST_SAFE(c, n, l) \
+ for (c = g_list_first(l), n = g_list_next(c); c; c = n, n = g_list_next(c))
+
+/**
+ * @brief Reverse iterate for each list
+ * nodes. #FOREACH_G_LIST_SAFE_REVERSE is similar with
+ * #FOREACH_G_LIST_REVERSE but safe for list remove. When you are
+ * iterating a list to remove some of list nodes, you have to use
+ * #FOREACH_G_LIST_SAFE_REVERSE for safe iteration.
+ *
+ * @param c current node
+ * @param p previous node of current iteration, this is used for safe iteration
* @param l list to iterate
*/
-#define FOREACH_G_LIST(n, l) \
- for (n = g_list_first(l); n; n = g_list_next(n))
+#define FOREACH_G_LIST_SAFE_REVERSE(c, p, l) \
+ for (c = g_list_last(l), p = g_list_previous(c); c; c = p, p = g_list_previous(c))
/**
* @brief Convert GError to errno.
diff --git a/src/test/test-foreach-glist.c b/src/test/test-foreach-glist.c
new file mode 100644
index 0000000..ba952e0
--- /dev/null
+++ b/src/test/test-foreach-glist.c
@@ -0,0 +1,138 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/*
+ * libsystem
+ *
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <limits.h>
+#include <glib.h>
+
+#include "libsystem/libsystem.h"
+#include "libsystem/glib-util.h"
+
+static void gen_test_list(GList **list) {
+ GList *l = NULL;
+ int i;
+
+ assert(list);
+ assert(!*list);
+
+ for (i = 1; i <= 10; i++)
+ l = g_list_append(l, GINT_TO_POINTER(i));
+
+ *list = l;
+}
+
+static void test_foreach_g_list(void) {
+ GList *list = NULL, *node;
+ char buf[LINE_MAX];
+ int n = 0;
+
+ gen_test_list(&list);
+
+ FOREACH_G_LIST(node, list) {
+ int i = GPOINTER_TO_INT(node->data);
+
+ n += snprintf(buf + n, LINE_MAX - n - 1, "%d ", i);
+ }
+
+ assert(streq(buf, "1 2 3 4 5 6 7 8 9 10 "));
+
+ g_list_free(list);
+}
+
+static void test_foreach_g_list_reverse(void) {
+ GList *list = NULL, *node;
+ char buf[LINE_MAX];
+ int n = 0;
+
+ gen_test_list(&list);
+
+ FOREACH_G_LIST_REVERSE(node, list) {
+ int i = GPOINTER_TO_INT(node->data);
+
+ n += snprintf(buf + n, LINE_MAX - n - 1, "%d ", i);
+ }
+
+ assert(streq(buf, "10 9 8 7 6 5 4 3 2 1 "));
+
+ g_list_free(list);
+}
+
+static void test_foreach_g_list_safe(void) {
+ GList *list = NULL, *node, *next;
+ char buf[LINE_MAX];
+ int n = 0;
+
+ gen_test_list(&list);
+
+ FOREACH_G_LIST_SAFE(node, next, list) {
+ int i = GPOINTER_TO_INT(node->data);
+
+ if (i % 2)
+ list = g_list_remove_link(list, node);
+ }
+
+ FOREACH_G_LIST(node, list) {
+ int i = GPOINTER_TO_INT(node->data);
+
+ n += snprintf(buf + n, LINE_MAX - n - 1, "%d ", i);
+ }
+
+ assert(streq(buf, "2 4 6 8 10 "));
+
+ g_list_free(list);
+}
+
+static void test_foreach_g_list_safe_reverse(void) {
+ GList *list = NULL, *node, *prev;
+ char buf[LINE_MAX];
+ int n = 0;
+
+ gen_test_list(&list);
+
+ FOREACH_G_LIST_SAFE_REVERSE(node, prev, list) {
+ int i = GPOINTER_TO_INT(node->data);
+
+ if (i % 2)
+ list = g_list_remove_link(list, node);
+ }
+
+ FOREACH_G_LIST_REVERSE(node, list) {
+ int i = GPOINTER_TO_INT(node->data);
+
+ n += snprintf(buf + n, LINE_MAX - n - 1, "%d ", i);
+ }
+
+ assert(streq(buf, "10 8 6 4 2 "));
+
+ g_list_free(list);
+}
+
+int main(int argc, char *argv[]) {
+
+ test_foreach_g_list();
+ test_foreach_g_list_reverse();
+
+ test_foreach_g_list_safe();
+ test_foreach_g_list_safe_reverse();
+
+ return 0;
+}