-
Notifications
You must be signed in to change notification settings - Fork 0
/
patch-distill.tcl
executable file
·60 lines (46 loc) · 1.52 KB
/
patch-distill.tcl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
#!/usr/bin/tclsh
# Use [lassign] in Tcl 8.5
proc mset {vars list} { uplevel [list foreach $vars $list break] }
mset {overlay patch} $argv
if { $overlay == "" } {
puts stderr "Usage: [file tail $argv0] <patch overlay> ?raw patch=cin? (distilled patch printed to cout)"
exit 1
}
if { ![file readable $overlay] } {
puts stderr "error: The overlay patch '$overlay' can't be open for reading."
exit 1
}
if { $patch == "" } {
set fd stdin
} else {
set fd [open $patch r]
}
# Execute diff and pass the patch to stdin (overlay patch is passed as filename)
set erc [catch {exec diff - $overlay << [read $fd]} patch2]
set ecode $errorCode
set einfo $errorInfo
set lines [split $patch2 \n]
# Diff returns exit code 1 if files differ (but the process succeded)
# Make an error-to-expected-code fallback for Tcl, as Tcl treats nonzero code as error.
if { $erc } {
mset {statkey pid status} $ecode
if { $statkey == "CHILDSTATUS" } {
if { $status == 1 } {
# Just there are difs. Remove the last line that says 'child status failed' or something
set lines [lrange $lines 0 end-1]
} else {
puts stderr "diff: diff could not open file (strange!)"
exit 1
}
} else {
error "(propagated)\n$einfo"
}
}
# Now make an integrate of patch2 into a distilled patch (extract changes only)
set outlines ""
foreach l $lines {
if { [string index $l 0] == "<" } {
lappend outlines [string range $l 2 end]
}
}
puts [join $outlines \n]