|
Graphviz 2.29.20120208.0545
|
00001 #include "dthdr.h" 00002 00003 /* List, Deque, Stack, Queue. 00004 ** 00005 ** Written by Kiem-Phong Vo (05/25/96) 00006 */ 00007 00008 #if __STD_C 00009 static Void_t* dtlist(reg Dt_t* dt, reg Void_t* obj, reg int type) 00010 #else 00011 static Void_t* dtlist(dt, obj, type) 00012 reg Dt_t* dt; 00013 reg Void_t* obj; 00014 reg int type; 00015 #endif 00016 { 00017 reg int lk, sz, ky; 00018 reg Dtcompar_f cmpf; 00019 reg Dtdisc_t* disc; 00020 reg Dtlink_t *r, *t; 00021 reg Void_t *key, *k; 00022 00023 UNFLATTEN(dt); 00024 disc = dt->disc; _DTDSC(disc,ky,sz,lk,cmpf); 00025 dt->type &= ~DT_FOUND; 00026 00027 if(!obj) 00028 { if(type&(DT_LAST|DT_FIRST) ) 00029 { if((r = dt->data->head) ) 00030 { if(type&DT_LAST) 00031 r = r->left; 00032 dt->data->here = r; 00033 } 00034 return r ? _DTOBJ(r,lk) : NIL(Void_t*); 00035 } 00036 else if(type&(DT_DELETE|DT_DETACH)) 00037 { if((dt->data->type&(DT_LIST|DT_DEQUE)) || !(r = dt->data->head)) 00038 return NIL(Void_t*); 00039 else goto dt_delete; 00040 } 00041 else if(type&DT_CLEAR) 00042 { if(disc->freef || disc->link < 0) 00043 { for(r = dt->data->head; r; r = t) 00044 { t = r->right; 00045 if(disc->freef) 00046 (*disc->freef)(dt,_DTOBJ(r,lk),disc); 00047 if(disc->link < 0) 00048 (*dt->memoryf)(dt,(Void_t*)r,0,disc); 00049 } 00050 } 00051 dt->data->head = dt->data->here = NIL(Dtlink_t*); 00052 dt->data->size = 0; 00053 return NIL(Void_t*); 00054 } 00055 else return NIL(Void_t*); 00056 } 00057 00058 if(type&(DT_INSERT|DT_ATTACH)) 00059 { if(disc->makef && (type&DT_INSERT) && 00060 !(obj = (*disc->makef)(dt,obj,disc)) ) 00061 return NIL(Void_t*); 00062 if(lk >= 0) 00063 r = _DTLNK(obj,lk); 00064 else 00065 { r = (Dtlink_t*)(*dt->memoryf) 00066 (dt,NIL(Void_t*),sizeof(Dthold_t),disc); 00067 if(r) 00068 ((Dthold_t*)r)->obj = obj; 00069 else 00070 { if(disc->makef && disc->freef && (type&DT_INSERT)) 00071 (*disc->freef)(dt,obj,disc); 00072 return NIL(Void_t*); 00073 } 00074 } 00075 00076 if(dt->data->type&DT_DEQUE) 00077 { if(type&DT_APPEND) 00078 goto dt_queue; 00079 else goto dt_stack; 00080 } 00081 else if(dt->data->type&DT_LIST) 00082 { if(type&DT_APPEND) 00083 { if(!(t = dt->data->here) || !t->right) 00084 goto dt_queue; 00085 r->right = t->right; 00086 r->right->left = r; 00087 r->left = t; 00088 r->left->right = r; 00089 } 00090 else 00091 { if(!(t = dt->data->here) || t == dt->data->head) 00092 goto dt_stack; 00093 r->left = t->left; 00094 r->left->right = r; 00095 r->right = t; 00096 r->right->left = r; 00097 } 00098 } 00099 else if(dt->data->type&DT_STACK) 00100 { dt_stack: 00101 r->right = t = dt->data->head; 00102 if(t) 00103 { r->left = t->left; 00104 t->left = r; 00105 } 00106 else r->left = r; 00107 dt->data->head = r; 00108 } 00109 else /* if(dt->data->type&DT_QUEUE) */ 00110 { dt_queue: 00111 if((t = dt->data->head) ) 00112 { t->left->right = r; 00113 r->left = t->left; 00114 t->left = r; 00115 } 00116 else 00117 { dt->data->head = r; 00118 r->left = r; 00119 } 00120 r->right = NIL(Dtlink_t*); 00121 } 00122 00123 if(dt->data->size >= 0) 00124 dt->data->size += 1; 00125 00126 dt->data->here = r; 00127 return _DTOBJ(r,lk); 00128 } 00129 00130 if((type&DT_MATCH) || !(r = dt->data->here) || _DTOBJ(r,lk) != obj) 00131 { key = (type&DT_MATCH) ? obj : _DTKEY(obj,ky,sz); 00132 for(r = dt->data->head; r; r = r->right) 00133 { k = _DTOBJ(r,lk); k = _DTKEY(k,ky,sz); 00134 if(_DTCMP(dt,key,k,disc,cmpf,sz) == 0) 00135 break; 00136 } 00137 } 00138 00139 if(!r) 00140 return NIL(Void_t*); 00141 dt->type |= DT_FOUND; 00142 00143 if(type&(DT_DELETE|DT_DETACH)) 00144 { dt_delete: 00145 if(r->right) 00146 r->right->left = r->left; 00147 if(r == (t = dt->data->head) ) 00148 { dt->data->head = r->right; 00149 if(dt->data->head) 00150 dt->data->head->left = t->left; 00151 } 00152 else 00153 { r->left->right = r->right; 00154 if(r == t->left) 00155 t->left = r->left; 00156 } 00157 00158 dt->data->here = r == dt->data->here ? r->right : NIL(Dtlink_t*); 00159 dt->data->size -= 1; 00160 00161 obj = _DTOBJ(r,lk); 00162 if(disc->freef && (type&DT_DELETE)) 00163 (*disc->freef)(dt,obj,disc); 00164 if(disc->link < 0) 00165 (*dt->memoryf)(dt,(Void_t*)r,0,disc); 00166 return obj; 00167 } 00168 else if(type&DT_NEXT) 00169 r = r->right; 00170 else if(type&DT_PREV) 00171 r = r == dt->data->head ? NIL(Dtlink_t*) : r->left; 00172 00173 dt->data->here = r; 00174 return r ? _DTOBJ(r,lk) : NIL(Void_t*); 00175 } 00176 00177 #ifndef KPVDEL /* to be remove next round */ 00178 #define static 00179 #endif 00180 static Dtmethod_t _Dtlist = { dtlist, DT_LIST }; 00181 static Dtmethod_t _Dtdeque = { dtlist, DT_DEQUE }; 00182 static Dtmethod_t _Dtstack = { dtlist, DT_STACK }; 00183 static Dtmethod_t _Dtqueue = { dtlist, DT_QUEUE }; 00184 00185 __DEFINE__(Dtmethod_t*,Dtlist,&_Dtlist); 00186 __DEFINE__(Dtmethod_t*,Dtdeque,&_Dtdeque); 00187 __DEFINE__(Dtmethod_t*,Dtstack,&_Dtstack); 00188 __DEFINE__(Dtmethod_t*,Dtqueue,&_Dtqueue); 00189 00190 #ifdef NoF 00191 NoF(dtlist) 00192 #endif
1.7.4