1 /* 2 * circular list maintenance macros 3 * 4 * Copyright (C) 2005 iptelorg GmbH 5 * 6 * This file is part of Kamailio, a free SIP server. 7 * 8 * Kamailio is free software; you can redistribute it and/or modify 9 * it under the terms of the GNU General Public License as published by 10 * the Free Software Foundation; either version 2 of the License, or 11 * (at your option) any later version 12 * 13 * Kamailio is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 * GNU General Public License for more details. 17 * 18 * You should have received a copy of the GNU General Public License 19 * along with this program; if not, write to the Free Software 20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 21 */ 22 23 /*! 24 * \file 25 * \brief Kamailio core :: circular list maintenance macros 26 * 27 * \author andrei 28 * \ingroup core 29 * Module: \ref core 30 */ 31 32 33 #ifndef _clist_h 34 #define _clist_h 35 36 /*! \brief circular list */ 37 #define clist_init(c, next, prev) \ 38 do{ \ 39 (c)->next=(void*)(c); \ 40 (c)->prev=(void*)(c); \ 41 } while(0) 42 43 44 45 /*! \brief adds an entire sublist { s,e } (including s & e ) 46 * after head 47 * 48 * \note WARNING: clist_insert_sublist(head, n, n->prev) won't work, 49 * same for clist_insert_sublist(head, n->next, n) 50 * (macro!), use e=n->prev; clist_insert_sublist(head, n, e, ...) 51 * instead! 52 */ 53 #define clist_insert_sublist(head, s, e, next, prev) \ 54 do{ \ 55 (s)->prev=(void*)(head); \ 56 (e)->next=(head)->next; \ 57 (e)->next->prev=(e); \ 58 (head)->next=s; \ 59 }while(0) 60 61 62 63 /*! \brief appends an entire sublist { s,e } (including s & e ) 64 * at the end of the list 65 * 66 * WARNING: clist_append_sublist(head, n, n->prev, ...) won't work, 67 * (macro!), use e=n->prev; clist_append_sublist(head, n, e, ...) 68 * instead! 69 */ 70 #define clist_append_sublist(head, s, e, next, prev) \ 71 do{ \ 72 (s)->prev=(head)->prev; \ 73 (e)->next=(void*)(head); \ 74 (s)->prev->next=(s); \ 75 (head)->prev=(e); \ 76 }while(0) 77 78 79 80 81 /*! \brief remove sublist { s,e } (including s & e ) 82 * always, if start is the beginning of the list use 83 * clist_rm_sublist(head->next, e, next, prev ) 84 * WARNING: clist_rm_sublist(n, n->prev, ...) won't work, 85 * (macro!), use e=n->prev; clist_rm_sublist(n, e, ...) 86 * instead! */ 87 #define clist_rm_sublist(s, e, next, prev) \ 88 do{\ 89 (s)->prev->next=(e)->next; \ 90 (e)->next->prev=(s)->prev; \ 91 (s)->prev=NULL; \ 92 (e)->next=NULL; \ 93 }while(0) 94 95 96 97 /*! \brief insert after (head) */ 98 #define clist_insert(head, c, next, prev) \ 99 clist_insert_sublist(head, c, c, next, prev) 100 101 102 103 /*! \brief append at the end of the list (head->prev) */ 104 #define clist_append(head, c, next, prev) \ 105 clist_append_sublist(head, c, c, next, prev) 106 107 108 109 /*! \brief remove and element */ 110 #define clist_rm(c, next, prev) \ 111 clist_rm_sublist(c, c, next, prev) 112 113 114 115 /*! \brief iterate on a clist */ 116 #define clist_foreach(head, v, dir) \ 117 for((v)=(head)->dir; (v)!=(void*)(head); (v)=(v)->dir) 118 119 /*! \brief iterate on a clist, safe version (requires an extra bak. var) 120 * (it allows removing of the current element) */ 121 #define clist_foreach_safe(head, v, bak, dir) \ 122 for((v)=(head)->dir, (bak)=(v)->dir; (v)!=(void*)(head); \ 123 (v)=(bak), (bak)=(v)->dir) 124 125 /*! \brief test if clist is empty (1 - empty; 0 - not empty)*/ 126 #define clist_empty(head, dir) \ 127 (((head)->dir!=(void*)(head))?0:1) 128 129 130 #endif 131