Eskil

Check-in [d8ae37f9be]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:First working plugin in dirdiff
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: d8ae37f9be3d33f393c4adc1917c792658fcccf8
User & Date: peter 2014-11-16 23:27:18.832
Context
2014-11-16
23:54
Handle Fossil revs a bit better check-in: 00d1e0c608 user: peter tags: trunk
23:27
First working plugin in dirdiff check-in: d8ae37f9be user: peter tags: trunk
2014-11-14
00:14
Added SVN support to VFS and dirdiff check-in: 0827ab89b0 user: peter tags: trunk
Changes
Unified Diff Ignore Whitespace Patch
Changes to Changes.



1
2
3
4
5
6
7



2014-11-13
 Undid all dirdiff refactoring from August. Bad idea...

2014-11-12
 Bumped revision to 2.6.7

2014-11-12
>
>
>







1
2
3
4
5
6
7
8
9
10
2014-11-16
 First working plugin in dirdiff.

2014-11-13
 Undid all dirdiff refactoring from August. Bad idea...

2014-11-12
 Bumped revision to 2.6.7

2014-11-12
Changes to Makefile.
1
2
3
4
5
6
7
8
9
10
11
12
#----------------------------------------------------------------------
# Make file for Eskil
#----------------------------------------------------------------------

VERSION = 267

# Path to the TclKits used for creating StarPacks.
TCLKIT = /home/peter/tclkit/v85
TCLKIT_LINUX   = $(TCLKIT)/tclkit-linux
TCLKIT_SOLARIS = $(TCLKIT)/tclkit-solaris-sparc
TCLKIT_WIN     = $(TCLKIT)/tclkit-win32.upx.exe





|







1
2
3
4
5
6
7
8
9
10
11
12
#----------------------------------------------------------------------
# Make file for Eskil
#----------------------------------------------------------------------

VERSION = 2671

# Path to the TclKits used for creating StarPacks.
TCLKIT = /home/peter/tclkit/v85
TCLKIT_LINUX   = $(TCLKIT)/tclkit-linux
TCLKIT_SOLARIS = $(TCLKIT)/tclkit-solaris-sparc
TCLKIT_WIN     = $(TCLKIT)/tclkit-win32.upx.exe

Changes to src/dirdiff.tcl.
77
78
79
80
81
82
83

84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114















115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
        file stat $file1 stat1
        file stat $file2 stat2
    }
    # If contents is not checked, same size is enough to be equal
    if {$stat1(size) == $stat2(size) && $::Pref(dir,comparelevel) == 0} {
        return 1
    }

    set ignorekey $::Pref(dir,ignorekey)
    # Different size is enough when doing binary compare
    if {$stat1(size) != $stat2(size) && $::Pref(dir,comparelevel) == 2 \
        && !$ignorekey} {
        return 0
    }
    # Same size and time is always considered equal
    if {$stat1(size) == $stat2(size) && $stat1(mtime) == $stat2(mtime)} {
	return 1
    }
    # Don't check further if contents should not be checked
    if {$::Pref(dir,comparelevel) == 0} {
        return 0
    }
    # Don't check further if any is a directory
    if {$isdir1 || $isdir2} {
        # Consider dirs equal until we implement something recursive
	return 1
    }

    switch $::Pref(dir,comparelevel) {
        2 -
        1 { # Check contents internally
            set bufsz 65536
            set eq 1
            set ch1 [open $file1 r]
            set ch2 [open $file2 r]
            if {$::Pref(dir,comparelevel) == 2} {
                fconfigure $ch1 -translation binary
                fconfigure $ch2 -translation binary
            }















            if {$ignorekey} {
                # Assume that all keywords are in the first block
                set f1 [read $ch1 $bufsz]
                set f2 [read $ch2 $bufsz]
                regsub -all {\$\w+:[^\$]*\$} $f1 {} f1
                regsub -all {\$\w+:[^\$]*\$} $f2 {} f2
                # Compensate for any change in length
                if {[string length $f1] < [string length $f2]} {
                    append f1 [read $ch1 [expr {[string length $f2] - [string length $f1]}]]
                }
                if {[string length $f2] < [string length $f1]} {
                    append f2 [read $ch2 [expr {[string length $f1] - [string length $f2]}]]
                }
                if {![string equal $f1 $f2]} {
                    set eq 0
                }
            }
            while {$eq && ![eof $ch1] && ![eof $ch2]} {
                set f1 [read $ch1 $bufsz]
                set f2 [read $ch2 $bufsz]
                if {![string equal $f1 $f2]} {
                    set eq 0
                }
            }
            if {![eof $ch1] || ![eof $ch2]} {
                set eq 0
            }
            close $ch1
            close $ch2
        }
    }
    return $eq
}

