xref: /onnv-gate/usr/src/lib/libast/common/cdt/dtlist.c (revision 12068:08a39a083754)
14887Schin /***********************************************************************
24887Schin *                                                                      *
34887Schin *               This software is part of the ast package               *
4*12068SRoger.Faulkner@Oracle.COM *          Copyright (c) 1985-2010 AT&T Intellectual Property          *
54887Schin *                      and is licensed under the                       *
64887Schin *                  Common Public License, Version 1.0                  *
78462SApril.Chin@Sun.COM *                    by AT&T Intellectual Property                     *
84887Schin *                                                                      *
94887Schin *                A copy of the License is available at                 *
104887Schin *            http://www.opensource.org/licenses/cpl1.0.txt             *
114887Schin *         (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9)         *
124887Schin *                                                                      *
134887Schin *              Information and Software Systems Research               *
144887Schin *                            AT&T Research                             *
154887Schin *                           Florham Park NJ                            *
164887Schin *                                                                      *
174887Schin *                 Glenn Fowler <gsf@research.att.com>                  *
184887Schin *                  David Korn <dgk@research.att.com>                   *
194887Schin *                   Phong Vo <kpv@research.att.com>                    *
204887Schin *                                                                      *
214887Schin ***********************************************************************/
224887Schin #include	"dthdr.h"
234887Schin 
244887Schin /*	List, Stack, Queue.
254887Schin **
264887Schin **	Written by Kiem-Phong Vo (05/25/96)
274887Schin */
284887Schin 
294887Schin #if __STD_C
dtlist(reg Dt_t * dt,reg Void_t * obj,reg int type)304887Schin static Void_t* dtlist(reg Dt_t* dt, reg Void_t* obj, reg int type)
314887Schin #else
324887Schin static Void_t* dtlist(dt, obj, type)
334887Schin reg Dt_t*	dt;
344887Schin reg Void_t*	obj;
354887Schin reg int		type;
364887Schin #endif
374887Schin {
384887Schin 	reg int		lk, sz, ky;
394887Schin 	reg Dtcompar_f	cmpf;
404887Schin 	reg Dtdisc_t*	disc;
414887Schin 	reg Dtlink_t	*r, *t;
424887Schin 	reg Void_t	*key, *k;
434887Schin 
444887Schin 	UNFLATTEN(dt);
454887Schin 	disc = dt->disc; _DTDSC(disc,ky,sz,lk,cmpf);
464887Schin 	dt->type &= ~DT_FOUND;
474887Schin 
484887Schin 	if(!obj)
494887Schin 	{	if(type&(DT_LAST|DT_FIRST) )
504887Schin 		{	if((r = dt->data->head) )
514887Schin 			{	if(type&DT_LAST)
524887Schin 					r = r->left;
534887Schin 				dt->data->here = r;
544887Schin 			}
554887Schin 			return r ? _DTOBJ(r,lk) : NIL(Void_t*);
564887Schin 		}
574887Schin 		else if(type&(DT_DELETE|DT_DETACH))
584887Schin 		{	if((dt->data->type&DT_LIST) || !(r = dt->data->head))
594887Schin 				return NIL(Void_t*);
604887Schin 			else	goto dt_delete;
614887Schin 		}
624887Schin 		else if(type&DT_CLEAR)
634887Schin 		{	if(disc->freef || disc->link < 0)
644887Schin 			{	for(r = dt->data->head; r; r = t)
654887Schin 				{	t = r->right;
664887Schin 					if(disc->freef)
674887Schin 						(*disc->freef)(dt,_DTOBJ(r,lk),disc);
684887Schin 					if(disc->link < 0)
694887Schin 						(*dt->memoryf)(dt,(Void_t*)r,0,disc);
704887Schin 				}
714887Schin 			}
724887Schin 			dt->data->head = dt->data->here = NIL(Dtlink_t*);
734887Schin 			dt->data->size = 0;
744887Schin 			return NIL(Void_t*);
754887Schin 		}
764887Schin 		else	return NIL(Void_t*);
774887Schin 	}
784887Schin 
794887Schin 	if(type&(DT_INSERT|DT_ATTACH))
804887Schin 	{	if(disc->makef && (type&DT_INSERT) &&
814887Schin 		   !(obj = (*disc->makef)(dt,obj,disc)) )
824887Schin 			return NIL(Void_t*);
834887Schin 		if(lk >= 0)
844887Schin 			r = _DTLNK(obj,lk);
854887Schin 		else
864887Schin 		{	r = (Dtlink_t*)(*dt->memoryf)
874887Schin 				(dt,NIL(Void_t*),sizeof(Dthold_t),disc);
884887Schin 			if(r)
894887Schin 				((Dthold_t*)r)->obj = obj;
904887Schin 			else
914887Schin 			{	if(disc->makef && disc->freef && (type&DT_INSERT))
924887Schin 					(*disc->freef)(dt,obj,disc);
934887Schin 				return NIL(Void_t*);
944887Schin 			}
954887Schin 		}
964887Schin 
974887Schin 		if(dt->data->type&DT_LIST)
984887Schin 		{	if((t = dt->data->here) && t != dt->data->head)
994887Schin 			{	r->left = t->left;
1004887Schin 				t->left->right = r;
1014887Schin 				r->right = t;
1024887Schin 				t->left = r;
1034887Schin 			}
1044887Schin 			else	goto dt_stack;
1054887Schin 		}
1064887Schin 		else if(dt->data->type&DT_STACK)
1074887Schin 		{ dt_stack:
1084887Schin 			r->right = t = dt->data->head;
1094887Schin 			if(t)
1104887Schin 			{	r->left = t->left;
1114887Schin 				t->left = r;
1124887Schin 			}
1134887Schin 			else	r->left = r;
1144887Schin 			dt->data->head = r;
1154887Schin 		}
1164887Schin 		else /* if(dt->data->type&DT_QUEUE) */
1174887Schin 		{	if((t = dt->data->head) )
1184887Schin 			{	t->left->right = r;
1194887Schin 				r->left = t->left;
1204887Schin 				t->left = r;
1214887Schin 			}
1224887Schin 			else
1234887Schin 			{	dt->data->head = r;
1244887Schin 				r->left = r;
1254887Schin 			}
1264887Schin 			r->right = NIL(Dtlink_t*);
1274887Schin 		}
1284887Schin 
1294887Schin 		if(dt->data->size >= 0)
1304887Schin 			dt->data->size += 1;
1314887Schin 
1324887Schin 		dt->data->here = r;
1334887Schin 		return _DTOBJ(r,lk);
1344887Schin 	}
1354887Schin 
1364887Schin 	if((type&DT_MATCH) || !(r = dt->data->here) || _DTOBJ(r,lk) != obj)
1374887Schin 	{	key = (type&DT_MATCH) ? obj : _DTKEY(obj,ky,sz);
1384887Schin 		for(r = dt->data->head; r; r = r->right)
1394887Schin 		{	k = _DTOBJ(r,lk); k = _DTKEY(k,ky,sz);
1404887Schin 			if(_DTCMP(dt,key,k,disc,cmpf,sz) == 0)
1414887Schin 				break;
1424887Schin 		}
1434887Schin 	}
1444887Schin 
1454887Schin 	if(!r)
1464887Schin 		return NIL(Void_t*);
1474887Schin 	dt->type |= DT_FOUND;
1484887Schin 
1494887Schin 	if(type&(DT_DELETE|DT_DETACH))
1504887Schin 	{ dt_delete:
1514887Schin 		if(r->right)
1524887Schin 			r->right->left = r->left;
1534887Schin 		if(r == (t = dt->data->head) )
1544887Schin 		{	dt->data->head = r->right;
1554887Schin 			if(dt->data->head)
1564887Schin 				dt->data->head->left = t->left;
1574887Schin 		}
1584887Schin 		else
1594887Schin 		{	r->left->right = r->right;
1604887Schin 			if(r == t->left)
1614887Schin 				t->left = r->left;
1624887Schin 		}
1634887Schin 
1644887Schin 		dt->data->here = r == dt->data->here ? r->right : NIL(Dtlink_t*);
1654887Schin 		dt->data->size -= 1;
1664887Schin 
1674887Schin 		obj = _DTOBJ(r,lk);
1684887Schin 		if(disc->freef && (type&DT_DELETE))
1694887Schin 			(*disc->freef)(dt,obj,disc);
1704887Schin 		if(disc->link < 0)
1714887Schin 			(*dt->memoryf)(dt,(Void_t*)r,0,disc);
1724887Schin 		return obj;
1734887Schin 	}
1744887Schin 	else if(type&DT_NEXT)
1754887Schin 		r = r->right;
1764887Schin 	else if(type&DT_PREV)
1774887Schin 		r = r == dt->data->head ? NIL(Dtlink_t*) : r->left;
1784887Schin 
1794887Schin 	dt->data->here = r;
1804887Schin 	return r ? _DTOBJ(r,lk) : NIL(Void_t*);
1814887Schin }
1824887Schin 
1834887Schin #ifndef KPVDEL	/* to be remove next round */
1844887Schin #define static
1854887Schin #endif
1864887Schin static Dtmethod_t _Dtlist  = { dtlist, DT_LIST  };
1874887Schin static Dtmethod_t _Dtstack = { dtlist, DT_STACK };
1884887Schin static Dtmethod_t _Dtqueue = { dtlist, DT_QUEUE };
1894887Schin 
1904887Schin __DEFINE__(Dtmethod_t*,Dtlist,&_Dtlist);
1914887Schin __DEFINE__(Dtmethod_t*,Dtstack,&_Dtstack);
1924887Schin __DEFINE__(Dtmethod_t*,Dtqueue,&_Dtqueue);
1934887Schin 
1944887Schin #ifdef NoF
1954887Schin NoF(dtlist)
1964887Schin #endif
197