00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #include "dthdr.h"
00018
00019 #ifdef DMALLOC
00020 #include "dmalloc.h"
00021 #endif
00022
00023
00024
00025
00026
00027
00028 #if __STD_C
00029 static Void_t *dtlist(reg Dt_t * dt, reg Void_t * obj, reg int type)
00030 #else
00031 static Void_t *dtlist(dt, obj, type)
00032 reg Dt_t *dt;
00033 reg Void_t *obj;
00034 reg int type;
00035 #endif
00036 {
00037 reg int lk, sz, ky;
00038 reg Dtcompar_f cmpf;
00039 reg Dtdisc_t *disc;
00040 reg Dtlink_t *r, *t;
00041 reg Void_t *key, *k;
00042
00043 INITDISC(dt, disc, ky, sz, lk, cmpf);
00044
00045 UNFLATTEN(dt);
00046
00047 if (!obj) {
00048 if (type & (DT_LAST | DT_FIRST)) {
00049 if ((r = dt->data->head)) {
00050 if (type & DT_LAST)
00051 r = r->left;
00052 dt->data->here = r;
00053 }
00054 return r ? OBJ(r, lk) : NIL(Void_t *);
00055 } else if (type & (DT_DELETE | DT_DETACH)) {
00056 if ((dt->data->type & DT_LIST) || !(r = dt->data->head))
00057 return NIL(Void_t *);
00058 else
00059 goto dt_delete;
00060 } else if (type & DT_CLEAR) {
00061 if (disc->freef || disc->link < 0) {
00062 for (r = dt->data->head; r; r = t) {
00063 t = r->right;
00064 if (disc->freef)
00065 (*disc->freef) (dt, OBJ(r, lk), disc);
00066 if (disc->link < 0)
00067 (*dt->memoryf) (dt, (Void_t *) r, 0, disc);
00068 }
00069 }
00070 dt->data->head = dt->data->here = NIL(Dtlink_t *);
00071 dt->data->size = 0;
00072 return NIL(Void_t *);
00073 } else
00074 return NIL(Void_t *);
00075 }
00076
00077 if (type & (DT_INSERT | DT_ATTACH)) {
00078 if (disc->makef && (type & DT_INSERT) &&
00079 !(obj = (*disc->makef) (dt, obj, disc)))
00080 return NIL(Void_t *);
00081 if (lk >= 0)
00082 r = ELT(obj, lk);
00083 else {
00084 r = (Dtlink_t *) (*dt->memoryf)
00085 (dt, NIL(Void_t *), sizeof(Dthold_t), disc);
00086 if (r)
00087 ((Dthold_t *) r)->obj = obj;
00088 else {
00089 if (disc->makef && disc->freef && (type & DT_INSERT))
00090 (*disc->freef) (dt, obj, disc);
00091 return NIL(Void_t *);
00092 }
00093 }
00094
00095 if (dt->data->type & DT_LIST) {
00096 if ((t = dt->data->here) && t != dt->data->head) {
00097 r->left = t->left;
00098 t->left->right = r;
00099 r->right = t;
00100 t->left = r;
00101 } else
00102 goto dt_stack;
00103 } else if (dt->data->type & DT_STACK) {
00104 dt_stack:
00105 r->right = t = dt->data->head;
00106 if (t) {
00107 r->left = t->left;
00108 t->left = r;
00109 } else
00110 r->left = r;
00111 dt->data->head = r;
00112 } else {
00113 if ((t = dt->data->head)) {
00114 t->left->right = r;
00115 r->left = t->left;
00116 t->left = r;
00117 } else {
00118 dt->data->head = r;
00119 r->left = r;
00120 }
00121 r->right = NIL(Dtlink_t *);
00122 }
00123
00124 if (dt->data->size >= 0)
00125 dt->data->size += 1;
00126
00127 dt->data->here = r;
00128 return OBJ(r, lk);
00129 }
00130
00131 if ((type & DT_MATCH) || !(r = dt->data->here) || OBJ(r, lk) != obj) {
00132 key = (type & DT_MATCH) ? obj : KEY(obj, ky, sz);
00133 for (r = dt->data->head; r; r = r->right) {
00134 k = OBJ(r, lk);
00135 k = KEY(k, ky, sz);
00136 if (CMP(dt, key, k, disc, cmpf, sz) == 0)
00137 break;
00138 }
00139 }
00140
00141 if (!r)
00142 return NIL(Void_t *);
00143
00144 if (type & (DT_DELETE | DT_DETACH)) {
00145 dt_delete:
00146 if (r->right)
00147 r->right->left = r->left;
00148 if (r == (t = dt->data->head)) {
00149 dt->data->head = r->right;
00150 if (dt->data->head)
00151 dt->data->head->left = t->left;
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 = OBJ(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 } else if (type & DT_NEXT)
00168 r = r->right;
00169 else if (type & DT_PREV)
00170 r = r == dt->data->head ? NIL(Dtlink_t *) : r->left;
00171
00172 dt->data->here = r;
00173 return r ? OBJ(r, lk) : NIL(Void_t *);
00174 }
00175
00176 #ifndef KPVDEL
00177 #define static
00178 #endif
00179 static Dtmethod_t _Dtlist = { dtlist, DT_LIST };
00180 static Dtmethod_t _Dtstack = { dtlist, DT_STACK };
00181 static Dtmethod_t _Dtqueue = { dtlist, DT_QUEUE };
00182
00183 __DEFINE__(Dtmethod_t *, Dtlist, &_Dtlist);
00184 __DEFINE__(Dtmethod_t *, Dtstack, &_Dtstack);
00185 __DEFINE__(Dtmethod_t *, Dtqueue, &_Dtqueue);