103 lines
2.4 KiB
C
Executable file
103 lines
2.4 KiB
C
Executable file
#pragma once
|
|
/**
|
|
* util/list.h
|
|
*
|
|
* Double Linked Lists for C
|
|
*
|
|
* (c) 2016 Harald Christian Joachim Wolff
|
|
*
|
|
* API (may be implemented with macros!) :
|
|
*
|
|
*
|
|
*/
|
|
|
|
typedef struct _list {
|
|
struct _list *next,
|
|
*prev;
|
|
} list_t;
|
|
|
|
#define LIST_INIT_STATIC(name) { &(name), &(name) }
|
|
|
|
#define LIST(name) list_t name = LIST_INIT_STATIC(name)
|
|
|
|
static inline void __list_init(list_t *list){
|
|
list->next = list->prev = list;
|
|
}
|
|
|
|
#define list_init(L) __list_init(L);
|
|
|
|
static inline void __list_add(list_t *item,list_t *prev,list_t *next) {
|
|
prev->next = item;
|
|
next->prev = item;
|
|
item->next = next;
|
|
item->prev = prev;
|
|
};
|
|
|
|
static inline void list_remove(list_t *item){
|
|
item->prev->next = item->next;
|
|
item->next->prev = item->prev;
|
|
item->prev = item->next = item;
|
|
};
|
|
|
|
static inline void list_append(list_t* item,list_t* head){
|
|
__list_add(item,head->prev,head);
|
|
};
|
|
|
|
static inline void list_insert(list_t* item,list_t* head){
|
|
__list_add(item,head,head->next);
|
|
};
|
|
|
|
static inline list_t* list_next(list_t* item){ return item->next; };
|
|
static inline list_t* list_prev(list_t* item){ return item->prev; };
|
|
|
|
static inline int list_is_empty(list_t *list) {
|
|
return (list->next == list);
|
|
};
|
|
|
|
static inline list_t* list_get(list_t *head,int n){
|
|
if (list_is_empty(head)){
|
|
return 0L;
|
|
};
|
|
while (n--){
|
|
head = head->next;
|
|
};
|
|
return head;
|
|
};
|
|
static inline list_t* list_fetch_first(list_t *head){
|
|
if (!list_is_empty(head)){
|
|
list_t *f = head->next;
|
|
list_remove(f);
|
|
return f;
|
|
} else {
|
|
return 0L;
|
|
};
|
|
};
|
|
|
|
/**
|
|
* list_entry - get container struct of entry
|
|
* @P: Pointer to entry
|
|
* @T: Type of struct
|
|
* @M: entry member of struct
|
|
*/
|
|
#define list_entry(P,T,M) ((T*)(int)(((int)(P)) - (int)(&(((T*)0L)->M))))
|
|
|
|
#define list_next_entry(P,T,M) list_entry((P)->next,T,M)
|
|
#define list_prev_entry(P,T,M) list_entry((P)->prev,T,M)
|
|
|
|
#define list_first_entry(P,T,M) ((P)->next != (P) ? list_entry((P)->next,T,M) : NULL)
|
|
#define list_last_entry(P,T,M) ((P)->prev != (P) ? list_entry((P)->prev,T,M) : NULL)
|
|
|
|
#define for_each_list_entry(pos,list) for (pos = (list)->next; pos != (list); pos = pos->next)
|
|
#define for_each_list_entry_reverse(pos,list) for (pos = (list)->prev; pos != (list); pos = pos->prev)
|
|
|
|
#define for_each_list_entry_save(pos,tmp,list) for (pos = (list)->next, tmp = pos->next; pos != (list); pos = tmp, tmp = pos->next)
|
|
|
|
static inline int list_count(list_t *head){
|
|
list_t *t;
|
|
int n = 0;
|
|
for_each_list_entry(t,head){
|
|
n++;
|
|
};
|
|
return n;
|
|
};
|