• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright © 2008-2011 Kristian Høgsberg
3  * Copyright © 2011 Intel Corporation
4  * Copyright © 2013-2015 Red Hat, Inc.
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a
7  * copy of this software and associated documentation files (the "Software"),
8  * to deal in the Software without restriction, including without limitation
9  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10  * and/or sell copies of the Software, and to permit persons to whom the
11  * Software is furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice (including the next
14  * paragraph) shall be included in all copies or substantial portions of the
15  * Software.
16  *
17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
20  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23  * DEALINGS IN THE SOFTWARE.
24  */
25 
26 #pragma once
27 
28 #include "config.h"
29 
30 #include <stdbool.h>
31 #include <stddef.h>
32 
33 /*
34  * This list data structure is a verbatim copy from wayland-util.h from the
35  * Wayland project; except that wl_ prefix has been removed.
36  */
37 
38 /**
39  * Doubly linked list implementation. This struct is used for both the list
40  * nodes and the list head. Use like this:
41  *
42  * @code
43  *
44  *	struct foo {
45  *	   struct list list_of_bars; // the list head
46  *	};
47  *
48  *	struct bar {
49  *	   struct list link; // links between the bars
50  *	};
51  *
52  *      struct foo *f = zalloc(sizeof *f);
53  *      struct bar *b = make_some_bar();
54  *
55  *	list_init(&f->list_of_bars);
56  *	list_append(&f->list_of_bars, &b->link);
57  *	list_remove(&b->link);
58  * @endcode
59  */
60 struct list {
61 	struct list *prev;
62 	struct list *next;
63 };
64 
65 /**
66  * Initialize a list head. This function *must* be called once for each list
67  * head. This function *must not* be called for a node to be added to a
68  * list.
69  */
70 void list_init(struct list *list);
71 
72 /**
73  * Insert an element at the front of the list
74  */
75 void list_insert(struct list *list, struct list *elm);
76 /**
77  * Append an element to the  back of the list
78  */
79 void list_append(struct list *list, struct list *elm);
80 
81 /**
82  * Remove an element from list.
83  *
84  * Removing a list element is only possible once, the caller must track
85  * whether the list node has already been removed.
86  *
87  */
88 void list_remove(struct list *elm);
89 /**
90  * Returns true if the given list head is an empty list.
91  */
92 bool list_empty(const struct list *list);
93 
94 /**
95  * Return the 'type' parent container struct of 'ptr' of which
96  * 'member' is our 'ptr' field. For example:
97  *
98  * @code
99  *     struct foo {			// the parent container struct
100  *         uint32_t a;
101  *         struct bar bar_member;	// the member field
102  *     };
103  *
104  *     struct foo *f = zalloc(sizeof *f);
105  *     struct bar *b = &f->bar_member;
106  *     struct foo *f2 = container_of(b, struct foo, bar_member);
107  *
108  *     assert(f == f2);
109  * @endcode
110  */
111 #define container_of(ptr, type, member)					\
112 	(__typeof__(type) *)((char *)(ptr) -				\
113 		 offsetof(__typeof__(type), member))
114 
115 /**
116  * Given a list 'head', return the first entry of type 'pos' that has a
117  * member 'link'.
118  *
119  * The 'pos' argument is solely used to determine the type be returned and
120  * not modified otherwise. It is common to use the same pointer that the
121  * return value of list_first_entry() is assigned to, for example:
122  *
123  * @code
124  *     struct foo {
125  *        struct list list_of_bars;
126  *     };
127  *
128  *     struct bar {
129  *         struct list link;
130  *     }
131  *
132  *     struct foo *f = get_a_foo();
133  *     struct bar *b = 0;  // initialize to avoid static analysis errors
134  *     b = list_first_entry(&f->list_of_bars, b, link);
135  * @endcode
136  */
137 #define list_first_entry(head, pointer_of_type, member)				\
138 	container_of((head)->next, __typeof__(*pointer_of_type), member)
139 
140 /**
141  * Given a list 'head', return the first entry of type 'container_type' that
142  * has a member 'link'.
143  *
144  * @code
145  *     struct foo {
146  *        struct list list_of_bars;
147  *     };
148  *
149  *     struct bar {
150  *         struct list link;
151  *     }
152  *
153  *     struct foo *f = get_a_foo();
154  *     struct bar *b = list_first_entry(&f->list_of_bars, struct bar, link);
155  * @endcode
156  */
157 #define list_first_entry_by_type(head, container_type, member)		\
158 	container_of((head)->next, container_type, member)
159 
160 /**
161  * Iterate through the list.
162  *
163  * @code
164  *     struct foo *f =  get_a_foo();
165  *     struct bar *element;
166  *     list_for_each(element, &f->list_of_bars, link) {
167  *     }
168  * @endcode
169  *
170  * If a list node needs to be removed during iteration, use
171  * list_for_each_safe().
172  */
173 #define list_for_each(pos, head, member)				\
174 	for (pos = list_first_entry_by_type(head, __typeof__(*pos), member); \
175 	     &pos->member != (head);					\
176 	     pos = list_first_entry_by_type(&pos->member, __typeof__(*pos), member))
177 
178 /**
179  * Iterate through the list. Equivalent to list_for_each() but allows
180  * calling list_remove() on the element.
181  *
182  * @code
183  *     struct foo *f =  get_a_foo();
184  *     struct bar *element;
185  *     list_for_each(element, tmp, &f->list_of_bars, link) {
186  *          list_remove(&element->link);
187  *     }
188  * @endcode
189  */
190 #define list_for_each_safe(pos, head, member)				\
191 	for (__typeof__(pos) _tmp = ({ \
192 				     pos = list_first_entry_by_type(head, __typeof__(*pos), member);	\
193 				     list_first_entry_by_type(&pos->member, __typeof__(*_tmp), member); \
194 				     }); \
195 	     &pos->member != (head);					\
196 	     pos = _tmp,						\
197 	     _tmp = list_first_entry_by_type(&pos->member, __typeof__(*_tmp), member))
198