Number: 359
Title: 2 bugs of Tcldot: setting attribute to subgraph and extra edge handles
Submitter: HIRAKI Hideaki
Date: Wed Oct 8 22:40:00 2003
Subsys: Tcl/Tk utilities
Version: 1.10.20031007.0415
System: *-*-
Severity: minor
Problem:

$ 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)
$

Fix:

--- 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;


Owner: ellson
Status: Fixed (10 October 2003)