/*
|
/*
|
* lists.h: Simple list macros for Linux
|
* lists.h: Simple list macros for Linux
|
*/
|
*/
|
|
|
#define DLNODE(ptype) \
|
#define DLNODE(ptype) \
|
struct { \
|
struct { \
|
ptype * dl_prev; \
|
ptype * dl_prev; \
|
ptype * dl_next; \
|
ptype * dl_next; \
|
}
|
}
|
|
|
#define DNODE_SINGLE(node) {(node),(node)}
|
#define DNODE_SINGLE(node) {(node),(node)}
|
#define DNODE_NULL {0,0}
|
#define DNODE_NULL {0,0}
|
|
|
#define DLIST_INIT(listnam) \
|
#define DLIST_INIT(listnam) \
|
(listnam).dl_prev = &(listnam); \
|
(listnam).dl_prev = &(listnam); \
|
(listnam).dl_next = &(listnam);
|
(listnam).dl_next = &(listnam);
|
|
|
#define DLIST_NEXT(listnam) listnam.dl_next
|
#define DLIST_NEXT(listnam) listnam.dl_next
|
#define DLIST_PREV(listnam) listnam.dl_prev
|
#define DLIST_PREV(listnam) listnam.dl_prev
|
|
|
#define DLIST_INSERT_AFTER(node, new, listnam) do { \
|
#define DLIST_INSERT_AFTER(node, new, listnam) do { \
|
(new)->listnam.dl_prev = (node); \
|
(new)->listnam.dl_prev = (node); \
|
(new)->listnam.dl_next = (node)->listnam.dl_next; \
|
(new)->listnam.dl_next = (node)->listnam.dl_next; \
|
(node)->listnam.dl_next->listnam.dl_prev = (new); \
|
(node)->listnam.dl_next->listnam.dl_prev = (new); \
|
(node)->listnam.dl_next = (new); \
|
(node)->listnam.dl_next = (new); \
|
} while (0)
|
} while (0)
|
|
|
#define DLIST_INSERT_BEFORE(node, new, listnam) do { \
|
#define DLIST_INSERT_BEFORE(node, new, listnam) do { \
|
(new)->listnam.dl_next = (node); \
|
(new)->listnam.dl_next = (node); \
|
(new)->listnam.dl_prev = (node)->listnam.dl_prev; \
|
(new)->listnam.dl_prev = (node)->listnam.dl_prev; \
|
(node)->listnam.dl_prev->listnam.dl_next = (new); \
|
(node)->listnam.dl_prev->listnam.dl_next = (new); \
|
(node)->listnam.dl_prev = (new); \
|
(node)->listnam.dl_prev = (new); \
|
} while (0)
|
} while (0)
|
|
|
#define DLIST_DELETE(node, listnam) do { \
|
#define DLIST_DELETE(node, listnam) do { \
|
node->listnam.dl_prev->listnam.dl_next = \
|
node->listnam.dl_prev->listnam.dl_next = \
|
node->listnam.dl_next; \
|
node->listnam.dl_next; \
|
node->listnam.dl_next->listnam.dl_prev = \
|
node->listnam.dl_next->listnam.dl_prev = \
|
node->listnam.dl_prev; \
|
node->listnam.dl_prev; \
|
} while (0)
|
} while (0)
|
|
|
/*
|
/*
|
* queue-style operations, which have a head and tail
|
* queue-style operations, which have a head and tail
|
*/
|
*/
|
|
|
#define QUEUE_INIT(head, listnam, ptype) \
|
#define QUEUE_INIT(head, listnam, ptype) \
|
(head)->listnam.dl_prev = (head)->listnam.dl_next = (ptype)(head);
|
(head)->listnam.dl_prev = (head)->listnam.dl_next = (ptype)(head);
|
|
|
#define QUEUE_FIRST(head, listnam) (head)->DLIST_NEXT(listnam)
|
#define QUEUE_FIRST(head, listnam) (head)->DLIST_NEXT(listnam)
|
#define QUEUE_LAST(head, listnam) (head)->DLIST_PREV(listnam)
|
#define QUEUE_LAST(head, listnam) (head)->DLIST_PREV(listnam)
|
#define QUEUE_EMPTY(head, listnam) \
|
#define QUEUE_EMPTY(head, listnam) \
|
((QUEUE_FIRST(head, listnam) == QUEUE_LAST(head, listnam)) && \
|
((QUEUE_FIRST(head, listnam) == QUEUE_LAST(head, listnam)) && \
|
((u_long)QUEUE_FIRST(head, listnam) == (u_long)head))
|
((u_long)QUEUE_FIRST(head, listnam) == (u_long)head))
|
|
|
#define QUEUE_ENTER(head, new, listnam, ptype) do { \
|
#define QUEUE_ENTER(head, new, listnam, ptype) do { \
|
(new)->listnam.dl_prev = (ptype)(head); \
|
(new)->listnam.dl_prev = (ptype)(head); \
|
(new)->listnam.dl_next = (head)->listnam.dl_next; \
|
(new)->listnam.dl_next = (head)->listnam.dl_next; \
|
(head)->listnam.dl_next->listnam.dl_prev = (new); \
|
(head)->listnam.dl_next->listnam.dl_prev = (new); \
|
(head)->listnam.dl_next = (new); \
|
(head)->listnam.dl_next = (new); \
|
} while (0)
|
} while (0)
|
|
|
#define QUEUE_REMOVE(head, node, listnam) DLIST_DELETE(node, listnam)
|
#define QUEUE_REMOVE(head, node, listnam) DLIST_DELETE(node, listnam)
|
|
|