commit - e3f361530d5b3c16f397a90c6f03e76715955985
commit + 6ae7a56e0f08ffd6e04a5312789e91ddb3059fc9
blob - 13f6ba8319a779dea33ffc6865f0366a04382848
blob + a1f4b1c0cbcb37cca869106d9198736e47d3467c
--- exercise
+++ exercise
# Report test failures and errors to our stderr.
if {$what ne "ok"} {
- set foot "$what $path"
+ set foot [list "$what $path"]
if {[isatty stderr]} {
- set foot [color {33} $foot] ;# dark yellow
+ set foot [color 3 $foot] ;# dark yellow
}
- puts stderr $foot
+ puts stderr [join $foot ""]
puts stderr ""
}
dict exists [fconfigure $chan] -mode
}
+# ANSI (ECMA-48) escape sequences
+set esc(bu) [list "\033\[4m"] ;# begin underline
+set esc(eu) [list "\033\[24m"] ;# end underline
+set esc(ce) [list "\033\[0K"] ;# clear to end
+set esc(endc) [list "\033\[39m"] ;# end color
+set esc(endcb) [list "\033\[39;22m"] ;# end color and bold
+
proc color {c s} {
- return "\033\[${c}m$s\033\[0m"
+ global esc
+ concat [list "\033\[3${c}m"] $s $esc(endc)
}
+proc boldc {c s} {
+ global esc
+ concat [list "\033\[1;3${c}m"] $s $esc(endcb)
+}
+
+proc cinsert {line pos args} {
+ set cur 0
+ set idx 0
+
+ foreach elem $line {
+ if {$cur == $pos} {
+ return [linsert $line $idx {*}$args]
+ }
+ if {[string index $elem 0] ne "\033"} {
+ set len [string length $elem]
+
+ if {$pos < $cur + $len} {
+ set split [expr {$pos - $cur}]
+ set left [string range $elem 0 [expr {$split - 1}]]
+ set right [string range $elem $split end]
+ return [lreplace $line $idx $idx $left {*}$args $right]
+ }
+
+ incr cur $len
+ }
+ incr idx
+ }
+
+ # if we reach here, pos is beyond the end of line
+ lappend line [string repeat " " [expr {$pos - $cur}]] {*}$args
+}
+
+proc clength {line} {
+ foreach elem $line {
+ if {[string index $elem 0] eq "\033"} continue
+ incr len [string length $elem]
+ }
+ return $len
+}
+
proc inconsistent {counters} {
dict with counters {
expr {$run < $ok + $fail + $error}
}
proc summary {counters} {
+ global esc
+
dict with counters {
- set r "run $run"
- set o "ok $ok"
- set f "fail $fail"
- set e "error $error"
+ set r [list "run $run"]
+ set o [list "ok $ok"]
+ set f [list "fail $fail"]
+ set e [list "error $error"]
# color
if {[isatty stdout]} {
set good [expr {$ok>0 && ![notok $counters]}]
- if {$run == 0} {set r [color {31} $r]} ;# dark red
- if {$good} {set o [color {1;32} $o]} ;# bright green
- if {$fail > 0} {set f [color {1;31} $f]} ;# bright red
- if {$error > 0} {set e [color {31} $e]} ;# dark red
+ if {$run == 0} {set r [color 1 $r]} ;# dark red
+ if {$good} {set o [boldc 2 $o]} ;# bright green
+ if {$fail > 0} {set f [boldc 1 $f]} ;# bright red
+ if {$error > 0} {set e [color 1 $e]} ;# dark red
}
- return "$r $o $f $e"
+ set line [concat $r "{ }" $o "{ }" $f "{ }" $e]
+
+ # progress bar, using underlining
+ if {[isatty stdout]} {
+ set ran [expr {$ok + $fail + $error}]
+ if {$run > 0 && $ran < $run} {
+ set pos [expr {[clength $line] * $ran / $run}]
+ set line [concat $esc(bu) [cinsert $line $pos {*}$esc(eu)]]
+ }
+ }
+
+ return [join $line ""]
}
}