mirror of https://gerrit.osmocom.org/asn1c
65 lines
1.5 KiB
C
65 lines
1.5 KiB
C
/*
|
|
* Singly linked tail queue support.
|
|
*/
|
|
#ifndef ASN1_PARSER_LIST_H
|
|
#define ASN1_PARSER_LIST_H
|
|
|
|
#define TQ_HEAD(type) \
|
|
struct { \
|
|
type *tq_head; \
|
|
type**tq_tail; \
|
|
}
|
|
|
|
#define TQ_MOVE(to, from) do { \
|
|
if(&(TQ_FIRST(from)) == (from)->tq_tail) { \
|
|
TQ_INIT(to); \
|
|
} else { \
|
|
(to)->tq_head = (from)->tq_head; \
|
|
(to)->tq_tail = (from)->tq_tail; \
|
|
} \
|
|
TQ_INIT(from); \
|
|
} while(0)
|
|
|
|
#define TQ_ENTRY(type) \
|
|
struct { \
|
|
type *tq_next; \
|
|
}
|
|
|
|
#define TQ_FIRST(headp) ((headp)->tq_head)
|
|
#define TQ_NEXT(el, field) ((el)->field.tq_next)
|
|
|
|
#define TQ_INIT(head) do { \
|
|
TQ_FIRST((head)) = 0; \
|
|
(head)->tq_tail = &TQ_FIRST((head)); \
|
|
} while(0)
|
|
|
|
#define TQ_FOR(var, head, field) \
|
|
for((var) = TQ_FIRST((head)); \
|
|
(var); (var) = TQ_NEXT((var), field))
|
|
|
|
/* MSVC does not have typeof(), cannot prevent side effects! */
|
|
#define TQ_ADD(head, xel, field) do { \
|
|
typeof(xel) __el = (xel); \
|
|
assert(TQ_NEXT((__el), field) == 0); \
|
|
*(head)->tq_tail = (__el); \
|
|
(head)->tq_tail = &TQ_NEXT((__el), field); \
|
|
} while(0)
|
|
|
|
/*
|
|
* Remove the first element and return it.
|
|
*/
|
|
#define TQ_REMOVE(head, field) ({ \
|
|
typeof(TQ_FIRST((head))) __fel; \
|
|
__fel = TQ_FIRST((head)); \
|
|
if(__fel == 0 \
|
|
|| (TQ_FIRST((head)) = TQ_NEXT(__fel, field)) \
|
|
== 0) { \
|
|
(head)->tq_tail = &TQ_FIRST((head)); \
|
|
} else { \
|
|
TQ_NEXT(__fel, field) = 0; \
|
|
} \
|
|
__fel; })
|
|
|
|
|
|
#endif /* ASN1_PARSER_LIST_H */
|