Browse Source

gitk: Fix more bugs resulting in Tcl "no such element in array" errors

First, update_arcrows was being overly aggressive in trimming
displayorder, resulting in calls to rowofcommit sometimes trimming off
commits that layoutrows had asked for in make_disporder and was relying
on having present.  This adds a vrowmod($view) variable that lets
update_arcrows be more precise in trimming off the invalid bits of
displayorder (and it also simplifies the check in make_disporder).
This modifies modify_arc and its callers so that vrowmod($view) is
updated appropriately.

Secondly, we were sometimes calling idcol with $i==-1, which resulted
in a call to ordertoken with the null string.  This fixes it by
forcing $i to 0 if it is less than zero.

This also fixes a possible infinite recursion with rowofcommit and
update_arcrows calling each other ad infinitum.

Signed-off-by: Paul Mackerras <paulus@samba.org>
maint
Paul Mackerras 17 years ago
parent
commit
e5b37ac1ec
  1. 59
      gitk

59
gitk

@ -268,7 +268,7 @@ proc strrep {n} {


proc varcinit {view} { proc varcinit {view} {
global vseeds varcstart vupptr vdownptr vleftptr varctok varcrow global vseeds varcstart vupptr vdownptr vleftptr varctok varcrow
global vtokmod varcmod varcix uat global vtokmod varcmod vrowmod varcix uat


set vseeds($view) {} set vseeds($view) {}
set varcstart($view) {{}} set varcstart($view) {{}}
@ -279,6 +279,7 @@ proc varcinit {view} {
set varcrow($view) {{}} set varcrow($view) {{}}
set vtokmod($view) {} set vtokmod($view) {}
set varcmod($view) 0 set varcmod($view) 0
set vrowmod($view) 0
set varcix($view) {{}} set varcix($view) {{}}
set uat 0 set uat 0
} }
@ -307,7 +308,7 @@ proc resetvarcs {view} {
proc newvarc {view id} { proc newvarc {view id} {
global varcid varctok parents children vseeds global varcid varctok parents children vseeds
global vupptr vdownptr vleftptr varcrow varcix varcstart global vupptr vdownptr vleftptr varcrow varcix varcstart
global commitdata commitinfo vseedcount global commitdata commitinfo vseedcount varccommits


set a [llength $varctok($view)] set a [llength $varctok($view)]
set vid $view,$id set vid $view,$id
@ -377,6 +378,7 @@ proc newvarc {view id} {
lappend vdownptr($view) 0 lappend vdownptr($view) 0
lappend varcrow($view) {} lappend varcrow($view) {}
lappend varcix($view) {} lappend varcix($view) {}
set varccommits($view,$a) {}
return $a return $a
} }


@ -547,7 +549,7 @@ proc insertrow {id p v} {
# note we deliberately don't update varcstart($v) even if $i == 0 # note we deliberately don't update varcstart($v) even if $i == 0
set varccommits($v,$a) [linsert $varccommits($v,$a) $i $id] set varccommits($v,$a) [linsert $varccommits($v,$a) $i $id]
if {[string compare [lindex $varctok($v) $a] $vtokmod($v)] < 0} { if {[string compare [lindex $varctok($v) $a] $vtokmod($v)] < 0} {
modify_arc $v $a modify_arc $v $a $i
} }
drawvisible drawvisible
} }
@ -579,7 +581,7 @@ proc removerow {id v} {
} }
set tok [lindex $varctok($v) $a] set tok [lindex $varctok($v) $a]
if {[string compare [lindex $varctok($v) $a] $vtokmod($v)] < 0} { if {[string compare [lindex $varctok($v) $a] $vtokmod($v)] < 0} {
modify_arc $v $a modify_arc $v $a $i
} }
drawvisible drawvisible
} }
@ -591,22 +593,30 @@ proc vtokcmp {v a b} {
[lindex $varctok($v) $varcid($v,$b)]] [lindex $varctok($v) $varcid($v,$b)]]
} }


proc modify_arc {v a} { proc modify_arc {v a {lim {}}} {
global varctok vtokmod varcmod varcrow vupptr curview global varctok vtokmod varcmod varcrow vupptr curview vrowmod varccommits


set vtokmod($v) [lindex $varctok($v) $a] set vtokmod($v) [lindex $varctok($v) $a]
set varcmod($v) $a set varcmod($v) $a
if {$v == $curview} { if {$v == $curview} {
while {$a != 0 && [lindex $varcrow($v) $a] eq {}} { while {$a != 0 && [lindex $varcrow($v) $a] eq {}} {
set a [lindex $vupptr($v) $a] set a [lindex $vupptr($v) $a]
set lim {}
} }
set r [expr {$a == 0? 0: [lindex $varcrow($v) $a]}] set r 0
if {$a != 0} {
if {$lim eq {}} {
set lim [llength $varccommits($v,$a)]
}
set r [expr {[lindex $varcrow($v) $a] + $lim}]
}
set vrowmod($v) $r
undolayout $r undolayout $r
} }
} }


