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