60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
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
|
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
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
|
-
+
-
-
+
+
-
-
-
-
-
+
-
+
-
-
-
+
+
+
+
-
+
-
+
-
-
+
+
-
-
+
+
|
return 0
}
# Same type?
set isdir1 [FileIsDirectory $file1]
set isdir2 [FileIsDirectory $file2]
if {$isdir1 != $isdir2} {
return 0
return 0
}
# Handle links
if {$stat1(type) eq "link" && $stat2(type) eq "link"} {
set l1 [file link $file1]
set l2 [file link $file2]
# Equal links are considered equal, otherwise check contents
if {$l1 eq $l2} {
return 1
}
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,1) ne "" && \
[dict get $::eskil(.dirdiff,pluginpinfo,1) dir]}]
set anyPlugin $::eskil(.dirdiff,dirPlugin)
set ignorekey $::Pref(dir,ignorekey)
set nocase $::Pref(nocase)
# 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
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,1) eval \
$::eskil(.dirdiff,plugin,$anyPlugin) eval \
[list array set ::Pref [array get ::Pref]]
$::eskil(.dirdiff,plugin,1) eval [list set ::argv $::eskil(argv)]
interp share {} $ch1 $::eskil(.dirdiff,plugin,1)
interp share {} $ch2 $::eskil(.dirdiff,plugin,1)
$::eskil(.dirdiff,plugin,$anyPlugin) eval \
[list set ::argv $::eskil(argv)]
interp share {} $ch1 $::eskil(.dirdiff,plugin,$anyPlugin)
interp share {} $ch2 $::eskil(.dirdiff,plugin,$anyPlugin)
set info1 [dict create name $file1 size $stat1(size)]
set info2 [dict create name $file2 size $stat2(size)]
set eq [$::eskil(.dirdiff,plugin,1) eval \
set eq [$::eskil(.dirdiff,plugin,$anyPlugin) eval \
[list FileCompare $ch1 $ch2 $info1 $info2]]
set allow [dict get $::eskil(.dirdiff,pluginpinfo,1) allow]
set allow [dict get $::eskil(.dirdiff,pluginpinfo,$anyPlugin) allow]
if {$allow} {
$::eskil(.dirdiff,plugin,1) eval close $ch1
$::eskil(.dirdiff,plugin,1) eval close $ch2
$::eskil(.dirdiff,plugin,$anyPlugin) eval close $ch1
$::eskil(.dirdiff,plugin,$anyPlugin) eval close $ch2
} else {
$::eskil(.dirdiff,plugin,1) invokehidden close $ch1
$::eskil(.dirdiff,plugin,1) invokehidden close $ch2
$::eskil(.dirdiff,plugin,$anyPlugin) invokehidden close $ch1
$::eskil(.dirdiff,plugin,$anyPlugin) invokehidden close $ch2
}
}
if {$ignorekey} {
# Assume that all keywords are in the first block
set f1 [read $ch1 $bufsz]
set f2 [read $ch2 $bufsz]
|
409
410
411
412
413
414
415
416
417
418
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
446
447
448
449
450
451
452
453
454
455
456
457
|
406
407
408
409
410
411
412
413
414
415
416
417
418
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
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
|
-
-
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
+
+
|
set right $newRight
set rightDir $right
}
if {!$ScheduledRestart} {
set ScheduledRestart 1
after idle [mymethod ReStart]
}
}
}
method nice {ms} {
# Sanity check
if {$ms < 1} { set ms 1 }
if {$ms > 1000} {set ms 1000 }
set AfterTime $ms
}
method ReStart {} {
# Delete all idle processing
if {$AfterId ne ""} {
after cancel $AfterId
}
set AfterId ""
set IdleQueue {}
set ScheduledRestart 0
array unset IdleQueueArr
set protect {left 0 right 0}
# Directory Diff only supports one plugin.
# Find if any configured plugin supports dir diff and choose it.
set ::eskil(.dirdiff,dirPlugin) 0
foreach item [lsort -dictionary [array names ::eskil .dirdiff,pluginname,*]] {
set n [lindex [split $item ","] end]
if {$::eskil(.dirdiff,plugin,$n) ne "" && \
[dict get $::eskil(.dirdiff,pluginpinfo,$n) dir]} {
set ::eskil(.dirdiff,dirPlugin) $n
break
}
}
# Fill in clean root data
$tree delete 0 end
set topIndex [$tree insertchild root end {}]
set d1 [file tail $leftDir]
set d2 [file tail $rightDir]
if {$d1 eq $d2} {
$tree cellconfigure $topIndex,structure -text $d1
} else {
$tree cellconfigure $topIndex,structure -text "$d1 vs $d2"
}
$tree cellconfigure $topIndex,structure -image $::img(open)
$tree rowattrib $topIndex type directory
$self SetNodeStatus $topIndex empty
$tree rowattrib $topIndex leftfull $leftDir
$tree rowattrib $topIndex rightfull $rightDir
$tree rowattrib $topIndex leftfull $leftDir
$tree rowattrib $topIndex rightfull $rightDir
$self UpdateDirNode $topIndex
}
method expandCmd {tbl row} {
if {[$tree childcount $row] != 0} {
$tree cellconfigure $row,0 -image $::img(open)
|