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