ccfilter.c 8.4 KB

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