#endif
#include <compile.h>
#include <assert.h>
+#ifdef USE_CGRAPH
+#include <cgraph.h>
+#else
#include <agraph.h>
+#endif
#include <error.h>
#include <actions.h>
#include <sfstr.h>
* Apply symbol to get field value of objp
* Assume objp != NULL
*/
-static int lookup(Expr_t * pgm, Agobj_t * objp, Exid_t * sym, Extype_t * v)
+static int lookup(Expr_t * pgm, Agobj_t * objp, Exid_t * sym, Extype_t * v,
+ Gpr_t *state)
{
if (sym->lex == ID) {
switch (sym->index) {
break;
case M_indegree:
if (AGTYPE(objp) == AGNODE)
+#ifdef USE_CGRAPH
+ v->integer = agdegree(state->curgraph, (Agnode_t *) objp, 1, 0);
+#else
v->integer = agdegree((Agnode_t *) objp, 1, 0);
+#endif
else {
error(ERROR_FATAL, "indegree of non-node");
return -1;
break;
case M_outdegree:
if (AGTYPE(objp) == AGNODE)
+#ifdef USE_CGRAPH
+ v->integer = agdegree(state->curgraph, (Agnode_t *) objp, 0, 1);
+#else
v->integer = agdegree((Agnode_t *) objp, 0, 1);
+#endif
else {
error(ERROR_FATAL, "outdegree of non-node");
return -1;
break;
case M_degree:
if (AGTYPE(objp) == AGNODE)
+#ifdef USE_CGRAPH
+ v->integer = agdegree(state->curgraph, (Agnode_t *) objp, 1, 1);
+#else
v->integer = agdegree((Agnode_t *) objp, 1, 1);
+#endif
else {
error(ERROR_FATAL, "degree of non-node");
return -1;
error(ERROR_WARNING, "NULL node passed to addNode()");
v.integer = 0;
} else
- v.integer = PTR2INT(addNode(gp, np));
+ v.integer = PTR2INT(addNode(gp, np, 1));
break;
case F_fstnode:
gp = INT2PTR(Agraph_t *, args[0].integer);
case F_nxtnode:
np = INT2PTR(Agnode_t *, args[0].integer);
if (np) {
+#ifdef USE_CGRAPH
+ np = agnxtnode(state->curgraph, np);
+#else
np = agnxtnode(np);
+#endif
v.integer = PTR2INT(np);
} else {
error(ERROR_WARNING, "NULL node passed to nxtnode()");
v.integer = 0;
}
break;
+ case F_nxtnodesg:
+#ifdef USE_CGRAPH
+ gp = INT2PTR(Agraph_t *, args[0].integer);
+ np = INT2PTR(Agnode_t *, args[1].integer);
+ if (!gp)
+ gp = state->curgraph;
+ if (np) {
+ np = agnxtnode(gp, np);
+ v.integer = PTR2INT(np);
+ } else {
+ error(ERROR_WARNING, "NULL node passed to nxtnode_sg()");
+ v.integer = 0;
+ }
+#else
+ error(ERROR_FATAL, "nxtnode_sg currently unsupported");
+#endif
+ break;
case F_isnode:
gp = INT2PTR(Agraph_t *, args[0].integer);
if (gp) {
v.integer = 0;
}
break;
+ case F_issubnode:
+#ifdef USE_CGRAPH
+ gp = INT2PTR(Agraph_t *, args[0].integer);
+ np = INT2PTR(Agnode_t *, args[1].integer);
+ if (!gp)
+ gp = state->curgraph;
+ if (np) {
+ v.integer = PTR2INT(addNode(gp, np, 0));
+ } else {
+ error(ERROR_WARNING, "NULL node passed to isSubnode()");
+ v.integer = 0;
+ }
+#else
+ error(ERROR_FATAL, "isSubnode currently unsupported");
+#endif
+ break;
+ case F_indegree:
+#ifdef USE_CGRAPH
+ gp = INT2PTR(Agraph_t *, args[0].integer);
+ np = INT2PTR(Agnode_t *, args[1].integer);
+ if (!gp)
+ gp = state->curgraph;
+ if (np) {
+ v.integer = agdegree(gp, np, 1, 0);
+ } else {
+ error(ERROR_WARNING, "NULL node passed to indegreeOf()");
+ v.integer = 0;
+ }
+#else
+ error(ERROR_FATAL, "indegreeOf currently unsupported");
+#endif
+ break;
+ case F_outdegree:
+#ifdef USE_CGRAPH
+ gp = INT2PTR(Agraph_t *, args[0].integer);
+ np = INT2PTR(Agnode_t *, args[1].integer);
+ if (!gp)
+ gp = state->curgraph;
+ if (np) {
+ v.integer = agdegree(gp, np, 0, 1);
+ } else {
+ error(ERROR_WARNING, "NULL node passed to outdegreeOf()");
+ v.integer = 0;
+ }
+#else
+ error(ERROR_FATAL, "outdegreeOf currently unsupported");
+#endif
+ break;
+ case F_degree:
+#ifdef USE_CGRAPH
+ gp = INT2PTR(Agraph_t *, args[0].integer);
+ np = INT2PTR(Agnode_t *, args[1].integer);
+ if (!gp)
+ gp = state->curgraph;
+ if (np) {
+ v.integer = agdegree(gp, np, 1, 1);
+ } else {
+ error(ERROR_WARNING, "NULL node passed to degreeOf()");
+ v.integer = 0;
+ }
+#else
+ error(ERROR_FATAL, "degreeOf currently unsupported");
+#endif
+ break;
case F_isin:
gp = INT2PTR(Agraph_t *, args[0].integer);
objp = INT2PTR(Agobj_t *, args[1].integer);
error(ERROR_WARNING, "NULL head node passed to edge()");
v.integer = 0;
} else {
- ep = openEdge(np, hp, key);
+ ep = openEdge(0, np, hp, key);
+ v.integer = PTR2INT(ep);
+ }
+ break;
+ case F_edgesg:
+#ifdef USE_CGRAPH
+ key = args[3].string;
+ if (*key == '\0')
+ key = 0;
+ gp = INT2PTR(Agraph_t *, args[0].integer);
+ np = INT2PTR(Agnode_t *, args[1].integer);
+ hp = INT2PTR(Agnode_t *, args[2].integer);
+ if (!np) {
+ error(ERROR_WARNING, "NULL tail node passed to edge_sg()");
+ v.integer = 0;
+ } else if (!hp) {
+ error(ERROR_WARNING, "NULL head node passed to edge_sg()");
+ v.integer = 0;
+ } else {
+ ep = openEdge(gp, np, hp, key);
v.integer = PTR2INT(ep);
}
+#else
+ error(ERROR_FATAL, "edge_sg currently unsupported");
+#endif
break;
case F_addedge:
gp = INT2PTR(Agraph_t *, args[0].integer);
error(ERROR_WARNING, "NULL edge passed to addEdge()");
v.integer = 0;
} else
- v.integer = PTR2INT(addEdge(gp, ep));
+ v.integer = PTR2INT(addEdge(gp, ep, 1));
break;
case F_isedge:
key = args[2].string;
error(ERROR_WARNING, "NULL head node passed to isEdge()");
v.integer = 0;
} else
- v.integer = PTR2INT(isEdge(np, hp, key));
+ v.integer = PTR2INT(isEdge(state->curgraph, np, hp, key));
+ break;
+ case F_isedgesg:
+#ifdef USE_CGRAPH
+ key = args[3].string;
+ if (*key == '\0')
+ key = 0;
+ gp = INT2PTR(Agraph_t *, args[0].integer);
+ np = INT2PTR(Agnode_t *, args[1].integer);
+ hp = INT2PTR(Agnode_t *, args[2].integer);
+ if (!gp)
+ gp = state->curgraph;
+ if (!np) {
+ error(ERROR_WARNING, "NULL tail node passed to isEdge_sg()");
+ v.integer = 0;
+ } else if (!hp) {
+ error(ERROR_WARNING, "NULL head node passed to isEdge_sg()");
+ v.integer = 0;
+ } else
+ v.integer = PTR2INT(isEdge(gp, np, hp, key));
+#else
+ error(ERROR_FATAL, "isEdge_sg currently unsupported");
+#endif
+ break;
+ case F_issubedge:
+#ifdef USE_CGRAPH
+ gp = INT2PTR(Agraph_t *, args[0].integer);
+ ep = INT2PTR(Agedge_t *, args[1].integer);
+ if (!gp)
+ gp = state->curgraph;
+ if (ep) {
+ v.integer = PTR2INT(addEdge(gp, ep, 0));
+ } else {
+ error(ERROR_WARNING, "NULL edge passed to isSubedge()");
+ v.integer = 0;
+ }
+#else
+ error(ERROR_FATAL, "isSubedge currently unsupported");
+#endif
break;
case F_fstout:
np = INT2PTR(Agnode_t *, args[0].integer);
if (np) {
+#ifdef USE_CGRAPH
+ ep = agfstout(state->curgraph, np);
+#else
ep = agfstout(np);
+#endif
v.integer = PTR2INT(ep);
} else {
error(ERROR_WARNING, "NULL node passed to fstout()");
v.integer = 0;
}
break;
+ case F_fstoutsg:
+#ifdef USE_CGRAPH
+ gp = INT2PTR(Agraph_t *, args[0].integer);
+ np = INT2PTR(Agnode_t *, args[1].integer);
+ if (!gp)
+ gp = state->curgraph;
+ if (np) {
+ ep = agfstout(gp, np);
+ v.integer = PTR2INT(ep);
+ } else {
+ error(ERROR_WARNING, "NULL node passed to fstout_sg()");
+ v.integer = 0;
+ }
+#else
+ error(ERROR_FATAL, "fstout_sg currently unsupported");
+#endif
+ break;
case F_nxtout:
ep = INT2PTR(Agedge_t *, args[0].integer);
if (ep) {
+#ifdef USE_CGRAPH
+ ep = agnxtout(state->curgraph, ep);
+#else
ep = agnxtout(ep);
+#endif
v.integer = PTR2INT(ep);
} else {
error(ERROR_WARNING, "NULL edge passed to nxtout()");
v.integer = 0;
}
break;
+ case F_nxtoutsg:
+#ifdef USE_CGRAPH
+ gp = INT2PTR(Agraph_t *, args[0].integer);
+ ep = INT2PTR(Agedge_t *, args[1].integer);
+ if (!gp)
+ gp = state->curgraph;
+ if (ep) {
+ ep = agnxtout(gp, ep);
+ v.integer = PTR2INT(ep);
+ } else {
+ error(ERROR_WARNING, "NULL edge passed to nxtout_sg()");
+ v.integer = 0;
+ }
+#else
+ error(ERROR_FATAL, "nxtout_sg currently unsupported");
+#endif
+ break;
case F_fstin:
np = INT2PTR(Agnode_t *, args[0].integer);
if (np) {
+#ifdef USE_CGRAPH
+ ep = agfstin(state->curgraph, np);
+#else
ep = agfstin(np);
+#endif
v.integer = PTR2INT(ep);
} else {
error(ERROR_WARNING, "NULL node passed to fstin()");
v.integer = 0;
}
break;
+ case F_fstinsg:
+#ifdef USE_CGRAPH
+ gp = INT2PTR(Agraph_t *, args[0].integer);
+ np = INT2PTR(Agnode_t *, args[1].integer);
+ if (!gp)
+ gp = state->curgraph;
+ if (np) {
+ ep = agfstin(gp, np);
+ v.integer = PTR2INT(ep);
+ } else {
+ error(ERROR_WARNING, "NULL node passed to fstin_sg()");
+ v.integer = 0;
+ }
+#else
+ error(ERROR_FATAL, "fstin_sg currently unsupported");
+#endif
+ break;
case F_nxtin:
ep = INT2PTR(Agedge_t *, args[0].integer);
if (ep) {
+#ifdef USE_CGRAPH
+ ep = agnxtin(state->curgraph, ep);
+#else
ep = agnxtin(ep);
+#endif
v.integer = PTR2INT(ep);
} else {
error(ERROR_WARNING, "NULL edge passed to nxtin()");
v.integer = 0;
}
break;
+ case F_nxtinsg:
+#ifdef USE_CGRAPH
+ gp = INT2PTR(Agraph_t *, args[0].integer);
+ ep = INT2PTR(Agedge_t *, args[1].integer);
+ if (!gp)
+ gp = state->curgraph;
+ if (ep) {
+ ep = agnxtin(gp, ep);
+ v.integer = PTR2INT(ep);
+ } else {
+ error(ERROR_WARNING, "NULL edge passed to nxtin_sg()");
+ v.integer = 0;
+ }
+#else
+ error(ERROR_FATAL, "nxtin_sg currently unsupported");
+#endif
+ break;
case F_fstedge:
np = INT2PTR(Agnode_t *, args[0].integer);
if (np) {
+#ifdef USE_CGRAPH
+ ep = agfstedge(state->curgraph, np);
+#else
ep = agfstedge(np);
+#endif
v.integer = PTR2INT(ep);
} else {
error(ERROR_WARNING, "NULL node passed to fstedge()");
v.integer = 0;
}
break;
+ case F_fstedgesg:
+#ifdef USE_CGRAPH
+ gp = INT2PTR(Agraph_t *, args[0].integer);
+ np = INT2PTR(Agnode_t *, args[1].integer);
+ if (!gp)
+ gp = state->curgraph;
+ if (np) {
+ ep = agfstedge(gp, np);
+ v.integer = PTR2INT(ep);
+ } else {
+ error(ERROR_WARNING, "NULL node passed to fstedge_sg()");
+ v.integer = 0;
+ }
+#else
+ error(ERROR_FATAL, "fstedge_sg currently unsupported");
+#endif
+ break;
case F_nxtedge:
ep = INT2PTR(Agedge_t *, args[0].integer);
np = INT2PTR(Agnode_t *, args[1].integer);
error(ERROR_WARNING, "NULL node passed to nxtedge()");
v.integer = 0;
} else {
+#ifdef USE_CGRAPH
+ ep = agnxtedge(state->curgraph, ep, np);
+#else
ep = agnxtedge(ep, np);
+#endif
v.integer = PTR2INT(ep);
}
break;
+ case F_nxtedgesg:
+#ifdef USE_CGRAPH
+ gp = INT2PTR(Agraph_t *, args[0].integer);
+ ep = INT2PTR(Agedge_t *, args[1].integer);
+ np = INT2PTR(Agnode_t *, args[2].integer);
+ if (!gp)
+ gp = state->curgraph;
+ if (!ep) {
+ error(ERROR_WARNING, "NULL edge passed to nxtedge_sg()");
+ v.integer = 0;
+ } else if (!np) {
+ error(ERROR_WARNING, "NULL node passed to nxtedge_sg()");
+ v.integer = 0;
+ } else {
+ ep = agnxtedge(gp, ep, np);
+ v.integer = PTR2INT(ep);
+ }
+#else
+ error(ERROR_FATAL, "nxtedge_sg currently unsupported");
+#endif
+ break;
case F_copy:
gp = INT2PTR(Agraph_t *, args[0].integer);
objp = INT2PTR(Agobj_t *, args[1].integer);
deparse(pgm, node, state->tmp));
}
- if (lookup(pgm, objp, sym, &v))
+ if (lookup(pgm, objp, sym, &v, state))
error(ERROR_FATAL, "in expression %s",
deparse(pgm, node, state->tmp));
* Create edge and initialize dynamic data.
* The edge is always created in the root graph.
*/
-Agedge_t *openEdge(Agnode_t * t, Agnode_t * h, char *key)
+Agedge_t *openEdge(Agraph_t* g, Agnode_t * t, Agnode_t * h, char *key)
{
Agedge_t *ep;
Agraph_t *root;
root = sameG(t, h, "openEdge", "tail and head node");
if (!root)
return 0;
+#ifdef USE_CGRAPH
+ if (g && (root != agroot(g)))
+ return 0;
+ else
+ g = root;
+ ep = agedge(g, t, h, key, 1);
+#else
t = (Agnode_t *) agrebind(root, OBJ(t));
h = (Agnode_t *) agrebind(root, OBJ(h));
ep = agedge(t, h, key, 1);
+#endif
if (ep && !aggetrec(ep, UDATA, 0))
agbindrec(ep, UDATA, sizeof(edata), 0);
return ep;