14887Schin /***********************************************************************
24887Schin * *
34887Schin * This software is part of the ast package *
4*12068SRoger.Faulkner@Oracle.COM * Copyright (c) 1985-2010 AT&T Intellectual Property *
54887Schin * and is licensed under the *
64887Schin * Common Public License, Version 1.0 *
78462SApril.Chin@Sun.COM * by AT&T Intellectual Property *
84887Schin * *
94887Schin * A copy of the License is available at *
104887Schin * http://www.opensource.org/licenses/cpl1.0.txt *
114887Schin * (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
124887Schin * *
134887Schin * Information and Software Systems Research *
144887Schin * AT&T Research *
154887Schin * Florham Park NJ *
164887Schin * *
174887Schin * Glenn Fowler <gsf@research.att.com> *
184887Schin * David Korn <dgk@research.att.com> *
194887Schin * Phong Vo <kpv@research.att.com> *
204887Schin * *
214887Schin ***********************************************************************/
224887Schin #include "dthdr.h"
234887Schin
244887Schin /* List, Stack, Queue.
254887Schin **
264887Schin ** Written by Kiem-Phong Vo (05/25/96)
274887Schin */
284887Schin
294887Schin #if __STD_C
dtlist(reg Dt_t * dt,reg Void_t * obj,reg int type)304887Schin static Void_t* dtlist(reg Dt_t* dt, reg Void_t* obj, reg int type)
314887Schin #else
324887Schin static Void_t* dtlist(dt, obj, type)
334887Schin reg Dt_t* dt;
344887Schin reg Void_t* obj;
354887Schin reg int type;
364887Schin #endif
374887Schin {
384887Schin reg int lk, sz, ky;
394887Schin reg Dtcompar_f cmpf;
404887Schin reg Dtdisc_t* disc;
414887Schin reg Dtlink_t *r, *t;
424887Schin reg Void_t *key, *k;
434887Schin
444887Schin UNFLATTEN(dt);
454887Schin disc = dt->disc; _DTDSC(disc,ky,sz,lk,cmpf);
464887Schin dt->type &= ~DT_FOUND;
474887Schin
484887Schin if(!obj)
494887Schin { if(type&(DT_LAST|DT_FIRST) )
504887Schin { if((r = dt->data->head) )
514887Schin { if(type&DT_LAST)
524887Schin r = r->left;
534887Schin dt->data->here = r;
544887Schin }
554887Schin return r ? _DTOBJ(r,lk) : NIL(Void_t*);
564887Schin }
574887Schin else if(type&(DT_DELETE|DT_DETACH))
584887Schin { if((dt->data->type&DT_LIST) || !(r = dt->data->head))
594887Schin return NIL(Void_t*);
604887Schin else goto dt_delete;
614887Schin }
624887Schin else if(type&DT_CLEAR)
634887Schin { if(disc->freef || disc->link < 0)
644887Schin { for(r = dt->data->head; r; r = t)
654887Schin { t = r->right;
664887Schin if(disc->freef)
674887Schin (*disc->freef)(dt,_DTOBJ(r,lk),disc);
684887Schin if(disc->link < 0)
694887Schin (*dt->memoryf)(dt,(Void_t*)r,0,disc);
704887Schin }
714887Schin }
724887Schin dt->data->head = dt->data->here = NIL(Dtlink_t*);
734887Schin dt->data->size = 0;
744887Schin return NIL(Void_t*);
754887Schin }
764887Schin else return NIL(Void_t*);
774887Schin }
784887Schin
794887Schin if(type&(DT_INSERT|DT_ATTACH))
804887Schin { if(disc->makef && (type&DT_INSERT) &&
814887Schin !(obj = (*disc->makef)(dt,obj,disc)) )
824887Schin return NIL(Void_t*);
834887Schin if(lk >= 0)
844887Schin r = _DTLNK(obj,lk);
854887Schin else
864887Schin { r = (Dtlink_t*)(*dt->memoryf)
874887Schin (dt,NIL(Void_t*),sizeof(Dthold_t),disc);
884887Schin if(r)
894887Schin ((Dthold_t*)r)->obj = obj;
904887Schin else
914887Schin { if(disc->makef && disc->freef && (type&DT_INSERT))
924887Schin (*disc->freef)(dt,obj,disc);
934887Schin return NIL(Void_t*);
944887Schin }
954887Schin }
964887Schin
974887Schin if(dt->data->type&DT_LIST)
984887Schin { if((t = dt->data->here) && t != dt->data->head)
994887Schin { r->left = t->left;
1004887Schin t->left->right = r;
1014887Schin r->right = t;
1024887Schin t->left = r;
1034887Schin }
1044887Schin else goto dt_stack;
1054887Schin }
1064887Schin else if(dt->data->type&DT_STACK)
1074887Schin { dt_stack:
1084887Schin r->right = t = dt->data->head;
1094887Schin if(t)
1104887Schin { r->left = t->left;
1114887Schin t->left = r;
1124887Schin }
1134887Schin else r->left = r;
1144887Schin dt->data->head = r;
1154887Schin }
1164887Schin else /* if(dt->data->type&DT_QUEUE) */
1174887Schin { if((t = dt->data->head) )
1184887Schin { t->left->right = r;
1194887Schin r->left = t->left;
1204887Schin t->left = r;
1214887Schin }
1224887Schin else
1234887Schin { dt->data->head = r;
1244887Schin r->left = r;
1254887Schin }
1264887Schin r->right = NIL(Dtlink_t*);
1274887Schin }
1284887Schin
1294887Schin if(dt->data->size >= 0)
1304887Schin dt->data->size += 1;
1314887Schin
1324887Schin dt->data->here = r;
1334887Schin return _DTOBJ(r,lk);
1344887Schin }
1354887Schin
1364887Schin if((type&DT_MATCH) || !(r = dt->data->here) || _DTOBJ(r,lk) != obj)
1374887Schin { key = (type&DT_MATCH) ? obj : _DTKEY(obj,ky,sz);
1384887Schin for(r = dt->data->head; r; r = r->right)
1394887Schin { k = _DTOBJ(r,lk); k = _DTKEY(k,ky,sz);
1404887Schin if(_DTCMP(dt,key,k,disc,cmpf,sz) == 0)
1414887Schin break;
1424887Schin }
1434887Schin }
1444887Schin
1454887Schin if(!r)
1464887Schin return NIL(Void_t*);
1474887Schin dt->type |= DT_FOUND;
1484887Schin
1494887Schin if(type&(DT_DELETE|DT_DETACH))
1504887Schin { dt_delete:
1514887Schin if(r->right)
1524887Schin r->right->left = r->left;
1534887Schin if(r == (t = dt->data->head) )
1544887Schin { dt->data->head = r->right;
1554887Schin if(dt->data->head)
1564887Schin dt->data->head->left = t->left;
1574887Schin }
1584887Schin else
1594887Schin { r->left->right = r->right;
1604887Schin if(r == t->left)
1614887Schin t->left = r->left;
1624887Schin }
1634887Schin
1644887Schin dt->data->here = r == dt->data->here ? r->right : NIL(Dtlink_t*);
1654887Schin dt->data->size -= 1;
1664887Schin
1674887Schin obj = _DTOBJ(r,lk);
1684887Schin if(disc->freef && (type&DT_DELETE))
1694887Schin (*disc->freef)(dt,obj,disc);
1704887Schin if(disc->link < 0)
1714887Schin (*dt->memoryf)(dt,(Void_t*)r,0,disc);
1724887Schin return obj;
1734887Schin }
1744887Schin else if(type&DT_NEXT)
1754887Schin r = r->right;
1764887Schin else if(type&DT_PREV)
1774887Schin r = r == dt->data->head ? NIL(Dtlink_t*) : r->left;
1784887Schin
1794887Schin dt->data->here = r;
1804887Schin return r ? _DTOBJ(r,lk) : NIL(Void_t*);
1814887Schin }
1824887Schin
1834887Schin #ifndef KPVDEL /* to be remove next round */
1844887Schin #define static
1854887Schin #endif
1864887Schin static Dtmethod_t _Dtlist = { dtlist, DT_LIST };
1874887Schin static Dtmethod_t _Dtstack = { dtlist, DT_STACK };
1884887Schin static Dtmethod_t _Dtqueue = { dtlist, DT_QUEUE };
1894887Schin
1904887Schin __DEFINE__(Dtmethod_t*,Dtlist,&_Dtlist);
1914887Schin __DEFINE__(Dtmethod_t*,Dtstack,&_Dtstack);
1924887Schin __DEFINE__(Dtmethod_t*,Dtqueue,&_Dtqueue);
1934887Schin
1944887Schin #ifdef NoF
1954887Schin NoF(dtlist)
1964887Schin #endif
197