Created
August 12, 2016 08:33
-
-
Save everwanna/eff719fcfc5005d18ba5635e5d21012b to your computer and use it in GitHub Desktop.
colorgcc for ubuntu 12.04
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#! /usr/bin/perl -w | |
# | |
# | |
# lrwxrwxrwx 1 root root 17 Aug 10 03:12 /usr/local/bin/g++ -> /usr/bin/colorgcc | |
# lrwxrwxrwx 1 root root 17 Aug 10 03:12 /usr/local/bin/gcc -> /usr/bin/colorgcc | |
# | |
# colorgcc | |
# | |
# Version: 1.3.2 | |
# | |
# $Id: colorgcc,v 1.10 1999/04/29 17:15:52 jamoyers Exp $ | |
# | |
# A wrapper to colorize the output from compilers whose messages | |
# match the "gcc" format. | |
# | |
# Requires the ANSIColor module from CPAN. | |
# | |
# Usage: | |
# | |
# In a directory that occurs in your PATH _before_ the directory | |
# where the compiler lives, create a softlink to colorgcc for | |
# each compiler you want to colorize: | |
# | |
# g++ -> colorgcc | |
# gcc -> colorgcc | |
# cc -> colorgcc | |
# etc. | |
# | |
# That's it. When "g++" is invoked, colorgcc is run instead. | |
# colorgcc looks at the program name to figure out which compiler to run. | |
# | |
# The default settings can be overridden with ~/.colorgccrc. | |
# See the comments in the sample .colorgccrc for more information. | |
# | |
# Note: | |
# | |
# colorgcc will only emit color codes if: | |
# | |
# (1) Its STDOUT is a tty and | |
# (2) the value of $TERM is not listed in the "nocolor" option. | |
# | |
# If colorgcc colorizes the output, the compiler's STDERR will be | |
# combined with STDOUT. Otherwise, colorgcc just passes the output from | |
# the compiler through without modification. | |
# | |
# Author: Jamie Moyers <jmoyers@geeks.com> | |
# Started: April 20, 1999 | |
# Licence: GNU Public License | |
# | |
# Credits: | |
# | |
# I got the idea for this from a script called "color_cvs": | |
# color_cvs .03 Adrian Likins <adrian@gimp.org> <adrian@redhat.com> | |
# | |
# <seh4@ix.netcom.com> (Scott Harrington) | |
# Much improved handling of compiler command line arguments. | |
# exec compiler when not colorizing to preserve STDOUT, STDERR. | |
# Fixed my STDIN kludge. | |
# | |
# <ecarotti@athena.polito.it> (Elias S. G. Carotti) | |
# Corrected handling of text like -DPACKAGE=\"Package\" | |
# Spotted return code bug. | |
# | |
# <erwin@erwin.andreasen.org> (Erwin S. Andreasen) | |
# <schurchi@ucsd.edu> (Steve Churchill) | |
# Return code bug fixes. | |
# | |
# <rik@kde.org> (Rik Hemsley) | |
# Found STDIN bug. | |
# | |
# Changes: | |
# | |
# 1.3.2 Better handling of command line arguments to compiler. | |
# | |
# If we aren't colorizing output, we just exec the compiler which | |
# preserves the original STDOUT and STDERR. | |
# | |
# Removed STDIN kludge. STDIN being passed correctly now. | |
# | |
# 1.3.1 Added kludge to copy STDIN to the compiler's STDIN. | |
# | |
# 1.3.0 Now correctly returns (I hope) the return code of the compiler | |
# process as its own. | |
# | |
# 1.2.1 Applied patch to handle text similar to -DPACKAGE=\"Package\". | |
# | |
# 1.2.0 Added tty check. If STDOUT is not a tty, don't do color. | |
# | |
# 1.1.0 Added the "nocolor" option to turn off the color if the terminal type | |
# ($TERM) is listed. | |
# | |
# 1.0.0 Initial Version | |
use Term::ANSIColor; | |
use IPC::Open3; | |
sub initDefaults | |
{ | |
$compilerPaths{"gcc"} = "/usr/bin/gcc-4.6"; | |
$compilerPaths{"g++"} = "/usr/bin/g++-4.6"; | |
$compilerPaths{"cc"} = "/usr/bin/gcc"; | |
$compilerPaths{"c++"} = "/usr/bin/g++"; | |
$compilerPaths{"g77"} = "/usr/bin/g77"; | |
$compilerPaths{"f77"} = "/usr/bin/g77"; | |
$compilerPaths{"gcj"} = "/usr/bin/gcj"; | |
$nocolor{"dumb"} = "true"; | |
$colors{"srcColor"} = color("cyan"); | |
$colors{"introColor"} = color("blue"); | |
$colors{"warningFileNameColor"} = color("yellow"); | |
$colors{"warningNumberColor"} = color("yellow"); | |
$colors{"warningMessageColor"} = color("yellow"); | |
$colors{"errorFileNameColor"} = color("bold red"); | |
$colors{"errorNumberColor"} = color("bold red"); | |
$colors{"errorMessageColor"} = color("bold red"); | |
@{$translations{"warning"}} = (); | |
@{$translations{"error"}} = (); | |
} | |
sub loadPreferences | |
{ | |
# Usage: loadPreferences("filename"); | |
my($filename) = @_; | |
open(PREFS, "<$filename") || return; | |
my $gccVersion; | |
my $overrideCompilerPaths = 0; | |
while(<PREFS>) | |
{ | |
next if (m/^\#.*/); # It's a comment. | |
next if (!m/(.*):\s*(.*)/); # It's not of the form "foo: bar". | |
$option = $1; | |
$value = $2; | |
if ($option =~ m/\A(cc|c\+\+|gcc|g\+\+|g77|f77|gcj)\Z/) | |
{ | |
$compilerPaths{$option} = $value; | |
$overrideCompilerPaths = 1; | |
} | |
elsif ($option eq "gccVersion") | |
{ | |
$gccVersion = $value; | |
} | |
elsif ($option eq "nocolor") | |
{ | |
# The nocolor option lists terminal types, separated by | |
# spaces, not to do color on. | |
foreach $termtype (split(/\s+/, $value)) | |
{ | |
$nocolor{$termtype} = "true"; | |
} | |
} | |
elsif ($option =~ m/(.+)Translations/) | |
{ | |
@{$translations{$1}} = split(/\s+/, $value); | |
} | |
elsif ($option =~ m/Color$/) | |
{ | |
$colors{$option} = color($value); | |
} | |
else | |
{ | |
# treat unknown options as user defined compilers | |
$compilerPaths{$option} = $value; | |
} | |
} | |
close(PREFS); | |
# Append "-<gccVersion>" to user-defined compilerPaths | |
if ($overrideCompilerPaths && $gccVersion) { | |
$compilerPaths{$_} .= "-$gccVersion" foreach (keys %compilerPaths); | |
} | |
} | |
sub srcscan | |
{ | |
# Usage: srcscan($text, $normalColor) | |
# $text -- the text to colorize | |
# $normalColor -- The escape sequence to use for non-source text. | |
# Looks for text between ` and ', and colors it srcColor. | |
my($line, $normalColor) = @_; | |
my($srcon) = color("reset") . $colors{"srcColor"}; | |
my($srcoff) = color("reset") . $normalColor; | |
$line = $normalColor . $line; | |
# This substitute replaces `foo' with `AfooB' where A is the escape | |
# sequence that turns on the the desired source color, and B is the | |
# escape sequence that returns to $normalColor. | |
$line =~ s/(\`|\')(.*?)\'/\`$srcon$2$srcoff\'/g; | |
print($line, color("reset")); | |
} | |
# | |
# Main program | |
# | |
# Set up default values for colors and compilers. | |
initDefaults(); | |
# Read the configuration file, if there is one. | |
# $configFile = $ENV{"HOME"} . "/.colorgccrc"; | |
my($found_HOME) = 0; | |
while (my ($key, $value) = each (%ENV)) | |
{ | |
if ($key =~ /HOME/) | |
{ | |
$found_HOME = 1; | |
last; | |
} | |
} | |
if ($found_HOME == 0) | |
{ | |
$ENV{"HOME"} = "/"; | |
} | |
$configFile = $ENV{"HOME"} . "/.colorgccrc"; | |
# env['CC'] = 'colorgcc' | |
# env['CXX'] = 'colorgcc' | |
$default_configFile = "/etc/colorgcc/colorgccrc"; | |
if (-f $configFile) | |
{ | |
loadPreferences($configFile); | |
} elsif (-f $default_configFile ) { | |
loadPreferences($default_configFile) | |
} | |
# Figure out which compiler to invoke based on our program name. | |
$0 =~ m%.*/(.*)$%; | |
$progName = $1 || $0; | |
$compiler = $compilerPaths{$progName} || $compilerPaths{"gcc"}; | |
@comp_list = split /\s+/, $compiler; | |
$compiler = $comp_list[0]; | |
@comp_args = ( @comp_list[1 .. $#comp_list], @ARGV ); | |
# Check that we don't reference self | |
die "$compiler is self-referencing" | |
if ( -l $compiler and (stat $compiler)[1] == (stat $0)[1] ); | |
# Get the terminal type. | |
$terminal = $ENV{"TERM"} || "dumb"; | |
# If it's in the list of terminal types not to color, or if | |
# we're writing to something that's not a tty, don't do color. | |
if (! $ENV{"CGCC_FORCE_COLOR"} && (! -t STDOUT || $nocolor{$terminal})) | |
{ | |
exec $compiler, @comp_args | |
or die("Couldn't exec"); | |
} | |
# Keep the pid of the compiler process so we can get its return | |
# code and use that as our return code. | |
$compiler_pid = open3('<&STDIN', \*GCCOUT, \*GCCOUT, $compiler, @comp_args); | |
binmode(\*GCCOUT,":bytes"); | |
binmode(\*STDOUT,":bytes"); | |
# Colorize the output from the compiler. | |
while(<GCCOUT>) | |
{ | |
if (m/^(.*?):([0-9]+):(.*)$/) # filename:lineno:message | |
{ | |
$field1 = $1 || ""; | |
$field2 = $2 || ""; | |
$field3 = $3 || ""; | |
# See if this is a warning message. | |
$is_warning = 0; | |
for $translation ("warning", @{$translations{"warning"}}) | |
{ | |
if ($field3 =~ m/\s+$translation:.*/) | |
{ | |
$is_warning = 1; | |
last; | |
} | |
} | |
if ($is_warning) | |
{ | |
# Warning | |
print($colors{"warningFileNameColor"}, "$field1:", color("reset")); | |
print($colors{"warningNumberColor"}, "$field2:", color("reset")); | |
srcscan($field3, $colors{"warningMessageColor"}); | |
} | |
else | |
{ | |
# Error | |
print($colors{"errorFileNameColor"}, "$field1:", color("reset")); | |
print($colors{"errorNumberColor"}, "$field2:", color("reset")); | |
srcscan($field3, $colors{"errorMessageColor"}); | |
} | |
print("\n"); | |
} | |
elsif (m/^(<command-line>):(.*)$/) # special-location:message | |
{ | |
$field1 = $1 || ""; | |
$field2 = $2 || ""; | |
# See if this is a warning message. | |
$is_warning = 0; | |
for $translation ("warning", @{$translations{"warning"}}) | |
{ | |
if ($field2 =~ m/\s+$translation:.*/) | |
{ | |
$is_warning = 1; | |
last; | |
} | |
} | |
if ($is_warning) | |
{ | |
# Warning | |
print($colors{"warningFileNameColor"}, "$field1:", color("reset")); | |
srcscan($field2, $colors{"warningMessageColor"}); | |
} | |
else | |
{ | |
# Error | |
print($colors{"errorFileNameColor"}, "$field1:", color("reset")); | |
srcscan($field2, $colors{"errorMessageColor"}); | |
} | |
print("\n"); | |
} | |
elsif (m/^(.*?):(.+):$/) # filename:message: | |
{ | |
# No line number, treat as an "introductory" line of text. | |
srcscan($_, $colors{"introColor"}); | |
} | |
else # Anything else. | |
{ | |
# Doesn't seem to be a warning or an error. Print normally. | |
print(color("reset"), $_); | |
} | |
} | |
# Get the return code of the compiler and exit with that. | |
waitpid($compiler_pid, 0); | |
exit ($? >> 8); | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment