DevelopmentTools/ColorGCC: colorgcc2.pl

File colorgcc2.pl, 6.6 KB (added by brecht, 13 years ago)

colorgcc for GCC 2

Line 
1#!/boot/common/bin/perl -w
2
3#
4# colorgcc
5#
6# Version: 1.3.2
7#
8# $Id: colorgcc,v 1.10 1999/04/29 17:15:52 jamoyers Exp $
9#
10# A wrapper to colorize the output from compilers whose messages
11# match the "gcc" format.
12#
13# Requires the ANSIColor module from CPAN.
14#
15# Usage:
16#
17# In a directory that occurs in your PATH _before_ the directory
18# where the compiler lives, create a softlink to colorgcc for
19# each compiler you want to colorize:
20#
21# g++ -> colorgcc
22# gcc -> colorgcc
23# cc -> colorgcc
24# etc.
25#
26# That's it. When "g++" is invoked, colorgcc is run instead.
27# colorgcc looks at the program name to figure out which compiler to run.
28#
29# The default settings can be overridden with ~/.colorgccrc.
30# See the comments in the sample .colorgccrc for more information.
31#
32# Note:
33#
34# colorgcc will only emit color codes if:
35#
36# (1) Its STDOUT is a tty and
37# (2) the value of $TERM is not listed in the "nocolor" option.
38#
39# If colorgcc colorizes the output, the compiler's STDERR will be
40# combined with STDOUT. Otherwise, colorgcc just passes the output from
41# the compiler through without modification.
42#
43# Author: Jamie Moyers <jmoyers@geeks.com>
44# Started: April 20, 1999
45# Licence: GNU Public License
46#
47# Credits:
48#
49# I got the idea for this from a script called "color_cvs":
50# color_cvs .03 Adrian Likins <adrian@gimp.org> <adrian@redhat.com>
51#
52# <seh4@ix.netcom.com> (Scott Harrington)
53# Much improved handling of compiler command line arguments.
54# exec compiler when not colorizing to preserve STDOUT, STDERR.
55# Fixed my STDIN kludge.
56#
57# <ecarotti@athena.polito.it> (Elias S. G. Carotti)
58# Corrected handling of text like -DPACKAGE=\"Package\"
59# Spotted return code bug.
60#
61# <erwin@erwin.andreasen.org> (Erwin S. Andreasen)
62# <schurchi@ucsd.edu> (Steve Churchill)
63# Return code bug fixes.
64#
65# <rik@kde.org> (Rik Hemsley)
66# Found STDIN bug.
67#
68# Changes:
69#
70# 1.3.2 Better handling of command line arguments to compiler.
71#
72# If we aren't colorizing output, we just exec the compiler which
73# preserves the original STDOUT and STDERR.
74#
75# Removed STDIN kludge. STDIN being passed correctly now.
76#
77# 1.3.1 Added kludge to copy STDIN to the compiler's STDIN.
78#
79# 1.3.0 Now correctly returns (I hope) the return code of the compiler
80# process as its own.
81#
82# 1.2.1 Applied patch to handle text similar to -DPACKAGE=\"Package\".
83#
84# 1.2.0 Added tty check. If STDOUT is not a tty, don't do color.
85#
86# 1.1.0 Added the "nocolor" option to turn off the color if the terminal type
87# ($TERM) is listed.
88#
89# 1.0.0 Initial Version
90
91use Term::ANSIColor;
92use IPC::Open3;
93
94sub initDefaults
95{
96 $compilerPaths{"gcc"} = "/boot/develop/abi/x86/gcc2/tools/current/bin/gcc_real";
97 $compilerPaths{"g++"} = "/boot/develop/abi/x86/gcc2/tools/current/bin/g++_real";
98 #$compilerPaths{"cc"} = "/bin/cc";
99 #$compilerPaths{"c++"} = "/bin/c++";
100
101 $nocolor{"dumb"} = "true";
102
103 $colors{"srcColor"} = color("cyan");
104 $colors{"introColor"} = color("blue");
105
106 $colors{"warningFileNameColor"} = color("yellow");
107 $colors{"warningNumberColor"} = color("yellow");
108 $colors{"warningMessageColor"} = color("yellow");
109
110 $colors{"errorFileNameColor"} = color("bold red");
111 $colors{"errorNumberColor"} = color("bold red");
112 $colors{"errorMessageColor"} = color("bold red");
113}
114
115sub loadPreferences
116{
117# Usage: loadPreferences("filename");
118
119 my($filename) = @_;
120
121 open(PREFS, "<$filename") || return;
122
123 while(<PREFS>)
124 {
125 next if (m/^\#.*/); # It's a comment.
126 next if (!m/(.*):\s*(.*)/); # It's not of the form "foo: bar".
127
128 $option = $1;
129 $value = $2;
130
131 if ($option =~ m/cc|c\+\+|gcc|g\+\+/)
132 {
133 $compilerPaths{$option} = $value;
134 }
135 elsif ($option eq "nocolor")
136 {
137 # The nocolor option lists terminal types, separated by
138 # spaces, not to do color on.
139 foreach $termtype (split(/\s+/, $value))
140 {
141 $nocolor{$termtype} = "true";
142 }
143 }
144 else
145 {
146 $colors{$option} = color($value);
147 }
148 }
149 close(PREFS);
150}
151
152sub srcscan
153{
154# Usage: srcscan($text, $normalColor)
155# $text -- the text to colorize
156# $normalColor -- The escape sequence to use for non-source text.
157
158# Looks for text between ` and ', and colors it srcColor.
159
160 my($line, $normalColor) = @_;
161
162 my($srcon) = color("reset") . $colors{"srcColor"};
163 my($srcoff) = color("reset") . $normalColor;
164
165 $line = $normalColor . $line;
166
167 # This substitute replaces `foo' with `AfooB' where A is the escape
168 # sequence that turns on the the desired source color, and B is the
169 # escape sequence that returns to $normalColor.
170 $line =~ s/\`(.*?)\'/\`$srcon$1$srcoff\'/g;
171
172 print($line, color("reset"));
173}
174
175#
176# Main program
177#
178
179# Set up default values for colors and compilers.
180initDefaults();
181
182# Read the configuration file, if there is one.
183$configFile = $ENV{"HOME"} . "/.colorgccrc";
184if (-f $configFile)
185{
186 loadPreferences($configFile);
187}
188
189# Figure out which compiler to invoke based on our program name.
190$0 =~ m%.*/(.*)$%;
191$progName = $1 || $0;
192
193$compiler = $compilerPaths{$progName} || $compilerPaths{"gcc"};
194
195# Get the terminal type.
196$terminal = $ENV{"TERM"} || "dumb";
197
198# If it's in the list of terminal types not to color, or if
199# we're writing to something that's not a tty, don't do color.
200if (! -t STDOUT || $nocolor{$terminal})
201{
202 exec $compiler, @ARGV
203 or die("Couldn't exec");
204}
205
206# Keep the pid of the compiler process so we can get its return
207# code and use that as our return code.
208$compiler_pid = open3('<&STDIN', \*GCCOUT, '', $compiler, @ARGV);
209
210# Colorize the output from the compiler.
211while(<GCCOUT>)
212{
213 if (m/^(.*?):([0-9]+):(.*)$/) # filename:lineno:message
214 {
215 $field1 = $1 || "";
216 $field2 = $2 || "";
217 $field3 = $3 || "";
218
219 if ($field3 =~ m/\s+warning:.*/)
220 {
221 # Warning
222 print($colors{"warningFileNameColor"}, "$field1:", color("reset"));
223 print($colors{"warningNumberColor"}, "$field2:", color("reset"));
224 srcscan($field3, $colors{"warningMessageColor"});
225 }
226 else
227 {
228 # Error
229 print($colors{"errorFileNameColor"}, "$field1:", color("reset"));
230 print($colors{"errorNumberColor"}, "$field2:", color("reset"));
231 srcscan($field3, $colors{"errorMessageColor"});
232 }
233 print("\n");
234 }
235 elsif (m/^(.*?):(.+):$/) # filename:message:
236 {
237 # No line number, treat as an "introductory" line of text.
238 srcscan($_, $colors{"introColor"});
239 }
240 else # Anything else.
241 {
242 # Doesn't seem to be a warning or an error. Print normally.
243 print(color("reset"), $_);
244 }
245}
246
247# Get the return code of the compiler and exit with that.
248waitpid($compiler_pid, 0);
249exit ($? >> 8);
250
251
252
253
254