1 /* ======================================================================= */ 2 /* Project : VIM */ 3 /* Module : ccfilter Version: 02.01.01 */ 4 /* File : ccfilter.c */ 5 /* Purpose : Filter gmake/cc output into a standardized form */ 6 /* ======================================================================= */ 7 /* Created On: 12-Sep-95 20:32 */ 8 /* Last modification: 03-Feb-98 */ 9 /* -e option added by Bernd Feige */ 10 /* ======================================================================= */ 11 /* Copyright : */ 12 /* This source file is copyright (c) to Pablo Ariel Kohan */ 13 /* ======================================================================= */ 14 #define __CCFILTER_C__ 15 16 #include <ctype.h> 17 #include <stdio.h> 18 #include <string.h> 19 #include <unistd.h> 20 21 #define LINELENGTH 2048 22 23 /* Collector(s) */ 24 char Line[LINELENGTH]; 25 char Line2[LINELENGTH]; 26 /* Components */ 27 char FileName[1024]; 28 char BasePath[1024]; 29 char CWD[1024]; 30 unsigned long Row; 31 unsigned long Col; 32 char Severity; 33 char Reason[LINELENGTH]; 34 35 #define COMPILER_UNKNOWN 0 36 #define COMPILER_GCC 1 37 #define COMPILER_AIX 2 38 #define COMPILER_ATT 3 39 #define COMPILER_IRIX 4 40 #define COMPILER_SOLARIS 5 41 #define COMPILER_HPUX 6 42 43 char *COMPILER_Names[][2] = 44 { 45 /* Name Description */ 46 { "N/A", "" }, 47 { "GCC", "GCC compiler" }, 48 { "AIX", "AIX's C compiler" }, 49 { "ATT", "AT&T/NCR's High Performance C Compiler" }, 50 { "IRIX", "IRIX's MIPS/MIPSpro C compiler" }, 51 { "SOLARIS", "SOLARIS's SparcWorks C compiler" }, 52 { "HPUX", "HPUX's C compiler" } 53 }; 54 #define COMPILER_QTY (sizeof(COMPILER_Names)/sizeof(COMPILER_Names[0])) 55 56 #if defined(_GCC) 57 # define COMPILER_DEFAULT COMPILER_GCC 58 #elif defined(_AIX) 59 # define COMPILER_DEFAULT COMPILER_AIX 60 #elif defined(_ATT) 61 # define COMPILER_DEFAULT COMPILER_ATT 62 #elif defined(_IRIX) 63 # define COMPILER_DEFAULT COMPILER_IRIX 64 #elif defined(_SOLARIS) 65 # define COMPILER_DEFAULT COMPILER_SOLARIS 66 #elif defined(_HPUX) 67 # define COMPILER_DEFAULT COMPILER_HPUX 68 #else 69 # define COMPILER_DEFAULT COMPILER_UNKNOWN 70 #endif 71 72 const char USAGE[] = 73 "ccfilter v2.1 (c)1994-1997 by Pablo Ariel Kohan\n" 74 "Filter Out compiler's output, and converts it to fit VIM\n\n" 75 "Usage:\n" 76 " ccfilter [<options>]\n" 77 "Where: <options> is one or more of:\n" 78 " -c Decrement column by one\n" 79 " -r Decrement row by one\n" 80 " -e Echo stdin to stderr\n" 81 " -v Verbose (Outputs also invalid lines)\n" 82 " -o <COMPILER> Treat input as <COMPILER>'s output\n" 83 " Note: COMPILER may be preceded by an _\n" 84 " -h This usage.\n"; 85 86 87 int ShowUsage( char *szError ) 88 { int i; 89 90 fprintf( stderr, USAGE ); 91 92 fprintf( stderr, "Current default <COMPILER>: %s\n", 93 COMPILER_Names[COMPILER_DEFAULT][0] ); 94 95 fprintf( stderr, "Acceptable parameters for <COMPILER> are:\n" ); 96 for (i=1; i < COMPILER_QTY; i++) 97 fprintf( stderr, " %-15.15s %s\n", 98 COMPILER_Names[i][0], 99 COMPILER_Names[i][1] ); 100 fprintf(stderr, szError); 101 return 0; 102 } 103 104 char *echogets(char *s, int echo) { 105 char * const retval=fgets(s, LINELENGTH, stdin); 106 if (echo!=0 && retval!=NULL) { 107 fputs(retval, stderr); 108 } 109 return retval; 110 } 111 112 int main( int argc, char *argv[] ) 113 { int rv, i, j, ok; 114 int stay; 115 int prefetch; 116 char *p; 117 int dec_col = 0; /* Decrement column value by 1 */ 118 int dec_row = 0; /* Decrement row value by 1 */ 119 int echo = 0; /* Echo stdin to stderr */ 120 int verbose = 0; /* Include Bad Formatted Lines */ 121 int CWDlen; 122 int COMPILER = COMPILER_DEFAULT; 123 124 getcwd( CWD, sizeof(CWD) ); 125 CWDlen = strlen(CWD); 126 127 for (i=1; i<argc; i++) 128 { 129 if (argv[i][0] != '-') 130 return ShowUsage(""); 131 switch ( argv[i][1] ) 132 { 133 case 'c': 134 dec_col = 1; 135 break; 136 case 'r': 137 dec_row = 1; 138 break; 139 case 'e': 140 echo = 1; 141 break; 142 case 'v': 143 verbose = 1; 144 break; 145 case 'o': 146 { 147 if (i+1 >= argc) 148 return ShowUsage("Error: Missing parameter for -o\n"); 149 i++; 150 COMPILER = -1; 151 for (j=1; j<COMPILER_QTY; j++) 152 if ( (strcmp(argv[i], COMPILER_Names[j][0]) == 0) || 153 ( (argv[i][0] == '_') && 154 (strcmp(&argv[i][1], COMPILER_Names[j][0]) == 0) ) ) 155 COMPILER = j; 156 if (COMPILER == -1) 157 return ShowUsage("Error: Invalid COMPILER specified\n"); 158 } 159 break; 160 case 'h': 161 return ShowUsage(""); 162 default: 163 return ShowUsage("Error: Invalid option\n"); 164 } 165 } 166 if (COMPILER == 0) 167 return ShowUsage("Error: COMPILER must be specified in this system\n"); 168 169 stay = ( echogets(Line, echo) != NULL ); 170 prefetch = 0; 171 172 while( stay ) 173 { 174 *FileName = 0; 175 Row = 0; 176 Col = 0; 177 Severity = ' '; 178 *Reason = 0; 179 ok = 0; 180 switch (COMPILER) 181 { 182 case COMPILER_GCC: 183 Severity = 'e'; 184 #ifdef GOTO_FROM_WHERE_INCLUDED 185 rv = sscanf( Line, "In file included from %[^:]:%u:", 186 FileName, &Row ); 187 if ( rv == 2 ) 188 { 189 ok = (echogets(Reason, echo) != NULL); 190 } 191 else 192 #endif 193 { 194 if ((rv = sscanf( Line, "%[^:]:%u: warning: %[^\n]", 195 FileName, &Row, Reason ))==3) { 196 Severity = 'w'; 197 } else { 198 rv = sscanf( Line, "%[^:]:%u: %[^\n]", 199 FileName, &Row, Reason ); 200 } 201 ok = ( rv == 3 ); 202 } 203 Col = (dec_col ? 1 : 0 ); 204 break; 205 case COMPILER_AIX: 206 rv = sscanf( Line, "\"%[^\"]\", line %u.%u: %*s (%c) %[^\n]", 207 FileName, &Row, &Col, &Severity, Reason ); 208 ok = ( rv == 5 ); 209 break; 210 case COMPILER_HPUX: 211 rv = sscanf( Line, "cc: \"%[^\"]\", line %u: %c%*[^:]: %[^\n]", 212 FileName, &Row, &Severity, Reason ); 213 ok = ( rv == 4 ); 214 Col = (dec_col ? 1 : 0 ); 215 break; 216 case COMPILER_SOLARIS: 217 rv = sscanf( Line, "\"%[^\"]\", line %u: warning: %[^\n]", 218 FileName, &Row, Reason ); 219 Severity = 'w'; 220 ok = ( rv == 3 ); 221 if ( rv != 3 ) 222 { 223 rv = sscanf( Line, "\"%[^\"]\", line %u: %[^\n]", 224 FileName, &Row, Reason ); 225 Severity = 'e'; 226 ok = ( rv == 3 ); 227 } 228 Col = (dec_col ? 1 : 0 ); 229 break; 230 case COMPILER_ATT: 231 rv = sscanf( Line, "%c \"%[^\"]\",L%u/C%u%*[^:]:%[^\n]", 232 &Severity, FileName, &Row, &Col, Reason ); 233 ok = ( rv == 5 ); 234 235 if (rv != 5) 236 { rv = sscanf( Line, "%c \"%[^\"]\",L%u/C%u: %[^\n]", 237 &Severity, FileName, &Row, &Col, Reason ); 238 ok = ( rv == 5 ); 239 } 240 241 if (rv != 5) 242 { rv = sscanf( Line, "%c \"%[^\"]\",L%u: %[^\n]", 243 &Severity, FileName, &Row, Reason ); 244 ok = ( rv == 4 ); 245 Col = (dec_col ? 1 : 0 ); 246 } 247 248 stay = (echogets(Line2, echo) != NULL); 249 while ( stay && (Line2[0] == '|') ) 250 { for (p=&Line2[2]; (*p) && (isspace(*p)); p++); 251 strcat( Reason, ": " ); 252 strcat( Reason, p ); 253 Line2[0] = 0; 254 stay = (echogets(Line2, echo) != NULL); 255 } 256 prefetch = 1; 257 strcpy( Line, Line2 ); 258 break; 259 case COMPILER_IRIX: 260 Col = 1; 261 prefetch = 0; 262 rv = 0; 263 ok = 0; 264 if ( !strncmp(Line, "cfe: ", 5) ) 265 { p = &Line[5]; 266 Severity = tolower(*p); 267 p = strchr( &Line[5], ':' ); 268 if (p == NULL) 269 { ok = 0; 270 } 271 else 272 { 273 rv = sscanf( p+2, "%[^:]: %u: %[^\n]", 274 FileName, &Row, Reason ); 275 if (rv != 3) 276 rv = sscanf( p+2, "%[^,], line %u: %[^\n]", 277 FileName, &Row, Reason ); 278 ok = ( rv == 3 ); 279 } 280 281 if (ok) 282 { prefetch = 1; 283 stay = (echogets(Line, echo) != NULL); 284 if (Line[0] == ' ') 285 stay = (echogets(Line2, echo) != NULL); 286 if ( (Line2[0] == ' ') && 287 ( (Line2[1] == '-') || (Line2[1] == '^') ) ) 288 { Col = strlen(Line2)-1; 289 prefetch = 0; 290 } 291 else 292 { strcat( Line, "\n" ); 293 strcat( Line, Line2 ); 294 } 295 } 296 } 297 break; 298 } 299 if (dec_col) Col--; 300 if (dec_row) Row--; 301 if (!ok) 302 { 303 if ( Line[0] == 'g' ) 304 p = &Line[1]; 305 else 306 p = &Line[0]; 307 ok = sscanf( p, "make[%*d]: Entering directory `%[^']", 308 BasePath ); 309 if (verbose) 310 printf( "[%u]?%s\n", ok, Line ); 311 } 312 else 313 { 314 for (p=Reason; (*p) && (isspace(*p)); p++); 315 if ( BasePath[CWDlen] == 0 ) 316 printf( "%s:%u:%u:%c:%s\n", FileName, Row, Col, Severity, p ); 317 else 318 { 319 printf( "%s/%s:%u:%u:%c:%s\n", &BasePath[CWDlen+1], FileName, Row, Col, Severity, p ); 320 } 321 } 322 if (!prefetch) 323 stay = ( echogets(Line, echo) != NULL ); 324 } 325 return 0; 326 } 327