GCC Code Coverage Report


Directory: src/
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 100.0% 23 / 0 / 23
Functions: 100.0% 6 / 0 / 6
Branches: -% 0 / 0 / 0

utils/src/list.h
Line Branch Exec Source
1 /*
2 * SPDX-License-Identifier: MIT
3 *
4 * Copyright (c) 2026 Manuel Hernández Méndez
5 *
6 * Authors:
7 * Manuel Hernández Méndez <maherme.dev@gmail.com>
8 */
9
10 #ifndef __LIST_H__
11 #define __LIST_H__
12
13 #include <stddef.h>
14 #include <stdlib.h>
15
16 /* clang-format off */
17 #define container_of(ptr, type, member) \
18 ((type *)((char *)(ptr) - offsetof(type, member)))
19 /* clang-format on */
20
21 struct list_head
22 {
23 struct list_head *next;
24 struct list_head *prev;
25 };
26
27 /* clang-format off */
28 #define LIST_HEAD_INIT(name) \
29 {&(name), &(name)}
30
31 #define LIST_HEAD(name) \
32 struct list_head name = LIST_HEAD_INIT(name)
33 /* clang-format on */
34
35 static inline void
36 32 init_list_head(struct list_head *list)
37 {
38 32 list->next = list;
39 32 list->prev = list;
40 32 }
41
42 static inline void
43 25 list_add__(struct list_head *new, struct list_head *prev, struct list_head *next)
44 {
45 25 next->prev = new;
46 25 new->next = next;
47 25 new->prev = prev;
48 25 prev->next = new;
49 25 }
50
51 static inline void
52 18 list_add(struct list_head *new, struct list_head *head)
53 {
54 18 list_add__(new, head, head->next);
55 18 }
56
57 static inline void
58 7 list_add_tail(struct list_head *new, struct list_head *head)
59 {
60 7 list_add__(new, head->prev, head);
61 7 }
62
63 static inline void
64 25 list_del__(struct list_head *prev, struct list_head *next)
65 {
66 25 next->prev = prev;
67 25 prev->next = next;
68 25 }
69
70 static inline void
71 25 list_del(struct list_head *entry)
72 {
73 25 list_del__(entry->prev, entry->next);
74 25 }
75
76 /* clang-format off */
77 #define list_empty(head) \
78 ((head)->next == (head))
79
80 #define list_entry(ptr, type, member) \
81 container_of(ptr, type, member)
82
83 #define list_for_each(pos, head) \
84 for (pos = (head)->next; pos != (head); pos = pos->next)
85
86 #define list_for_each_safe(pos, n, head) \
87 for (pos = (head)->next, n = pos->next; pos != (head); pos = n, n = pos->next)
88
89 #define list_for_each_entry(pos, head, member) \
90 for (pos = list_entry((head)->next, __typeof__(*pos), member); \
91 &pos->member != (head); \
92 pos = list_entry(pos->member.next, __typeof__(*pos), member))
93
94 #define list_for_each_entry_safe(pos, n, head, member) \
95 for (pos = list_entry((head)->next, __typeof__(*pos), member), n = list_entry(pos->member.next, __typeof__(*pos), member); \
96 &pos->member != (head); \
97 pos = n, n = list_entry(n->member.next, __typeof__(*n), member))
98
99 #define list_clear_with_free(head, type, member) \
100 do { \
101 type *pos, *tmp; \
102 list_for_each_entry_safe(pos, tmp, head, member) { \
103 list_del(&pos->member); \
104 free(pos); \
105 } \
106 } while (0)
107 /* clang-format on */
108
109 #endif /* __LIST_H__ */
110