summaryrefslogtreecommitdiff
blob: 13199715c9fadd9784d323a34c8a064b4171dd05 (plain)
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
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
--- a/colorgcc
+++ b/colorgcc
@@ -88,16 +88,16 @@
 #
 # 1.0.0 Initial Version
 
+use strict;
+
 use Term::ANSIColor;
 use IPC::Open3;
+use Cwd 'abs_path';
+
+my(%nocolor, %colors, %compilerPaths);
 
 sub initDefaults
 {
-   $compilerPaths{"gcc"} = "/usr/local/bin/gcc";
-   $compilerPaths{"g++"} = "/usr/local/bin/g++";
-   $compilerPaths{"cc"}  = "/usr/bin/cc";
-   $compilerPaths{"c++"} = "/usr/local/bin/c++";
-
    $nocolor{"dumb"} = "true";
 
    $colors{"srcColor"} = color("cyan");
@@ -125,26 +125,26 @@
       next if (m/^\#.*/);          # It's a comment.
       next if (!m/(.*):\s*(.*)/);  # It's not of the form "foo: bar".
 
-      $option = $1;
-      $value = $2;
+      my $option = $1;
+      my $value = $2;
 
-      if ($option =~ m/cc|c\+\+|gcc|g\+\+/)
-      {
-	 $compilerPaths{$option} = $value;
-      }
-      elsif ($option eq "nocolor")
+      if ($option eq "nocolor")
       {
 	 # The nocolor option lists terminal types, separated by
 	 # spaces, not to do color on.
-	 foreach $termtype (split(/\s+/, $value))
+	 foreach my $term (split(' ', $value))
 	 {
-	    $nocolor{$termtype} = "true";
+	    $nocolor{$term} = 1;
 	 }
       }
-      else
+      elsif (defined $colors{$option})
       {
 	 $colors{$option} = color($value);
       }
+      else
+      {
+	 $compilerPaths{$option} = $value;
+      }
    }
    close(PREFS);
 }
@@ -180,41 +180,80 @@
 initDefaults();
 
 # Read the configuration file, if there is one.
-$configFile = $ENV{"HOME"} . "/.colorgccrc";
+my $configFile = $ENV{"HOME"} . "/.colorgccrc";
 if (-f $configFile)
 {
    loadPreferences($configFile);
 }
+elsif (-f '/etc/colorgcc/colorgccrc')
+{
+   loadPreferences('/etc/colorgcc/colorgccrc');
+}
 
 # Figure out which compiler to invoke based on our program name.
 $0 =~ m%.*/(.*)$%;
-$progName = $1 || $0;
-
-$compiler = $compilerPaths{$progName} || $compilerPaths{"gcc"};
-
-# Get the terminal type. 
-$terminal = $ENV{"TERM"} || "dumb";
+my $progName = $1 || $0;
+my $compiler_pid;
 
-# 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 (! -t STDOUT || $nocolor{$terminal})
+# If called as "colorgcc", just filter STDIN to STDOUT.
+if ($progName eq 'colorgcc')
 {
-   exec $compiler, @ARGV
-      or die("Couldn't exec");
+   open(GCCOUT, "<&STDIN");
 }
+else
+{
+   # See if the user asked for a specific compiler.
+   my $compiler;
+   if (!defined($compiler = $compilerPaths{$progName}))
+   {
+      # Find our wrapper dir on the PATH and tweak the PATH to remove
+      # everything up-to and including our wrapper dir.
+      if ($0 =~ m#(.*)/#)
+      {
+	 # We were called with an explicit path, so trim that off the PATH.
+	 my $find = $1;
+	 $find = abs_path($1) unless $find =~ m#^/#;
+	 $ENV{'PATH'} =~ s#.*(^|:)\Q$find\E(:|$)##;
+      }
+      else
+      {
+	 my(@dirs) = split(/:/, $ENV{'PATH'});
+	 while (defined($_ = shift @dirs))
+	 {
+	    if (-x "$_/$progName")
+	    {
+	       $ENV{'PATH'} = join(':', @dirs);
+	       last;
+	    }
+	 }
+      }
+      $compiler = $progName;
+   }
 
-# 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, @ARGV);
+   # Get the terminal type. 
+   my $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 (! -t STDOUT || $nocolor{$terminal})
+   {
+      exec $compiler, @ARGV
+	 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, @ARGV);
+}
 
 # Colorize the output from the compiler.
 while(<GCCOUT>)
 {
-   if (m/^(.*?):([0-9]+):(.*)$/) # filename:lineno:message
+   if (m#^(.+?\.[^:/ ]+):([0-9]+):(.*)$#) # filename:lineno:message
    {
-      $field1 = $1 || "";
-      $field2 = $2 || "";
-      $field3 = $3 || "";
+      my $field1 = $1 || "";
+      my $field2 = $2 || "";
+      my $field3 = $3 || "";
 
       if ($field3 =~ m/\s+warning:.*/)
       {
@@ -232,6 +271,10 @@
       }
       print("\n");
    }
+   elsif (m/^:.+`.*'$/) # filename:message:
+   {
+      srcscan($_, $colors{"warningMessageColor"});
+   }
    elsif (m/^(.*?):(.+):$/) # filename:message:
    {
       # No line number, treat as an "introductory" line of text.
@@ -244,11 +287,9 @@
    }
 }
 
-# Get the return code of the compiler and exit with that.
-waitpid($compiler_pid, 0);
-exit ($? >> 8);
-
-
-
-
-
+if ($compiler_pid)
+{
+   # Get the return code of the compiler and exit with that.
+   waitpid($compiler_pid, 0);
+   exit ($? >> 8);
+}
--- a/colorgccrc
+++ b/colorgccrc
@@ -20,12 +20,14 @@
 # For example, srcColor: bold cyan on_yellow
 #
 
-# Define the paths to the actual location of the various compilers.
+# Only define the paths to the actual location of the various compilers if
+# you need to do something weird.  For normal installs, we'll figure out
+# who to call next automatically.
 # (Currently, colorgcc only understands these: g++ gcc c++ cc)
-g++: /usr/local/bin/g++
-gcc: /usr/local/bin/gcc
-c++: /usr/local/bin/c++
-cc:  /usr/bin/cc
+##g++: /usr/bin/g++
+##gcc: /usr/bin/gcc
+##c++: /usr/bin/c++
+##cc:  /usr/bin/cc
 
 # Don't do color if our terminal type ($TERM) is one of these.
 # (List all terminal types on one line, seperated by whitespace.)
@@ -43,12 +45,10 @@
 
 # Warnings
 warningFileNameColor: reset
-warningNumberColor:   white
+warningNumberColor:   blue
 warningMessageColor:  yellow
 
 # Errors
 errorFileNameColor: reset
-errorNumberColor:   white
+errorNumberColor:   blue
 errorMessageColor:  bold red
-
-
--- a/INSTALL
+++ b/INSTALL
@@ -27,9 +27,9 @@
 When "g++" is invoked, colorgcc is run instead.  colorgcc looks at the
 program name to figure out which compiler to use. 
 
-Copy the sample colorgccrc file to $HOME/.colorgccrc and make sure the
-absolute paths for the compilers are correct for your system.
-See the comments in the sample .colorgccrc for more information.
+Modify the file /etc/colorgcc/colorgccrc if you want to change the default
+values for everyone.  For individual customizations, copy this file to
+$HOME/.colorgccrc and change that.
 
 
 Note: