Coverage Report

Created: 2025-12-11 06:15

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/opensips/lib/list.h
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 */