| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| #ifndef _ZEBRA_LINKLIST_H |
| #define _ZEBRA_LINKLIST_H |
| |
| #ifdef __cplusplus |
| extern "C" { |
| #endif |
| |
| |
| |
| |
| struct listnode { |
| struct listnode *next; |
| struct listnode *prev; |
| |
| |
| void *data; |
| }; |
| |
| struct list { |
| struct listnode *head; |
| struct listnode *tail; |
| |
| |
| unsigned int count; |
| |
| uint8_t flags; |
| |
| |
| |
| #define LINKLIST_FLAG_NODE_MEM_BY_APP (1 << 0) |
| |
| |
| |
| |
| |
| int (*cmp)(void *val1, void *val2); |
| |
| |
| |
| |
| void (*del)(void *val); |
| }; |
| |
| #define listnextnode(X) ((X) ? ((X)->next) : NULL) |
| #define listnextnode_unchecked(X) ((X)->next) |
| #define listhead(X) ((X) ? ((X)->head) : NULL) |
| #define listhead_unchecked(X) ((X)->head) |
| #define listtail(X) ((X) ? ((X)->tail) : NULL) |
| #define listtail_unchecked(X) ((X)->tail) |
| #define listcount(X) ((X)->count) |
| #define list_isempty(X) ((X)->head == NULL && (X)->tail == NULL) |
| |
| #define listgetdata(X) (assert(X), assert((X)->data != NULL), (X)->data) |
| |
| #define listset_app_node_mem(X) ((X)->flags |= LINKLIST_FLAG_NODE_MEM_BY_APP) |
| #define listnode_init(X, val) ((X)->data = (val)) |
| |
| |
| |
| |
| |
| |
| |
| extern struct list *list_new(void); |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| extern struct listnode *listnode_add(struct list *list, void *data); |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| extern void listnode_add_head(struct list *list, void *data); |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| extern void listnode_add_sort(struct list *list, void *val); |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| extern struct listnode *listnode_add_after(struct list *list, |
| struct listnode *pp, void *data); |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| extern struct listnode *listnode_add_before(struct list *list, |
| struct listnode *pp, void *data); |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| extern void listnode_move_to_tail(struct list *list, struct listnode *node); |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| extern void listnode_delete(struct list *list, const void *data); |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| extern struct listnode *listnode_lookup(struct list *list, const void *data); |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| extern void *listnode_head(struct list *list); |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| extern void list_sort(struct list *list, |
| int (*cmp)(const void **, const void **)); |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| void **list_to_array(struct list *list, void **arr, size_t arrlen); |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| extern void list_delete(struct list **plist); |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| extern void list_delete_all_node(struct list *list); |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| extern void list_delete_node(struct list *list, struct listnode *node); |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| extern void list_filter_out_nodes(struct list *list, bool (*cond)(void *data)); |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| extern bool listnode_add_sort_nodup(struct list *list, void *val); |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| extern struct list *list_dup(struct list *list); |
| |
| |
| |
| |
| |
| #define ALL_LIST_ELEMENTS(list, node, nextnode, data) \ |
| (node) = listhead(list), ((data) = NULL); \ |
| (node) != NULL \ |
| && ((data) = static_cast(data, listgetdata(node)), \ |
| (nextnode) = node->next, 1); \ |
| (node) = (nextnode), ((data) = NULL) |
| |
| |
| |
| |
| |
| |
| |
| #define ALL_LIST_ELEMENTS_RO(list, node, data) \ |
| (node) = listhead(list), ((data) = NULL); \ |
| (node) != NULL && ((data) = static_cast(data, listgetdata(node)), 1); \ |
| (node) = listnextnode(node), ((data) = NULL) |
| |
| |
| |
| |
| |
| |
| #define LISTNODE_ATTACH(L, N) \ |
| do { \ |
| (N)->prev = (L)->tail; \ |
| (N)->next = NULL; \ |
| if ((L)->head == NULL) \ |
| (L)->head = (N); \ |
| else \ |
| (L)->tail->next = (N); \ |
| (L)->tail = (N); \ |
| (L)->count++; \ |
| } while (0) |
| |
| |
| #define LISTNODE_DETACH(L, N) \ |
| do { \ |
| if ((N)->prev) \ |
| (N)->prev->next = (N)->next; \ |
| else \ |
| (L)->head = (N)->next; \ |
| if ((N)->next) \ |
| (N)->next->prev = (N)->prev; \ |
| else \ |
| (L)->tail = (N)->prev; \ |
| (L)->count--; \ |
| } while (0) |
| |
| extern struct listnode *listnode_lookup_nocheck(struct list *list, void *data); |
| |
| |
| |
| |
| |
| |
| |
| extern struct listnode *listnode_add_force(struct list **list, void *val); |
| |
| #ifdef __cplusplus |
| } |
| #endif |
| |
| #endif /* _ZEBRA_LINKLIST_H */ |