1 2 #ifndef _LLIST_H 3 #define _LLIST_H 4 5 // this file provides macros which implement common operations on linked lists. 6 // this saves a little bit of thinking and helps prevent bugs caused by 7 // forgetting one of the steps. 8 9 // call them giving them the node to work on and the names of the fields 10 // for next, prev, first and last nodes. 11 12 // add a node to the end of a linked list 13 #define LL_ADD_END(O, PREV, NEXT, FIRST, LAST) \ 14 { \ 15 if (LAST) \ 16 LAST->NEXT = O; \ 17 else \ 18 FIRST = O; \ 19 \ 20 O->PREV = LAST; \ 21 O->NEXT = NULL; \ 22 LAST = O; \ 23 } 24 25 // add a node at the start of a linked list 26 #define LL_ADD_BEGIN(O, PREV, NEXT, FIRST, LAST) \ 27 { \ 28 O->NEXT = FIRST; \ 29 O->PREV = NULL; \ 30 \ 31 if (FIRST) \ 32 FIRST->PREV = O; \ 33 else \ 34 FIRST = LAST = O; \ 35 } 36 37 // insert a node just before another node 38 #define LL_INSERT_BEFORE(O, BEHIND, PREV, NEXT, FIRST, LAST) \ 39 { \ 40 if (BEHIND == FIRST) \ 41 FIRST = O; \ 42 else \ 43 BEHIND->PREV->NEXT = O; \ 44 \ 45 O->NEXT = BEHIND; \ 46 O->PREV = BEHIND->PREV; \ 47 BEHIND->PREV = O; \ 48 } 49 50 // insert a node just after another node 51 #define LL_INSERT_AFTER(O, AFTER, PREV, NEXT, FIRST, LAST) \ 52 { \ 53 if (AFTER == LAST) \ 54 LAST = O; \ 55 else \ 56 AFTER->NEXT->PREV = O; \ 57 \ 58 O->NEXT = AFTER->NEXT; \ 59 O->PREV = AFTER; \ 60 AFTER->NEXT = O; \ 61 } 62 63 // remove a node from a linked list 64 #define LL_REMOVE(O, PREV, NEXT, FIRST, LAST) \ 65 { \ 66 if (O == FIRST) \ 67 FIRST = FIRST->NEXT; \ 68 else if (O->PREV) \ 69 O->PREV->NEXT = O->NEXT; \ 70 \ 71 if (O == LAST) \ 72 LAST = LAST->PREV; \ 73 else if (O->NEXT) \ 74 O->NEXT->PREV = O->PREV; \ 75 } 76 77 // debug function 78 #define LL_DUMP_LIST(START, PREV, NEXT, NODETYPE) \ 79 { \ 80 stat("LL_DUMP_LIST from %s using %s", #START, #NEXT); \ 81 \ 82 NODETYPE *n = START; \ 83 int iter = 0; \ 84 while(n) \ 85 { \ 86 stat("%d: %08x P:%08x N:%08x", iter++, n, n->PREV, n->NEXT); \ 87 n = n->NEXT; \ 88 } \ 89 } 90 91 92 #endif 93 94 95