-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
yaml --- r: 54128 b: refs/heads/master c: 6e019b0 h: refs/heads/master v: v3
- Loading branch information
H. Peter Anvin
authored and
Sam Ravnborg
committed
May 2, 2007
1 parent
e48a97a
commit 264db3b
Showing
2 changed files
with
207 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,2 @@ | ||
--- | ||
refs/heads/master: 12b315603a1eb95b4e4ea3389ba44bd7ded0aa35 | ||
refs/heads/master: 6e019b001d27c4289f8e48ebc458e92410446259 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,206 @@ | ||
#!/usr/bin/perl -w | ||
# | ||
# Clean a patch file -- or directory of patch files -- of stealth whitespace. | ||
# WARNING: this can be a highly destructive operation. Use with caution. | ||
# | ||
|
||
use bytes; | ||
use File::Basename; | ||
|
||
# | ||
# Clean up space-tab sequences, either by removing spaces or | ||
# replacing them with tabs. | ||
sub clean_space_tabs($) | ||
{ | ||
no bytes; # Tab alignment depends on characters | ||
|
||
my($li) = @_; | ||
my($lo) = ''; | ||
my $pos = 0; | ||
my $nsp = 0; | ||
my($i, $c); | ||
|
||
for ($i = 0; $i < length($li); $i++) { | ||
$c = substr($li, $i, 1); | ||
if ($c eq "\t") { | ||
my $npos = ($pos+$nsp+8) & ~7; | ||
my $ntab = ($npos >> 3) - ($pos >> 3); | ||
$lo .= "\t" x $ntab; | ||
$pos = $npos; | ||
$nsp = 0; | ||
} elsif ($c eq "\n" || $c eq "\r") { | ||
$lo .= " " x $nsp; | ||
$pos += $nsp; | ||
$nsp = 0; | ||
$lo .= $c; | ||
$pos = 0; | ||
} elsif ($c eq " ") { | ||
$nsp++; | ||
} else { | ||
$lo .= " " x $nsp; | ||
$pos += $nsp; | ||
$nsp = 0; | ||
$lo .= $c; | ||
$pos++; | ||
} | ||
} | ||
$lo .= " " x $nsp; | ||
return $lo; | ||
} | ||
|
||
$name = basename($0); | ||
|
||
foreach $f ( @ARGV ) { | ||
print STDERR "$name: $f\n"; | ||
|
||
if (! -f $f) { | ||
print STDERR "$f: not a file\n"; | ||
next; | ||
} | ||
|
||
if (!open(FILE, '+<', $f)) { | ||
print STDERR "$name: Cannot open file: $f: $!\n"; | ||
next; | ||
} | ||
|
||
binmode FILE; | ||
|
||
# First, verify that it is not a binary file; consider any file | ||
# with a zero byte to be a binary file. Is there any better, or | ||
# additional, heuristic that should be applied? | ||
$is_binary = 0; | ||
|
||
while (read(FILE, $data, 65536) > 0) { | ||
if ($data =~ /\0/) { | ||
$is_binary = 1; | ||
last; | ||
} | ||
} | ||
|
||
if ($is_binary) { | ||
print STDERR "$name: $f: binary file\n"; | ||
next; | ||
} | ||
|
||
seek(FILE, 0, 0); | ||
|
||
$in_bytes = 0; | ||
$out_bytes = 0; | ||
|
||
@lines = (); | ||
|
||
$in_hunk = 0; | ||
$err = 0; | ||
|
||
while ( defined($line = <FILE>) ) { | ||
$in_bytes += length($line); | ||
|
||
if (!$in_hunk) { | ||
if ($line =~ /^\@\@\s+\-([0-9]+),([0-9]+)\s+\+([0-9]+),([0-9]+)\s\@\@/) { | ||
$minus_lines = $2; | ||
$plus_lines = $4; | ||
if ($minus_lines || $plus_lines) { | ||
$in_hunk = 1; | ||
@hunk_lines = ($line); | ||
} | ||
} else { | ||
push(@lines, $line); | ||
$out_bytes += length($line); | ||
} | ||
} else { | ||
# We're in a hunk | ||
|
||
if ($line =~ /^\+/) { | ||
$plus_lines--; | ||
|
||
$text = substr($line, 1); | ||
$text =~ s/[ \t\r]*$//; # Remove trailing spaces | ||
$text = clean_space_tabs($text); | ||
|
||
push(@hunk_lines, '+'.$text); | ||
} elsif ($line =~ /^\-/) { | ||
$minus_lines--; | ||
push(@hunk_lines, $line); | ||
} elsif ($line =~ /^ /) { | ||
$plus_lines--; | ||
$minus_lines--; | ||
push(@hunk_lines, $line); | ||
} else { | ||
print STDERR "$name: $f: malformed patch\n"; | ||
$err = 1; | ||
last; | ||
} | ||
|
||
if ($plus_lines < 0 || $minus_lines < 0) { | ||
print STDERR "$name: $f: malformed patch\n"; | ||
$err = 1; | ||
last; | ||
} elsif ($plus_lines == 0 && $minus_lines == 0) { | ||
# End of a hunk. Process this hunk. | ||
my $i; | ||
my $l; | ||
my @h = (); | ||
my $adj = 0; | ||
my $done = 0; | ||
|
||
for ($i = scalar(@hunk_lines)-1; $i > 0; $i--) { | ||
$l = $hunk_lines[$i]; | ||
if (!$done && $l eq "+\n") { | ||
$adj++; # Skip this line | ||
} elsif ($l =~ /^[ +]/) { | ||
$done = 1; | ||
unshift(@h, $l); | ||
} else { | ||
unshift(@h, $l); | ||
} | ||
} | ||
|
||
$l = $hunk_lines[0]; # Hunk header | ||
undef @hunk_lines; # Free memory | ||
|
||
if ($adj) { | ||
die unless | ||
($l =~ /^\@\@\s+\-([0-9]+),([0-9]+)\s+\+([0-9]+),([0-9]+)\s\@\@(.*)$/); | ||
my $mstart = $1; | ||
my $mlin = $2; | ||
my $pstart = $3; | ||
my $plin = $4; | ||
my $tail = $5; # doesn't include the final newline | ||
|
||
$l = sprintf("@@ -%d,%d +%d,%d @@%s\n", | ||
$mstart, $mlin, $pstart, $plin-$adj, | ||
$tail); | ||
} | ||
unshift(@h, $l); | ||
|
||
# Transfer to the output array | ||
foreach $l (@h) { | ||
$out_bytes += length($l); | ||
push(@lines, $l); | ||
} | ||
|
||
$in_hunk = 0; | ||
} | ||
} | ||
} | ||
|
||
if ($in_hunk) { | ||
print STDERR "$name: $f: malformed patch\n"; | ||
$err = 1; | ||
} | ||
|
||
if (!$err) { | ||
if ($in_bytes != $out_bytes) { | ||
# Only write to the file if changed | ||
seek(FILE, 0, 0); | ||
print FILE @lines; | ||
|
||
if ( !defined($where = tell(FILE)) || | ||
!truncate(FILE, $where) ) { | ||
die "$name: Failed to truncate modified file: $f: $!\n"; | ||
} | ||
} | ||
} | ||
|
||
close(FILE); | ||
} |