# Returns the contents of a directory as a sorted list of full file paths.
proc DirContents {dir} {
    if {$::tcl_platform(platform) eq "windows"} {
        # .-files are not treated specially on windows. * is enough to get all
        set files [glob -directory $dir -nocomplain *]







>



|




















|






>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

















|






|






|







77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
        file stat $file1 stat1
        file stat $file2 stat2
    }
    # If contents is not checked, same size is enough to be equal
    if {$stat1(size) == $stat2(size) && $::Pref(dir,comparelevel) == 0} {
        return 1
    }
    set anyPlugin [expr {$::eskil(.dirdiff,plugin) ne ""}]
    set ignorekey $::Pref(dir,ignorekey)
    # Different size is enough when doing binary compare
    if {$stat1(size) != $stat2(size) && $::Pref(dir,comparelevel) == 2 \
        && !$ignorekey && !$anyPlugin} {
        return 0
    }
    # Same size and time is always considered equal
    if {$stat1(size) == $stat2(size) && $stat1(mtime) == $stat2(mtime)} {
	return 1
    }
    # Don't check further if contents should not be checked
    if {$::Pref(dir,comparelevel) == 0} {
        return 0
    }
    # Don't check further if any is a directory
    if {$isdir1 || $isdir2} {
        # Consider dirs equal until we implement something recursive
	return 1
    }

    switch $::Pref(dir,comparelevel) {
        2 -
        1 { # Check contents internally
            set bufsz 65536
            set eq 2 ;# 2 = equal this far, 1 = equal, 0 = not equal
            set ch1 [open $file1 r]
            set ch2 [open $file2 r]
            if {$::Pref(dir,comparelevel) == 2} {
                fconfigure $ch1 -translation binary
                fconfigure $ch2 -translation binary
            }
            # Allow a plugin to do its thing
            if {$anyPlugin} {
                #puts "PLUGIN!"
                $::eskil(.dirdiff,plugin) eval \
                        [list array set ::Pref [array get ::Pref]]
                interp share {} $ch1 $::eskil(.dirdiff,plugin)
                interp share {} $ch2 $::eskil(.dirdiff,plugin)
                set info1 [dict create name $file1 size $stat1(size)]
                set info2 [dict create name $file2 size $stat2(size)]
                set eq [$::eskil(.dirdiff,plugin) eval \
                                [list FileCompare $ch1 $ch2 $info1 $info2]]
                $::eskil(.dirdiff,plugin) invokehidden close $ch1
                $::eskil(.dirdiff,plugin) invokehidden close $ch2
            }

            if {$ignorekey} {
                # Assume that all keywords are in the first block
                set f1 [read $ch1 $bufsz]
                set f2 [read $ch2 $bufsz]
                regsub -all {\$\w+:[^\$]*\$} $f1 {} f1
                regsub -all {\$\w+:[^\$]*\$} $f2 {} f2
                # Compensate for any change in length
                if {[string length $f1] < [string length $f2]} {
                    append f1 [read $ch1 [expr {[string length $f2] - [string length $f1]}]]
                }
                if {[string length $f2] < [string length $f1]} {
                    append f2 [read $ch2 [expr {[string length $f1] - [string length $f2]}]]
                }
                if {![string equal $f1 $f2]} {
                    set eq 0
                }
            }
            while {$eq == 2 && ![eof $ch1] && ![eof $ch2]} {
                set f1 [read $ch1 $bufsz]
                set f2 [read $ch2 $bufsz]
                if {![string equal $f1 $f2]} {
                    set eq 0
                }
            }
            if {$eq == 2 && (![eof $ch1] || ![eof $ch2])} {
                set eq 0
            }
            close $ch1
            close $ch2
        }
    }
    return [expr {$eq != 0}]
}

