17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
57c478bd9Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
67c478bd9Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
77c478bd9Sstevel@tonic-gate  * with the License.
87c478bd9Sstevel@tonic-gate  *
97c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
107c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
117c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
127c478bd9Sstevel@tonic-gate  * and limitations under the License.
137c478bd9Sstevel@tonic-gate  *
147c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
157c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
167c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
177c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
187c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
197c478bd9Sstevel@tonic-gate  *
207c478bd9Sstevel@tonic-gate  * CDDL HEADER END
217c478bd9Sstevel@tonic-gate  */
229fb11590Smike_s 
237c478bd9Sstevel@tonic-gate /*
249fb11590Smike_s  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
259fb11590Smike_s  * Use is subject to license terms.
267c478bd9Sstevel@tonic-gate  */
277c478bd9Sstevel@tonic-gate 
287c478bd9Sstevel@tonic-gate #include <stdio.h>
297c478bd9Sstevel@tonic-gate #include <ctype.h>
309fb11590Smike_s #include <string.h>
319fb11590Smike_s #include <stdlib.h>
327c478bd9Sstevel@tonic-gate #include "error.h"
337c478bd9Sstevel@tonic-gate 
347c478bd9Sstevel@tonic-gate int	wordc;		/* how long the current error message is */
357c478bd9Sstevel@tonic-gate char	**wordv;	/* the actual error message */
367c478bd9Sstevel@tonic-gate 
379fb11590Smike_s Errorclass	onelong(void);
389fb11590Smike_s Errorclass	cpp(void);
399fb11590Smike_s Errorclass	pccccom(void);	/* Portable C Compiler C Compiler */
409fb11590Smike_s Errorclass	richieccom(void);	/* Richie Compiler for 11 */
419fb11590Smike_s Errorclass	lint0(void);
429fb11590Smike_s Errorclass	lint1(void);
439fb11590Smike_s Errorclass	lint2(void);
449fb11590Smike_s Errorclass	lint3(void);
459fb11590Smike_s Errorclass	make(void);
469fb11590Smike_s Errorclass	f77(void);
479fb11590Smike_s Errorclass	pi(void);
489fb11590Smike_s Errorclass	ri(void);
499fb11590Smike_s Errorclass	troff(void);
509fb11590Smike_s Errorclass	mod2(void);
519fb11590Smike_s Errorclass	sunf77(void);
529fb11590Smike_s 
539fb11590Smike_s static Errorclass catchall(void);
549fb11590Smike_s 
557c478bd9Sstevel@tonic-gate /*
567c478bd9Sstevel@tonic-gate  *	Eat all of the lines in the input file, attempting to categorize
577c478bd9Sstevel@tonic-gate  *	them by their various flavors
587c478bd9Sstevel@tonic-gate  */
597c478bd9Sstevel@tonic-gate static	char	inbuffer[BUFSIZ];
607c478bd9Sstevel@tonic-gate 
619fb11590Smike_s void
eaterrors(int * r_errorc,Eptr ** r_errorv)629fb11590Smike_s eaterrors(int *r_errorc, Eptr **r_errorv)
637c478bd9Sstevel@tonic-gate {
647c478bd9Sstevel@tonic-gate 	Errorclass	errorclass = C_SYNC;
657c478bd9Sstevel@tonic-gate 
669fb11590Smike_s 	for (;;) {
679fb11590Smike_s 		if (fgets(inbuffer, BUFSIZ, errorfile) == NULL)
689fb11590Smike_s 			break;
699fb11590Smike_s 		wordvbuild(inbuffer, &wordc, &wordv);
709fb11590Smike_s 		/*
719fb11590Smike_s 		 * for convenience, convert wordv to be 1 based, instead
729fb11590Smike_s 		 * of 0 based.
739fb11590Smike_s 		 */
749fb11590Smike_s 		wordv -= 1;
759fb11590Smike_s 		/*
769fb11590Smike_s 		 * check for sunf77 errors has to be done before
779fb11590Smike_s 		 * pccccom to be able to distingush between the two
789fb11590Smike_s 		 */
799fb11590Smike_s 		if ((wordc > 0) &&
809fb11590Smike_s 		    (((errorclass = onelong()) != C_UNKNOWN) ||
819fb11590Smike_s 		    ((errorclass = cpp()) != C_UNKNOWN) ||
829fb11590Smike_s 		    ((errorclass = sunf77()) != C_UNKNOWN) ||
839fb11590Smike_s 		    ((errorclass = pccccom()) != C_UNKNOWN) ||
849fb11590Smike_s 		    ((errorclass = richieccom()) != C_UNKNOWN) ||
859fb11590Smike_s 		    ((errorclass = lint0()) != C_UNKNOWN) ||
869fb11590Smike_s 		    ((errorclass = lint1()) != C_UNKNOWN) ||
879fb11590Smike_s 		    ((errorclass = lint2()) != C_UNKNOWN) ||
889fb11590Smike_s 		    ((errorclass = lint3()) != C_UNKNOWN) ||
899fb11590Smike_s 		    ((errorclass = make()) != C_UNKNOWN) ||
909fb11590Smike_s 		    ((errorclass = f77()) != C_UNKNOWN) ||
919fb11590Smike_s 		    ((errorclass = pi()) != C_UNKNOWN) ||
929fb11590Smike_s 		    ((errorclass = ri()) != C_UNKNOWN) ||
939fb11590Smike_s 		    ((errorclass = troff()) != C_UNKNOWN) ||
949fb11590Smike_s 		    ((errorclass = mod2()) != C_UNKNOWN) ||
959fb11590Smike_s 		    ((errorclass = troff()) != C_UNKNOWN))) {
969fb11590Smike_s 		    /* EMPTY */
979fb11590Smike_s 		} else {
989fb11590Smike_s 			errorclass = catchall();
999fb11590Smike_s 		}
1009fb11590Smike_s 		if (wordc)
1019fb11590Smike_s 			erroradd(wordc, wordv+1, errorclass, C_UNKNOWN);
1029fb11590Smike_s 	}
1037c478bd9Sstevel@tonic-gate #ifdef FULLDEBUG
1049fb11590Smike_s 	printf("%d errorentrys\n", nerrors);
1057c478bd9Sstevel@tonic-gate #endif
1069fb11590Smike_s 	arrayify(r_errorc, r_errorv, er_head);
1077c478bd9Sstevel@tonic-gate }
1087c478bd9Sstevel@tonic-gate 
1097c478bd9Sstevel@tonic-gate /*
1107c478bd9Sstevel@tonic-gate  *	create a new error entry, given a zero based array and count
1117c478bd9Sstevel@tonic-gate  */
1129fb11590Smike_s void
erroradd(int errorlength,char ** errorv,Errorclass errorclass,Errorclass errorsubclass)1139fb11590Smike_s erroradd(int errorlength, char **errorv, Errorclass errorclass,
1149fb11590Smike_s     Errorclass errorsubclass)
1157c478bd9Sstevel@tonic-gate {
1169fb11590Smike_s 	Eptr	newerror;
1179fb11590Smike_s 	char	*cp;
1187c478bd9Sstevel@tonic-gate 
1199fb11590Smike_s 	if (errorclass == C_TRUE) {
1209fb11590Smike_s 		/* check canonicalization of the second argument */
1219fb11590Smike_s 		for (cp = errorv[1]; *cp && isdigit(*cp); cp++)
1227c478bd9Sstevel@tonic-gate 			continue;
1237c478bd9Sstevel@tonic-gate 		errorclass = (*cp == '\0') ? C_TRUE : C_NONSPEC;
1247c478bd9Sstevel@tonic-gate #ifdef FULLDEBUG
1257c478bd9Sstevel@tonic-gate 		if (errorclass != C_TRUE)
1267c478bd9Sstevel@tonic-gate 			printf("The 2nd word, \"%s\" is not a number.\n",
127*c6867562SToomas Soome 			    errorv[1]);
1287c478bd9Sstevel@tonic-gate #endif
1297c478bd9Sstevel@tonic-gate 	}
1309fb11590Smike_s 	if (errorlength > 0) {
1319fb11590Smike_s 		newerror = Calloc(1, sizeof (Edesc));
1327c478bd9Sstevel@tonic-gate 		newerror->error_language = language; /* language is global */
1337c478bd9Sstevel@tonic-gate 		newerror->error_text = errorv;
1347c478bd9Sstevel@tonic-gate 		newerror->error_lgtext = errorlength;
1357c478bd9Sstevel@tonic-gate 		if (errorclass == C_TRUE)
1367c478bd9Sstevel@tonic-gate 			newerror->error_line = atoi(errorv[1]);
1377c478bd9Sstevel@tonic-gate 		newerror->error_e_class = errorclass;
1387c478bd9Sstevel@tonic-gate 		newerror->error_s_class = errorsubclass;
1399fb11590Smike_s 		switch (newerror->error_e_class = discardit(newerror)) {
1407c478bd9Sstevel@tonic-gate 			case C_SYNC:		nsyncerrors++; break;
141*c6867562SToomas Soome 			case C_DISCARD:		ndiscard++; break;
1427c478bd9Sstevel@tonic-gate 			case C_NULLED:		nnulled++; break;
1437c478bd9Sstevel@tonic-gate 			case C_NONSPEC:		nnonspec++; break;
144*c6867562SToomas Soome 			case C_THISFILE:	nthisfile++; break;
1457c478bd9Sstevel@tonic-gate 			case C_TRUE:		ntrue++; break;
1467c478bd9Sstevel@tonic-gate 			case C_UNKNOWN:		nunknown++; break;
1477c478bd9Sstevel@tonic-gate 			case C_IGNORE:		nignore++; break;
1487c478bd9Sstevel@tonic-gate 		}
1497c478bd9Sstevel@tonic-gate 		newerror->error_next = er_head;
1507c478bd9Sstevel@tonic-gate 		er_head = newerror;
1517c478bd9Sstevel@tonic-gate 		newerror->error_no = nerrors++;
1527c478bd9Sstevel@tonic-gate 	}	/* length > 0 */
1537c478bd9Sstevel@tonic-gate }
1547c478bd9Sstevel@tonic-gate 
1559fb11590Smike_s Errorclass
onelong(void)1569fb11590Smike_s onelong(void)
1577c478bd9Sstevel@tonic-gate {
1587c478bd9Sstevel@tonic-gate 	char	**nwordv;
1599fb11590Smike_s 	if ((wordc == 1) && (language != INLD)) {
1607c478bd9Sstevel@tonic-gate 		/*
1617c478bd9Sstevel@tonic-gate 		 *	We have either:
1627c478bd9Sstevel@tonic-gate 		 *	a)	file name from cc
1637c478bd9Sstevel@tonic-gate 		 *	b)	Assembler telling world that it is complaining
1647c478bd9Sstevel@tonic-gate 		 *	c)	Noise from make ("Stop.")
1657c478bd9Sstevel@tonic-gate 		 *	c)	Random noise
1667c478bd9Sstevel@tonic-gate 		 */
1677c478bd9Sstevel@tonic-gate 		wordc = 0;
1689fb11590Smike_s 		if (wordv[1] != NULL && strcmp(wordv[1], "Stop.") == 0) {
1699fb11590Smike_s 			language = INMAKE;
1709fb11590Smike_s 			return (C_SYNC);
1717c478bd9Sstevel@tonic-gate 		}
1727c478bd9Sstevel@tonic-gate 		if (wordv[1] != NULL) {
1739fb11590Smike_s 			if (strcmp(wordv[1], "Assembler:") == 0) {
1749fb11590Smike_s 				/*
1759fb11590Smike_s 				 * assembler always alerts us to
1769fb11590Smike_s 				 * what happened
1779fb11590Smike_s 				 */
1789fb11590Smike_s 				language = INAS;
1799fb11590Smike_s 				return (C_SYNC);
1809fb11590Smike_s 			} else if (strcmp(wordv[1], "Undefined:") == 0) {
1819fb11590Smike_s 				/* loader complains about unknown symbols */
1829fb11590Smike_s 				language = INLD;
1839fb11590Smike_s 				return (C_SYNC);
1847c478bd9Sstevel@tonic-gate 			}
1857c478bd9Sstevel@tonic-gate 		}
1869fb11590Smike_s 		if (lastchar(wordv[1]) == ':') {
1877c478bd9Sstevel@tonic-gate 			/* cc tells us what file we are in */
1889fb11590Smike_s 			/* Sunf77 tells us what subroutine we are in */
1897c478bd9Sstevel@tonic-gate 			currentfilename = wordv[1];
1909fb11590Smike_s 			(void) substitute(currentfilename, ':', '\0');
1919fb11590Smike_s 			language = INCC;
1929fb11590Smike_s 			return (C_SYNC);
1937c478bd9Sstevel@tonic-gate 		}
1949fb11590Smike_s 	} else if ((wordc == 1) && (language == INLD)) {
1959fb11590Smike_s 		nwordv = Calloc(4, sizeof (char *));
1967c478bd9Sstevel@tonic-gate 		nwordv[0] = "ld:";
1977c478bd9Sstevel@tonic-gate 		nwordv[1] = wordv[1];
1987c478bd9Sstevel@tonic-gate 		nwordv[2] = "is";
1997c478bd9Sstevel@tonic-gate 		nwordv[3] = "undefined.";
2007c478bd9Sstevel@tonic-gate 		wordc = 4;
2017c478bd9Sstevel@tonic-gate 		wordv = nwordv - 1;
2029fb11590Smike_s 		return (C_NONSPEC);
2039fb11590Smike_s 	} else if (wordc == 1) {
2049fb11590Smike_s 		/*
2059fb11590Smike_s 		 * any other single word messages are
2069fb11590Smike_s 		 * considered synchronizing
2079fb11590Smike_s 		 */
2089fb11590Smike_s 		return (C_SYNC);
2097c478bd9Sstevel@tonic-gate 	} else
2109fb11590Smike_s 	/* Sunf77 may derive 2-word synchronizing messages ending with a `:' */
2119fb11590Smike_s 	if ((wordc == 2) && (lastchar(wordv[2]) == ':')) {
2129fb11590Smike_s 		wordc = 0;
2139fb11590Smike_s 		language = INSUNF77;
2149fb11590Smike_s 		return (C_SYNC);
2159fb11590Smike_s 	}
2169fb11590Smike_s 	return (C_UNKNOWN);
2177c478bd9Sstevel@tonic-gate }	/* end of one long */
2187c478bd9Sstevel@tonic-gate 
2199fb11590Smike_s Errorclass
cpp(void)2209fb11590Smike_s cpp(void)
2217c478bd9Sstevel@tonic-gate {
2229fb11590Smike_s 	/*
2237c478bd9Sstevel@tonic-gate 	 *	Now attempt a cpp error message match
2247c478bd9Sstevel@tonic-gate 	 *	Examples:
2257c478bd9Sstevel@tonic-gate 	 *		./morse.h: 23: undefined control
2267c478bd9Sstevel@tonic-gate 	 *		morsesend.c: 229: MAGNIBBL: argument mismatch
2277c478bd9Sstevel@tonic-gate 	 *		morsesend.c: 237: MAGNIBBL: argument mismatch
2287c478bd9Sstevel@tonic-gate 	 *		test1.c: 6: undefined control
2297c478bd9Sstevel@tonic-gate 	 */
2309fb11590Smike_s 	if ((language != INLD) &&	/* loader errors have almost same fmt */
2319fb11590Smike_s 	    (lastchar(wordv[1]) == ':') &&
2329fb11590Smike_s 	    (isdigit(firstchar(wordv[2]))) &&
2339fb11590Smike_s 	    (lastchar(wordv[2]) == ':')) {
2347c478bd9Sstevel@tonic-gate 		language = INCPP;
2357c478bd9Sstevel@tonic-gate 		clob_last(wordv[1], '\0');
2367c478bd9Sstevel@tonic-gate 		clob_last(wordv[2], '\0');
2379fb11590Smike_s 		return (C_TRUE);
2387c478bd9Sstevel@tonic-gate 	}
2399fb11590Smike_s 	return (C_UNKNOWN);
2407c478bd9Sstevel@tonic-gate }	/*end of cpp*/
2417c478bd9Sstevel@tonic-gate 
2429fb11590Smike_s Errorclass
pccccom(void)2439fb11590Smike_s pccccom(void)
2447c478bd9Sstevel@tonic-gate {
2457c478bd9Sstevel@tonic-gate 	/*
2467c478bd9Sstevel@tonic-gate 	 *	Now attempt a ccom error message match:
2477c478bd9Sstevel@tonic-gate 	 *	Examples:
2487c478bd9Sstevel@tonic-gate 	 *	  "morsesend.c", line 237: operands of & have incompatible types
2497c478bd9Sstevel@tonic-gate 	 *	  "test.c", line 7: warning: old-fashioned initialization: use =
2507c478bd9Sstevel@tonic-gate 	 *	  "subdir.d/foo2.h", line 1: illegal initialization
2517c478bd9Sstevel@tonic-gate 	 */
2529fb11590Smike_s 	if ((firstchar(wordv[1]) == '"') &&
2539fb11590Smike_s 	    (lastchar(wordv[1]) == ',') &&
2549fb11590Smike_s 	    (next_lastchar(wordv[1]) == '"') &&
2559fb11590Smike_s 	    (strcmp(wordv[2], "line") == 0) &&
2569fb11590Smike_s 	    (isdigit(firstchar(wordv[3]))) &&
2579fb11590Smike_s 	    (lastchar(wordv[3]) == ':')) {
2587c478bd9Sstevel@tonic-gate 		clob_last(wordv[1], '\0');	/* drop last , */
2597c478bd9Sstevel@tonic-gate 		clob_last(wordv[1], '\0');	/* drop last " */
2607c478bd9Sstevel@tonic-gate 		wordv[1]++;			/* drop first " */
2617c478bd9Sstevel@tonic-gate 		clob_last(wordv[3], '\0');	/* drop : on line number */
2627c478bd9Sstevel@tonic-gate 		wordv[2] = wordv[1];	/* overwrite "line" */
2639fb11590Smike_s 		wordv++;		/* compensate */
2647c478bd9Sstevel@tonic-gate 		wordc--;
2657c478bd9Sstevel@tonic-gate 		currentfilename = wordv[1];
2667c478bd9Sstevel@tonic-gate 		language = INCC;
2679fb11590Smike_s 		return (C_TRUE);
2687c478bd9Sstevel@tonic-gate 	}
2699fb11590Smike_s 	return (C_UNKNOWN);
2707c478bd9Sstevel@tonic-gate }	/* end of ccom */
2719fb11590Smike_s 
2727c478bd9Sstevel@tonic-gate /*
2737c478bd9Sstevel@tonic-gate  *	Do the error message from the Richie C Compiler for the PDP11,
2747c478bd9Sstevel@tonic-gate  *	which has this source:
2757c478bd9Sstevel@tonic-gate  *
2767c478bd9Sstevel@tonic-gate  *	if (filename[0])
2777c478bd9Sstevel@tonic-gate  *		fprintf(stderr, "%s:", filename);
2787c478bd9Sstevel@tonic-gate  *	fprintf(stderr, "%d: ", line);
2797c478bd9Sstevel@tonic-gate  *
2807c478bd9Sstevel@tonic-gate  */
2819fb11590Smike_s Errorclass
richieccom(void)2829fb11590Smike_s richieccom(void)
2837c478bd9Sstevel@tonic-gate {
2849fb11590Smike_s 	char	*cp;
2859fb11590Smike_s 	char	**nwordv;
2869fb11590Smike_s 	char	*file;
2877c478bd9Sstevel@tonic-gate 
2889fb11590Smike_s 	if (lastchar(wordv[1]) == ':') {
2897c478bd9Sstevel@tonic-gate 		cp = wordv[1] + strlen(wordv[1]) - 1;
2907c478bd9Sstevel@tonic-gate 		while (isdigit(*--cp))
2917c478bd9Sstevel@tonic-gate 			continue;
2929fb11590Smike_s 		if (*cp == ':') {
2937c478bd9Sstevel@tonic-gate 			clob_last(wordv[1], '\0');	/* last : */
2947c478bd9Sstevel@tonic-gate 			*cp = '\0';			/* first : */
2957c478bd9Sstevel@tonic-gate 			file = wordv[1];
2967c478bd9Sstevel@tonic-gate 			nwordv = wordvsplice(1, wordc, wordv+1);
2977c478bd9Sstevel@tonic-gate 			nwordv[0] = file;
2987c478bd9Sstevel@tonic-gate 			nwordv[1] = cp + 1;
2997c478bd9Sstevel@tonic-gate 			wordc += 1;
3007c478bd9Sstevel@tonic-gate 			wordv = nwordv - 1;
3017c478bd9Sstevel@tonic-gate 			language = INCC;
3027c478bd9Sstevel@tonic-gate 			currentfilename = wordv[1];
3039fb11590Smike_s 			return (C_TRUE);
3047c478bd9Sstevel@tonic-gate 		}
3057c478bd9Sstevel@tonic-gate 	}
3069fb11590Smike_s 	return (C_UNKNOWN);
3077c478bd9Sstevel@tonic-gate }
3087c478bd9Sstevel@tonic-gate 
3099fb11590Smike_s Errorclass
lint0(void)3109fb11590Smike_s lint0(void)
3117c478bd9Sstevel@tonic-gate {
3129fb11590Smike_s 	char	**nwordv;
313*c6867562SToomas Soome 	char	*line, *file;
3147c478bd9Sstevel@tonic-gate 	/*
3157c478bd9Sstevel@tonic-gate 	 *	Attempt a match for the new lint style normal compiler
3167c478bd9Sstevel@tonic-gate 	 *	error messages, of the form
3179fb11590Smike_s 	 *
3187c478bd9Sstevel@tonic-gate 	 *	printf("%s(%d): %s\n", filename, linenumber, message);
3197c478bd9Sstevel@tonic-gate 	 */
3209fb11590Smike_s 	if (wordc >= 2) {
3219fb11590Smike_s 		if ((lastchar(wordv[1]) == ':') &&
3229fb11590Smike_s 		    (next_lastchar(wordv[1]) == ')')) {
3237c478bd9Sstevel@tonic-gate 			clob_last(wordv[1], '\0'); /* colon */
3249fb11590Smike_s 			if (persperdexplode(wordv[1], &line, &file)) {
3257c478bd9Sstevel@tonic-gate 				nwordv = wordvsplice(1, wordc, wordv+1);
3267c478bd9Sstevel@tonic-gate 				nwordv[0] = file;	/* file name */
3277c478bd9Sstevel@tonic-gate 				nwordv[1] = line;	/* line number */
3287c478bd9Sstevel@tonic-gate 				wordc += 1;
3297c478bd9Sstevel@tonic-gate 				wordv = nwordv - 1;
3307c478bd9Sstevel@tonic-gate 				language = INLINT;
3319fb11590Smike_s 				return (C_TRUE);
3327c478bd9Sstevel@tonic-gate 			}
3337c478bd9Sstevel@tonic-gate 			wordv[1][strlen(wordv[1])] = ':';
3347c478bd9Sstevel@tonic-gate 		}
3357c478bd9Sstevel@tonic-gate 	}
3367c478bd9Sstevel@tonic-gate 	return (C_UNKNOWN);
3377c478bd9Sstevel@tonic-gate }
3387c478bd9Sstevel@tonic-gate 
3399fb11590Smike_s Errorclass
lint1(void)3409fb11590Smike_s lint1(void)
3417c478bd9Sstevel@tonic-gate {
3427c478bd9Sstevel@tonic-gate 	char	*line1, *line2;
3437c478bd9Sstevel@tonic-gate 	char	*file1, *file2;
3447c478bd9Sstevel@tonic-gate 	char	**nwordv1, **nwordv2;
3457c478bd9Sstevel@tonic-gate 
3467c478bd9Sstevel@tonic-gate 	/*
3477c478bd9Sstevel@tonic-gate 	 *	Now, attempt a match for the various errors that lint
3487c478bd9Sstevel@tonic-gate 	 *	can complain about.
3497c478bd9Sstevel@tonic-gate 	 *
3507c478bd9Sstevel@tonic-gate 	 *	Look first for type 1 lint errors
3517c478bd9Sstevel@tonic-gate 	 */
3529fb11590Smike_s 	if (wordc > 1 && strcmp(wordv[wordc-1], "::") == 0) {
3539fb11590Smike_s 	/*
3549fb11590Smike_s 	 * %.7s, arg. %d used inconsistently %s(%d) :: %s(%d)
3559fb11590Smike_s 	 * %.7s value used inconsistently %s(%d) :: %s(%d)
3569fb11590Smike_s 	 * %.7s multiply declared %s(%d) :: %s(%d)
3579fb11590Smike_s 	 * %.7s value declared inconsistently %s(%d) :: %s(%d)
3589fb11590Smike_s 	 * %.7s function value type must be declared before use %s(%d) :: %s(%d)
3599fb11590Smike_s 	 */
3607c478bd9Sstevel@tonic-gate 		language = INLINT;
3619fb11590Smike_s 		if ((wordc > 2) &&
3629fb11590Smike_s 		    (persperdexplode(wordv[wordc], &line2, &file2)) &&
3639fb11590Smike_s 		    (persperdexplode(wordv[wordc-2], &line1, &file1))) {
3647c478bd9Sstevel@tonic-gate 			nwordv1 = wordvsplice(2, wordc, wordv+1);
3657c478bd9Sstevel@tonic-gate 			nwordv2 = wordvsplice(2, wordc, wordv+1);
3667c478bd9Sstevel@tonic-gate 			nwordv1[0] = file1; nwordv1[1] = line1;
3679fb11590Smike_s 			/* takes 0 based */
3689fb11590Smike_s 			erroradd(wordc+2, nwordv1, C_TRUE, C_DUPL);
3697c478bd9Sstevel@tonic-gate 			nwordv2[0] = file2; nwordv2[1] = line2;
3707c478bd9Sstevel@tonic-gate 			wordc = wordc + 2;
3717c478bd9Sstevel@tonic-gate 			wordv = nwordv2 - 1;	/* 1 based */
3729fb11590Smike_s 			return (C_TRUE);
3737c478bd9Sstevel@tonic-gate 		}
3747c478bd9Sstevel@tonic-gate 	}
3759fb11590Smike_s 	return (C_UNKNOWN);
3767c478bd9Sstevel@tonic-gate } /* end of lint 1*/
3777c478bd9Sstevel@tonic-gate 
3789fb11590Smike_s Errorclass
lint2(void)3799fb11590Smike_s lint2(void)
3807c478bd9Sstevel@tonic-gate {
3817c478bd9Sstevel@tonic-gate 	char	*file;
3827c478bd9Sstevel@tonic-gate 	char	*line;
3837c478bd9Sstevel@tonic-gate 	char	**nwordv;
3847c478bd9Sstevel@tonic-gate 	/*
3857c478bd9Sstevel@tonic-gate 	 *	Look for type 2 lint errors
3867c478bd9Sstevel@tonic-gate 	 *
3877c478bd9Sstevel@tonic-gate 	 *	%.7s used( %s(%d) ), but not defined
3887c478bd9Sstevel@tonic-gate 	 *	%.7s defined( %s(%d) ), but never used
3897c478bd9Sstevel@tonic-gate 	 *	%.7s declared( %s(%d) ), but never used or defined
3907c478bd9Sstevel@tonic-gate 	 *
3917c478bd9Sstevel@tonic-gate 	 *	bufp defined( "./metric.h"(10) ), but never used
3927c478bd9Sstevel@tonic-gate 	 */
3939fb11590Smike_s 	if ((lastchar(wordv[2]) == '(' /* ')' */) &&
3949fb11590Smike_s 	    (strcmp(wordv[4], "),") == 0)) {
3957c478bd9Sstevel@tonic-gate 		language = INLINT;
3969fb11590Smike_s 		if (persperdexplode(wordv[3], &line, &file)) {
3977c478bd9Sstevel@tonic-gate 			nwordv = wordvsplice(2, wordc, wordv+1);
3987c478bd9Sstevel@tonic-gate 			nwordv[0] = file; nwordv[1] = line;
3997c478bd9Sstevel@tonic-gate 			wordc = wordc + 2;
4007c478bd9Sstevel@tonic-gate 			wordv = nwordv - 1;	/* 1 based */
4019fb11590Smike_s 			return (C_TRUE);
4027c478bd9Sstevel@tonic-gate 		}
4037c478bd9Sstevel@tonic-gate 	}
4049fb11590Smike_s 	return (C_UNKNOWN);
4057c478bd9Sstevel@tonic-gate } /* end of lint 2*/
4067c478bd9Sstevel@tonic-gate 
4077c478bd9Sstevel@tonic-gate char	*Lint31[4] = {"returns", "value", "which", "is"};
4087c478bd9Sstevel@tonic-gate char	*Lint32[6] = {"value", "is", "used,", "but", "none", "returned"};
4099fb11590Smike_s 
4109fb11590Smike_s Errorclass
lint3(void)4119fb11590Smike_s lint3(void)
4127c478bd9Sstevel@tonic-gate {
4139fb11590Smike_s 	if ((wordvcmp(wordv+2, 4, Lint31) == 0) ||
4149fb11590Smike_s 	    (wordvcmp(wordv+2, 6, Lint32) == 0)) {
4157c478bd9Sstevel@tonic-gate 		language = INLINT;
4169fb11590Smike_s 		return (C_NONSPEC);
4177c478bd9Sstevel@tonic-gate 	}
4189fb11590Smike_s 	return (C_UNKNOWN);
4197c478bd9Sstevel@tonic-gate }
4207c478bd9Sstevel@tonic-gate 
4217c478bd9Sstevel@tonic-gate /*
4227c478bd9Sstevel@tonic-gate  *	Special word vectors for use by F77 recognition
4237c478bd9Sstevel@tonic-gate  */
4247c478bd9Sstevel@tonic-gate char	*F77_fatal[3] = {"Compiler", "error", "line"};
4257c478bd9Sstevel@tonic-gate char	*F77_error[3] = {"Error", "on", "line"};
4267c478bd9Sstevel@tonic-gate char	*F77_warning[3] = {"Warning", "on", "line"};
4279fb11590Smike_s char    *F77_no_ass[3] = {"Error.", "No", "assembly."};
4287c478bd9Sstevel@tonic-gate 
4299fb11590Smike_s Errorclass
f77(void)4309fb11590Smike_s f77(void)
4317c478bd9Sstevel@tonic-gate {
4327c478bd9Sstevel@tonic-gate 	char	**nwordv;
4337c478bd9Sstevel@tonic-gate 	/*
4347c478bd9Sstevel@tonic-gate 	 *	look for f77 errors:
4357c478bd9Sstevel@tonic-gate 	 *	Error messages from /usr/src/cmd/f77/error.c, with
4367c478bd9Sstevel@tonic-gate 	 *	these printf formats:
4377c478bd9Sstevel@tonic-gate 	 *
4387c478bd9Sstevel@tonic-gate 	 *		Compiler error line %d of %s: %s
4397c478bd9Sstevel@tonic-gate 	 *		Error on line %d of %s: %s
4407c478bd9Sstevel@tonic-gate 	 *		Warning on line %d of %s: %s
4417c478bd9Sstevel@tonic-gate 	 *		Error.  No assembly.
4427c478bd9Sstevel@tonic-gate 	 */
4437c478bd9Sstevel@tonic-gate 	if (wordc == 3 && wordvcmp(wordv+1, 3, F77_no_ass) == 0) {
4447c478bd9Sstevel@tonic-gate 		wordc = 0;
4459fb11590Smike_s 		return (C_SYNC);
4467c478bd9Sstevel@tonic-gate 	}
4477c478bd9Sstevel@tonic-gate 	if (wordc < 6)
4489fb11590Smike_s 		return (C_UNKNOWN);
4499fb11590Smike_s 	if ((lastchar(wordv[6]) == ':') &&
4509fb11590Smike_s 	    ((wordvcmp(wordv+1, 3, F77_fatal) == 0) ||
451*c6867562SToomas Soome 	    (wordvcmp(wordv+1, 3, F77_error) == 0) ||
452*c6867562SToomas Soome 	    (wordvcmp(wordv+1, 3, F77_warning) == 0))) {
4537c478bd9Sstevel@tonic-gate 		language = INF77;
4547c478bd9Sstevel@tonic-gate 		nwordv = wordvsplice(2, wordc, wordv+1);
4557c478bd9Sstevel@tonic-gate 		nwordv[0] = wordv[6];
4569fb11590Smike_s 		clob_last(nwordv[0], '\0');
4577c478bd9Sstevel@tonic-gate 		nwordv[1] = wordv[4];
4587c478bd9Sstevel@tonic-gate 		wordc += 2;
4597c478bd9Sstevel@tonic-gate 		wordv = nwordv - 1;	/* 1 based */
4609fb11590Smike_s 		return (C_TRUE);
4617c478bd9Sstevel@tonic-gate 	}
4629fb11590Smike_s 	return (C_UNKNOWN);
4637c478bd9Sstevel@tonic-gate } /* end of f77 */
4647c478bd9Sstevel@tonic-gate 
4657c478bd9Sstevel@tonic-gate char	*Make_Croak[3] = {"***", "Error", "code"};
4667c478bd9Sstevel@tonic-gate char	*Make_NotRemade[5] = {"not", "remade", "because", "of", "errors"};
4679fb11590Smike_s 
4689fb11590Smike_s Errorclass
make(void)4699fb11590Smike_s make(void)
4707c478bd9Sstevel@tonic-gate {
4719fb11590Smike_s 	if (wordvcmp(wordv+1, 3, Make_Croak) == 0) {
4727c478bd9Sstevel@tonic-gate 		language = INMAKE;
4739fb11590Smike_s 		return (C_SYNC);
4747c478bd9Sstevel@tonic-gate 	}
4759fb11590Smike_s 	if (wordvcmp(wordv+2, 5, Make_NotRemade) == 0) {
4767c478bd9Sstevel@tonic-gate 		language = INMAKE;
4779fb11590Smike_s 		return (C_SYNC);
4787c478bd9Sstevel@tonic-gate 	}
4799fb11590Smike_s 	return (C_UNKNOWN);
4807c478bd9Sstevel@tonic-gate }
4819fb11590Smike_s 
4829fb11590Smike_s Errorclass
ri(void)4839fb11590Smike_s ri(void)
4847c478bd9Sstevel@tonic-gate {
4857c478bd9Sstevel@tonic-gate /*
4867c478bd9Sstevel@tonic-gate  *	Match an error message produced by ri; here is the
4877c478bd9Sstevel@tonic-gate  *	procedure yanked from the distributed version of ri
4887c478bd9Sstevel@tonic-gate  *	April 24, 1980.
4899fb11590Smike_s  *
4907c478bd9Sstevel@tonic-gate  *	serror(str, x1, x2, x3)
4917c478bd9Sstevel@tonic-gate  *		char str[];
4927c478bd9Sstevel@tonic-gate  *		char *x1, *x2, *x3;
4937c478bd9Sstevel@tonic-gate  *	{
4947c478bd9Sstevel@tonic-gate  *		extern int yylineno;
4959fb11590Smike_s  *
4967c478bd9Sstevel@tonic-gate  *		putc('"', stdout);
4977c478bd9Sstevel@tonic-gate  *		fputs(srcfile, stdout);
4987c478bd9Sstevel@tonic-gate  *		putc('"', stdout);
4997c478bd9Sstevel@tonic-gate  *		fprintf(stdout, " %d: ", yylineno);
5007c478bd9Sstevel@tonic-gate  *		fprintf(stdout, str, x1, x2, x3);
5017c478bd9Sstevel@tonic-gate  *		fprintf(stdout, "\n");
5027c478bd9Sstevel@tonic-gate  *		synerrs++;
5037c478bd9Sstevel@tonic-gate  *	}
5047c478bd9Sstevel@tonic-gate  */
5059fb11590Smike_s 	if ((firstchar(wordv[1]) == '"') &&
5069fb11590Smike_s 	    (lastchar(wordv[1]) == '"') &&
5079fb11590Smike_s 	    (lastchar(wordv[2]) == ':') &&
5089fb11590Smike_s 	    (isdigit(firstchar(wordv[2])))) {
5097c478bd9Sstevel@tonic-gate 		clob_last(wordv[1], '\0');	/* drop the last " */
5107c478bd9Sstevel@tonic-gate 		wordv[1]++;	/* skip over the first " */
5117c478bd9Sstevel@tonic-gate 		clob_last(wordv[2], '\0');
5127c478bd9Sstevel@tonic-gate 		language = INRI;
5139fb11590Smike_s 		return (C_TRUE);
5147c478bd9Sstevel@tonic-gate 	}
5159fb11590Smike_s 	return (C_UNKNOWN);
5167c478bd9Sstevel@tonic-gate }
5177c478bd9Sstevel@tonic-gate 
5189fb11590Smike_s static Errorclass
catchall(void)5199fb11590Smike_s catchall(void)
5207c478bd9Sstevel@tonic-gate {
5217c478bd9Sstevel@tonic-gate 	/*
5227c478bd9Sstevel@tonic-gate 	 *	Catches random things.
5237c478bd9Sstevel@tonic-gate 	 */
5247c478bd9Sstevel@tonic-gate 	language = INUNKNOWN;
5259fb11590Smike_s 	return (C_NONSPEC);
5269fb11590Smike_s }
5277c478bd9Sstevel@tonic-gate 
5289fb11590Smike_s Errorclass
troff(void)5299fb11590Smike_s troff(void)
5307c478bd9Sstevel@tonic-gate {
5317c478bd9Sstevel@tonic-gate 	/*
5327c478bd9Sstevel@tonic-gate 	 *	troff source error message, from eqn, bib, tbl...
5337c478bd9Sstevel@tonic-gate 	 *	Just like pcc ccom, except uses `'
5347c478bd9Sstevel@tonic-gate 	 */
5359fb11590Smike_s 	if ((firstchar(wordv[1]) == '`') &&
5369fb11590Smike_s 	    (lastchar(wordv[1]) == ',') &&
5379fb11590Smike_s 	    (next_lastchar(wordv[1]) == '\'') &&
5389fb11590Smike_s 	    (strcmp(wordv[2], "line") == 0) &&
5399fb11590Smike_s 	    (isdigit(firstchar(wordv[3]))) &&
5409fb11590Smike_s 	    (lastchar(wordv[3]) == ':')) {
5417c478bd9Sstevel@tonic-gate 		clob_last(wordv[1], '\0');	/* drop last , */
5427c478bd9Sstevel@tonic-gate 		clob_last(wordv[1], '\0');	/* drop last " */
5437c478bd9Sstevel@tonic-gate 		wordv[1]++;			/* drop first " */
5447c478bd9Sstevel@tonic-gate 		clob_last(wordv[3], '\0');	/* drop : on line number */
5457c478bd9Sstevel@tonic-gate 		wordv[2] = wordv[1];	/* overwrite "line" */
5469fb11590Smike_s 		wordv++;		/* compensate */
5477c478bd9Sstevel@tonic-gate 		currentfilename = wordv[1];
5487c478bd9Sstevel@tonic-gate 		language = INTROFF;
5499fb11590Smike_s 		return (C_TRUE);
5507c478bd9Sstevel@tonic-gate 	}
5519fb11590Smike_s 	return (C_UNKNOWN);
5527c478bd9Sstevel@tonic-gate }
5539fb11590Smike_s 
5549fb11590Smike_s Errorclass
mod2(void)5559fb11590Smike_s mod2(void)
5567c478bd9Sstevel@tonic-gate {
5577c478bd9Sstevel@tonic-gate 	/*
5587c478bd9Sstevel@tonic-gate 	 *	for decwrl modula2 compiler (powell)
5597c478bd9Sstevel@tonic-gate 	 */
5609fb11590Smike_s 	if (((strcmp(wordv[1], "!!!") == 0) ||		/* early version */
5619fb11590Smike_s 	    (strcmp(wordv[1], "File") == 0)) &&		/* later version */
562*c6867562SToomas Soome 	    (lastchar(wordv[2]) == ',') &&		/* file name */
563*c6867562SToomas Soome 	    (strcmp(wordv[3], "line") == 0) &&
564*c6867562SToomas Soome 	    (isdigit(firstchar(wordv[4]))) &&	/* line number */
565*c6867562SToomas Soome 	    (lastchar(wordv[4]) == ':')) {	/* line number */
5667c478bd9Sstevel@tonic-gate 		clob_last(wordv[2], '\0');	/* drop last , on file name */
5677c478bd9Sstevel@tonic-gate 		clob_last(wordv[4], '\0');	/* drop last : on line number */
5687c478bd9Sstevel@tonic-gate 		wordv[3] = wordv[2];		/* file name on top of "line" */
5697c478bd9Sstevel@tonic-gate 		wordv += 2;
5707c478bd9Sstevel@tonic-gate 		wordc -= 2;
5717c478bd9Sstevel@tonic-gate 		currentfilename = wordv[1];
5727c478bd9Sstevel@tonic-gate 		language = INMOD2;
5739fb11590Smike_s 		return (C_TRUE);
5747c478bd9Sstevel@tonic-gate 	}
5759fb11590Smike_s 	return (C_UNKNOWN);
5767c478bd9Sstevel@tonic-gate }
5777c478bd9Sstevel@tonic-gate 
5789fb11590Smike_s Errorclass
sunf77(void)5799fb11590Smike_s sunf77(void)
5807c478bd9Sstevel@tonic-gate {
5817c478bd9Sstevel@tonic-gate 	/*
5829fb11590Smike_s 	 * Finally attempt a Sun f77 error message match:
5839fb11590Smike_s 	 * Examples:
5849fb11590Smike_s 	 *	"bar.f", line 237: Error: no label on format statement
5859fb11590Smike_s 	 *	"test.f", line 7: ANSI extension: Hollerith constant
5869fb11590Smike_s 	 *	"dir/foo.h", line 1: Warning: missing END statement
5877c478bd9Sstevel@tonic-gate 	 */
5889fb11590Smike_s 	if ((firstchar(wordv[1]) == '"') &&
5899fb11590Smike_s 	    (lastchar(wordv[1]) == ',') &&
5909fb11590Smike_s 	    (next_lastchar(wordv[1]) == '"') &&
5919fb11590Smike_s 	    (strcmp(wordv[2], "line") == 0) &&
5929fb11590Smike_s 	    (isdigit(firstchar(wordv[3]))) &&
5939fb11590Smike_s 	    (lastchar(wordv[3]) == ':') &&
594*c6867562SToomas Soome 	    ((strcmp(wordv[4], "Error:") == 0) ||
595*c6867562SToomas Soome 	    (strcmp(wordv[4], "Warning:") == 0) ||
596*c6867562SToomas Soome 	    ((strcmp(wordv[4], "ANSI") == 0) &&
597*c6867562SToomas Soome 	    (strcmp(wordv[5], "extension:") == 0)))) {
5987c478bd9Sstevel@tonic-gate 		clob_last(wordv[1], '\0');	/* drop last , */
5997c478bd9Sstevel@tonic-gate 		clob_last(wordv[1], '\0');	/* drop last " */
6007c478bd9Sstevel@tonic-gate 		wordv[1]++;			/* drop first " */
6017c478bd9Sstevel@tonic-gate 		clob_last(wordv[3], '\0');	/* drop : on line number */
6027c478bd9Sstevel@tonic-gate 		wordv[2] = wordv[1];	/* overwrite "line" */
6039fb11590Smike_s 		wordv++;		/* compensate */
6047c478bd9Sstevel@tonic-gate 		wordc--;
6057c478bd9Sstevel@tonic-gate 		currentfilename = wordv[1];
6067c478bd9Sstevel@tonic-gate 		language = INSUNF77;
6079fb11590Smike_s 		return (C_TRUE);
6087c478bd9Sstevel@tonic-gate 	}
6099fb11590Smike_s 	return (C_UNKNOWN);
6107c478bd9Sstevel@tonic-gate }	/* end of Sun f77 */
611