#ifndef _KERNEL_LIBK_LIST_H #define _KERNEL_LIBK_LIST_H struct list_node_link { struct list_node_link* next; struct list_node_link* prev; }; #define list_entry(ptr, type, member) ((type*)((char*)(ptr) - offsetof (type, member))) #define list_append(head, new) \ do { \ if ((new) != NULL) { \ (new)->next = NULL; \ if ((head) != NULL) { \ struct list_node_link* __tmp = (head); \ while (__tmp->next != NULL) { \ __tmp = __tmp->next; \ } \ __tmp->next = (new); \ (new)->prev = __tmp; \ } else { \ (new)->prev = NULL; \ (head) = (new); \ } \ } \ } while (0) #define list_prepend(head, new) \ do { \ if ((new) != NULL) { \ (new)->prev = NULL; \ (new)->next = (head); \ if ((head) != NULL) { \ (head)->prev = (new); \ } \ (head) = (new); \ } \ } while (0) #define list_remove(head, ele) \ do { \ if ((ele) != NULL) { \ if ((ele)->prev != NULL) { \ (ele)->prev->next = (ele)->next; \ } else { \ (head) = (ele)->next; \ } \ if ((ele)->next != NULL) { \ (ele)->next->prev = (ele)->prev; \ } \ (ele)->next = NULL; \ (ele)->prev = NULL; \ } \ } while (0) #define list_find(head, out, propname, propvalue) \ do { \ (out) = NULL; \ struct list_node_link* __tmp = (head); \ while (__tmp) { \ if (__tmp->propname == (propvalue)) { \ (out) = __tmp; \ break; \ } \ __tmp = __tmp->next; \ } \ } while (0) #define list_foreach(head, var, tmp) \ for (var = (head), tmp = (var ? var->next : NULL); var != NULL; \ var = tmp, tmp = (var ? var->next : NULL)) #define list_foreach_index(head, var, tmp, idx) \ for ((idx) = 0, var = (head), tmp = (var ? var->next : NULL); var != NULL; \ var = tmp, tmp = (var ? var->next : NULL), (idx)++) #define list_foreach_index_limit(head, var, tmp, idx, max) \ for ((idx) = 0, var = (head), tmp = (var ? var->next : NULL); var != NULL && (idx) < (max); \ var = tmp, tmp = (var ? var->next : NULL), (idx)++) #define list_back(head, out) \ do { \ (out) = NULL; \ if ((head) != NULL) { \ struct list_node_link* __tmp = (head); \ while (__tmp->next != NULL) { \ __tmp = __tmp->next; \ } \ (out) = __tmp; \ } \ } while (0) #define list_front(head, out) \ do { \ (out) = NULL; \ if ((head) != NULL) { \ struct list_node_link* __tmp = (head); \ while (__tmp->prev != NULL) { \ __tmp = __tmp->prev; \ } \ (out) = __tmp; \ } \ } while (0) #define list_insert_after(head, pos, new) \ do { \ if ((pos) != NULL && (new) != NULL) { \ (new)->prev = (pos); \ (new)->next = (pos)->next; \ if ((pos)->next != NULL) { \ (pos)->next->prev = (new); \ } \ (pos)->next = (new); \ } else if ((pos) == NULL && (head) == NULL) { \ (new)->prev = NULL; \ (new)->next = NULL; \ (head) = (new); \ } \ } while (0) #define list_insert_before(head, pos, new) \ do { \ if ((pos) != NULL && (new) != NULL) { \ (new)->next = (pos); \ (new)->prev = (pos)->prev; \ if ((pos)->prev != NULL) { \ (pos)->prev->next = (new); \ } else { \ (head) = (new); \ } \ (pos)->prev = (new); \ } else if ((pos) == NULL && (head) == NULL) { \ (new)->prev = NULL; \ (new)->next = NULL; \ (head) = (new); \ } \ } while (0) #define list_index_of(head, ele, out_idx) \ do { \ (out_idx) = -1; \ int __idx = 0; \ struct list_node_link* __tmp = (head); \ while (__tmp != NULL) { \ if (__tmp == (ele)) { \ (out_idx) = __idx; \ break; \ } \ __tmp = __tmp->next; \ __idx++; \ } \ } while (0) #define list_index_of_prop(head, propname, propvalue, out_idx) \ do { \ (out_idx) = -1; \ int __idx = 0; \ struct list_node_link* __tmp = (head); \ while (__tmp != NULL) { \ if (__tmp->propname == (propvalue)) { \ (out_idx) = __idx; \ break; \ } \ __tmp = __tmp->next; \ __idx++; \ } \ } while (0) #endif // _KERNEL_LIBK_LIST_H