proc update_arcrows {v} { proc update_arcrows {v} {
global vtokmod varcmod varcrow commitidx currentid selectedline global vtokmod varcmod vrowmod varcrow commitidx currentid selectedline
global varcid vseeds vrownum varcorder varcix varccommits global varcid vseeds vrownum varcorder varcix varccommits
global vupptr vdownptr vleftptr varctok global vupptr vdownptr vleftptr varctok
global uat displayorder parentlist curview cached_commitrow global uat displayorder parentlist curview cached_commitrow
@ -640,11 +650,11 @@ proc update_arcrows {v} {
} }
set row [lindex $varcrow($v) $a] set row [lindex $varcrow($v) $a]
} }
if {[llength $displayorder] > $row} {
set displayorder [lrange $displayorder 0 [expr {$row - 1}]]
set parentlist [lrange $parentlist 0 [expr {$row - 1}]]
}
if {$v == $curview} { if {$v == $curview} {
if {[llength $displayorder] > $vrowmod($v)} {
set displayorder [lrange $displayorder 0 [expr {$vrowmod($v) - 1}]]
set parentlist [lrange $parentlist 0 [expr {$vrowmod($v) - 1}]]
}
catch {unset cached_commitrow} catch {unset cached_commitrow}
} }
while {1} { while {1} {
@ -668,11 +678,12 @@ proc update_arcrows {v} {
lset varcix($v) $a $arcn lset varcix($v) $a $arcn
lset varcrow($v) $a $row lset varcrow($v) $a $row
} }
set vtokmod($v) [lindex $varctok($v) $p]
set varcmod($v) $p
set vrowmod($v) $row
if {[info exists currentid]} { if {[info exists currentid]} {
set selectedline [rowofcommit $currentid] set selectedline [rowofcommit $currentid]
} }
set vtokmod($v) [lindex $varctok($v) $p]
set varcmod($v) $p
set t2 [clock clicks -milliseconds] set t2 [clock clicks -milliseconds]
incr uat [expr {$t2-$t1}] incr uat [expr {$t2-$t1}]
} }
@ -734,13 +745,10 @@ proc bsearch {l elt} {
# Make sure rows $start..$end-1 are valid in displayorder and parentlist # Make sure rows $start..$end-1 are valid in displayorder and parentlist
proc make_disporder {start end} { proc make_disporder {start end} {
global vrownum curview commitidx displayorder parentlist global vrownum curview commitidx displayorder parentlist
global varccommits varcorder parents varcmod varcrow global varccommits varcorder parents vrowmod varcrow
global d_valid_start d_valid_end global d_valid_start d_valid_end


set la $varcmod($curview) if {$end > $vrowmod($curview)} {
set lrow [lindex $varcrow($curview) $la]
if {$la == 0 || $lrow eq {} || \
$end > $lrow + [llength $varccommits($curview,$la)]} {
update_arcrows $curview update_arcrows $curview
} }
set ai [bsearch $vrownum($curview) $start] set ai [bsearch $vrownum($curview) $start]
@ -808,10 +816,10 @@ proc closevarcs {v} {
set b [newvarc $v $p] set b [newvarc $v $p]
} }
set varcid($v,$p) $b set varcid($v,$p) $b
lappend varccommits($v,$b) $p
if {[string compare [lindex $varctok($v) $b] $vtokmod($v)] < 0} { if {[string compare [lindex $varctok($v) $b] $vtokmod($v)] < 0} {
modify_arc $v $b modify_arc $v $b
} }
lappend varccommits($v,$b) $p
incr commitidx($v) incr commitidx($v)
if {[info exists commitinterest($p)]} { if {[info exists commitinterest($p)]} {
foreach script $commitinterest($p) { foreach script $commitinterest($p) {
@ -958,8 +966,11 @@ proc getcommitlines {fd inst view} {
set a [newvarc $view $id] set a [newvarc $view $id]
} }
set varcid($vid) $a set varcid($vid) $a
if {[string compare [lindex $varctok($view) $a] $vtokmod($view)] < 0} {
modify_arc $view $a
}
lappend varccommits($view,$a) $id lappend varccommits($view,$a) $id
set tok [lindex $varctok($view) $a]
set i 0 set i 0
foreach p $olds { foreach p $olds {
if {$i == 0 || [lsearch -exact $olds $p] >= $i} { if {$i == 0 || [lsearch -exact $olds $p] >= $i} {
@ -976,9 +987,6 @@ proc getcommitlines {fd inst view} {
} }
incr i incr i
} }
if {[string compare $tok $vtokmod($view)] < 0} {
modify_arc $view $a
}


incr commitidx($view) incr commitidx($view)
if {[info exists commitinterest($id)]} { if {[info exists commitinterest($id)]} {
@ -3345,6 +3353,9 @@ proc ordertoken {id} {
# values increase from left to right # values increase from left to right
proc idcol {idlist id {i 0}} { proc idcol {idlist id {i 0}} {
set t [ordertoken $id] set t [ordertoken $id]
if {$i < 0} {
set i 0
}
if {$i >= [llength $idlist] || $t < [ordertoken [lindex $idlist $i]]} { if {$i >= [llength $idlist] || $t < [ordertoken [lindex $idlist $i]]} {
if {$i > [llength $idlist]} { if {$i > [llength $idlist]} {
set i [llength $idlist] set i [llength $idlist]

Loading…
Cancel
Save