Merge git://git.kernel.org/pub/scm/gitk/gitk
[git.git] / contrib / colordiff / colordiff.perl
1 #!/usr/bin/perl -w
2 #
3 # $Id: colordiff.pl,v 1.4.2.10 2004/01/04 15:02:59 daveewart Exp $
4
5 ########################################################################
6 #                                                                      #
7 # ColorDiff - a wrapper/replacment for 'diff' producing                #
8 #             colourful output                                         #
9 #                                                                      #
10 # Copyright (C)2002-2004 Dave Ewart (davee@sungate.co.uk)              #
11 #                                                                      #
12 ########################################################################
13 #                                                                      #
14 # This program is free software; you can redistribute it and/or modify #
15 # it under the terms of the GNU General Public License as published by #
16 # the Free Software Foundation; either version 2 of the License, or    #
17 # (at your option) any later version.                                  #
18 #                                                                      #
19 # This program is distributed in the hope that it will be useful,      #
20 # but WITHOUT ANY WARRANTY; without even the implied warranty of       #
21 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the        #
22 # GNU General Public License for more details.                         #
23 #                                                                      #
24 # You should have received a copy of the GNU General Public License    #
25 # along with this program; if not, write to the Free Software          #
26 # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.            #
27 #                                                                      #
28 ########################################################################
29
30 use strict;
31 use Getopt::Long qw(:config pass_through);
32 use IPC::Open2;
33
34 my $app_name     = 'colordiff';
35 my $version      = '1.0.4';
36 my $author       = 'Dave Ewart';
37 my $author_email = 'davee@sungate.co.uk';
38 my $app_www      = 'http://colordiff.sourceforge.net/';
39 my $copyright    = '(C)2002-2004';
40 my $show_banner  = 1;
41
42 # ANSI sequences for colours
43 my %colour;
44 $colour{white}       = "\033[1;37m";
45 $colour{yellow}      = "\033[1;33m";
46 $colour{green}       = "\033[1;32m";
47 $colour{blue}        = "\033[1;34m";
48 $colour{cyan}        = "\033[1;36m";
49 $colour{red}         = "\033[1;31m";
50 $colour{magenta}     = "\033[1;35m";
51 $colour{black}       = "\033[1;30m";
52 $colour{darkwhite}   = "\033[0;37m";
53 $colour{darkyellow}  = "\033[0;33m";
54 $colour{darkgreen}   = "\033[0;32m";
55 $colour{darkblue}    = "\033[0;34m";
56 $colour{darkcyan}    = "\033[0;36m";
57 $colour{darkred}     = "\033[0;31m";
58 $colour{darkmagenta} = "\033[0;35m";
59 $colour{darkblack}   = "\033[0;30m";
60 $colour{OFF}         = "\033[0;0m";
61
62 # Default colours if /etc/colordiffrc or ~/.colordiffrc do not exist
63 my $plain_text = $colour{OFF};
64 my $file_old   = $colour{red};
65 my $file_new   = $colour{blue};
66 my $diff_stuff = $colour{magenta};
67
68 # Locations for personal and system-wide colour configurations
69 my $HOME   = $ENV{HOME};
70 my $etcdir = '/etc';
71
72 my ($setting, $value);
73 my @config_files = ("$etcdir/colordiffrc", "$HOME/.colordiffrc");
74 my $config_file;
75
76 foreach $config_file (@config_files) {
77     if (open(COLORDIFFRC, "<$config_file")) {
78         while (<COLORDIFFRC>) {
79             chop;
80             next if (/^#/ || /^$/);
81             s/\s+//g;
82             ($setting, $value) = split ('=');
83             if ($setting eq 'banner') {
84                 if ($value eq 'no') {
85                     $show_banner = 0;
86                 }
87                 next;
88             }
89             if (!defined $colour{$value}) {
90                 print "Invalid colour specification ($value) in $config_file\n";
91                 next;
92             }
93             if ($setting eq 'plain') {
94                 $plain_text = $colour{$value};
95             }
96             elsif ($setting eq 'oldtext') {
97                 $file_old = $colour{$value};
98             }
99             elsif ($setting eq 'newtext') {
100                 $file_new = $colour{$value};
101             }
102             elsif ($setting eq 'diffstuff') {
103                 $diff_stuff = $colour{$value};
104             }
105             else {
106                 print "Unknown option in $etcdir/colordiffrc: $setting\n";
107             }
108         }
109         close COLORDIFFRC;
110     }
111 }
112
113 # colordiff specfic options here.  Need to pre-declare if using variables
114 GetOptions(
115     "no-banner" => sub { $show_banner = 0 },
116     "plain-text=s" => \&set_color,
117     "file-old=s"   => \&set_color,
118     "file-new=s"   => \&set_color,
119     "diff-stuff=s" => \&set_color
120 );
121
122 if ($show_banner == 1) {
123     print STDERR "$app_name $version ($app_www)\n";
124     print STDERR "$copyright $author, $author_email\n\n";
125 }
126
127 if (defined $ARGV[0]) {
128     # More reliable way of pulling in arguments
129     open2(\*INPUTSTREAM, undef, "git", "diff", @ARGV);
130 }
131 else {
132     *INPUTSTREAM = \*STDIN;
133 }
134
135 my $record;
136 my $nrecs           = 0;
137 my $inside_file_old = 1;
138 my $nparents        = undef;
139
140 while (<INPUTSTREAM>) {
141     $nrecs++;
142     if (/^(\@\@+) -[-+0-9, ]+ \1/) {
143             print "$diff_stuff";
144             $nparents = length($1) - 1;
145     }
146     elsif (/^diff -/ || /^index / ||
147            /^old mode / || /^new mode / ||
148            /^deleted file mode / || /^new file mode / ||
149            /^similarity index / || /^dissimilarity index / ||
150            /^copy from / || /^copy to / ||
151            /^rename from / || /^rename to /) {
152             $nparents = undef;
153             print "$diff_stuff";
154     }
155     elsif (defined $nparents) {
156             if ($nparents == 1) {
157                     if (/^\+/) {
158                             print $file_new;
159                     }
160                     elsif (/^-/) {
161                             print $file_old;
162                     }
163                     else {
164                             print $plain_text;
165                     }
166             }
167             elsif (/^ {$nparents}/) {
168                     print "$plain_text";
169             }
170             elsif (/^[+ ]{$nparents}/) {
171                     print "$file_new";
172             }
173             elsif (/^[- ]{$nparents}/) {
174                     print "$file_old";
175             }
176             else {
177                     print $plain_text;
178             }
179     }
180     elsif (/^--- / || /^\+\+\+ /) {
181             print $diff_stuff;
182     }
183     else {
184             print "$plain_text";
185     }
186     s/$/$colour{OFF}/;
187     print "$_";
188 }
189 close INPUTSTREAM;
190
191 sub set_color {
192     my ($type, $color) = @_;
193
194     $type =~ s/-/_/;
195     eval "\$$type = \$colour{$color}";
196 }