summaryrefslogtreecommitdiffstats
path: root/scripts/remove-trailing-ws.in
blob: 8179a9aed91162a6193a91a6ee040ddcbdc327d0 (plain) (blame)
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
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
144
145
#! @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);

# This ugly trick lets the script work even if gettext support is missing.
# We did so because Locale::gettext doesn't ship with the standard perl
# distribution.
BEGIN {
    if (eval { require Locale::gettext }) {
	import Locale::gettext;
	require POSIX;
	import POSIX, qw(setlocale);
    } else {
	eval '
	    use constant LC_MESSAGES => 0;
	    sub setlocale($$) { }
	    sub bindtextdomain($$) { }
	    sub textdomain($) { }
	    sub gettext($) { shift }
	'
    }
}

setlocale(LC_MESSAGES, "");
bindtextdomain("quilt", "@LOCALEDIR@");
textdomain("quilt");

sub _($) {
    return gettext(shift);
}

$opt_p = 0;
getopts('np:')
    or die sprintf(_("SYNOPSIS: %s [-p num] [-n] [patch]\n"), $0);

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 sprintf(_("%s: I'm confused.\n"), $0);
		    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 sprintf(_("%s: I'm confused.\n"), $0);
		    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 sprintf(
_("Warning: trailing whitespace in line %s of %s\n"), $lines[0], $file)
	    if @lines == 1;
	print STDERR sprintf(
_("Warning: trailing whitespace in lines %s of %s\n"), join(',', @lines), $file)
	    if @lines > 1;
    } else {
	print STDERR sprintf(
_("Removing trailing whitespace from line %s of %s\n"), $lines[0], $file)
	    if @lines == 1;
	print STDERR sprintf(
_("Removing trailing whitespace from lines %s of %s\n"), join(',', @lines), $file)
	    if @lines > 1;
    }

    unless ($opt_n) {
	my $fh = new FileHandle("< $file")
	    or die "$file: $!\n";
	my ($tmp, $tmpname) = mkstemp("$file.XXXXXX")
	    or die "$file.*: $!\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 sprintf(_("Renaming %s to %s: %s\n"), $tmpname, $file, $!);
    }
}