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