aboutsummaryrefslogtreecommitdiff
path: root/src/list.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/list.h')
-rw-r--r--src/list.h83
1 files changed, 83 insertions, 0 deletions
diff --git a/src/list.h b/src/list.h
new file mode 100644
index 0000000..2a9df61
--- /dev/null
+++ b/src/list.h
@@ -0,0 +1,83 @@
+#ifndef LIST_H
+#define LIST_H
+
+#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
+#define container_of(ptr, type, member) ((type *)((char *)(ptr) - offsetof(type, member)))
+
+struct list_head {
+ struct list_head *prev;
+ struct list_head *next;
+};
+
+#define LIST_END NULL
+
+#define LIST_EMPTY(list) do { \
+ (list)->next = LIST_END; \
+ (list)->prev = LIST_END; \
+ } while(0);
+
+#define list_entry(ptr, type, member) \
+ container_of(ptr, type, member)
+
+#define list_next_entry(entry, type, member) \
+ list_entry(entry->member.next, type, member)
+
+#define list_for_each(pos, start) \
+ for(struct list_head *pos = start; pos; pos = pos->next)
+#define list_for_each_entry(type, entry, member, start) \
+ for(type *entry = list_entry((start), type, member); \
+ entry; \
+ entry = (entry->member.next == LIST_END ? NULL : \
+ list_next_entry(entry, type, member)))
+
+#define list_for_each_safe(pos, start) \
+ for(struct list_head *pos = (start), *__next = LIST_END; \
+ pos && (__next = pos->next,1); \
+ pos = __next)
+
+static inline int list_is_head(struct list_head *l)
+{
+ return l->prev == LIST_END;
+}
+
+static inline int list_is_tail(struct list_head *l)
+{
+ return l->next == LIST_END;
+}
+
+static inline struct list_head *list_get_head(struct list_head *l)
+{
+ while(!list_is_head(l)) l = l->prev;
+ return l;
+}
+
+static inline struct list_head *list_get_tail(struct list_head *l)
+{
+ while(!list_is_tail(l)) l = l->next;
+ return l;
+}
+
+static inline struct list_head *list_add(
+ struct list_head *head,
+ struct list_head *new)
+{
+ if(head) {
+ new->next = head->next;
+ head->next = new;
+ }
+ new->prev = head;
+ return new;
+}
+
+static inline struct list_head *list_append(
+ struct list_head *head,
+ struct list_head *new)
+{
+ if(head) {
+ head->next = new;
+ }
+ new->prev = head;
+ return new;
+}
+
+#endif