Graphviz 2.29.20120208.0545
lib/graph/node.c
Go to the documentation of this file.
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 #include <limits.h>
00015 
00016 #include "libgraph.h"
00017 
00018 #ifdef DMALLOC
00019 #include "dmalloc.h"
00020 #endif
00021 
00022 Agnode_t *agfindnode(Agraph_t * g, char *name)
00023 {
00024     Agnode_t *rv;
00025 
00026     rv = (Agnode_t *) dtmatch(g->univ->node_dict, name);
00027     if (rv && (g != g->root))
00028         rv = (Agnode_t *) dtsearch(g->nodes, rv);
00029     return rv;
00030 }
00031 
00032 Agnode_t *agidnode(Agraph_t * g, int index)
00033 {
00034     Agnode_t *rv;
00035     rv = (Agnode_t *) dtmatch(g->nodes, &index);
00036     return rv;
00037 }
00038 
00039 Agnode_t *agnode(Agraph_t * g, char *name)
00040 {
00041     Agnode_t *n;
00042     if ((n = agfindnode(g->root, name)) == NULL) {
00043         n = agNEWnode(g, name, g->proto->n);
00044         dtinsert(g->univ->node_dict, n);
00045     }
00046     agINSnode(g, n);
00047     return n;
00048 }
00049 
00050 void agINSnode(Agraph_t * g, Agnode_t * n)
00051 {
00052     Agraph_t *meta;
00053     Agedge_t *e;
00054 
00055     if (agidnode(g, n->id))
00056         return;
00057     dtinsert(g->nodes, n);
00058     if (AG_IS_METAGRAPH(g) == FALSE) {
00059         meta = g->meta_node->graph;
00060         for (e = agfstin(meta, g->meta_node); e; e = agnxtin(meta, e))
00061             agINSnode(agusergraph(e->tail), n);
00062     }
00063 }
00064 
00065 void agDELnode(Agraph_t * g, Agnode_t * n)
00066 {
00067     Agedge_t *e, *f;
00068     Agraph_t *meta, *h;
00069 
00070     for (e = agfstedge(g, n); e; e = f) {
00071         f = agnxtedge(g, e, n);
00072         agDELedge(g, e);
00073     }
00074 
00075     if (AG_IS_METAGRAPH(g) == FALSE) {
00076         meta = g->meta_node->graph;
00077         for (e = agfstout(meta, g->meta_node); e; e = agnxtout(meta, e)) {
00078             h = agusergraph(e->head);
00079             if (dtsearch(h->nodes, n))
00080                 agDELnode(h, n);
00081         }
00082     }
00083     dtdelete(g->nodes, n);
00084     if (g == g->root)
00085         agFREEnode(n);
00086 }
00087 
00088 Agnode_t *agfstnode(Agraph_t * g)
00089 {
00090     return (Agnode_t *) dtfirst(g->nodes);
00091 }
00092 
00093 Agnode_t *agnxtnode(Agraph_t * g, Agnode_t * n)
00094 {
00095     return (Agnode_t *) dtnext(g->nodes, n);
00096 }
00097 
00098 Agnode_t *aglstnode(Agraph_t * g)
00099 {
00100     return (Agnode_t *) dtlast(g->nodes);
00101 }
00102 
00103 Agnode_t *agprvnode(Agraph_t * g, Agnode_t * n)
00104 {
00105     return (Agnode_t *) dtprev(g->nodes, n);
00106 }
00107 
00108 Agnode_t *agNEWnode(Agraph_t * subg, char *name, Agnode_t * proto)
00109 {
00110     int i, nobj;
00111     Agnode_t *n;
00112 
00113     n = (Agnode_t *) calloc(1, AG.node_nbytes);
00114     n->tag = TAG_NODE;
00115     n->name = agstrdup(name);
00116     n->id = subg->univ->max_node_id++;
00117     n->graph = subg->root;
00118     nobj = dtsize(subg->univ->nodeattr->dict);
00119     if (nobj) {
00120                 n->attr = N_NEW(nobj, char *);
00121                 n->didset = N_NEW((nobj + CHAR_BIT - 1) / CHAR_BIT, char);
00122         }
00123     else {
00124                 n->attr = NULL;
00125                 n->didset = NULL;
00126         }
00127     for (i = 0; i < nobj; i++)
00128                 n->attr[i] = agstrdup(proto ? proto->attr[i] :
00129                         subg->univ->nodeattr->list[i]->value);
00130     return n;
00131 }
00132 
00133 void agFREEnode(Agnode_t * n)
00134 {
00135     int i, nobj;
00136     Agdict_t *dict = agdictof(n);
00137 
00138     dict = dict;
00139     dtdelete(n->graph->univ->node_dict, n);
00140     TAG_OF(n) = -1;
00141     agstrfree(n->name);
00142     if (AG_IS_METAGRAPH(n->graph) == FALSE) {
00143         nobj = dtsize(n->graph->univ->nodeattr->dict);
00144         for (i = 0; i < nobj; i++)
00145             agstrfree(n->attr[i]);
00146     }
00147     free(n->attr);
00148         free(n->didset);
00149     free(n);
00150 }