1*b30d1939SAndy Fiddaman /***********************************************************************
2*b30d1939SAndy Fiddaman *                                                                      *
3*b30d1939SAndy Fiddaman *               This software is part of the ast package               *
4*b30d1939SAndy Fiddaman *          Copyright (c) 1985-2012 AT&T Intellectual Property          *
5*b30d1939SAndy Fiddaman *                      and is licensed under the                       *
6*b30d1939SAndy Fiddaman *                 Eclipse Public License, Version 1.0                  *
7*b30d1939SAndy Fiddaman *                    by AT&T Intellectual Property                     *
8*b30d1939SAndy Fiddaman *                                                                      *
9*b30d1939SAndy Fiddaman *                A copy of the License is available at                 *
10*b30d1939SAndy Fiddaman *          http://www.eclipse.org/org/documents/epl-v10.html           *
11*b30d1939SAndy Fiddaman *         (with md5 checksum b35adb5213ca9657e911e9befb180842)         *
12*b30d1939SAndy Fiddaman *                                                                      *
13*b30d1939SAndy Fiddaman *              Information and Software Systems Research               *
14*b30d1939SAndy Fiddaman *                            AT&T Research                             *
15*b30d1939SAndy Fiddaman *                           Florham Park NJ                            *
16*b30d1939SAndy Fiddaman *                                                                      *
17*b30d1939SAndy Fiddaman *                 Glenn Fowler <gsf@research.att.com>                  *
18*b30d1939SAndy Fiddaman *                  David Korn <dgk@research.att.com>                   *
19*b30d1939SAndy Fiddaman *                   Phong Vo <kpv@research.att.com>                    *
20*b30d1939SAndy Fiddaman *                                                                      *
21*b30d1939SAndy Fiddaman ***********************************************************************/
22*b30d1939SAndy Fiddaman #include	"dthdr.h"
23*b30d1939SAndy Fiddaman 
24*b30d1939SAndy Fiddaman /*	List, Deque, Stack, Queue.
25*b30d1939SAndy Fiddaman **
26*b30d1939SAndy Fiddaman **	Written by Kiem-Phong Vo (05/25/96)
27*b30d1939SAndy Fiddaman */
28*b30d1939SAndy Fiddaman 
29*b30d1939SAndy Fiddaman typedef struct _dtlist_s
30*b30d1939SAndy Fiddaman {	Dtdata_t	data;
31*b30d1939SAndy Fiddaman 	Dtlink_t*	link;	/* list of objects		*/
32*b30d1939SAndy Fiddaman 	Dtlink_t*	here;	/* finger to searched objects	*/
33*b30d1939SAndy Fiddaman } Dtlist_t;
34*b30d1939SAndy Fiddaman 
35*b30d1939SAndy Fiddaman #ifdef DEBUG
dtlistprint(Dt_t * dt,Dtlink_t * here,char * (* objprintf)(Void_t *))36*b30d1939SAndy Fiddaman int dtlistprint(Dt_t* dt, Dtlink_t* here, char* (*objprintf)(Void_t*) )
37*b30d1939SAndy Fiddaman {
38*b30d1939SAndy Fiddaman 	int		k;
39*b30d1939SAndy Fiddaman 	char		*obj, *endb, buf[1024];
40*b30d1939SAndy Fiddaman 	Dtdisc_t	*disc = dt->disc;
41*b30d1939SAndy Fiddaman 	Dtlist_t	*list = (Dtlist_t*)dt->data;
42*b30d1939SAndy Fiddaman 
43*b30d1939SAndy Fiddaman 	if(!here && !(here = list->link) )
44*b30d1939SAndy Fiddaman 		return -1;
45*b30d1939SAndy Fiddaman 
46*b30d1939SAndy Fiddaman 	for(; here; here = here->_rght)
47*b30d1939SAndy Fiddaman 	{	endb = buf; /* indentation */
48*b30d1939SAndy Fiddaman 		*endb++ = '(';
49*b30d1939SAndy Fiddaman 		obj = (*objprintf)(_DTOBJ(disc, here));
50*b30d1939SAndy Fiddaman 		k = strlen(obj); memcpy(endb, obj, k); endb += k;
51*b30d1939SAndy Fiddaman 		*endb++ = ')';
52*b30d1939SAndy Fiddaman 		*endb++ = '\n';
53*b30d1939SAndy Fiddaman 		write(2, buf, endb-buf);
54*b30d1939SAndy Fiddaman 	}
55*b30d1939SAndy Fiddaman 
56*b30d1939SAndy Fiddaman 	return 0;
57*b30d1939SAndy Fiddaman }
58*b30d1939SAndy Fiddaman #endif
59*b30d1939SAndy Fiddaman 
60*b30d1939SAndy Fiddaman /* terminal objects: DT_FIRST|DT_LAST */
61*b30d1939SAndy Fiddaman #if __STD_C
lfirstlast(Dt_t * dt,int type)62*b30d1939SAndy Fiddaman Void_t* lfirstlast(Dt_t* dt, int type)
63*b30d1939SAndy Fiddaman #else
64*b30d1939SAndy Fiddaman Void_t* lfirstlast(dt, type)
65*b30d1939SAndy Fiddaman Dt_t*	dt;
66*b30d1939SAndy Fiddaman int	type;
67*b30d1939SAndy Fiddaman #endif
68*b30d1939SAndy Fiddaman {
69*b30d1939SAndy Fiddaman 	Dtlink_t	*lnk;
70*b30d1939SAndy Fiddaman 	Dtdisc_t	*disc = dt->disc;
71*b30d1939SAndy Fiddaman 	Dtlist_t	*list = (Dtlist_t*)dt->data;
72*b30d1939SAndy Fiddaman 
73*b30d1939SAndy Fiddaman 	if((lnk = list->link) )
74*b30d1939SAndy Fiddaman 	{	if(type&DT_LAST)
75*b30d1939SAndy Fiddaman 			lnk = lnk->_left;
76*b30d1939SAndy Fiddaman 		list->here = lnk; /* finger points to this */
77*b30d1939SAndy Fiddaman 	}
78*b30d1939SAndy Fiddaman 
79*b30d1939SAndy Fiddaman 	return lnk ? _DTOBJ(disc,lnk) : NIL(Void_t*);
80*b30d1939SAndy Fiddaman }
81*b30d1939SAndy Fiddaman 
82*b30d1939SAndy Fiddaman /* DT_CLEAR */
83*b30d1939SAndy Fiddaman #if __STD_C
lclear(Dt_t * dt)84*b30d1939SAndy Fiddaman Void_t* lclear(Dt_t* dt)
85*b30d1939SAndy Fiddaman #else
86*b30d1939SAndy Fiddaman Void_t* lclear(dt)
87*b30d1939SAndy Fiddaman Dt_t*	dt;
88*b30d1939SAndy Fiddaman #endif
89*b30d1939SAndy Fiddaman {
90*b30d1939SAndy Fiddaman 	Dtlink_t	*lnk, *next;
91*b30d1939SAndy Fiddaman 	Dtdisc_t	*disc = dt->disc;
92*b30d1939SAndy Fiddaman 	Dtlist_t	*list = (Dtlist_t*)dt->data;
93*b30d1939SAndy Fiddaman 
94*b30d1939SAndy Fiddaman 	lnk = list->link;
95*b30d1939SAndy Fiddaman 	list->link = list->here = NIL(Dtlink_t*);
96*b30d1939SAndy Fiddaman 	list->data.size = 0;
97*b30d1939SAndy Fiddaman 
98*b30d1939SAndy Fiddaman 	if(disc->freef || disc->link < 0)
99*b30d1939SAndy Fiddaman 	{	for(; lnk; lnk = next)
100*b30d1939SAndy Fiddaman 		{	next = lnk->_rght;
101*b30d1939SAndy Fiddaman 			_dtfree(dt, lnk, DT_DELETE);
102*b30d1939SAndy Fiddaman 		}
103*b30d1939SAndy Fiddaman 	}
104*b30d1939SAndy Fiddaman 
105*b30d1939SAndy Fiddaman 	return NIL(Void_t*);
106*b30d1939SAndy Fiddaman }
107*b30d1939SAndy Fiddaman 
108*b30d1939SAndy Fiddaman /* DT_FLATTEN|DT_EXTRACT|DT_RESTORE */
109*b30d1939SAndy Fiddaman #if __STD_C
llist(Dt_t * dt,Dtlink_t * lnk,int type)110*b30d1939SAndy Fiddaman Void_t* llist(Dt_t* dt, Dtlink_t* lnk, int type)
111*b30d1939SAndy Fiddaman #else
112*b30d1939SAndy Fiddaman Void_t* llist(dt, lnk, type)
113*b30d1939SAndy Fiddaman Dt_t*		dt;
114*b30d1939SAndy Fiddaman Dtlink_t*	lnk;
115*b30d1939SAndy Fiddaman int		type;
116*b30d1939SAndy Fiddaman #endif
117*b30d1939SAndy Fiddaman {
118*b30d1939SAndy Fiddaman 	Dtlist_t	*list = (Dtlist_t*)dt->data;
119*b30d1939SAndy Fiddaman 
120*b30d1939SAndy Fiddaman 	if(type&(DT_FLATTEN|DT_EXTRACT) )
121*b30d1939SAndy Fiddaman 	{	if(lnk) /* error on calling */
122*b30d1939SAndy Fiddaman 			return NIL(Void_t*);
123*b30d1939SAndy Fiddaman 
124*b30d1939SAndy Fiddaman 		lnk = list->link;
125*b30d1939SAndy Fiddaman 		if(type&DT_EXTRACT)
126*b30d1939SAndy Fiddaman 		{	list->link = NIL(Dtlink_t*);
127*b30d1939SAndy Fiddaman 			dt->data->size = 0;
128*b30d1939SAndy Fiddaman 		}
129*b30d1939SAndy Fiddaman 	}
130*b30d1939SAndy Fiddaman 	else /* if(type&DT_RESTORE) */
131*b30d1939SAndy Fiddaman 	{	if(list->link != NIL(Dtlink_t*))
132*b30d1939SAndy Fiddaman 			return NIL(Void_t*);
133*b30d1939SAndy Fiddaman 
134*b30d1939SAndy Fiddaman 		list->link = lnk;
135*b30d1939SAndy Fiddaman 
136*b30d1939SAndy Fiddaman 		dt->data->size = 0;
137*b30d1939SAndy Fiddaman 		for(; lnk; lnk = lnk->_rght)
138*b30d1939SAndy Fiddaman 			dt->data->size += 1;
139*b30d1939SAndy Fiddaman 	}
140*b30d1939SAndy Fiddaman 
141*b30d1939SAndy Fiddaman 	return (Void_t*)lnk;
142*b30d1939SAndy Fiddaman }
143*b30d1939SAndy Fiddaman 
144*b30d1939SAndy Fiddaman #if __STD_C
liststat(Dt_t * dt,Dtstat_t * st)145*b30d1939SAndy Fiddaman static Void_t* liststat(Dt_t* dt, Dtstat_t* st)
146*b30d1939SAndy Fiddaman #else
147*b30d1939SAndy Fiddaman static Void_t* liststat(dt, st)
148*b30d1939SAndy Fiddaman Dt_t*		dt;
149*b30d1939SAndy Fiddaman Dtstat_t*	st;
150*b30d1939SAndy Fiddaman #endif
151*b30d1939SAndy Fiddaman {
152*b30d1939SAndy Fiddaman 	if(st)
153*b30d1939SAndy Fiddaman 	{	memset(st, 0, sizeof(Dtstat_t));
154*b30d1939SAndy Fiddaman 		st->meth  = dt->meth->type;
155*b30d1939SAndy Fiddaman 		st->size  = dt->data->size;
156*b30d1939SAndy Fiddaman 		st->space = sizeof(Dtlist_t) + (dt->disc->link >= 0 ? 0 : dt->data->size*sizeof(Dthold_t));
157*b30d1939SAndy Fiddaman 	}
158*b30d1939SAndy Fiddaman 
159*b30d1939SAndy Fiddaman 	return (Void_t*)dt->data->size;
160*b30d1939SAndy Fiddaman }
161*b30d1939SAndy Fiddaman 
162*b30d1939SAndy Fiddaman #if __STD_C
dtlist(Dt_t * dt,Void_t * obj,int type)163*b30d1939SAndy Fiddaman static Void_t* dtlist(Dt_t* dt, Void_t* obj, int type)
164*b30d1939SAndy Fiddaman #else
165*b30d1939SAndy Fiddaman static Void_t* dtlist(dt, obj, type)
166*b30d1939SAndy Fiddaman Dt_t*	dt;
167*b30d1939SAndy Fiddaman Void_t*	obj;
168*b30d1939SAndy Fiddaman int	type;
169*b30d1939SAndy Fiddaman #endif
170*b30d1939SAndy Fiddaman {
171*b30d1939SAndy Fiddaman 	Dtlink_t	*r, *t, *h;
172*b30d1939SAndy Fiddaman 	Void_t		*key, *o, *k;
173*b30d1939SAndy Fiddaman 	Dtdisc_t	*disc = dt->disc;
174*b30d1939SAndy Fiddaman 	Dtlist_t	*list = (Dtlist_t*)dt->data;
175*b30d1939SAndy Fiddaman 
176*b30d1939SAndy Fiddaman 	type = DTTYPE(dt,type); /* map type for upward compatibility */
177*b30d1939SAndy Fiddaman 	if(!(type&DT_OPERATIONS) )
178*b30d1939SAndy Fiddaman 		return NIL(Void_t*);
179*b30d1939SAndy Fiddaman 
180*b30d1939SAndy Fiddaman 	DTSETLOCK(dt);
181*b30d1939SAndy Fiddaman 
182*b30d1939SAndy Fiddaman 	if(type&(DT_FIRST|DT_LAST) )
183*b30d1939SAndy Fiddaman 		DTRETURN(obj, lfirstlast(dt, type));
184*b30d1939SAndy Fiddaman 	else if(type&(DT_EXTRACT|DT_RESTORE|DT_FLATTEN) )
185*b30d1939SAndy Fiddaman 		DTRETURN(obj, llist(dt, (Dtlink_t*)obj, type));
186*b30d1939SAndy Fiddaman 	else if(type&DT_CLEAR)
187*b30d1939SAndy Fiddaman 		DTRETURN(obj, lclear(dt));
188*b30d1939SAndy Fiddaman 	else if(type&DT_STAT )
189*b30d1939SAndy Fiddaman 		DTRETURN(obj, liststat(dt, (Dtstat_t*)obj));
190*b30d1939SAndy Fiddaman 
191*b30d1939SAndy Fiddaman 	h = list->here; /* save finger to last search object */
192*b30d1939SAndy Fiddaman 	list->here = NIL(Dtlink_t*);
193*b30d1939SAndy Fiddaman 
194*b30d1939SAndy Fiddaman 	if(!obj)
195*b30d1939SAndy Fiddaman 	{	if((type&(DT_DELETE|DT_DETACH|DT_REMOVE)) && (dt->meth->type&(DT_STACK|DT_QUEUE)) )
196*b30d1939SAndy Fiddaman 			if((r = list->link) ) /* special case for destack or dequeue */
197*b30d1939SAndy Fiddaman 				goto dt_delete;
198*b30d1939SAndy Fiddaman 		DTRETURN(obj, NIL(Void_t*)); /* error, needing non-void object */
199*b30d1939SAndy Fiddaman 	}
200*b30d1939SAndy Fiddaman 
201*b30d1939SAndy Fiddaman 	if(type&DT_RELINK) /* relink object after some processing */
202*b30d1939SAndy Fiddaman 	{	r = (Dtlink_t*)obj;
203*b30d1939SAndy Fiddaman 		goto do_insert;
204*b30d1939SAndy Fiddaman 	}
205*b30d1939SAndy Fiddaman 	else if(type&(DT_INSERT|DT_APPEND|DT_ATTACH))
206*b30d1939SAndy Fiddaman 	{	if(!(r = _dtmake(dt, obj, type)) )
207*b30d1939SAndy Fiddaman 			DTRETURN(obj, NIL(Void_t*));
208*b30d1939SAndy Fiddaman 		dt->data->size += 1;
209*b30d1939SAndy Fiddaman 
210*b30d1939SAndy Fiddaman 	do_insert:
211*b30d1939SAndy Fiddaman 		if(dt->meth->type&DT_DEQUE)
212*b30d1939SAndy Fiddaman 		{	if(type&DT_APPEND)
213*b30d1939SAndy Fiddaman 				goto dt_queue; /* append at end */
214*b30d1939SAndy Fiddaman 			else	goto dt_stack; /* insert at top */
215*b30d1939SAndy Fiddaman 		}
216*b30d1939SAndy Fiddaman 		else if(dt->meth->type&DT_LIST)
217*b30d1939SAndy Fiddaman 		{	if(type&DT_APPEND)
218*b30d1939SAndy Fiddaman 			{	if(!h || !h->_rght)
219*b30d1939SAndy Fiddaman 					goto dt_queue;
220*b30d1939SAndy Fiddaman 				r->_rght = h->_rght;
221*b30d1939SAndy Fiddaman 				r->_rght->_left = r;
222*b30d1939SAndy Fiddaman 				r->_left = h;
223*b30d1939SAndy Fiddaman 				r->_left->_rght = r;
224*b30d1939SAndy Fiddaman 			}
225*b30d1939SAndy Fiddaman 			else
226*b30d1939SAndy Fiddaman 			{	if(!h || h == list->link )
227*b30d1939SAndy Fiddaman 					goto dt_stack;
228*b30d1939SAndy Fiddaman 				r->_left = h->_left;
229*b30d1939SAndy Fiddaman 				r->_left->_rght = r;
230*b30d1939SAndy Fiddaman 				r->_rght = h;
231*b30d1939SAndy Fiddaman 				r->_rght->_left = r;
232*b30d1939SAndy Fiddaman 			}
233*b30d1939SAndy Fiddaman 		}
234*b30d1939SAndy Fiddaman 		else if(dt->meth->type&DT_STACK)
235*b30d1939SAndy Fiddaman 		{ dt_stack:
236*b30d1939SAndy Fiddaman 			r->_rght = t = list->link;
237*b30d1939SAndy Fiddaman 			if(t)
238*b30d1939SAndy Fiddaman 			{	r->_left = t->_left;
239*b30d1939SAndy Fiddaman 				t->_left = r;
240*b30d1939SAndy Fiddaman 			}
241*b30d1939SAndy Fiddaman 			else	r->_left = r;
242*b30d1939SAndy Fiddaman 			list->link = r;
243*b30d1939SAndy Fiddaman 		}
244*b30d1939SAndy Fiddaman 		else /* if(dt->meth->type&DT_QUEUE) */
245*b30d1939SAndy Fiddaman 		{ dt_queue:
246*b30d1939SAndy Fiddaman 			if((t = list->link) )
247*b30d1939SAndy Fiddaman 			{	t->_left->_rght = r;
248*b30d1939SAndy Fiddaman 				r->_left = t->_left;
249*b30d1939SAndy Fiddaman 				t->_left = r;
250*b30d1939SAndy Fiddaman 			}
251*b30d1939SAndy Fiddaman 			else
252*b30d1939SAndy Fiddaman 			{	list->link = r;
253*b30d1939SAndy Fiddaman 				r->_left = r;
254*b30d1939SAndy Fiddaman 			}
255*b30d1939SAndy Fiddaman 			r->_rght = NIL(Dtlink_t*);
256*b30d1939SAndy Fiddaman 		}
257*b30d1939SAndy Fiddaman 
258*b30d1939SAndy Fiddaman 		list->here = r;
259*b30d1939SAndy Fiddaman 		DTRETURN(obj, _DTOBJ(disc,r));
260*b30d1939SAndy Fiddaman 	}
261*b30d1939SAndy Fiddaman 
262*b30d1939SAndy Fiddaman 	/* define key to match */
263*b30d1939SAndy Fiddaman 	if(type&DT_MATCH)
264*b30d1939SAndy Fiddaman 	{	key = obj;
265*b30d1939SAndy Fiddaman 		obj = NIL(Void_t*);
266*b30d1939SAndy Fiddaman 	}
267*b30d1939SAndy Fiddaman 	else	key = _DTKEY(disc, obj);
268*b30d1939SAndy Fiddaman 
269*b30d1939SAndy Fiddaman 	/* try to find a matching object */
270*b30d1939SAndy Fiddaman 	if(h && _DTOBJ(disc,h) == obj && (type & (DT_SEARCH|DT_NEXT|DT_PREV)) )
271*b30d1939SAndy Fiddaman 		r = h; /* match at the finger, no search needed */
272*b30d1939SAndy Fiddaman 	else /* linear search through the list */
273*b30d1939SAndy Fiddaman 	{	h = NIL(Dtlink_t*); /* track first/last obj with same key */
274*b30d1939SAndy Fiddaman 		for(r = list->link; r; r = r->_rght)
275*b30d1939SAndy Fiddaman 		{	o = _DTOBJ(disc,r); k = _DTKEY(disc,o);
276*b30d1939SAndy Fiddaman 			if(_DTCMP(dt, key, k, disc) != 0)
277*b30d1939SAndy Fiddaman 				continue;
278*b30d1939SAndy Fiddaman 			else if(type & (DT_REMOVE|DT_NEXT|DT_PREV) )
279*b30d1939SAndy Fiddaman 			{	if(o == obj) /* got exact object, done */
280*b30d1939SAndy Fiddaman 					break;
281*b30d1939SAndy Fiddaman 				else if(type&DT_NEXT) /* track last object */
282*b30d1939SAndy Fiddaman 					h = r;
283*b30d1939SAndy Fiddaman 				else if(type&DT_PREV) /* track first object */
284*b30d1939SAndy Fiddaman 					h = h ? h : r;
285*b30d1939SAndy Fiddaman 				else	continue;
286*b30d1939SAndy Fiddaman 			}
287*b30d1939SAndy Fiddaman 			else if(type & DT_ATLEAST )
288*b30d1939SAndy Fiddaman 				h = r; /* track last object */
289*b30d1939SAndy Fiddaman 			else	break;
290*b30d1939SAndy Fiddaman 		}
291*b30d1939SAndy Fiddaman 		r = h ? h : r;
292*b30d1939SAndy Fiddaman 	}
293*b30d1939SAndy Fiddaman 	if(!r)
294*b30d1939SAndy Fiddaman 		DTRETURN(obj, NIL(Void_t*));
295*b30d1939SAndy Fiddaman 
296*b30d1939SAndy Fiddaman 	if(type&(DT_DELETE|DT_DETACH|DT_REMOVE))
297*b30d1939SAndy Fiddaman 	{ dt_delete:
298*b30d1939SAndy Fiddaman 		if(r->_rght)
299*b30d1939SAndy Fiddaman 			r->_rght->_left = r->_left;
300*b30d1939SAndy Fiddaman 		if(r == (t = list->link) )
301*b30d1939SAndy Fiddaman 		{	list->link = r->_rght;
302*b30d1939SAndy Fiddaman 			if((h = list->link) )
303*b30d1939SAndy Fiddaman 				h->_left = t->_left;
304*b30d1939SAndy Fiddaman 		}
305*b30d1939SAndy Fiddaman 		else
306*b30d1939SAndy Fiddaman 		{	r->_left->_rght = r->_rght;
307*b30d1939SAndy Fiddaman 			if(r == t->_left)
308*b30d1939SAndy Fiddaman 				t->_left = r->_left;
309*b30d1939SAndy Fiddaman 		}
310*b30d1939SAndy Fiddaman 
311*b30d1939SAndy Fiddaman 		list->here = r == list->here ? r->_rght : NIL(Dtlink_t*);
312*b30d1939SAndy Fiddaman 
313*b30d1939SAndy Fiddaman 		obj = _DTOBJ(disc,r);
314*b30d1939SAndy Fiddaman 		_dtfree(dt, r, type);
315*b30d1939SAndy Fiddaman 		dt->data->size -= 1;
316*b30d1939SAndy Fiddaman 
317*b30d1939SAndy Fiddaman 		DTRETURN(obj, obj);
318*b30d1939SAndy Fiddaman 	}
319*b30d1939SAndy Fiddaman 
320*b30d1939SAndy Fiddaman 	if(type&DT_NEXT)
321*b30d1939SAndy Fiddaman 		r = r->_rght;
322*b30d1939SAndy Fiddaman 	else if(type&DT_PREV)
323*b30d1939SAndy Fiddaman 		r = r == list->link ? NIL(Dtlink_t*) : r->_left;
324*b30d1939SAndy Fiddaman 	/* else: if(type&(DT_SEARCH|DT_MATCH|DT_ATLEAST|DT_ATMOST)) */
325*b30d1939SAndy Fiddaman 
326*b30d1939SAndy Fiddaman 	list->here = r;
327*b30d1939SAndy Fiddaman 	if(r)
328*b30d1939SAndy Fiddaman 		DTRETURN(obj, _DTOBJ(disc,r));
329*b30d1939SAndy Fiddaman 	else	DTRETURN(obj, NIL(Void_t*));
330*b30d1939SAndy Fiddaman 
331*b30d1939SAndy Fiddaman dt_return:
332*b30d1939SAndy Fiddaman 	DTANNOUNCE(dt,obj,type);
333*b30d1939SAndy Fiddaman 	DTCLRLOCK(dt);
334*b30d1939SAndy Fiddaman 	return obj;
335*b30d1939SAndy Fiddaman }
336*b30d1939SAndy Fiddaman 
337*b30d1939SAndy Fiddaman #if __STD_C
listevent(Dt_t * dt,int event,Void_t * arg)338*b30d1939SAndy Fiddaman static int listevent(Dt_t* dt, int event, Void_t* arg)
339*b30d1939SAndy Fiddaman #else
340*b30d1939SAndy Fiddaman static int listevent(dt, event, arg)
341*b30d1939SAndy Fiddaman Dt_t*	dt;
342*b30d1939SAndy Fiddaman int	event;
343*b30d1939SAndy Fiddaman Void_t*	arg;
344*b30d1939SAndy Fiddaman #endif
345*b30d1939SAndy Fiddaman {
346*b30d1939SAndy Fiddaman 	Dtlist_t	*list = (Dtlist_t*)dt->data;
347*b30d1939SAndy Fiddaman 
348*b30d1939SAndy Fiddaman 	if(event == DT_OPEN)
349*b30d1939SAndy Fiddaman 	{	if(list) /* already initialized */
350*b30d1939SAndy Fiddaman 			return 0;
351*b30d1939SAndy Fiddaman 		if(!(list = (Dtlist_t*)(*dt->memoryf)(dt, 0, sizeof(Dtlist_t), dt->disc)) )
352*b30d1939SAndy Fiddaman 		{	DTERROR(dt, "Error in allocating a list data structure");
353*b30d1939SAndy Fiddaman 			return -1;
354*b30d1939SAndy Fiddaman 		}
355*b30d1939SAndy Fiddaman 		memset(list, 0, sizeof(Dtlist_t));
356*b30d1939SAndy Fiddaman 		dt->data = (Dtdata_t*)list;
357*b30d1939SAndy Fiddaman 		return 1;
358*b30d1939SAndy Fiddaman 	}
359*b30d1939SAndy Fiddaman 	else if(event == DT_CLOSE)
360*b30d1939SAndy Fiddaman 	{	if(!list) /* already closed */
361*b30d1939SAndy Fiddaman 			return 0;
362*b30d1939SAndy Fiddaman 		if(list->link) /* remove all items */
363*b30d1939SAndy Fiddaman 			(void)lclear(dt);
364*b30d1939SAndy Fiddaman 		(void)(*dt->memoryf)(dt, (Void_t*)list, 0, dt->disc);
365*b30d1939SAndy Fiddaman 		dt->data = NIL(Dtdata_t*);
366*b30d1939SAndy Fiddaman 		return 0;
367*b30d1939SAndy Fiddaman 	}
368*b30d1939SAndy Fiddaman 	else	return 0;
369*b30d1939SAndy Fiddaman }
370*b30d1939SAndy Fiddaman 
371*b30d1939SAndy Fiddaman static Dtmethod_t _Dtlist  = { dtlist, DT_LIST,  listevent, "Dtlist"  };
372*b30d1939SAndy Fiddaman static Dtmethod_t _Dtdeque = { dtlist, DT_DEQUE, listevent, "Dtdeque" };
373*b30d1939SAndy Fiddaman static Dtmethod_t _Dtstack = { dtlist, DT_STACK, listevent, "Dtstack" };
374*b30d1939SAndy Fiddaman static Dtmethod_t _Dtqueue = { dtlist, DT_QUEUE, listevent, "Dtqueue" };
375*b30d1939SAndy Fiddaman 
376*b30d1939SAndy Fiddaman __DEFINE__(Dtmethod_t*,Dtlist,&_Dtlist);
377*b30d1939SAndy Fiddaman __DEFINE__(Dtmethod_t*,Dtdeque,&_Dtdeque);
378*b30d1939SAndy Fiddaman __DEFINE__(Dtmethod_t*,Dtstack,&_Dtstack);
379*b30d1939SAndy Fiddaman __DEFINE__(Dtmethod_t*,Dtqueue,&_Dtqueue);
380*b30d1939SAndy Fiddaman 
381*b30d1939SAndy Fiddaman #ifdef NoF
382*b30d1939SAndy Fiddaman NoF(dtlist)
383*b30d1939SAndy Fiddaman #endif
384