blob: d6a669ac4c64fae3b87ca062989b5a668d2e6f6f [file] [log] [blame]
Lev Walkinf15320b2004-06-03 03:38:44 +00001/*
2 * Singly linked tail queue support.
3 */
4#ifndef ASN1_PARSER_LIST_H
5#define ASN1_PARSER_LIST_H
6
Lev Walkinc7d17be2004-08-25 00:42:44 +00007#define TQ_HEAD(type) \
8 struct { \
9 type *tq_head; \
10 type**tq_tail; \
Lev Walkinf15320b2004-06-03 03:38:44 +000011 }
12
Lev Walkinc7d17be2004-08-25 00:42:44 +000013#define TQ_MOVE(to, from) do { \
14 if(&(TQ_FIRST(from)) == (from)->tq_tail) { \
15 TQ_INIT(to); \
16 } else { \
17 (to)->tq_head = (from)->tq_head; \
18 (to)->tq_tail = (from)->tq_tail; \
19 } \
20 TQ_INIT(from); \
21 } while(0)
Lev Walkinf15320b2004-06-03 03:38:44 +000022
Lev Walkinc7d17be2004-08-25 00:42:44 +000023#define TQ_ENTRY(type) \
24 struct { \
25 type *tq_next; \
Lev Walkinf15320b2004-06-03 03:38:44 +000026 }
27
28#define TQ_FIRST(headp) ((headp)->tq_head)
29#define TQ_NEXT(el, field) ((el)->field.tq_next)
30
31#define TQ_INIT(head) do { \
32 TQ_FIRST((head)) = 0; \
33 (head)->tq_tail = &TQ_FIRST((head)); \
34 } while(0)
35
36#define TQ_FOR(var, head, field) \
37 for((var) = TQ_FIRST((head)); \
38 (var); (var) = TQ_NEXT((var), field))
39
Lev Walkin4efbfb72005-02-25 14:20:30 +000040/* MSVC does not have typeof(), cannot prevent side effects! */
Lev Walkinf15320b2004-06-03 03:38:44 +000041#define TQ_ADD(head, xel, field) do { \
Lev Walkinfa095972005-02-25 14:25:46 +000042 typeof(xel) __el = (xel); \
43 assert(TQ_NEXT((__el), field) == 0); \
44 *(head)->tq_tail = (__el); \
45 (head)->tq_tail = &TQ_NEXT((__el), field); \
Lev Walkinf15320b2004-06-03 03:38:44 +000046 } while(0)
47
48/*
49 * Remove the first element and return it.
50 */
51#define TQ_REMOVE(head, field) ({ \
52 typeof(TQ_FIRST((head))) __fel; \
53 __fel = TQ_FIRST((head)); \
54 if(__fel == 0 \
55 || (TQ_FIRST((head)) = TQ_NEXT(__fel, field)) \
56 == 0) { \
57 (head)->tq_tail = &TQ_FIRST((head)); \
58 } else { \
59 TQ_NEXT(__fel, field) = 0; \
60 } \
61 __fel; })
62
63
64#endif /* ASN1_PARSER_LIST_H */