GDB (API)
|
00001 /* General queue data structure for GDB, the GNU debugger. 00002 00003 Copyright (C) 2012-2013 Free Software Foundation, Inc. 00004 00005 This file is part of GDB. 00006 00007 This program is free software; you can redistribute it and/or modify 00008 it under the terms of the GNU General Public License as published by 00009 the Free Software Foundation; either version 3 of the License, or 00010 (at your option) any later version. 00011 00012 This program is distributed in the hope that it will be useful, 00013 but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 GNU General Public License for more details. 00016 00017 You should have received a copy of the GNU General Public License 00018 along with this program. If not, see <http://www.gnu.org/licenses/>. */ 00019 00020 #ifndef QUEUE_H 00021 #define QUEUE_H 00022 00023 #include "libiberty.h" /* xmalloc */ 00024 #include "gdb_assert.h" 00025 00026 /* These macros implement functions and structs for a general queue. 00027 Macro 'DEFINE_QUEUE_P(TYPEDEF)' is to define the new queue type for 00028 TYPEDEF', and macro 'DECLARE_QUEUE_P' is to declare external queue 00029 APIs. The character P indicates TYPEDEF is a pointer (P). The 00030 counterpart on object (O) and integer (I) are not implemented. 00031 00032 An example of their use would be, 00033 00034 typedef struct foo 00035 {} *foo_p; 00036 00037 DEFINE_QUEUE_P (foo_p); 00038 // A pointer to a queue of foo pointers. FOO_XFREE is a destructor 00039 // function for foo instances in queue. 00040 QUEUE(foo_p) *foo_queue = QUEUE_alloc (foo_p, foo_xfree); 00041 00042 foo_p foo_var_p; 00043 // Enqueue and Dequeue 00044 QUEUE_enque (foo_p, foo_queue, foo_var_p); 00045 foo_var_p = QUEUE_deque (foo_p, foo_queue); 00046 00047 static int visit_foo (QUEUE (foo_p) *q, QUEUE_ITER (foo_p) *iter, 00048 foo_p f, void *data) 00049 { 00050 return 1; 00051 } 00052 // Iterate over queue. 00053 QUEUE_iterate (foo_p, foo_queue, visit_foo, ¶m); 00054 00055 QUEUE_free (foo_p, foo_queue); // Free queue. */ 00056 00057 /* Typical enqueue operation. Put V into queue Q. */ 00058 #define QUEUE_enque(TYPE, Q, V) queue_ ## TYPE ## _enque ((Q), (V)) 00059 00060 /* Typical dequeue operation. Return head element of queue Q and 00061 remove it. Q must not be empty. */ 00062 #define QUEUE_deque(TYPE, Q) queue_ ## TYPE ## _deque (Q) 00063 00064 /* Return the head element, but don't remove it from the queue. 00065 Q must not be empty. */ 00066 #define QUEUE_peek(TYPE, Q) queue_ ## TYPE ## _peek (Q) 00067 00068 /* Return true if queue Q is empty. */ 00069 #define QUEUE_is_empty(TYPE, Q) queue_ ## TYPE ## _is_empty (Q) 00070 00071 /* Allocate memory for queue. FREE_FUNC is a function to release the 00072 data put in each queue element. */ 00073 #define QUEUE_alloc(TYPE, FREE_FUNC) queue_ ## TYPE ## _alloc (FREE_FUNC) 00074 00075 /* Length of queue Q. */ 00076 #define QUEUE_length(TYPE, Q) queue_ ## TYPE ## _length (Q) 00077 00078 /* Free queue Q. Q's free_func is called once for each element. */ 00079 #define QUEUE_free(TYPE, Q) queue_ ## TYPE ## _free (Q) 00080 00081 /* Iterate over elements in the queue Q and call function OPERATE on 00082 each element. It is allowed to remove element by OPERATE. OPERATE 00083 returns false to terminate the iteration and true to continue the 00084 iteration. Return false if iteration is terminated by function 00085 OPERATE, otherwise return true. */ 00086 #define QUEUE_iterate(TYPE, Q, OPERATE, PARAM) \ 00087 queue_ ## TYPE ## _iterate ((Q), (OPERATE), (PARAM)) 00088 00089 /* Remove the element per the state of iterator ITER from queue Q. 00090 Leave the caller to release the data in the queue element. */ 00091 #define QUEUE_remove_elem(TYPE, Q, ITER) \ 00092 queue_ ## TYPE ## _remove_elem ((Q), (ITER)) 00093 00094 /* Define a new queue implementation. */ 00095 00096 #define QUEUE(TYPE) struct queue_ ## TYPE 00097 #define QUEUE_ELEM(TYPE) struct queue_elem_ ## TYPE 00098 #define QUEUE_ITER(TYPE) struct queue_iter_ ## TYPE 00099 #define QUEUE_ITER_FUNC(TYPE) queue_ ## TYPE ## _operate_func 00100 00101 #define DEFINE_QUEUE_P(TYPE) \ 00102 QUEUE_ELEM (TYPE) \ 00103 { \ 00104 QUEUE_ELEM (TYPE) *next; \ 00105 \ 00106 TYPE data; \ 00107 }; \ 00108 \ 00109 /* Queue iterator. */ \ 00110 QUEUE_ITER (TYPE) \ 00111 { \ 00112 /* The current element during traverse. */ \ 00113 QUEUE_ELEM (TYPE) *p; \ 00114 /* The previous element of P. */ \ 00115 QUEUE_ELEM (TYPE) *prev; \ 00116 }; \ 00117 \ 00118 QUEUE(TYPE) \ 00119 { \ 00120 /* The head and tail of the queue. */ \ 00121 QUEUE_ELEM (TYPE) *head; \ 00122 QUEUE_ELEM (TYPE) *tail; \ 00123 /* Function to release the data put in each \ 00124 queue element. */ \ 00125 void (*free_func) (TYPE); \ 00126 }; \ 00127 \ 00128 void \ 00129 queue_ ## TYPE ## _enque (QUEUE (TYPE) *q, TYPE v) \ 00130 { \ 00131 QUEUE_ELEM (TYPE) *p \ 00132 = xmalloc (sizeof (QUEUE_ELEM (TYPE))); \ 00133 \ 00134 gdb_assert (q != NULL); \ 00135 p->data = v; \ 00136 p->next = NULL; \ 00137 if (q->tail == NULL) \ 00138 { \ 00139 q->tail = p; \ 00140 q->head = p; \ 00141 } \ 00142 else \ 00143 { \ 00144 q->tail->next = p; \ 00145 q->tail = p; \ 00146 } \ 00147 } \ 00148 \ 00149 TYPE \ 00150 queue_ ## TYPE ## _deque (QUEUE (TYPE) *q) \ 00151 { \ 00152 QUEUE_ELEM (TYPE) *p; \ 00153 TYPE v; \ 00154 \ 00155 gdb_assert (q != NULL); \ 00156 p = q->head; \ 00157 gdb_assert (p != NULL); \ 00158 \ 00159 if (q->head == q->tail) \ 00160 { \ 00161 q->head = NULL; \ 00162 q->tail = NULL; \ 00163 } \ 00164 else \ 00165 q->head = q->head->next; \ 00166 \ 00167 v = p->data; \ 00168 \ 00169 xfree (p); \ 00170 return v; \ 00171 } \ 00172 \ 00173 TYPE \ 00174 queue_ ## TYPE ## _peek (QUEUE (TYPE) *q) \ 00175 { \ 00176 gdb_assert (q != NULL); \ 00177 gdb_assert (q->head != NULL); \ 00178 return q->head->data; \ 00179 } \ 00180 \ 00181 int \ 00182 queue_ ## TYPE ## _is_empty (QUEUE (TYPE) *q) \ 00183 { \ 00184 gdb_assert (q != NULL); \ 00185 return q->head == NULL; \ 00186 } \ 00187 \ 00188 void \ 00189 queue_ ## TYPE ## _remove_elem (QUEUE (TYPE) *q, \ 00190 QUEUE_ITER (TYPE) *iter) \ 00191 { \ 00192 gdb_assert (q != NULL); \ 00193 gdb_assert (iter != NULL && iter->p != NULL); \ 00194 \ 00195 if (iter->p == q->head || iter->p == q->tail) \ 00196 { \ 00197 if (iter->p == q->head) \ 00198 q->head = iter->p->next; \ 00199 if (iter->p == q->tail) \ 00200 q->tail = iter->prev; \ 00201 } \ 00202 else \ 00203 iter->prev->next = iter->p->next; \ 00204 \ 00205 xfree (iter->p); \ 00206 /* Indicate that ITER->p has been deleted from QUEUE q. */ \ 00207 iter->p = NULL; \ 00208 } \ 00209 \ 00210 int \ 00211 queue_ ## TYPE ## _iterate (QUEUE (TYPE) *q, \ 00212 QUEUE_ITER_FUNC (TYPE) operate, \ 00213 void *data) \ 00214 { \ 00215 QUEUE_ELEM (TYPE) *next = NULL; \ 00216 QUEUE_ITER (TYPE) iter = { NULL, NULL }; \ 00217 \ 00218 gdb_assert (q != NULL); \ 00219 \ 00220 for (iter.p = q->head; iter.p != NULL; iter.p = next) \ 00221 { \ 00222 next = iter.p->next; \ 00223 if (!operate (q, &iter, iter.p->data, data)) \ 00224 return 0; \ 00225 /* ITER.P was not deleted by function OPERATE. */ \ 00226 if (iter.p != NULL) \ 00227 iter.prev = iter.p; \ 00228 } \ 00229 return 1; \ 00230 } \ 00231 \ 00232 QUEUE (TYPE) * \ 00233 queue_ ## TYPE ## _alloc (void (*free_func) (TYPE)) \ 00234 { \ 00235 QUEUE (TYPE) *q; \ 00236 \ 00237 q = (QUEUE (TYPE) *) xmalloc (sizeof (QUEUE (TYPE))); \ 00238 q->head = NULL; \ 00239 q->tail = NULL; \ 00240 q->free_func = free_func; \ 00241 return q; \ 00242 } \ 00243 \ 00244 int \ 00245 queue_ ## TYPE ## _length (QUEUE (TYPE) *q) \ 00246 { \ 00247 QUEUE_ELEM (TYPE) *p; \ 00248 int len = 0; \ 00249 \ 00250 gdb_assert (q != NULL); \ 00251 \ 00252 for (p = q->head; p != NULL; p = p->next) \ 00253 len++; \ 00254 \ 00255 return len; \ 00256 } \ 00257 \ 00258 void \ 00259 queue_ ## TYPE ## _free (QUEUE (TYPE) *q) \ 00260 { \ 00261 QUEUE_ELEM (TYPE) *p, *next; \ 00262 \ 00263 gdb_assert (q != NULL); \ 00264 \ 00265 for (p = q->head; p != NULL; p = next) \ 00266 { \ 00267 next = p->next; \ 00268 if (q->free_func) \ 00269 q->free_func (p->data); \ 00270 xfree (p); \ 00271 } \ 00272 xfree (q); \ 00273 } \ 00274 00275 /* External declarations for queue functions. */ 00276 #define DECLARE_QUEUE_P(TYPE) \ 00277 QUEUE (TYPE); \ 00278 QUEUE_ELEM (TYPE); \ 00279 QUEUE_ITER (TYPE); \ 00280 extern void \ 00281 queue_ ## TYPE ## _enque (QUEUE (TYPE) *q, TYPE v); \ 00282 extern TYPE \ 00283 queue_ ## TYPE ## _deque (QUEUE (TYPE) *q); \ 00284 extern int queue_ ## TYPE ## _is_empty (QUEUE (TYPE) *q); \ 00285 extern QUEUE (TYPE) * \ 00286 queue_ ## TYPE ## _alloc (void (*free_func) (TYPE)); \ 00287 extern int queue_ ## TYPE ## _length (QUEUE (TYPE) *q); \ 00288 extern TYPE \ 00289 queue_ ## TYPE ## _peek (QUEUE (TYPE) *q); \ 00290 extern void queue_ ## TYPE ## _free (QUEUE (TYPE) *q); \ 00291 typedef int QUEUE_ITER_FUNC(TYPE) (QUEUE (TYPE) *, \ 00292 QUEUE_ITER (TYPE) *, \ 00293 TYPE, \ 00294 void *); \ 00295 extern int \ 00296 queue_ ## TYPE ## _iterate (QUEUE (TYPE) *q, \ 00297 QUEUE_ITER_FUNC (TYPE) operate, \ 00298 void *); \ 00299 extern void \ 00300 queue_ ## TYPE ## _remove_elem (QUEUE (TYPE) *q, \ 00301 QUEUE_ITER (TYPE) *iter); \ 00302 00303 #endif /* QUEUE_H */