1da2e3ebdSchin /***********************************************************************
2da2e3ebdSchin * *
3da2e3ebdSchin * This software is part of the ast package *
4*3e14f97fSRoger A. Faulkner * Copyright (c) 1985-2010 AT&T Intellectual Property *
5da2e3ebdSchin * and is licensed under the *
6da2e3ebdSchin * Common Public License, Version 1.0 *
77c2fbfb3SApril Chin * by AT&T Intellectual Property *
8da2e3ebdSchin * *
9da2e3ebdSchin * A copy of the License is available at *
10da2e3ebdSchin * http://www.opensource.org/licenses/cpl1.0.txt *
11da2e3ebdSchin * (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
12da2e3ebdSchin * *
13da2e3ebdSchin * Information and Software Systems Research *
14da2e3ebdSchin * AT&T Research *
15da2e3ebdSchin * Florham Park NJ *
16da2e3ebdSchin * *
17da2e3ebdSchin * Glenn Fowler <gsf@research.att.com> *
18da2e3ebdSchin * David Korn <dgk@research.att.com> *
19da2e3ebdSchin * Phong Vo <kpv@research.att.com> *
20da2e3ebdSchin * *
21da2e3ebdSchin ***********************************************************************/
22da2e3ebdSchin #include "dthdr.h"
23da2e3ebdSchin
24da2e3ebdSchin /* Set a view path from dict to view.
25da2e3ebdSchin **
26da2e3ebdSchin ** Written by Kiem-Phong Vo (5/25/96)
27da2e3ebdSchin */
28da2e3ebdSchin
29da2e3ebdSchin
30da2e3ebdSchin #if __STD_C
dtvsearch(Dt_t * dt,reg Void_t * obj,reg int type)31da2e3ebdSchin static Void_t* dtvsearch(Dt_t* dt, reg Void_t* obj, reg int type)
32da2e3ebdSchin #else
33da2e3ebdSchin static Void_t* dtvsearch(dt,obj,type)
34da2e3ebdSchin Dt_t* dt;
35da2e3ebdSchin reg Void_t* obj;
36da2e3ebdSchin reg int type;
37da2e3ebdSchin #endif
38da2e3ebdSchin {
39da2e3ebdSchin Dt_t *d, *p;
40da2e3ebdSchin Void_t *o, *n, *ok, *nk;
41da2e3ebdSchin int cmp, lk, sz, ky;
42da2e3ebdSchin Dtcompar_f cmpf;
43da2e3ebdSchin
44da2e3ebdSchin /* these operations only happen at the top level */
45da2e3ebdSchin if(type&(DT_INSERT|DT_DELETE|DT_CLEAR|DT_RENEW))
46da2e3ebdSchin return (*(dt->meth->searchf))(dt,obj,type);
47da2e3ebdSchin
48da2e3ebdSchin if((type&(DT_MATCH|DT_SEARCH)) || /* order sets first/last done below */
49da2e3ebdSchin ((type&(DT_FIRST|DT_LAST)) && !(dt->meth->type&(DT_OBAG|DT_OSET)) ) )
50da2e3ebdSchin { for(d = dt; d; d = d->view)
51da2e3ebdSchin if((o = (*(d->meth->searchf))(d,obj,type)) )
52da2e3ebdSchin break;
53da2e3ebdSchin dt->walk = d;
54da2e3ebdSchin return o;
55da2e3ebdSchin }
56da2e3ebdSchin
57da2e3ebdSchin if(dt->meth->type & (DT_OBAG|DT_OSET) )
58da2e3ebdSchin { if(!(type & (DT_FIRST|DT_LAST|DT_NEXT|DT_PREV)) )
59da2e3ebdSchin return NIL(Void_t*);
60da2e3ebdSchin
61da2e3ebdSchin n = nk = NIL(Void_t*); p = NIL(Dt_t*);
62da2e3ebdSchin for(d = dt; d; d = d->view)
63da2e3ebdSchin { if(!(o = (*d->meth->searchf)(d, obj, type)) )
64da2e3ebdSchin continue;
65da2e3ebdSchin _DTDSC(d->disc,ky,sz,lk,cmpf);
66da2e3ebdSchin ok = _DTKEY(o,ky,sz);
67da2e3ebdSchin
68da2e3ebdSchin if(n) /* get the right one among all dictionaries */
69da2e3ebdSchin { cmp = _DTCMP(d,ok,nk,d->disc,cmpf,sz);
70da2e3ebdSchin if(((type & (DT_NEXT|DT_FIRST)) && cmp < 0) ||
71da2e3ebdSchin ((type & (DT_PREV|DT_LAST)) && cmp > 0) )
72da2e3ebdSchin goto a_dj;
73da2e3ebdSchin }
74da2e3ebdSchin else /* looks good for now */
75da2e3ebdSchin { a_dj: p = d;
76da2e3ebdSchin n = o;
77da2e3ebdSchin nk = ok;
78da2e3ebdSchin }
79da2e3ebdSchin }
80da2e3ebdSchin
81da2e3ebdSchin dt->walk = p;
82da2e3ebdSchin return n;
83da2e3ebdSchin }
84da2e3ebdSchin
85da2e3ebdSchin /* non-ordered methods */
86da2e3ebdSchin if(!(type & (DT_NEXT|DT_PREV)) )
87da2e3ebdSchin return NIL(Void_t*);
88da2e3ebdSchin
89da2e3ebdSchin if(!dt->walk || obj != _DTOBJ(dt->walk->data->here, dt->walk->disc->link) )
90da2e3ebdSchin { for(d = dt; d; d = d->view)
91da2e3ebdSchin if((o = (*(d->meth->searchf))(d, obj, DT_SEARCH)) )
92da2e3ebdSchin break;
93da2e3ebdSchin dt->walk = d;
94da2e3ebdSchin if(!(obj = o) )
95da2e3ebdSchin return NIL(Void_t*);
96da2e3ebdSchin }
97da2e3ebdSchin
98da2e3ebdSchin for(d = dt->walk, obj = (*d->meth->searchf)(d, obj, type);; )
99da2e3ebdSchin { while(obj) /* keep moving until finding an uncovered object */
100da2e3ebdSchin { for(p = dt; ; p = p->view)
101da2e3ebdSchin { if(p == d) /* adjacent object is uncovered */
102da2e3ebdSchin return obj;
103da2e3ebdSchin if((*(p->meth->searchf))(p, obj, DT_SEARCH) )
104da2e3ebdSchin break;
105da2e3ebdSchin }
106da2e3ebdSchin obj = (*d->meth->searchf)(d, obj, type);
107da2e3ebdSchin }
108da2e3ebdSchin
109da2e3ebdSchin if(!(d = dt->walk = d->view) ) /* move on to next dictionary */
110da2e3ebdSchin return NIL(Void_t*);
111da2e3ebdSchin else if(type&DT_NEXT)
112da2e3ebdSchin obj = (*(d->meth->searchf))(d,NIL(Void_t*),DT_FIRST);
113da2e3ebdSchin else obj = (*(d->meth->searchf))(d,NIL(Void_t*),DT_LAST);
114da2e3ebdSchin }
115da2e3ebdSchin }
116da2e3ebdSchin
117da2e3ebdSchin #if __STD_C
dtview(reg Dt_t * dt,reg Dt_t * view)118da2e3ebdSchin Dt_t* dtview(reg Dt_t* dt, reg Dt_t* view)
119da2e3ebdSchin #else
120da2e3ebdSchin Dt_t* dtview(dt,view)
121da2e3ebdSchin reg Dt_t* dt;
122da2e3ebdSchin reg Dt_t* view;
123da2e3ebdSchin #endif
124da2e3ebdSchin {
125da2e3ebdSchin reg Dt_t* d;
126da2e3ebdSchin
127da2e3ebdSchin UNFLATTEN(dt);
128da2e3ebdSchin if(view)
129da2e3ebdSchin { UNFLATTEN(view);
130da2e3ebdSchin if(view->meth != dt->meth) /* must use the same method */
131da2e3ebdSchin return NIL(Dt_t*);
132da2e3ebdSchin }
133da2e3ebdSchin
134da2e3ebdSchin /* make sure there won't be a cycle */
135da2e3ebdSchin for(d = view; d; d = d->view)
136da2e3ebdSchin if(d == dt)
137da2e3ebdSchin return NIL(Dt_t*);
138da2e3ebdSchin
139da2e3ebdSchin /* no more viewing lower dictionary */
140da2e3ebdSchin if((d = dt->view) )
141da2e3ebdSchin d->nview -= 1;
142da2e3ebdSchin dt->view = dt->walk = NIL(Dt_t*);
143da2e3ebdSchin
144da2e3ebdSchin if(!view)
145da2e3ebdSchin { dt->searchf = dt->meth->searchf;
146da2e3ebdSchin return d;
147da2e3ebdSchin }
148da2e3ebdSchin
149da2e3ebdSchin /* ok */
150da2e3ebdSchin dt->view = view;
151da2e3ebdSchin dt->searchf = dtvsearch;
152da2e3ebdSchin view->nview += 1;
153da2e3ebdSchin
154da2e3ebdSchin return view;
155da2e3ebdSchin }
156