Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Replaced != with ne in a lot of places. Reworked compareBlocks to use lists of lists instead of array as matrix. Added flags to enscript to make sure print behaves the same on different enscript versions. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
e807edee25efe40493999fd709f5778b |
User & Date: | peter 2004-03-30 14:01:22.000 |
Context
2004-05-02
| ||
13:54 | Started on Makefile. check-in: d82acf76ed user: peter tags: trunk | |
2004-03-30
| ||
14:01 | Replaced != with ne in a lot of places. Reworked compareBlocks to use lists of lists instead of array as matrix. Added flags to enscript to make sure print behaves the same on different enscript versions. check-in: e807edee25 user: peter tags: trunk | |
2004-02-23
| ||
21:11 | *** empty log message *** check-in: f705f9fd7c user: peter tags: trunk | |
Changes
Changes to src/eskil.tcl.
︙ | ︙ | |||
47 48 49 50 51 52 53 | # Add a dummy if it does not exists. proc addBalloon {args} {} } else { namespace import -force psballoon::addBalloon } set debug 0 | | | 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 | # Add a dummy if it does not exists. proc addBalloon {args} {} } else { namespace import -force psballoon::addBalloon } set debug 0 set diffver "Version 2.0.1+ 2004-03-30" set thisScript [file join [pwd] [info script]] set thisDir [file dirname $thisScript] # Follow any link set tmplink $thisScript while {[file type $tmplink] eq "link"} { set tmplink [file readlink $tmplink] |
︙ | ︙ | |||
196 197 198 199 200 201 202 | # element is equal between the strings. # This is sort of a Longest Common Subsequence algorithm but with # a preference for long consecutive substrings, and it does not look # for really small substrings. ##syntax compareMidString x x n n x? proc compareMidString {s1 s2 res1Name res2Name {test 0}} { global Pref | | < | 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 | # element is equal between the strings. # This is sort of a Longest Common Subsequence algorithm but with # a preference for long consecutive substrings, and it does not look # for really small substrings. ##syntax compareMidString x x n n x? proc compareMidString {s1 s2 res1Name res2Name {test 0}} { global Pref upvar $res1Name res1 $res2Name res2 set len1 [string length $s1] set len2 [string length $s2] # Is s1 a substring of s2 ? if {$len1 < $len2} { set t [string first $s1 $s2] |
︙ | ︙ | |||
244 245 246 247 248 249 250 | # Find the longest string common to both strings for {set t 0 ; set u $minlen} {$u < $len1} {incr t ; incr u} { set i [string first [string range $s1 $t $u] $s2] if {$i >= 0} { for {set p1 [expr {$u + 1}]; set p2 [expr {$i + $minlen + 1}]} \ {$p1 < $len1 && $p2 < $len2} {incr p1 ; incr p2} { | | | | | | | 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 | # Find the longest string common to both strings for {set t 0 ; set u $minlen} {$u < $len1} {incr t ; incr u} { set i [string first [string range $s1 $t $u] $s2] if {$i >= 0} { for {set p1 [expr {$u + 1}]; set p2 [expr {$i + $minlen + 1}]} \ {$p1 < $len1 && $p2 < $len2} {incr p1 ; incr p2} { if {[string index $s1 $p1] ne [string index $s2 $p2]} { break } } if {$Pref(lineparsewords) != 0 && $test == 0} { set newt $t if {($t > 0 && [string index $s1 [expr {$t - 1}]] ne " ") || \ ($i > 0 && [string index $s2 [expr {$i - 1}]] ne " ")} { for {} {$newt < $p1} {incr newt} { if {[string index $s1 $newt] eq " "} break } } set newp1 [expr {$p1 - 1}] if {($p1 < $len1 && [string index $s1 $p1] ne " ") || \ ($p2 < $len2 && [string index $s2 $p2] ne " ")} { for {} {$newp1 > $newt} {incr newp1 -1} { if {[string index $s1 $newp1] eq " "} break } } incr newp1 if {$newp1 - $newt > $minlen} { |
︙ | ︙ | |||
295 296 297 298 299 300 301 | set mid1 [string range $s1 $found1 [expr {$found1 + $foundlen - 1}]] set right1 [string range $s1 [expr {$found1 + $foundlen}] end] set left2 [string range $s2 0 [expr {$found2 - 1}]] set mid2 [string range $s2 $found2 [expr {$found2 + $foundlen - 1}]] set right2 [string range $s2 [expr {$found2 + $foundlen}] end] | | | | | | 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 | set mid1 [string range $s1 $found1 [expr {$found1 + $foundlen - 1}]] set right1 [string range $s1 [expr {$found1 + $foundlen}] end] set left2 [string range $s2 0 [expr {$found2 - 1}]] set mid2 [string range $s2 $found2 [expr {$found2 + $foundlen - 1}]] set right2 [string range $s2 [expr {$found2 + $foundlen}] end] compareMidString $left1 $left2 left1l left2l $test compareMidString $right1 $right2 right1l right2l $test set res1 [concat $left1l [list $mid1] $right1l] set res2 [concat $left2l [list $mid2] $right2l] } } # Experiment using DiffUtil ##syntax compareLinesX x x n n x? proc compareLinesX {line1 line2 res1Name res2Name {test 0}} { global Pref |
︙ | ︙ | |||
329 330 331 332 333 334 335 | upvar $res1Name res1 upvar $res2Name res2 # This processes the lines from both ends first. # A typical line has few changes thus this gets rid of most # equalities. The middle part is then optionally parsed further. | | | 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 | upvar $res1Name res1 upvar $res2Name res2 # This processes the lines from both ends first. # A typical line has few changes thus this gets rid of most # equalities. The middle part is then optionally parsed further. if {$Pref(ignore) ne " "} { # Skip white space in both ends set apa1 [string trimleft $line1] set leftp1 [expr {[string length $line1] - [string length $apa1]}] set mid1 [string trimright $line1] set apa2 [string trimleft $line2] |
︙ | ︙ | |||
420 421 422 423 424 425 426 | if {$leftp1 > $t1 && $leftp2 > $t2} { set res1 [list $line1] set res2 [list $line2] } else { set right1 [string range $line1 [expr {$t1 + 1}] end] set mid1 [string range $line1 $leftp1 $t1] set left1 [string range $line1 0 [expr {$leftp1 - 1}]] | < < | | < | | | | | | 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 | if {$leftp1 > $t1 && $leftp2 > $t2} { set res1 [list $line1] set res2 [list $line2] } else { set right1 [string range $line1 [expr {$t1 + 1}] end] set mid1 [string range $line1 $leftp1 $t1] set left1 [string range $line1 0 [expr {$leftp1 - 1}]] set right2 [string range $line2 [expr {$t2 + 1}] end] set mid2 [string range $line2 $leftp2 $t2] set left2 [string range $line2 0 [expr {$leftp2 - 1}]] if {$Pref(extralineparse) != 0 && $mid1 ne "" && $mid2 ne ""} { compareMidString $mid1 $mid2 mid1l mid2l $test # Replace middle element in res* with list elements from mid* set res1 [concat [list $left1] $mid1l [list $right1]] set res2 [concat [list $left2] $mid2l [list $right2]] } else { set res1 [list $left1 $mid1 $right1] set res2 [list $left2 $mid2 $right2] } } } # Compare two lines and rate how much they resemble each other. # This has never worked well. Some day I'll sit down, think this through, # and come up with a better algorithm. |
︙ | ︙ | |||
488 489 490 491 492 493 494 495 496 497 498 499 500 501 | } # puts "Same ($sames)" # puts "D1 ($diffs1)" # puts "D2 ($diffs2)" # puts "S $sumsame D $sumdiff1 D $sumdiff2" return [expr {$sumsame - [maxAbs $sumdiff1 $sumdiff2]}] } # Decide how to display change blocks # This tries to match the lines that resemble each other and put them # next to each other. # As the previous procedure, this would need a complete rework and a # better algorithm. proc compareBlocks {block1 block2} { | > > > > > > > > > > > > > > | 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 | } # puts "Same ($sames)" # puts "D1 ($diffs1)" # puts "D2 ($diffs2)" # puts "S $sumsame D $sumdiff1 D $sumdiff2" return [expr {$sumsame - [maxAbs $sumdiff1 $sumdiff2]}] } # Initialise a multidimensional list with empty values # This should use lrepeat once 8.5 is required # The args are in the same order as indexes to lset/lindex proc Linit {elem args} { for {set t [expr {[llength $args] - 1}]} {$t >= 0} {incr t -1} { set new {} for {set j [lindex $args $t]} {$j >= 1} {incr j -1} { lappend new $elem } set elem $new } return $elem } # Decide how to display change blocks # This tries to match the lines that resemble each other and put them # next to each other. # As the previous procedure, this would need a complete rework and a # better algorithm. proc compareBlocks {block1 block2} { |
︙ | ︙ | |||
518 519 520 521 522 523 524 | set asym d } else { set dsym d set asym a } # Collect statistics | > > | > > | | | | | | | | | < < | < > | | | > | | | > | | > | | | | | | | | | | | > | | | | | | | | | | | 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 | set asym d } else { set dsym d set asym a } # Collect statistics set scores [Linit {} $size1 $size2] set emptyResult [Linit {} $size1] set scoresbest $emptyResult set origresult $emptyResult set j 0 set bestsum 0 foreach line1 $block1 { set bestscore -100000 set bestline 0 set i 0 foreach line2 $block2 { set x [compareLines2 $line1 $line2] lset scores $j $i $x # puts "Score $j $i : $x" if {$x > $bestscore} { set bestscore $x set bestline $i } incr i } # puts "Best for $j is $bestline : $bestscore" lset origresult $j $bestline lset scoresbest $j $bestscore incr bestsum $bestscore incr j } # puts "Bestsum: $bestsum" # origresult holds a mapping between blocks where each row # is paired with its best match. This may not be a possible # result since it has to be in order. set bestresult $origresult set bestscoresum -100000 # If the size is 1, it is automatically in order so we # don't need further processing. if {$size1 > 1} { # If both blocks are the same size, try first with the # simple row to row match, as a base score if {$size1 == $size2} { set sum 0 set result $emptyResult for {set i 0} {$i < $size1} {incr i} { lset result $i $i incr sum [lindex $scores $i $i] } # puts "Simple map sum: $sum" set bestresult $result set bestscoresum $sum } # If result is in order, no problem. # Otherwise, try to adjust result to make it ordered while {1} { # The outer loop restarts from the "best mapping" set result $origresult set mark [Linit 0 $size1] set high $mark while {1} { # The inner loop tries to get the result in order set besti 0 set bestscore -100000 set order 1 for {set i 0} {$i < $size1} {incr i} { if {[lindex $mark $i] == 0} { for {set j [expr {$i + 1}]} {$j < $size1} {incr j} { if {[lindex $mark $j] == 0} break } if {$j < $size1 && \ [lindex $result $i] >= [lindex $result $j]} { set order 0 } set x [lindex $scoresbest $i] if {$x > $bestscore} { set bestscore $x set besti $i } } } # puts "Best $besti order $order sc $bestscore" if {$order} break lset mark $besti 1 set bestr [lindex $result $besti] for {set i 0} {$i < $besti} {incr i} { if {[lindex $mark $i] == 0 && \ [lindex $result $i] >= $bestr} { lset mark $i 2 } } for {set i [expr {$besti + 1}]} {$i < $size1} {incr i} { if {[lindex $mark $i] == 0 && \ [lindex $result $i] <= $bestr} { lset mark $i 2 } } } set prev $size2 for {set i [expr {$size1 - 1}]} {$i >= 0} {incr i -1} { if {[lindex $mark $i] != 2} { set prev [lindex $result $i] } else { lset high $i [expr {$prev - 1}] } } set prev -1 for {set i 0} {$i < $size1} {incr i} { if {[lindex $mark $i] != 2} { set prev [lindex $result $i] } else { if {[lindex $high $i] > $prev} { incr prev lset result $i $prev } else { lset result $i -1 } } } set scoresum 0 for {set i 0} {$i < $size1} {incr i} { set j [lindex $result $i] set sc [lindex $scores $i $j] ;# FIXA: can this fail? if {[string is integer -strict $sc]} { # puts "Score: $i $j $scores($i,$j)" incr scoresum $sc } } # puts "Scoresum: $scoresum ($bestscoresum)" # If it was not an improvement over previous iteration, quit if {$scoresum <= $bestscoresum} { break } set bestresult $result set bestscoresum $scoresum # If it is close enough to the theoretical max, take it if {$bestscoresum >= (3 * $bestsum / 4)} { break } # We are redoing from start, but try to improve by # ignoring the most awkwardly placed line. set mostp -1 set mosti 0 for {set i 0} {$i < $size1} {incr i} { if {[lindex $mark $i] == 1} { if {abs([lindex $result $i] - $i) > $mostp} { set mostp [expr {abs([lindex $result $i] - $i)}] set mosti $i } } } # puts "Most $mosti $mostp" lset scoresbest $mosti 0 } } set result $bestresult # Collect the result into diff-like codes to use as display info. set apa {} set t1 0 set t2 0 while {$t1 < $size1 || $t2 < $size2} { if {$t1 < $size1} { set r [lindex $result $t1] if {$r < $t2 || $t2 >= $size2} { lappend apa $dsym incr t1 } elseif {$r == $t2} { #if {[string match Wm* [lindex $block2 $t2]]} { # puts "Left : [lindex $block1 $t1]" # puts "Right: [lindex $block2 $t2]" # puts "Score: $scores($t1,$t2)" #} # If the score is too bad, don't do line parsing. if {[lindex $scores $t1 $t2] < 0} { lappend apa "C" } else { lappend apa "c" } incr t1 incr t2 } else { |
︙ | ︙ | |||
2448 2449 2450 2451 2452 2453 2454 | close $ch if {$::tcl_platform(platform) eq "windows" &&\ ![info exists ::env(ENSCRIPT_LIBRARY)]} { set ::env(ENSCRIPT_LIBRARY) [pwd] } | | | 2464 2465 2466 2467 2468 2469 2470 2471 2472 2473 2474 2475 2476 2477 2478 | close $ch if {$::tcl_platform(platform) eq "windows" &&\ ![info exists ::env(ENSCRIPT_LIBRARY)]} { set ::env(ENSCRIPT_LIBRARY) [pwd] } set enscriptCmd [list enscript -2jcre -L 66 -M A4] if {![regexp {^(.*)( \(.*?\))$} $::diff($top,leftLabel) -> lfile lrest]} { set lfile $::diff($top,leftLabel) set lrest "" } set lfile [file tail $lfile]$lrest if {![regexp {^(.*)( \(.*?\))$} $::diff($top,rightLabel) -> rfile rrest]} { set rfile $::diff($top,rightLabel) |
︙ | ︙ |