To each list type, I added a macro that makes it easier to define and
[samba.git] / source3 / ubiqx / ubi_sLinkList.h
1 #ifndef UBI_SLINKLIST_H
2 #define UBI_SLINKLIST_H
3 /* ========================================================================== **
4  *                              ubi_sLinkList.h
5  *
6  *  Copyright (C) 1997, 1998 by Christopher R. Hertel
7  *
8  *  Email: crh@ubiqx.mn.org
9  * -------------------------------------------------------------------------- **
10  *  This module implements a simple singly-linked list.
11  * -------------------------------------------------------------------------- **
12  *
13  *  This library is free software; you can redistribute it and/or
14  *  modify it under the terms of the GNU Library General Public
15  *  License as published by the Free Software Foundation; either
16  *  version 2 of the License, or (at your option) any later version.
17  *
18  *  This library is distributed in the hope that it will be useful,
19  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
20  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
21  *  Library General Public License for more details.
22  *
23  *  You should have received a copy of the GNU Library General Public
24  *  License along with this library; if not, write to the Free
25  *  Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26  *
27  * -------------------------------------------------------------------------- **
28  *
29  * Log: ubi_sLinkList.h,v
30  * Revision 0.9  1998/07/24 07:30:20  crh
31  * Added the ubi_slNewList() macro.
32  *
33  * Revision 0.8  1998/06/04 21:29:27  crh
34  * Upper-cased defined constants (eg UBI_BINTREE_H) in some header files.
35  * This is more "standard", and is what people expect.  Weird, eh?
36  *
37  * Revision 0.7  1998/06/03 18:06:03  crh
38  * Further fiddling with sys_include.h, which has been moved from the .c file
39  * to the .h file.
40  *
41  * Revision 0.6  1998/06/02 01:38:47  crh
42  * Changed include file name from ubi_null.h to sys_include.h to make it
43  * more generic.
44  *
45  * Revision 0.5  1998/05/20 04:38:05  crh
46  * The C file now includes ubi_null.h.  See ubi_null.h for more info.
47  *
48  * Revision 0.4  1998/03/10 02:22:39  crh
49  * Combined ubi_StackQueue and ubi_sLinkList into one module.  Redesigned
50  * the functions and macros.  Not a complete rewrite but close to it.
51  *
52  * Revision 0.3  1998/01/03 02:00:02  crh
53  * Added ubi_slCount() macro.
54  *
55  * Revision 0.2  1997/10/21 03:36:14  crh
56  * Added parameter <After> in function Insert().  Made necessary changes
57  * to macro AddHead() and added macro AddHere().
58  *
59  * Revision 0.1  1997/10/16 02:54:08  crh
60  * Initial Revision.
61  *
62  * -------------------------------------------------------------------------- **
63  *  This module implements a singly-linked list which may also be used as a
64  *  queue or a stack.  For a queue, entries are added at the tail and removed
65  *  from the head of the list.  For a stack, the entries are entered and
66  *  removed from the head of the list.  A traversal of the list will always
67  *  start at the head of the list and proceed toward the tail.  This is all
68  *  mind-numbingly simple, but I'm surprised by the number of programs out
69  *  there which re-implement this a dozen or so times.
70  *
71  *  Note:  When the list header is initialized, the Tail pointer is set to
72  *         point to the Head pointer.  This simplifies things a great deal,
73  *         except that you can't initialize a stack or queue by simply
74  *         zeroing it out.  One sure way to initialize the header is to call
75  *         ubi_slInit().  Another option would be something like this:
76  *
77  *           ubi_slNewList( MyList );
78  *
79  *         Which translates to:
80  *
81  *           ubi_slList MyList[1] = { NULL, (ubi_slNodePtr)MyList, 0 };
82  *
83  *         See ubi_slInit(), ubi_slNewList(), and the ubi_slList structure
84  *         for more info.
85  *
86  *        + Also, note that this module is similar to the ubi_dLinkList
87  *          module.  There are three key differences:
88  *          - This is a singly-linked list, the other is a doubly-linked
89  *            list.
90  *          - In this module, if the list is empty, the tail pointer will
91  *            point back to the head of the list as described above.  This
92  *            is not done in ubi_dLinkList.
93  *          - The ubi_slRemove() function, by necessity, removed the 'next'
94  *            node.  In ubi_dLinkList, the ubi_dlRemove() function removes
95  *            the 'current' node.
96  *
97  * ========================================================================== **
98  */
99
100 #include "sys_include.h"    /* System-specific includes. */
101
102 /* ========================================================================== **
103  * Typedefs...
104  *
105  *  ubi_slNode    - This is the basic node structure.
106  *  ubi_slNodePtr - Pointer to a node.
107  *  ubi_slList    - This is the list header structure.
108  *  ubi_slListPtr - Pointer to a List (i.e., a list header structure).
109  *
110  */
111
112 typedef struct ubi_slListNode
113   {
114   struct ubi_slListNode *Next;
115   } ubi_slNode;
116
117 typedef ubi_slNode *ubi_slNodePtr;
118
119 typedef struct
120   {
121   ubi_slNodePtr Head;
122   ubi_slNodePtr Tail;
123   unsigned long count;
124   } ubi_slList;
125
126 typedef ubi_slList *ubi_slListPtr;
127
128
129 /* ========================================================================== **
130  * Macros...
131  * 
132  *  ubi_slNewList - Macro used to declare and initialize a list header in
133  *                  one step.
134  *
135  *  ubi_slCount   - Returns the current number of entries in the list.
136  *
137  *  ubi_slAddHead - Add a new node at the head of the list.
138  *  ubi_slAddNext - Add a new node following the indicated node.
139  *  ubi_slAddTail - Add a new node to the tail of the list.
140  *                  Note: AddTail evaluates the L parameter twice.
141  *
142  *  ubi_slRemHead - Remove the node at the head of the list, if any.
143  *  ubi_slRemNext - Remove the node following the given node.
144  *
145  *  ubi_slFirst   - Return a pointer to the first node in the list, if any.
146  *  ubi_slNext    - Given a node, return a pointer to the next node.
147  *  ubi_slLast    - Return a pointer to the last node in the list, if any.
148  *
149  *  ubi_slPush    - Add a node at the head of the list (synonym of AddHead).
150  *  ubi_slPop     - Remove a node at the head of the list (synonym of RemHead).
151  *  ubi_slEnqueue - Add a node at the tail of the list (sysnonym of AddTail).
152  *  ubi_slDequeue - Remove a node at the head of the list (synonym of RemHead).
153  *
154  *  Note that all of these provide type casting of the parameters.  The
155  *  Add and Rem macros are nothing more than nice front-ends to the
156  *  Insert and Remove functions.
157  *
158  *  Also note that the First, Next and Last macros do no parameter checking!
159  *
160  */
161
162 #define ubi_slNewList( L ) ubi_slList (L)[1] = {{ NULL, (ubi_slNodePtr)(L), 0 }}
163
164 #define ubi_slCount( L ) (((ubi_slListPtr)(L))->count)
165
166 #define ubi_slAddHead( L, N ) \
167         ubi_slInsert( (ubi_slListPtr)(L), (ubi_slNodePtr)(N), NULL )
168
169 #define ubi_slAddNext( L, N, A ) \
170         ubi_slInsert( (ubi_slListPtr)(L), \
171                       (ubi_slNodePtr)(N), \
172                       (ubi_slNodePtr)(A) )
173
174 #define ubi_slAddTail( L, N ) \
175         ubi_slInsert( (ubi_slListPtr)(L), \
176                       (ubi_slNodePtr)(N), \
177                      ((ubi_slListPtr)(L))->Tail )
178
179 #define ubi_slRemHead( L ) ubi_slRemove( (ubi_slListPtr)(L), NULL )
180
181 #define ubi_slRemNext( L, N ) \
182         ubi_slRemove( (ubi_slListPtr)(L), (ubi_slNodePtr)(N) )
183
184 #define ubi_slFirst( L ) (((ubi_slListPtr)(L))->Head)
185
186 #define ubi_slNext( N )  (((ubi_slNodePtr)(N))->Next)
187
188 #define ubi_slLast( L )  (((ubi_slListPtr)(L))->Tail)
189
190 #define ubi_slPush    ubi_slAddHead
191 #define ubi_slPop     ubi_slRemHead
192 #define ubi_slEnqueue ubi_slAddTail
193 #define ubi_slDequeue ubi_slRemHead
194
195 /* ========================================================================== **
196  * Function prototypes...
197  */
198
199 ubi_slListPtr ubi_slInitList( ubi_slListPtr ListPtr );
200   /* ------------------------------------------------------------------------ **
201    * Initialize a singly-linked list header.
202    *
203    *  Input:  ListPtr - A pointer to the list structure that is to be
204    *                    initialized for use.
205    *
206    *  Output: A pointer to the initialized list header (i.e., same as
207    *          <ListPtr>).
208    *
209    * ------------------------------------------------------------------------ **
210    */
211
212 ubi_slNodePtr ubi_slInsert( ubi_slListPtr ListPtr,
213                             ubi_slNodePtr New,
214                             ubi_slNodePtr After );
215   /* ------------------------------------------------------------------------ **
216    * Add a node to the list.
217    *
218    *  Input:  ListPtr - A pointer to the list into which the node is to
219    *                    be inserted.
220    *          New     - Pointer to the node that is to be added to the list.
221    *          After   - Pointer to a list in a node after which the new node
222    *                    will be inserted.  If NULL, then the new node will
223    *                    be added at the head of the list.
224    *
225    *  Output: A pointer to the node that was inserted into the list (i.e.,
226    *          the same as <New>).
227    *
228    * ------------------------------------------------------------------------ **
229    */
230
231 ubi_slNodePtr ubi_slRemove( ubi_slListPtr ListPtr, ubi_slNodePtr After );
232   /* ------------------------------------------------------------------------ **
233    * Remove the node followng <After>.  If <After> is NULL, remove from the
234    * head of the list.
235    *
236    *  Input:  ListPtr - A pointer to the list from which the node is to be
237    *                    removed.
238    *          After   - Pointer to the node preceeding the node to be
239    *                    removed.
240    *
241    *  Output: A pointer to the node that was removed, or NULL if the list is
242    *          empty.
243    *
244    * ------------------------------------------------------------------------ **
245    */
246
247 /* ================================ The End ================================= */
248 #endif /* UBI_SLINKLIST_H */