Line | Count | Source |
1 | | /* |
2 | | * a doubly linked list implementation - inspired by Linux kernel's list.h |
3 | | * |
4 | | * This file is part of opensips, a free SIP server. |
5 | | * |
6 | | * opensips is free software; you can redistribute it and/or modify |
7 | | * it under the terms of the GNU General Public License as published by |
8 | | * the Free Software Foundation; either version 2 of the License, or |
9 | | * (at your option) any later version |
10 | | * |
11 | | * opensips is distributed in the hope that it will be useful, |
12 | | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 | | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
14 | | * GNU General Public License for more details. |
15 | | * |
16 | | * You should have received a copy of the GNU General Public License |
17 | | * along with this program; if not, write to the Free Software |
18 | | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
19 | | */ |
20 | | |
21 | | #ifndef __OSS_LIST_H__ |
22 | | #define __OSS_LIST_H__ |
23 | | |
24 | | #include "container.h" |
25 | | |
26 | | #define LIST_POISON1 ((void *) 0x00100100) |
27 | | #define LIST_POISON2 ((void *) 0x00200200) |
28 | | |
29 | | struct list_head { |
30 | | struct list_head *prev; |
31 | | struct list_head *next; |
32 | | }; |
33 | | |
34 | | #define LIST_HEAD_INIT(name) { &(name), &(name) } |
35 | | |
36 | | #define OSIPS_LIST_HEAD(name) \ |
37 | | struct list_head name = LIST_HEAD_INIT(name) |
38 | | |
39 | | static inline void INIT_LIST_HEAD(struct list_head *list) |
40 | 0 | { |
41 | 0 | list->next = list; |
42 | 0 | list->prev = list; |
43 | 0 | } Unexecuted instantiation: fuzz_csv_parser.c:INIT_LIST_HEAD Unexecuted instantiation: csv.c:INIT_LIST_HEAD Unexecuted instantiation: mod_fix.c:INIT_LIST_HEAD Unexecuted instantiation: transformations.c:INIT_LIST_HEAD Unexecuted instantiation: time_rec.c:INIT_LIST_HEAD Unexecuted instantiation: core_cmds.c:INIT_LIST_HEAD Unexecuted instantiation: cachedb.c:INIT_LIST_HEAD Unexecuted instantiation: fuzz_uri_parser.c:INIT_LIST_HEAD Unexecuted instantiation: fuzz_core_funcs.c:INIT_LIST_HEAD Unexecuted instantiation: fuzz_msg_parser.c:INIT_LIST_HEAD |
44 | | |
45 | | /* |
46 | | * Insert a new entry between two known consecutive entries. |
47 | | * |
48 | | * This is only for internal list manipulation where we know |
49 | | * the prev/next entries already! |
50 | | */ |
51 | | static inline void __list_add(struct list_head *new_entry, |
52 | | struct list_head *prev, |
53 | | struct list_head *next) |
54 | 0 | { |
55 | 0 | next->prev = new_entry; |
56 | 0 | new_entry->next = next; |
57 | 0 | new_entry->prev = prev; |
58 | 0 | prev->next = new_entry; |
59 | 0 | } Unexecuted instantiation: fuzz_csv_parser.c:__list_add Unexecuted instantiation: csv.c:__list_add Unexecuted instantiation: mod_fix.c:__list_add Unexecuted instantiation: transformations.c:__list_add Unexecuted instantiation: time_rec.c:__list_add Unexecuted instantiation: core_cmds.c:__list_add Unexecuted instantiation: cachedb.c:__list_add Unexecuted instantiation: fuzz_uri_parser.c:__list_add Unexecuted instantiation: fuzz_core_funcs.c:__list_add Unexecuted instantiation: fuzz_msg_parser.c:__list_add |
60 | | |
61 | | /** |
62 | | * list_add - add a new entry |
63 | | * @new_entry: new entry to be added |
64 | | * @head: list head to add it after |
65 | | * |
66 | | * Insert a new entry after the specified head. |
67 | | * This is good for implementing stacks. |
68 | | */ |
69 | | #ifndef _list_h_skip_list_add_ /* conflict with 'mysql/my_list.h' list_add() */ |
70 | | static inline void list_add(struct list_head *new_entry, struct list_head *head) |
71 | 0 | { |
72 | 0 | __list_add(new_entry, head, head->next); |
73 | 0 | } Unexecuted instantiation: fuzz_csv_parser.c:list_add Unexecuted instantiation: csv.c:list_add Unexecuted instantiation: mod_fix.c:list_add Unexecuted instantiation: transformations.c:list_add Unexecuted instantiation: time_rec.c:list_add Unexecuted instantiation: core_cmds.c:list_add Unexecuted instantiation: cachedb.c:list_add Unexecuted instantiation: fuzz_uri_parser.c:list_add Unexecuted instantiation: fuzz_core_funcs.c:list_add Unexecuted instantiation: fuzz_msg_parser.c:list_add |
74 | | #endif |
75 | | |
76 | | /** |
77 | | * list_add_tail - add a new entry |
78 | | * @new_entry: new entry to be added |
79 | | * @head: list head to add it before |
80 | | * |
81 | | * Insert a new entry before the specified head. |
82 | | * This is useful for implementing queues. |
83 | | */ |
84 | | static inline void list_add_tail(struct list_head *new_entry, struct list_head *head) |
85 | 0 | { |
86 | 0 | __list_add(new_entry, head->prev, head); |
87 | 0 | } Unexecuted instantiation: fuzz_csv_parser.c:list_add_tail Unexecuted instantiation: csv.c:list_add_tail Unexecuted instantiation: mod_fix.c:list_add_tail Unexecuted instantiation: transformations.c:list_add_tail Unexecuted instantiation: time_rec.c:list_add_tail Unexecuted instantiation: core_cmds.c:list_add_tail Unexecuted instantiation: cachedb.c:list_add_tail Unexecuted instantiation: fuzz_uri_parser.c:list_add_tail Unexecuted instantiation: fuzz_core_funcs.c:list_add_tail Unexecuted instantiation: fuzz_msg_parser.c:list_add_tail |
88 | | |
89 | | /* |
90 | | * Delete a list entry by making the prev/next entries |
91 | | * point to each other. |
92 | | * |
93 | | * This is only for internal list manipulation where we know |
94 | | * the prev/next entries already! |
95 | | */ |
96 | | static inline void __list_del(struct list_head * prev, struct list_head * next) |
97 | 0 | { |
98 | 0 | next->prev = prev; |
99 | 0 | prev->next = next; |
100 | 0 | } Unexecuted instantiation: fuzz_csv_parser.c:__list_del Unexecuted instantiation: csv.c:__list_del Unexecuted instantiation: mod_fix.c:__list_del Unexecuted instantiation: transformations.c:__list_del Unexecuted instantiation: time_rec.c:__list_del Unexecuted instantiation: core_cmds.c:__list_del Unexecuted instantiation: cachedb.c:__list_del Unexecuted instantiation: fuzz_uri_parser.c:__list_del Unexecuted instantiation: fuzz_core_funcs.c:__list_del Unexecuted instantiation: fuzz_msg_parser.c:__list_del |
101 | | |
102 | | /** |
103 | | * list_del - deletes entry from list. |
104 | | * @entry: the element to delete from the list. |
105 | | * Note: list_empty() on entry does not return true after this, the entry is |
106 | | * in an undefined state. |
107 | | */ |
108 | | static inline void list_del(struct list_head *entry) |
109 | 0 | { |
110 | 0 | __list_del(entry->prev, entry->next); |
111 | 0 | entry->next = (struct list_head *)LIST_POISON1; |
112 | 0 | entry->prev = (struct list_head *)LIST_POISON2; |
113 | 0 | } Unexecuted instantiation: fuzz_csv_parser.c:list_del Unexecuted instantiation: csv.c:list_del Unexecuted instantiation: mod_fix.c:list_del Unexecuted instantiation: transformations.c:list_del Unexecuted instantiation: time_rec.c:list_del Unexecuted instantiation: core_cmds.c:list_del Unexecuted instantiation: cachedb.c:list_del Unexecuted instantiation: fuzz_uri_parser.c:list_del Unexecuted instantiation: fuzz_core_funcs.c:list_del Unexecuted instantiation: fuzz_msg_parser.c:list_del |
114 | | |
115 | | /** |
116 | | * list_is_last - tests whether @list is the last entry in list @head |
117 | | * @list: the entry to test |
118 | | * @head: the head of the list |
119 | | */ |
120 | | static inline int list_is_last(const struct list_head *list, |
121 | | const struct list_head *head) |
122 | 0 | { |
123 | 0 | return list->next == head; |
124 | 0 | } Unexecuted instantiation: fuzz_csv_parser.c:list_is_last Unexecuted instantiation: csv.c:list_is_last Unexecuted instantiation: mod_fix.c:list_is_last Unexecuted instantiation: transformations.c:list_is_last Unexecuted instantiation: time_rec.c:list_is_last Unexecuted instantiation: core_cmds.c:list_is_last Unexecuted instantiation: cachedb.c:list_is_last Unexecuted instantiation: fuzz_uri_parser.c:list_is_last Unexecuted instantiation: fuzz_core_funcs.c:list_is_last Unexecuted instantiation: fuzz_msg_parser.c:list_is_last |
125 | | |
126 | | /** |
127 | | * list_empty - tests whether a list is empty |
128 | | * @head: the list to test. |
129 | | */ |
130 | | static inline int list_empty(const struct list_head *head) |
131 | 0 | { |
132 | 0 | return head->next == head; |
133 | 0 | } Unexecuted instantiation: fuzz_csv_parser.c:list_empty Unexecuted instantiation: csv.c:list_empty Unexecuted instantiation: mod_fix.c:list_empty Unexecuted instantiation: transformations.c:list_empty Unexecuted instantiation: time_rec.c:list_empty Unexecuted instantiation: core_cmds.c:list_empty Unexecuted instantiation: cachedb.c:list_empty Unexecuted instantiation: fuzz_uri_parser.c:list_empty Unexecuted instantiation: fuzz_core_funcs.c:list_empty Unexecuted instantiation: fuzz_msg_parser.c:list_empty |
134 | | |
135 | | /** |
136 | | * list_is_singular - tests whether a list has just one entry. |
137 | | * @head: the list to test. |
138 | | */ |
139 | | static inline int list_is_singular(const struct list_head *head) |
140 | 0 | { |
141 | 0 | return !list_empty(head) && (head->next == head->prev); |
142 | 0 | } Unexecuted instantiation: fuzz_csv_parser.c:list_is_singular Unexecuted instantiation: csv.c:list_is_singular Unexecuted instantiation: mod_fix.c:list_is_singular Unexecuted instantiation: transformations.c:list_is_singular Unexecuted instantiation: time_rec.c:list_is_singular Unexecuted instantiation: core_cmds.c:list_is_singular Unexecuted instantiation: cachedb.c:list_is_singular Unexecuted instantiation: fuzz_uri_parser.c:list_is_singular Unexecuted instantiation: fuzz_core_funcs.c:list_is_singular Unexecuted instantiation: fuzz_msg_parser.c:list_is_singular |
143 | | |
144 | | static inline void __list_cut_position(struct list_head *list, |
145 | | struct list_head *head, struct list_head *entry) |
146 | 0 | { |
147 | 0 | struct list_head *new_first = entry->next; |
148 | 0 | list->next = head->next; |
149 | 0 | list->next->prev = list; |
150 | 0 | list->prev = entry; |
151 | 0 | entry->next = list; |
152 | 0 | head->next = new_first; |
153 | 0 | new_first->prev = head; |
154 | 0 | } Unexecuted instantiation: fuzz_csv_parser.c:__list_cut_position Unexecuted instantiation: csv.c:__list_cut_position Unexecuted instantiation: mod_fix.c:__list_cut_position Unexecuted instantiation: transformations.c:__list_cut_position Unexecuted instantiation: time_rec.c:__list_cut_position Unexecuted instantiation: core_cmds.c:__list_cut_position Unexecuted instantiation: cachedb.c:__list_cut_position Unexecuted instantiation: fuzz_uri_parser.c:__list_cut_position Unexecuted instantiation: fuzz_core_funcs.c:__list_cut_position Unexecuted instantiation: fuzz_msg_parser.c:__list_cut_position |
155 | | |
156 | | /** |
157 | | * list_cut_position - cut a list into two |
158 | | * @list: a new list to add all removed entries |
159 | | * @head: a list with entries |
160 | | * @entry: an entry within head, could be the head itself |
161 | | * and if so we won't cut the list |
162 | | * |
163 | | * This helper moves the initial part of @head, up to and |
164 | | * including @entry, from @head to @list. You should |
165 | | * pass on @entry an element you know is on @head. @list |
166 | | * should be an empty list or a list you do not care about |
167 | | * losing its data. |
168 | | * |
169 | | */ |
170 | | static inline void list_cut_position(struct list_head *list, |
171 | | struct list_head *head, struct list_head *entry) |
172 | 0 | { |
173 | 0 | if (list_empty(head)) |
174 | 0 | return; |
175 | 0 | if (list_is_singular(head) && |
176 | 0 | (head->next != entry && head != entry)) |
177 | 0 | return; |
178 | 0 | if (entry == head) |
179 | 0 | INIT_LIST_HEAD(list); |
180 | 0 | else |
181 | 0 | __list_cut_position(list, head, entry); |
182 | 0 | } Unexecuted instantiation: fuzz_csv_parser.c:list_cut_position Unexecuted instantiation: csv.c:list_cut_position Unexecuted instantiation: mod_fix.c:list_cut_position Unexecuted instantiation: transformations.c:list_cut_position Unexecuted instantiation: time_rec.c:list_cut_position Unexecuted instantiation: core_cmds.c:list_cut_position Unexecuted instantiation: cachedb.c:list_cut_position Unexecuted instantiation: fuzz_uri_parser.c:list_cut_position Unexecuted instantiation: fuzz_core_funcs.c:list_cut_position Unexecuted instantiation: fuzz_msg_parser.c:list_cut_position |
183 | | |
184 | | #undef list_entry |
185 | | /** |
186 | | * list_entry - get the struct for this entry |
187 | | * @ptr: the &struct list_head pointer. |
188 | | * @type: the type of the struct this is embedded in. |
189 | | * @member: the name of the list_struct within the struct. |
190 | | */ |
191 | | #define list_entry(ptr, type, member) \ |
192 | 0 | container_of(ptr, type, member) |
193 | | |
194 | | /** |
195 | | * list_last_entry - get the last element from a list |
196 | | * @ptr: the list head to take the element from. |
197 | | * @type: the type of the struct this is embedded in. |
198 | | * @member: the name of the list_struct within the struct. |
199 | | * |
200 | | * Note, that list is expected to be not empty. |
201 | | */ |
202 | | #define list_last_entry(ptr, type, member) \ |
203 | | list_entry((ptr)->prev, type, member) |
204 | | |
205 | | /** |
206 | | * list_next_entry - get the next element in list |
207 | | * @pos: the type * to cursor |
208 | | * @member: the name of the list_struct within the struct. |
209 | | */ |
210 | | #define list_next_entry(pos, member) \ |
211 | | list_entry((pos)->member.next, typeof(*(pos)), member) |
212 | | |
213 | | /** |
214 | | * list_prev_entry - get the prev element in list |
215 | | * @pos: the type * to cursor |
216 | | * @member: the name of the list_struct within the struct. |
217 | | */ |
218 | | #define list_prev_entry(pos, member) \ |
219 | | list_entry((pos)->member.prev, typeof(*(pos)), member) |
220 | | |
221 | | /** |
222 | | * list_for_each - iterate over a list |
223 | | * @pos: the &struct list_head to use as a loop cursor. |
224 | | * @head: the head for your list. |
225 | | */ |
226 | | #define list_for_each(pos, head) \ |
227 | 0 | for (pos = (head)->next; pos != (head); pos = pos->next) |
228 | | |
229 | | /** |
230 | | * list_for_each_prev - iterate over a list backwards |
231 | | * @pos: the &struct list_head to use as a loop cursor. |
232 | | * @head: the head for your list. |
233 | | */ |
234 | | #define list_for_each_prev(pos, head) \ |
235 | | for (pos = (head)->prev; pos != (head); pos = pos->prev) |
236 | | |
237 | | /** |
238 | | * list_for_each_safe - iterate over a list safe against removal of list entry |
239 | | * @pos: the &struct list_head to use as a loop cursor. |
240 | | * @n: another &struct list_head to use as temporary storage |
241 | | * @head: the head for your list. |
242 | | */ |
243 | | #define list_for_each_safe(pos, n, head) \ |
244 | 0 | for (pos = (head)->next, n = pos->next; pos != (head); \ |
245 | 0 | pos = n, n = pos->next) |
246 | | |
247 | | /** |
248 | | * list_for_each_prev_safe - iterate over a list backwards safe against removal of list entry |
249 | | * @pos: the &struct list_head to use as a loop cursor. |
250 | | * @n: another &struct list_head to use as temporary storage |
251 | | * @head: the head for your list. |
252 | | */ |
253 | | #define list_for_each_prev_safe(pos, n, head) \ |
254 | | for (pos = (head)->prev, n = pos->prev; \ |
255 | | pos != (head); \ |
256 | | pos = n, n = pos->prev) |
257 | | |
258 | | /** |
259 | | * list_size - returns the number of elements in the list |
260 | | * @head: a list with entries |
261 | | */ |
262 | | static inline int list_size(struct list_head *head) |
263 | 0 | { |
264 | 0 | int count = 0; |
265 | 0 | struct list_head *it; |
266 | 0 | list_for_each(it, head) |
267 | 0 | count++; |
268 | 0 | return count; |
269 | 0 | } Unexecuted instantiation: fuzz_csv_parser.c:list_size Unexecuted instantiation: csv.c:list_size Unexecuted instantiation: mod_fix.c:list_size Unexecuted instantiation: transformations.c:list_size Unexecuted instantiation: time_rec.c:list_size Unexecuted instantiation: core_cmds.c:list_size Unexecuted instantiation: cachedb.c:list_size Unexecuted instantiation: fuzz_uri_parser.c:list_size Unexecuted instantiation: fuzz_core_funcs.c:list_size Unexecuted instantiation: fuzz_msg_parser.c:list_size |
270 | | |
271 | | /** |
272 | | * list_is_valid - checks if an element is in a valid list |
273 | | * @entry: the element to check |
274 | | * in an undefined state. |
275 | | */ |
276 | | #define list_is_valid(entry) \ |
277 | | ((entry)->next != LIST_POISON1 && (entry)->prev != LIST_POISON2) |
278 | | |
279 | | |
280 | | |
281 | | #endif /* __OSS_LIST_H */ |