lst.h revision 138916
1/*
2 * Copyright (c) 1988, 1989, 1990, 1993
3 *	The Regents of the University of California.  All rights reserved.
4 * Copyright (c) 1988, 1989 by Adam de Boor
5 * Copyright (c) 1989 by Berkeley Softworks
6 * All rights reserved.
7 *
8 * This code is derived from software contributed to Berkeley by
9 * Adam de Boor.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 *    notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 *    notice, this list of conditions and the following disclaimer in the
18 *    documentation and/or other materials provided with the distribution.
19 * 3. All advertising materials mentioning features or use of this software
20 *    must display the following acknowledgement:
21 *	This product includes software developed by the University of
22 *	California, Berkeley and its contributors.
23 * 4. Neither the name of the University nor the names of its contributors
24 *    may be used to endorse or promote products derived from this software
25 *    without specific prior written permission.
26 *
27 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
28 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
29 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
30 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
31 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
32 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
33 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
34 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
35 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
36 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
37 * SUCH DAMAGE.
38 *
39 *	@(#)lst.h	8.2 (Berkeley) 4/28/95
40 * $FreeBSD: head/usr.bin/make/lst.h 138916 2004-12-16 16:14:16Z harti $
41 */
42
43/*-
44 * lst.h --
45 *	Header for using the list library
46 */
47#ifndef _LST_H_
48#define	_LST_H_
49
50#include	<sys/param.h>
51#include	<stdlib.h>
52#include	"sprite.h"
53
54/*
55 * Structure of a list node.
56 */
57struct LstNode {
58	struct LstNode	*prevPtr;   /* previous element in list */
59	struct LstNode	*nextPtr;   /* next in list */
60	int	useCount:8; /* Count of functions using the node. Node may not
61			     * be deleted until count goes to 0 */
62 	int	flags:8;    /* Node status flags */
63	void	*datum;	    /* datum associated with this element */
64};
65typedef	struct	LstNode	LstNode;
66
67/*
68 * Flags required for synchronization
69 */
70#define	LN_DELETED  	0x0001      /* List node should be removed when done */
71
72typedef enum {
73	LstHead, LstMiddle, LstTail, LstUnknown
74} LstWhere;
75
76/*
77 * The list itself
78 */
79struct Lst {
80	LstNode  	*firstPtr; /* first node in list */
81	LstNode  	*lastPtr;  /* last node in list */
82};
83typedef	struct	Lst Lst;
84
85typedef	int CompareProc(const void *, const void *);
86typedef	int DoProc(void *, void *);
87typedef	void *DuplicateProc(void *);
88typedef	void FreeProc(void *);
89
90/*
91 * NOFREE can be used as the freeProc to Lst_Destroy when the elements are
92 *	not to be freed.
93 * NOCOPY performs similarly when given as the copyProc to Lst_Duplicate.
94 */
95#define	NOFREE		((FreeProc *)NULL)
96#define	NOCOPY		((DuplicateProc *)NULL)
97
98#define	LST_CONCNEW	0   /* create new LstNode's when using Lst_Concat */
99#define	LST_CONCLINK	1   /* relink LstNode's when using Lst_Concat */
100
101/*
102 * Creation/destruction functions
103 */
104/* Create a new list */
105#define	Lst_Init(LST)	do {						\
106				(LST)->firstPtr = NULL;			\
107				(LST)->lastPtr = NULL;			\
108			} while (0)
109#define	Lst_Initializer(NAME)	{ NULL, NULL }
110
111/* Duplicate an existing list */
112void	Lst_Duplicate(Lst *, Lst *, DuplicateProc *);
113
114/* Destroy an old one */
115void	Lst_Destroy(Lst *, FreeProc *);
116
117/*
118 * Functions to modify a list
119 */
120/* Insert an element before another */
121void		Lst_Insert(Lst *, LstNode *, void *);
122/* Insert an element after another */
123void		Lst_Append(Lst *, LstNode *, void *);
124/* Place an element at the front of a lst. */
125#define	Lst_AtFront(LST, D)	(Lst_Insert((LST), Lst_First(LST), (D)))
126/* Place an element at the end of a lst. */
127#define	Lst_AtEnd(LST, D) 	(Lst_Append((LST), Lst_Last(LST), (D)))
128/* Remove an element */
129void		Lst_Remove(Lst *, LstNode *);
130/* Replace a node with a new value */
131#define	Lst_Replace(NODE, D)	(((NODE) == NULL) ? FAILURE : \
132				    (((NODE)->datum = (D)), SUCCESS))
133/* Concatenate two lists */
134void	Lst_Concat(Lst *, Lst *, int);
135
136/*
137 * Node-specific functions
138 */
139/* Return first element in list */
140#define	Lst_First(LST)	((Lst_Valid(LST) && !Lst_IsEmpty(LST)) \
141			    ? (LST)->firstPtr : NULL)
142/* Return last element in list */
143#define	Lst_Last(LST)	((Lst_Valid(LST) && !Lst_IsEmpty(LST)) \
144			    ? (LST)->lastPtr : NULL)
145/* Return successor to given element */
146#define	Lst_Succ(NODE)	(((NODE) == NULL) ? NULL : (NODE)->nextPtr)
147/* Get datum from LstNode */
148#define	Lst_Datum(NODE)	((NODE)->datum)
149
150/*
151 * Functions for entire lists
152 */
153/* Find an element in a list */
154#define	Lst_Find(LST, D, FN)	(Lst_FindFrom((LST), Lst_First(LST), (D), (FN)))
155/* Find an element starting from somewhere */
156LstNode		*Lst_FindFrom(Lst *, LstNode *, const void *, CompareProc *);
157/*
158 * See if the given datum is on the list. Returns the LstNode containing
159 * the datum
160 */
161LstNode		*Lst_Member(Lst *, void *);
162/* Apply a function to all elements of a lst */
163void		Lst_ForEach(Lst *, DoProc *, void *);
164#define	Lst_ForEach(LST, FN, D)	(Lst_ForEachFrom((LST), Lst_First(LST), \
165				    (FN), (D)))
166/*
167 * Apply a function to all elements of a lst starting from a certain point.
168 * If the list is circular, the application will wrap around to the
169 * beginning of the list again.
170 */
171void		Lst_ForEachFrom(Lst *, LstNode *, DoProc *, void *);
172
173/*
174 * for using the list as a queue
175 */
176/* Place an element at tail of queue */
177#define	Lst_EnQueue(LST, D)	(Lst_Valid(LST) \
178				    ? Lst_Append((LST), Lst_Last(LST), (D)) \
179				    : FAILURE)
180/* Remove an element from head of queue */
181void		*Lst_DeQueue(Lst *);
182
183/*
184 * LstValid (L) --
185 *	Return TRUE if the list L is valid
186 */
187#define Lst_Valid(L)	(((L) == NULL) ? FALSE : TRUE)
188
189/*
190 * LstNodeValid (LN, L) --
191 *	Return TRUE if the LstNode LN is valid with respect to L
192 */
193#define Lst_NodeValid(LN, L)	(((LN) == NULL) ? FALSE : TRUE)
194
195/*
196 * Lst_IsEmpty(L) --
197 *	TRUE if the list L is empty.
198 */
199#define Lst_IsEmpty(L)	(!Lst_Valid(L) || (L)->firstPtr == NULL)
200
201
202#endif /* _LST_H_ */
203