2 This file is part of GNUnet.
3 (C) 2009, 2010 Christian Grothoff (and other contributing authors)
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 3, or (at your
8 option) any later version.
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA.
22 * @file nat/bsdqueue.h
23 * @brief BSD implementation of simple lists
25 * @author Milan Bouchet-Valat
29 * Copyright (c) 1991, 1993
30 * The Regents of the University of California. All rights reserved.
32 * Redistribution and use in source and binary forms, with or without
33 * modification, are permitted provided that the following conditions
35 * 1. Redistributions of source code must retain the above copyright
36 * notice, this list of conditions and the following disclaimer.
37 * 2. Redistributions in binary form must reproduce the above copyright
38 * notice, this list of conditions and the following disclaimer in the
39 * documentation and/or other materials provided with the distribution.
40 * 3. Neither the name of the University nor the names of its contributors
41 * may be used to endorse or promote products derived from this software
42 * without specific prior written permission.
44 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
45 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
46 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
47 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
48 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
49 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
50 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
51 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
52 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
53 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
56 * @(#)queue.h 8.5 (Berkeley) 8/20/94
63 * A list is headed by a single forward pointer (or an array of forward
64 * pointers for a hash table header). The elements are doubly linked
65 * so that an arbitrary element can be removed without a need to
66 * traverse the list. New elements can be added to the list before
67 * or after an existing element or at the head of the list. A list
68 * may only be traversed in the forward direction.
71 #ifdef QUEUE_MACRO_DEBUG
72 #define _Q_INVALIDATE(a) (a) = ((void *)-1)
74 #define _Q_INVALIDATE(a)
80 #define LIST_HEAD(name, type) \
82 struct type *lh_first; /* first element */ \
85 #define LIST_HEAD_INITIALIZER(head) \
88 #define LIST_ENTRY(type) \
90 struct type *le_next; /* next element */ \
91 struct type **le_prev; /* address of previous next element */ \
97 #define LIST_FIRST(head) ((head)->lh_first)
98 #define LIST_END(head) NULL
99 #define LIST_EMPTY(head) (LIST_FIRST(head) == LIST_END(head))
100 #define LIST_NEXT(elm, field) ((elm)->field.le_next)
102 #define LIST_FOREACH(var, head, field) \
103 for((var) = LIST_FIRST(head); \
104 (var)!= LIST_END(head); \
105 (var) = LIST_NEXT(var, field))
110 #define LIST_INIT(head) do { \
111 LIST_FIRST(head) = LIST_END(head); \
114 #define LIST_INSERT_AFTER(listelm, elm, field) do { \
115 if (((elm)->field.le_next = (listelm)->field.le_next) != NULL) \
116 (listelm)->field.le_next->field.le_prev = \
117 &(elm)->field.le_next; \
118 (listelm)->field.le_next = (elm); \
119 (elm)->field.le_prev = &(listelm)->field.le_next; \
122 #define LIST_INSERT_BEFORE(listelm, elm, field) do { \
123 (elm)->field.le_prev = (listelm)->field.le_prev; \
124 (elm)->field.le_next = (listelm); \
125 *(listelm)->field.le_prev = (elm); \
126 (listelm)->field.le_prev = &(elm)->field.le_next; \
129 #define LIST_INSERT_HEAD(head, elm, field) do { \
130 if (((elm)->field.le_next = (head)->lh_first) != NULL) \
131 (head)->lh_first->field.le_prev = &(elm)->field.le_next;\
132 (head)->lh_first = (elm); \
133 (elm)->field.le_prev = &(head)->lh_first; \
136 #define LIST_REMOVE(elm, field) do { \
137 if ((elm)->field.le_next != NULL) \
138 (elm)->field.le_next->field.le_prev = \
139 (elm)->field.le_prev; \
140 *(elm)->field.le_prev = (elm)->field.le_next; \
141 _Q_INVALIDATE((elm)->field.le_prev); \
142 _Q_INVALIDATE((elm)->field.le_next); \
145 #define LIST_REPLACE(elm, elm2, field) do { \
146 if (((elm2)->field.le_next = (elm)->field.le_next) != NULL) \
147 (elm2)->field.le_next->field.le_prev = \
148 &(elm2)->field.le_next; \
149 (elm2)->field.le_prev = (elm)->field.le_prev; \
150 *(elm2)->field.le_prev = (elm2); \
151 _Q_INVALIDATE((elm)->field.le_prev); \
152 _Q_INVALIDATE((elm)->field.le_next); \
157 /* end of bsd-queue.h */