/misc/src/release/graphviz-2.18-1/src/graphviz-2.18/lib/cdt/dtlist.c

Go to the documentation of this file.
00001 /* $Id: dtlist.c,v 1.1.1.1 2004/12/23 04:04:00 ellson Exp $ $Revision: 1.1.1.1 $ */
00002 /* vim:set shiftwidth=4 ts=8: */
00003 
00004 /**********************************************************
00005 *      This software is part of the graphviz package      *
00006 *                http://www.graphviz.org/                 *
00007 *                                                         *
00008 *            Copyright (c) 1994-2004 AT&T Corp.           *
00009 *                and is licensed under the                *
00010 *            Common Public License, Version 1.0           *
00011 *                      by AT&T Corp.                      *
00012 *                                                         *
00013 *        Information and Software Systems Research        *
00014 *              AT&T Research, Florham Park NJ             *
00015 **********************************************************/
00016 
00017 #include        "dthdr.h"
00018 
00019 #ifdef DMALLOC
00020 #include "dmalloc.h"
00021 #endif
00022 
00023 /*      List, Stack, Queue.
00024 **
00025 **      Written by Kiem-Phong Vo (05/25/96)
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 {                /* if(dt->data->type&DT_QUEUE) */
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                  /* to be remove next round */
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);

Generated on Mon Mar 31 19:03:23 2008 for Graphviz by  doxygen 1.5.1