| 1 | #include	"dthdr.h" | 
|---|
| 2 |  | 
|---|
| 3 | /*	List, Deque, Stack, Queue. | 
|---|
| 4 | ** | 
|---|
| 5 | **	Written by Kiem-Phong Vo (05/25/96) | 
|---|
| 6 | */ | 
|---|
| 7 |  | 
|---|
| 8 | static void* dtlist(reg Dt_t* dt, reg void* obj, reg int type) | 
|---|
| 9 | { | 
|---|
| 10 | reg int		lk, sz, ky; | 
|---|
| 11 | reg Dtcompar_f	cmpf; | 
|---|
| 12 | reg Dtdisc_t*	disc; | 
|---|
| 13 | reg Dtlink_t	*r, *t; | 
|---|
| 14 | reg void	*key, *k; | 
|---|
| 15 |  | 
|---|
| 16 | UNFLATTEN(dt); | 
|---|
| 17 | disc = dt->disc; _DTDSC(disc,ky,sz,lk,cmpf); | 
|---|
| 18 | dt->type &= ~DT_FOUND; | 
|---|
| 19 |  | 
|---|
| 20 | if(!obj) | 
|---|
| 21 | {	if(type&(DT_LAST|DT_FIRST) ) | 
|---|
| 22 | {	if((r = dt->data->head) ) | 
|---|
| 23 | {	if(type&DT_LAST) | 
|---|
| 24 | r = r->left; | 
|---|
| 25 | dt->data->here = r; | 
|---|
| 26 | } | 
|---|
| 27 | return r ? _DTOBJ(r,lk) : NIL(void*); | 
|---|
| 28 | } | 
|---|
| 29 | else if(type&(DT_DELETE|DT_DETACH)) | 
|---|
| 30 | {	if((dt->data->type&(DT_LIST|DT_DEQUE)) || !(r = dt->data->head)) | 
|---|
| 31 | return NIL(void*); | 
|---|
| 32 | else	goto dt_delete; | 
|---|
| 33 | } | 
|---|
| 34 | else if(type&DT_CLEAR) | 
|---|
| 35 | {	if(disc->freef || disc->link < 0) | 
|---|
| 36 | {	for(r = dt->data->head; r; r = t) | 
|---|
| 37 | {	t = r->right; | 
|---|
| 38 | if(disc->freef) | 
|---|
| 39 | (*disc->freef)(dt,_DTOBJ(r,lk),disc); | 
|---|
| 40 | if(disc->link < 0) | 
|---|
| 41 | (*dt->memoryf)(dt,(void*)r,0,disc); | 
|---|
| 42 | } | 
|---|
| 43 | } | 
|---|
| 44 | dt->data->head = dt->data->here = NIL(Dtlink_t*); | 
|---|
| 45 | dt->data->size = 0; | 
|---|
| 46 | return NIL(void*); | 
|---|
| 47 | } | 
|---|
| 48 | else	return NIL(void*); | 
|---|
| 49 | } | 
|---|
| 50 |  | 
|---|
| 51 | if(type&(DT_INSERT|DT_ATTACH)) | 
|---|
| 52 | {	if(disc->makef && (type&DT_INSERT) && | 
|---|
| 53 | !(obj = (*disc->makef)(dt,obj,disc)) ) | 
|---|
| 54 | return NIL(void*); | 
|---|
| 55 | if(lk >= 0) | 
|---|
| 56 | r = _DTLNK(obj,lk); | 
|---|
| 57 | else | 
|---|
| 58 | {	r = (Dtlink_t*)(*dt->memoryf) | 
|---|
| 59 | (dt,NIL(void*),sizeof(Dthold_t),disc); | 
|---|
| 60 | if(r) | 
|---|
| 61 | ((Dthold_t*)r)->obj = obj; | 
|---|
| 62 | else | 
|---|
| 63 | {	if(disc->makef && disc->freef && (type&DT_INSERT)) | 
|---|
| 64 | (*disc->freef)(dt,obj,disc); | 
|---|
| 65 | return NIL(void*); | 
|---|
| 66 | } | 
|---|
| 67 | } | 
|---|
| 68 |  | 
|---|
| 69 | if(dt->data->type&DT_DEQUE) | 
|---|
| 70 | {	if(type&DT_APPEND) | 
|---|
| 71 | goto dt_queue; | 
|---|
| 72 | else	goto dt_stack; | 
|---|
| 73 | } | 
|---|
| 74 | else if(dt->data->type&DT_LIST) | 
|---|
| 75 | {	if(type&DT_APPEND) | 
|---|
| 76 | {	if(!(t = dt->data->here) || !t->right) | 
|---|
| 77 | goto dt_queue; | 
|---|
| 78 | r->right = t->right; | 
|---|
| 79 | r->right->left = r; | 
|---|
| 80 | r->left = t; | 
|---|
| 81 | r->left->right = r; | 
|---|
| 82 | } | 
|---|
| 83 | else | 
|---|
| 84 | {	if(!(t = dt->data->here) || t == dt->data->head) | 
|---|
| 85 | goto dt_stack; | 
|---|
| 86 | r->left = t->left; | 
|---|
| 87 | r->left->right = r; | 
|---|
| 88 | r->right = t; | 
|---|
| 89 | r->right->left = r; | 
|---|
| 90 | } | 
|---|
| 91 | } | 
|---|
| 92 | else if(dt->data->type&DT_STACK) | 
|---|
| 93 | { dt_stack: | 
|---|
| 94 | r->right = t = dt->data->head; | 
|---|
| 95 | if(t) | 
|---|
| 96 | {	r->left = t->left; | 
|---|
| 97 | t->left = r; | 
|---|
| 98 | } | 
|---|
| 99 | else	r->left = r; | 
|---|
| 100 | dt->data->head = r; | 
|---|
| 101 | } | 
|---|
| 102 | else /* if(dt->data->type&DT_QUEUE) */ | 
|---|
| 103 | { dt_queue: | 
|---|
| 104 | if((t = dt->data->head) ) | 
|---|
| 105 | {	t->left->right = r; | 
|---|
| 106 | r->left = t->left; | 
|---|
| 107 | t->left = r; | 
|---|
| 108 | } | 
|---|
| 109 | else | 
|---|
| 110 | {	dt->data->head = r; | 
|---|
| 111 | r->left = r; | 
|---|
| 112 | } | 
|---|
| 113 | r->right = NIL(Dtlink_t*); | 
|---|
| 114 | } | 
|---|
| 115 |  | 
|---|
| 116 | if(dt->data->size >= 0) | 
|---|
| 117 | dt->data->size += 1; | 
|---|
| 118 |  | 
|---|
| 119 | dt->data->here = r; | 
|---|
| 120 | return _DTOBJ(r,lk); | 
|---|
| 121 | } | 
|---|
| 122 |  | 
|---|
| 123 | if((type&DT_MATCH) || !(r = dt->data->here) || _DTOBJ(r,lk) != obj) | 
|---|
| 124 | {	key = (type&DT_MATCH) ? obj : _DTKEY(obj,ky,sz); | 
|---|
| 125 | for(r = dt->data->head; r; r = r->right) | 
|---|
| 126 | {	k = _DTOBJ(r,lk); k = _DTKEY(k,ky,sz); | 
|---|
| 127 | if(_DTCMP(dt,key,k,disc,cmpf,sz) == 0) | 
|---|
| 128 | break; | 
|---|
| 129 | } | 
|---|
| 130 | } | 
|---|
| 131 |  | 
|---|
| 132 | if(!r) | 
|---|
| 133 | return NIL(void*); | 
|---|
| 134 | dt->type |= DT_FOUND; | 
|---|
| 135 |  | 
|---|
| 136 | if(type&(DT_DELETE|DT_DETACH)) | 
|---|
| 137 | { dt_delete: | 
|---|
| 138 | if(r->right) | 
|---|
| 139 | r->right->left = r->left; | 
|---|
| 140 | if(r == (t = dt->data->head) ) | 
|---|
| 141 | {	dt->data->head = r->right; | 
|---|
| 142 | if(dt->data->head) | 
|---|
| 143 | dt->data->head->left = t->left; | 
|---|
| 144 | } | 
|---|
| 145 | else | 
|---|
| 146 | {	r->left->right = r->right; | 
|---|
| 147 | if(r == t->left) | 
|---|
| 148 | t->left = r->left; | 
|---|
| 149 | } | 
|---|
| 150 |  | 
|---|
| 151 | dt->data->here = r == dt->data->here ? r->right : NIL(Dtlink_t*); | 
|---|
| 152 | dt->data->size -= 1; | 
|---|
| 153 |  | 
|---|
| 154 | obj = _DTOBJ(r,lk); | 
|---|
| 155 | if(disc->freef && (type&DT_DELETE)) | 
|---|
| 156 | (*disc->freef)(dt,obj,disc); | 
|---|
| 157 | if(disc->link < 0) | 
|---|
| 158 | (*dt->memoryf)(dt,(void*)r,0,disc); | 
|---|
| 159 | return obj; | 
|---|
| 160 | } | 
|---|
| 161 | else if(type&DT_NEXT) | 
|---|
| 162 | r = r->right; | 
|---|
| 163 | else if(type&DT_PREV) | 
|---|
| 164 | r = r == dt->data->head ? NIL(Dtlink_t*) : r->left; | 
|---|
| 165 |  | 
|---|
| 166 | dt->data->here = r; | 
|---|
| 167 | return r ? _DTOBJ(r,lk) : NIL(void*); | 
|---|
| 168 | } | 
|---|
| 169 |  | 
|---|
| 170 | #ifndef KPVDEL	/* to be remove next round */ | 
|---|
| 171 | #define static | 
|---|
| 172 | #endif | 
|---|
| 173 | static Dtmethod_t _Dtlist  = { dtlist, DT_LIST  }; | 
|---|
| 174 | static Dtmethod_t _Dtdeque  = { dtlist, DT_DEQUE  }; | 
|---|
| 175 | static Dtmethod_t _Dtstack = { dtlist, DT_STACK }; | 
|---|
| 176 | static Dtmethod_t _Dtqueue = { dtlist, DT_QUEUE }; | 
|---|
| 177 |  | 
|---|
| 178 | Dtmethod_t* Dtlist = &_Dtlist; | 
|---|
| 179 | Dtmethod_t* Dtdeque = &_Dtdeque; | 
|---|
| 180 | Dtmethod_t* Dtstack = &_Dtstack; | 
|---|
| 181 | Dtmethod_t* Dtqueue = &_Dtqueue; | 
|---|
| 182 |  | 
|---|
| 183 | #ifdef NoF | 
|---|
| 184 | NoF(dtlist) | 
|---|
| 185 | #endif | 
|---|
| 186 |  | 
|---|