1141104Sharti/*-
294589Sobrien * Copyright (c) 1988, 1989, 1990, 1993
394589Sobrien *	The Regents of the University of California.  All rights reserved.
45814Sjkh * Copyright (c) 1988, 1989 by Adam de Boor
51590Srgrimes * Copyright (c) 1989 by Berkeley Softworks
61590Srgrimes * All rights reserved.
71590Srgrimes *
81590Srgrimes * This code is derived from software contributed to Berkeley by
91590Srgrimes * Adam de Boor.
101590Srgrimes *
111590Srgrimes * Redistribution and use in source and binary forms, with or without
121590Srgrimes * modification, are permitted provided that the following conditions
131590Srgrimes * are met:
141590Srgrimes * 1. Redistributions of source code must retain the above copyright
151590Srgrimes *    notice, this list of conditions and the following disclaimer.
161590Srgrimes * 2. Redistributions in binary form must reproduce the above copyright
171590Srgrimes *    notice, this list of conditions and the following disclaimer in the
181590Srgrimes *    documentation and/or other materials provided with the distribution.
191590Srgrimes * 3. All advertising materials mentioning features or use of this software
201590Srgrimes *    must display the following acknowledgement:
211590Srgrimes *	This product includes software developed by the University of
221590Srgrimes *	California, Berkeley and its contributors.
231590Srgrimes * 4. Neither the name of the University nor the names of its contributors
241590Srgrimes *    may be used to endorse or promote products derived from this software
251590Srgrimes *    without specific prior written permission.
261590Srgrimes *
271590Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
281590Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
291590Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
301590Srgrimes * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
311590Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
321590Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
331590Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
341590Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
351590Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
361590Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
371590Srgrimes * SUCH DAMAGE.
381590Srgrimes *
3994589Sobrien *	@(#)lst.h	8.2 (Berkeley) 4/28/95
4050477Speter * $FreeBSD$
411590Srgrimes */
421590Srgrimes
43141104Sharti#ifndef lst_h_38f3ead1
44141104Sharti#define	lst_h_38f3ead1
45141104Sharti
461590Srgrimes/*-
471590Srgrimes * lst.h --
481590Srgrimes *	Header for using the list library
491590Srgrimes */
501590Srgrimes
511590Srgrimes/*
52138185Sharti * Structure of a list node.
531590Srgrimes */
54138185Shartistruct LstNode {
55138185Sharti	struct LstNode	*prevPtr;   /* previous element in list */
56138185Sharti	struct LstNode	*nextPtr;   /* next in list */
57143704Sharti	void		*datum;	    /* datum associated with this element */
58138185Sharti};
59138512Shartitypedef	struct	LstNode	LstNode;
601590Srgrimes
61138185Sharti/*
62138185Sharti * The list itself
63138185Sharti */
64138185Shartistruct Lst {
65138512Sharti	LstNode  	*firstPtr; /* first node in list */
66138512Sharti	LstNode  	*lastPtr;  /* last node in list */
67138185Sharti};
68138512Shartitypedef	struct	Lst Lst;
691590Srgrimes
70138192Shartitypedef	void *DuplicateProc(void *);
71138192Shartitypedef	void FreeProc(void *);
72138192Sharti
731590Srgrimes/*
741590Srgrimes * NOFREE can be used as the freeProc to Lst_Destroy when the elements are
751590Srgrimes *	not to be freed.
761590Srgrimes * NOCOPY performs similarly when given as the copyProc to Lst_Duplicate.
771590Srgrimes */
78138192Sharti#define	NOFREE		((FreeProc *)NULL)
79138192Sharti#define	NOCOPY		((DuplicateProc *)NULL)
801590Srgrimes
81103503Sjmallett#define	LST_CONCNEW	0   /* create new LstNode's when using Lst_Concat */
82103503Sjmallett#define	LST_CONCLINK	1   /* relink LstNode's when using Lst_Concat */
831590Srgrimes
841590Srgrimes/*
851590Srgrimes * Creation/destruction functions
861590Srgrimes */
875814Sjkh/* Create a new list */
88138916Sharti#define	Lst_Init(LST)	do {						\
89138916Sharti				(LST)->firstPtr = NULL;			\
90138916Sharti				(LST)->lastPtr = NULL;			\
91138916Sharti			} while (0)
92138916Sharti#define	Lst_Initializer(NAME)	{ NULL, NULL }
93138916Sharti
945814Sjkh/* Duplicate an existing list */
95138916Shartivoid	Lst_Duplicate(Lst *, Lst *, DuplicateProc *);
96138916Sharti
975814Sjkh/* Destroy an old one */
98138916Shartivoid	Lst_Destroy(Lst *, FreeProc *);
991590Srgrimes
1001590Srgrimes/*
1011590Srgrimes * Functions to modify a list
1021590Srgrimes */
1035814Sjkh/* Insert an element before another */
104138629Shartivoid		Lst_Insert(Lst *, LstNode *, void *);
1055814Sjkh/* Insert an element after another */
106138629Shartivoid		Lst_Append(Lst *, LstNode *, void *);
1075814Sjkh/* Place an element at the front of a lst. */
108138222Sharti#define	Lst_AtFront(LST, D)	(Lst_Insert((LST), Lst_First(LST), (D)))
1095814Sjkh/* Place an element at the end of a lst. */
110138222Sharti#define	Lst_AtEnd(LST, D) 	(Lst_Append((LST), Lst_Last(LST), (D)))
1115814Sjkh/* Remove an element */
112138577Shartivoid		Lst_Remove(Lst *, LstNode *);
1135814Sjkh/* Replace a node with a new value */
114146338Sharti#define	Lst_Replace(NODE, D)	((void)((NODE)->datum = (D)))
1155814Sjkh/* Concatenate two lists */
116138916Shartivoid	Lst_Concat(Lst *, Lst *, int);
1171590Srgrimes
1181590Srgrimes/*
1191590Srgrimes * Node-specific functions
1201590Srgrimes */
1215814Sjkh/* Return first element in list */
122138222Sharti#define	Lst_First(LST)	((Lst_Valid(LST) && !Lst_IsEmpty(LST)) \
123138222Sharti			    ? (LST)->firstPtr : NULL)
1245814Sjkh/* Return last element in list */
125138222Sharti#define	Lst_Last(LST)	((Lst_Valid(LST) && !Lst_IsEmpty(LST)) \
126138222Sharti			    ? (LST)->lastPtr : NULL)
1275814Sjkh/* Return successor to given element */
128138222Sharti#define	Lst_Succ(NODE)	(((NODE) == NULL) ? NULL : (NODE)->nextPtr)
129143328Sharti#define	LST_NEXT(NODE)	((NODE)->nextPtr)
1305814Sjkh/* Get datum from LstNode */
131138222Sharti#define	Lst_Datum(NODE)	((NODE)->datum)
1321590Srgrimes
1331590Srgrimes/*
1341590Srgrimes * Functions for entire lists
1351590Srgrimes */
136143976Sharti
1378874Srgrimes/*
1385814Sjkh * See if the given datum is on the list. Returns the LstNode containing
1395814Sjkh * the datum
1405814Sjkh */
141138512ShartiLstNode		*Lst_Member(Lst *, void *);
142142208Sharti
143143704Sharti/* Loop through a list. Note, that you may not delete the list element. */
144142208Sharti#define	LST_FOREACH(PTR, LST)						\
145142208Sharti	for ((PTR) = (LST)->firstPtr; (PTR) != NULL; (PTR) = (PTR)->nextPtr)
146142208Sharti
1471590Srgrimes/*
1481590Srgrimes * for using the list as a queue
1491590Srgrimes */
1505814Sjkh/* Place an element at tail of queue */
151138222Sharti#define	Lst_EnQueue(LST, D)	(Lst_Valid(LST) \
152138222Sharti				    ? Lst_Append((LST), Lst_Last(LST), (D)) \
153141645Sharti				    : (void)0)
1545814Sjkh/* Remove an element from head of queue */
155138512Shartivoid		*Lst_DeQueue(Lst *);
1561590Srgrimes
157138185Sharti/*
158138185Sharti * LstValid (L) --
159138185Sharti *	Return TRUE if the list L is valid
160138185Sharti */
161138185Sharti#define Lst_Valid(L)	(((L) == NULL) ? FALSE : TRUE)
162138185Sharti
163138185Sharti/*
164138185Sharti * LstNodeValid (LN, L) --
165138185Sharti *	Return TRUE if the LstNode LN is valid with respect to L
166138185Sharti */
167138185Sharti#define Lst_NodeValid(LN, L)	(((LN) == NULL) ? FALSE : TRUE)
168138185Sharti
169138185Sharti/*
170138185Sharti * Lst_IsEmpty(L) --
171138185Sharti *	TRUE if the list L is empty.
172138185Sharti */
173138185Sharti#define Lst_IsEmpty(L)	(!Lst_Valid(L) || (L)->firstPtr == NULL)
174138185Sharti
175141104Sharti#endif /* lst_h_38f3ead1 */
176