|
|
1.1 root 1: /*
2: * Copyright (c) 1980 Regents of the University of California.
3: * All rights reserved.
4: *
5: * Redistribution and use in source and binary forms are permitted
6: * provided that: (1) source distributions retain this entire copyright
7: * notice and comment, and (2) distributions including binaries display
8: * the following acknowledgement: ``This product includes software
9: * developed by the University of California, Berkeley and its contributors''
10: * in the documentation or other materials provided with the distribution
11: * and in all advertising materials mentioning features or use of this
12: * software. Neither the name of the University nor the names of its
13: * contributors may be used to endorse or promote products derived
14: * from this software without specific prior written permission.
15: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
16: * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
17: * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
18: */
19:
20: #ifndef lint
21: static char sccsid[] = "@(#)errorinput.c 5.4 (Berkeley) 6/1/90";
22: #endif /* not lint */
23:
24: #include <stdio.h>
25: #include <ctype.h>
26: #include "error.h"
27:
28: int wordc; /* how long the current error message is */
29: char **wordv; /* the actual error message */
30:
31: int nerrors;
32: int language;
33:
34: Errorclass onelong();
35: Errorclass cpp();
36: Errorclass pccccom(); /* Portable C Compiler C Compiler */
37: Errorclass richieccom(); /* Richie Compiler for 11 */
38: Errorclass lint0();
39: Errorclass lint1();
40: Errorclass lint2();
41: Errorclass lint3();
42: Errorclass make();
43: Errorclass f77();
44: Errorclass pi();
45: Errorclass ri();
46: Errorclass troff();
47: Errorclass mod2();
48: /*
49: * Eat all of the lines in the input file, attempting to categorize
50: * them by their various flavors
51: */
52: static char inbuffer[BUFSIZ];
53:
54: eaterrors(r_errorc, r_errorv)
55: int *r_errorc;
56: Eptr **r_errorv;
57: {
58: extern boolean piflag;
59: Errorclass errorclass = C_SYNC;
60:
61: for (;;){
62: if (fgets(inbuffer, BUFSIZ, errorfile) == NULL)
63: break;
64: wordvbuild(inbuffer, &wordc, &wordv);
65: /*
66: * for convience, convert wordv to be 1 based, instead
67: * of 0 based.
68: */
69: wordv -= 1;
70: if ( wordc > 0 &&
71: ((( errorclass = onelong() ) != C_UNKNOWN)
72: || (( errorclass = cpp() ) != C_UNKNOWN)
73: || (( errorclass = pccccom() ) != C_UNKNOWN)
74: || (( errorclass = richieccom() ) != C_UNKNOWN)
75: || (( errorclass = lint0() ) != C_UNKNOWN)
76: || (( errorclass = lint1() ) != C_UNKNOWN)
77: || (( errorclass = lint2() ) != C_UNKNOWN)
78: || (( errorclass = lint3() ) != C_UNKNOWN)
79: || (( errorclass = make() ) != C_UNKNOWN)
80: || (( errorclass = f77() ) != C_UNKNOWN)
81: || ((errorclass = pi() ) != C_UNKNOWN)
82: || (( errorclass = ri() )!= C_UNKNOWN)
83: || (( errorclass = mod2() )!= C_UNKNOWN)
84: || (( errorclass = troff() )!= C_UNKNOWN))
85: ) ;
86: else
87: errorclass = catchall();
88: if (wordc)
89: erroradd(wordc, wordv+1, errorclass, C_UNKNOWN);
90: }
91: #ifdef FULLDEBUG
92: printf("%d errorentrys\n", nerrors);
93: #endif
94: arrayify(r_errorc, r_errorv, er_head);
95: }
96:
97: /*
98: * create a new error entry, given a zero based array and count
99: */
100: erroradd(errorlength, errorv, errorclass, errorsubclass)
101: int errorlength;
102: char **errorv;
103: Errorclass errorclass;
104: Errorclass errorsubclass;
105: {
106: reg Eptr newerror;
107: reg char *cp;
108:
109: if (errorclass == C_TRUE){
110: /* check canonicalization of the second argument*/
111: for(cp = errorv[1]; *cp && isdigit(*cp); cp++)
112: continue;
113: errorclass = (*cp == '\0') ? C_TRUE : C_NONSPEC;
114: #ifdef FULLDEBUG
115: if (errorclass != C_TRUE)
116: printf("The 2nd word, \"%s\" is not a number.\n",
117: errorv[1]);
118: #endif
119: }
120: if (errorlength > 0){
121: newerror = (Eptr)Calloc(1, sizeof(Edesc));
122: newerror->error_language = language; /* language is global */
123: newerror->error_text = errorv;
124: newerror->error_lgtext = errorlength;
125: if (errorclass == C_TRUE)
126: newerror->error_line = atoi(errorv[1]);
127: newerror->error_e_class = errorclass;
128: newerror->error_s_class = errorsubclass;
129: switch(newerror->error_e_class = discardit(newerror)){
130: case C_SYNC: nsyncerrors++; break;
131: case C_DISCARD: ndiscard++; break;
132: case C_NULLED: nnulled++; break;
133: case C_NONSPEC: nnonspec++; break;
134: case C_THISFILE: nthisfile++; break;
135: case C_TRUE: ntrue++; break;
136: case C_UNKNOWN: nunknown++; break;
137: case C_IGNORE: nignore++; break;
138: }
139: newerror->error_next = er_head;
140: er_head = newerror;
141: newerror->error_no = nerrors++;
142: } /* length > 0 */
143: }
144:
145: Errorclass onelong()
146: {
147: char **nwordv;
148: if ( (wordc == 1) && (language != INLD) ){
149: /*
150: * We have either:
151: * a) file name from cc
152: * b) Assembler telling world that it is complaining
153: * c) Noise from make ("Stop.")
154: * c) Random noise
155: */
156: wordc = 0;
157: if (strcmp(wordv[1], "Stop.") == 0){
158: language = INMAKE; return(C_SYNC);
159: }
160: if (strcmp(wordv[1], "Assembler:") == 0){
161: /* assembler always alerts us to what happened*/
162: language = INAS; return(C_SYNC);
163: } else
164: if (strcmp(wordv[1], "Undefined:") == 0){
165: /* loader complains about unknown symbols*/
166: language = INLD; return(C_SYNC);
167: }
168: if (lastchar(wordv[1]) == ':'){
169: /* cc tells us what file we are in */
170: currentfilename = wordv[1];
171: (void)substitute(currentfilename, ':', '\0');
172: language = INCC; return(C_SYNC);
173: }
174: } else
175: if ( (wordc == 1) && (language == INLD) ){
176: nwordv = (char **)Calloc(4, sizeof(char *));
177: nwordv[0] = "ld:";
178: nwordv[1] = wordv[1];
179: nwordv[2] = "is";
180: nwordv[3] = "undefined.";
181: wordc = 4;
182: wordv = nwordv - 1;
183: return(C_NONSPEC);
184: } else
185: if (wordc == 1){
186: return(C_SYNC);
187: }
188: return(C_UNKNOWN);
189: } /* end of one long */
190:
191: Errorclass cpp()
192: {
193: /*
194: * Now attempt a cpp error message match
195: * Examples:
196: * ./morse.h: 23: undefined control
197: * morsesend.c: 229: MAGNIBBL: argument mismatch
198: * morsesend.c: 237: MAGNIBBL: argument mismatch
199: * test1.c: 6: undefined control
200: */
201: if ( (language != INLD) /* loader errors have almost same fmt*/
202: && (lastchar(wordv[1]) == ':')
203: && (isdigit(firstchar(wordv[2])))
204: && (lastchar(wordv[2]) == ':') ){
205: language = INCPP;
206: clob_last(wordv[1], '\0');
207: clob_last(wordv[2], '\0');
208: return(C_TRUE);
209: }
210: return(C_UNKNOWN);
211: } /*end of cpp*/
212:
213: Errorclass pccccom()
214: {
215: /*
216: * Now attempt a ccom error message match:
217: * Examples:
218: * "morsesend.c", line 237: operands of & have incompatible types
219: * "test.c", line 7: warning: old-fashioned initialization: use =
220: * "subdir.d/foo2.h", line 1: illegal initialization
221: */
222: if ( (firstchar(wordv[1]) == '"')
223: && (lastchar(wordv[1]) == ',')
224: && (next_lastchar(wordv[1]) == '"')
225: && (strcmp(wordv[2],"line") == 0)
226: && (isdigit(firstchar(wordv[3])))
227: && (lastchar(wordv[3]) == ':') ){
228: clob_last(wordv[1], '\0'); /* drop last , */
229: clob_last(wordv[1], '\0'); /* drop last " */
230: wordv[1]++; /* drop first " */
231: clob_last(wordv[3], '\0'); /* drop : on line number */
232: wordv[2] = wordv[1]; /* overwrite "line" */
233: wordv++; /*compensate*/
234: wordc--;
235: currentfilename = wordv[1];
236: language = INCC;
237: return(C_TRUE);
238: }
239: return(C_UNKNOWN);
240: } /* end of ccom */
241: /*
242: * Do the error message from the Richie C Compiler for the PDP11,
243: * which has this source:
244: *
245: * if (filename[0])
246: * fprintf(stderr, "%s:", filename);
247: * fprintf(stderr, "%d: ", line);
248: *
249: */
250: Errorclass richieccom()
251: {
252: reg char *cp;
253: reg char **nwordv;
254: char *file;
255:
256: if (lastchar(wordv[1]) == ':'){
257: cp = wordv[1] + strlen(wordv[1]) - 1;
258: while (isdigit(*--cp))
259: continue;
260: if (*cp == ':'){
261: clob_last(wordv[1], '\0'); /* last : */
262: *cp = '\0'; /* first : */
263: file = wordv[1];
264: nwordv = wordvsplice(1, wordc, wordv+1);
265: nwordv[0] = file;
266: nwordv[1] = cp + 1;
267: wordc += 1;
268: wordv = nwordv - 1;
269: language = INCC;
270: currentfilename = wordv[1];
271: return(C_TRUE);
272: }
273: }
274: return(C_UNKNOWN);
275: }
276:
277: Errorclass lint0()
278: {
279: reg char **nwordv;
280: char *line, *file;
281: /*
282: * Attempt a match for the new lint style normal compiler
283: * error messages, of the form
284: *
285: * printf("%s(%d): %s\n", filename, linenumber, message);
286: */
287: if (wordc >= 2){
288: if ( (lastchar(wordv[1]) == ':')
289: && (next_lastchar(wordv[1]) == ')')
290: ) {
291: clob_last(wordv[1], '\0'); /* colon */
292: if (persperdexplode(wordv[1], &line, &file)){
293: nwordv = wordvsplice(1, wordc, wordv+1);
294: nwordv[0] = file; /* file name */
295: nwordv[1] = line; /* line number */
296: wordc += 1;
297: wordv = nwordv - 1;
298: language = INLINT;
299: return(C_TRUE);
300: }
301: wordv[1][strlen(wordv[1])] = ':';
302: }
303: }
304: return (C_UNKNOWN);
305: }
306:
307: Errorclass lint1()
308: {
309: char *line1, *line2;
310: char *file1, *file2;
311: char **nwordv1, **nwordv2;
312:
313: /*
314: * Now, attempt a match for the various errors that lint
315: * can complain about.
316: *
317: * Look first for type 1 lint errors
318: */
319: if (wordc > 1 && strcmp(wordv[wordc-1], "::") == 0){
320: /*
321: * %.7s, arg. %d used inconsistently %s(%d) :: %s(%d)
322: * %.7s value used inconsistently %s(%d) :: %s(%d)
323: * %.7s multiply declared %s(%d) :: %s(%d)
324: * %.7s value declared inconsistently %s(%d) :: %s(%d)
325: * %.7s function value type must be declared before use %s(%d) :: %s(%d)
326: */
327: language = INLINT;
328: if (wordc > 2
329: && (persperdexplode(wordv[wordc], &line2, &file2))
330: && (persperdexplode(wordv[wordc-2], &line1, &file1)) ){
331: nwordv1 = wordvsplice(2, wordc, wordv+1);
332: nwordv2 = wordvsplice(2, wordc, wordv+1);
333: nwordv1[0] = file1; nwordv1[1] = line1;
334: erroradd(wordc+2, nwordv1, C_TRUE, C_DUPL); /* takes 0 based*/
335: nwordv2[0] = file2; nwordv2[1] = line2;
336: wordc = wordc + 2;
337: wordv = nwordv2 - 1; /* 1 based */
338: return(C_TRUE);
339: }
340: }
341: return(C_UNKNOWN);
342: } /* end of lint 1*/
343:
344: Errorclass lint2()
345: {
346: char *file;
347: char *line;
348: char **nwordv;
349: /*
350: * Look for type 2 lint errors
351: *
352: * %.7s used( %s(%d) ), but not defined
353: * %.7s defined( %s(%d) ), but never used
354: * %.7s declared( %s(%d) ), but never used or defined
355: *
356: * bufp defined( "./metric.h"(10) ), but never used
357: */
358: if ( (lastchar(wordv[2]) == '(' /* ')' */ )
359: && (strcmp(wordv[4], "),") == 0) ){
360: language = INLINT;
361: if (persperdexplode(wordv[3], &line, &file)){
362: nwordv = wordvsplice(2, wordc, wordv+1);
363: nwordv[0] = file; nwordv[1] = line;
364: wordc = wordc + 2;
365: wordv = nwordv - 1; /* 1 based */
366: return(C_TRUE);
367: }
368: }
369: return(C_UNKNOWN);
370: } /* end of lint 2*/
371:
372: char *Lint31[4] = {"returns", "value", "which", "is"};
373: char *Lint32[6] = {"value", "is", "used,", "but", "none", "returned"};
374: Errorclass lint3()
375: {
376: if ( (wordvcmp(wordv+2, 4, Lint31) == 0)
377: || (wordvcmp(wordv+2, 6, Lint32) == 0) ){
378: language = INLINT;
379: return(C_NONSPEC);
380: }
381: return(C_UNKNOWN);
382: }
383:
384: /*
385: * Special word vectors for use by F77 recognition
386: */
387: char *F77_fatal[3] = {"Compiler", "error", "line"};
388: char *F77_error[3] = {"Error", "on", "line"};
389: char *F77_warning[3] = {"Warning", "on", "line"};
390: char *F77_no_ass[3] = {"Error.","No","assembly."};
391: f77()
392: {
393: char **nwordv;
394: /*
395: * look for f77 errors:
396: * Error messages from /usr/src/cmd/f77/error.c, with
397: * these printf formats:
398: *
399: * Compiler error line %d of %s: %s
400: * Error on line %d of %s: %s
401: * Warning on line %d of %s: %s
402: * Error. No assembly.
403: */
404: if (wordc == 3 && wordvcmp(wordv+1, 3, F77_no_ass) == 0) {
405: wordc = 0;
406: return(C_SYNC);
407: }
408: if (wordc < 6)
409: return(C_UNKNOWN);
410: if ( (lastchar(wordv[6]) == ':')
411: &&(
412: (wordvcmp(wordv+1, 3, F77_fatal) == 0)
413: || (wordvcmp(wordv+1, 3, F77_error) == 0)
414: || (wordvcmp(wordv+1, 3, F77_warning) == 0) )
415: ){
416: language = INF77;
417: nwordv = wordvsplice(2, wordc, wordv+1);
418: nwordv[0] = wordv[6];
419: clob_last(nwordv[0],'\0');
420: nwordv[1] = wordv[4];
421: wordc += 2;
422: wordv = nwordv - 1; /* 1 based */
423: return(C_TRUE);
424: }
425: return(C_UNKNOWN);
426: } /* end of f77 */
427:
428: char *Make_Croak[3] = {"***", "Error", "code"};
429: char *Make_NotRemade[5] = {"not", "remade", "because", "of", "errors"};
430: Errorclass make()
431: {
432: if (wordvcmp(wordv+1, 3, Make_Croak) == 0){
433: language = INMAKE;
434: return(C_SYNC);
435: }
436: if (wordvcmp(wordv+2, 5, Make_NotRemade) == 0){
437: language = INMAKE;
438: return(C_SYNC);
439: }
440: return(C_UNKNOWN);
441: }
442: Errorclass ri()
443: {
444: /*
445: * Match an error message produced by ri; here is the
446: * procedure yanked from the distributed version of ri
447: * April 24, 1980.
448: *
449: * serror(str, x1, x2, x3)
450: * char str[];
451: * char *x1, *x2, *x3;
452: * {
453: * extern int yylineno;
454: *
455: * putc('"', stdout);
456: * fputs(srcfile, stdout);
457: * putc('"', stdout);
458: * fprintf(stdout, " %d: ", yylineno);
459: * fprintf(stdout, str, x1, x2, x3);
460: * fprintf(stdout, "\n");
461: * synerrs++;
462: * }
463: */
464: if ( (firstchar(wordv[1]) == '"')
465: &&(lastchar(wordv[1]) == '"')
466: &&(lastchar(wordv[2]) == ':')
467: &&(isdigit(firstchar(wordv[2]))) ){
468: clob_last(wordv[1], '\0'); /* drop the last " */
469: wordv[1]++; /* skip over the first " */
470: clob_last(wordv[2], '\0');
471: language = INRI;
472: return(C_TRUE);
473: }
474: return(C_UNKNOWN);
475: }
476:
477: Errorclass catchall()
478: {
479: /*
480: * Catches random things.
481: */
482: language = INUNKNOWN;
483: return(C_NONSPEC);
484: } /* end of catch all*/
485:
486: Errorclass troff()
487: {
488: /*
489: * troff source error message, from eqn, bib, tbl...
490: * Just like pcc ccom, except uses `'
491: */
492: if ( (firstchar(wordv[1]) == '`')
493: && (lastchar(wordv[1]) == ',')
494: && (next_lastchar(wordv[1]) == '\'')
495: && (strcmp(wordv[2],"line") == 0)
496: && (isdigit(firstchar(wordv[3])))
497: && (lastchar(wordv[3]) == ':') ){
498: clob_last(wordv[1], '\0'); /* drop last , */
499: clob_last(wordv[1], '\0'); /* drop last " */
500: wordv[1]++; /* drop first " */
501: clob_last(wordv[3], '\0'); /* drop : on line number */
502: wordv[2] = wordv[1]; /* overwrite "line" */
503: wordv++; /*compensate*/
504: currentfilename = wordv[1];
505: language = INTROFF;
506: return(C_TRUE);
507: }
508: return(C_UNKNOWN);
509: }
510: Errorclass mod2()
511: {
512: /*
513: * for decwrl modula2 compiler (powell)
514: */
515: if ( ( (strcmp(wordv[1], "!!!") == 0) /* early version */
516: ||(strcmp(wordv[1], "File") == 0)) /* later version */
517: && (lastchar(wordv[2]) == ',') /* file name */
518: && (strcmp(wordv[3], "line") == 0)
519: && (isdigit(firstchar(wordv[4]))) /* line number */
520: && (lastchar(wordv[4]) == ':') /* line number */
521: ){
522: clob_last(wordv[2], '\0'); /* drop last , on file name */
523: clob_last(wordv[4], '\0'); /* drop last : on line number */
524: wordv[3] = wordv[2]; /* file name on top of "line" */
525: wordv += 2;
526: wordc -= 2;
527: currentfilename = wordv[1];
528: language = INMOD2;
529: return(C_TRUE);
530: }
531: return(C_UNKNOWN);
532: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.