# Returns the contents of a directory as a sorted list of full file paths.
proc DirContents {dir} {
    if {$::tcl_platform(platform) eq "windows"} {
        # .-files are not treated specially on windows. * is enough to get all
        set files [glob -directory $dir -nocomplain *]
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
        $win.m.mo.mc add radiobutton -variable ::Pref(dir,comparelevel) -value 1 \
                -label "Normal compare"
        $win.m.mo.mc add radiobutton -variable ::Pref(dir,comparelevel) -value 2 \
                -label "Exact compare"
        $win.m.mo.mc add checkbutton -variable ::Pref(dir,ignorekey) \
                -label "Ignore \$Keyword:\$"

        #$win.m.mo add command -label "Plugins..." -underline 1 \
        #        -command [list EditPrefPlugins $win]
        $win.m.mo add cascade -label "Nice" -menu $win.m.mo.mn
        menu $win.m.mo.mn
        $win.m.mo.mn add radiobutton -variable [myvar nice] -value 1 \
                -command [mymethod DoNice] -label 1
        $win.m.mo.mn add radiobutton -variable [myvar nice] -value 50 \
                -command [mymethod DoNice] -label 50
        $win.m.mo.mn add radiobutton -variable [myvar nice] -value 100 \







|
|







993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
        $win.m.mo.mc add radiobutton -variable ::Pref(dir,comparelevel) -value 1 \
                -label "Normal compare"
        $win.m.mo.mc add radiobutton -variable ::Pref(dir,comparelevel) -value 2 \
                -label "Exact compare"
        $win.m.mo.mc add checkbutton -variable ::Pref(dir,ignorekey) \
                -label "Ignore \$Keyword:\$"

        $win.m.mo add command -label "Plugins..." -underline 1 \
                -command [list EditPrefPlugins $win 1]
        $win.m.mo add cascade -label "Nice" -menu $win.m.mo.mn
        menu $win.m.mo.mn
        $win.m.mo.mn add radiobutton -variable [myvar nice] -value 1 \
                -command [mymethod DoNice] -label 1
        $win.m.mo.mn add radiobutton -variable [myvar nice] -value 50 \
                -command [mymethod DoNice] -label 50
        $win.m.mo.mn add radiobutton -variable [myvar nice] -value 100 \
1239
1240
1241
1242
1243
1244
1245



1246

1247
1248
1249
1250
1251
1252
1253
1254
1255
    }
    if {![info exists ::dirdiff(leftDir)]} {
        set ::dirdiff(leftDir) ""
    }
    if {![info exists ::dirdiff(rightDir)]} {
        set ::dirdiff(rightDir) ""
    }





    # Experiment to support -r for directory diff
    # Currently only Fossil is supported
    if {[info exists opts(doptrev1)] && $opts(doptrev1) ne ""} {
        set fullname $::dirdiff(leftDir)
        set type [detectRevSystem $fullname]
        # Is this a revision system with dirdiff support?
        if {[info commands eskil::rev::${type}::mount] ne ""} {
            set revs [list $opts(doptrev1)]
            if {[info exists opts(doptrev2)] && $opts(doptrev2) ne ""} {







>
>
>
|
>

|







1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
    }
    if {![info exists ::dirdiff(leftDir)]} {
        set ::dirdiff(leftDir) ""
    }
    if {![info exists ::dirdiff(rightDir)]} {
        set ::dirdiff(rightDir) ""
    }
    set ::eskil(.dirdiff,plugin) ""
    foreach {item val} [array get opts] {
        set ::eskil(.dirdiff,$item) $val
    }

    # Experiment to support -r for directory diff
    # Currently only Fossil/SVN is supported
    if {[info exists opts(doptrev1)] && $opts(doptrev1) ne ""} {
        set fullname $::dirdiff(leftDir)
        set type [detectRevSystem $fullname]
        # Is this a revision system with dirdiff support?
        if {[info commands eskil::rev::${type}::mount] ne ""} {
            set revs [list $opts(doptrev1)]
            if {[info exists opts(doptrev2)] && $opts(doptrev2) ne ""} {
Changes to src/eskil.tcl.
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
# Stop Tk from meddling with the command line by copying it first.
set ::eskil(argv) $::argv
set ::eskil(argc) $::argc
set ::argv {}
set ::argc 0

set ::eskil(debug) 0
set ::eskil(diffver) "Version 2.6.7 2014-11-12"
set ::eskil(thisScript) [file join [pwd] [info script]]

namespace import tcl::mathop::+
namespace import tcl::mathop::-
namespace import tcl::mathop::*
namespace import tcl::mathop::/








|







33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
# Stop Tk from meddling with the command line by copying it first.
set ::eskil(argv) $::argv
set ::eskil(argc) $::argc
set ::argv {}
set ::argc 0

set ::eskil(debug) 0
set ::eskil(diffver) "Version 2.6.7+ 2014-11-16"
set ::eskil(thisScript) [file join [pwd] [info script]]

namespace import tcl::mathop::+
namespace import tcl::mathop::-
namespace import tcl::mathop::*
namespace import tcl::mathop::/

Changes to src/plugin.tcl.
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
    }
    unset -nocomplain \
            ::eskil($top,leftFileBak) ::eskil($top,rightFileBak) \
            ::eskil($top,leftFileDiff) ::eskil($top,rightFileDiff)
}

# GUI for plugin selection
proc EditPrefPlugins {top} {
    set w $top.prefplugin

    # Create window
    destroy $w
    toplevel $w -padx 3 -pady 3
    ttk::frame $w._bg
    place $w._bg -x 0 -y 0 -relwidth 1.0 -relheight 1.0 -border outside







|







199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
    }
    unset -nocomplain \
            ::eskil($top,leftFileBak) ::eskil($top,rightFileBak) \
            ::eskil($top,leftFileDiff) ::eskil($top,rightFileDiff)
}

# GUI for plugin selection
proc EditPrefPlugins {top {dirdiff 0}} {
    set w $top.prefplugin

    # Create window
    destroy $w
    toplevel $w -padx 3 -pady 3
    ttk::frame $w._bg
    place $w._bg -x 0 -y 0 -relwidth 1.0 -relheight 1.0 -border outside
224
225
226
227
228
229
230

231
232
233
234
235
236
237
        set ::eskil($top,plugininfo) ""
    }
    set ::eskil($top,edit,pluginname) $::eskil($top,pluginname) 
    set ::eskil($top,edit,plugininfo) $::eskil($top,plugininfo)
    set t 0
    foreach {plugin info} $plugins {
        set descr [dict get $info descr]

        ttk::radiobutton $w.rb$t -variable ::eskil($top,edit,pluginname) -value $plugin -text $plugin
        ttk::label $w.l$t -text $descr -anchor "w"
        grid $w.rb$t $w.l$t -sticky we -padx 3 -pady 3
        incr t
    }
    ttk::radiobutton $w.rb$t -variable ::eskil($top,edit,pluginname) -value "" -text "No Plugin"
    grid $w.rb$t -sticky we -padx 3 -pady 3







>







224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
        set ::eskil($top,plugininfo) ""
    }
    set ::eskil($top,edit,pluginname) $::eskil($top,pluginname) 
    set ::eskil($top,edit,plugininfo) $::eskil($top,plugininfo)
    set t 0
    foreach {plugin info} $plugins {
        set descr [dict get $info descr]
        if {$dirdiff && ![dict get $info dir]} continue
        ttk::radiobutton $w.rb$t -variable ::eskil($top,edit,pluginname) -value $plugin -text $plugin
        ttk::label $w.l$t -text $descr -anchor "w"
        grid $w.rb$t $w.l$t -sticky we -padx 3 -pady 3
        incr t
    }
    ttk::radiobutton $w.rb$t -variable ::eskil($top,edit,pluginname) -value "" -text "No Plugin"
    grid $w.rb$t -sticky we -padx 3 -pady 3