blob: 858f24de4b93522b865b1eb0044525d720b990ad [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
Lev Walkin0e90aa02013-03-19 16:17:13 -070048#define TQ_CONCAT(head1, head2, field) do { \
49 if(TQ_FIRST(head2)) { \
50 *(head1)->tq_tail = (head2)->tq_head; \
51 (head1)->tq_tail = (head2)->tq_tail; \
52 TQ_INIT(head2); \
53 } \
54 } while(0)
55
Lev Walkinf15320b2004-06-03 03:38:44 +000056/*
57 * Remove the first element and return it.
58 */
59#define TQ_REMOVE(head, field) ({ \
60 typeof(TQ_FIRST((head))) __fel; \
61 __fel = TQ_FIRST((head)); \
62 if(__fel == 0 \
63 || (TQ_FIRST((head)) = TQ_NEXT(__fel, field)) \
64 == 0) { \
65 (head)->tq_tail = &TQ_FIRST((head)); \
66 } else { \
67 TQ_NEXT(__fel, field) = 0; \
68 } \
69 __fel; })
70
71
72#endif /* ASN1_PARSER_LIST_H */