#! @PERL@ -w # Remove trailing whitespace from modified lines in working files. # # Input: diff between original and working files (unified or context # format). use strict; use FileHandle; use File::Temp qw( :mktemp ); use Getopt::Std; use vars qw($opt_p $opt_n); $opt_p = 0; getopts('np:') or die "SYNOPSIS: $0 [-p num] [-n] [patch]\n"; my %files; my $file; while (<>) { print unless $opt_n; if (/^--- ./) { # unified diff while (<>) { print unless $opt_n; if (/^\+\+\+ (.+?)(?:[ \t][^\t]*)?$/) { $file = $1; $file =~ s<^([^/]+/+){$opt_p}><>; #print STDERR "[$file]\n"; } elsif ($file && /^@@ -(\d+)(?:,(\d+))? \+(\d+)(?:,(\d+))? @@/) { my $removed = defined $2 ? $2 : 1; my $added = defined $4 ? $4 : 1; my $line_number = $3; while ($removed || $added) { $_ = <>; defined $_ or die "$0: I'm confused.\n"; if (/^\+/) { push @{$files{$file}}, $line_number if s/(^\+.*?)[ \t]+$/$1/; $added--; $line_number++; } elsif (/^-/) { $removed--; } elsif (/^ / || /^$/) { $removed--; $added--; $line_number++; } print unless $opt_n; } } } } elsif (/^\*\*\* ./) { # context diff while (<>) { print unless $opt_n; if ($file && /^--- (\d+)(?:,(\d+))? ----$/) { my $line_number = $1; my $last_line = defined $2 ? $2 : $1; while ($line_number <= $last_line) { $_ = <>; defined $_ or die "$0: I'm confused.\n"; if (s/(^[+!] .*?)[ \t]+$/$1/) { push @{$files{$file}}, $line_number; } $line_number++; print unless $opt_n; last if (/^\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*$/); } } elsif (/^--- (.+?)(?:[ \t][^\t]*)?$/) { $file = $1; $file =~ s<^([^/]+/+){$opt_p}><>; #print STDERR "[$file]\n"; } } } } foreach my $file (keys %files) { my @lines = @{$files{$file}}; if ($opt_n) { print STDERR "Warning: trailing whitespace in line"; } else { print STDERR "Removing trailing whitespace from line"; } print STDERR "s" if @lines > 1; print STDERR " " . join(',', @lines) . " of $file\n"; unless ($opt_n) { my $fh = new FileHandle("< $file") or die "$file: $!\n"; my ($tmp, $tmpname) = mkstemp("$file.XXXXXX") or die "$file.XXXXXX: $!\n"; while (<$fh>) { if (@lines && $lines[0] == $.) { s/[ \t]+$//; shift @lines; } print $tmp $_; } $fh->close; $tmp->close or die "$tmpname: $!\n"; rename $tmpname, $file or die "Renaming $tmpname to $file: $!\n"; } } #exit (%files ? 1 : 0);