1 /* General queue data structure for GDB, the GNU debugger.
3 Copyright (C) 2012-2014 Free Software Foundation, Inc.
5 This file is part of GDB.
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.
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.
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/>. */
23 #include "gdb_assert.h"
25 /* These macros implement functions and structs for a general queue.
26 Macro 'DEFINE_QUEUE_P(TYPEDEF)' is to define the new queue type for
27 TYPEDEF', and macro 'DECLARE_QUEUE_P' is to declare external queue
28 APIs. The character P indicates TYPEDEF is a pointer (P). The
29 counterpart on object (O) and integer (I) are not implemented.
31 An example of their use would be,
36 DEFINE_QUEUE_P (foo_p);
37 // A pointer to a queue of foo pointers. FOO_XFREE is a destructor
38 // function for foo instances in queue.
39 QUEUE(foo_p) *foo_queue = QUEUE_alloc (foo_p, foo_xfree);
42 // Enqueue and Dequeue
43 QUEUE_enque (foo_p, foo_queue, foo_var_p);
44 foo_var_p = QUEUE_deque (foo_p, foo_queue);
46 static int visit_foo (QUEUE (foo_p) *q, QUEUE_ITER (foo_p) *iter,
51 // Iterate over queue.
52 QUEUE_iterate (foo_p, foo_queue, visit_foo, ¶m);
54 QUEUE_free (foo_p, foo_queue); // Free queue. */
56 /* Typical enqueue operation. Put V into queue Q. */
57 #define QUEUE_enque(TYPE, Q, V) queue_ ## TYPE ## _enque ((Q), (V))
59 /* Typical dequeue operation. Return head element of queue Q and
60 remove it. Q must not be empty. */
61 #define QUEUE_deque(TYPE, Q) queue_ ## TYPE ## _deque (Q)
63 /* Return the head element, but don't remove it from the queue.
64 Q must not be empty. */
65 #define QUEUE_peek(TYPE, Q) queue_ ## TYPE ## _peek (Q)
67 /* Return true if queue Q is empty. */
68 #define QUEUE_is_empty(TYPE, Q) queue_ ## TYPE ## _is_empty (Q)
70 /* Allocate memory for queue. FREE_FUNC is a function to release the
71 data put in each queue element. */
72 #define QUEUE_alloc(TYPE, FREE_FUNC) queue_ ## TYPE ## _alloc (FREE_FUNC)
74 /* Length of queue Q. */
75 #define QUEUE_length(TYPE, Q) queue_ ## TYPE ## _length (Q)
77 /* Free queue Q. Q's free_func is called once for each element. */
78 #define QUEUE_free(TYPE, Q) queue_ ## TYPE ## _free (Q)
80 /* Iterate over elements in the queue Q and call function OPERATE on
81 each element. It is allowed to remove element by OPERATE. OPERATE
82 returns false to terminate the iteration and true to continue the
83 iteration. Return false if iteration is terminated by function
84 OPERATE, otherwise return true. */
85 #define QUEUE_iterate(TYPE, Q, OPERATE, PARAM) \
86 queue_ ## TYPE ## _iterate ((Q), (OPERATE), (PARAM))
88 /* Remove the element per the state of iterator ITER from queue Q.
89 Leave the caller to release the data in the queue element. */
90 #define QUEUE_remove_elem(TYPE, Q, ITER) \
91 queue_ ## TYPE ## _remove_elem ((Q), (ITER))
93 /* Define a new queue implementation. */
95 #define QUEUE(TYPE) struct queue_ ## TYPE
96 #define QUEUE_ELEM(TYPE) struct queue_elem_ ## TYPE
97 #define QUEUE_ITER(TYPE) struct queue_iter_ ## TYPE
98 #define QUEUE_ITER_FUNC(TYPE) queue_ ## TYPE ## _operate_func
100 #define DEFINE_QUEUE_P(TYPE) \
103 QUEUE_ELEM (TYPE) *next; \
108 /* Queue iterator. */ \
111 /* The current element during traverse. */ \
112 QUEUE_ELEM (TYPE) *p; \
113 /* The previous element of P. */ \
114 QUEUE_ELEM (TYPE) *prev; \
119 /* The head and tail of the queue. */ \
120 QUEUE_ELEM (TYPE) *head; \
121 QUEUE_ELEM (TYPE) *tail; \
122 /* Function to release the data put in each \
124 void (*free_func) (TYPE); \
128 queue_ ## TYPE ## _enque (QUEUE (TYPE) *q, TYPE v) \
130 QUEUE_ELEM (TYPE) *p \
131 = xmalloc (sizeof (QUEUE_ELEM (TYPE))); \
133 gdb_assert (q != NULL); \
136 if (q->tail == NULL) \
149 queue_ ## TYPE ## _deque (QUEUE (TYPE) *q) \
151 QUEUE_ELEM (TYPE) *p; \
154 gdb_assert (q != NULL); \
156 gdb_assert (p != NULL); \
158 if (q->head == q->tail) \
164 q->head = q->head->next; \
173 queue_ ## TYPE ## _peek (QUEUE (TYPE) *q) \
175 gdb_assert (q != NULL); \
176 gdb_assert (q->head != NULL); \
177 return q->head->data; \
181 queue_ ## TYPE ## _is_empty (QUEUE (TYPE) *q) \
183 gdb_assert (q != NULL); \
184 return q->head == NULL; \
188 queue_ ## TYPE ## _remove_elem (QUEUE (TYPE) *q, \
189 QUEUE_ITER (TYPE) *iter) \
191 gdb_assert (q != NULL); \
192 gdb_assert (iter != NULL && iter->p != NULL); \
194 if (iter->p == q->head || iter->p == q->tail) \
196 if (iter->p == q->head) \
197 q->head = iter->p->next; \
198 if (iter->p == q->tail) \
199 q->tail = iter->prev; \
202 iter->prev->next = iter->p->next; \
205 /* Indicate that ITER->p has been deleted from QUEUE q. */ \
210 queue_ ## TYPE ## _iterate (QUEUE (TYPE) *q, \
211 QUEUE_ITER_FUNC (TYPE) operate, \
214 QUEUE_ELEM (TYPE) *next = NULL; \
215 QUEUE_ITER (TYPE) iter = { NULL, NULL }; \
217 gdb_assert (q != NULL); \
219 for (iter.p = q->head; iter.p != NULL; iter.p = next) \
221 next = iter.p->next; \
222 if (!operate (q, &iter, iter.p->data, data)) \
224 /* ITER.P was not deleted by function OPERATE. */ \
225 if (iter.p != NULL) \
226 iter.prev = iter.p; \
232 queue_ ## TYPE ## _alloc (void (*free_func) (TYPE)) \
236 q = (QUEUE (TYPE) *) xmalloc (sizeof (QUEUE (TYPE))); \
239 q->free_func = free_func; \
244 queue_ ## TYPE ## _length (QUEUE (TYPE) *q) \
246 QUEUE_ELEM (TYPE) *p; \
249 gdb_assert (q != NULL); \
251 for (p = q->head; p != NULL; p = p->next) \
258 queue_ ## TYPE ## _free (QUEUE (TYPE) *q) \
260 QUEUE_ELEM (TYPE) *p, *next; \
262 gdb_assert (q != NULL); \
264 for (p = q->head; p != NULL; p = next) \
268 q->free_func (p->data); \
274 /* External declarations for queue functions. */
275 #define DECLARE_QUEUE_P(TYPE) \
280 queue_ ## TYPE ## _enque (QUEUE (TYPE) *q, TYPE v); \
282 queue_ ## TYPE ## _deque (QUEUE (TYPE) *q); \
283 extern int queue_ ## TYPE ## _is_empty (QUEUE (TYPE) *q); \
284 extern QUEUE (TYPE) * \
285 queue_ ## TYPE ## _alloc (void (*free_func) (TYPE)); \
286 extern int queue_ ## TYPE ## _length (QUEUE (TYPE) *q); \
288 queue_ ## TYPE ## _peek (QUEUE (TYPE) *q); \
289 extern void queue_ ## TYPE ## _free (QUEUE (TYPE) *q); \
290 typedef int QUEUE_ITER_FUNC(TYPE) (QUEUE (TYPE) *, \
291 QUEUE_ITER (TYPE) *, \
295 queue_ ## TYPE ## _iterate (QUEUE (TYPE) *q, \
296 QUEUE_ITER_FUNC (TYPE) operate, \
299 queue_ ## TYPE ## _remove_elem (QUEUE (TYPE) *q, \
300 QUEUE_ITER (TYPE) *iter); \