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