]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - gdb/common/queue.h
fce43493955be3d70a183719d619e3b3bb17bfd5
[thirdparty/binutils-gdb.git] / gdb / common / queue.h
1 /* General queue data structure for GDB, the GNU debugger.
2
3 Copyright (C) 2012-2015 Free Software Foundation, Inc.
4
5 This file is part of GDB.
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>. */
19
20 #ifndef QUEUE_H
21 #define QUEUE_H
22
23 /* These macros implement functions and structs for a general queue.
24 Macro 'DEFINE_QUEUE_P(TYPEDEF)' is to define the new queue type for
25 TYPEDEF', and macro 'DECLARE_QUEUE_P' is to declare external queue
26 APIs. The character P indicates TYPEDEF is a pointer (P). The
27 counterpart on object (O) and integer (I) are not implemented.
28
29 An example of their use would be,
30
31 typedef struct foo
32 {} *foo_p;
33
34 DEFINE_QUEUE_P (foo_p);
35 // A pointer to a queue of foo pointers. FOO_XFREE is a destructor
36 // function for foo instances in queue.
37 QUEUE(foo_p) *foo_queue = QUEUE_alloc (foo_p, foo_xfree);
38
39 foo_p foo_var_p;
40 // Enqueue and Dequeue
41 QUEUE_enque (foo_p, foo_queue, foo_var_p);
42 foo_var_p = QUEUE_deque (foo_p, foo_queue);
43
44 static int visit_foo (QUEUE (foo_p) *q, QUEUE_ITER (foo_p) *iter,
45 foo_p f, void *data)
46 {
47 return 1;
48 }
49 // Iterate over queue.
50 QUEUE_iterate (foo_p, foo_queue, visit_foo, &param);
51
52 QUEUE_free (foo_p, foo_queue); // Free queue. */
53
54 /* Typical enqueue operation. Put V into queue Q. */
55 #define QUEUE_enque(TYPE, Q, V) queue_ ## TYPE ## _enque ((Q), (V))
56
57 /* Typical dequeue operation. Return head element of queue Q and
58 remove it. Q must not be empty. */
59 #define QUEUE_deque(TYPE, Q) queue_ ## TYPE ## _deque (Q)
60
61 /* Return the head element, but don't remove it from the queue.
62 Q must not be empty. */
63 #define QUEUE_peek(TYPE, Q) queue_ ## TYPE ## _peek (Q)
64
65 /* Return true if queue Q is empty. */
66 #define QUEUE_is_empty(TYPE, Q) queue_ ## TYPE ## _is_empty (Q)
67
68 /* Allocate memory for queue. FREE_FUNC is a function to release the
69 data put in each queue element. */
70 #define QUEUE_alloc(TYPE, FREE_FUNC) queue_ ## TYPE ## _alloc (FREE_FUNC)
71
72 /* Length of queue Q. */
73 #define QUEUE_length(TYPE, Q) queue_ ## TYPE ## _length (Q)
74
75 /* Free queue Q. Q's free_func is called once for each element. */
76 #define QUEUE_free(TYPE, Q) queue_ ## TYPE ## _free (Q)
77
78 /* Iterate over elements in the queue Q and call function OPERATE on
79 each element. It is allowed to remove element by OPERATE. OPERATE
80 returns false to terminate the iteration and true to continue the
81 iteration. Return false if iteration is terminated by function
82 OPERATE, otherwise return true. */
83 #define QUEUE_iterate(TYPE, Q, OPERATE, PARAM) \
84 queue_ ## TYPE ## _iterate ((Q), (OPERATE), (PARAM))
85
86 /* Remove the element per the state of iterator ITER from queue Q.
87 Leave the caller to release the data in the queue element. */
88 #define QUEUE_remove_elem(TYPE, Q, ITER) \
89 queue_ ## TYPE ## _remove_elem ((Q), (ITER))
90
91 /* Define a new queue implementation. */
92
93 #define QUEUE(TYPE) struct queue_ ## TYPE
94 #define QUEUE_ELEM(TYPE) struct queue_elem_ ## TYPE
95 #define QUEUE_ITER(TYPE) struct queue_iter_ ## TYPE
96 #define QUEUE_ITER_FUNC(TYPE) queue_ ## TYPE ## _operate_func
97
98 #define DEFINE_QUEUE_P(TYPE) \
99 QUEUE_ELEM (TYPE) \
100 { \
101 QUEUE_ELEM (TYPE) *next; \
102 \
103 TYPE data; \
104 }; \
105 \
106 /* Queue iterator. */ \
107 QUEUE_ITER (TYPE) \
108 { \
109 /* The current element during traverse. */ \
110 QUEUE_ELEM (TYPE) *p; \
111 /* The previous element of P. */ \
112 QUEUE_ELEM (TYPE) *prev; \
113 }; \
114 \
115 QUEUE(TYPE) \
116 { \
117 /* The head and tail of the queue. */ \
118 QUEUE_ELEM (TYPE) *head; \
119 QUEUE_ELEM (TYPE) *tail; \
120 /* Function to release the data put in each \
121 queue element. */ \
122 void (*free_func) (TYPE); \
123 }; \
124 \
125 void \
126 queue_ ## TYPE ## _enque (QUEUE (TYPE) *q, TYPE v) \
127 { \
128 QUEUE_ELEM (TYPE) *p \
129 = xmalloc (sizeof (QUEUE_ELEM (TYPE))); \
130 \
131 gdb_assert (q != NULL); \
132 p->data = v; \
133 p->next = NULL; \
134 if (q->tail == NULL) \
135 { \
136 q->tail = p; \
137 q->head = p; \
138 } \
139 else \
140 { \
141 q->tail->next = p; \
142 q->tail = p; \
143 } \
144 } \
145 \
146 TYPE \
147 queue_ ## TYPE ## _deque (QUEUE (TYPE) *q) \
148 { \
149 QUEUE_ELEM (TYPE) *p; \
150 TYPE v; \
151 \
152 gdb_assert (q != NULL); \
153 p = q->head; \
154 gdb_assert (p != NULL); \
155 \
156 if (q->head == q->tail) \
157 { \
158 q->head = NULL; \
159 q->tail = NULL; \
160 } \
161 else \
162 q->head = q->head->next; \
163 \
164 v = p->data; \
165 \
166 xfree (p); \
167 return v; \
168 } \
169 \
170 TYPE \
171 queue_ ## TYPE ## _peek (QUEUE (TYPE) *q) \
172 { \
173 gdb_assert (q != NULL); \
174 gdb_assert (q->head != NULL); \
175 return q->head->data; \
176 } \
177 \
178 int \
179 queue_ ## TYPE ## _is_empty (QUEUE (TYPE) *q) \
180 { \
181 gdb_assert (q != NULL); \
182 return q->head == NULL; \
183 } \
184 \
185 void \
186 queue_ ## TYPE ## _remove_elem (QUEUE (TYPE) *q, \
187 QUEUE_ITER (TYPE) *iter) \
188 { \
189 gdb_assert (q != NULL); \
190 gdb_assert (iter != NULL && iter->p != NULL); \
191 \
192 if (iter->p == q->head || iter->p == q->tail) \
193 { \
194 if (iter->p == q->head) \
195 q->head = iter->p->next; \
196 if (iter->p == q->tail) \
197 q->tail = iter->prev; \
198 } \
199 else \
200 iter->prev->next = iter->p->next; \
201 \
202 xfree (iter->p); \
203 /* Indicate that ITER->p has been deleted from QUEUE q. */ \
204 iter->p = NULL; \
205 } \
206 \
207 int \
208 queue_ ## TYPE ## _iterate (QUEUE (TYPE) *q, \
209 QUEUE_ITER_FUNC (TYPE) operate, \
210 void *data) \
211 { \
212 QUEUE_ELEM (TYPE) *next = NULL; \
213 QUEUE_ITER (TYPE) iter = { NULL, NULL }; \
214 \
215 gdb_assert (q != NULL); \
216 \
217 for (iter.p = q->head; iter.p != NULL; iter.p = next) \
218 { \
219 next = iter.p->next; \
220 if (!operate (q, &iter, iter.p->data, data)) \
221 return 0; \
222 /* ITER.P was not deleted by function OPERATE. */ \
223 if (iter.p != NULL) \
224 iter.prev = iter.p; \
225 } \
226 return 1; \
227 } \
228 \
229 QUEUE (TYPE) * \
230 queue_ ## TYPE ## _alloc (void (*free_func) (TYPE)) \
231 { \
232 QUEUE (TYPE) *q; \
233 \
234 q = (QUEUE (TYPE) *) xmalloc (sizeof (QUEUE (TYPE))); \
235 q->head = NULL; \
236 q->tail = NULL; \
237 q->free_func = free_func; \
238 return q; \
239 } \
240 \
241 int \
242 queue_ ## TYPE ## _length (QUEUE (TYPE) *q) \
243 { \
244 QUEUE_ELEM (TYPE) *p; \
245 int len = 0; \
246 \
247 gdb_assert (q != NULL); \
248 \
249 for (p = q->head; p != NULL; p = p->next) \
250 len++; \
251 \
252 return len; \
253 } \
254 \
255 void \
256 queue_ ## TYPE ## _free (QUEUE (TYPE) *q) \
257 { \
258 QUEUE_ELEM (TYPE) *p, *next; \
259 \
260 gdb_assert (q != NULL); \
261 \
262 for (p = q->head; p != NULL; p = next) \
263 { \
264 next = p->next; \
265 if (q->free_func) \
266 q->free_func (p->data); \
267 xfree (p); \
268 } \
269 xfree (q); \
270 } \
271
272 /* External declarations for queue functions. */
273 #define DECLARE_QUEUE_P(TYPE) \
274 QUEUE (TYPE); \
275 QUEUE_ELEM (TYPE); \
276 QUEUE_ITER (TYPE); \
277 extern void \
278 queue_ ## TYPE ## _enque (QUEUE (TYPE) *q, TYPE v); \
279 extern TYPE \
280 queue_ ## TYPE ## _deque (QUEUE (TYPE) *q); \
281 extern int queue_ ## TYPE ## _is_empty (QUEUE (TYPE) *q); \
282 extern QUEUE (TYPE) * \
283 queue_ ## TYPE ## _alloc (void (*free_func) (TYPE)); \
284 extern int queue_ ## TYPE ## _length (QUEUE (TYPE) *q); \
285 extern TYPE \
286 queue_ ## TYPE ## _peek (QUEUE (TYPE) *q); \
287 extern void queue_ ## TYPE ## _free (QUEUE (TYPE) *q); \
288 typedef int QUEUE_ITER_FUNC(TYPE) (QUEUE (TYPE) *, \
289 QUEUE_ITER (TYPE) *, \
290 TYPE, \
291 void *); \
292 extern int \
293 queue_ ## TYPE ## _iterate (QUEUE (TYPE) *q, \
294 QUEUE_ITER_FUNC (TYPE) operate, \
295 void *); \
296 extern void \
297 queue_ ## TYPE ## _remove_elem (QUEUE (TYPE) *q, \
298 QUEUE_ITER (TYPE) *iter); \
299
300 #endif /* QUEUE_H */