iproute2/include/list.h
<<
>>
Prefs
   1/* SPDX-License-Identifier: GPL-2.0 */
   2#ifndef __LIST_H__
   3#define __LIST_H__ 1
   4/* List and hash list stuff from kernel */
   5
   6#include <stddef.h>
   7
   8#define container_of(ptr, type, member) ({                      \
   9        const typeof( ((type *)0)->member ) *__mptr = (ptr);    \
  10        (type *)( (char *)__mptr - offsetof(type,member) );})
  11
  12struct list_head {
  13        struct list_head *next, *prev;
  14};
  15
  16static inline void INIT_LIST_HEAD(struct list_head *list)
  17{
  18        list->next = list;
  19        list->prev = list;
  20}
  21
  22static inline void __list_add(struct list_head *new,
  23                              struct list_head *prev,
  24                              struct list_head *next)
  25{
  26        next->prev = new;
  27        new->next = next;
  28        new->prev = prev;
  29        prev->next = new;
  30}
  31
  32static inline void list_add(struct list_head *new, struct list_head *head)
  33{
  34        __list_add(new, head, head->next);
  35}
  36
  37static inline void list_add_tail(struct list_head *new, struct list_head *head)
  38{
  39        __list_add(new, head->prev, head);
  40}
  41
  42static inline void __list_del(struct list_head *prev, struct list_head *next)
  43{
  44        next->prev = prev;
  45        prev->next = next;
  46}
  47
  48static inline void list_del(struct list_head *entry)
  49{
  50        __list_del(entry->prev, entry->next);
  51}
  52
  53#define list_entry(ptr, type, member) \
  54        container_of(ptr, type, member)
  55
  56#define list_first_entry(ptr, type, member) \
  57        list_entry((ptr)->next, type, member)
  58
  59#define list_last_entry(ptr, type, member) \
  60        list_entry((ptr)->prev, type, member)
  61
  62#define list_next_entry(pos, member) \
  63        list_entry((pos)->member.next, typeof(*(pos)), member)
  64
  65#define list_prev_entry(pos, member) \
  66        list_entry((pos)->member.prev, typeof(*(pos)), member)
  67
  68#define list_for_each_entry(pos, head, member)                          \
  69        for (pos = list_first_entry(head, typeof(*pos), member);        \
  70             &pos->member != (head);                                    \
  71             pos = list_next_entry(pos, member))
  72
  73#define list_for_each_entry_safe(pos, n, head, member)                  \
  74        for (pos = list_first_entry(head, typeof(*pos), member),        \
  75                n = list_next_entry(pos, member);                       \
  76             &pos->member != (head);                                    \
  77             pos = n, n = list_next_entry(n, member))
  78
  79#define list_for_each_entry_reverse(pos, head, member)                  \
  80        for (pos = list_last_entry(head, typeof(*pos), member);         \
  81             &pos->member != (head);                                    \
  82             pos = list_prev_entry(pos, member))
  83
  84struct hlist_head {
  85        struct hlist_node *first;
  86};
  87
  88struct hlist_node {
  89        struct hlist_node *next, **pprev;
  90};
  91
  92static inline void hlist_del(struct hlist_node *n)
  93{
  94        struct hlist_node *next = n->next;
  95        struct hlist_node **pprev = n->pprev;
  96        *pprev = next;
  97        if (next)
  98                next->pprev = pprev;
  99}
 100
 101static inline void hlist_add_head(struct hlist_node *n, struct hlist_head *h)
 102{
 103        struct hlist_node *first = h->first;
 104        n->next = first;
 105        if (first)
 106                first->pprev = &n->next;
 107        h->first = n;
 108        n->pprev = &h->first;
 109}
 110
 111static inline int list_empty(const struct list_head *head)
 112{
 113        return head->next == head;
 114}
 115
 116#define hlist_for_each(pos, head) \
 117        for (pos = (head)->first; pos ; pos = pos->next)
 118
 119
 120#define hlist_for_each_safe(pos, n, head) \
 121        for (pos = (head)->first; pos && ({ n = pos->next; 1; }); \
 122             pos = n)
 123
 124#define hlist_entry_safe(ptr, type, member) \
 125        ({ typeof(ptr) ____ptr = (ptr); \
 126           ____ptr ? hlist_entry(____ptr, type, member) : NULL; \
 127        })
 128
 129#define hlist_for_each_entry(pos, head, member)                         \
 130        for (pos = hlist_entry_safe((head)->first, typeof(*(pos)), member);\
 131             pos;                                                       \
 132             pos = hlist_entry_safe((pos)->member.next, typeof(*(pos)), member))
 133
 134#endif /* __LIST_H__ */
 135