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