#include "dthdr.h"
#ifdef DMALLOC
#include "dmalloc.h"
#endif
#if __STD_C
static Void_t* dtvsearch(Dt_t* dt, reg Void_t* obj, reg int type)
#else
static Void_t* dtvsearch(dt,obj,type)
Dt_t* dt;
reg Void_t* obj;
reg int type;
#endif
{
reg Dt_t *d, *p;
reg Void_t* o;
reg Dtdisc_t* disc;
reg Dtlink_t* here;
if(type&(DT_INSERT|DT_DELETE|DT_CLEAR|DT_RENEW))
return (*(dt->meth->searchf))(dt,obj,type);
if(!obj && !(type&(DT_FIRST|DT_LAST)) )
return NIL(Void_t*);
if(type&(DT_MATCH|DT_SEARCH|DT_FIRST|DT_LAST))
{ for(d = dt; d; d = d->view)
{ if((o = (*(d->meth->searchf))(d,obj,type)) )
{ dt->walk = d;
return o;
}
}
dt->walk = NIL(Dt_t*);
return NIL(Void_t*);
}
if(!dt->walk || !(here = dt->walk->data->here) ||
obj != OBJ(here,dt->walk->disc->link) )
{ for(d = dt; d; d = d->view)
{ if((o = (*(d->meth->searchf))(d,obj,DT_SEARCH)) )
{ dt->walk = d;
goto do_adj;
}
}
dt->walk = NIL(Dt_t*);
return NIL(Void_t*);
}
do_adj: for(d = dt->walk, o = (*(d->meth->searchf))(d,obj,type); ; )
{ while(o)
{ disc = d->disc;
here = (d->meth->type&(DT_SET|DT_BAG)) ?
d->data->here : NIL(Dtlink_t*);
for(p = dt; ; p = p->view)
{ reg Dtdisc_t* dc;
if(p == d)
return o;
if(here && (p->meth->type&(DT_SET|DT_BAG)) &&
(disc == (dc = p->disc) ||
(disc->key == dc->key && disc->size == dc->size &&
disc->link == dc->link && disc->hashf == dc->hashf)))
{ if((*(p->meth->searchf))(p,here,DT_VSEARCH) )
break;
}
else
{ if((*(p->meth->searchf))(p,o,DT_SEARCH) )
break;
}
}
o = (*(d->meth->searchf))(d,o,type);
}
if(!(d = dt->walk = d->view) )
return NIL(Void_t*);
if(type&DT_NEXT)
o = (*(d->meth->searchf))(d,NIL(Void_t*),DT_FIRST);
else
o = (*(d->meth->searchf))(d,NIL(Void_t*),DT_LAST);
}
}
#if __STD_C
Dt_t* dtview(reg Dt_t* dt, reg Dt_t* view)
#else
Dt_t* dtview(dt,view)
reg Dt_t* dt;
reg Dt_t* view;
#endif
{
reg Dt_t* d;
UNFLATTEN(dt);
if(view)
UNFLATTEN(view);
for(d = view; d; d = d->view)
if(d == dt)
return NIL(Dt_t*);
if((d = dt->view) )
d->nview -= 1;
dt->view = dt->walk = NIL(Dt_t*);
if(!view)
{ dt->searchf = dt->meth->searchf;
return d;
}
dt->view = view;
dt->searchf = dtvsearch;
view->nview += 1;
return view;
}