$ tclsh
% package require Tcldot
1.10.20031007.0415
% dotstring "digraph g0 { a -> A; subgraph g1 { } }"
graph0
% ##### Problem 1. setting attribute to subgraph
% graph0 setattribute ga g0
% graph0 queryattribute ga
g0
% graph0 setnodeattribute na n0
% graph0 querynodeattribute na
n0
% graph0 setedgeattribute ea e0
% graph0 queryedgeattribute ea
e0
% ##### Ok, attributes can be set to the root graph.
% graph0 listsubgraphs
graph1
% graph1 setattribute ga g1
% graph1 queryattribute ga
{}
% graph0 queryattribute ga
g1
% ##### But it is impossible to set an graph attribute to a subgraph.
% ##### Instead, the attribute of the root graph has been changed.
% graph1 setnodeattribute na n1
% graph1 querynodeattribute na
n0
% graph0 querynodeattribute na
n0
% graph1 setedgeattribute ea e1
% graph1 queryedgeattribute ea
e0
% graph0 queryedgeattribute ea
e0
% ##### And setting node/edge attributes to a subgraph is ignored.
% ##### Problem 2. extra edge handles
% graph0 listedges
edge1
% ##### Ok, there is one edge.
% info commands edge*
edge0 edge1
% ##### But two edge handles exist.
% graph0 delete
% info commands edge*
edge0
% ##### Then one edge handle has leaked and may cause segmentation fault.
% edge0 listattributes
Segmentation fault (core dumped)
$
--- tcldot/tcldot.c.orig Tue Jul 29 00:41:43 2003
+++ tcldot/tcldot.c Wed Oct 8 17:49:24 2003
@@ -847,7 +847,7 @@
return TCL_ERROR;
for (j = 0; j < argc2; j++) {
if ((a = agfindattr(g->proto->e, argv2[j]))) {
- Tcl_AppendElement(interp, a->value);
+ Tcl_AppendElement(interp, agxget(g->proto->e, a->index));
} else {
Tcl_AppendResult(interp, " No attribute named "",
argv2[j], """, (char *) 0);
@@ -865,7 +865,7 @@
for (j = 0; j < argc2; j++) {
if ((a = agfindattr(g->proto->e, argv2[j]))) {
Tcl_AppendElement(interp, argv2[j]);
- Tcl_AppendElement(interp, a->value);
+ Tcl_AppendElement(interp, agxget(g->proto->e, a->index));
} else {
Tcl_AppendResult(interp, " No attribute named "",
argv2[j], """, (char *) 0);
@@ -882,7 +882,7 @@
return TCL_ERROR;
for (j = 0; j < argc2; j++) {
if ((a = agfindattr(g->proto->n, argv2[j]))) {
- Tcl_AppendElement(interp, a->value);
+ Tcl_AppendElement(interp, agxget(g->proto->n, a->index));
} else {
Tcl_AppendResult(interp, " No attribute named "",
argv2[j], """, (char *) 0);
@@ -900,7 +900,7 @@
for (j = 0; j < argc2; j++) {
if ((a = agfindattr(g->proto->n, argv2[j]))) {
Tcl_AppendElement(interp, argv2[j]);
- Tcl_AppendElement(interp, a->value);
+ Tcl_AppendElement(interp, agxget(g->proto->n, a->index));
} else {
Tcl_AppendResult(interp, " No attribute named "",
argv2[j], """, (char *) 0);
@@ -973,7 +973,6 @@
return TCL_OK;
} else if ((c == 's') && (strncmp(argv[1], "setattributes", length) == 0)) {
- g = g->root;
if (argc == 3) {
if (Tcl_SplitList(interp, argv[2], &argc2, (CONST84 char***) &argv2) != TCL_OK)
return TCL_ERROR;
@@ -985,8 +984,8 @@
return TCL_ERROR;
}
for (i = 0; i < argc2; i++) {
- if (!(a = agfindattr(g, argv2[i])))
- a = agraphattr(g, argv2[i], "");
+ if (!(a = agfindattr(g->root, argv2[i])))
+ a = agraphattr(g->root, argv2[i], "");
agxset(g, a->index, argv2[++i]);
}
Tcl_Free((char *)argv2);
@@ -999,8 +998,8 @@
return TCL_ERROR;
}
for (i = 2; i < argc; i++) {
- if (!(a = agfindattr(g, argv[i])))
- a = agraphattr(g, argv[i], "");
+ if (!(a = agfindattr(g->root, argv[i])))
+ a = agraphattr(g->root, argv[i], "");
agxset(g, a->index, argv[++i]);
}
}
@@ -1019,8 +1018,14 @@
return TCL_ERROR;
}
for (i = 0; i < argc2; i++) {
- j = i++;
- agedgeattr(g, argv2[j], argv2[i]);
+ if (!(a = agfindattr(g->proto->e, argv2[i]))) {
+ if (g == g->root) {
+ a = agedgeattr(g, argv2[i], argv2[i + 1]);
+ } else {
+ a = agedgeattr(g->root, argv2[i], "");
+ }
+ }
+ agxset(g->proto->e, a->index, argv2[++i]);
}
Tcl_Free((char *)argv2);
}
@@ -1031,8 +1036,14 @@
(char *) NULL);
}
for (i = 2; i < argc; i++) {
- j = i++;
- agedgeattr(g, argv[j], argv[i]);
+ if (!(a = agfindattr(g->proto->e, argv[i]))) {
+ if (g == g->root) {
+ a = agedgeattr(g, argv[i], argv[i + 1]);
+ } else {
+ a = agedgeattr(g->root, argv[i], "");
+ }
+ }
+ agxset(g->proto->e, a->index, argv[++i]);
}
}
reset_layout(g);
@@ -1050,8 +1061,14 @@
return TCL_ERROR;
}
for (i = 0; i < argc2; i++) {
- j = i++;
- agnodeattr(g, argv2[j], argv2[i]);
+ if (!(a = agfindattr(g->proto->n, argv2[i]))) {
+ if (g == g->root) {
+ a = agnodeattr(g, argv2[i], argv2[i + 1]);
+ } else {
+ a = agnodeattr(g->root, argv2[i], "");
+ }
+ }
+ agxset(g->proto->n, a->index, argv2[++i]);
}
Tcl_Free((char *)argv2);
}
@@ -1062,8 +1079,14 @@
(char *) NULL);
}
for (i = 2; i < argc; i++) {
- j = i++;
- agnodeattr(g, argv[j], argv[i]);
+ if (!(a = agfindattr(g->proto->n, argv[i]))) {
+ if (g == g->root) {
+ a = agnodeattr(g, argv[i], argv[i + 1]);
+ } else {
+ a = agnodeattr(g->root, argv[i], "");
+ }
+ }
+ agxset(g->proto->n, a->index, argv[++i]);
}
}
reset_layout(g);
@@ -1229,7 +1252,7 @@
Tcl_CreateObjCommand(interp, buf, nodecmd,
(ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);
#endif /* TCLOBJ */
- for (e = agfstedge(g, n); e; e = agnxtedge(g, e, n)) {
+ for (e = agfstout(g, n); e; e = agnxtout(g, e)) {
ep = (Agedge_t **) tclhandleAlloc (edgeTblPtr, buf, &id);
*ep = e;
e->handle = id;