]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
basic/list: add LIST_JOIN helper
authorLuca Boccassi <luca.boccassi@microsoft.com>
Fri, 17 Jul 2020 17:26:51 +0000 (18:26 +0100)
committerLuca Boccassi <luca.boccassi@microsoft.com>
Wed, 29 Jul 2020 16:12:45 +0000 (17:12 +0100)
Joins together two lists, tail to head.

a -> b
c -> d

a -> b -> c -> d

src/basic/list.h
src/test/test-list.c

index f7f97000e0a2e0e15b0b9628238096e2980bc40b..b62c374985770418b06c3cf1125bf9acc4f124ed 100644 (file)
 
 #define LIST_IS_EMPTY(head)                                             \
         (!(head))
+
+/* Join two lists tail to head: a->b, c->d to a->b->c->d and de-initialise second list */
+#define LIST_JOIN(name,a,b)                                             \
+        do {                                                            \
+                assert(b);                                              \
+                if (!(a))                                               \
+                        (a) = (b);                                      \
+                else {                                                  \
+                        typeof(*(a)) *_head = (b), *_tail;              \
+                        LIST_FIND_TAIL(name, (a), _tail);               \
+                        _tail->name##_next = _head;                     \
+                        _head->name##_prev = _tail;                     \
+                }                                                       \
+                (b) = NULL;                                             \
+        } while (false)
index 24e0496d46b415d8433bf02eadd135287b2ef211..ca5361adb9d599f45abd0c059998c1a2c73ffa1c 100644 (file)
@@ -12,11 +12,14 @@ int main(int argc, const char *argv[]) {
                 LIST_FIELDS(struct list_item, item);
         } list_item;
         LIST_HEAD(list_item, head);
+        LIST_HEAD(list_item, head2);
         list_item items[4];
         list_item *cursor;
 
         LIST_HEAD_INIT(head);
+        LIST_HEAD_INIT(head2);
         assert_se(head == NULL);
+        assert_se(head2 == NULL);
 
         for (i = 0; i < ELEMENTSOF(items); i++) {
                 LIST_INIT(item, &items[i]);
@@ -203,5 +206,49 @@ int main(int argc, const char *argv[]) {
 
         assert_se(head == NULL);
 
+        for (i = 0; i < ELEMENTSOF(items) / 2; i++) {
+                LIST_INIT(item, &items[i]);
+                assert_se(LIST_JUST_US(item, &items[i]));
+                LIST_PREPEND(item, head, &items[i]);
+        }
+
+        for (i = ELEMENTSOF(items) / 2; i < ELEMENTSOF(items); i++) {
+                LIST_INIT(item, &items[i]);
+                assert_se(LIST_JUST_US(item, &items[i]));
+                LIST_PREPEND(item, head2, &items[i]);
+        }
+
+        assert_se(items[0].item_next == NULL);
+        assert_se(items[1].item_next == &items[0]);
+        assert_se(items[2].item_next == NULL);
+        assert_se(items[3].item_next == &items[2]);
+
+        assert_se(items[0].item_prev == &items[1]);
+        assert_se(items[1].item_prev == NULL);
+        assert_se(items[2].item_prev == &items[3]);
+        assert_se(items[3].item_prev == NULL);
+
+        LIST_JOIN(item, head2, head);
+        assert_se(head == NULL);
+
+        assert_se(items[0].item_next == NULL);
+        assert_se(items[1].item_next == &items[0]);
+        assert_se(items[2].item_next == &items[1]);
+        assert_se(items[3].item_next == &items[2]);
+
+        assert_se(items[0].item_prev == &items[1]);
+        assert_se(items[1].item_prev == &items[2]);
+        assert_se(items[2].item_prev == &items[3]);
+        assert_se(items[3].item_prev == NULL);
+
+        LIST_JOIN(item, head, head2);
+        assert_se(head2 == NULL);
+        assert_se(!LIST_IS_EMPTY(head));
+
+        for (i = 0; i < ELEMENTSOF(items); i++)
+                LIST_REMOVE(item, head, &items[i]);
+
+        assert_se(head == NULL);
+
         return 0;
 }