1
0
Fork 0
mirror of git://git.code.sf.net/p/cdesktopenv/code synced 2025-03-09 15:50:02 +00:00
cde/src/lib/libast/cdt/dtview.c
Martijn Dekker 441dcc0483 Upgrade licence to EPL 2.0
EPL 1.0 says, in section 7: "The Program (including Contributions)
may always be distributed subject to the version of the Agreement
under which it was received. In addition, after a new version of
the Agreement is published, Contributor may elect to distribute the
Program (including its Contributions) under the new version."

The Eclipse Foundation also encourage everyone to upgrade:
https://www.eclipse.org/legal/epl-2.0/faq.php#h.60mjudroo8e5
https://www.eclipse.org/legal/epl-2.0/faq.php#h.tci84nlsqpgw

Unfortunately the new Secondary License option is not available to
us as we're not the original copyright holders and don't have the
legal power to add one. So, no GPL compatibility. Sorry.
2022-07-28 05:46:08 +02:00

140 lines
4.1 KiB
C

/***********************************************************************
* *
* This software is part of the ast package *
* Copyright (c) 1985-2011 AT&T Intellectual Property *
* Copyright (c) 2020-2022 Contributors to ksh 93u+m *
* and is licensed under the *
* Eclipse Public License, Version 2.0 *
* *
* A copy of the License is available at *
* https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html *
* (with md5 checksum 84283fa8859daf213bdda5a9f8d1be1d) *
* *
* Glenn Fowler <gsf@research.att.com> *
* David Korn <dgk@research.att.com> *
* Phong Vo <kpv@research.att.com> *
* *
***********************************************************************/
#include "dthdr.h"
/* Set a view path from dict to view.
**
** Written by Kiem-Phong Vo (5/25/96)
*/
/* these operations must be done without viewpathing */
#define DT_NOVIEWPATH (DT_INSERT|DT_APPEND|DT_DELETE|\
DT_ATTACH|DT_DETACH|DT_RELINK|DT_CLEAR| \
DT_FLATTEN|DT_EXTRACT|DT_RESTORE|DT_STAT)
static void* dtvsearch(Dt_t* dt, reg void* obj, reg int type)
{
int cmp;
Dt_t *d, *p;
void *o, *n, *oky, *nky;
if(type&DT_NOVIEWPATH)
return (*(dt->meth->searchf))(dt,obj,type);
o = NIL(void*);
/* these ops look for the first appearance of an object of the right type */
if((type & (DT_MATCH|DT_SEARCH)) ||
((type & (DT_FIRST|DT_LAST|DT_ATLEAST|DT_ATMOST)) && !(dt->meth->type&DT_ORDERED) ) )
{ for(d = dt; d; d = d->view)
if((o = (*(d->meth->searchf))(d,obj,type)) )
break;
dt->walk = d;
return o;
}
if(dt->meth->type & DT_ORDERED) /* ordered sets/bags */
{ if(!(type & (DT_FIRST|DT_LAST|DT_NEXT|DT_PREV|DT_ATLEAST|DT_ATMOST)) )
return NIL(void*);
/* find the min/max element that satisfies the op requirement */
n = nky = NIL(void*); p = NIL(Dt_t*);
for(d = dt; d; d = d->view)
{ if(!(o = (*d->meth->searchf)(d, obj, type)) )
continue;
oky = _DTKEY(d->disc,o);
if(n) /* get the right one among all dictionaries */
{ cmp = _DTCMP(d,oky,nky,d->disc);
if(((type & (DT_NEXT|DT_FIRST|DT_ATLEAST)) && cmp < 0) ||
((type & (DT_PREV|DT_LAST|DT_ATMOST)) && cmp > 0) )
goto b_est;
}
else
{ b_est: /* current best element to fit op requirement */
p = d;
n = o;
nky = oky;
}
}
dt->walk = p;
return n;
}
/* unordered collections */
if(!(type&(DT_NEXT|DT_PREV)) )
return NIL(void*);
if(!dt->walk )
{ for(d = dt; d; d = d->view)
if((o = (*(d->meth->searchf))(d, obj, DT_SEARCH)) )
break;
dt->walk = d;
if(!(obj = o) )
return NIL(void*);
}
for(d = dt->walk, obj = (*d->meth->searchf)(d, obj, type);; )
{ while(obj) /* keep moving until finding an uncovered object */
{ for(p = dt; ; p = p->view)
{ if(p == d) /* adjacent object is uncovered */
return obj;
if((*(p->meth->searchf))(p, obj, DT_SEARCH) )
break;
}
obj = (*d->meth->searchf)(d, obj, type);
}
if(!(d = dt->walk = d->view) ) /* move on to next dictionary */
return NIL(void*);
else if(type&DT_NEXT)
obj = (*(d->meth->searchf))(d,NIL(void*),DT_FIRST);
else obj = (*(d->meth->searchf))(d,NIL(void*),DT_LAST);
}
}
Dt_t* dtview(reg Dt_t* dt, reg Dt_t* view)
{
reg Dt_t* d;
if(view && view->meth != dt->meth) /* must use the same method */
return NIL(Dt_t*);
/* make sure there won't be a cycle */
for(d = view; d; d = d->view)
if(d == dt)
return NIL(Dt_t*);
/* no more viewing lower dictionary */
if((d = dt->view) )
d->nview -= 1;
dt->view = dt->walk = NIL(Dt_t*);
if(!view)
{ dt->searchf = dt->meth->searchf;
return d;
}
/* ok */
dt->view = view;
dt->searchf = dtvsearch;
view->nview += 1;
return view;
}