1 /***********************************************************************
3 * This software is part of the ast package *
4 * Copyright (c) 1985-2010 AT&T Intellectual Property *
5 * and is licensed under the *
6 * Common Public License, Version 1.0 *
7 * by AT&T Intellectual Property *
9 * A copy of the License is available at *
10 * http://www.opensource.org/licenses/cpl1.0.txt *
11 * (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
13 * Information and Software Systems Research *
17 * Glenn Fowler <gsf@research.att.com> *
18 * David Korn <dgk@research.att.com> *
19 * Phong Vo <kpv@research.att.com> *
21 ***********************************************************************/
24 /* List, Stack, Queue.
26 ** Written by Kiem-Phong Vo (05/25/96)
30 static Void_t
* dtlist(reg Dt_t
* dt
, reg Void_t
* obj
, reg
int type
)
32 static Void_t
* dtlist(dt
, obj
, type
)
45 disc
= dt
->disc
; _DTDSC(disc
,ky
,sz
,lk
,cmpf
);
46 dt
->type
&= ~DT_FOUND
;
49 { if(type
&(DT_LAST
|DT_FIRST
) )
50 { if((r
= dt
->data
->head
) )
55 return r
? _DTOBJ(r
,lk
) : NIL(Void_t
*);
57 else if(type
&(DT_DELETE
|DT_DETACH
))
58 { if((dt
->data
->type
&DT_LIST
) || !(r
= dt
->data
->head
))
62 else if(type
&DT_CLEAR
)
63 { if(disc
->freef
|| disc
->link
< 0)
64 { for(r
= dt
->data
->head
; r
; r
= t
)
67 (*disc
->freef
)(dt
,_DTOBJ(r
,lk
),disc
);
69 (*dt
->memoryf
)(dt
,(Void_t
*)r
,0,disc
);
72 dt
->data
->head
= dt
->data
->here
= NIL(Dtlink_t
*);
76 else return NIL(Void_t
*);
79 if(type
&(DT_INSERT
|DT_ATTACH
))
80 { if(disc
->makef
&& (type
&DT_INSERT
) &&
81 !(obj
= (*disc
->makef
)(dt
,obj
,disc
)) )
86 { r
= (Dtlink_t
*)(*dt
->memoryf
)
87 (dt
,NIL(Void_t
*),sizeof(Dthold_t
),disc
);
89 ((Dthold_t
*)r
)->obj
= obj
;
91 { if(disc
->makef
&& disc
->freef
&& (type
&DT_INSERT
))
92 (*disc
->freef
)(dt
,obj
,disc
);
97 if(dt
->data
->type
&DT_LIST
)
98 { if((t
= dt
->data
->here
) && t
!= dt
->data
->head
)
106 else if(dt
->data
->type
&DT_STACK
)
108 r
->right
= t
= dt
->data
->head
;
116 else /* if(dt->data->type&DT_QUEUE) */
117 { if((t
= dt
->data
->head
) )
118 { t
->left
->right
= r
;
123 { dt
->data
->head
= r
;
126 r
->right
= NIL(Dtlink_t
*);
129 if(dt
->data
->size
>= 0)
136 if((type
&DT_MATCH
) || !(r
= dt
->data
->here
) || _DTOBJ(r
,lk
) != obj
)
137 { key
= (type
&DT_MATCH
) ? obj
: _DTKEY(obj
,ky
,sz
);
138 for(r
= dt
->data
->head
; r
; r
= r
->right
)
139 { k
= _DTOBJ(r
,lk
); k
= _DTKEY(k
,ky
,sz
);
140 if(_DTCMP(dt
,key
,k
,disc
,cmpf
,sz
) == 0)
147 dt
->type
|= DT_FOUND
;
149 if(type
&(DT_DELETE
|DT_DETACH
))
152 r
->right
->left
= r
->left
;
153 if(r
== (t
= dt
->data
->head
) )
154 { dt
->data
->head
= r
->right
;
156 dt
->data
->head
->left
= t
->left
;
159 { r
->left
->right
= r
->right
;
164 dt
->data
->here
= r
== dt
->data
->here
? r
->right
: NIL(Dtlink_t
*);
168 if(disc
->freef
&& (type
&DT_DELETE
))
169 (*disc
->freef
)(dt
,obj
,disc
);
171 (*dt
->memoryf
)(dt
,(Void_t
*)r
,0,disc
);
174 else if(type
&DT_NEXT
)
176 else if(type
&DT_PREV
)
177 r
= r
== dt
->data
->head
? NIL(Dtlink_t
*) : r
->left
;
180 return r
? _DTOBJ(r
,lk
) : NIL(Void_t
*);
183 #ifndef KPVDEL /* to be remove next round */
186 static Dtmethod_t _Dtlist
= { dtlist
, DT_LIST
};
187 static Dtmethod_t _Dtstack
= { dtlist
, DT_STACK
};
188 static Dtmethod_t _Dtqueue
= { dtlist
, DT_QUEUE
};
190 __DEFINE__(Dtmethod_t
*,Dtlist
,&_Dtlist
);
191 __DEFINE__(Dtmethod_t
*,Dtstack
,&_Dtstack
);
192 __DEFINE__(Dtmethod_t
*,Dtqueue
,&_Dtqueue
);