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