Attachment "532783.diff" to
ticket [532783ffff]
added by
andreas_kupries
2002-03-21 12:35:12.
Index: modules/struct/ChangeLog
===================================================================
RCS file: /cvsroot/tcllib/tcllib/modules/struct/ChangeLog,v
retrieving revision 1.25
diff -u -r1.25 ChangeLog
--- modules/struct/ChangeLog 15 Mar 2002 19:22:26 -0000 1.25
+++ modules/struct/ChangeLog 21 Mar 2002 05:33:24 -0000
@@ -1,3 +1,13 @@
+2002-03-20 Andreas Kupries <[email protected]>
+
+ * matrix.tcl: Fixed bug #532783 reported by Ken Jones
+ <[email protected]>. Any operation adding new material
+ to a linked matrix causes a circular trace (op -> "MatTraceOut"
+ -> "MatTraceIn" -> set cell) and the inbound trace fails because
+ the data structures are not uptodate causing the range checks in
+ "set cell" to fail. Fixed by breaking the cycle. Calls to
+ "MatTraceIn" are now disabled while we are in "MatTraceOut".
+
2002-03-15 Andreas Kupries <[email protected]>
* matrix.man: Added example of formatting a matrix using tabular
Index: modules/struct/matrix.tcl
===================================================================
RCS file: /cvsroot/tcllib/tcllib/modules/struct/matrix.tcl,v
retrieving revision 1.8
diff -u -r1.8 matrix.tcl
--- modules/struct/matrix.tcl 10 Mar 2002 02:49:52 -0000 1.8
+++ modules/struct/matrix.tcl 21 Mar 2002 05:33:24 -0000
@@ -28,6 +28,7 @@
# - colw cache of columnwidths
# - rowh cache of rowheights
# - link information about linked arrays
+ # - lock boolean flag to disable MatTraceIn while in MatTraceOut [#532783]
# counter is used to give a unique name for unnamed matrixs
variable counter 0
@@ -99,11 +100,13 @@
variable colw
variable rowh
variable link
+ variable lock
array set data {}
array set colw {}
array set rowh {}
array set link {}
+ set lock 0
}
# Create the command to manipulate the matrix
@@ -1975,6 +1978,9 @@
proc ::struct::matrix::MatTraceIn {avar name var idx op} {
# Propagate changes in the linked array back into the matrix.
+ upvar ::struct::matrix::matrix${name}::lock lock
+ if {$lock} {return}
+
if {![string compare $op u]} {
# External array was destroyed, perform automatic unlink.
$name unlink $avar
@@ -2014,11 +2020,15 @@
proc ::struct::matrix::MatTraceOut {avar name var idx op} {
# Propagate changes in the matrix data array into the linked array.
+ upvar ::struct::matrix::matrix${name}::lock lock
+ set lock 1 ; # Disable MatTraceIn [#532783]
+
upvar #0 $avar array
upvar ::struct::matrix::matrix${name}::data data
upvar ::struct::matrix::matrix${name}::link link
set transpose $link($avar)
+
if {$transpose} {
foreach {r c} [split $idx ,] break
} else {
@@ -2026,5 +2036,6 @@
}
set array($c,$r) $data($idx)
+ set lock 0
return
}
Index: modules/struct/matrix.test
===================================================================
RCS file: /cvsroot/tcllib/tcllib/modules/struct/matrix.test,v
retrieving revision 1.5
diff -u -r1.5 matrix.test
--- modules/struct/matrix.test 10 Mar 2002 02:49:52 -0000 1.5
+++ modules/struct/matrix.test 21 Mar 2002 05:33:24 -0000
@@ -1589,6 +1589,35 @@
set result
} {a {}}
+test matrix-9.12 {unset in linked array} {
+ matrix mymatrix
+ mymatrix add columns 3
+ mymatrix add row {1 2 3}
+ mymatrix add row {a b c}
+
+ catch {unset a}
+ mymatrix link a
+
+ set result [list]
+ lappend result [aget a]
+ unset a(0,0)
+ lappend result [mymatrix get rect 0 0 end end]
+
+ mymatrix destroy
+ set result
+} {{0,0 1 0,1 a 1,0 2 1,1 b 2,0 3 2,1 c} {{1 2 3} {a b c}}}
+
+test matrix-9.13 {operation on linked matrix} {
+ catch {unset a}
+ matrix mymatrix
+ mymatrix add columns 4
+ mymatrix add row {1 2 3}
+ mymatrix link a
+ mymatrix add row {a b c d}
+ set result [mymatrix get rect 0 0 end end]
+ mymatrix destroy
+ set result
+} {{1 2 3 {}} {a b c d}}}
test 10.1 {search errors} {
matrix mymatrix