xref: /onnv-gate/usr/src/cmd/sgs/error/common/errorinput.c (revision 291:0ac955735323)
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