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