#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