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