#ifndef NTP_LISTS_H
#define NTP_LISTS_H
#include "ntp_types.h"
#include "ntp_assert.h"
#ifdef DEBUG
# define NTP_DEBUG_LISTS_H
#endif
#ifndef NTP_DEBUG_LISTS_H
#define MAYBE_Z_LISTS(p) do { } while (FALSE)
#else
#define MAYBE_Z_LISTS(p) (p) = NULL
#endif
#define LINK_SLIST(listhead, pentry, nextlink) \
do { \
(pentry)->nextlink = (listhead); \
(listhead) = (pentry); \
} while (FALSE)
#define LINK_TAIL_SLIST(listhead, pentry, nextlink, entrytype) \
do { \
entrytype **pptail; \
\
pptail = &(listhead); \
while (*pptail != NULL) \
pptail = &((*pptail)->nextlink); \
\
(pentry)->nextlink = NULL; \
*pptail = (pentry); \
} while (FALSE)
#define LINK_SORT_SLIST_CURRENT() (*ppentry)
#define L_S_S_CUR() LINK_SORT_SLIST_CURRENT()
#define LINK_SORT_SLIST(listhead, pentry, beforecur, nextlink, \
entrytype) \
do { \
entrytype **ppentry; \
\
ppentry = &(listhead); \
while (TRUE) { \
if (NULL == *ppentry || (beforecur)) { \
(pentry)->nextlink = *ppentry; \
*ppentry = (pentry); \
break; \
} \
ppentry = &((*ppentry)->nextlink); \
if (NULL == *ppentry) { \
(pentry)->nextlink = NULL; \
*ppentry = (pentry); \
break; \
} \
} \
} while (FALSE)
#define UNLINK_HEAD_SLIST(punlinked, listhead, nextlink) \
do { \
(punlinked) = (listhead); \
if (NULL != (punlinked)) { \
(listhead) = (punlinked)->nextlink; \
MAYBE_Z_LISTS((punlinked)->nextlink); \
} \
} while (FALSE)
#define UNLINK_EXPR_SLIST_CURRENT() (*ppentry)
#define U_E_S_CUR() UNLINK_EXPR_SLIST_CURRENT()
#define UNLINK_EXPR_SLIST(punlinked, listhead, expr, nextlink, \
entrytype) \
do { \
entrytype **ppentry; \
\
ppentry = &(listhead); \
\
while (!(expr)) \
if (*ppentry != NULL && \
(*ppentry)->nextlink != NULL) { \
ppentry = &((*ppentry)->nextlink); \
} else { \
ppentry = NULL; \
break; \
} \
\
if (ppentry != NULL) { \
(punlinked) = *ppentry; \
*ppentry = (punlinked)->nextlink; \
MAYBE_Z_LISTS((punlinked)->nextlink); \
} else { \
(punlinked) = NULL; \
} \
} while (FALSE)
#define UNLINK_SLIST(punlinked, listhead, ptounlink, nextlink, \
entrytype) \
UNLINK_EXPR_SLIST(punlinked, listhead, (ptounlink) == \
U_E_S_CUR(), nextlink, entrytype)
#define CHECK_SLIST(listhead, nextlink, entrytype) \
do { \
entrytype *pentry; \
\
for (pentry = (listhead); \
pentry != NULL; \
pentry = pentry->nextlink) { \
INSIST(pentry != pentry->nextlink); \
INSIST((listhead) != pentry->nextlink); \
} \
} while (FALSE)
#define DECL_FIFO_ANCHOR(entrytype) \
struct { \
entrytype * phead; \
entrytype ** pptail; \
}
#define HEAD_FIFO(anchor) ((anchor).phead)
#define TAIL_FIFO(anchor) ((NULL == (anchor).pptail) \
? NULL \
: *((anchor).pptail))
#if !defined(NTP_DEBUG_LISTS_H)
#define CHECK_FIFO_CONSISTENCY(anchor) do { } while (FALSE)
#else
#define CHECK_FIFO_CONSISTENCY(anchor) \
check_gen_fifo_consistency(&(anchor))
void check_gen_fifo_consistency(void *fifo);
#endif
typedef struct gen_node_tag gen_node;
struct gen_node_tag {
gen_node * link;
};
typedef DECL_FIFO_ANCHOR(gen_node) gen_fifo;
#define LINK_FIFO(anchor, pentry, nextlink) \
do { \
CHECK_FIFO_CONSISTENCY(anchor); \
\
(pentry)->nextlink = NULL; \
if (NULL != (anchor).pptail) { \
(*((anchor).pptail))->nextlink = (pentry); \
(anchor).pptail = \
&(*((anchor).pptail))->nextlink; \
} else { \
(anchor).phead = (pentry); \
(anchor).pptail = &(anchor).phead; \
} \
\
CHECK_FIFO_CONSISTENCY(anchor); \
} while (FALSE)
#define UNLINK_FIFO(punlinked, anchor, nextlink) \
do { \
CHECK_FIFO_CONSISTENCY(anchor); \
\
(punlinked) = (anchor).phead; \
if (NULL != (punlinked)) { \
(anchor).phead = (punlinked)->nextlink; \
if (NULL == (anchor).phead) \
(anchor).pptail = NULL; \
else if ((anchor).pptail == \
&(punlinked)->nextlink) \
(anchor).pptail = &(anchor).phead; \
MAYBE_Z_LISTS((punlinked)->nextlink); \
CHECK_FIFO_CONSISTENCY(anchor); \
} \
} while (FALSE)
#define UNLINK_MID_FIFO(punlinked, anchor, tounlink, nextlink, \
entrytype) \
do { \
entrytype **ppentry; \
\
CHECK_FIFO_CONSISTENCY(anchor); \
\
ppentry = &(anchor).phead; \
\
while ((tounlink) != *ppentry) \
if ((*ppentry)->nextlink != NULL) { \
ppentry = &((*ppentry)->nextlink); \
} else { \
ppentry = NULL; \
break; \
} \
\
if (ppentry != NULL) { \
(punlinked) = *ppentry; \
*ppentry = (punlinked)->nextlink; \
if (NULL == *ppentry) \
(anchor).pptail = NULL; \
else if ((anchor).pptail == \
&(punlinked)->nextlink) \
(anchor).pptail = &(anchor).phead; \
MAYBE_Z_LISTS((punlinked)->nextlink); \
CHECK_FIFO_CONSISTENCY(anchor); \
} else { \
(punlinked) = NULL; \
} \
} while (FALSE)
#define CONCAT_FIFO(f1, f2, nextlink) \
do { \
CHECK_FIFO_CONSISTENCY(f1); \
CHECK_FIFO_CONSISTENCY(f2); \
\
if ((f2).pptail != NULL) { \
if ((f1).pptail != NULL) { \
(*(f1).pptail)->nextlink = (f2).phead; \
if ((f2).pptail == &(f2).phead) \
(f1).pptail = \
&(*(f1).pptail)->nextlink; \
else \
(f1).pptail = (f2).pptail; \
CHECK_FIFO_CONSISTENCY(f1); \
} else { \
(f1) = (f2); \
} \
MAYBE_Z_LISTS((f2).phead); \
MAYBE_Z_LISTS((f2).pptail); \
} \
} while (FALSE)
#define DECL_DLIST_LINK(entrytype, link) \
struct { \
entrytype * b; \
entrytype * f; \
} link
#define INIT_DLIST(listhead, link) \
do { \
(listhead).link.f = &(listhead); \
(listhead).link.b = &(listhead); \
} while (FALSE)
#define HEAD_DLIST(listhead, link) \
( \
(&(listhead) != (listhead).link.f) \
? (listhead).link.f \
: NULL \
)
#define TAIL_DLIST(listhead, link) \
( \
(&(listhead) != (listhead).link.b) \
? (listhead).link.b \
: NULL \
)
#define NEXT_DLIST(listhead, entry, link) \
( \
(&(listhead) != (entry)->link.f) \
? (entry)->link.f \
: NULL \
)
#define PREV_DLIST(listhead, entry, link) \
( \
(&(listhead) != (entry)->link.b) \
? (entry)->link.b \
: NULL \
)
#define LINK_DLIST(listhead, pentry, link) \
do { \
(pentry)->link.f = (listhead).link.f; \
(pentry)->link.b = &(listhead); \
(listhead).link.f->link.b = (pentry); \
(listhead).link.f = (pentry); \
} while (FALSE)
#define LINK_TAIL_DLIST(listhead, pentry, link) \
do { \
(pentry)->link.b = (listhead).link.b; \
(pentry)->link.f = &(listhead); \
(listhead).link.b->link.f = (pentry); \
(listhead).link.b = (pentry); \
} while (FALSE)
#define UNLINK_DLIST(ptounlink, link) \
do { \
(ptounlink)->link.b->link.f = (ptounlink)->link.f; \
(ptounlink)->link.f->link.b = (ptounlink)->link.b; \
MAYBE_Z_LISTS((ptounlink)->link.b); \
MAYBE_Z_LISTS((ptounlink)->link.f); \
} while (FALSE)
#define ITER_DLIST_BEGIN(listhead, iter, link, entrytype) \
{ \
entrytype *i_dl_nextiter; \
\
for ((iter) = (listhead).link.f; \
(iter) != &(listhead) \
&& ((i_dl_nextiter = (iter)->link.f), TRUE); \
(iter) = i_dl_nextiter) {
#define ITER_DLIST_END() \
} \
}
#define REV_ITER_DLIST_BEGIN(listhead, iter, link, entrytype) \
{ \
entrytype *i_dl_nextiter; \
\
for ((iter) = (listhead).link.b; \
(iter) != &(listhead) \
&& ((i_dl_nextiter = (iter)->link.b), TRUE); \
(iter) = i_dl_nextiter) {
#define REV_ITER_DLIST_END() \
} \
}
#endif