Lev Walkin | f15320b | 2004-06-03 03:38:44 +0000 | [diff] [blame] | 1 | /* |
| 2 | * Singly linked tail queue support. |
| 3 | */ |
| 4 | #ifndef ASN1_PARSER_LIST_H |
| 5 | #define ASN1_PARSER_LIST_H |
| 6 | |
Lev Walkin | c7d17be | 2004-08-25 00:42:44 +0000 | [diff] [blame] | 7 | #define TQ_HEAD(type) \ |
| 8 | struct { \ |
| 9 | type *tq_head; \ |
| 10 | type**tq_tail; \ |
Lev Walkin | f15320b | 2004-06-03 03:38:44 +0000 | [diff] [blame] | 11 | } |
| 12 | |
Lev Walkin | c7d17be | 2004-08-25 00:42:44 +0000 | [diff] [blame] | 13 | #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 Walkin | f15320b | 2004-06-03 03:38:44 +0000 | [diff] [blame] | 22 | |
Lev Walkin | c7d17be | 2004-08-25 00:42:44 +0000 | [diff] [blame] | 23 | #define TQ_ENTRY(type) \ |
| 24 | struct { \ |
| 25 | type *tq_next; \ |
Lev Walkin | f15320b | 2004-06-03 03:38:44 +0000 | [diff] [blame] | 26 | } |
| 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 Walkin | 4efbfb7 | 2005-02-25 14:20:30 +0000 | [diff] [blame] | 40 | /* MSVC does not have typeof(), cannot prevent side effects! */ |
Lev Walkin | f15320b | 2004-06-03 03:38:44 +0000 | [diff] [blame] | 41 | #define TQ_ADD(head, xel, field) do { \ |
Lev Walkin | fa09597 | 2005-02-25 14:25:46 +0000 | [diff] [blame] | 42 | 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 Walkin | f15320b | 2004-06-03 03:38:44 +0000 | [diff] [blame] | 46 | } 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 */ |