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  <andreas_kupries@users.sourceforge.net>
+
+	* matrix.tcl: Fixed bug #532783 reported by Ken Jones
+	  <kenj@users.sourceforge.net>. 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  <andreas_kupries@users.sourceforge.net>
 
 	* 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
