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 { 89 int i; 90 91 fprintf( stderr, USAGE ); 92 93 fprintf( stderr, "Current default <COMPILER>: %s\n", 94 COMPILER_Names[COMPILER_DEFAULT][0] ); 95 96 fprintf( stderr, "Acceptable parameters for <COMPILER> are:\n" ); 97 for (i=1; i < COMPILER_QTY; i++) 98 fprintf( stderr, " %-15.15s %s\n", 99 COMPILER_Names[i][0], 100 COMPILER_Names[i][1] ); 101 fprintf(stderr, szError); 102 return 0; 103 } 104 105 char *echogets(char *s, int echo) 106 { 107 char * const retval=fgets(s, LINELENGTH, stdin); 108 if (echo!=0 && retval!=NULL) { 109 fputs(retval, stderr); 110 } 111 return retval; 112 } 113 114 int main( int argc, char *argv[] ) 115 { int rv, i, j, ok; 116 int stay; 117 int prefetch; 118 char *p; 119 int dec_col = 0; /* Decrement column value by 1 */ 120 int dec_row = 0; /* Decrement row value by 1 */ 121 int echo = 0; /* Echo stdin to stderr */ 122 int verbose = 0; /* Include Bad Formatted Lines */ 123 int CWDlen; 124 int COMPILER = COMPILER_DEFAULT; 125 126 getcwd( CWD, sizeof(CWD) ); 127 CWDlen = strlen(CWD); 128 129 for (i=1; i<argc; i++) 130 { 131 if (argv[i][0] != '-') 132 return ShowUsage(""); 133 switch ( argv[i][1] ) 134 { 135 case 'c': 136 dec_col = 1; 137 break; 138 case 'r': 139 dec_row = 1; 140 break; 141 case 'e': 142 echo = 1; 143 break; 144 case 'v': 145 verbose = 1; 146 break; 147 case 'o': 148 { 149 if (i+1 >= argc) 150 return ShowUsage("Error: Missing parameter for -o\n"); 151 i++; 152 COMPILER = -1; 153 for (j=1; j<COMPILER_QTY; j++) 154 if ( (strcmp(argv[i], COMPILER_Names[j][0]) == 0) || 155 ( (argv[i][0] == '_') && 156 (strcmp(&argv[i][1], COMPILER_Names[j][0]) == 0) ) ) 157 COMPILER = j; 158 if (COMPILER == -1) 159 return ShowUsage("Error: Invalid COMPILER specified\n"); 160 } 161 break; 162 case 'h': 163 return ShowUsage(""); 164 default: 165 return ShowUsage("Error: Invalid option\n"); 166 } 167 } 168 if (COMPILER == 0) 169 return ShowUsage("Error: COMPILER must be specified in this system\n"); 170 171 stay = ( echogets(Line, echo) != NULL ); 172 prefetch = 0; 173 174 while( stay ) 175 { 176 *FileName = 0; 177 Row = 0; 178 Col = 0; 179 Severity = ' '; 180 *Reason = 0; 181 ok = 0; 182 switch (COMPILER) 183 { 184 case COMPILER_GCC: 185 Severity = 'e'; 186 #ifdef GOTO_FROM_WHERE_INCLUDED 187 rv = sscanf( Line, "In file included from %[^:]:%u:", 188 FileName, &Row ); 189 if ( rv == 2 ) 190 { 191 ok = (echogets(Reason, echo) != NULL); 192 } 193 else 194 #endif 195 { 196 if ((rv = sscanf( Line, "%[^:]:%u: warning: %[^\n]", 197 FileName, &Row, Reason ))==3) { 198 Severity = 'w'; 199 } else { 200 rv = sscanf( Line, "%[^:]:%u: %[^\n]", 201 FileName, &Row, Reason ); 202 } 203 ok = ( rv == 3 ); 204 } 205 Col = (dec_col ? 1 : 0 ); 206 break; 207 case COMPILER_AIX: 208 rv = sscanf( Line, "\"%[^\"]\", line %u.%u: %*s (%c) %[^\n]", 209 FileName, &Row, &Col, &Severity, Reason ); 210 ok = ( rv == 5 ); 211 break; 212 case COMPILER_HPUX: 213 rv = sscanf( Line, "cc: \"%[^\"]\", line %u: %c%*[^:]: %[^\n]", 214 FileName, &Row, &Severity, Reason ); 215 ok = ( rv == 4 ); 216 Col = (dec_col ? 1 : 0 ); 217 break; 218 case COMPILER_SOLARIS: 219 rv = sscanf( Line, "\"%[^\"]\", line %u: warning: %[^\n]", 220 FileName, &Row, Reason ); 221 Severity = 'w'; 222 ok = ( rv == 3 ); 223 if ( rv != 3 ) 224 { 225 rv = sscanf( Line, "\"%[^\"]\", line %u: %[^\n]", 226 FileName, &Row, Reason ); 227 Severity = 'e'; 228 ok = ( rv == 3 ); 229 } 230 Col = (dec_col ? 1 : 0 ); 231 break; 232 case COMPILER_ATT: 233 rv = sscanf( Line, "%c \"%[^\"]\",L%u/C%u%*[^:]:%[^\n]", 234 &Severity, FileName, &Row, &Col, Reason ); 235 ok = ( rv == 5 ); 236 237 if (rv != 5) 238 { rv = sscanf( Line, "%c \"%[^\"]\",L%u/C%u: %[^\n]", 239 &Severity, FileName, &Row, &Col, Reason ); 240 ok = ( rv == 5 ); 241 } 242 243 if (rv != 5) 244 { rv = sscanf( Line, "%c \"%[^\"]\",L%u: %[^\n]", 245 &Severity, FileName, &Row, Reason ); 246 ok = ( rv == 4 ); 247 Col = (dec_col ? 1 : 0 ); 248 } 249 250 stay = (echogets(Line2, echo) != NULL); 251 while ( stay && (Line2[0] == '|') ) 252 { for (p=&Line2[2]; (*p) && (isspace(*p)); p++); 253 strcat( Reason, ": " ); 254 strcat( Reason, p ); 255 Line2[0] = 0; 256 stay = (echogets(Line2, echo) != NULL); 257 } 258 prefetch = 1; 259 strcpy( Line, Line2 ); 260 break; 261 case COMPILER_IRIX: 262 Col = 1; 263 prefetch = 0; 264 rv = 0; 265 ok = 0; 266 if ( !strncmp(Line, "cfe: ", 5) ) 267 { p = &Line[5]; 268 Severity = tolower(*p); 269 p = strchr( &Line[5], ':' ); 270 if (p == NULL) 271 { ok = 0; 272 } 273 else 274 { 275 rv = sscanf( p+2, "%[^:]: %u: %[^\n]", 276 FileName, &Row, Reason ); 277 if (rv != 3) 278 rv = sscanf( p+2, "%[^,], line %u: %[^\n]", 279 FileName, &Row, Reason ); 280 ok = ( rv == 3 ); 281 } 282 283 if (ok) 284 { prefetch = 1; 285 stay = (echogets(Line, echo) != NULL); 286 if (Line[0] == ' ') 287 stay = (echogets(Line2, echo) != NULL); 288 if ( (Line2[0] == ' ') && 289 ( (Line2[1] == '-') || (Line2[1] == '^') ) ) 290 { Col = strlen(Line2)-1; 291 prefetch = 0; 292 } 293 else 294 { strcat( Line, "\n" ); 295 strcat( Line, Line2 ); 296 } 297 } 298 } 299 break; 300 } 301 if (dec_col) Col--; 302 if (dec_row) Row--; 303 if (!ok) 304 { 305 if ( Line[0] == 'g' ) 306 p = &Line[1]; 307 else 308 p = &Line[0]; 309 ok = sscanf( p, "make[%*d]: Entering directory `%[^']", 310 BasePath ); 311 if (verbose) 312 printf( "[%u]?%s\n", ok, Line ); 313 } 314 else 315 { 316 for (p=Reason; (*p) && (isspace(*p)); p++); 317 if ( BasePath[CWDlen] == 0 ) 318 printf( "%s:%u:%u:%c:%s\n", FileName, Row, Col, Severity, p ); 319 else 320 { 321 printf( "%s/%s:%u:%u:%c:%s\n", &BasePath[CWDlen+1], FileName, Row, Col, Severity, p ); 322 } 323 } 324 if (!prefetch) 325 stay = ( echogets(Line, echo) != NULL ); 326 } 327 return 0; 328 } 329