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
30use strict;
31use Getopt::Long qw(:config pass_through);
32use IPC::Open2;
33
34my $app_name = 'colordiff';
35my $version = '1.0.4';
36my $author = 'Dave Ewart';
37my $author_email = 'davee@sungate.co.uk';
38my $app_www = 'http://colordiff.sourceforge.net/';
39my $copyright = '(C)2002-2004';
40my $show_banner = 1;
41
42# ANSI sequences for colours
43my %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
63my $plain_text = $colour{OFF};
64my $file_old = $colour{red};
65my $file_new = $colour{blue};
66my $diff_stuff = $colour{magenta};
67
68# Locations for personal and system-wide colour configurations
69my $HOME = $ENV{HOME};
70my $etcdir = '/etc';
71
72my ($setting, $value);
73my @config_files = ("$etcdir/colordiffrc", "$HOME/.colordiffrc");
74my $config_file;
75
76foreach $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
114GetOptions(
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
122if ($show_banner == 1) {
123 print STDERR "$app_name $version ($app_www)\n";
124 print STDERR "$copyright $author, $author_email\n\n";
125}
126
127if (defined $ARGV[0]) {
128 # More reliable way of pulling in arguments
129 open2(\*INPUTSTREAM, undef, "git", "diff", @ARGV);
130}
131else {
132 *INPUTSTREAM = \*STDIN;
133}
134
135my $record;
136my $nrecs = 0;
137my $inside_file_old = 1;
138my $nparents = undef;
139
140while (<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}
189close INPUTSTREAM;
190
191sub set_color {
192 my ($type, $color) = @_;
193
194 $type =~ s/-/_/;
195 eval "\$$type = \$colour{$color}";
196}