/misc/src/release/graphviz-2.18-1/src/graphviz-2.18/lib/circogen/nodelist.c

Go to the documentation of this file.
00001 /* $Id: nodelist.c,v 1.1.1.1 2004/12/23 04:04:30 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 
00018 #include        "nodelist.h"
00019 #include        "circular.h"
00020 #include        <assert.h>
00021 
00022 static nodelistitem_t *init_nodelistitem(Agnode_t * n)
00023 {
00024     nodelistitem_t *p = NEW(nodelistitem_t);
00025     p->curr = n;
00026     return p;
00027 }
00028 
00029 nodelist_t *mkNodelist()
00030 {
00031     nodelist_t *list = NEW(nodelist_t);
00032     return list;
00033 }
00034 
00035 void freeNodelist(nodelist_t * list)
00036 {
00037     nodelistitem_t *temp;
00038     nodelistitem_t *next;
00039 
00040     if (!list)
00041         return;
00042 
00043     for (temp = list->first; temp; temp = next) {
00044         next = temp->next;
00045         free(temp);
00046     }
00047     free(list);
00048 }
00049 
00050 /* appendNodelist:
00051  * Add node after one.
00052  * If one == NULL, add n to end.
00053  */
00054 void appendNodelist(nodelist_t * list, nodelistitem_t * one, Agnode_t * n)
00055 {
00056     nodelistitem_t *np = init_nodelistitem(n);
00057 
00058     list->sz++;
00059     if (!one)
00060         one = list->last;
00061     if (one == list->last) {
00062         if (one)
00063             one->next = np;
00064         else
00065             list->first = np;
00066         np->prev = one;
00067         np->next = NULL;
00068         list->last = np;
00069     } else {
00070         nodelistitem_t *temp = one->next;
00071         one->next = np;
00072         np->prev = one;
00073         temp->prev = np;
00074         np->next = temp;
00075     }
00076 }
00077 
00078 #ifdef OLD
00079 /* addNodelist:
00080  * Adds node to end of list if not already present.
00081  */
00082 void addNodelist(nodelist_t * list, Agnode_t * n)
00083 {
00084     nodelistitem_t *temp;
00085     nodelistitem_t *item = 0;
00086 
00087     for (temp = list->first; temp; temp = temp->next) {
00088         if (n == temp->curr) {
00089             item = temp;
00090             break;
00091         }
00092     }
00093 
00094     if (item)
00095         return;
00096 
00097     item = init_nodelistitem(n);
00098     if (list->last) {
00099         list->last->next = item;
00100         item->prev = list->last;
00101     } else
00102         list->first = item;
00103     list->last = item;
00104     list->sz++;
00105 }
00106 
00107 void removeNodelist(nodelist_t * list, Agnode_t * n)
00108 {
00109     nodelistitem_t *temp;
00110 
00111     for (temp = list->first; temp; temp = temp->next) {
00112         if (n == temp->curr) {
00113             list->sz--;
00114             if (temp->prev == NULL) {   /* the first node */
00115                 list->first = temp->next;
00116             } else {
00117                 temp->prev->next = temp->next;
00118             }
00119             if (temp == list->last) {   /* the last node */
00120                 list->last = temp->prev;
00121             } else {
00122                 temp->next->prev = temp->prev;
00123             }
00124             free(temp);
00125             return;
00126         }
00127     }
00128 }
00129 #endif
00130 
00131 /* reverseNodelist;
00132  * Destructively reverse a list.
00133  */
00134 nodelist_t *reverseNodelist(nodelist_t * list)
00135 {
00136     nodelistitem_t *temp;
00137     nodelistitem_t *p;
00138 
00139     for (p = list->first; p; p = p->prev) {
00140         temp = p->next;
00141         p->next = p->prev;
00142         p->prev = temp;
00143     }
00144     temp = list->last;
00145     list->last = list->first;
00146     list->first = temp;
00147     return list;
00148 }
00149 
00150 /* realignNodelist:
00151  * Make np new front of list, with current last hooked to
00152  * current first. I.e., make list circular, then cut between
00153  * np and np->prev.
00154  */
00155 void realignNodelist(nodelist_t * list, nodelistitem_t * np)
00156 {
00157     nodelistitem_t *temp;
00158     nodelistitem_t *prev;
00159 
00160     if (np == list->first)
00161         return;
00162 
00163     temp = list->first;
00164     prev = np->prev;
00165 
00166     list->first = np;
00167     np->prev = NULL;
00168     list->last->next = temp;
00169     temp->prev = list->last;
00170     list->last = prev;
00171     prev->next = NULL;
00172 }
00173 
00174 /* cloneNodelist:
00175  * Create a copy of list.
00176  */
00177 nodelist_t *cloneNodelist(nodelist_t * list)
00178 {
00179     nodelist_t *newlist = mkNodelist();
00180     nodelistitem_t *temp;
00181     nodelistitem_t *prev = 0;
00182 
00183     for (temp = list->first; temp; temp = temp->next) {
00184         appendNodelist(newlist, prev, temp->curr);
00185         prev = newlist->last;
00186     }
00187     return newlist;
00188 }
00189 
00190 /* insertNodelist:
00191  * Remove cn. Then, insert cn before neighbor if pos == 0 and 
00192  * after neighbor otherwise.
00193  */
00194 void
00195 insertNodelist(nodelist_t * list, Agnode_t * cn, Agnode_t * neighbor,
00196                int pos)
00197 {
00198     nodelistitem_t *temp;
00199     nodelistitem_t *prev;
00200     nodelistitem_t *next;
00201     nodelistitem_t *actual = 0;
00202 
00203     for (temp = list->first; temp; temp = temp->next) {
00204         if (temp->curr == cn) {
00205             actual = temp;
00206             prev = actual->prev;
00207             next = actual->next;
00208             if (prev)           /* not first */
00209                 prev->next = next;
00210             else
00211                 list->first = next;
00212 
00213             if (next)           /* not last */
00214                 next->prev = prev;
00215             else
00216                 list->last = prev;
00217             break;
00218         }
00219     }
00220     assert(actual);
00221 
00222     prev = NULL;
00223     for (temp = list->first; temp; temp = temp->next) {
00224         if (temp->curr == neighbor) {
00225             if (pos == 0) {
00226                 if (temp == list->first) {
00227                     list->first = actual;
00228                     actual->next = temp;
00229                     actual->prev = NULL;
00230                     temp->prev = actual;
00231                     return;
00232                 }
00233                 prev->next = actual;
00234                 actual->prev = prev;
00235                 actual->next = temp;
00236                 temp->prev = actual;
00237                 return;
00238             } else {
00239                 if (temp == list->last) {
00240                     list->last = actual;
00241                     actual->next = NULL;
00242                     actual->prev = temp;
00243                     temp->next = actual;
00244                     return;
00245                 }
00246                 actual->prev = temp;
00247                 actual->next = temp->next;
00248                 temp->next->prev = actual;
00249                 temp->next = actual;
00250                 return;
00251             }
00252             break;
00253         }
00254         prev = temp;
00255     }
00256 }
00257 
00258 int sizeNodelist(nodelist_t * list)
00259 {
00260     return list->sz;
00261 #ifdef OLD
00262     int i = 0;
00263     nodelistitem_t *temp = NULL;
00264 
00265     temp = list->first;
00266     while (temp) {
00267         i++;
00268         temp = temp->next;
00269     }
00270     return i;
00271 #endif
00272 }
00273 
00274 #ifdef OLD
00275 /* node_exists:
00276  * Return true if node is in list.
00277  */
00278 int node_exists(nodelist_t * list, Agnode_t * n)
00279 {
00280     nodelistitem_t *temp;
00281 
00282     for (temp = list->first; temp; temp = temp->next) {
00283         if (temp->curr == n) {
00284             return 1;
00285         }
00286     }
00287     return 0;
00288 }
00289 
00290 /* nodename_exists:
00291  * Return true if node with given name is in list.
00292  * Assumes n == np->name for some node np;
00293  */
00294 int nodename_exists(nodelist_t * list, char *n)
00295 {
00296     nodelistitem_t *temp;
00297 
00298     temp = list->first;
00299 
00300     for (temp = list->first; temp; temp = temp->next) {
00301         if (temp->curr->name == n) {
00302             return 1;
00303         }
00304     }
00305     return 0;
00306 }
00307 #endif
00308 
00309 /* node_position:
00310  * Returns index of node n in list, starting at 0.
00311  * Returns -1 if not in list.
00312  */
00313 int node_position(nodelist_t * list, Agnode_t * n)
00314 {
00315     return POSITION(n);
00316 #ifdef OLD
00317     nodelistitem_t *temp;
00318     int i = 0;
00319     char *name = n->name;
00320 
00321     for (temp = list->first; temp; temp = temp->next) {
00322         if (temp->curr->name == name) {
00323             return i;
00324         }
00325         i++;
00326     }
00327     return -1;
00328 #endif
00329 }
00330 
00331 /* concatNodelist:
00332  * attach l2 to l1.
00333  */
00334 static void concatNodelist(nodelist_t * l1, nodelist_t * l2)
00335 {
00336     if (l2->first) {
00337         if (l2->first) {
00338             l1->last->next = l2->first;
00339             l2->first->prev = l1->last;
00340             l1->last = l2->last;
00341             l1->sz += l2->sz;
00342         } else {
00343             *l1 = *l2;
00344         }
00345     }
00346 }
00347 
00348 /* reverse_append;
00349  * Create l1 @ (rev l2)
00350  * Destroys and frees l2.
00351  */
00352 void reverseAppend(nodelist_t * l1, nodelist_t * l2)
00353 {
00354     l2 = reverseNodelist(l2);
00355     concatNodelist(l1, l2);
00356     free(l2);
00357 }
00358 
00359 #ifdef DEBUG
00360 void printNodelist(nodelist_t * list)
00361 {
00362     nodelistitem_t *temp = NULL;
00363 
00364     temp = list->first;
00365     while (temp != NULL) {
00366         fprintf(stderr, "%s ", temp->curr->name);
00367         temp = temp->next;
00368     }
00369     fputs("\n", stderr);
00370 }
00371 #endif

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