Home | History | Annotate | Line # | Download | only in error
input.c revision 1.11
      1  1.11  christos /*	$NetBSD: input.c,v 1.11 2006/04/09 19:27:22 christos Exp $	*/
      2   1.3       jtc 
      3   1.1       cgd /*
      4   1.3       jtc  * Copyright (c) 1980, 1993
      5   1.3       jtc  *	The Regents of the University of California.  All rights reserved.
      6   1.1       cgd  *
      7   1.1       cgd  * Redistribution and use in source and binary forms, with or without
      8   1.1       cgd  * modification, are permitted provided that the following conditions
      9   1.1       cgd  * are met:
     10   1.1       cgd  * 1. Redistributions of source code must retain the above copyright
     11   1.1       cgd  *    notice, this list of conditions and the following disclaimer.
     12   1.1       cgd  * 2. Redistributions in binary form must reproduce the above copyright
     13   1.1       cgd  *    notice, this list of conditions and the following disclaimer in the
     14   1.1       cgd  *    documentation and/or other materials provided with the distribution.
     15  1.10       agc  * 3. Neither the name of the University nor the names of its contributors
     16   1.1       cgd  *    may be used to endorse or promote products derived from this software
     17   1.1       cgd  *    without specific prior written permission.
     18   1.1       cgd  *
     19   1.1       cgd  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     20   1.1       cgd  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     21   1.1       cgd  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     22   1.1       cgd  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
     23   1.1       cgd  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     24   1.1       cgd  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     25   1.1       cgd  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     26   1.1       cgd  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     27   1.1       cgd  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     28   1.1       cgd  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     29   1.1       cgd  * SUCH DAMAGE.
     30   1.1       cgd  */
     31   1.1       cgd 
     32   1.5     lukem #include <sys/cdefs.h>
     33   1.1       cgd #ifndef lint
     34   1.3       jtc #if 0
     35   1.3       jtc static char sccsid[] = "@(#)input.c	8.1 (Berkeley) 6/6/93";
     36   1.3       jtc #endif
     37  1.11  christos __RCSID("$NetBSD: input.c,v 1.11 2006/04/09 19:27:22 christos Exp $");
     38   1.1       cgd #endif /* not lint */
     39   1.1       cgd 
     40   1.1       cgd #include <stdio.h>
     41   1.1       cgd #include <ctype.h>
     42   1.1       cgd #include <stdlib.h>
     43   1.1       cgd #include <string.h>
     44   1.1       cgd #include "error.h"
     45   1.1       cgd 
     46   1.1       cgd int	wordc;		/* how long the current error message is */
     47   1.1       cgd char	**wordv;	/* the actual error message */
     48   1.1       cgd 
     49   1.9       wiz Errorclass	catchall(void);
     50   1.9       wiz Errorclass	cpp(void);
     51   1.9       wiz Errorclass	f77(void);
     52   1.9       wiz Errorclass	lint0(void);
     53   1.9       wiz Errorclass	lint1(void);
     54   1.9       wiz Errorclass	lint2(void);
     55   1.9       wiz Errorclass	lint3(void);
     56   1.9       wiz Errorclass	make(void);
     57   1.9       wiz Errorclass	mod2(void);
     58   1.9       wiz Errorclass	onelong(void);
     59   1.9       wiz Errorclass	pccccom(void);	/* Portable C Compiler C Compiler */
     60   1.9       wiz Errorclass	pi(void);
     61   1.9       wiz Errorclass	ri(void);
     62   1.9       wiz Errorclass	richieccom(void);	/* Richie Compiler for 11 */
     63   1.9       wiz Errorclass	troff(void);
     64   1.5     lukem 
     65   1.1       cgd /*
     66   1.1       cgd  *	Eat all of the lines in the input file, attempting to categorize
     67   1.1       cgd  *	them by their various flavors
     68   1.1       cgd  */
     69   1.5     lukem void
     70   1.9       wiz eaterrors(int *r_errorc, Eptr **r_errorv)
     71   1.1       cgd {
     72   1.1       cgd 	Errorclass	errorclass = C_SYNC;
     73   1.4  christos 	char *line;
     74   1.4  christos 	char *inbuffer;
     75   1.4  christos 	size_t inbuflen;
     76   1.1       cgd 
     77   1.1       cgd     for (;;){
     78   1.4  christos 	if ((inbuffer = fgetln(errorfile, &inbuflen)) == NULL)
     79   1.1       cgd 		break;
     80   1.4  christos 	line = Calloc(inbuflen + 1, sizeof(char));
     81   1.4  christos 	memcpy(line, inbuffer, inbuflen);
     82   1.4  christos 	line[inbuflen] = '\0';
     83   1.4  christos 	wordvbuild(line, &wordc, &wordv);
     84   1.1       cgd 	/*
     85   1.1       cgd 	 *	for convience, convert wordv to be 1 based, instead
     86   1.1       cgd 	 *	of 0 based.
     87   1.1       cgd 	 */
     88   1.1       cgd 	wordv -= 1;
     89   1.1       cgd 	if ( wordc > 0 &&
     90   1.1       cgd 	   ((( errorclass = onelong() ) != C_UNKNOWN)
     91   1.1       cgd 	   || (( errorclass = cpp() ) != C_UNKNOWN)
     92   1.1       cgd 	   || (( errorclass = pccccom() ) != C_UNKNOWN)
     93   1.1       cgd 	   || (( errorclass = richieccom() ) != C_UNKNOWN)
     94   1.1       cgd 	   || (( errorclass = lint0() ) != C_UNKNOWN)
     95   1.1       cgd 	   || (( errorclass = lint1() ) != C_UNKNOWN)
     96   1.1       cgd 	   || (( errorclass = lint2() ) != C_UNKNOWN)
     97   1.1       cgd 	   || (( errorclass = lint3() ) != C_UNKNOWN)
     98   1.1       cgd 	   || (( errorclass = make() ) != C_UNKNOWN)
     99   1.1       cgd 	   || (( errorclass = f77() ) != C_UNKNOWN)
    100   1.1       cgd 	   || ((errorclass = pi() ) != C_UNKNOWN)
    101   1.1       cgd 	   || (( errorclass = ri() )!= C_UNKNOWN)
    102   1.1       cgd 	   || (( errorclass = mod2() )!= C_UNKNOWN)
    103   1.1       cgd 	   || (( errorclass = troff() )!= C_UNKNOWN))
    104   1.1       cgd 	) ;
    105   1.1       cgd 	else
    106   1.1       cgd 		errorclass = catchall();
    107   1.1       cgd 	if (wordc)
    108   1.1       cgd 		erroradd(wordc, wordv+1, errorclass, C_UNKNOWN);
    109   1.1       cgd     }
    110   1.1       cgd #ifdef FULLDEBUG
    111   1.1       cgd     printf("%d errorentrys\n", nerrors);
    112   1.1       cgd #endif
    113   1.1       cgd     arrayify(r_errorc, r_errorv, er_head);
    114   1.1       cgd }
    115   1.1       cgd 
    116   1.1       cgd /*
    117   1.1       cgd  *	create a new error entry, given a zero based array and count
    118   1.1       cgd  */
    119   1.5     lukem void
    120   1.9       wiz erroradd(int errorlength, char **errorv, Errorclass errorclass,
    121   1.9       wiz 	 Errorclass errorsubclass)
    122   1.1       cgd {
    123   1.5     lukem 	Eptr	newerror;
    124   1.5     lukem 	char	*cp;
    125   1.1       cgd 
    126   1.1       cgd 	if (errorclass == C_TRUE){
    127   1.1       cgd 		/* check canonicalization of the second argument*/
    128   1.7  christos 		for(cp = errorv[1]; *cp && isdigit((unsigned char)*cp); cp++)
    129   1.1       cgd 			continue;
    130   1.1       cgd 		errorclass = (*cp == '\0') ? C_TRUE : C_NONSPEC;
    131   1.1       cgd #ifdef FULLDEBUG
    132   1.1       cgd 		if (errorclass != C_TRUE)
    133   1.1       cgd 			printf("The 2nd word, \"%s\" is not a number.\n",
    134   1.1       cgd 				errorv[1]);
    135   1.1       cgd #endif
    136   1.1       cgd 	}
    137   1.1       cgd 	if (errorlength > 0){
    138   1.1       cgd 		newerror = (Eptr)Calloc(1, sizeof(Edesc));
    139   1.1       cgd 		newerror->error_language = language; /* language is global */
    140   1.1       cgd 		newerror->error_text = errorv;
    141   1.1       cgd 		newerror->error_lgtext = errorlength;
    142   1.1       cgd 		if (errorclass == C_TRUE)
    143   1.1       cgd 			newerror->error_line = atoi(errorv[1]);
    144   1.1       cgd 		newerror->error_e_class = errorclass;
    145   1.1       cgd 		newerror->error_s_class = errorsubclass;
    146   1.1       cgd 		switch(newerror->error_e_class = discardit(newerror)){
    147   1.1       cgd 			case C_SYNC:		nsyncerrors++; break;
    148   1.1       cgd 			case C_DISCARD: 	ndiscard++; break;
    149   1.1       cgd 			case C_NULLED:		nnulled++; break;
    150   1.1       cgd 			case C_NONSPEC:		nnonspec++; break;
    151   1.1       cgd 			case C_THISFILE: 	nthisfile++; break;
    152   1.1       cgd 			case C_TRUE:		ntrue++; break;
    153   1.1       cgd 			case C_UNKNOWN:		nunknown++; break;
    154   1.1       cgd 			case C_IGNORE:		nignore++; break;
    155   1.1       cgd 		}
    156   1.1       cgd 		newerror->error_next = er_head;
    157   1.1       cgd 		er_head = newerror;
    158   1.1       cgd 		newerror->error_no = nerrors++;
    159   1.1       cgd 	}	/* length > 0 */
    160   1.1       cgd }
    161   1.1       cgd 
    162   1.5     lukem Errorclass
    163   1.9       wiz onelong(void)
    164   1.1       cgd {
    165   1.1       cgd 	char	**nwordv;
    166   1.1       cgd 	if ( (wordc == 1) && (language != INLD) ){
    167   1.1       cgd 		/*
    168   1.1       cgd 		 *	We have either:
    169   1.1       cgd 		 *	a)	file name from cc
    170   1.1       cgd 		 *	b)	Assembler telling world that it is complaining
    171   1.1       cgd 		 *	c)	Noise from make ("Stop.")
    172   1.1       cgd 		 *	c)	Random noise
    173   1.1       cgd 		 */
    174   1.1       cgd 		wordc = 0;
    175   1.1       cgd 		if (strcmp(wordv[1], "Stop.") == 0){
    176   1.1       cgd 			language = INMAKE; return(C_SYNC);
    177   1.1       cgd 		}
    178   1.1       cgd 		if (strcmp(wordv[1], "Assembler:") == 0){
    179   1.1       cgd 			/* assembler always alerts us to what happened*/
    180   1.1       cgd 			language = INAS; return(C_SYNC);
    181   1.1       cgd 		} else
    182   1.1       cgd 		if (strcmp(wordv[1], "Undefined:") == 0){
    183   1.1       cgd 			/* loader complains about unknown symbols*/
    184   1.1       cgd 			language = INLD; return(C_SYNC);
    185   1.1       cgd 		}
    186   1.1       cgd 		if (lastchar(wordv[1]) == ':'){
    187   1.1       cgd 			/* cc tells us what file we are in */
    188   1.1       cgd 			currentfilename = wordv[1];
    189   1.1       cgd 			(void)substitute(currentfilename, ':', '\0');
    190   1.1       cgd 			language = INCC; return(C_SYNC);
    191   1.1       cgd 		}
    192   1.1       cgd 	} else
    193   1.1       cgd 	if ( (wordc == 1) && (language == INLD) ){
    194   1.1       cgd 		nwordv = (char **)Calloc(4, sizeof(char *));
    195   1.1       cgd 		nwordv[0] = "ld:";
    196   1.1       cgd 		nwordv[1] = wordv[1];
    197   1.1       cgd 		nwordv[2] = "is";
    198   1.1       cgd 		nwordv[3] = "undefined.";
    199   1.1       cgd 		wordc = 4;
    200   1.1       cgd 		wordv = nwordv - 1;
    201   1.1       cgd 		return(C_NONSPEC);
    202   1.1       cgd 	} else
    203   1.1       cgd 	if (wordc == 1){
    204   1.1       cgd 		return(C_SYNC);
    205   1.1       cgd 	}
    206   1.1       cgd 	return(C_UNKNOWN);
    207   1.1       cgd }	/* end of one long */
    208   1.1       cgd 
    209   1.5     lukem Errorclass
    210   1.9       wiz cpp(void)
    211   1.1       cgd {
    212   1.1       cgd 	/*
    213   1.1       cgd 	 *	Now attempt a cpp error message match
    214   1.1       cgd 	 *	Examples:
    215   1.1       cgd 	 *		./morse.h: 23: undefined control
    216   1.1       cgd 	 *		morsesend.c: 229: MAGNIBBL: argument mismatch
    217   1.1       cgd 	 *		morsesend.c: 237: MAGNIBBL: argument mismatch
    218   1.1       cgd 	 *		test1.c: 6: undefined control
    219   1.1       cgd 	 */
    220   1.8  christos 	if (wordc < 3)
    221   1.8  christos 		return (C_UNKNOWN);
    222   1.1       cgd 	if (   (language != INLD)		/* loader errors have almost same fmt*/
    223   1.1       cgd 	    && (lastchar(wordv[1]) == ':')
    224   1.7  christos 	    && (isdigit((unsigned char)firstchar(wordv[2])))
    225   1.1       cgd 	    && (lastchar(wordv[2]) == ':') ){
    226   1.1       cgd 		language = INCPP;
    227   1.1       cgd 		clob_last(wordv[1], '\0');
    228   1.1       cgd 		clob_last(wordv[2], '\0');
    229   1.1       cgd 		return(C_TRUE);
    230   1.1       cgd 	}
    231   1.1       cgd 	return(C_UNKNOWN);
    232   1.1       cgd }	/*end of cpp*/
    233   1.1       cgd 
    234   1.5     lukem Errorclass
    235   1.9       wiz pccccom(void)
    236   1.1       cgd {
    237   1.1       cgd 	/*
    238   1.1       cgd 	 *	Now attempt a ccom error message match:
    239   1.1       cgd 	 *	Examples:
    240   1.1       cgd 	 *	  "morsesend.c", line 237: operands of & have incompatible types
    241   1.1       cgd 	 *	  "test.c", line 7: warning: old-fashioned initialization: use =
    242   1.1       cgd 	 *	  "subdir.d/foo2.h", line 1: illegal initialization
    243   1.1       cgd 	 */
    244   1.8  christos 	if (wordc < 4)
    245   1.8  christos 		return (C_UNKNOWN);
    246   1.1       cgd 	if (   (firstchar(wordv[1]) == '"')
    247   1.1       cgd 	    && (lastchar(wordv[1]) == ',')
    248   1.1       cgd 	    && (next_lastchar(wordv[1]) == '"')
    249   1.1       cgd 	    && (strcmp(wordv[2],"line") == 0)
    250   1.7  christos 	    && (isdigit((unsigned char)firstchar(wordv[3])))
    251   1.1       cgd 	    && (lastchar(wordv[3]) == ':') ){
    252   1.1       cgd 		clob_last(wordv[1], '\0');	/* drop last , */
    253   1.1       cgd 		clob_last(wordv[1], '\0');	/* drop last " */
    254   1.1       cgd 		wordv[1]++;			/* drop first " */
    255   1.1       cgd 		clob_last(wordv[3], '\0');	/* drop : on line number */
    256   1.1       cgd 		wordv[2] = wordv[1];	/* overwrite "line" */
    257   1.1       cgd 		wordv++;		/*compensate*/
    258   1.1       cgd 		wordc--;
    259   1.1       cgd 		currentfilename = wordv[1];
    260   1.1       cgd 		language = INCC;
    261   1.1       cgd 		return(C_TRUE);
    262   1.1       cgd 	}
    263   1.1       cgd 	return(C_UNKNOWN);
    264   1.1       cgd }	/* end of ccom */
    265   1.1       cgd /*
    266   1.1       cgd  *	Do the error message from the Richie C Compiler for the PDP11,
    267   1.1       cgd  *	which has this source:
    268   1.1       cgd  *
    269   1.1       cgd  *	if (filename[0])
    270   1.1       cgd  *		fprintf(stderr, "%s:", filename);
    271   1.1       cgd  *	fprintf(stderr, "%d: ", line);
    272   1.1       cgd  *
    273   1.1       cgd  */
    274   1.5     lukem 
    275   1.5     lukem Errorclass
    276   1.9       wiz richieccom(void)
    277   1.1       cgd {
    278   1.5     lukem 	char	*cp;
    279   1.5     lukem 	char	**nwordv;
    280   1.5     lukem 	char	*file;
    281   1.1       cgd 
    282   1.8  christos 	if (wordc < 2)
    283   1.8  christos 		return (C_UNKNOWN);
    284   1.8  christos 
    285   1.1       cgd 	if (lastchar(wordv[1]) == ':'){
    286   1.1       cgd 		cp = wordv[1] + strlen(wordv[1]) - 1;
    287   1.7  christos 		while (isdigit((unsigned char)*--cp))
    288   1.1       cgd 			continue;
    289   1.1       cgd 		if (*cp == ':'){
    290   1.1       cgd 			clob_last(wordv[1], '\0');	/* last : */
    291   1.1       cgd 			*cp = '\0';			/* first : */
    292   1.1       cgd 			file = wordv[1];
    293   1.1       cgd 			nwordv = wordvsplice(1, wordc, wordv+1);
    294   1.1       cgd 			nwordv[0] = file;
    295   1.1       cgd 			nwordv[1] = cp + 1;
    296   1.1       cgd 			wordc += 1;
    297   1.1       cgd 			wordv = nwordv - 1;
    298   1.1       cgd 			language = INCC;
    299   1.1       cgd 			currentfilename = wordv[1];
    300   1.1       cgd 			return(C_TRUE);
    301   1.1       cgd 		}
    302   1.1       cgd 	}
    303   1.1       cgd 	return(C_UNKNOWN);
    304   1.1       cgd }
    305   1.1       cgd 
    306   1.5     lukem Errorclass
    307   1.9       wiz lint0(void)
    308   1.1       cgd {
    309   1.5     lukem 	char	**nwordv;
    310   1.5     lukem 	char	*line, *file;
    311   1.1       cgd 	/*
    312   1.1       cgd 	 *	Attempt a match for the new lint style normal compiler
    313   1.1       cgd 	 *	error messages, of the form
    314   1.1       cgd 	 *
    315   1.1       cgd 	 *	printf("%s(%d): %s\n", filename, linenumber, message);
    316   1.1       cgd 	 */
    317   1.8  christos 	if (wordc < 2)
    318   1.8  christos 		return (C_UNKNOWN);
    319   1.8  christos 
    320   1.8  christos 	if (   (lastchar(wordv[1]) == ':')
    321   1.8  christos 	    && (next_lastchar(wordv[1]) == ')') ) {
    322   1.8  christos 		clob_last(wordv[1], '\0'); /* colon */
    323   1.8  christos 		if (persperdexplode(wordv[1], &line, &file)){
    324   1.8  christos 			nwordv = wordvsplice(1, wordc, wordv+1);
    325   1.8  christos 			nwordv[0] = file;	/* file name */
    326   1.8  christos 			nwordv[1] = line;	/* line number */
    327   1.8  christos 			wordc += 1;
    328   1.8  christos 			wordv = nwordv - 1;
    329   1.8  christos 			language = INLINT;
    330   1.8  christos 			return(C_TRUE);
    331   1.1       cgd 		}
    332   1.8  christos 		wordv[1][strlen(wordv[1])] = ':';
    333   1.1       cgd 	}
    334   1.1       cgd 	return (C_UNKNOWN);
    335   1.1       cgd }
    336   1.1       cgd 
    337   1.5     lukem Errorclass
    338   1.9       wiz lint1(void)
    339   1.1       cgd {
    340  1.11  christos 	char	*line1 = NULL, *line2 = NULL;
    341  1.11  christos 	char	*file1 = NULL, *file2 = NULL;
    342   1.1       cgd 	char	**nwordv1, **nwordv2;
    343   1.1       cgd 
    344   1.1       cgd 	/*
    345   1.1       cgd 	 *	Now, attempt a match for the various errors that lint
    346   1.1       cgd 	 *	can complain about.
    347   1.1       cgd 	 *
    348   1.1       cgd 	 *	Look first for type 1 lint errors
    349   1.1       cgd 	 */
    350   1.1       cgd 	if (wordc > 1 && strcmp(wordv[wordc-1], "::") == 0){
    351   1.1       cgd 	 /*
    352   1.1       cgd   	  * %.7s, arg. %d used inconsistently %s(%d) :: %s(%d)
    353   1.1       cgd   	  * %.7s value used inconsistently %s(%d) :: %s(%d)
    354   1.1       cgd   	  * %.7s multiply declared %s(%d) :: %s(%d)
    355   1.1       cgd   	  * %.7s value declared inconsistently %s(%d) :: %s(%d)
    356   1.1       cgd   	  * %.7s function value type must be declared before use %s(%d) :: %s(%d)
    357   1.1       cgd 	  */
    358   1.1       cgd 		language = INLINT;
    359   1.1       cgd 		if (wordc > 2
    360   1.1       cgd 		     && (persperdexplode(wordv[wordc], &line2, &file2))
    361   1.1       cgd 		     && (persperdexplode(wordv[wordc-2], &line1, &file1)) ){
    362   1.1       cgd 			nwordv1 = wordvsplice(2, wordc, wordv+1);
    363   1.1       cgd 			nwordv2 = wordvsplice(2, wordc, wordv+1);
    364   1.1       cgd 			nwordv1[0] = file1; nwordv1[1] = line1;
    365   1.1       cgd 			erroradd(wordc+2, nwordv1, C_TRUE, C_DUPL); /* takes 0 based*/
    366   1.1       cgd 			nwordv2[0] = file2; nwordv2[1] = line2;
    367   1.1       cgd 			wordc = wordc + 2;
    368   1.1       cgd 			wordv = nwordv2 - 1;	/* 1 based */
    369   1.1       cgd 			return(C_TRUE);
    370   1.1       cgd 		}
    371   1.1       cgd 	}
    372  1.11  christos 	if (file2)
    373  1.11  christos 		free(file2);
    374  1.11  christos 	if (file1)
    375  1.11  christos 		free(file1);
    376  1.11  christos 	if (line2)
    377  1.11  christos 		free(line2);
    378  1.11  christos 	if (line1)
    379  1.11  christos 		free(line1);
    380   1.1       cgd 	return(C_UNKNOWN);
    381   1.1       cgd } /* end of lint 1*/
    382   1.1       cgd 
    383   1.5     lukem Errorclass
    384   1.9       wiz lint2(void)
    385   1.1       cgd {
    386   1.1       cgd 	char	*file;
    387   1.1       cgd 	char	*line;
    388   1.1       cgd 	char	**nwordv;
    389   1.1       cgd 	/*
    390   1.1       cgd 	 *	Look for type 2 lint errors
    391   1.1       cgd 	 *
    392   1.1       cgd 	 *	%.7s used( %s(%d) ), but not defined
    393   1.1       cgd 	 *	%.7s defined( %s(%d) ), but never used
    394   1.1       cgd 	 *	%.7s declared( %s(%d) ), but never used or defined
    395   1.1       cgd 	 *
    396   1.1       cgd 	 *	bufp defined( "./metric.h"(10) ), but never used
    397   1.1       cgd 	 */
    398   1.8  christos 	if (wordc < 5)
    399   1.8  christos 		return (C_UNKNOWN);
    400   1.8  christos 
    401   1.1       cgd 	if (   (lastchar(wordv[2]) == '(' /* ')' */ )
    402   1.1       cgd 	    && (strcmp(wordv[4], "),") == 0) ){
    403   1.1       cgd 		language = INLINT;
    404   1.1       cgd 		if (persperdexplode(wordv[3], &line, &file)){
    405   1.1       cgd 			nwordv = wordvsplice(2, wordc, wordv+1);
    406   1.1       cgd 			nwordv[0] = file; nwordv[1] = line;
    407   1.1       cgd 			wordc = wordc + 2;
    408   1.1       cgd 			wordv = nwordv - 1;	/* 1 based */
    409   1.1       cgd 			return(C_TRUE);
    410   1.1       cgd 		}
    411   1.1       cgd 	}
    412   1.1       cgd 	return(C_UNKNOWN);
    413   1.1       cgd } /* end of lint 2*/
    414   1.1       cgd 
    415   1.1       cgd char	*Lint31[4] = {"returns", "value", "which", "is"};
    416   1.1       cgd char	*Lint32[6] = {"value", "is", "used,", "but", "none", "returned"};
    417   1.5     lukem 
    418   1.5     lukem Errorclass
    419   1.9       wiz lint3(void)
    420   1.1       cgd {
    421   1.8  christos 	if (wordc < 3)
    422   1.8  christos 		return(C_UNKNOWN);
    423   1.1       cgd 	if (   (wordvcmp(wordv+2, 4, Lint31) == 0)
    424   1.1       cgd 	    || (wordvcmp(wordv+2, 6, Lint32) == 0) ){
    425   1.1       cgd 		language = INLINT;
    426   1.1       cgd 		return(C_NONSPEC);
    427   1.1       cgd 	}
    428   1.1       cgd 	return(C_UNKNOWN);
    429   1.1       cgd }
    430   1.1       cgd 
    431   1.1       cgd /*
    432   1.1       cgd  *	Special word vectors for use by F77 recognition
    433   1.1       cgd  */
    434   1.1       cgd char	*F77_fatal[3] = {"Compiler", "error", "line"};
    435   1.1       cgd char	*F77_error[3] = {"Error", "on", "line"};
    436   1.1       cgd char	*F77_warning[3] = {"Warning", "on", "line"};
    437   1.1       cgd char    *F77_no_ass[3] = {"Error.","No","assembly."};
    438   1.5     lukem 
    439   1.5     lukem Errorclass
    440   1.9       wiz f77(void)
    441   1.1       cgd {
    442   1.1       cgd 	char	**nwordv;
    443   1.1       cgd 	/*
    444   1.1       cgd 	 *	look for f77 errors:
    445   1.1       cgd 	 *	Error messages from /usr/src/cmd/f77/error.c, with
    446   1.1       cgd 	 *	these printf formats:
    447   1.1       cgd 	 *
    448   1.1       cgd 	 *		Compiler error line %d of %s: %s
    449   1.1       cgd 	 *		Error on line %d of %s: %s
    450   1.1       cgd 	 *		Warning on line %d of %s: %s
    451   1.1       cgd 	 *		Error.  No assembly.
    452   1.1       cgd 	 */
    453   1.1       cgd 	if (wordc == 3 && wordvcmp(wordv+1, 3, F77_no_ass) == 0) {
    454   1.1       cgd 		wordc = 0;
    455   1.1       cgd 		return(C_SYNC);
    456   1.1       cgd 	}
    457   1.1       cgd 	if (wordc < 6)
    458   1.1       cgd 		return(C_UNKNOWN);
    459   1.1       cgd 	if (	(lastchar(wordv[6]) == ':')
    460   1.1       cgd 	    &&(
    461   1.1       cgd 	       (wordvcmp(wordv+1, 3, F77_fatal) == 0)
    462   1.1       cgd 	    || (wordvcmp(wordv+1, 3, F77_error) == 0)
    463   1.1       cgd 	    || (wordvcmp(wordv+1, 3, F77_warning) == 0) )
    464   1.1       cgd 	){
    465   1.1       cgd 		language = INF77;
    466   1.1       cgd 		nwordv = wordvsplice(2, wordc, wordv+1);
    467   1.1       cgd 		nwordv[0] = wordv[6];
    468   1.1       cgd 		clob_last(nwordv[0],'\0');
    469   1.1       cgd 		nwordv[1] = wordv[4];
    470   1.1       cgd 		wordc += 2;
    471   1.1       cgd 		wordv = nwordv - 1;	/* 1 based */
    472   1.1       cgd 		return(C_TRUE);
    473   1.1       cgd 	}
    474   1.1       cgd 	return(C_UNKNOWN);
    475   1.1       cgd } /* end of f77 */
    476   1.1       cgd 
    477   1.1       cgd char	*Make_Croak[3] = {"***", "Error", "code"};
    478   1.1       cgd char	*Make_NotRemade[5] = {"not", "remade", "because", "of", "errors"};
    479   1.5     lukem 
    480   1.5     lukem Errorclass
    481   1.9       wiz make(void)
    482   1.1       cgd {
    483   1.1       cgd 	if (wordvcmp(wordv+1, 3, Make_Croak) == 0){
    484   1.1       cgd 		language = INMAKE;
    485   1.1       cgd 		return(C_SYNC);
    486   1.1       cgd 	}
    487   1.1       cgd 	if  (wordvcmp(wordv+2, 5, Make_NotRemade) == 0){
    488   1.1       cgd 		language = INMAKE;
    489   1.1       cgd 		return(C_SYNC);
    490   1.1       cgd 	}
    491   1.1       cgd 	return(C_UNKNOWN);
    492   1.1       cgd }
    493   1.5     lukem 
    494   1.5     lukem Errorclass
    495   1.9       wiz ri(void)
    496   1.1       cgd {
    497   1.1       cgd /*
    498   1.1       cgd  *	Match an error message produced by ri; here is the
    499   1.1       cgd  *	procedure yanked from the distributed version of ri
    500   1.1       cgd  *	April 24, 1980.
    501   1.1       cgd  *
    502   1.1       cgd  *	serror(str, x1, x2, x3)
    503   1.1       cgd  *		char str[];
    504   1.1       cgd  *		char *x1, *x2, *x3;
    505   1.1       cgd  *	{
    506   1.1       cgd  *		extern int yylineno;
    507   1.1       cgd  *
    508   1.1       cgd  *		putc('"', stdout);
    509   1.1       cgd  *		fputs(srcfile, stdout);
    510   1.1       cgd  *		putc('"', stdout);
    511   1.1       cgd  *		fprintf(stdout, " %d: ", yylineno);
    512   1.1       cgd  *		fprintf(stdout, str, x1, x2, x3);
    513   1.1       cgd  *		fprintf(stdout, "\n");
    514   1.1       cgd  *		synerrs++;
    515   1.1       cgd  *	}
    516   1.1       cgd  */
    517   1.8  christos 	if (wordc < 3)
    518   1.8  christos 		return(C_UNKNOWN);
    519   1.1       cgd 	if (  (firstchar(wordv[1]) == '"')
    520   1.1       cgd 	    &&(lastchar(wordv[1]) == '"')
    521   1.1       cgd 	    &&(lastchar(wordv[2]) == ':')
    522   1.7  christos 	    &&(isdigit((unsigned char)firstchar(wordv[2]))) ){
    523   1.1       cgd 		clob_last(wordv[1], '\0');	/* drop the last " */
    524   1.1       cgd 		wordv[1]++;	/* skip over the first " */
    525   1.1       cgd 		clob_last(wordv[2], '\0');
    526   1.1       cgd 		language = INRI;
    527   1.1       cgd 		return(C_TRUE);
    528   1.1       cgd 	}
    529   1.1       cgd 	return(C_UNKNOWN);
    530   1.1       cgd }
    531   1.1       cgd 
    532   1.5     lukem Errorclass
    533   1.9       wiz catchall(void)
    534   1.1       cgd {
    535   1.1       cgd 	/*
    536   1.1       cgd 	 *	Catches random things.
    537   1.1       cgd 	 */
    538   1.1       cgd 	language = INUNKNOWN;
    539   1.1       cgd 	return(C_NONSPEC);
    540   1.1       cgd } /* end of catch all*/
    541   1.1       cgd 
    542   1.5     lukem Errorclass
    543   1.9       wiz troff(void)
    544   1.1       cgd {
    545   1.1       cgd 	/*
    546   1.1       cgd 	 *	troff source error message, from eqn, bib, tbl...
    547   1.1       cgd 	 *	Just like pcc ccom, except uses `'
    548   1.1       cgd 	 */
    549   1.8  christos 	if (wordc < 4)
    550   1.8  christos 		return(C_UNKNOWN);
    551   1.8  christos 
    552   1.1       cgd 	if (   (firstchar(wordv[1]) == '`')
    553   1.1       cgd 	    && (lastchar(wordv[1]) == ',')
    554   1.1       cgd 	    && (next_lastchar(wordv[1]) == '\'')
    555   1.1       cgd 	    && (strcmp(wordv[2],"line") == 0)
    556   1.7  christos 	    && (isdigit((unsigned char)firstchar(wordv[3])))
    557   1.1       cgd 	    && (lastchar(wordv[3]) == ':') ){
    558   1.1       cgd 		clob_last(wordv[1], '\0');	/* drop last , */
    559   1.1       cgd 		clob_last(wordv[1], '\0');	/* drop last " */
    560   1.1       cgd 		wordv[1]++;			/* drop first " */
    561   1.1       cgd 		clob_last(wordv[3], '\0');	/* drop : on line number */
    562   1.1       cgd 		wordv[2] = wordv[1];	/* overwrite "line" */
    563   1.1       cgd 		wordv++;		/*compensate*/
    564   1.1       cgd 		currentfilename = wordv[1];
    565   1.1       cgd 		language = INTROFF;
    566   1.1       cgd 		return(C_TRUE);
    567   1.1       cgd 	}
    568   1.1       cgd 	return(C_UNKNOWN);
    569   1.1       cgd }
    570   1.5     lukem 
    571   1.5     lukem Errorclass
    572   1.9       wiz mod2(void)
    573   1.1       cgd {
    574   1.1       cgd 	/*
    575   1.1       cgd 	 *	for decwrl modula2 compiler (powell)
    576   1.1       cgd 	 */
    577   1.8  christos 	if (wordc < 5)
    578   1.8  christos 		return(C_UNKNOWN);
    579   1.1       cgd 	if (   (  (strcmp(wordv[1], "!!!") == 0)	/* early version */
    580   1.1       cgd 	        ||(strcmp(wordv[1], "File") == 0))	/* later version */
    581   1.1       cgd 	    && (lastchar(wordv[2]) == ',')	/* file name */
    582   1.1       cgd 	    && (strcmp(wordv[3], "line") == 0)
    583   1.7  christos 	    && (isdigit((unsigned char)firstchar(wordv[4])))	/* line number */
    584   1.1       cgd 	    && (lastchar(wordv[4]) == ':')	/* line number */
    585   1.1       cgd 	){
    586   1.1       cgd 		clob_last(wordv[2], '\0');	/* drop last , on file name */
    587   1.1       cgd 		clob_last(wordv[4], '\0');	/* drop last : on line number */
    588   1.1       cgd 		wordv[3] = wordv[2];		/* file name on top of "line" */
    589   1.1       cgd 		wordv += 2;
    590   1.1       cgd 		wordc -= 2;
    591   1.1       cgd 		currentfilename = wordv[1];
    592   1.1       cgd 		language = INMOD2;
    593   1.1       cgd 		return(C_TRUE);
    594   1.1       cgd 	}
    595   1.1       cgd 	return(C_UNKNOWN);
    596   1.1       cgd }
    597