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