Commit | Line | Data |
---|---|---|
d273fd4b MD |
1 | // SPDX-FileCopyrightText: 2002 Free Software Foundation, Inc. |
2 | // SPDX-FileCopyrightText: 2009 Pierre-Marc Fournier | |
3 | // SPDX-FileCopyrightText: 2010 Mathieu Desnoyers <mathieu.desnoyers@efficios.com> | |
4 | // | |
5 | // SPDX-License-Identifier: LGPL-2.1-or-later | |
6 | ||
7 | /* | |
8 | * (originally part of the GNU C Library) | |
9 | * Contributed by Ulrich Drepper <drepper@redhat.com>, 2002. | |
10 | */ | |
11 | ||
12 | #ifndef _LIST_H | |
13 | #define _LIST_H 1 | |
14 | ||
15 | /* | |
16 | * container_of - Get the address of an object containing a field. | |
17 | * | |
18 | * @ptr: pointer to the field. | |
19 | * @type: type of the object. | |
20 | * @member: name of the field within the object. | |
21 | */ | |
22 | #define container_of(ptr, type, member) \ | |
23 | __extension__ \ | |
24 | ({ \ | |
25 | const __typeof__(((type *) NULL)->member) * __ptr = (ptr); \ | |
26 | (type *)((char *)__ptr - offsetof(type, member)); \ | |
27 | }) | |
28 | ||
29 | /* | |
30 | * The definitions of this file are adopted from those which can be | |
31 | * found in the Linux kernel headers to enable people familiar with the | |
32 | * latter find their way in these sources as well. | |
33 | */ | |
34 | ||
35 | /* Basic type for the double-link list. */ | |
36 | struct list_head { | |
37 | struct list_head *next, *prev; | |
38 | }; | |
39 | ||
40 | /* Define a variable with the head and tail of the list. */ | |
41 | #define LIST_HEAD(name) \ | |
42 | struct list_head name = { &(name), &(name) } | |
43 | ||
44 | /* Initialize a new list head. */ | |
45 | #define INIT_LIST_HEAD(ptr) \ | |
46 | (ptr)->next = (ptr)->prev = (ptr) | |
47 | ||
48 | #define LIST_HEAD_INIT(name) { .next = &(name), .prev = &(name) } | |
49 | ||
50 | /* Add new element at the head of the list. */ | |
51 | static inline | |
52 | void list_add(struct list_head *newp, struct list_head *head) | |
53 | { | |
54 | head->next->prev = newp; | |
55 | newp->next = head->next; | |
56 | newp->prev = head; | |
57 | head->next = newp; | |
58 | } | |
59 | ||
60 | /* Add new element at the tail of the list. */ | |
61 | static inline | |
62 | void list_add_tail(struct list_head *newp, struct list_head *head) | |
63 | { | |
64 | head->prev->next = newp; | |
65 | newp->next = head; | |
66 | newp->prev = head->prev; | |
67 | head->prev = newp; | |
68 | } | |
69 | ||
70 | /* Remove element from list. */ | |
71 | static inline | |
72 | void __list_del(struct list_head *prev, struct list_head *next) | |
73 | { | |
74 | next->prev = prev; | |
75 | prev->next = next; | |
76 | } | |
77 | ||
78 | /* Remove element from list. */ | |
79 | static inline | |
80 | void list_del(struct list_head *elem) | |
81 | { | |
82 | __list_del(elem->prev, elem->next); | |
83 | } | |
84 | ||
85 | /* Remove element from list, initializing the element's list pointers. */ | |
86 | static inline | |
87 | void list_del_init(struct list_head *elem) | |
88 | { | |
89 | list_del(elem); | |
90 | INIT_LIST_HEAD(elem); | |
91 | } | |
92 | ||
93 | /* Delete from list, add to another list as head. */ | |
94 | static inline | |
95 | void list_move(struct list_head *elem, struct list_head *head) | |
96 | { | |
97 | __list_del(elem->prev, elem->next); | |
98 | list_add(elem, head); | |
99 | } | |
100 | ||
101 | /* Replace an old entry. */ | |
102 | static inline | |
103 | void list_replace(struct list_head *old, struct list_head *_new) | |
104 | { | |
105 | _new->next = old->next; | |
106 | _new->prev = old->prev; | |
107 | _new->prev->next = _new; | |
108 | _new->next->prev = _new; | |
109 | } | |
110 | ||
111 | /* Join two lists. */ | |
112 | static inline | |
113 | void list_splice(struct list_head *add, struct list_head *head) | |
114 | { | |
115 | /* Do nothing if the list which gets added is empty. */ | |
116 | if (add != add->next) { | |
117 | add->next->prev = head; | |
118 | add->prev->next = head->next; | |
119 | head->next->prev = add->prev; | |
120 | head->next = add->next; | |
121 | } | |
122 | } | |
123 | ||
124 | /* Get typed element from list at a given position. */ | |
125 | #define list_entry(ptr, type, member) container_of(ptr, type, member) | |
126 | ||
127 | /* Get first entry from a list. */ | |
128 | #define list_first_entry(ptr, type, member) \ | |
129 | list_entry((ptr)->next, type, member) | |
130 | ||
131 | /* Iterate forward over the elements of the list. */ | |
132 | #define list_for_each(pos, head) \ | |
133 | for (pos = (head)->next; (pos) != (head); pos = (pos)->next) | |
134 | ||
135 | /* | |
136 | * Iterate forward over the elements list. The list elements can be | |
137 | * removed from the list while doing this. | |
138 | */ | |
139 | #define list_for_each_safe(pos, p, head) \ | |
140 | for (pos = (head)->next, p = (pos)->next; \ | |
141 | (pos) != (head); \ | |
142 | pos = (p), p = (pos)->next) | |
143 | ||
144 | /* Iterate backward over the elements of the list. */ | |
145 | #define list_for_each_prev(pos, head) \ | |
146 | for (pos = (head)->prev; (pos) != (head); pos = (pos)->prev) | |
147 | ||
148 | /* | |
149 | * Iterate backwards over the elements list. The list elements can be | |
150 | * removed from the list while doing this. | |
151 | */ | |
152 | #define list_for_each_prev_safe(pos, p, head) \ | |
153 | for (pos = (head)->prev, p = (pos)->prev; \ | |
154 | (pos) != (head); \ | |
155 | pos = (p), p = (pos)->prev) | |
156 | ||
157 | #define list_for_each_entry(pos, head, member) \ | |
158 | for (pos = list_entry((head)->next, __typeof__(*(pos)), member); \ | |
159 | &(pos)->member != (head); \ | |
160 | pos = list_entry((pos)->member.next, __typeof__(*(pos)), member)) | |
161 | ||
162 | #define list_for_each_entry_reverse(pos, head, member) \ | |
163 | for (pos = list_entry((head)->prev, __typeof__(*(pos)), member); \ | |
164 | &(pos)->member != (head); \ | |
165 | pos = list_entry((pos)->member.prev, __typeof__(*(pos)), member)) | |
166 | ||
167 | #define list_for_each_entry_safe(pos, p, head, member) \ | |
168 | for (pos = list_entry((head)->next, __typeof__(*(pos)), member), \ | |
169 | p = list_entry((pos)->member.next, __typeof__(*(pos)), member); \ | |
170 | &(pos)->member != (head); \ | |
171 | pos = (p), p = list_entry((pos)->member.next, __typeof__(*(pos)), member)) | |
172 | ||
173 | /* | |
174 | * Same as list_for_each_entry_safe, but starts from "pos" which should | |
175 | * point to an entry within the list. | |
176 | */ | |
177 | #define list_for_each_entry_safe_from(pos, p, head, member) \ | |
178 | for (p = list_entry((pos)->member.next, __typeof__(*(pos)), member); \ | |
179 | &(pos)->member != (head); \ | |
180 | pos = (p), p = list_entry((pos)->member.next, __typeof__(*(pos)), member)) | |
181 | ||
182 | static inline | |
183 | int list_empty(struct list_head *head) | |
184 | { | |
185 | return head == head->next; | |
186 | } | |
187 | ||
188 | static inline | |
189 | void list_replace_init(struct list_head *old, struct list_head *_new) | |
190 | { | |
191 | struct list_head *head = old->next; | |
192 | ||
193 | list_del(old); | |
194 | list_add_tail(_new, head); | |
195 | INIT_LIST_HEAD(old); | |
196 | } | |
197 | ||
198 | #endif /* _LIST_H */ |