Graphviz 2.29.20120208.0545
lib/cdt/dtview.c
Go to the documentation of this file.
00001 #include        "dthdr.h"
00002 
00003 /*      Set a view path from dict to view.
00004 **
00005 **      Written by Kiem-Phong Vo (5/25/96)
00006 */
00007 
00008 
00009 #if __STD_C
00010 static Void_t* dtvsearch(Dt_t* dt, reg Void_t* obj, reg int type)
00011 #else
00012 static Void_t* dtvsearch(dt,obj,type)
00013 Dt_t*           dt;
00014 reg Void_t*     obj;
00015 reg int         type;
00016 #endif
00017 {
00018         Dt_t            *d, *p;
00019         Void_t          *o, *n, *ok, *nk;
00020         int             cmp, lk, sz, ky;
00021         Dtcompar_f      cmpf;
00022 
00023         /* these operations only happen at the top level */
00024         if(type&(DT_INSERT|DT_DELETE|DT_CLEAR|DT_RENEW))
00025                 return (*(dt->meth->searchf))(dt,obj,type);
00026 
00027         if((type&(DT_MATCH|DT_SEARCH)) || /* order sets first/last done below */
00028            ((type&(DT_FIRST|DT_LAST)) && !(dt->meth->type&(DT_OBAG|DT_OSET)) ) )
00029         {       for(d = dt; d; d = d->view)
00030                         if((o = (*(d->meth->searchf))(d,obj,type)) )
00031                                 break;
00032                 dt->walk = d;
00033                 return o;
00034         }
00035 
00036         if(dt->meth->type & (DT_OBAG|DT_OSET) )
00037         {       if(!(type & (DT_FIRST|DT_LAST|DT_NEXT|DT_PREV)) )
00038                         return NIL(Void_t*);
00039 
00040                 n = nk = NIL(Void_t*); p = NIL(Dt_t*);
00041                 for(d = dt; d; d = d->view)
00042                 {       if(!(o = (*d->meth->searchf)(d, obj, type)) )
00043                                 continue;
00044                         _DTDSC(d->disc,ky,sz,lk,cmpf);
00045                         ok = _DTKEY(o,ky,sz);
00046 
00047                         if(n) /* get the right one among all dictionaries */
00048                         {       cmp = _DTCMP(d,ok,nk,d->disc,cmpf,sz);
00049                                 if(((type & (DT_NEXT|DT_FIRST)) && cmp < 0) ||
00050                                    ((type & (DT_PREV|DT_LAST)) && cmp > 0) )
00051                                         goto a_dj;
00052                         }
00053                         else /* looks good for now */
00054                         { a_dj: p  = d;
00055                                 n  = o;
00056                                 nk = ok;
00057                         }
00058                 }
00059 
00060                 dt->walk = p;
00061                 return n;
00062         }
00063 
00064         /* non-ordered methods */
00065         if(!(type & (DT_NEXT|DT_PREV)) )
00066                 return NIL(Void_t*);
00067 
00068         if(!dt->walk || obj != _DTOBJ(dt->walk->data->here, dt->walk->disc->link) )
00069         {       for(d = dt; d; d = d->view)
00070                         if((o = (*(d->meth->searchf))(d, obj, DT_SEARCH)) )
00071                                 break;
00072                 dt->walk = d;
00073                 if(!(obj = o) )
00074                         return NIL(Void_t*);
00075         }
00076 
00077         for(d = dt->walk, obj = (*d->meth->searchf)(d, obj, type);; )
00078         {       while(obj) /* keep moving until finding an uncovered object */
00079                 {       for(p = dt; ; p = p->view)
00080                         {       if(p == d) /* adjacent object is uncovered */   
00081                                         return obj;
00082                                 if((*(p->meth->searchf))(p, obj, DT_SEARCH) )
00083                                         break;
00084                         }
00085                         obj = (*d->meth->searchf)(d, obj, type);
00086                 }
00087 
00088                 if(!(d = dt->walk = d->view) ) /* move on to next dictionary */
00089                         return NIL(Void_t*);
00090                 else if(type&DT_NEXT)
00091                         obj = (*(d->meth->searchf))(d,NIL(Void_t*),DT_FIRST);
00092                 else    obj = (*(d->meth->searchf))(d,NIL(Void_t*),DT_LAST);
00093         }
00094 }
00095 
00096 #if __STD_C
00097 Dt_t* dtview(reg Dt_t* dt, reg Dt_t* view)
00098 #else
00099 Dt_t* dtview(dt,view)
00100 reg Dt_t*       dt;
00101 reg Dt_t*       view;
00102 #endif
00103 {
00104         reg Dt_t*       d;
00105 
00106         UNFLATTEN(dt);
00107         if(view)
00108         {       UNFLATTEN(view);
00109                 if(view->meth != dt->meth) /* must use the same method */
00110                         return NIL(Dt_t*);
00111         }
00112 
00113         /* make sure there won't be a cycle */
00114         for(d = view; d; d = d->view)
00115                 if(d == dt)
00116                         return NIL(Dt_t*);
00117 
00118         /* no more viewing lower dictionary */
00119         if((d = dt->view) )
00120                 d->nview -= 1;
00121         dt->view = dt->walk = NIL(Dt_t*);
00122 
00123         if(!view)
00124         {       dt->searchf = dt->meth->searchf;
00125                 return d;
00126         }
00127 
00128         /* ok */
00129         dt->view = view;
00130         dt->searchf = dtvsearch;
00131         view->nview += 1;
00132 
00133         return view;
00134 }