chiark / gitweb /
basic: add LIST_INSERT_BEFORE
authorAlex Crawford <alex.crawford@coreos.com>
Tue, 4 Aug 2015 06:11:53 +0000 (23:11 -0700)
committerSven Eden <yamakuzure@gmx.net>
Tue, 14 Mar 2017 09:18:46 +0000 (10:18 +0100)
Similar in function to LIST_INSERT_AFTER, this will insert a new element
into the list before the specified position. If the specified position
is NULL, the element is added as the tail of the list.

src/basic/list.h

index 2939216adb60ef0aa43015421d3c9631de206a6e..760abcdab3bd087ca40f5cd5d055f5f687c60ac9 100644 (file)
                 }                                                       \
         } while(false)
 
+/* Insert an item before another one (a = where, b = what) */
+#define LIST_INSERT_BEFORE(name,head,a,b)                               \
+        do {                                                            \
+                typeof(*(head)) **_head = &(head), *_a = (a), *_b = (b); \
+                assert(_b);                                             \
+                if (!_a) {                                              \
+                        if (!*_head) {                                  \
+                                _b->name##_next = NULL;                 \
+                                _b->name##_prev = NULL;                 \
+                                *_head = _b;                            \
+                        } else {                                        \
+                                typeof(*(head)) *_tail = (head);        \
+                                while (_tail->name##_next)              \
+                                        _tail = _tail->name##_next;     \
+                                _b->name##_next = NULL;                 \
+                                _b->name##_prev = _tail;                \
+                                _tail->name##_next = _b;                \
+                        }                                               \
+                } else {                                                \
+                        if ((_b->name##_prev = _a->name##_prev))        \
+                                _b->name##_prev->name##_next = _b;      \
+                        _b->name##_next = _a;                           \
+                        _a->name##_prev = _b;                           \
+                }                                                       \
+        } while(false)
+
 #define LIST_JUST_US(name,item)                                         \
         (!(item)->name##_prev && !(item)->name##_next)                  \