xref: /onnv-gate/usr/src/lib/libast/common/cdt/dtview.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 /*	Set a view path from dict to view.
254887Schin **
264887Schin **	Written by Kiem-Phong Vo (5/25/96)
274887Schin */
284887Schin 
294887Schin 
304887Schin #if __STD_C
dtvsearch(Dt_t * dt,reg Void_t * obj,reg int type)314887Schin static Void_t* dtvsearch(Dt_t* dt, reg Void_t* obj, reg int type)
324887Schin #else
334887Schin static Void_t* dtvsearch(dt,obj,type)
344887Schin Dt_t*		dt;
354887Schin reg Void_t*	obj;
364887Schin reg int		type;
374887Schin #endif
384887Schin {
394887Schin 	Dt_t		*d, *p;
404887Schin 	Void_t		*o, *n, *ok, *nk;
414887Schin 	int		cmp, lk, sz, ky;
424887Schin 	Dtcompar_f	cmpf;
434887Schin 
444887Schin 	/* these operations only happen at the top level */
454887Schin 	if(type&(DT_INSERT|DT_DELETE|DT_CLEAR|DT_RENEW))
464887Schin 		return (*(dt->meth->searchf))(dt,obj,type);
474887Schin 
484887Schin 	if((type&(DT_MATCH|DT_SEARCH)) || /* order sets first/last done below */
494887Schin 	   ((type&(DT_FIRST|DT_LAST)) && !(dt->meth->type&(DT_OBAG|DT_OSET)) ) )
504887Schin 	{	for(d = dt; d; d = d->view)
514887Schin 			if((o = (*(d->meth->searchf))(d,obj,type)) )
524887Schin 				break;
534887Schin 		dt->walk = d;
544887Schin 		return o;
554887Schin 	}
564887Schin 
574887Schin 	if(dt->meth->type & (DT_OBAG|DT_OSET) )
584887Schin 	{	if(!(type & (DT_FIRST|DT_LAST|DT_NEXT|DT_PREV)) )
594887Schin 			return NIL(Void_t*);
604887Schin 
614887Schin 		n = nk = NIL(Void_t*); p = NIL(Dt_t*);
624887Schin 		for(d = dt; d; d = d->view)
634887Schin 		{	if(!(o = (*d->meth->searchf)(d, obj, type)) )
644887Schin 				continue;
654887Schin 			_DTDSC(d->disc,ky,sz,lk,cmpf);
664887Schin 			ok = _DTKEY(o,ky,sz);
674887Schin 
684887Schin 			if(n) /* get the right one among all dictionaries */
694887Schin 			{	cmp = _DTCMP(d,ok,nk,d->disc,cmpf,sz);
704887Schin 				if(((type & (DT_NEXT|DT_FIRST)) && cmp < 0) ||
714887Schin 				   ((type & (DT_PREV|DT_LAST)) && cmp > 0) )
724887Schin 					goto a_dj;
734887Schin 			}
744887Schin 			else /* looks good for now */
754887Schin 			{ a_dj: p  = d;
764887Schin 				n  = o;
774887Schin 				nk = ok;
784887Schin 			}
794887Schin 		}
804887Schin 
814887Schin 		dt->walk = p;
824887Schin 		return n;
834887Schin 	}
844887Schin 
854887Schin 	/* non-ordered methods */
864887Schin 	if(!(type & (DT_NEXT|DT_PREV)) )
874887Schin 		return NIL(Void_t*);
884887Schin 
894887Schin 	if(!dt->walk || obj != _DTOBJ(dt->walk->data->here, dt->walk->disc->link) )
904887Schin 	{	for(d = dt; d; d = d->view)
914887Schin 			if((o = (*(d->meth->searchf))(d, obj, DT_SEARCH)) )
924887Schin 				break;
934887Schin 		dt->walk = d;
944887Schin 		if(!(obj = o) )
954887Schin 			return NIL(Void_t*);
964887Schin 	}
974887Schin 
984887Schin 	for(d = dt->walk, obj = (*d->meth->searchf)(d, obj, type);; )
994887Schin 	{	while(obj) /* keep moving until finding an uncovered object */
1004887Schin 		{	for(p = dt; ; p = p->view)
1014887Schin 			{	if(p == d) /* adjacent object is uncovered */
1024887Schin 					return obj;
1034887Schin 				if((*(p->meth->searchf))(p, obj, DT_SEARCH) )
1044887Schin 					break;
1054887Schin 			}
1064887Schin 			obj = (*d->meth->searchf)(d, obj, type);
1074887Schin 		}
1084887Schin 
1094887Schin 		if(!(d = dt->walk = d->view) ) /* move on to next dictionary */
1104887Schin 			return NIL(Void_t*);
1114887Schin 		else if(type&DT_NEXT)
1124887Schin 			obj = (*(d->meth->searchf))(d,NIL(Void_t*),DT_FIRST);
1134887Schin 		else	obj = (*(d->meth->searchf))(d,NIL(Void_t*),DT_LAST);
1144887Schin 	}
1154887Schin }
1164887Schin 
1174887Schin #if __STD_C
dtview(reg Dt_t * dt,reg Dt_t * view)1184887Schin Dt_t* dtview(reg Dt_t* dt, reg Dt_t* view)
1194887Schin #else
1204887Schin Dt_t* dtview(dt,view)
1214887Schin reg Dt_t*	dt;
1224887Schin reg Dt_t*	view;
1234887Schin #endif
1244887Schin {
1254887Schin 	reg Dt_t*	d;
1264887Schin 
1274887Schin 	UNFLATTEN(dt);
1284887Schin 	if(view)
1294887Schin 	{	UNFLATTEN(view);
1304887Schin 		if(view->meth != dt->meth) /* must use the same method */
1314887Schin 			return NIL(Dt_t*);
1324887Schin 	}
1334887Schin 
1344887Schin 	/* make sure there won't be a cycle */
1354887Schin 	for(d = view; d; d = d->view)
1364887Schin 		if(d == dt)
1374887Schin 			return NIL(Dt_t*);
1384887Schin 
1394887Schin 	/* no more viewing lower dictionary */
1404887Schin 	if((d = dt->view) )
1414887Schin 		d->nview -= 1;
1424887Schin 	dt->view = dt->walk = NIL(Dt_t*);
1434887Schin 
1444887Schin 	if(!view)
1454887Schin 	{	dt->searchf = dt->meth->searchf;
1464887Schin 		return d;
1474887Schin 	}
1484887Schin 
1494887Schin 	/* ok */
1504887Schin 	dt->view = view;
1514887Schin 	dt->searchf = dtvsearch;
1524887Schin 	view->nview += 1;
1534887Schin 
1544887Schin 	return view;
1554887Schin }
156