10Sstevel@tonic-gate /*
20Sstevel@tonic-gate * CDDL HEADER START
30Sstevel@tonic-gate *
40Sstevel@tonic-gate * The contents of this file are subject to the terms of the
50Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only
60Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance
70Sstevel@tonic-gate * with the License.
80Sstevel@tonic-gate *
90Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
100Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
110Sstevel@tonic-gate * See the License for the specific language governing permissions
120Sstevel@tonic-gate * and limitations under the License.
130Sstevel@tonic-gate *
140Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
150Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
160Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
170Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
180Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
190Sstevel@tonic-gate *
200Sstevel@tonic-gate * CDDL HEADER END
210Sstevel@tonic-gate */
22*291Smike_s
230Sstevel@tonic-gate /*
24*291Smike_s * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
25*291Smike_s * Use is subject to license terms.
260Sstevel@tonic-gate */
270Sstevel@tonic-gate
280Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI"
290Sstevel@tonic-gate
300Sstevel@tonic-gate #include <stdio.h>
310Sstevel@tonic-gate #include <ctype.h>
32*291Smike_s #include <string.h>
33*291Smike_s #include <stdlib.h>
340Sstevel@tonic-gate #include "error.h"
350Sstevel@tonic-gate
360Sstevel@tonic-gate int wordc; /* how long the current error message is */
370Sstevel@tonic-gate char **wordv; /* the actual error message */
380Sstevel@tonic-gate
390Sstevel@tonic-gate int nerrors;
400Sstevel@tonic-gate int language;
410Sstevel@tonic-gate
42*291Smike_s Errorclass onelong(void);
43*291Smike_s Errorclass cpp(void);
44*291Smike_s Errorclass pccccom(void); /* Portable C Compiler C Compiler */
45*291Smike_s Errorclass richieccom(void); /* Richie Compiler for 11 */
46*291Smike_s Errorclass lint0(void);
47*291Smike_s Errorclass lint1(void);
48*291Smike_s Errorclass lint2(void);
49*291Smike_s Errorclass lint3(void);
50*291Smike_s Errorclass make(void);
51*291Smike_s Errorclass f77(void);
52*291Smike_s Errorclass pi(void);
53*291Smike_s Errorclass ri(void);
54*291Smike_s Errorclass troff(void);
55*291Smike_s Errorclass mod2(void);
56*291Smike_s Errorclass sunf77(void);
57*291Smike_s
58*291Smike_s static Errorclass catchall(void);
59*291Smike_s
600Sstevel@tonic-gate /*
610Sstevel@tonic-gate * Eat all of the lines in the input file, attempting to categorize
620Sstevel@tonic-gate * them by their various flavors
630Sstevel@tonic-gate */
640Sstevel@tonic-gate static char inbuffer[BUFSIZ];
650Sstevel@tonic-gate
66*291Smike_s void
eaterrors(int * r_errorc,Eptr ** r_errorv)67*291Smike_s eaterrors(int *r_errorc, Eptr **r_errorv)
680Sstevel@tonic-gate {
690Sstevel@tonic-gate Errorclass errorclass = C_SYNC;
700Sstevel@tonic-gate
71*291Smike_s for (;;) {
72*291Smike_s if (fgets(inbuffer, BUFSIZ, errorfile) == NULL)
73*291Smike_s break;
74*291Smike_s wordvbuild(inbuffer, &wordc, &wordv);
75*291Smike_s /*
76*291Smike_s * for convenience, convert wordv to be 1 based, instead
77*291Smike_s * of 0 based.
78*291Smike_s */
79*291Smike_s wordv -= 1;
80*291Smike_s /*
81*291Smike_s * check for sunf77 errors has to be done before
82*291Smike_s * pccccom to be able to distingush between the two
83*291Smike_s */
84*291Smike_s if ((wordc > 0) &&
85*291Smike_s (((errorclass = onelong()) != C_UNKNOWN) ||
86*291Smike_s ((errorclass = cpp()) != C_UNKNOWN) ||
87*291Smike_s ((errorclass = sunf77()) != C_UNKNOWN) ||
88*291Smike_s ((errorclass = pccccom()) != C_UNKNOWN) ||
89*291Smike_s ((errorclass = richieccom()) != C_UNKNOWN) ||
90*291Smike_s ((errorclass = lint0()) != C_UNKNOWN) ||
91*291Smike_s ((errorclass = lint1()) != C_UNKNOWN) ||
92*291Smike_s ((errorclass = lint2()) != C_UNKNOWN) ||
93*291Smike_s ((errorclass = lint3()) != C_UNKNOWN) ||
94*291Smike_s ((errorclass = make()) != C_UNKNOWN) ||
95*291Smike_s ((errorclass = f77()) != C_UNKNOWN) ||
96*291Smike_s ((errorclass = pi()) != C_UNKNOWN) ||
97*291Smike_s ((errorclass = ri()) != C_UNKNOWN) ||
98*291Smike_s ((errorclass = troff()) != C_UNKNOWN) ||
99*291Smike_s ((errorclass = mod2()) != C_UNKNOWN) ||
100*291Smike_s ((errorclass = troff()) != C_UNKNOWN))) {
101*291Smike_s /* EMPTY */
102*291Smike_s } else {
103*291Smike_s errorclass = catchall();
104*291Smike_s }
105*291Smike_s if (wordc)
106*291Smike_s erroradd(wordc, wordv+1, errorclass, C_UNKNOWN);
107*291Smike_s }
1080Sstevel@tonic-gate #ifdef FULLDEBUG
109*291Smike_s printf("%d errorentrys\n", nerrors);
1100Sstevel@tonic-gate #endif
111*291Smike_s arrayify(r_errorc, r_errorv, er_head);
1120Sstevel@tonic-gate }
1130Sstevel@tonic-gate
1140Sstevel@tonic-gate /*
1150Sstevel@tonic-gate * create a new error entry, given a zero based array and count
1160Sstevel@tonic-gate */
117*291Smike_s void
erroradd(int errorlength,char ** errorv,Errorclass errorclass,Errorclass errorsubclass)118*291Smike_s erroradd(int errorlength, char **errorv, Errorclass errorclass,
119*291Smike_s Errorclass errorsubclass)
1200Sstevel@tonic-gate {
121*291Smike_s Eptr newerror;
122*291Smike_s char *cp;
1230Sstevel@tonic-gate
124*291Smike_s if (errorclass == C_TRUE) {
125*291Smike_s /* check canonicalization of the second argument */
126*291Smike_s for (cp = errorv[1]; *cp && isdigit(*cp); cp++)
1270Sstevel@tonic-gate continue;
1280Sstevel@tonic-gate errorclass = (*cp == '\0') ? C_TRUE : C_NONSPEC;
1290Sstevel@tonic-gate #ifdef FULLDEBUG
1300Sstevel@tonic-gate if (errorclass != C_TRUE)
1310Sstevel@tonic-gate printf("The 2nd word, \"%s\" is not a number.\n",
1320Sstevel@tonic-gate errorv[1]);
1330Sstevel@tonic-gate #endif
1340Sstevel@tonic-gate }
135*291Smike_s if (errorlength > 0) {
136*291Smike_s newerror = Calloc(1, sizeof (Edesc));
1370Sstevel@tonic-gate newerror->error_language = language; /* language is global */
1380Sstevel@tonic-gate newerror->error_text = errorv;
1390Sstevel@tonic-gate newerror->error_lgtext = errorlength;
1400Sstevel@tonic-gate if (errorclass == C_TRUE)
1410Sstevel@tonic-gate newerror->error_line = atoi(errorv[1]);
1420Sstevel@tonic-gate newerror->error_e_class = errorclass;
1430Sstevel@tonic-gate newerror->error_s_class = errorsubclass;
144*291Smike_s switch (newerror->error_e_class = discardit(newerror)) {
1450Sstevel@tonic-gate case C_SYNC: nsyncerrors++; break;
1460Sstevel@tonic-gate case C_DISCARD: ndiscard++; break;
1470Sstevel@tonic-gate case C_NULLED: nnulled++; break;
1480Sstevel@tonic-gate case C_NONSPEC: nnonspec++; break;
1490Sstevel@tonic-gate case C_THISFILE: nthisfile++; break;
1500Sstevel@tonic-gate case C_TRUE: ntrue++; break;
1510Sstevel@tonic-gate case C_UNKNOWN: nunknown++; break;
1520Sstevel@tonic-gate case C_IGNORE: nignore++; break;
1530Sstevel@tonic-gate }
1540Sstevel@tonic-gate newerror->error_next = er_head;
1550Sstevel@tonic-gate er_head = newerror;
1560Sstevel@tonic-gate newerror->error_no = nerrors++;
1570Sstevel@tonic-gate } /* length > 0 */
1580Sstevel@tonic-gate }
1590Sstevel@tonic-gate
160*291Smike_s Errorclass
onelong(void)161*291Smike_s onelong(void)
1620Sstevel@tonic-gate {
1630Sstevel@tonic-gate char **nwordv;
164*291Smike_s if ((wordc == 1) && (language != INLD)) {
1650Sstevel@tonic-gate /*
1660Sstevel@tonic-gate * We have either:
1670Sstevel@tonic-gate * a) file name from cc
1680Sstevel@tonic-gate * b) Assembler telling world that it is complaining
1690Sstevel@tonic-gate * c) Noise from make ("Stop.")
1700Sstevel@tonic-gate * c) Random noise
1710Sstevel@tonic-gate */
1720Sstevel@tonic-gate wordc = 0;
173*291Smike_s if (wordv[1] != NULL && strcmp(wordv[1], "Stop.") == 0) {
174*291Smike_s language = INMAKE;
175*291Smike_s return (C_SYNC);
1760Sstevel@tonic-gate }
1770Sstevel@tonic-gate if (wordv[1] != NULL) {
178*291Smike_s if (strcmp(wordv[1], "Assembler:") == 0) {
179*291Smike_s /*
180*291Smike_s * assembler always alerts us to
181*291Smike_s * what happened
182*291Smike_s */
183*291Smike_s language = INAS;
184*291Smike_s return (C_SYNC);
185*291Smike_s } else if (strcmp(wordv[1], "Undefined:") == 0) {
186*291Smike_s /* loader complains about unknown symbols */
187*291Smike_s language = INLD;
188*291Smike_s return (C_SYNC);
1890Sstevel@tonic-gate }
1900Sstevel@tonic-gate }
191*291Smike_s if (lastchar(wordv[1]) == ':') {
1920Sstevel@tonic-gate /* cc tells us what file we are in */
193*291Smike_s /* Sunf77 tells us what subroutine we are in */
1940Sstevel@tonic-gate currentfilename = wordv[1];
195*291Smike_s (void) substitute(currentfilename, ':', '\0');
196*291Smike_s language = INCC;
197*291Smike_s return (C_SYNC);
1980Sstevel@tonic-gate }
199*291Smike_s } else if ((wordc == 1) && (language == INLD)) {
200*291Smike_s nwordv = Calloc(4, sizeof (char *));
2010Sstevel@tonic-gate nwordv[0] = "ld:";
2020Sstevel@tonic-gate nwordv[1] = wordv[1];
2030Sstevel@tonic-gate nwordv[2] = "is";
2040Sstevel@tonic-gate nwordv[3] = "undefined.";
2050Sstevel@tonic-gate wordc = 4;
2060Sstevel@tonic-gate wordv = nwordv - 1;
207*291Smike_s return (C_NONSPEC);
208*291Smike_s } else if (wordc == 1) {
209*291Smike_s /*
210*291Smike_s * any other single word messages are
211*291Smike_s * considered synchronizing
212*291Smike_s */
213*291Smike_s return (C_SYNC);
2140Sstevel@tonic-gate } else
215*291Smike_s /* Sunf77 may derive 2-word synchronizing messages ending with a `:' */
216*291Smike_s if ((wordc == 2) && (lastchar(wordv[2]) == ':')) {
217*291Smike_s wordc = 0;
218*291Smike_s language = INSUNF77;
219*291Smike_s return (C_SYNC);
220*291Smike_s }
221*291Smike_s return (C_UNKNOWN);
2220Sstevel@tonic-gate } /* end of one long */
2230Sstevel@tonic-gate
224*291Smike_s Errorclass
cpp(void)225*291Smike_s cpp(void)
2260Sstevel@tonic-gate {
227*291Smike_s /*
2280Sstevel@tonic-gate * Now attempt a cpp error message match
2290Sstevel@tonic-gate * Examples:
2300Sstevel@tonic-gate * ./morse.h: 23: undefined control
2310Sstevel@tonic-gate * morsesend.c: 229: MAGNIBBL: argument mismatch
2320Sstevel@tonic-gate * morsesend.c: 237: MAGNIBBL: argument mismatch
2330Sstevel@tonic-gate * test1.c: 6: undefined control
2340Sstevel@tonic-gate */
235*291Smike_s if ((language != INLD) && /* loader errors have almost same fmt */
236*291Smike_s (lastchar(wordv[1]) == ':') &&
237*291Smike_s (isdigit(firstchar(wordv[2]))) &&
238*291Smike_s (lastchar(wordv[2]) == ':')) {
2390Sstevel@tonic-gate language = INCPP;
2400Sstevel@tonic-gate clob_last(wordv[1], '\0');
2410Sstevel@tonic-gate clob_last(wordv[2], '\0');
242*291Smike_s return (C_TRUE);
2430Sstevel@tonic-gate }
244*291Smike_s return (C_UNKNOWN);
2450Sstevel@tonic-gate } /*end of cpp*/
2460Sstevel@tonic-gate
247*291Smike_s Errorclass
pccccom(void)248*291Smike_s pccccom(void)
2490Sstevel@tonic-gate {
2500Sstevel@tonic-gate /*
2510Sstevel@tonic-gate * Now attempt a ccom error message match:
2520Sstevel@tonic-gate * Examples:
2530Sstevel@tonic-gate * "morsesend.c", line 237: operands of & have incompatible types
2540Sstevel@tonic-gate * "test.c", line 7: warning: old-fashioned initialization: use =
2550Sstevel@tonic-gate * "subdir.d/foo2.h", line 1: illegal initialization
2560Sstevel@tonic-gate */
257*291Smike_s if ((firstchar(wordv[1]) == '"') &&
258*291Smike_s (lastchar(wordv[1]) == ',') &&
259*291Smike_s (next_lastchar(wordv[1]) == '"') &&
260*291Smike_s (strcmp(wordv[2], "line") == 0) &&
261*291Smike_s (isdigit(firstchar(wordv[3]))) &&
262*291Smike_s (lastchar(wordv[3]) == ':')) {
2630Sstevel@tonic-gate clob_last(wordv[1], '\0'); /* drop last , */
2640Sstevel@tonic-gate clob_last(wordv[1], '\0'); /* drop last " */
2650Sstevel@tonic-gate wordv[1]++; /* drop first " */
2660Sstevel@tonic-gate clob_last(wordv[3], '\0'); /* drop : on line number */
2670Sstevel@tonic-gate wordv[2] = wordv[1]; /* overwrite "line" */
268*291Smike_s wordv++; /* compensate */
2690Sstevel@tonic-gate wordc--;
2700Sstevel@tonic-gate currentfilename = wordv[1];
2710Sstevel@tonic-gate language = INCC;
272*291Smike_s return (C_TRUE);
2730Sstevel@tonic-gate }
274*291Smike_s return (C_UNKNOWN);
2750Sstevel@tonic-gate } /* end of ccom */
276*291Smike_s
2770Sstevel@tonic-gate /*
2780Sstevel@tonic-gate * Do the error message from the Richie C Compiler for the PDP11,
2790Sstevel@tonic-gate * which has this source:
2800Sstevel@tonic-gate *
2810Sstevel@tonic-gate * if (filename[0])
2820Sstevel@tonic-gate * fprintf(stderr, "%s:", filename);
2830Sstevel@tonic-gate * fprintf(stderr, "%d: ", line);
2840Sstevel@tonic-gate *
2850Sstevel@tonic-gate */
286*291Smike_s Errorclass
richieccom(void)287*291Smike_s richieccom(void)
2880Sstevel@tonic-gate {
289*291Smike_s char *cp;
290*291Smike_s char **nwordv;
291*291Smike_s char *file;
2920Sstevel@tonic-gate
293*291Smike_s if (lastchar(wordv[1]) == ':') {
2940Sstevel@tonic-gate cp = wordv[1] + strlen(wordv[1]) - 1;
2950Sstevel@tonic-gate while (isdigit(*--cp))
2960Sstevel@tonic-gate continue;
297*291Smike_s if (*cp == ':') {
2980Sstevel@tonic-gate clob_last(wordv[1], '\0'); /* last : */
2990Sstevel@tonic-gate *cp = '\0'; /* first : */
3000Sstevel@tonic-gate file = wordv[1];
3010Sstevel@tonic-gate nwordv = wordvsplice(1, wordc, wordv+1);
3020Sstevel@tonic-gate nwordv[0] = file;
3030Sstevel@tonic-gate nwordv[1] = cp + 1;
3040Sstevel@tonic-gate wordc += 1;
3050Sstevel@tonic-gate wordv = nwordv - 1;
3060Sstevel@tonic-gate language = INCC;
3070Sstevel@tonic-gate currentfilename = wordv[1];
308*291Smike_s return (C_TRUE);
3090Sstevel@tonic-gate }
3100Sstevel@tonic-gate }
311*291Smike_s return (C_UNKNOWN);
3120Sstevel@tonic-gate }
3130Sstevel@tonic-gate
314*291Smike_s Errorclass
lint0(void)315*291Smike_s lint0(void)
3160Sstevel@tonic-gate {
317*291Smike_s char **nwordv;
3180Sstevel@tonic-gate char *line, *file;
3190Sstevel@tonic-gate /*
3200Sstevel@tonic-gate * Attempt a match for the new lint style normal compiler
3210Sstevel@tonic-gate * error messages, of the form
322*291Smike_s *
3230Sstevel@tonic-gate * printf("%s(%d): %s\n", filename, linenumber, message);
3240Sstevel@tonic-gate */
325*291Smike_s if (wordc >= 2) {
326*291Smike_s if ((lastchar(wordv[1]) == ':') &&
327*291Smike_s (next_lastchar(wordv[1]) == ')')) {
3280Sstevel@tonic-gate clob_last(wordv[1], '\0'); /* colon */
329*291Smike_s if (persperdexplode(wordv[1], &line, &file)) {
3300Sstevel@tonic-gate nwordv = wordvsplice(1, wordc, wordv+1);
3310Sstevel@tonic-gate nwordv[0] = file; /* file name */
3320Sstevel@tonic-gate nwordv[1] = line; /* line number */
3330Sstevel@tonic-gate wordc += 1;
3340Sstevel@tonic-gate wordv = nwordv - 1;
3350Sstevel@tonic-gate language = INLINT;
336*291Smike_s return (C_TRUE);
3370Sstevel@tonic-gate }
3380Sstevel@tonic-gate wordv[1][strlen(wordv[1])] = ':';
3390Sstevel@tonic-gate }
3400Sstevel@tonic-gate }
3410Sstevel@tonic-gate return (C_UNKNOWN);
3420Sstevel@tonic-gate }
3430Sstevel@tonic-gate
344*291Smike_s Errorclass
lint1(void)345*291Smike_s lint1(void)
3460Sstevel@tonic-gate {
3470Sstevel@tonic-gate char *line1, *line2;
3480Sstevel@tonic-gate char *file1, *file2;
3490Sstevel@tonic-gate char **nwordv1, **nwordv2;
3500Sstevel@tonic-gate
3510Sstevel@tonic-gate /*
3520Sstevel@tonic-gate * Now, attempt a match for the various errors that lint
3530Sstevel@tonic-gate * can complain about.
3540Sstevel@tonic-gate *
3550Sstevel@tonic-gate * Look first for type 1 lint errors
3560Sstevel@tonic-gate */
357*291Smike_s if (wordc > 1 && strcmp(wordv[wordc-1], "::") == 0) {
358*291Smike_s /*
359*291Smike_s * %.7s, arg. %d used inconsistently %s(%d) :: %s(%d)
360*291Smike_s * %.7s value used inconsistently %s(%d) :: %s(%d)
361*291Smike_s * %.7s multiply declared %s(%d) :: %s(%d)
362*291Smike_s * %.7s value declared inconsistently %s(%d) :: %s(%d)
363*291Smike_s * %.7s function value type must be declared before use %s(%d) :: %s(%d)
364*291Smike_s */
3650Sstevel@tonic-gate language = INLINT;
366*291Smike_s if ((wordc > 2) &&
367*291Smike_s (persperdexplode(wordv[wordc], &line2, &file2)) &&
368*291Smike_s (persperdexplode(wordv[wordc-2], &line1, &file1))) {
3690Sstevel@tonic-gate nwordv1 = wordvsplice(2, wordc, wordv+1);
3700Sstevel@tonic-gate nwordv2 = wordvsplice(2, wordc, wordv+1);
3710Sstevel@tonic-gate nwordv1[0] = file1; nwordv1[1] = line1;
372*291Smike_s /* takes 0 based */
373*291Smike_s erroradd(wordc+2, nwordv1, C_TRUE, C_DUPL);
3740Sstevel@tonic-gate nwordv2[0] = file2; nwordv2[1] = line2;
3750Sstevel@tonic-gate wordc = wordc + 2;
3760Sstevel@tonic-gate wordv = nwordv2 - 1; /* 1 based */
377*291Smike_s return (C_TRUE);
3780Sstevel@tonic-gate }
3790Sstevel@tonic-gate }
380*291Smike_s return (C_UNKNOWN);
3810Sstevel@tonic-gate } /* end of lint 1*/
3820Sstevel@tonic-gate
383*291Smike_s Errorclass
lint2(void)384*291Smike_s lint2(void)
3850Sstevel@tonic-gate {
3860Sstevel@tonic-gate char *file;
3870Sstevel@tonic-gate char *line;
3880Sstevel@tonic-gate char **nwordv;
3890Sstevel@tonic-gate /*
3900Sstevel@tonic-gate * Look for type 2 lint errors
3910Sstevel@tonic-gate *
3920Sstevel@tonic-gate * %.7s used( %s(%d) ), but not defined
3930Sstevel@tonic-gate * %.7s defined( %s(%d) ), but never used
3940Sstevel@tonic-gate * %.7s declared( %s(%d) ), but never used or defined
3950Sstevel@tonic-gate *
3960Sstevel@tonic-gate * bufp defined( "./metric.h"(10) ), but never used
3970Sstevel@tonic-gate */
398*291Smike_s if ((lastchar(wordv[2]) == '(' /* ')' */) &&
399*291Smike_s (strcmp(wordv[4], "),") == 0)) {
4000Sstevel@tonic-gate language = INLINT;
401*291Smike_s if (persperdexplode(wordv[3], &line, &file)) {
4020Sstevel@tonic-gate nwordv = wordvsplice(2, wordc, wordv+1);
4030Sstevel@tonic-gate nwordv[0] = file; nwordv[1] = line;
4040Sstevel@tonic-gate wordc = wordc + 2;
4050Sstevel@tonic-gate wordv = nwordv - 1; /* 1 based */
406*291Smike_s return (C_TRUE);
4070Sstevel@tonic-gate }
4080Sstevel@tonic-gate }
409*291Smike_s return (C_UNKNOWN);
4100Sstevel@tonic-gate } /* end of lint 2*/
4110Sstevel@tonic-gate
4120Sstevel@tonic-gate char *Lint31[4] = {"returns", "value", "which", "is"};
4130Sstevel@tonic-gate char *Lint32[6] = {"value", "is", "used,", "but", "none", "returned"};
414*291Smike_s
415*291Smike_s Errorclass
lint3(void)416*291Smike_s lint3(void)
4170Sstevel@tonic-gate {
418*291Smike_s if ((wordvcmp(wordv+2, 4, Lint31) == 0) ||
419*291Smike_s (wordvcmp(wordv+2, 6, Lint32) == 0)) {
4200Sstevel@tonic-gate language = INLINT;
421*291Smike_s return (C_NONSPEC);
4220Sstevel@tonic-gate }
423*291Smike_s return (C_UNKNOWN);
4240Sstevel@tonic-gate }
4250Sstevel@tonic-gate
4260Sstevel@tonic-gate /*
4270Sstevel@tonic-gate * Special word vectors for use by F77 recognition
4280Sstevel@tonic-gate */
4290Sstevel@tonic-gate char *F77_fatal[3] = {"Compiler", "error", "line"};
4300Sstevel@tonic-gate char *F77_error[3] = {"Error", "on", "line"};
4310Sstevel@tonic-gate char *F77_warning[3] = {"Warning", "on", "line"};
432*291Smike_s char *F77_no_ass[3] = {"Error.", "No", "assembly."};
4330Sstevel@tonic-gate
434*291Smike_s Errorclass
f77(void)435*291Smike_s f77(void)
4360Sstevel@tonic-gate {
4370Sstevel@tonic-gate char **nwordv;
4380Sstevel@tonic-gate /*
4390Sstevel@tonic-gate * look for f77 errors:
4400Sstevel@tonic-gate * Error messages from /usr/src/cmd/f77/error.c, with
4410Sstevel@tonic-gate * these printf formats:
4420Sstevel@tonic-gate *
4430Sstevel@tonic-gate * Compiler error line %d of %s: %s
4440Sstevel@tonic-gate * Error on line %d of %s: %s
4450Sstevel@tonic-gate * Warning on line %d of %s: %s
4460Sstevel@tonic-gate * Error. No assembly.
4470Sstevel@tonic-gate */
4480Sstevel@tonic-gate if (wordc == 3 && wordvcmp(wordv+1, 3, F77_no_ass) == 0) {
4490Sstevel@tonic-gate wordc = 0;
450*291Smike_s return (C_SYNC);
4510Sstevel@tonic-gate }
4520Sstevel@tonic-gate if (wordc < 6)
453*291Smike_s return (C_UNKNOWN);
454*291Smike_s if ((lastchar(wordv[6]) == ':') &&
455*291Smike_s ((wordvcmp(wordv+1, 3, F77_fatal) == 0) ||
456*291Smike_s (wordvcmp(wordv+1, 3, F77_error) == 0) ||
457*291Smike_s (wordvcmp(wordv+1, 3, F77_warning) == 0))) {
4580Sstevel@tonic-gate language = INF77;
4590Sstevel@tonic-gate nwordv = wordvsplice(2, wordc, wordv+1);
4600Sstevel@tonic-gate nwordv[0] = wordv[6];
461*291Smike_s clob_last(nwordv[0], '\0');
4620Sstevel@tonic-gate nwordv[1] = wordv[4];
4630Sstevel@tonic-gate wordc += 2;
4640Sstevel@tonic-gate wordv = nwordv - 1; /* 1 based */
465*291Smike_s return (C_TRUE);
4660Sstevel@tonic-gate }
467*291Smike_s return (C_UNKNOWN);
4680Sstevel@tonic-gate } /* end of f77 */
4690Sstevel@tonic-gate
4700Sstevel@tonic-gate char *Make_Croak[3] = {"***", "Error", "code"};
4710Sstevel@tonic-gate char *Make_NotRemade[5] = {"not", "remade", "because", "of", "errors"};
472*291Smike_s
473*291Smike_s Errorclass
make(void)474*291Smike_s make(void)
4750Sstevel@tonic-gate {
476*291Smike_s if (wordvcmp(wordv+1, 3, Make_Croak) == 0) {
4770Sstevel@tonic-gate language = INMAKE;
478*291Smike_s return (C_SYNC);
4790Sstevel@tonic-gate }
480*291Smike_s if (wordvcmp(wordv+2, 5, Make_NotRemade) == 0) {
4810Sstevel@tonic-gate language = INMAKE;
482*291Smike_s return (C_SYNC);
4830Sstevel@tonic-gate }
484*291Smike_s return (C_UNKNOWN);
4850Sstevel@tonic-gate }
486*291Smike_s
487*291Smike_s Errorclass
ri(void)488*291Smike_s ri(void)
4890Sstevel@tonic-gate {
4900Sstevel@tonic-gate /*
4910Sstevel@tonic-gate * Match an error message produced by ri; here is the
4920Sstevel@tonic-gate * procedure yanked from the distributed version of ri
4930Sstevel@tonic-gate * April 24, 1980.
494*291Smike_s *
4950Sstevel@tonic-gate * serror(str, x1, x2, x3)
4960Sstevel@tonic-gate * char str[];
4970Sstevel@tonic-gate * char *x1, *x2, *x3;
4980Sstevel@tonic-gate * {
4990Sstevel@tonic-gate * extern int yylineno;
500*291Smike_s *
5010Sstevel@tonic-gate * putc('"', stdout);
5020Sstevel@tonic-gate * fputs(srcfile, stdout);
5030Sstevel@tonic-gate * putc('"', stdout);
5040Sstevel@tonic-gate * fprintf(stdout, " %d: ", yylineno);
5050Sstevel@tonic-gate * fprintf(stdout, str, x1, x2, x3);
5060Sstevel@tonic-gate * fprintf(stdout, "\n");
5070Sstevel@tonic-gate * synerrs++;
5080Sstevel@tonic-gate * }
5090Sstevel@tonic-gate */
510*291Smike_s if ((firstchar(wordv[1]) == '"') &&
511*291Smike_s (lastchar(wordv[1]) == '"') &&
512*291Smike_s (lastchar(wordv[2]) == ':') &&
513*291Smike_s (isdigit(firstchar(wordv[2])))) {
5140Sstevel@tonic-gate clob_last(wordv[1], '\0'); /* drop the last " */
5150Sstevel@tonic-gate wordv[1]++; /* skip over the first " */
5160Sstevel@tonic-gate clob_last(wordv[2], '\0');
5170Sstevel@tonic-gate language = INRI;
518*291Smike_s return (C_TRUE);
5190Sstevel@tonic-gate }
520*291Smike_s return (C_UNKNOWN);
5210Sstevel@tonic-gate }
5220Sstevel@tonic-gate
523*291Smike_s static Errorclass
catchall(void)524*291Smike_s catchall(void)
5250Sstevel@tonic-gate {
5260Sstevel@tonic-gate /*
5270Sstevel@tonic-gate * Catches random things.
5280Sstevel@tonic-gate */
5290Sstevel@tonic-gate language = INUNKNOWN;
530*291Smike_s return (C_NONSPEC);
531*291Smike_s }
5320Sstevel@tonic-gate
533*291Smike_s Errorclass
troff(void)534*291Smike_s troff(void)
5350Sstevel@tonic-gate {
5360Sstevel@tonic-gate /*
5370Sstevel@tonic-gate * troff source error message, from eqn, bib, tbl...
5380Sstevel@tonic-gate * Just like pcc ccom, except uses `'
5390Sstevel@tonic-gate */
540*291Smike_s if ((firstchar(wordv[1]) == '`') &&
541*291Smike_s (lastchar(wordv[1]) == ',') &&
542*291Smike_s (next_lastchar(wordv[1]) == '\'') &&
543*291Smike_s (strcmp(wordv[2], "line") == 0) &&
544*291Smike_s (isdigit(firstchar(wordv[3]))) &&
545*291Smike_s (lastchar(wordv[3]) == ':')) {
5460Sstevel@tonic-gate clob_last(wordv[1], '\0'); /* drop last , */
5470Sstevel@tonic-gate clob_last(wordv[1], '\0'); /* drop last " */
5480Sstevel@tonic-gate wordv[1]++; /* drop first " */
5490Sstevel@tonic-gate clob_last(wordv[3], '\0'); /* drop : on line number */
5500Sstevel@tonic-gate wordv[2] = wordv[1]; /* overwrite "line" */
551*291Smike_s wordv++; /* compensate */
5520Sstevel@tonic-gate currentfilename = wordv[1];
5530Sstevel@tonic-gate language = INTROFF;
554*291Smike_s return (C_TRUE);
5550Sstevel@tonic-gate }
556*291Smike_s return (C_UNKNOWN);
5570Sstevel@tonic-gate }
558*291Smike_s
559*291Smike_s Errorclass
mod2(void)560*291Smike_s mod2(void)
5610Sstevel@tonic-gate {
5620Sstevel@tonic-gate /*
5630Sstevel@tonic-gate * for decwrl modula2 compiler (powell)
5640Sstevel@tonic-gate */
565*291Smike_s if (((strcmp(wordv[1], "!!!") == 0) || /* early version */
566*291Smike_s (strcmp(wordv[1], "File") == 0)) && /* later version */
567*291Smike_s (lastchar(wordv[2]) == ',') && /* file name */
568*291Smike_s (strcmp(wordv[3], "line") == 0) &&
569*291Smike_s (isdigit(firstchar(wordv[4]))) && /* line number */
570*291Smike_s (lastchar(wordv[4]) == ':')) { /* line number */
5710Sstevel@tonic-gate clob_last(wordv[2], '\0'); /* drop last , on file name */
5720Sstevel@tonic-gate clob_last(wordv[4], '\0'); /* drop last : on line number */
5730Sstevel@tonic-gate wordv[3] = wordv[2]; /* file name on top of "line" */
5740Sstevel@tonic-gate wordv += 2;
5750Sstevel@tonic-gate wordc -= 2;
5760Sstevel@tonic-gate currentfilename = wordv[1];
5770Sstevel@tonic-gate language = INMOD2;
578*291Smike_s return (C_TRUE);
5790Sstevel@tonic-gate }
580*291Smike_s return (C_UNKNOWN);
5810Sstevel@tonic-gate }
5820Sstevel@tonic-gate
583*291Smike_s Errorclass
sunf77(void)584*291Smike_s sunf77(void)
5850Sstevel@tonic-gate {
5860Sstevel@tonic-gate /*
587*291Smike_s * Finally attempt a Sun f77 error message match:
588*291Smike_s * Examples:
589*291Smike_s * "bar.f", line 237: Error: no label on format statement
590*291Smike_s * "test.f", line 7: ANSI extension: Hollerith constant
591*291Smike_s * "dir/foo.h", line 1: Warning: missing END statement
5920Sstevel@tonic-gate */
593*291Smike_s if ((firstchar(wordv[1]) == '"') &&
594*291Smike_s (lastchar(wordv[1]) == ',') &&
595*291Smike_s (next_lastchar(wordv[1]) == '"') &&
596*291Smike_s (strcmp(wordv[2], "line") == 0) &&
597*291Smike_s (isdigit(firstchar(wordv[3]))) &&
598*291Smike_s (lastchar(wordv[3]) == ':') &&
599*291Smike_s ((strcmp(wordv[4], "Error:") == 0) ||
600*291Smike_s (strcmp(wordv[4], "Warning:") == 0) ||
601*291Smike_s ((strcmp(wordv[4], "ANSI") == 0) &&
602*291Smike_s (strcmp(wordv[5], "extension:") == 0)))) {
6030Sstevel@tonic-gate clob_last(wordv[1], '\0'); /* drop last , */
6040Sstevel@tonic-gate clob_last(wordv[1], '\0'); /* drop last " */
6050Sstevel@tonic-gate wordv[1]++; /* drop first " */
6060Sstevel@tonic-gate clob_last(wordv[3], '\0'); /* drop : on line number */
6070Sstevel@tonic-gate wordv[2] = wordv[1]; /* overwrite "line" */
608*291Smike_s wordv++; /* compensate */
6090Sstevel@tonic-gate wordc--;
6100Sstevel@tonic-gate currentfilename = wordv[1];
6110Sstevel@tonic-gate language = INSUNF77;
612*291Smike_s return (C_TRUE);
6130Sstevel@tonic-gate }
614*291Smike_s return (C_UNKNOWN);
6150Sstevel@tonic-gate } /* end of Sun f77 */
616