4 Queue Handling Routines
6 Taken from smartall by John Walker.
8 http://www.fourmilab.ch/smartall/
13 Copyright (C) 2000, 2001, 2002 Kern Sibbald and John Walker
15 This program is free software; you can redistribute it and/or
16 modify it under the terms of the GNU General Public License as
17 published by the Free Software Foundation; either version 2 of
18 the License, or (at your option) any later version.
20 This program is distributed in the hope that it will be useful,
21 but WITHOUT ANY WARRANTY; without even the implied warranty of
22 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
23 General Public License for more details.
25 You should have received a copy of the GNU General Public
26 License along with this program; if not, write to the Free
27 Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
35 /* General purpose queue */
39 struct b_queue *qnext, /* Next item in queue */
40 *qprev; /* Previous item in queue */
45 * To define a queue, use the following
47 * static BQUEUE xyz = { &xyz, &xyz };
49 * Also, note, that the only real requirement is that
50 * the object that is passed to these routines contain
51 * a BQUEUE object as the very first member. The
52 * rest of the structure may be anything.
54 * NOTE!!!! The casting here is REALLY painful, but this avoids
55 * doing ugly casting every where else in the code.
59 /* Queue manipulation functions. */
62 /* QINSERT -- Insert object at end of queue */
64 void qinsert(BQUEUE *qhead, BQUEUE *object)
66 #define qh ((BQUEUE *)qhead)
67 #define obj ((BQUEUE *)object)
69 ASSERT(qh->qprev->qnext == qh);
70 ASSERT(qh->qnext->qprev == qh);
73 obj->qprev = qh->qprev;
75 obj->qprev->qnext = obj;
81 /* QREMOVE -- Remove next object from the queue given
82 the queue head (or any item).
83 Returns NULL if queue is empty */
85 BQUEUE *qremove(BQUEUE *qhead)
87 #define qh ((BQUEUE *)qhead)
90 ASSERT(qh->qprev->qnext == qh);
91 ASSERT(qh->qnext->qprev == qh);
93 if ((object = qh->qnext) == qh)
95 qh->qnext = object->qnext;
96 object->qnext->qprev = qh;
101 /* QNEXT -- Return next item from the queue
102 * returns NULL at the end of the queue.
103 * If qitem is NULL, the first item from
104 * the queue is returned.
107 BQUEUE *qnext(BQUEUE *qhead, BQUEUE *qitem)
109 #define qh ((BQUEUE *)qhead)
110 #define qi ((BQUEUE *)qitem)
116 ASSERT(qi->qprev->qnext == qi);
117 ASSERT(qi->qnext->qprev == qi);
119 if ((object = qi->qnext) == qh)
127 /* QDCHAIN -- Dequeue an item from the middle of a queue. Passed
128 the queue item, returns the (now dechained) queue item. */
130 BQUEUE *qdchain(BQUEUE *qitem)
132 #define qi ((BQUEUE *)qitem)
134 ASSERT(qi->qprev->qnext == qi);
135 ASSERT(qi->qnext->qprev == qi);
137 return qremove(qi->qprev);