#!/bin/sh # \ exec wish "$0" ${1+"$@"} proc assert { prop } { # Evaluate the given proposition in the calling context and die with an error # message if it's false. set p $prop set pattern {(.*)<([^:>]+)>:([0-9]+)(.*)} while { [ regexp $pattern $p _ pre lst idx post ] } { if { [ regexp {^[a-zA-Z0-9]$} $lst _ ] } { set lst "\$$lst" } set p "$pre\[lindex $lst $idx]$post" } if { ![ uplevel $p ] } { puts stderr "Assertion \"$prop\" failed." puts $errorInfo exit 1 } } proc max { a b } { # Return the larger of the given values. if { [ expr $a > $b ] } { return $a } return $b } proc min { a b } { # Return the smaller of the given values. if { [ expr $a < $b ] } { return $a } return $b } proc rint { max } { # Return a random integer in [0, max). return [ expr int($max*rand()) ] } # $Log: utils.tcl,v $ # Revision 1.1 2003/09/01 18:36:19 rclayton # Initial revision # # Local Variables: # mode: tcl # tcl-application: "tclsh" # End: proc check-edges { edges } { # Check the given edges. set c [ llength $edges ] if { [ expr $c % 2 != 0 ] } { set s "" if { $c != 1 } { set s s } puts stderr "$c edge$s read from std-in, should be an even number." exit 1 } set new_edges { } foreach e $edges { if { [ regexp { (.*[^-0-9 ].*) } " $e " _ bad ] } { puts stderr "Invalid input \"$bad\" read from std-in." exit 1 } set e [ split $e ] set elen [ llength $e ] if { $elen == 1 } { if { [ expr [ lindex $e 0 ] != 0 ] } { puts stderr "An edge with one-nonzero value read from std-in." exit 1 } set e { } } \ elseif { [ expr $elen % 2 != 0 ] } { set s "" if { $c != 1 } { set s s } puts stderr "An edge has $elen coordinates, should have an even number of coordinates." exit 1 } lappend new_edges $e } for { set i 1 } { $i < [ expr $c - 1] } { incr i 2 } { set e1 [ lindex $new_edges $i ] set e2 [ lindex $new_edges [ expr $i + 1 ] ] set el1 [ llength $e1 ] set el2 [ llength $e2 ] if { $el1 != $el2 } { puts stderr "Adjacent edges have $el1 and $el2 coordinates, should have the same number of coordinates." exit 1 } for { set j [ expr [ llength $e1 ] - 1 ] } { $j >= 0 } { incr j -1 } { set c1 [ lindex $e1 $j ] set c2 [ lindex $e2 $j ] if { $c1 != $c2 } { puts stderr "Adjacent edges differ at coordinate $j: $c1 vs. $c2." exit 1 } } } return $new_edges } proc edge-min-max { edge minref maxref } { # Find the largest and smallest coordinate values in the given edge. upvar $minref mn upvar $maxref mx foreach coord $edge { set mn [ min $coord $mn ] set mx [ max $coord $mx ] } } proc find-min-max { edges minref maxref } { # Find the largest and smallest coordinate values in the given edges. upvar $minref mn upvar $maxref mx set n $mn set x $mx foreach e $edges { edge-min-max $e n x set mn [ min $n $mn ] set mx [ max $x $mx ] } } proc read-edges { inf } { # Read and return the edges from the given input file. set edges { } while { [ expr [ gets $inf line ] > -1 ] } { regsub -all {[ \t]+} [ string trim $line ] " " line if { [ llength $line ] } { lappend edges $line } } return $edges } proc show-edge { edge offset scale margin x } { # Draw the given edge using the given y-offset, scale, margin, and x # coordinate. for { set i 0 } { $i < [ llength $edge ] } { incr i 2 } { set y0 [ lindex $edge $i ] set y1 [ lindex $edge [ expr $i + 1 ] ] set y0 [ expr ($y0 - $offset)*$scale + $margin ] set y1 [ expr ($y1 - $offset)*$scale + $margin ] # puts stderr "x = $x, y0 = $y0, y1 = $y1" .canvas create line $x $y0 $x $y1 -width 2 } } proc show-edges { edges } { # Show the given edges. global canvasy canvasx margin set min $canvasy set max [ expr -$canvasy ] find-min-max $edges min max set c [ expr [ llength $edges ]/2 ] set deltax [ expr ($canvasx - 2*$margin)/double($c) ] set y0 $margin set y1 [ expr $canvasy - $margin ] set scale [ expr double($canvasy - 2*$margin)/($max - $min) ] for { set i 0 } { $i < $c } { incr i } { set x [ expr $i*$deltax + $margin ] .canvas create line $x $y0 $x $y1 -fill gray show-edge [ lindex $edges [ expr 2*$i ] ] $min $scale $margin $x } set x [ expr $canvasx - $margin ] .canvas create line $x $y0 $x $y1 -fill gray show-edge [ lindex $edges end ] $min $scale $margin $x } set edges [ read-edges stdin ] set edges [ check-edges $edges ] if { ![ llength $edges ] } { exit 0 } set scale 4 set canvasy [ expr $scale*110 ] set canvasx [ expr $scale*85 ] set margin 5 canvas .canvas -height $canvasy -width $canvasx -background white pack .canvas bind .canvas q { exit 0 } focus .canvas show-edges $edges # $Log: show-shreds.tcl,v $ # Revision 1.3 2003/09/07 14:29:36 rclayton # Use .so instead of source for utils.tcl. # # Local Variables: # mode: tcl # tcl-application: "wish" # End: