|
Graphviz 2.29.20120208.0545
|
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 }
1.7.4