Jochen Pohl's lint(1) from NetBSD. Yet another import.

This is just a vendor import by now.  I'll wait until i'll get the
imported files back via CTM before applying the FreeBSD patches.
Don't use it yet.

Submitted by:	Jochen Pohl <jpo.drs@sni.de>
Obtained from:	(NetBSD -- this version is directly from Jochen)
This commit is contained in:
Joerg Wunsch 1995-11-05 15:56:42 +00:00
commit 96a322df43
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/cvs2svn/branches/JPO/; revision=12099
svn path=/cvs2svn/tags/v1_3/; revision=12101; tag=vendor/NetBSD/xlint/1.3
37 changed files with 20618 additions and 0 deletions

5
usr.bin/xlint/Makefile Normal file
View File

@ -0,0 +1,5 @@
# $NetBSD: Makefile,v 1.2 1995/07/03 21:23:45 cgd Exp $
SUBDIR= lint1 lint2 xlint llib
.include <bsd.subdir.mk>

View File

@ -0,0 +1,19 @@
# $NetBSD: Makefile,v 1.3 1995/07/04 01:53:05 cgd Exp $
PROG= lint1
SRCS= cgram.c scan.c mem1.c mem.c err.c main1.c decl.c tree.c func.c \
init.c emit.c emit1.c
NOMAN=
LDADD+= -ll
DPADD+= ${LIBL}
YFLAGS= -d
CFLAGS+=-I.
LINTFLAGS=-aehpz
CLEANFILES+=y.tab.h cgram.c scan.c
BINDIR= /usr/libexec
# XXX: -O causes the gcc to die on the i386, when compiling tree.o
CFLAGS+= -DXXX_BROKEN_GCC
.include <bsd.prog.mk>

1675
usr.bin/xlint/lint1/cgram.y Normal file

File diff suppressed because it is too large Load Diff

3134
usr.bin/xlint/lint1/decl.c Normal file

File diff suppressed because it is too large Load Diff

241
usr.bin/xlint/lint1/emit.c Normal file
View File

@ -0,0 +1,241 @@
/* $NetBSD: emit.c,v 1.2 1995/07/03 21:24:00 cgd Exp $ */
/*
* Copyright (c) 1994, 1995 Jochen Pohl
* All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Jochen Pohl for
* The NetBSD Project.
* 4. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef lint
static char rcsid[] = "$NetBSD: emit.c,v 1.2 1995/07/03 21:24:00 cgd Exp $";
#endif
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <err.h>
#include "lint.h"
/* name and handle of output file */
static const char *loname;
static FILE *lout;
/* output buffer data */
ob_t ob;
static void outxbuf __P((void));
/*
* initialize output
*/
void
outopen(name)
const char *name;
{
loname = name;
/* Ausgabedatei oeffnen */
if ((lout = fopen(name, "w")) == NULL)
err(1, "cannot open '%s'", name);
/* Ausgabepuffer anlegen */
ob.o_len = 1024;
ob.o_end = (ob.o_buf = ob.o_nxt = xmalloc(ob.o_len)) + ob.o_len;
}
/*
* flush output buffer and close file
*/
void
outclose()
{
outclr();
if (fclose(lout) == EOF)
err(1, "cannot close '%s'", loname);
}
/*
* resize output buffer
*/
static void
outxbuf()
{
ptrdiff_t coffs;
coffs = ob.o_nxt - ob.o_buf;
ob.o_len *= 2;
ob.o_end = (ob.o_buf = xrealloc(ob.o_buf, ob.o_len)) + ob.o_len;
ob.o_nxt = ob.o_buf + coffs;
}
/*
* reset output buffer
* if it is not empty, it is flushed
*/
void
outclr()
{
size_t sz;
if (ob.o_buf != ob.o_nxt) {
outchar('\n');
sz = ob.o_nxt - ob.o_buf;
if (sz > ob.o_len)
errx(1, "internal error: outclr() 1");
if (fwrite(ob.o_buf, sz, 1, lout) != 1)
err(1, "cannot write to %s", loname);
ob.o_nxt = ob.o_buf;
}
}
/*
* write a character to the output buffer
*/
void
outchar(c)
int c;
{
if (ob.o_nxt == ob.o_end)
outxbuf();
*ob.o_nxt++ = (char)c;
}
/*
* write a character to the output buffer, qouted if necessary
*/
void
outqchar(c)
int c;
{
if (isprint(c) && c != '\\' && c != '"' && c != '\'') {
outchar(c);
} else {
outchar('\\');
switch (c) {
case '\\':
outchar('\\');
break;
case '"':
outchar('"');
break;
case '\'':
outchar('\'');
break;
case '\b':
outchar('b');
break;
case '\t':
outchar('t');
break;
case '\n':
outchar('n');
break;
case '\f':
outchar('f');
break;
case '\r':
outchar('r');
break;
#ifdef __STDC__
case '\v':
#else
case '\013':
#endif
outchar('v');
break;
#ifdef __STDC__
case '\a':
#else
case '\007':
#endif
outchar('a');
break;
default:
outchar((((u_int)c >> 6) & 07) + '0');
outchar((((u_int)c >> 3) & 07) + '0');
outchar((c & 07) + '0');
break;
}
}
}
/*
* write a strint to the output buffer
* the string must not contain any characters which
* should be quoted
*/
void
outstrg(s)
const char *s;
{
while (*s != '\0') {
if (ob.o_nxt == ob.o_end)
outxbuf();
*ob.o_nxt++ = *s++;
}
}
/*
* write an integer value to toe output buffer
*/
void
outint(i)
int i;
{
if ((ob.o_end - ob.o_nxt) < 3 * sizeof (int))
outxbuf();
ob.o_nxt += sprintf(ob.o_nxt, "%d", i);
}
/*
* write the name of a symbol to the output buffer
* the name is preceeded by its length
*/
void
outname(name)
const char *name;
{
if (name == NULL)
errx(1, "internal error: outname() 1");
outint((int)strlen(name));
outstrg(name);
}
/*
* write the name of the .c source
*/
void
outsrc(name)
const char *name;
{
outclr();
outchar('S');
outstrg(name);
}

587
usr.bin/xlint/lint1/emit1.c Normal file
View File

@ -0,0 +1,587 @@
/* $NetBSD: emit1.c,v 1.4 1995/10/02 17:21:28 jpo Exp $ */
/*
* Copyright (c) 1994, 1995 Jochen Pohl
* All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Jochen Pohl for
* The NetBSD Project.
* 4. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef lint
static char rcsid[] = "$NetBSD: emit1.c,v 1.4 1995/10/02 17:21:28 jpo Exp $";
#endif
#include <ctype.h>
#include "lint1.h"
static void outtt __P((sym_t *, sym_t *));
static void outfstrg __P((strg_t *));
/*
* Write type into the output buffer.
* The type is written as a sequence of substrings, each of which describes a
* node of type type_t
* a node is coded as follows:
* char C
* signed char s C
* unsigned char u C
* short S
* unsigned short u S
* int I
* unsigned int u I
* long L
* unsigned long u L
* long long Q
* unsigned long long u Q
* float s D
* double D
* long double l D
* void V
* * P
* [n] A n
* () F
* (void) F 0
* (n arguments) F n arg1 arg2 ... argn
* (n arguments, ...) F n arg1 arg2 ... argn-1 E
* (a, b, c, ...) f n arg1 arg2 ...
* enum tag e T tag_or_typename
* struct tag s T tag_or_typename
* union tag u T tag_or_typename
*
* tag_or_typename 0 no tag or type name
* 1 n tag Tag
* 2 n typename only type name
*
* spaces are only for better readability
* additionaly it is possible to prepend the characters 'c' (for const)
* and 'v' (for volatile)
*/
void
outtype(tp)
type_t *tp;
{
int t, s, na;
sym_t *arg;
tspec_t ts;
while (tp != NULL) {
if ((ts = tp->t_tspec) == INT && tp->t_isenum)
ts = ENUM;
switch (ts) {
case CHAR: t = 'C'; s = '\0'; break;
case SCHAR: t = 'C'; s = 's'; break;
case UCHAR: t = 'C'; s = 'u'; break;
case SHORT: t = 'S'; s = '\0'; break;
case USHORT: t = 'S'; s = 'u'; break;
case INT: t = 'I'; s = '\0'; break;
case UINT: t = 'I'; s = 'u'; break;
case LONG: t = 'L'; s = '\0'; break;
case ULONG: t = 'L'; s = 'u'; break;
case QUAD: t = 'Q'; s = '\0'; break;
case UQUAD: t = 'Q'; s = 'u'; break;
case FLOAT: t = 'D'; s = 's'; break;
case DOUBLE: t = 'D'; s = '\0'; break;
case LDOUBLE: t = 'D'; s = 'l'; break;
case VOID: t = 'V'; s = '\0'; break;
case PTR: t = 'P'; s = '\0'; break;
case ARRAY: t = 'A'; s = '\0'; break;
case FUNC: t = 'F'; s = '\0'; break;
case ENUM: t = 'T'; s = 'e'; break;
case STRUCT: t = 'T'; s = 's'; break;
case UNION: t = 'T'; s = 'u'; break;
default:
lerror("outtyp() 1");
}
if (tp->t_const)
outchar('c');
if (tp->t_volatile)
outchar('v');
if (s != '\0')
outchar(s);
outchar(t);
if (ts == ARRAY) {
outint(tp->t_dim);
} else if (ts == ENUM) {
outtt(tp->t_enum->etag, tp->t_enum->etdef);
} else if (ts == STRUCT || ts == UNION) {
outtt(tp->t_str->stag, tp->t_str->stdef);
} else if (ts == FUNC && tp->t_proto) {
na = 0;
for (arg = tp->t_args; arg != NULL; arg = arg->s_nxt)
na++;
if (tp->t_vararg)
na++;
outint(na);
for (arg = tp->t_args; arg != NULL; arg = arg->s_nxt)
outtype(arg->s_type);
if (tp->t_vararg)
outchar('E');
}
tp = tp->t_subt;
}
}
/*
* type to string
* used for debugging output
*
* it uses its own output buffer for conversion
*/
const char *
ttos(tp)
type_t *tp;
{
static ob_t tob;
ob_t tmp;
if (tob.o_buf == NULL) {
tob.o_len = 64;
tob.o_buf = tob.o_nxt = xmalloc(tob.o_len);
tob.o_end = tob.o_buf + tob.o_len;
}
tmp = ob;
ob = tob;
ob.o_nxt = ob.o_buf;
outtype(tp);
outchar('\0');
tob = ob;
ob = tmp;
return (tob.o_buf);
}
/*
* write the name of a tag or typename
*
* if the tag is named, the name of the
* tag is written, otherwise, if a typename exists which
* refers to this tag, this typename is written
*/
static void
outtt(tag, tdef)
sym_t *tag, *tdef;
{
if (tag->s_name != unnamed) {
outint(1);
outname(tag->s_name);
} else if (tdef != NULL) {
outint(2);
outname(tdef->s_name);
} else {
outint(0);
}
}
/*
* write information about an global declared/defined symbol
* with storage class extern
*
* informations about function definitions are written in outfdef(),
* not here
*/
void
outsym(sym, sc, def)
sym_t *sym;
scl_t sc;
def_t def;
{
/*
* Static function declarations must also be written to the output
* file. Compatibility of function declarations (for both static
* and extern functions) must be checked in lint2. Lint1 can't do
* this, especially not, if functions are declared at block level
* before their first declaration at level 0.
*/
if (sc != EXTERN && !(sc == STATIC && sym->s_type->t_tspec == FUNC))
return;
/* reset buffer */
outclr();
/*
* line number of .c source, 'd' for declaration, Id of current
* source (.c or .h), and line in current source.
*/
outint(csrc_pos.p_line);
outchar('d');
outint(getfnid(sym->s_dpos.p_file));
outchar('.');
outint(sym->s_dpos.p_line);
/* flags */
switch (def) {
case DEF:
/* defined */
outchar('d');
break;
case TDEF:
/* tentative defined */
outchar('t');
break;
case DECL:
/* declared */
outchar('e');
break;
default:
lerror("outsym() 2");
}
if (llibflg && def != DECL) {
/*
* mark it as used so we get no warnings from lint2 about
* unused symbols in libraries.
*/
outchar('u');
}
if (sc == STATIC)
outchar('s');
/* name of the symbol */
outname(sym->s_name);
/* type of the symbol */
outtype(sym->s_type);
}
/*
* write information about function definition
*
* this is also done for static functions so we are able to check if
* they are called with proper argument types
*/
void
outfdef(fsym, posp, rval, osdef, args)
sym_t *fsym, *args;
pos_t *posp;
int rval, osdef;
{
int narg;
sym_t *arg;
/* reset the buffer */
outclr();
/*
* line number of .c source, 'd' for declaration, Id of current
* source (.c or .h), and line in current source
*
* we are already at the end of the function. If we are in the
* .c source, posp->p_line is correct, otherwise csrc_pos.p_line
* (for functions defined in header files).
*/
if (posp->p_file == csrc_pos.p_file) {
outint(posp->p_line);
} else {
outint(csrc_pos.p_line);
}
outchar('d');
outint(getfnid(posp->p_file));
outchar('.');
outint(posp->p_line);
/* flags */
/* both SCANFLIKE and PRINTFLIKE imply VARARGS */
if (prflstrg != -1) {
nvararg = prflstrg;
} else if (scflstrg != -1) {
nvararg = scflstrg;
}
if (nvararg != -1) {
outchar('v');
outint(nvararg);
}
if (scflstrg != -1) {
outchar('S');
outint(scflstrg);
}
if (prflstrg != -1) {
outchar('P');
outint(prflstrg);
}
nvararg = prflstrg = scflstrg = -1;
outchar('d');
if (rval)
/* has return value */
outchar('r');
if (llibflg)
/*
* mark it as used so lint2 does not complain about
* unused symbols in libraries
*/
outchar('u');
if (osdef)
/* old style function definition */
outchar('o');
if (fsym->s_scl == STATIC)
outchar('s');
/* name of function */
outname(fsym->s_name);
/* argument types and return value */
if (osdef) {
narg = 0;
for (arg = args; arg != NULL; arg = arg->s_nxt)
narg++;
outchar('f');
outint(narg);
for (arg = args; arg != NULL; arg = arg->s_nxt)
outtype(arg->s_type);
outtype(fsym->s_type->t_subt);
} else {
outtype(fsym->s_type);
}
}
/*
* write out all information necessary for lint2 to check function
* calls
*
* rvused is set if the return value is used (asigned to a variable)
* rvdisc is set if the return value is not used and not ignored
* (casted to void)
*/
void
outcall(tn, rvused, rvdisc)
tnode_t *tn;
int rvused, rvdisc;
{
tnode_t *args, *arg;
int narg, n, i;
quad_t q;
tspec_t t;
/* reset buffer */
outclr();
/*
* line number of .c source, 'c' for function call, Id of current
* source (.c or .h), and line in current source
*/
outint(csrc_pos.p_line);
outchar('c');
outint(getfnid(curr_pos.p_file));
outchar('.');
outint(curr_pos.p_line);
/*
* flags; 'u' and 'i' must be last to make sure a letter
* is between the numeric argument of a flag and the name of
* the function
*/
narg = 0;
args = tn->tn_right;
for (arg = args; arg != NULL; arg = arg->tn_right)
narg++;
/* informations about arguments */
for (n = 1; n <= narg; n++) {
/* the last argument is the top one in the tree */
for (i = narg, arg = args; i > n; i--, arg = arg->tn_right) ;
arg = arg->tn_left;
if (arg->tn_op == CON) {
if (isityp(t = arg->tn_type->t_tspec)) {
/*
* XXX it would probably be better to
* explizitly test the sign
*/
if ((q = arg->tn_val->v_quad) == 0) {
/* zero constant */
outchar('z');
} else if (msb(q, t, 0) == 0) {
/* positive if casted to signed */
outchar('p');
} else {
/* negative if casted to signed */
outchar('n');
}
outint(n);
}
} else if (arg->tn_op == AMPER &&
arg->tn_left->tn_op == STRING &&
arg->tn_left->tn_strg->st_tspec == CHAR) {
/* constant string, write all format specifiers */
outchar('s');
outint(n);
outfstrg(arg->tn_left->tn_strg);
}
}
/* return value discarded/used/ignored */
outchar(rvdisc ? 'd' : (rvused ? 'u' : 'i'));
/* name of the called function */
outname(tn->tn_left->tn_left->tn_sym->s_name);
/* types of arguments */
outchar('f');
outint(narg);
for (n = 1; n <= narg; n++) {
/* the last argument is the top one in the tree */
for (i = narg, arg = args; i > n; i--, arg = arg->tn_right) ;
outtype(arg->tn_left->tn_type);
}
/* expected type of return value */
outtype(tn->tn_type);
}
/*
* extracts potential format specifiers for printf() and scanf() and
* writes them, enclosed in "" and qouted if necessary, to the output buffer
*/
static void
outfstrg(strg)
strg_t *strg;
{
int c, oc, first;
u_char *cp;
if (strg->st_tspec != CHAR)
lerror("outfstrg() 1");
cp = strg->st_cp;
outchar('"');
c = *cp++;
while (c != '\0') {
if (c != '%') {
c = *cp++;
continue;
}
outqchar('%');
c = *cp++;
/* flags for printf and scanf and *-fieldwidth for printf */
while (c != '\0' && (c == '-' || c == '+' || c == ' ' ||
c == '#' || c == '0' || c == '*')) {
outqchar(c);
c = *cp++;
}
/* numeric field width */
while (c != '\0' && isdigit(c)) {
outqchar(c);
c = *cp++;
}
/* precision for printf */
if (c == '.') {
outqchar(c);
if ((c = *cp++) == '*') {
outqchar(c);
c = *cp++;
} else {
while (c != '\0' && isdigit(c)) {
outqchar(c);
c = *cp++;
}
}
}
/* h, l, L and q flags fpr printf and scanf */
if (c == 'h' || c == 'l' || c == 'L' || c == 'q') {
outqchar(c);
c = *cp++;
}
/*
* The last character. It is always written so we can detect
* invalid format specifiers.
*/
if (c != '\0') {
outqchar(c);
oc = c;
c = *cp++;
/*
* handle [ for scanf. [-] means that a minus sign
* was found at an undefined position.
*/
if (oc == '[') {
if (c == '^')
c = *cp++;
if (c == ']')
c = *cp++;
first = 1;
while (c != '\0' && c != ']') {
if (c == '-') {
if (!first && *cp != ']')
outqchar(c);
}
first = 0;
c = *cp++;
}
if (c == ']') {
outqchar(c);
c = *cp++;
}
}
}
}
outchar('"');
}
/*
* writes a record if sym was used
*/
void
outusg(sym)
sym_t *sym;
{
/* reset buffer */
outclr();
/*
* line number of .c source, 'u' for used, Id of current
* source (.c or .h), and line in current source
*/
outint(csrc_pos.p_line);
outchar('u');
outint(getfnid(curr_pos.p_file));
outchar('.');
outint(curr_pos.p_line);
/* necessary to delimit both numbers */
outchar('x');
/* Den Namen des Symbols ausgeben */
outname(sym->s_name);
}

543
usr.bin/xlint/lint1/err.c Normal file
View File

@ -0,0 +1,543 @@
/* $NetBSD: err.c,v 1.8 1995/10/02 17:37:00 jpo Exp $ */
/*
* Copyright (c) 1994, 1995 Jochen Pohl
* All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Jochen Pohl for
* The NetBSD Project.
* 4. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef lint
static char rcsid[] = "$NetBSD: err.c,v 1.8 1995/10/02 17:37:00 jpo Exp $";
#endif
/* number of errors found */
int nerr;
/* number of syntax errors */
int sytxerr;
#include <stdlib.h>
#ifdef __STDC__
#include <stdarg.h>
#else
#include <varargs.h>
#endif
#include "lint1.h"
static const char *basename __P((const char *));
static void verror __P((int, va_list));
static void vwarning __P((int, va_list));
const char *msgs[] = {
"syntax error: empty declaration", /* 0 */
"old style declaration; add int", /* 1 */
"empty declaration", /* 2 */
"%s declared in argument declaration list", /* 3 */
"illegal type combination", /* 4 */
"modifying typedef with '%s'; only qualifiers allowed", /* 5 */
"use 'double' instead of 'long float'", /* 6 */
"only one storage class allowed", /* 7 */
"illegal storage class", /* 8 */
"only register valid as formal parameter storage class", /* 9 */
"duplicate '%s'", /* 10 */
"bit-field initializer out of range", /* 11 */
"compiler takes size of function", /* 12 */
"incomplete enum type: %s", /* 13 */
"compiler takes alignment of function", /* 14 */
"function returns illegal type", /* 15 */
"array of function is illegal", /* 16 */
"null dimension", /* 17 */
"illegal use of 'void'", /* 18 */
"void type for %s", /* 19 */
"zero or negative array dimension", /* 20 */
"redeclaration of formal parameter %s", /* 21 */
"incomplete or misplaced function definition", /* 22 */
"undefined label %s", /* 23 */
"cannot initialize function: %s", /* 24 */
"cannot initialize typedef: %s", /* 25 */
"cannot initialize extern declaration: %s", /* 26 */
"redeclaration of %s", /* 27 */
"redefinition of %s", /* 28 */
"previously declared extern, becomes static: %s", /* 29 */
"redeclaration of %s; ANSI C requires static", /* 30 */
"incomplete structure or union %s: %s", /* 31 */
"argument type defaults to 'int': %s", /* 32 */
"duplicate member name: %s", /* 33 */
"nonportable bit-field type", /* 34 */
"illegal bit-field type", /* 35 */
"illegal bit-field size", /* 36 */
"zero size bit-field", /* 37 */
"function illegal in structure or union", /* 38 */
"illegal zero sized structure member: %s", /* 39 */
"unknown size: %s", /* 40 */
"illegal use of bit-field", /* 41 */
"forward reference to enum type", /* 42 */
"redefinition hides earlier one: %s", /* 43 */
"declaration introduces new type in ANSI C: %s %s", /* 44 */
"base type is really '%s %s'", /* 45 */
"(%s) tag redeclared", /* 46 */
"zero sized %s", /* 47 */
"overflow in enumeration values: %s", /* 48 */
"struct or union member must be named", /* 49 */
"a function is declared as an argument: %s", /* 50 */
"parameter mismatch: %d declared, %d defined", /* 51 */
"cannot initialize parameter: %s", /* 52 */
"declared argument %s is missing", /* 53 */
"trailing ',' prohibited in enum declaration", /* 54 */
"integral constant expression expected", /* 55 */
"integral constant too large", /* 56 */
"enumeration constant hides parameter: %s", /* 57 */
"type does not match prototype: %s", /* 58 */
"formal parameter lacks name: param #%d", /* 59 */
"void must be sole parameter", /* 60 */
"void parameter cannot have name: %s", /* 61 */
"function prototype parameters must have types", /* 62 */
"prototype does not match old-style definition", /* 63 */
"()-less function definition", /* 64 */
"%s has no named members", /* 65 */
"syntax requires ';' after last struct/union member", /* 66 */
"cannot return incomplete type", /* 67 */
"typedef already qualified with '%s'", /* 68 */
"inappropriate qualifiers with 'void'", /* 69 */
"%soperand of '%s' is unsigned in ANSI C", /* 70 */
"too many characters in character constant", /* 71 */
"typedef declares no type name", /* 72 */
"empty character constant", /* 73 */
"no hex digits follow \\x", /* 74 */
"overflow in hex escape", /* 75 */
"character escape does not fit in character", /* 76 */
"bad octal digit %c", /* 77 */
"nonportable character escape", /* 78 */
"dubious escape \\%c", /* 79 */
"dubious escape \\%o", /* 80 */
"\\a undefined in traditional C", /* 81 */
"\\x undefined in traditional C", /* 82 */
"storage class after type is obsolescent", /* 83 */
"ANSI C requires formal parameter before '...'", /* 84 */
"dubious tag declaration: %s %s", /* 85 */
"automatic hides external declaration: %s", /* 86 */
"static hides external declaration: %s", /* 87 */
"typedef hides external declaration: %s", /* 88 */
"typedef redeclared: %s", /* 89 */
"inconsistent redeclaration of extern: %s", /* 90 */
"declaration hides parameter: %s", /* 91 */
"inconsistent redeclaration of static: %s", /* 92 */
"dubious static function at block level: %s", /* 93 */
"function has illegal storage class: %s", /* 94 */
"declaration hides earlier one: %s", /* 95 */
"cannot dereference non-pointer type", /* 96 */
"suffix U is illegal in traditional C", /* 97 */
"suffixes F and L are illegal in traditional C", /* 98 */
"%s undefined", /* 99 */
"unary + is illegal in traditional C", /* 100 */
"undefined struct/union member: %s", /* 101 */
"illegal member use: %s", /* 102 */
"left operand of '.' must be struct/union object", /* 103 */
"left operand of '->' must be pointer to struct/union", /* 104 */
"non-unique member requires struct/union %s", /* 105 */
"left operand of '->' must be pointer", /* 106 */
"operands of '%s' have incompatible types", /* 107 */
"operand of '%s' has incompatible type", /* 108 */
"void type illegal in expression", /* 109 */
"pointer to function is not allowed here", /* 110 */
"unacceptable operand of '%s'", /* 111 */
"cannot take address of bit-field", /* 112 */
"cannot take address of register %s", /* 113 */
"%soperand of '%s' must be lvalue", /* 114 */
"%soperand of '%s' must be modifiable lvalue", /* 115 */
"illegal pointer subtraction", /* 116 */
"bitwise operation on signed value possibly nonportable", /* 117 */
"semantics of '%s' change in ANSI C; use explicit cast", /* 118 */
"conversion of '%s' to '%s' is out of range", /* 119 */
"bitwise operation on signed value nonportable", /* 120 */
"negative shift", /* 121 */
"shift greater than size of object", /* 122 */
"illegal combination of pointer and integer, op %s", /* 123 */
"illegal pointer combination, op %s", /* 124 */
"ANSI C forbids ordered comparisons of pointers to functions",/* 125 */
"incompatible types in conditional", /* 126 */
"'&' before array or function: ignored", /* 127 */
"operands have incompatible pointer types, op %s", /* 128 */
"expression has null effect", /* 129 */
"enum type mismatch, op %s", /* 130 */
"conversion to '%s' may sign-extend incorrectly", /* 131 */
"conversion from '%s' may lose accuracy", /* 132 */
"conversion of pointer to '%s' loses bits", /* 133 */
"conversion of pointer to '%s' may lose bits", /* 134 */
"possible pointer alignment problem", /* 135 */
"cannot do pointer arithmetic on operand of unknown size", /* 136 */
"use of incomplete enum type, op %s", /* 137 */
"unknown operand size, op %s", /* 138 */
"division by 0", /* 139 */
"modulus by 0", /* 140 */
"integer overflow detected, op %s", /* 141 */
"floating point overflow detected, op %s", /* 142 */
"cannot take size of incomplete type", /* 143 */
"cannot take size of function", /* 144 */
"cannot take size of bit-field", /* 145 */
"cannot take size of void", /* 146 */
"invalid cast expression", /* 147 */
"improper cast of void expression", /* 148 */
"illegal function", /* 149 */
"argument mismatch: %d arg%s passed, %d expected", /* 150 */
"void expressions may not be arguments, arg #%d", /* 151 */
"argument cannot have unknown size, arg #%d", /* 152 */
"argument has incompatible pointer type, arg #%d", /* 153 */
"illegal combination of pointer and integer, arg #%d", /* 154 */
"argument is incompatible with prototype, arg #%d", /* 155 */
"enum type mismatch, arg #%d", /* 156 */
"ANSI C treats constant as unsigned", /* 157 */
"%s may be used before set", /* 158 */
"assignment in conditional context", /* 159 */
"operator '==' found where '=' was expected", /* 160 */
"constant in conditional context", /* 161 */
"comparision of %s with %s, op %s", /* 162 */
"a cast does not yield an lvalue", /* 163 */
"assignment of negative constant to unsigned type", /* 164 */
"constant truncated by assignment", /* 165 */
"precision lost in bit-field assignment", /* 166 */
"array subscript cannot be negative: %ld", /* 167 */
"array subscript cannot be > %d: %ld", /* 168 */
"precedence confusion possible: parenthesize!", /* 169 */
"first operand must have scalar type, op ? :", /* 170 */
"assignment type mismatch", /* 171 */
"too many struct/union initializers", /* 172 */
"too many array initializers", /* 173 */
"too many initializers", /* 174 */
"initialisation of an incomplete type", /* 175 */
"invalid initializer", /* 176 */
"non-constant initializer", /* 177 */
"initializer does not fit", /* 178 */
"cannot initialize struct/union with no named member", /* 179 */
"bit-field initializer does not fit", /* 180 */
"{}-enclosed initializer required", /* 181 */
"incompatible pointer types", /* 182 */
"illegal combination of pointer and integer", /* 183 */
"illegal pointer combination", /* 184 */
"initialisation type mismatch", /* 185 */
"bit-field initialisation is illegal in traditional C", /* 186 */
"non-null byte ignored in string initializer", /* 187 */
"no automatic aggregate initialization in traditional C", /* 188 */
"assignment of struct/union illegal in traditional C", /* 189 */
"empty array declaration: %s", /* 190 */
"%s set but not used in function %s", /* 191 */
"%s unused in function %s", /* 192 */
"statement not reached", /* 193 */
"label %s redefined", /* 194 */
"case not in switch", /* 195 */
"case label affected by conversion", /* 196 */
"non-constant case expression", /* 197 */
"non-integral case expression", /* 198 */
"duplicate case in switch: %ld", /* 199 */
"duplicate case in switch: %lu", /* 200 */
"default outside switch", /* 201 */
"duplicate default in switch", /* 202 */
"case label must be of type `int' in traditional C", /* 203 */
"controlling expressions must have scalar type", /* 204 */
"switch expression must have integral type", /* 205 */
"enumeration value(s) not handled in switch", /* 206 */
"loop not entered at top", /* 207 */
"break outside loop or switch", /* 208 */
"continue outside loop", /* 209 */
"enum type mismatch in initialisation", /* 210 */
"return value type mismatch", /* 211 */
"cannot return incomplete type", /* 212 */
"void function %s cannot return value", /* 213 */
"function %s expects to return value", /* 214 */
"function implicitly declared to return int", /* 215 */
"function %s has return (e); and return;", /* 216 */
"function %s falls off bottom without returning value", /* 217 */
"ANSI C treats constant as unsigned, op %s", /* 218 */
"concatenated strings are illegal in traditional C", /* 219 */
"fallthrough on case statement", /* 220 */
"initialisation of unsigned with negative constant", /* 221 */
"conversion of negative constant to unsigned type", /* 222 */
"end-of-loop code not reached", /* 223 */
"cannot recover from previous errors", /* 224 */
"static function called but not defined: %s()", /* 225 */
"static variable %s unused", /* 226 */
"const object %s should have initializer", /* 227 */
"function cannot return const or volatile object", /* 228 */
"questionable conversion of function pointer", /* 229 */
"nonportable character comparision, op %s", /* 230 */
"argument %s unused in function %s", /* 231 */
"label %s unused in function %s", /* 232 */
"struct %s never defined", /* 233 */
"union %s never defined", /* 234 */
"enum %s never defined", /* 235 */
"static function %s unused", /* 236 */
"redeclaration of formal parameter %s", /* 237 */
"initialisation of union is illegal in traditional C", /* 238 */
"constant argument to NOT", /* 239 */
"assignment of different structures", /* 240 */
"dubious operation on enum, op %s", /* 241 */
"combination of '%s' and '%s', op %s", /* 242 */
"dubious comparision of enums, op %s", /* 243 */
"illegal structure pointer combination", /* 244 */
"illegal structure pointer combination, op %s", /* 245 */
"dubious conversion of enum to '%s'", /* 246 */
"pointer casts may be troublesome", /* 247 */
"floating-point constant out of range", /* 248 */
"syntax error", /* 249 */
"unknown character \\%o", /* 250 */
"malformed integer constant", /* 251 */
"integer constant out of range", /* 252 */
"unterminated character constant", /* 253 */
"newline in string or char constant", /* 254 */
"undefined or invalid # directive", /* 255 */
"unterminated comment", /* 256 */
"extra characters in lint comment", /* 257 */
"unterminated string constant", /* 258 */
"conversion to '%s' due to prototype, arg #%d", /* 259 */
"previous declaration of %s", /* 260 */
"previous definition of %s", /* 261 */
"\\\" inside character constants undefined in traditional C", /* 262 */
"\\? undefined in traditional C", /* 263 */
"\\v undefined in traditional C", /* 264 */
"%s C does not support 'long long'", /* 265 */
"'long double' is illegal in traditional C", /* 266 */
"shift equal to size of object", /* 267 */
"variable declared inline: %s", /* 268 */
"argument declared inline: %s", /* 269 */
"function prototypes are illegal in traditional C", /* 270 */
"switch expression must be of type `int' in traditional C", /* 271 */
"empty translation unit", /* 272 */
"bit-field type '%s' invalid in ANSI C", /* 273 */
"ANSI C forbids comparision of %s with %s", /* 274 */
"cast discards 'const' from pointer target type", /* 275 */
"", /* 276 */
"initialisation of '%s' with '%s'", /* 277 */
"combination of '%s' and '%s', arg #%d", /* 278 */
"combination of '%s' and '%s' in return", /* 279 */
"must be outside function: /* %s */", /* 280 */
"duplicate use of /* %s */", /* 281 */
"must precede function definition: /* %s */", /* 282 */
"argument number mismatch with directive: /* %s */", /* 283 */
"fallthrough on default statement", /* 284 */
"prototype declaration", /* 285 */
"function definition is not a prototype", /* 286 */
"function declaration is not a prototype", /* 287 */
"dubious use of /* VARARGS */ with /* %s */", /* 288 */
"can't be used together: /* PRINTFLIKE */ /* SCANFLIKE */", /* 289 */
"static function %s declared but not defined", /* 290 */
"invalid multibyte character", /* 291 */
"cannot concatenate wide and regular string literals", /* 292 */
"argument %d must be 'char *' for PRINTFLIKE/SCANFLIKE", /* 293 */
"multi-character character constant", /* 294 */
"conversion of '%s' to '%s' is out of range, arg #%d", /* 295 */
"conversion of negative constant to unsigned type, arg #%d", /* 296 */
"conversion to '%s' may sign-extend incorrectly, arg #%d", /* 297 */
"conversion from '%s' may lose accuracy, arg #%d", /* 298 */
"prototype does not match old style definition, arg #%d", /* 299 */
"old style definition", /* 300 */
"array of incomplete type", /* 301 */
"%s returns pointer to automatic object", /* 302 */
"ANSI C forbids conversion of %s to %s", /* 303 */
"ANSI C forbids conversion of %s to %s, arg #%d", /* 304 */
"ANSI C forbids conversion of %s to %s, op %s", /* 305 */
"constant truncated by conversion, op %s", /* 306 */
"static variable %s set but not used", /* 307 */
"", /* 308 */
"extra bits set to 0 in conversion of '%s' to '%s', op %s", /* 309 */
};
/*
* If Fflag is not set basename() returns a pointer to the last
* component of the path, otherwise it returns the argument.
*/
static const char *
basename(path)
const char *path;
{
const char *cp, *cp1, *cp2;
if (Fflag)
return (path);
cp = cp1 = cp2 = path;
while (*cp != '\0') {
if (*cp++ == '/') {
cp2 = cp1;
cp1 = cp;
}
}
return (*cp1 == '\0' ? cp2 : cp1);
}
static void
verror(n, ap)
int n;
va_list ap;
{
const char *fn;
fn = basename(curr_pos.p_file);
(void)printf("%s(%d): ", fn, curr_pos.p_line);
(void)vprintf(msgs[n], ap);
(void)printf("\n");
nerr++;
}
static void
vwarning(n, ap)
int n;
va_list ap;
{
const char *fn;
if (nowarn)
/* this warning is suppressed by a LINTED comment */
return;
fn = basename(curr_pos.p_file);
(void)printf("%s(%d): warning: ", fn, curr_pos.p_line);
(void)vprintf(msgs[n], ap);
(void)printf("\n");
}
void
#ifdef __STDC__
error(int n, ...)
#else
error(n, va_alist)
int n;
va_dcl
#endif
{
va_list ap;
#ifdef __STDC__
va_start(ap, n);
#else
va_start(ap);
#endif
verror(n, ap);
va_end(ap);
}
void
#ifdef __STDC__
lerror(const char *msg, ...)
#else
lerror(msg, va_alist)
const char *msg;
va_dcl
#endif
{
va_list ap;
const char *fn;
#ifdef __STDC__
va_start(ap, msg);
#else
va_start(ap);
#endif
fn = basename(curr_pos.p_file);
(void)fprintf(stderr, "%s(%d): lint error: ", fn, curr_pos.p_line);
(void)vfprintf(stderr, msg, ap);
(void)fprintf(stderr, "\n");
va_end(ap);
exit(1);
}
void
#ifdef __STDC__
warning(int n, ...)
#else
warning(n, va_alist)
int n;
va_dcl
#endif
{
va_list ap;
#ifdef __STDC__
va_start(ap, n);
#else
va_start(ap);
#endif
vwarning(n, ap);
va_end(ap);
}
void
#ifdef __STDC__
message(int n, ...)
#else
message(n, va_alist)
int n;
va_dcl
#endif
{
va_list ap;
const char *fn;
#ifdef __STDC__
va_start(ap, n);
#else
va_start(ap);
#endif
fn = basename(curr_pos.p_file);
(void)printf("%s(%d): ", fn, curr_pos.p_line);
(void)vprintf(msgs[n], ap);
(void)printf("\n");
va_end(ap);
}
int
#ifdef __STDC__
gnuism(int n, ...)
#else
gnuism(n, va_alist)
int n;
va_dcl
#endif
{
va_list ap;
int msg;
#ifdef __STDC__
va_start(ap, n);
#else
va_start(ap);
#endif
if (sflag && !gflag) {
verror(n, ap);
msg = 1;
} else if (!sflag && gflag) {
msg = 0;
} else {
vwarning(n, ap);
msg = 1;
}
va_end(ap);
return (msg);
}

View File

@ -0,0 +1,56 @@
/* $NetBSD: externs.h,v 1.2 1995/07/03 21:24:06 cgd Exp $ */
/*
* Copyright (c) 1994, 1995 Jochen Pohl
* All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Jochen Pohl for
* The NetBSD Project.
* 4. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
* mem.c
*/
extern void *xmalloc __P((size_t));
extern void *xcalloc __P((size_t, size_t));
extern void *xrealloc __P((void *, size_t));
extern char *xstrdup __P((const char *));
extern void nomem __P((void));
/*
* emit.c
*/
extern ob_t ob;
extern void outopen __P((const char *));
extern void outclose __P((void));
extern void outclr __P((void));
extern void outchar __P((int));
extern void outqchar __P((int));
extern void outstrg __P((const char *));
extern void outint __P((int));
extern void outname __P((const char *));
extern void outsrc __P((const char *));

View File

@ -0,0 +1,281 @@
/* $NetBSD: externs1.h,v 1.7 1995/10/02 17:31:39 jpo Exp $ */
/*
* Copyright (c) 1994, 1995 Jochen Pohl
* All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Jochen Pohl for
* The NetBSD Project.
* 4. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
* main.c
*/
extern int aflag;
extern int bflag;
extern int cflag;
extern int dflag;
extern int eflag;
extern int Fflag;
extern int gflag;
extern int hflag;
extern int pflag;
extern int rflag;
extern int sflag;
extern int tflag;
extern int uflag;
extern int vflag;
extern int yflag;
extern int zflag;
extern void norecover __P((void));
/*
* cgram.y
*/
extern int blklev;
extern int mblklev;
extern int yydebug;
extern int yyerror __P((char *));
extern int yyparse __P((void));
/*
* scan.l
*/
extern pos_t curr_pos;
extern pos_t csrc_pos;
extern symt_t symtyp;
extern FILE *yyin;
extern u_quad_t qbmasks[], qlmasks[], qumasks[];
extern void initscan __P((void));
extern int sign __P((quad_t, tspec_t, int));
extern int msb __P((quad_t, tspec_t, int));
extern quad_t xsign __P((quad_t, tspec_t, int));
extern void clrwflgs __P((void));
extern sym_t *getsym __P((sbuf_t *));
extern void cleanup __P((void));
extern sym_t *pushdown __P((sym_t *));
extern void rmsym __P((sym_t *));
extern void rmsyms __P((sym_t *));
extern void inssym __P((int, sym_t *));
extern void freeyyv __P((void *, int));
extern int yylex __P((void));
/*
* mem1.c
*/
extern const char *fnalloc __P((const char *));
extern const char *fnnalloc __P((const char *, size_t));
extern int getfnid __P((const char *));
extern void initmem __P((void));
extern void *getblk __P((size_t));
extern void *getlblk __P((int, size_t));
extern void freeblk __P((void));
extern void freelblk __P((int));
extern void *tgetblk __P((size_t));
extern tnode_t *getnode __P((void));
extern void tfreeblk __P((void));
extern struct mbl *tsave __P((void));
extern void trestor __P((struct mbl *));
/*
* err.c
*/
extern int nerr;
extern int sytxerr;
extern const char *msgs[];
extern void error __P((int, ...));
extern void warning __P((int, ...));
extern void message __P((int, ...));
extern int gnuism __P((int, ...));
extern void lerror __P((const char *, ...));
/*
* decl.c
*/
extern dinfo_t *dcs;
extern const char *unnamed;
extern int enumval;
extern void initdecl __P((void));
extern type_t *gettyp __P((tspec_t));
extern type_t *duptyp __P((const type_t *));
extern type_t *tduptyp __P((const type_t *));
extern int incompl __P((type_t *));
extern void setcompl __P((type_t *, int));
extern void addscl __P((scl_t));
extern void addtype __P((type_t *));
extern void addqual __P((tqual_t));
extern void pushdecl __P((scl_t));
extern void popdecl __P((void));
extern void setasm __P((void));
extern void clrtyp __P((void));
extern void deftyp __P((void));
extern int length __P((type_t *, const char *));
extern int getbound __P((type_t *));
extern sym_t *lnklst __P((sym_t *, sym_t *));
extern void chktyp __P((sym_t *));
extern sym_t *decl1str __P((sym_t *));
extern sym_t *bitfield __P((sym_t *, int));
extern pqinf_t *mergepq __P((pqinf_t *, pqinf_t *));
extern sym_t *addptr __P((sym_t *, pqinf_t *));
extern sym_t *addarray __P((sym_t *, int, int));
extern sym_t *addfunc __P((sym_t *, sym_t *));
extern void chkfdef __P((sym_t *, int));
extern sym_t *dname __P((sym_t *));
extern sym_t *iname __P((sym_t *));
extern type_t *mktag __P((sym_t *, tspec_t, int, int));
extern const char *scltoa __P((scl_t));
extern type_t *compltag __P((type_t *, sym_t *));
extern sym_t *ename __P((sym_t *, int, int));
extern void decl1ext __P((sym_t *, int));
extern void cpuinfo __P((sym_t *, sym_t *));
extern int isredec __P((sym_t *, int *));
extern int eqtype __P((type_t *, type_t *, int, int, int *));
extern void compltyp __P((sym_t *, sym_t *));
extern sym_t *decl1arg __P((sym_t *, int));
extern void cluparg __P((void));
extern void decl1loc __P((sym_t *, int));
extern sym_t *aname __P((void));
extern void globclup __P((void));
extern sym_t *decl1abs __P((sym_t *));
extern void chksz __P((sym_t *));
extern void setsflg __P((sym_t *));
extern void setuflg __P((sym_t *, int, int));
extern void chkusage __P((dinfo_t *));
extern void chkusg1 __P((int, sym_t *));
extern void chkglsyms __P((void));
extern void prevdecl __P((int, sym_t *));
/*
* tree.c
*/
extern void initmtab __P((void));
extern type_t *incref __P((type_t *, tspec_t));
extern type_t *tincref __P((type_t *, tspec_t));
extern tnode_t *getcnode __P((type_t *, val_t *));
extern tnode_t *getnnode __P((sym_t *, int));
extern tnode_t *getsnode __P((strg_t *));
extern sym_t *strmemb __P((tnode_t *, op_t, sym_t *));
extern tnode_t *build __P((op_t, tnode_t *, tnode_t *));
extern tnode_t *cconv __P((tnode_t *));
extern int typeok __P((op_t, int, tnode_t *, tnode_t *));
extern tnode_t *promote __P((op_t, int, tnode_t *));
extern tnode_t *convert __P((op_t, int, type_t *, tnode_t *));
extern void cvtcon __P((op_t, int, type_t *, val_t *, val_t *));
extern const char *tyname __P((type_t *));
extern tnode_t *bldszof __P((type_t *));
extern tnode_t *cast __P((tnode_t *, type_t *));
extern tnode_t *funcarg __P((tnode_t *, tnode_t *));
extern tnode_t *funccall __P((tnode_t *, tnode_t *));
extern val_t *constant __P((tnode_t *));
extern void expr __P((tnode_t *, int, int));
extern void chkmisc __P((tnode_t *, int, int, int, int, int, int));
extern int conaddr __P((tnode_t *, sym_t **, ptrdiff_t *));
extern strg_t *catstrg __P((strg_t *, strg_t *));
/*
* func.c
*/
extern sym_t *funcsym;
extern int reached;
extern int rchflg;
extern int ftflg;
extern int nargusg;
extern pos_t aupos;
extern int nvararg;
extern pos_t vapos;
extern int prflstrg;
extern pos_t prflpos;
extern int scflstrg;
extern pos_t scflpos;
extern int ccflg;
extern int llibflg;
extern int nowarn;
extern int plibflg;
extern int quadflg;
extern void pushctrl __P((int));
extern void popctrl __P((int));
extern void chkreach __P((void));
extern void funcdef __P((sym_t *));
extern void funcend __P((void));
extern void label __P((int, sym_t *, tnode_t *));
extern void if1 __P((tnode_t *));
extern void if2 __P((void));
extern void if3 __P((int));
extern void switch1 __P((tnode_t *));
extern void switch2 __P((void));
extern void while1 __P((tnode_t *));
extern void while2 __P((void));
extern void do1 __P((void));
extern void do2 __P((tnode_t *));
extern void for1 __P((tnode_t *, tnode_t *, tnode_t *));
extern void for2 __P((void));
extern void dogoto __P((sym_t *));
extern void docont __P((void));
extern void dobreak __P((void));
extern void doreturn __P((tnode_t *));
extern void glclup __P((int));
extern void argsused __P((int));
extern void constcond __P((int));
extern void fallthru __P((int));
extern void notreach __P((int));
extern void lintlib __P((int));
extern void linted __P((int));
extern void varargs __P((int));
extern void printflike __P((int));
extern void scanflike __P((int));
extern void protolib __P((int));
extern void longlong __P((int));
/*
* init.c
*/
extern int initerr;
extern sym_t *initsym;
extern int startinit;
extern void prepinit __P((void));
extern void initrbr __P((void));
extern void initlbr __P((void));
extern void mkinit __P((tnode_t *));
/*
* emit.c
*/
extern void outtype __P((type_t *));
extern const char *ttos __P((type_t *));
extern void outsym __P((sym_t *, scl_t, def_t));
extern void outfdef __P((sym_t *, pos_t *, int, int, sym_t *));
extern void outcall __P((tnode_t *, int, int));
extern void outusg __P((sym_t *));

1261
usr.bin/xlint/lint1/func.c Normal file

File diff suppressed because it is too large Load Diff

513
usr.bin/xlint/lint1/init.c Normal file
View File

@ -0,0 +1,513 @@
/* $NetBSD: init.c,v 1.4 1995/10/02 17:21:37 jpo Exp $ */
/*
* Copyright (c) 1994, 1995 Jochen Pohl
* All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Jochen Pohl for
* The NetBSD Project.
* 4. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef lint
static char rcsid[] = "$NetBSD: init.c,v 1.4 1995/10/02 17:21:37 jpo Exp $";
#endif
#include <stdlib.h>
#include "lint1.h"
/*
* initerr is set as soon as a fatal error occured in an initialisation.
* The effect is that the rest of the initialisation is ignored (parsed
* by yacc, expression trees built, but no initialisation takes place).
*/
int initerr;
/* Pointer to the symbol which is to be initialized. */
sym_t *initsym;
/* Points to the top element of the initialisation stack. */
istk_t *initstk;
static void popi2 __P((void));
static void popinit __P((int));
static void pushinit __P((void));
static void testinit __P((void));
static void nextinit __P((int));
static int strginit __P((tnode_t *));
/*
* Initialize the initialisation stack by putting an entry for the variable
* which is to be initialized on it.
*/
void
prepinit()
{
istk_t *istk;
if (initerr)
return;
/* free memory used in last initialisation */
while ((istk = initstk) != NULL) {
initstk = istk->i_nxt;
free(istk);
}
/*
* If the type which is to be initialized is an incomplete type,
* it must be duplicated.
*/
if (initsym->s_type->t_tspec == ARRAY && incompl(initsym->s_type))
initsym->s_type = duptyp(initsym->s_type);
istk = initstk = xcalloc(1, sizeof (istk_t));
istk->i_subt = initsym->s_type;
istk->i_cnt = 1;
}
static void
popi2()
{
istk_t *istk;
sym_t *m;
initstk = (istk = initstk)->i_nxt;
if (initstk == NULL)
lerror("popi2() 1");
free(istk);
istk = initstk;
istk->i_cnt--;
if (istk->i_cnt < 0)
lerror("popi2() 3");
/*
* If the removed element was a structure member, we must go
* to the next structure member.
*/
if (istk->i_cnt > 0 && istk->i_type->t_tspec == STRUCT) {
do {
m = istk->i_mem = istk->i_mem->s_nxt;
if (m == NULL)
lerror("popi2() 2");
} while (m->s_field && m->s_name == unnamed);
istk->i_subt = m->s_type;
}
}
static void
popinit(brace)
int brace;
{
if (brace) {
/*
* Take all entries, including the first which requires
* a closing brace, from the stack.
*/
do {
brace = initstk->i_brace;
popi2();
} while (!brace);
} else {
/*
* Take all entries which cannot be used for further
* initializers from the stack, but do this only if
* they do not require a closing brace.
*/
while (!initstk->i_brace &&
initstk->i_cnt == 0 && !initstk->i_nolimit) {
popi2();
}
}
}
static void
pushinit()
{
istk_t *istk;
int cnt;
sym_t *m;
istk = initstk;
/* Extend an incomplete array type by one element */
if (istk->i_cnt == 0) {
/*
* Inside of other aggregate types must not be an incomplete
* type.
*/
if (istk->i_nxt->i_nxt != NULL)
lerror("pushinit() 1");
istk->i_cnt = 1;
if (istk->i_type->t_tspec != ARRAY)
lerror("pushinit() 2");
istk->i_type->t_dim++;
/* from now its an complete type */
setcompl(istk->i_type, 0);
}
if (istk->i_cnt <= 0)
lerror("pushinit() 3");
if (istk->i_type != NULL && issclt(istk->i_type->t_tspec))
lerror("pushinit() 4");
initstk = xcalloc(1, sizeof (istk_t));
initstk->i_nxt = istk;
initstk->i_type = istk->i_subt;
if (initstk->i_type->t_tspec == FUNC)
lerror("pushinit() 5");
istk = initstk;
switch (istk->i_type->t_tspec) {
case ARRAY:
if (incompl(istk->i_type) && istk->i_nxt->i_nxt != NULL) {
/* initialisation of an incomplete type */
error(175);
initerr = 1;
return;
}
istk->i_subt = istk->i_type->t_subt;
istk->i_nolimit = incompl(istk->i_type);
istk->i_cnt = istk->i_type->t_dim;
break;
case UNION:
if (tflag)
/* initialisation of union is illegal in trad. C */
warning(238);
/* FALLTHROUGH */
case STRUCT:
if (incompl(istk->i_type)) {
/* initialisation of an incomplete type */
error(175);
initerr = 1;
return;
}
cnt = 0;
for (m = istk->i_type->t_str->memb; m != NULL; m = m->s_nxt) {
if (m->s_field && m->s_name == unnamed)
continue;
if (++cnt == 1) {
istk->i_mem = m;
istk->i_subt = m->s_type;
}
}
if (cnt == 0) {
/* cannot init. struct/union with no named member */
error(179);
initerr = 1;
return;
}
istk->i_cnt = istk->i_type->t_tspec == STRUCT ? cnt : 1;
break;
default:
istk->i_cnt = 1;
break;
}
}
static void
testinit()
{
istk_t *istk;
istk = initstk;
/*
* If a closing brace is expected we have at least one initializer
* too much.
*/
if (istk->i_cnt == 0 && !istk->i_nolimit) {
switch (istk->i_type->t_tspec) {
case ARRAY:
/* too many array initializers */
error(173);
break;
case STRUCT:
case UNION:
/* too many struct/union initializers */
error(172);
break;
default:
/* too many initializers */
error(174);
break;
}
initerr = 1;
}
}
static void
nextinit(brace)
int brace;
{
if (!brace) {
if (initstk->i_type == NULL &&
!issclt(initstk->i_subt->t_tspec)) {
/* {}-enclosed initializer required */
error(181);
}
/*
* Make sure an entry with a scalar type is at the top
* of the stack.
*/
if (!initerr)
testinit();
while (!initerr && (initstk->i_type == NULL ||
!issclt(initstk->i_type->t_tspec))) {
if (!initerr)
pushinit();
}
} else {
if (initstk->i_type != NULL &&
issclt(initstk->i_type->t_tspec)) {
/* invalid initializer */
error(176);
initerr = 1;
}
if (!initerr)
testinit();
if (!initerr)
pushinit();
if (!initerr)
initstk->i_brace = 1;
}
}
void
initlbr()
{
if (initerr)
return;
if ((initsym->s_scl == AUTO || initsym->s_scl == REG) &&
initstk->i_nxt == NULL) {
if (tflag && !issclt(initstk->i_subt->t_tspec))
/* no automatic aggregate initialization in trad. C*/
warning(188);
}
/*
* Remove all entries which cannot be used for further initializers
* and do not expect a closing brace.
*/
popinit(0);
nextinit(1);
}
void
initrbr()
{
if (initerr)
return;
popinit(1);
}
void
mkinit(tn)
tnode_t *tn;
{
ptrdiff_t offs;
sym_t *sym;
tspec_t lt, rt;
tnode_t *ln;
struct mbl *tmem;
scl_t sc;
if (initerr || tn == NULL)
goto end;
sc = initsym->s_scl;
/*
* Do not test for automatic aggregat initialisation. If the
* initalizer starts with a brace we have the warning already.
* If not, an error will be printed that the initializer must
* be enclosed by braces.
*/
/*
* Local initialisation of non-array-types with only one expression
* without braces is done by ASSIGN
*/
if ((sc == AUTO || sc == REG) &&
initsym->s_type->t_tspec != ARRAY && initstk->i_nxt == NULL) {
ln = getnnode(initsym, 0);
ln->tn_type = tduptyp(ln->tn_type);
ln->tn_type->t_const = 0;
tn = build(ASSIGN, ln, tn);
expr(tn, 0, 0);
goto end;
}
/*
* Remove all entries which cannot be used for further initializers
* and do not require a closing brace.
*/
popinit(0);
/* Initialisations by strings are done in strginit(). */
if (strginit(tn))
goto end;
nextinit(0);
if (initerr || tn == NULL)
goto end;
initstk->i_cnt--;
/* Create a temporary node for the left side. */
ln = tgetblk(sizeof (tnode_t));
ln->tn_op = NAME;
ln->tn_type = tduptyp(initstk->i_type);
ln->tn_type->t_const = 0;
ln->tn_lvalue = 1;
ln->tn_sym = initsym; /* better than nothing */
tn = cconv(tn);
lt = ln->tn_type->t_tspec;
rt = tn->tn_type->t_tspec;
if (!issclt(lt))
lerror("mkinit() 1");
if (!typeok(INIT, 0, ln, tn))
goto end;
/*
* Store the tree memory. This is nessesary because otherwise
* expr() would free it.
*/
tmem = tsave();
expr(tn, 1, 0);
trestor(tmem);
if (isityp(lt) && ln->tn_type->t_isfield && !isityp(rt)) {
/*
* Bit-fields can be initialized in trad. C only by integer
* constants.
*/
if (tflag)
/* bit-field initialisation is illegal in trad. C */
warning(186);
}
if (lt != rt || (initstk->i_type->t_isfield && tn->tn_op == CON))
tn = convert(INIT, 0, initstk->i_type, tn);
if (tn != NULL && tn->tn_op != CON) {
sym = NULL;
offs = 0;
if (conaddr(tn, &sym, &offs) == -1) {
if (sc == AUTO || sc == REG) {
/* non-constant initializer */
(void)gnuism(177);
} else {
/* non-constant initializer */
error(177);
}
}
}
end:
tfreeblk();
}
static int
strginit(tn)
tnode_t *tn;
{
tspec_t t;
istk_t *istk;
int len;
strg_t *strg;
if (tn->tn_op != STRING)
return (0);
istk = initstk;
strg = tn->tn_strg;
/*
* Check if we have an array type which can be initialized by
* the string.
*/
if (istk->i_subt->t_tspec == ARRAY) {
t = istk->i_subt->t_subt->t_tspec;
if (!((strg->st_tspec == CHAR &&
(t == CHAR || t == UCHAR || t == SCHAR)) ||
(strg->st_tspec == WCHAR && t == WCHAR))) {
return (0);
}
/* Put the array at top of stack */
pushinit();
istk = initstk;
} else if (istk->i_type != NULL && istk->i_type->t_tspec == ARRAY) {
t = istk->i_type->t_subt->t_tspec;
if (!((strg->st_tspec == CHAR &&
(t == CHAR || t == UCHAR || t == SCHAR)) ||
(strg->st_tspec == WCHAR && t == WCHAR))) {
return (0);
}
/*
* If the array is already partly initialized, we are
* wrong here.
*/
if (istk->i_cnt != istk->i_type->t_dim)
return (0);
} else {
return (0);
}
/* Get length without trailing NUL character. */
len = strg->st_len;
if (istk->i_nolimit) {
istk->i_nolimit = 0;
istk->i_type->t_dim = len + 1;
/* from now complete type */
setcompl(istk->i_type, 0);
} else {
if (istk->i_type->t_dim < len) {
/* non-null byte ignored in string initializer */
warning(187);
}
}
/* In every case the array is initialized completely. */
istk->i_cnt = 0;
return (1);
}

118
usr.bin/xlint/lint1/lint.h Normal file
View File

@ -0,0 +1,118 @@
/* $NetBSD: lint.h,v 1.2 1995/07/03 21:24:18 cgd Exp $ */
/*
* Copyright (c) 1994, 1995 Jochen Pohl
* All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Jochen Pohl for
* The NetBSD Project.
* 4. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <sys/types.h>
#include <stdio.h>
#include <stddef.h>
#include "param.h"
/*
* Type specifiers, used in type structures (type_t) and otherwere.
*/
typedef enum {
NOTSPEC,
SIGNED, /* keyword "signed", only used in the parser */
UNSIGN, /* keyword "unsigned", only used in the parser */
CHAR, /* char */
SCHAR, /* signed char */
UCHAR, /* unsigned char */
SHORT, /* (signed) short */
USHORT, /* unsigned short */
INT, /* (signed) int */
UINT, /* unsigned int */
LONG, /* (signed) long */
ULONG, /* unsigned long */
QUAD, /* (signed) long long */
UQUAD, /* unsigned long long */
FLOAT, /* float */
DOUBLE, /* double or, with tflag, long float */
LDOUBLE, /* long double */
VOID, /* void */
STRUCT, /* structure tag */
UNION, /* union tag */
ENUM, /* enum tag */
PTR, /* pointer */
ARRAY, /* array */
FUNC /* function */
#define NTSPEC ((int)FUNC + 1)
} tspec_t;
/*
* size of types, name and classification
*/
typedef struct {
int tt_sz; /* size in bits */
int tt_psz; /* size, different from tt_sz
if pflag is set */
tspec_t tt_styp; /* signed counterpart */
tspec_t tt_utyp; /* unsigned counterpart */
u_int tt_isityp : 1; /* 1 if integer type */
u_int tt_isutyp : 1; /* 1 if unsigned integer type */
u_int tt_isftyp : 1; /* 1 if floating point type */
u_int tt_isatyp : 1; /* 1 if arithmetic type */
u_int tt_issclt : 1; /* 1 if scalar type */
char *tt_name; /* Bezeichnung des Typs */
} ttab_t;
#define size(t) (ttab[t].tt_sz)
#define psize(t) (ttab[t].tt_psz)
#define styp(t) (ttab[t].tt_styp)
#define utyp(t) (ttab[t].tt_utyp)
#define isityp(t) (ttab[t].tt_isityp)
#define isutyp(t) (ttab[t].tt_isutyp)
#define isftyp(t) (ttab[t].tt_isftyp)
#define isatyp(t) (ttab[t].tt_isatyp)
#define issclt(t) (ttab[t].tt_issclt)
extern ttab_t ttab[];
typedef enum {
NODECL, /* until now not declared */
DECL, /* declared */
TDEF, /* tentative defined */
DEF /* defined */
} def_t;
/*
* Following structure contains some data used for the output buffer.
*/
typedef struct ob {
char *o_buf; /* buffer */
char *o_end; /* first byte after buffer */
size_t o_len; /* length of buffer */
char *o_nxt; /* next free byte in buffer */
} ob_t;
#include "externs.h"

380
usr.bin/xlint/lint1/lint1.h Normal file
View File

@ -0,0 +1,380 @@
/* $NetBSD: lint1.h,v 1.6 1995/10/02 17:31:41 jpo Exp $ */
/*
* Copyright (c) 1994, 1995 Jochen Pohl
* All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Jochen Pohl for
* The NetBSD Project.
* 4. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "lint.h"
#include "op.h"
/*
* Describes the position of a declaration or anything else.
*/
typedef struct {
int p_line;
const char *p_file;
} pos_t;
/*
* Strings cannot be referenced to simply by a pointer to its first
* char. This is because strings can contain NUL characters other than the
* trailing NUL.
*
* Strings are stored with a trailing NUL.
*/
typedef struct strg {
tspec_t st_tspec; /* CHAR or WCHAR */
size_t st_len; /* length without trailing NUL */
union {
u_char *_st_cp;
wchar_t *_st_wcp;
} st_u;
} strg_t;
#define st_cp st_u._st_cp
#define st_wcp st_u._st_wcp
/*
* qualifiers (only for lex/yacc interface)
*/
typedef enum {
CONST, VOLATILE
} tqual_t;
/*
* Integer and floating point values are stored in this structure
*/
typedef struct {
tspec_t v_tspec;
int v_ansiu; /* set if an integer constant is
unsigned in ANSI C */
union {
quad_t _v_quad; /* integers */
ldbl_t _v_ldbl; /* floats */
} v_u;
} val_t;
#define v_quad v_u._v_quad
#define v_ldbl v_u._v_ldbl
/*
* Structures of type str_t uniqely identify structures. This can't
* be done in structures of type type_t, because these are copied
* if they must be modified. So it would not be possible to check
* if to structures are identical by comparing the pointers to
* the type structures.
*
* The typename is used if the structure is unnamed to identify
* the structure type in pass 2.
*/
typedef struct {
u_int size; /* size in bit */
u_int align : 15; /* alignment in bit */
u_int sincompl : 1; /* set if incomplete type */
struct sym *memb; /* list of members */
struct sym *stag; /* symbol table entry of tag */
struct sym *stdef; /* symbol table entry of first typename */
} str_t;
/*
* same as above for enums
*/
typedef struct {
u_int eincompl : 1; /* incomplete enum type */
struct sym *elem; /* list of enumerators */
struct sym *etag; /* symbol table entry of tag */
struct sym *etdef; /* symbol table entry of first typename */
} enum_t;
/*
* Types are represented by concatenation of structures of type type_t
* via t_subt.
*/
typedef struct type {
tspec_t t_tspec; /* type specifier */
u_int t_aincompl : 1; /* incomplete array type */
u_int t_const : 1; /* const modifier */
u_int t_volatile : 1; /* volatile modifier */
u_int t_proto : 1; /* function prototype (t_args valid) */
u_int t_vararg : 1; /* protoype with ... */
u_int t_typedef : 1; /* type defined with typedef */
u_int t_isfield : 1; /* type is bitfield */
u_int t_isenum : 1; /* type is (or was) enum (t_enum valid) */
union {
int _t_dim; /* dimension */
str_t *_t_str; /* struct/union tag */
enum_t *_t_enum; /* enum tag */
struct sym *_t_args; /* arguments (if t_proto) */
struct {
u_int _t_flen : 8; /* length of bit-field */
u_int _t_foffs : 24; /* offset of bit-field */
} _t_u;
} t_u;
struct type *t_subt; /* element type (arrays), return value
(functions), or type pointer points to */
} type_t;
#define t_dim t_u._t_dim
#define t_str t_u._t_str
#define t_field t_u._t_field
#define t_enum t_u._t_enum
#define t_args t_u._t_args
#define t_flen t_u._t_u._t_flen
#define t_foffs t_u._t_u._t_foffs
/*
* types of symbols
*/
typedef enum {
FVFT, /* variables, functions, type names, enums */
FMOS, /* members of structs or unions */
FTAG, /* tags */
FLAB /* labels */
} symt_t;
/*
* storage classes
*/
typedef enum {
NOSCL,
EXTERN, /* external symbols (indep. of decl_t) */
STATIC, /* static symbols (local and global) */
AUTO, /* automatic symbols (except register) */
REG, /* register */
TYPEDEF, /* typedef */
STRTAG,
UNIONTAG,
ENUMTAG,
MOS, /* member of struct */
MOU, /* member of union */
ENUMCON, /* enumerator */
ABSTRACT, /* abstract symbol (sizeof, casts, unnamed argument) */
ARG, /* argument */
PARG, /* used in declaration stack during prototype
declaration */
INLINE /* only used by the parser */
} scl_t;
/*
* symbol table entry
*/
typedef struct sym {
const char *s_name; /* name */
pos_t s_dpos; /* position of last (prototype)definition,
prototypedeclaration, no-prototype-def.,
tentative definition or declaration,
in this order */
pos_t s_spos; /* position of first initialisation */
pos_t s_upos; /* position of first use */
symt_t s_kind; /* type of symbol */
u_int s_keyw : 1; /* keyword */
u_int s_field : 1; /* bit-field */
u_int s_set : 1; /* variable set, label defined */
u_int s_used : 1; /* variable/label used */
u_int s_arg : 1; /* symbol is function argument */
u_int s_reg : 1; /* symbol is register variable */
u_int s_defarg : 1; /* undefined symbol in old style function
definition */
u_int s_rimpl : 1; /* return value of function implizit decl. */
u_int s_osdef : 1; /* symbol stems from old style function def. */
u_int s_inline : 1; /* true if this is a inline function */
struct sym *s_xsym; /* for local declared external symbols pointer
to external symbol with same name */
def_t s_def; /* declared, tentative defined, defined */
scl_t s_scl; /* storage class */
int s_blklev; /* level of declaration, -1 if not in symbol
table */
type_t *s_type; /* type */
val_t s_value; /* value (if enumcon) */
union {
str_t *_s_st; /* tag, if it is a struct/union member */
enum_t *_s_et; /* tag, if it is a enumerator */
tspec_t _s_tsp; /* type (only for keywords) */
tqual_t _s_tqu; /* qualifier (only for keywords) */
struct sym *_s_args; /* arguments in old style function
definitions */
} u;
struct sym *s_link; /* next symbol with same hash value */
struct sym **s_rlink; /* pointer to s_link of prev. symbol */
struct sym *s_nxt; /* next struct/union member, enumerator,
argument */
struct sym *s_dlnxt; /* next symbol declared on same level */
} sym_t;
#define s_styp u._s_st
#define s_etyp u._s_et
#define s_tspec u._s_tsp
#define s_tqual u._s_tqu
#define s_args u._s_args
/*
* Used to keep some informations about symbols before they are entered
* into the symbol table.
*/
typedef struct sbuf {
const char *sb_name; /* name of symbol */
size_t sb_len; /* length (without '\0') */
int sb_hash; /* hash value */
sym_t *sb_sym; /* symbol table entry */
struct sbuf *sb_nxt; /* for freelist */
} sbuf_t;
/*
* tree node
*/
typedef struct tnode {
op_t tn_op; /* operator */
type_t *tn_type; /* type */
u_int tn_lvalue : 1; /* node is lvalue */
u_int tn_cast : 1; /* if tn_op == CVT its an explizit cast */
u_int tn_parn : 1; /* node parenthesized */
union {
struct {
struct tnode *_tn_left; /* (left) operand */
struct tnode *_tn_right; /* right operand */
} tn_s;
sym_t *_tn_sym; /* symbol if op == NAME */
val_t *_tn_val; /* value if op == CON */
strg_t *_tn_strg; /* string if op == STRING */
} tn_u;
} tnode_t;
#define tn_left tn_u.tn_s._tn_left
#define tn_right tn_u.tn_s._tn_right
#define tn_sym tn_u._tn_sym
#define tn_val tn_u._tn_val
#define tn_strg tn_u._tn_strg
/*
* For nested declarations a stack exists, which holds all information
* needed for the current level. dcs points to the top element of this
* stack.
*
* ctx describes the context of the current declaration. Its value is
* one of
* EXTERN global declarations
* MOS oder MOU declarations of struct or union members
* ENUMCON declarations of enums
* ARG declaration of arguments in old style function definitions
* PARG declaration of arguments in function prototypes
* AUTO declaration of local symbols
* ABSTRACT abstract declarations (sizeof, casts)
*
*/
typedef struct dinfo {
tspec_t d_atyp; /* VOID, CHAR, INT, FLOAT or DOUBLE */
tspec_t d_smod; /* SIGNED or UNSIGN */
tspec_t d_lmod; /* SHORT, LONG or QUAD */
scl_t d_scl; /* storage class */
type_t *d_type; /* after deftyp() pointer to the type used
for all declarators */
sym_t *d_rdcsym; /* redeclared symbol */
int d_offset; /* offset of next structure member */
int d_stralign; /* alignment required for current structure */
scl_t d_ctx; /* context of declaration */
u_int d_const : 1; /* const in declaration specifiers */
u_int d_volatile : 1; /* volatile in declaration specifiers */
u_int d_inline : 1; /* inline in declaration specifiers */
u_int d_mscl : 1; /* multiple storage classes */
u_int d_terr : 1; /* invalid type combination */
u_int d_nedecl : 1; /* 1 if at least a tag is declared */
u_int d_vararg : 1; /* ... in in current function decl. */
u_int d_proto : 1; /* current funct. decl. is prototype */
u_int d_notyp : 1; /* set if no type specifier was present */
u_int d_asm : 1; /* set if d_ctx == AUTO and asm() present */
type_t *d_tagtyp; /* tag during member declaration */
sym_t *d_fargs; /* list of arguments during function def. */
pos_t d_fdpos; /* position of function definition */
sym_t *d_dlsyms; /* first symbol declared at this level */
sym_t **d_ldlsym; /* points to s_dlnxt in last symbol decl.
at this level */
sym_t *d_fpsyms; /* symbols defined in prototype */
struct dinfo *d_nxt; /* next level */
} dinfo_t;
/*
* Type of stack which is used for initialisation of aggregate types.
*/
typedef struct istk {
type_t *i_type; /* type of initialisation */
type_t *i_subt; /* type of next level */
u_int i_brace : 1; /* need } for pop */
u_int i_nolimit : 1; /* incomplete array type */
sym_t *i_mem; /* next structure member */
int i_cnt; /* # of remaining elements */
struct istk *i_nxt; /* previous level */
} istk_t;
/*
* Used to collect information about pointers and qualifiers in
* declarators.
*/
typedef struct pqinf {
int p_pcnt; /* number of asterisks */
u_int p_const : 1;
u_int p_volatile : 1;
struct pqinf *p_nxt;
} pqinf_t;
/*
* Case values are stored in a list of type clst_t.
*/
typedef struct clst {
val_t cl_val;
struct clst *cl_nxt;
} clst_t;
/*
* Used to keep informations about nested control statements.
*/
typedef struct cstk {
int c_env; /* type of statement (T_IF, ...) */
u_int c_loop : 1; /* continue && break are valid */
u_int c_switch : 1; /* case && break are valid */
u_int c_break : 1; /* loop/switch has break */
u_int c_cont : 1; /* loop has continue */
u_int c_default : 1; /* switch has default */
u_int c_infinite : 1; /* break condition always false
(for (;;), while (1)) */
u_int c_rchif : 1; /* end of if-branch reached */
u_int c_noretval : 1; /* had "return;" */
u_int c_retval : 1; /* had "return (e);" */
type_t *c_swtype; /* type of switch expression */
clst_t *c_clst; /* list of case values */
struct mbl *c_fexprm; /* saved memory for end of loop
expression in for() */
tnode_t *c_f3expr; /* end of loop expr in for() */
pos_t c_fpos; /* position of end of loop expr */
pos_t c_cfpos; /* same for csrc_pos */
struct cstk *c_nxt; /* outer control statement */
} cstk_t;
#include "externs1.h"

183
usr.bin/xlint/lint1/main1.c Normal file
View File

@ -0,0 +1,183 @@
/* $NetBSD: main1.c,v 1.3 1995/10/02 17:29:56 jpo Exp $ */
/*
* Copyright (c) 1994, 1995 Jochen Pohl
* All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Jochen Pohl for
* The NetBSD Project.
* 4. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef lint
static char rcsid[] = "$NetBSD: main1.c,v 1.3 1995/10/02 17:29:56 jpo Exp $";
#endif
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <err.h>
#include "lint1.h"
/* set yydebug to 1*/
int yflag;
/*
* Print warnings if an assignment of an integertype to another integertype
* causes an implizit narrowing conversion. If aflag is 1, these warnings
* are printed only if the source type is at least as wide as long. If aflag
* is greather then 1, they are always printed.
*/
int aflag;
/* Print a warning if a break statement cannot be reached. */
int bflag;
/* Print warnings for pointer casts. */
int cflag;
/* Print various debug information. */
int dflag;
/* Perform stricter checking of enum types and operations on enum types. */
int eflag;
/* Print complete pathnames, not only the basename. */
int Fflag;
/* Enable some extensions of gcc */
int gflag;
/*
* Apply a number of heuristic tests to attempt to intuit bugs, improve
* style, and reduce waste.
*/
int hflag;
/* Attempt to check portability to other dialects of C. */
int pflag;
/*
* In case of redeclarations/redefinitions print the location of the
* previous declaration/definition.
*/
int rflag;
/* Strict ANSI C mode. */
int sflag;
/* Traditional C mode. */
int tflag;
/*
* Complain about functions and external variables used and not defined,
* or defined and not used.
*/
int uflag = 1;
/* Complain about unused function arguments. */
int vflag = 1;
/* Complain about structures which are never defined. */
int zflag = 1;
static void usage __P((void));
int
main(argc, argv)
int argc;
char *argv[];
{
int c;
while ((c = getopt(argc, argv, "abcdeghprstuvyzF")) != -1) {
switch (c) {
case 'a': aflag++; break;
case 'b': bflag = 1; break;
case 'c': cflag = 1; break;
case 'd': dflag = 1; break;
case 'e': eflag = 1; break;
case 'F': Fflag = 1; break;
case 'g': gflag = 1; break;
case 'h': hflag = 1; break;
case 'p': pflag = 1; break;
case 'r': rflag = 1; break;
case 's': sflag = 1; break;
case 't': tflag = 1; break;
case 'u': uflag = 0; break;
case 'v': vflag = 0; break;
case 'y': yflag = 1; break;
case 'z': zflag = 0; break;
case '?': usage();
}
}
argc -= optind;
argv += optind;
if (argc != 2)
usage();
/* open the input file */
if ((yyin = fopen(argv[0], "r")) == NULL)
err(1, "cannot open '%s'", argv[0]);
/* initialize output */
outopen(argv[1]);
if (yflag)
yydebug = 1;
initmem();
initdecl();
initscan();
initmtab();
yyparse();
/* Following warnings cannot be suppressed by LINTED */
nowarn = 0;
chkglsyms();
outclose();
return (nerr != 0);
}
static void
usage()
{
(void)fprintf(stderr, "usage: lint1 [-abcdeghprstuvyzF] src dest\n");
exit(1);
}
void
norecover()
{
/* cannot recover from previous errors */
error(224);
exit(1);
}

91
usr.bin/xlint/lint1/mem.c Normal file
View File

@ -0,0 +1,91 @@
/* $NetBSD: mem.c,v 1.2 1995/07/03 21:24:24 cgd Exp $ */
/*
* Copyright (c) 1994, 1995 Jochen Pohl
* All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Jochen Pohl for
* The NetBSD Project.
* 4. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef lint
static char rcsid[] = "$NetBSD: mem.c,v 1.2 1995/07/03 21:24:24 cgd Exp $";
#endif
#include <stdlib.h>
#include <string.h>
#include <err.h>
#include "lint.h"
void *
xmalloc(s)
size_t s;
{
void *p;
if ((p = malloc(s)) == NULL)
nomem();
return (p);
}
void *
xcalloc(n, s)
size_t n, s;
{
void *p;
if ((p = calloc(n, s)) == NULL)
nomem();
return (p);
}
void *
xrealloc(p, s)
void *p;
size_t s;
{
if ((p = realloc(p, s)) == NULL)
nomem();
return (p);
}
char *
xstrdup(s)
const char *s;
{
char *s2;
if ((s2 = strdup(s)) == NULL)
nomem();
return (s2);
}
void
nomem()
{
errx(1, "virtual memory exhausted");
}

358
usr.bin/xlint/lint1/mem1.c Normal file
View File

@ -0,0 +1,358 @@
/* $NetBSD: mem1.c,v 1.2 1995/07/03 21:24:25 cgd Exp $ */
/*
* Copyright (c) 1994, 1995 Jochen Pohl
* All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Jochen Pohl for
* The NetBSD Project.
* 4. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef lint
static char rcsid[] = "$NetBSD: mem1.c,v 1.2 1995/07/03 21:24:25 cgd Exp $";
#endif
#include <sys/types.h>
#include <sys/mman.h>
#include <sys/param.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <err.h>
#include "lint1.h"
/*
* Filenames allocated by fnalloc() and fnnalloc() are shared.
*/
typedef struct fn {
char *fn_name;
size_t fn_len;
int fn_id;
struct fn *fn_nxt;
} fn_t;
static fn_t *fnames;
static fn_t *srchfn __P((const char *, size_t));
/*
* Look for a Filename of length l.
*/
static fn_t *
srchfn(s, len)
const char *s;
size_t len;
{
fn_t *fn;
for (fn = fnames; fn != NULL; fn = fn->fn_nxt) {
if (fn->fn_len == len && memcmp(fn->fn_name, s, len) == 0)
break;
}
return (fn);
}
/*
* Return a shared string for filename s.
*/
const char *
fnalloc(s)
const char *s;
{
return (s != NULL ? fnnalloc(s, strlen(s)) : NULL);
}
const char *
fnnalloc(s, len)
const char *s;
size_t len;
{
fn_t *fn;
static int nxt_id = 0;
if (s == NULL)
return (NULL);
if ((fn = srchfn(s, len)) == NULL) {
fn = xmalloc(sizeof (fn_t));
/* Do not used strdup() because string is not NUL-terminated.*/
fn->fn_name = xmalloc(len + 1);
(void)memcpy(fn->fn_name, s, len);
fn->fn_name[len] = '\0';
fn->fn_len = len;
fn->fn_id = nxt_id++;
fn->fn_nxt = fnames;
fnames = fn;
/* Write id of this filename to the output file. */
outclr();
outint(fn->fn_id);
outchar('s');
outstrg(fn->fn_name);
}
return (fn->fn_name);
}
/*
* Get id of a filename.
*/
int
getfnid(s)
const char *s;
{
fn_t *fn;
if (s == NULL || (fn = srchfn(s, strlen(s))) == NULL)
return (-1);
return (fn->fn_id);
}
/*
* Memory for declarations and other things which must be available
* until the end of a block (or the end of the translation unit)
* are assoziated with the level (mblklev) of the block (or wiht 0).
* Because these memory is allocated in large blocks associated with
* a given level it can be freed easily at the end of a block.
*/
#define ML_INC ((size_t)32) /* Increment for length of *mblks */
typedef struct mbl {
void *blk; /* beginning of memory block */
void *ffree; /* first free byte */
size_t nfree; /* # of free bytes */
size_t size; /* total size of memory block */
struct mbl *nxt; /* next block */
} mbl_t;
/*
* Array of pointers to lists of memory blocks. mblklev is used as
* index into this array.
*/
static mbl_t **mblks;
/* number of elements in *mblks */
static size_t nmblks;
/* free list for memory blocks */
static mbl_t *frmblks;
/* length of new allocated memory blocks */
static size_t mblklen;
static void *xgetblk __P((mbl_t **, size_t));
static void xfreeblk __P((mbl_t **));
static mbl_t *xnewblk __P((void));
static mbl_t *
xnewblk()
{
mbl_t *mb;
int prot, flags;
mb = xmalloc(sizeof (mbl_t));
/* use mmap instead of malloc to avoid malloc's size overhead */
prot = PROT_READ | PROT_WRITE;
flags = MAP_ANON | MAP_PRIVATE;
mb->blk = mmap(NULL, mblklen, prot, flags, -1, (off_t)0);
if (mb->blk == (void *)-1)
err(1, "can't map memory");
if (ALIGN((u_long)mb->blk) != (u_long)mb->blk)
errx(1, "mapped address is not aligned");
mb->size = mblklen;
return (mb);
}
/*
* Allocate new memory. If the first block of the list has not enough
* free space, or there is no first block, get a new block. The new
* block is taken from the free list or, if there is no block on the
* free list, is allocated using xnewblk(). If a new block is allocated
* it is initialized with zero. Blocks taken from the free list are
* zero'd in xfreeblk().
*/
static void *
xgetblk(mbp, s)
mbl_t **mbp;
size_t s;
{
mbl_t *mb;
void *p;
s = ALIGN(s);
if ((mb = *mbp) == NULL || mb->nfree < s) {
if ((mb = frmblks) == NULL) {
mb = xnewblk();
(void)memset(mb->blk, 0, mb->size);
} else {
frmblks = mb->nxt;
}
mb->ffree = mb->blk;
mb->nfree = mb->size;;
mb->nxt = *mbp;
*mbp = mb;
}
p = mb->ffree;
mb->ffree = (char *)mb->ffree + s;
mb->nfree -= s;
return (p);
}
/*
* Move all blocks from list *fmbp to free list. For each block, set all
* used memory to zero.
*/
static void
xfreeblk(fmbp)
mbl_t **fmbp;
{
mbl_t *mb;
while ((mb = *fmbp) != NULL) {
*fmbp = mb->nxt;
mb->nxt = frmblks;
frmblks = mb;
(void)memset(mb->blk, 0, mb->size - mb->nfree);
}
}
void
initmem()
{
int pgsz;
pgsz = getpagesize();
mblklen = ((MBLKSIZ + pgsz - 1) / pgsz) * pgsz;
mblks = xcalloc(nmblks = ML_INC, sizeof (mbl_t *));
}
/*
* Allocate memory associated with level l.
*/
void *
getlblk(l, s)
int l;
size_t s;
{
while (l >= nmblks) {
mblks = xrealloc(mblks, (nmblks + ML_INC) * sizeof (mbl_t *));
(void)memset(&mblks[nmblks], 0, ML_INC * sizeof (mbl_t *));
nmblks += ML_INC;
}
return (xgetblk(&mblks[l], s));
}
void *
getblk(s)
size_t s;
{
return (getlblk(mblklev, s));
}
/*
* Free all memory associated with level l.
*/
void
freelblk(l)
int l;
{
xfreeblk(&mblks[l]);
}
void
freeblk()
{
freelblk(mblklev);
}
/*
* tgetblk() returns memory which is associated with the current
* expression.
*/
static mbl_t *tmblk;
void *
tgetblk(s)
size_t s;
{
return (xgetblk(&tmblk, s));
}
/*
* Get memory for a new tree node.
*/
tnode_t *
getnode()
{
return (tgetblk(sizeof (tnode_t)));
}
/*
* Free all memory which is allocated by the the current expression.
*/
void
tfreeblk()
{
xfreeblk(&tmblk);
}
/*
* Save the memory which is used by the current expression. This memory
* is not freed by the next tfreeblk() call. The pointer returned can be
* used to restore the memory.
*/
mbl_t *
tsave()
{
mbl_t *tmem;
tmem = tmblk;
tmblk = NULL;
return (tmem);
}
/*
* Free all memory used for the current expression and the memory used
* be a previous expression and saved by tsave(). The next call to
* tfreeblk() frees the restored memory.
*/
void
trestor(tmem)
mbl_t *tmem;
{
tfreeblk();
if (tmblk != NULL) {
free(tmblk->blk);
free(tmblk);
}
tmblk = tmem;
}

120
usr.bin/xlint/lint1/op.h Normal file
View File

@ -0,0 +1,120 @@
/* $NetBSD: op.h,v 1.2 1995/07/03 21:24:27 cgd Exp $ */
/*
* Copyright (c) 1994, 1995 Jochen Pohl
* All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Jochen Pohl for
* The NetBSD Project.
* 4. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
* Various information about operators
*/
typedef struct {
u_int m_binary : 1; /* binary op. */
u_int m_logop : 1; /* logical op., result is int */
u_int m_rqint : 1; /* operands must have integer type */
u_int m_rqsclt : 1; /* operands must have scalar type */
u_int m_rqatyp : 1; /* operands must have arithmetic type */
u_int m_fold : 1; /* operands should be folded */
u_int m_vctx : 1; /* value context for left operand */
u_int m_tctx : 1; /* test context for left operand */
u_int m_balance : 1; /* op. requires balancing */
u_int m_sideeff : 1; /* op. has side effect */
u_int m_tlansiu : 1; /* warning if left op. is unsign. in ANSI C */
u_int m_transiu : 1; /* warning if right op. is unsign. in ANSI C */
u_int m_tpconf : 1; /* test possible precedence confusion */
u_int m_comp : 1; /* op. performs comparision */
u_int m_enumop : 1; /* valid operation on enums */
u_int m_badeop : 1; /* dubious operation on enums */
u_int m_eqwarn : 1; /* warning if on operand stems from == */
const char *m_name; /* name of op. */
} mod_t;
typedef enum {
NOOP = 0,
ARROW,
POINT,
NOT,
COMPL,
INC,
DEC,
INCBEF,
DECBEF,
INCAFT,
DECAFT,
UPLUS,
UMINUS,
STAR,
AMPER,
MULT,
DIV,
MOD,
PLUS,
MINUS,
SHL,
SHR,
LT,
LE,
GT,
GE,
EQ,
NE,
AND,
XOR,
OR,
LOGAND,
LOGOR,
QUEST,
COLON,
ASSIGN,
MULASS,
DIVASS,
MODASS,
ADDASS,
SUBASS,
SHLASS,
SHRASS,
ANDASS,
XORASS,
ORASS,
NAME,
CON,
STRING,
FSEL,
CALL,
COMMA,
CVT,
ICALL,
LOAD,
PUSH,
RETURN,
INIT, /* pseudo op, not used in trees */
CASE, /* pseudo op, not used in trees */
FARG /* pseudo op, not used in trees */
#define NOPS ((int)FARG + 1)
} op_t;

120
usr.bin/xlint/lint1/param.h Normal file
View File

@ -0,0 +1,120 @@
/* $NetBSD: param.h,v 1.4 1995/07/23 18:14:41 ragge Exp $ */
/*
* Copyright (c) 1994, 1995 Jochen Pohl
* All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Jochen Pohl for
* The NetBSD Project.
* 4. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
* Minimun size of string buffer. If this is not enough, the buffer
* is enlarged in steps of STRBLEN bytes.
*/
#define STRBLEN 256
/*
* This defines the size of memory blocks which are used to allocate
* memory in larger chunks.
*/
#define MBLKSIZ ((size_t)0x4000)
/*
* Sizes of hash tables
* Should be a prime. Possible primes are
* 307, 401, 503, 601, 701, 809, 907, 1009, 1103, 1201, 1301, 1409, 1511.
*
* HSHSIZ1 symbol table 1st pass
* HSHSIZ2 symbol table 2nd pass
* THSHSIZ2 type table 2nd pass
*/
#define HSHSIZ1 503
#define HSHSIZ2 1009
#define THSHSIZ2 1009
/*
* Should be set to 1 if the difference of two pointers is of type long
* or the value of sizeof is of type unsigned long.
*/
#ifdef __alpha__
#define PTRDIFF_IS_LONG 1
#define SIZEOF_IS_ULONG 1
#elif __i386__
#define PTRDIFF_IS_LONG 0
#define SIZEOF_IS_ULONG 0
#elif __m68k__
#define PTRDIFF_IS_LONG 0
#define SIZEOF_IS_ULONG 0
#elif __ns32k__
#define PTRDIFF_IS_LONG 0
#define SIZEOF_IS_ULONG 0
#elif __sparc__
#define PTRDIFF_IS_LONG 0
#define SIZEOF_IS_ULONG 0
#elif __vax__
#define PTRDIFF_IS_LONG 0
#define SIZEOF_IS_ULONG 0
#else
#error unknown machine type
#endif
/*
* Make sure this matches wchar_t.
*/
#define WCHAR SHORT
#ifndef __GNUC__
#ifndef lint
#ifndef QUAD_MAX /* necessary for mkdep */
#define QUAD_MAX LONG_MAX
#define QUAD_MIN LONG_MIN
#define UQUAD_MAX ULONG_MAX
#endif
typedef long quad_t;
typedef u_long u_quad_t;
#endif
#endif
/*
* long double only in ANSI C.
*/
#ifdef __STDC__
typedef long double ldbl_t;
#else
typedef double ldbl_t;
#endif
/*
* Some traditional compilers are not able to assign structures.
*/
#ifdef __STDC__
#define STRUCT_ASSIGN(dest, src) (dest) = (src)
#else
#define STRUCT_ASSIGN(dest, src) (void)memcpy(&(dest), &(src), \
sizeof (dest));
#endif

1426
usr.bin/xlint/lint1/scan.l Normal file

File diff suppressed because it is too large Load Diff

3924
usr.bin/xlint/lint1/tree.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,13 @@
# $NetBSD: Makefile,v 1.2 1995/07/03 21:24:39 cgd Exp $
.PATH: ${.CURDIR}/../lint1
PROG= lint2
SRCS= main2.c hash.c read.c mem.c mem2.c chk.c msg.c emit.c emit2.c
NOMAN=
CFLAGS+=-I${.CURDIR}/../lint1
LINTFLAGS=-abehrz
BINDIR= /usr/libexec
.include <bsd.prog.mk>

1462
usr.bin/xlint/lint2/chk.c Normal file

File diff suppressed because it is too large Load Diff

236
usr.bin/xlint/lint2/emit2.c Normal file
View File

@ -0,0 +1,236 @@
/* $NetBSD: emit2.c,v 1.2 1995/07/03 21:24:44 cgd Exp $ */
/*
* Copyright (c) 1994, 1995 Jochen Pohl
* All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Jochen Pohl for
* The NetBSD Project.
* 4. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef lint
static char rcsid[] = "$NetBSD: emit2.c,v 1.2 1995/07/03 21:24:44 cgd Exp $";
#endif
#include <err.h>
#include "lint2.h"
static void outtype __P((type_t *));
static void outdef __P((hte_t *, sym_t *));
static void dumpname __P((hte_t *));
/*
* Write type into the output buffer.
*/
static void
outtype(tp)
type_t *tp;
{
int t, s, na;
tspec_t ts;
type_t **ap;
while (tp != NULL) {
if ((ts = tp->t_tspec) == INT && tp->t_isenum)
ts = ENUM;
switch (ts) {
case CHAR: t = 'C'; s = '\0'; break;
case SCHAR: t = 'C'; s = 's'; break;
case UCHAR: t = 'C'; s = 'u'; break;
case SHORT: t = 'S'; s = '\0'; break;
case USHORT: t = 'S'; s = 'u'; break;
case INT: t = 'I'; s = '\0'; break;
case UINT: t = 'I'; s = 'u'; break;
case LONG: t = 'L'; s = '\0'; break;
case ULONG: t = 'L'; s = 'u'; break;
case QUAD: t = 'Q'; s = '\0'; break;
case UQUAD: t = 'Q'; s = 'u'; break;
case FLOAT: t = 'D'; s = 's'; break;
case DOUBLE: t = 'D'; s = '\0'; break;
case LDOUBLE: t = 'D'; s = 'l'; break;
case VOID: t = 'V'; s = '\0'; break;
case PTR: t = 'P'; s = '\0'; break;
case ARRAY: t = 'A'; s = '\0'; break;
case ENUM: t = 'T'; s = 'e'; break;
case STRUCT: t = 'T'; s = 's'; break;
case UNION: t = 'T'; s = 'u'; break;
case FUNC:
if (tp->t_args != NULL && !tp->t_proto) {
t = 'f';
} else {
t = 'F';
}
s = '\0';
break;
default:
errx(1, "internal error: outtype() 1");
}
if (tp->t_const)
outchar('c');
if (tp->t_volatile)
outchar('v');
if (s != '\0')
outchar(s);
outchar(t);
if (ts == ARRAY) {
outint(tp->t_dim);
} else if (ts == ENUM || ts == STRUCT || ts == UNION) {
if (tp->t_istag) {
outint(1);
outname(tp->t_tag->h_name);
} else if (tp->t_istynam) {
outint(2);
outname(tp->t_tynam->h_name);
} else {
outint(0);
}
} else if (ts == FUNC && tp->t_args != NULL) {
na = 0;
for (ap = tp->t_args; *ap != NULL; ap++)
na++;
if (tp->t_vararg)
na++;
outint(na);
for (ap = tp->t_args; *ap != NULL; ap++)
outtype(*ap);
if (tp->t_vararg)
outchar('E');
}
tp = tp->t_subt;
}
}
/*
* Write a definition.
*/
static void
outdef(hte, sym)
hte_t *hte;
sym_t *sym;
{
/* reset output buffer */
outclr();
/* line number in C source file */
outint(0);
/* this is a definition */
outchar('d');
/* index of file where symbol was defined and line number of def. */
outint(0);
outchar('.');
outint(0);
/* flags */
if (sym->s_va) {
outchar('v'); /* varargs */
outint(sym->s_nva);
}
if (sym->s_scfl) {
outchar('S'); /* scanflike */
outint(sym->s_nscfl);
}
if (sym->s_prfl) {
outchar('P'); /* printflike */
outint(sym->s_nprfl);
}
/* definition or tentative definition */
outchar(sym->s_def == DEF ? 'd' : 't');
if (TP(sym->s_type)->t_tspec == FUNC) {
if (sym->s_rval)
outchar('r'); /* fkt. has return value */
if (sym->s_osdef)
outchar('o'); /* old style definition */
}
outchar('u'); /* used (no warning if not used) */
/* name */
outname(hte->h_name);
/* type */
outtype(TP(sym->s_type));
}
/*
* Write the first definition of a name into the lint library.
*/
static void
dumpname(hte)
hte_t *hte;
{
sym_t *sym, *def;
/* static and undefined symbols are not written */
if (hte->h_static || !hte->h_def)
return;
/*
* If there is a definition, write it. Otherwise write a tentative
* definition. This is neccessary because more than one tentative
* definition is allowed (except with sflag).
*/
def = NULL;
for (sym = hte->h_syms; sym != NULL; sym = sym->s_nxt) {
if (sym->s_def == DEF) {
def = sym;
break;
}
if (sym->s_def == TDEF && def == NULL)
def = sym;
}
if (def == NULL)
errx(1, "internal error: dumpname() %s", hte->h_name);
outdef(hte, def);
}
/*
* Write a new lint library.
*/
void
outlib(name)
const char *name;
{
/* Open of output file and initialisation of the output buffer */
outopen(name);
/* write name of lint library */
outsrc(name);
/* name of lint lib has index 0 */
outclr();
outint(0);
outchar('s');
outstrg(name);
/* write all definitions with external linkage */
forall(dumpname);
/* close the output */
outclose();
}

View File

@ -0,0 +1,87 @@
/* $NetBSD: externs2.h,v 1.2 1995/07/03 21:24:46 cgd Exp $ */
/*
* Copyright (c) 1994, 1995 Jochen Pohl
* All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Jochen Pohl for
* The NetBSD Project.
* 4. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
* main.c
*/
extern int xflag;
extern int uflag;
extern int Cflag;
extern const char *libname;
extern int pflag;
extern int sflag;
extern int tflag;
extern int Hflag;
extern int hflag;
extern int Fflag;
/*
* hash.c
*/
extern void inithash __P((void));
extern hte_t *hsearch __P((const char *, int));
extern void forall __P((void (*)(hte_t *)));
/*
* read.c
*/
extern const char **fnames;
extern type_t **tlst;
extern void readfile __P((const char *));
extern void mkstatic __P((hte_t *));
/*
* mem2.c
*/
extern void initmem __P((void));
extern void *xalloc __P((size_t));
/*
* chk.c
*/
extern void inittyp __P((void));
extern void mainused __P((void));
extern void chkname __P((hte_t *));
/*
* msg.c
*/
extern void msg __P((int, ...));
extern const char *mkpos __P((pos_t *));
/*
* emit2.c
*/
extern void outlib __P((const char *));

123
usr.bin/xlint/lint2/hash.c Normal file
View File

@ -0,0 +1,123 @@
/* $NetBSD: hash.c,v 1.2 1995/07/03 21:24:47 cgd Exp $ */
/*
* Copyright (c) 1994, 1995 Jochen Pohl
* All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Jochen Pohl for
* The NetBSD Project.
* 4. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef lint
static char rcsid[] = "$NetBSD: hash.c,v 1.2 1995/07/03 21:24:47 cgd Exp $";
#endif
#include <stddef.h>
#include <string.h>
#include <limits.h>
#include "lint2.h"
/* pointer to hash table, initialized in inithash() */
static hte_t **htab;
static int hash __P((const char *));
/*
* Initialize hash table.
*/
void
inithash()
{
htab = xcalloc(HSHSIZ2, sizeof (hte_t *));
}
/*
* Compute hash value from a string.
*/
static int
hash(s)
const char *s;
{
u_int v;
const u_char *us;
v = 0;
for (us = (const u_char *)s; *us != '\0'; us++) {
v = (v << sizeof (v)) + *us;
v ^= v >> (sizeof (v) * CHAR_BIT - sizeof (v));
}
return (v % HSHSIZ2);
}
/*
* Look for a hash table entry. If no hash table entry for the
* given name exists and mknew is set, create a new one.
*/
hte_t *
hsearch(s, mknew)
const char *s;
int mknew;
{
int h;
hte_t *hte;
h = hash(s);
for (hte = htab[h]; hte != NULL; hte = hte->h_link) {
if (strcmp(hte->h_name, s) == 0)
break;
}
if (hte != NULL || !mknew)
return (hte);
/* create a new hte */
hte = xalloc(sizeof (hte_t));
hte->h_name = xstrdup(s);
hte->h_lsym = &hte->h_syms;
hte->h_lcall = &hte->h_calls;
hte->h_lusym = &hte->h_usyms;
hte->h_link = htab[h];
htab[h] = hte;
return (hte);
}
/*
* Call function f for each name in the hash table.
*/
void
forall(f)
void (*f) __P((hte_t *));
{
int i;
hte_t *hte;
for (i = 0; i < HSHSIZ2; i++) {
for (hte = htab[i]; hte != NULL; hte = hte->h_link)
(*f)(hte);
}
}

177
usr.bin/xlint/lint2/lint2.h Normal file
View File

@ -0,0 +1,177 @@
/* $NetBSD: lint2.h,v 1.2 1995/07/03 21:24:49 cgd Exp $ */
/*
* Copyright (c) 1994, 1995 Jochen Pohl
* All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Jochen Pohl for
* The NetBSD Project.
* 4. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "lint.h"
/*
* Types are described by structures of type type_t.
*/
typedef struct type {
tspec_t t_tspec; /* type specifier */
u_int t_const : 1; /* constant */
u_int t_volatile : 1; /* volatile */
u_int t_vararg : 1; /* function has variable number of arguments */
u_int t_isenum : 1; /* enum type */
u_int t_proto : 1; /* this is a prototype */
u_int t_istag : 1; /* tag with _t_tag valid */
u_int t_istynam : 1; /* tag with _t_tynam valid */
union {
int _t_dim; /* if the type is an ARRAY than this
is the dimension of the array. */
struct hte *_t_tag; /* hash table entry of tag if
t_isenum, STRUCT or UNION */
struct hte *_t_tynam; /* hash table entry of typename if
t_isenum, STRUCT or UNION */
struct type **_t_args; /* list of argument types if this
is a prototype */
} t_u;
struct type *t_subt; /* indirected type (array element, pointed to
type, type of return value) */
} type_t;
#define t_dim t_u._t_dim
#define t_tag t_u._t_tag
#define t_tynam t_u._t_tynam
#define t_args t_u._t_args
/*
* argument information
*
* Such a structure is created for each argument of a function call
* which is an integer constant or a constant string.
*/
typedef struct arginf {
int a_num; /* # of argument (1..) */
u_int a_zero : 1; /* argument is 0 */
u_int a_pcon : 1; /* msb of argument is not set */
u_int a_ncon : 1; /* msb of argument is set */
u_int a_fmt : 1; /* a_fstrg points to format string */
char *a_fstrg; /* format string */
struct arginf *a_nxt; /* information for next const. argument */
} arginf_t;
/*
* Keeps information about position in source file.
*/
typedef struct {
u_short p_src; /* index of name of translation unit
(the name which was specified at the
command line) */
u_short p_line; /* line number in p_src */
u_short p_isrc; /* index of (included) file */
u_short p_iline; /* line number in p_iline */
} pos_t;
/*
* Used for definitions and declarations
*
* To save memory, variable sized structures are used. If
* all s_va, s_prfl and s_scfl are not set, the memory allocated
* for a symbol is only large enough to keep the first member of
* struct sym, s_s.
*/
typedef struct sym {
struct {
pos_t s_pos; /* pos of def./decl. */
#ifndef lint
u_int s_def : 3; /* DECL, TDEF or DEF */
#else
def_t s_def;
#endif
u_int s_rval : 1; /* function has return value */
u_int s_osdef : 1; /* old style function definition */
u_int s_static : 1; /* symbol is static */
u_int s_va : 1; /* check only first s_nva arguments */
u_int s_prfl : 1; /* printflike */
u_int s_scfl : 1; /* scanflike */
u_short s_type; /* type */
struct sym *s_nxt; /* next symbol with same name */
} s_s;
short s_nva;
short s_nprfl;
short s_nscfl;
} sym_t;
#define s_pos s_s.s_pos
#define s_rval s_s.s_rval
#define s_osdef s_s.s_osdef
#define s_static s_s.s_static
#define s_def s_s.s_def
#define s_va s_s.s_va
#define s_prfl s_s.s_prfl
#define s_scfl s_s.s_scfl
#define s_type s_s.s_type
#define s_nxt s_s.s_nxt
/*
* Used to store informations about function calls.
*/
typedef struct fcall {
pos_t f_pos; /* position of call */
u_int f_rused : 1; /* return value used */
u_int f_rdisc : 1; /* return value discarded (casted to void) */
u_short f_type; /* types of expected return value and args */
arginf_t *f_args; /* information about constant arguments */
struct fcall *f_nxt; /* next call of same function */
} fcall_t;
/*
* Used to store information about usage of symbols other
* than for function calls.
*/
typedef struct usym {
pos_t u_pos; /* position */
struct usym *u_nxt; /* next usage */
} usym_t;
/*
* hash table entry
*/
typedef struct hte {
const char *h_name; /* name */
u_int h_used : 1; /* symbol is used */
u_int h_def : 1; /* symbol is defined */
u_int h_static : 1; /* static symbol */
sym_t *h_syms; /* declarations and definitions */
sym_t **h_lsym; /* points to s_nxt of last decl./def. */
fcall_t *h_calls; /* function calls */
fcall_t **h_lcall; /* points to f_nxt of last call */
usym_t *h_usyms; /* usage info */
usym_t **h_lusym; /* points to u_nxt of last usage info */
struct hte *h_link; /* next hte with same hash function */
} hte_t;
/* maps type indices into pointers to type structs */
#define TP(idx) (tlst[idx])
#include "externs2.h"

190
usr.bin/xlint/lint2/main2.c Normal file
View File

@ -0,0 +1,190 @@
/* $NetBSD: main2.c,v 1.2 1995/07/03 21:24:53 cgd Exp $ */
/*
* Copyright (c) 1994, 1995 Jochen Pohl
* All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Jochen Pohl for
* The NetBSD Project.
* 4. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef lint
static char rcsid[] = "$NetBSD: main2.c,v 1.2 1995/07/03 21:24:53 cgd Exp $";
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "lint2.h"
/* warnings for symbols which are declared but not defined or used */
int xflag;
/*
* warnings for symbols which are used and not defined or defined
* and not used
*/
int uflag = 1;
/* Create a lint library in the current directory with name libname. */
int Cflag;
const char *libname;
int pflag;
/*
* warnings for (tentative) definitions of the same name in more then
* one translation unit
*/
int sflag;
int tflag;
/*
* If a complaint stems from a included file, print the name of the included
* file instead of the name spezified at the command line followed by '?'
*/
int Hflag;
int hflag;
/* Print full path names, not only the last component */
int Fflag;
/*
* List of libraries (from -l flag). These libraries are read after all
* other input files has been read and, for Cflag, after the new lint library
* has been written.
*/
const char **libs;
static void usage __P((void));
int
main(argc, argv)
int argc;
char *argv[];
{
int c, i;
size_t len;
char *lname;
libs = xcalloc(1, sizeof (char *));
opterr = 0;
while ((c = getopt(argc, argv, "hpstxuC:HFl:")) != -1) {
switch (c) {
case 's':
sflag = 1;
break;
case 't':
tflag = 1;
break;
case 'u':
uflag = 0;
break;
case 'x':
xflag = 1;
break;
case 'p':
pflag = 1;
break;
case 'C':
len = strlen(optarg);
lname = xmalloc(len + 10);
(void)sprintf(lname, "llib-l%s.ln", optarg);
libname = lname;
Cflag = 1;
uflag = 0;
break;
case 'H':
Hflag = 1;
break;
case 'h':
hflag = 1;
break;
case 'F':
Fflag = 1;
break;
case 'l':
for (i = 0; libs[i] != NULL; i++) ;
libs = xrealloc(libs, (i + 2) * sizeof (char *));
libs[i] = xstrdup(optarg);
libs[i + 1] = NULL;
break;
case '?':
usage();
}
}
argc -= optind;
argv += optind;
if (argc == 0)
usage();
initmem();
/* initialize hash table */
inithash();
inittyp();
for (i = 0; i < argc; i++)
readfile(argv[i]);
/* write the lint library */
if (Cflag) {
forall(mkstatic);
outlib(libname);
}
/* read additional libraries */
for (i = 0; libs[i] != NULL; i++)
readfile(libs[i]);
forall(mkstatic);
mainused();
/* perform all tests */
forall(chkname);
exit(0);
/* NOTREACHED */
}
static void
usage()
{
(void)fprintf(stderr,
"usage: lint2 -hpstxuHF -Clib -l lib ... src1 ...\n");
exit(1);
}

View File

@ -0,0 +1,97 @@
/* $NetBSD: mem2.c,v 1.3 1995/10/02 17:27:11 jpo Exp $ */
/*
* Copyright (c) 1994, 1995 Jochen Pohl
* All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Jochen Pohl for
* The NetBSD Project.
* 4. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef lint
static char rcsid[] = "$NetBSD: mem2.c,v 1.3 1995/10/02 17:27:11 jpo Exp $";
#endif
#include <sys/param.h>
#include <sys/types.h>
#include <sys/mman.h>
#include <unistd.h>
#include <string.h>
#include <err.h>
#include "lint2.h"
/* length of new allocated memory blocks */
static size_t mblklen;
/* offset of next free byte in mbuf */
static size_t nxtfree;
/* current buffer to server memory requests from */
static void *mbuf;
void
initmem()
{
int pgsz;
pgsz = getpagesize();
mblklen = ((MBLKSIZ + pgsz - 1) / pgsz) * pgsz;
nxtfree = mblklen;
}
/*
* Allocate memory in large chunks to avoid space and time overhead of
* malloc(). This is possible because memory allocated by xalloc()
* need never to be freed.
*/
void *
xalloc(sz)
size_t sz;
{
void *ptr;
int prot, flags;
sz = ALIGN(sz);
if (nxtfree + sz > mblklen) {
/* use mmap() instead of malloc() to avoid malloc overhead. */
prot = PROT_READ | PROT_WRITE;
flags = MAP_ANON | MAP_PRIVATE;
mbuf = mmap(NULL, mblklen, prot, flags, -1, (off_t)0);
if (mbuf == (void *)-1)
err(1, "can't map memory");
if (ALIGN((u_long)mbuf) != (u_long)mbuf)
errx(1, "mapped address is not aligned");
(void)memset(mbuf, 0, mblklen);
nxtfree = 0;
}
ptr = (char *)mbuf + nxtfree;
nxtfree += sz;
return (ptr);
}

157
usr.bin/xlint/lint2/msg.c Normal file
View File

@ -0,0 +1,157 @@
/* $NetBSD: msg.c,v 1.2 1995/07/03 21:24:56 cgd Exp $ */
/*
* Copyright (c) 1994, 1995 Jochen Pohl
* All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Jochen Pohl for
* The NetBSD Project.
* 4. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef lint
static char rcsid[] = "$NetBSD: msg.c,v 1.2 1995/07/03 21:24:56 cgd Exp $";
#endif
#include <string.h>
#include <stdio.h>
#ifdef __STDC__
#include <stdarg.h>
#else
#include <varargs.h>
#endif
#include "lint2.h"
static const char *msgs[] = {
"%s used( %s ), but not defined", /* 0 */
"%s defined( %s ), but never used", /* 1 */
"%s declared( %s ), but never used or defined", /* 2 */
"%s multiply defined \t%s :: %s", /* 3 */
"%s value used inconsistently \t%s :: %s", /* 4 */
"%s value declared inconsistently \t%s :: %s", /* 5 */
"%s, arg %d used inconsistently \t%s :: %s", /* 6 */
"%s: variable # of args \t%s :: %s", /* 7 */
"%s returns value which is always ignored", /* 8 */
"%s returns value which is sometimes ignored", /* 9 */
"%s value is used( %s ), but none returned", /* 10 */
"%s, arg %d declared inconsistently \t%s :: %s", /* 11 */
"%s: variable # of args declared \t%s :: %s", /* 12 */
"%s: malformed format string \t%s", /* 13 */
"%s, arg %d inconsistent with format \t%s", /* 14 */
"%s: too few args for format \t%s", /* 15 */
"%s: too many args for format \t%s", /* 16 */
"%s function value must be declared before use \t%s :: %s",/* 17 */
};
static const char *basename __P((const char *));
#ifdef __STDC__
void
msg(int n, ...)
{
#else
void
msg(va_alist)
va_dcl
int n;
{
#endif
va_list ap;
#ifdef __STDC__
va_start(ap, n);
#else
va_start(ap);
n = va_arg(ap, int);
#endif
(void)vprintf(msgs[n], ap);
(void)printf("\n");
va_end(ap);
}
/*
* Return a pointer to the last component of a path.
*/
static const char *
basename(path)
const char *path;
{
const char *cp, *cp1, *cp2;
if (Fflag)
return (path);
cp = cp1 = cp2 = path;
while (*cp != '\0') {
if (*cp++ == '/') {
cp2 = cp1;
cp1 = cp;
}
}
return (*cp1 == '\0' ? cp2 : cp1);
}
/*
* Create a string which describes a position in a source file.
*/
const char *
mkpos(posp)
pos_t *posp;
{
size_t len;
const char *fn;
static char *buf;
static size_t blen = 0;
int qm, src, line;
if (Hflag && posp->p_src != posp->p_isrc) {
src = posp->p_isrc;
line = posp->p_iline;
} else {
src = posp->p_src;
line = posp->p_line;
}
qm = !Hflag && posp->p_src != posp->p_isrc;
len = strlen(fn = basename(fnames[src]));
len += 3 * sizeof (u_short) + 4;
if (len > blen)
buf = xrealloc(buf, blen = len);
if (line != 0) {
(void)sprintf(buf, "%s%s(%hu)",
fn, qm ? "?" : "", line);
} else {
(void)sprintf(buf, "%s", fn);
}
return (buf);
}

1133
usr.bin/xlint/lint2/read.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,20 @@
# $NetBSD: Makefile,v 1.2 1995/07/03 21:25:05 cgd Exp $
LIBS= llib-lposix.ln llib-lstdc.ln
all: ${LIBS}
install:
install ${COPY} -o ${BINOWN} -g ${BINGRP} -m ${NONBINMODE} \
${LIBS} ${DESTDIR}${LINTLIBDIR}
clean cleanall:
rm -f ${LIBS}
llib-lposix.ln: llib-lposix
lint -Cposix ${.ALLSRC}
llib-lstdc.ln: llib-lstdc
lint -Cstdc ${.ALLSRC}
.include <bsd.prog.mk>

View File

@ -0,0 +1,311 @@
/* $NetBSD: llib-lposix,v 1.2 1995/07/03 21:25:09 cgd Exp $ */
/*
* Copyright (c) 1994, 1995 Jochen Pohl
* All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Jochen Pohl for
* The NetBSD Project.
* 4. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/* LINTLIBRARY */
#define _POSIX_SOURCE
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/utsname.h>
#include <sys/times.h>
#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>
#include <unistd.h>
#include <math.h>
#include <time.h>
#include <assert.h>
#include <termios.h>
#include <dirent.h>
#include <fcntl.h>
#include <grp.h>
#include <pwd.h>
#include <ctype.h>
#include <signal.h>
#include <locale.h>
#include <setjmp.h>
#include <string.h>
#include <utime.h>
/* PROTOLIB1 */
void (abort)(void);
int (abs)(int j);
int (access)(const char *path, int amode);
double (acos)(double x);
unsigned (alarm)(unsigned seconds);
char *(asctime)(const struct tm *timeptr);
double (asin)(double x);
void (__assert)(const char *expression, int line, const char *file);
double (atan)(double x);
double (atan2)(double y, double x);
int (atexit)(void (*func)(void));
double (atof)(const char *nptr);
int (atoi)(const char *nptr);
long (atol)(const char *nptr);
void *(bsearch)(const void *key, const void *base, size_t nmemb,
size_t size, int (*compar)(const void *, const void *));
void *(calloc)(size_t nmemb, size_t size);
double (ceil)(double x);
speed_t (cfgetispeed)(const struct termios *p);
speed_t (cfgetospeed)(const struct termios *p);
int (cfsetispeed)(struct termios *p, speed_t speed);
int (cfsetospeed)(struct termios *p, speed_t speed);
int (chdir)(const char *path);
int (chmod)(const char *path, mode_t mode);
int (chown)(const char *path, uid_t owner, gid_t group);
void (clearerr)(FILE *stream);
clock_t (clock)(void);
int (close)(int fildes);
int (closedir)(DIR *dirp);
double (cos)(double x);
double (cosh)(double x);
int (creat)(const char *path, mode_t mode);
char *(ctermid)(char *s);
char *(ctime)(const time_t *timer);
char *(cuserid)(char *s);
double (difftime)(time_t time1, time_t time0);
div_t (div)(int numer, int denom);
int (dup)(int fildes);
int (dup2)(int fildes, int fildes2);
int (errno);
int (execl)(const char *path, const char *arg, ...);
int (execle)(const char *path, const char *arg, ...);
int (execlp)(const char *file, const char *arg, ...);
int (execv)(const char *path, char *const argv[]);
int (execve)(const char *path, char *const argv[], char *const *envp);
int (execvp)(const char *file, char *const argv[]);
void (exit)(int status);
void (_exit)(int status);
double (exp)(double x);
double (fabs)(double x);
int (fclose)(FILE *stream);
int (fcntl)(int fildes, int cmd, ...);
FILE *(fdopen)(int fildes, const char *type);
int (feof)(FILE *stream);
int (ferror)(FILE *stream);
int (fflush)(FILE *stream);
int (fgetc)(FILE *stream);
int (fgetpos)(FILE *stream, fpos_t *pos);
char *(fgets)(char *s, int n, FILE *stream);
int (fileno)(FILE *stream);
double (floor)(double x);
double (fmod)(double x, double y);
FILE *(fopen)(const char *filename, const char *mode);
pid_t (fork)(void);
long (fpathconf)(int fildes, int name);
/* PRINTFLIKE2 */
int (fprintf)(FILE *stream, const char *format, ...);
int (fputc)(int c, FILE *stream);
int (fputs)(const char *s, FILE *stream);
size_t (fread)(void *ptr, size_t size, size_t nmemb, FILE *stream);
void (free)(void *ptr);
FILE *(freopen)(const char *filename, const char *mode, FILE *stream);
double (frepx)(double value, int *exp);
/* SCANFLIKE2 */
int (fscanf)(FILE *stream, const char *format, ...);
int (fseek)(FILE *stream, long int offset, int whence);
int (fsetpos)(FILE *stream, const fpos_t *pos);
int (fstat)(int fildes, struct stat *buf);
long (ftell)(FILE *stream);
size_t (fwrite)(const void *ptr, size_t size, size_t nmemb, FILE *stream);
int (getc)(FILE *stream);
int (getchar)(void);
char *(getcwd)(char *buf, size_t size);
gid_t (getegid)(void);
char *(getenv)(const char *name);
uid_t (geteuid)(void);
gid_t (getgid)(void);
struct group *(getgrgid)(gid_t gid);
struct group *(getgrnam)(const char *name);
int (getgroups)(int gidsetsize, gid_t grouplist[]);
char *(getlogin)(void);
pid_t (getpgrp)(void);
pid_t (getpid)(void);
pid_t (getppid)(void);
struct passwd *(getpwnam)(const char *name);
struct passwd *(getpwuid)(uid_t uid);
char *(gets)(char *s);
uid_t (getuid)(void);
struct tm *(gmtime)(const time_t *timer);
int (isalnum)(int c);
int (isalpha)(int c);
int (isatty)(int fildes);
int (iscntrl)(int c);
int (isdigit)(int c);
int (isgraph)(int c);
int (islower)(int c);
int (isprint)(int c);
int (ispunct)(int c);
int (isspace)(int c);
int (isupper)(int c);
int (isxdigit)(int c);
int (kill)(pid_t pid, int sig);
long (labs)(long j);
double (ldexp)(double x, int exp);
ldiv_t (ldiv)(long numer, long denom);
int (link)(const char *existing, const char *new);
struct lconv *(localeconv)(void);
struct tm *(localtime)(const time_t *timer);
double (log)(double x);
double (log10)(double x);
void (longjmp)(jmp_buf env, int val);
off_t (lseek)(int fildes, off_t offset, int whence);
void *(malloc)(size_t size);
int (mblen)(const char *s, size_t n);
size_t (mbstowcs)(wchar_t *pwcs, const char *s, size_t n);
int (mbtowc)(wchar_t *pwc, const char *s, size_t n);
void *(memchr)(const void *s, int c, size_t n);
int (memcmp)(const void *s1, const void *s2, size_t n);
void *(memcpy)(void *s1, const void *s2, size_t n);
void *(memmove)(void *s1, const void *s2, size_t n);
void *(memset)(void *s, int c, size_t n);
int (mkdir)(const char *path, mode_t mode);
int (mkfifo)(const char *path, mode_t mode);
time_t (mktime)(struct tm *timeptr);
double (modf)(double value, double *iptr);
int (open)(const char *path, int oflag, ...);
DIR *(opendir)(const char *dirname);
long (pathconf)(const char *path, int name);
int (pause)(void);
void (perror)(const char *s);
int (pipe)(int fildes[2]);
double (pow)(double x, double y);
/* PRINTFLIKE1 */
int (printf)(const char *format, ...);
int (putc)(int c, FILE *stream);
int (putchar)(int c);
int (puts)(const char *s);
void (qsort)(void *base, size_t nmemb, size_t size,
int (*compar)(const void *, const void *));
int (raise)(int sig);
int (rand)(void);
ssize_t (read)(int fildes, void *buf, size_t nbyte);
struct dirent *(readdir)(DIR *dirp);
void *(realloc)(void *ptr, size_t size);
int (remove)(const char *filename);
int (rename)(const char *old, const char *new);
void (rewind)(FILE *stream);
void (rewinddir)(DIR *dirp);
int (rmdir)(const char *path);
/* SCANFLIKE1 */
int (scanf)(const char *format, ...);
void (setbuf)(FILE *stream, char *buf);
int (setgid)(gid_t gid);
int (setjmp)(jmp_buf env);
char *(setlocale)(int category, const char *locale);
int (setpgid)(pid_t pid, pid_t pgid);
pid_t (setsid)(void);
int (setuid)(uid_t uid);
int (setvbuf)(FILE *stream, char *buf, int mode, size_t size);
int (sigaction)(int sig, const struct sigaction *act,
struct sigaction *oact);
int (sigaddset)(sigset_t *set, int signo);
int (sigdelset)(sigset_t *set, int signo);
int (sigemptyset)(sigset_t *set);
int (sigfillset)(sigset_t *set);
int (sigismember)(const sigset_t *set, int signo);
void (siglongjmp)(sigjmp_buf env, int val);
void (*(signal)(int sig, void (*func)(int)))(int);
int (sigpending)(sigset_t *set);
int (sigprocmask)(int how, const sigset_t *set, sigset_t *oset);
int (sigsetjmp)(sigjmp_buf env, int savemask);
int (sigsuspend)(const sigset_t *sigmask);
double (sin)(double x);
double (sinh)(double x);
unsigned (sleep)(unsigned seconds);
/* PRINTFLIKE2 */
int (sprintf)(char *s, const char *format, ...);
double (sqrt)(double x);
void (srand)(unsigned seed);
/* SCANFLIKE2 */
int (sscanf)(const char *s, const char *format, ...);
int (stat)(const char *path, struct stat *buf);
char *(strcat)(char *s1, const char *s2);
char *(strchr)(const char *s, int c);
int (strcmp)(const char *s1, const char *s2);
int (strcoll)(const char *s1, const char *s2);
char *(strcpy)(char *s1, const char *s2);
size_t (strcspn)(const char *s1, const char *s2);
char *(strerror)(int errnum);
size_t (strftime)(char *s, size_t maxsize, const char *format,
const struct tm *timeptr);
size_t (strlen)(const char *s);
char *(strncat)(char *s1, const char *s2, size_t n);
int (strncmp)(const char *s1, const char *s2, size_t n);
char *(strncpy)(char *s1, const char *s2, size_t n);
char *(strpbrk)(const char *s1, const char *s2);
char *(strrchr)(const char *s, int c);
size_t (strspn)(const char *s1, const char *s2);
char *(strstr)(const char *s1, const char *s2);
double (strtod)(const char *nptr, char **endptr);
char *(strtok)(char *s1, const char *s2);
long (strtol)(const char *nptr, char **endptr, int base);
unsigned long (strtoul)(const char *nptr, char **endptr, int base);
size_t (strxfrm)(char *s1, const char *s2, size_t n);
long (sysconf)(int name);
int (system)(const char *string);
double (tan)(double x);
double (tanh)(double x);
int (tcdrain)(int fildes);
int (tcflow)(int fildes, int action);
int (tcflush)(int fildes, int queue_selector);
int (tcgetattr)(int fildes, struct termios *tp);
pid_t (tcgetpgrp)(int fildes);
int (tcsendbreak)(int fildes, int duration);
int (tcsetattr)(int fildes, int options, const struct termios *tp);
int (tcsetpgrp)(int fildes, pid_t pgrpid);
time_t (time)(time_t *timer);
clock_t (times)(struct tms *buffer);
FILE *(tmpfile)(void);
char *(tmpnam)(char *s);
int (tolower)(int c);
int (toupper)(int c);
char *(ttyname)(int filedes);
void (tzset)(void);
mode_t (umask)(mode_t cmask);
int (uname)(struct utsname *name);
int (ungetc)(int c, FILE *stream);
int (unlink)(const char *path);
int (utime)(const char *path, const struct utimbuf *times);
int (vfprintf)(FILE *stream, const char *format, va_list arg);
int (vprintf)(const char *format, va_list arg);
int (vsprintf)(char *s, const char *format, va_list arg);
pid_t (wait)(int *statloc);
pid_t (waitpid)(pid_t pid, int *stat_loc, int options);
size_t (wcstombs)(char *s, const wchar_t *pwcs, size_t n);
int (wctomb)(char *s, wchar_t wchar);
ssize_t (write)(int fildes, const void *buf, size_t nbyte);

View File

@ -0,0 +1,252 @@
/* $NetBSD: llib-lstdc,v 1.3 1995/07/03 21:39:28 cgd Exp $ */
/*
* Copyright (c) 1994, 1995 Jochen Pohl
* All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Jochen Pohl for
* The NetBSD Project.
* 4. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/* LINTLIBRARY */
#define _ANSI_SOURCE
#include <assert.h>
#include <ctype.h>
#include <errno.h>
#include <locale.h>
#include <math.h>
#include <setjmp.h>
#include <signal.h>
#include <stdarg.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
/* PROTOLIB1 */
/*
* assert.h
*/
#ifdef __NetBSD__
void (__assert)(const char *expression, int line, const char *file);
#else
void (assert)(int expression);
#endif
/*
* ctype.h
*/
int (isalnum)(int c);
int (isalpha)(int c);
int (iscntrl)(int c);
int (isdigit)(int c);
int (isgraph)(int c);
int (islower)(int c);
int (isprint)(int c);
int (ispunct)(int c);
int (isspace)(int c);
int (isupper)(int c);
int (isxdigit)(int c);
int (tolower)(int c);
int (toupper)(int c);
/*
* errno.h
*/
int (errno);
/*
* locale.h
*/
char *(setlocale)(int category, const char *locale);
struct lconv *(localeconv)(void);
/*
* math.h
*/
double (acos)(double x);
double (asin)(double x);
double (atan)(double x);
double (atan2)(double y, double x);
double (cos)(double x);
double (sin)(double x);
double (tan)(double x);
double (cosh)(double x);
double (sinh)(double x);
double (tanh)(double x);
double (exp)(double x);
double (frexp)(double value, int *exp);
double (ldexp)(double x, int exp);
double (log)(double x);
double (log10)(double x);
double (modf)(double value, double *iptr);
double (pow)(double x, double y);
double (sqrt)(double x);
double (ceil)(double x);
double (fabs)(double x);
double (floor)(double x);
double (fmod)(double x, double y);
/*
* setjmp.h
*/
int (setjmp)(jmp_buf env);
void (longjmp)(jmp_buf env, int val);
/*
* signal.h
*/
void (*(signal)(int sig, void (*func)(int)))(int);
int (raise)(int sig);
/*
* stdio.h
*/
int (remove)(const char *filename);
int (rename)(const char *old, const char *new);
FILE *(tmpfile)(void);
char *(tmpnam)(char *s);
int (fclose)(FILE *stream);
int (fflush)(FILE *stream);
FILE *(fopen)(const char *filename, const char *mode);
FILE *(freopen)(const char *filename, const char *mode, FILE *stream);
void (setbuf)(FILE *stream, char *buf);
int (setvbuf)(FILE *stream, char *buf, int mode, size_t size);
/* PRINTFLIKE2 */
int (fprintf)(FILE *stream, const char *format, ...);
/* SCANFLIKE2 */
int (fscanf)(FILE *stream, const char *format, ...);
/* PRINTFLIKE1 */
int (printf)(const char *format, ...);
/* SCANFLIKE1 */
int (scanf)(const char *format, ...);
/* PRINTFLIKE2 */
int (sprintf)(char *s, const char *format, ...);
/* SCANFLIKE2 */
int (sscanf)(const char *s, const char *format, ...);
int (vfprintf)(FILE *stream, const char *format, va_list arg);
int (vprintf)(const char *format, va_list arg);
int (vsprintf)(char *s, const char *format, va_list arg);
int (fgetc)(FILE *stream);
char *(fgets)(char *s, int n, FILE *stream);
int (fputc)(int c, FILE *stream);
int (fputs)(const char *s, FILE *stream);
int (getc)(FILE *stream);
int (getchar)(void);
char *(gets)(char *s);
int (putc)(int c, FILE *stream);
int (putchar)(int c);
int (puts)(const char *s);
int (ungetc)(int c, FILE *stream);
size_t (fread)(void *ptr, size_t size, size_t nmemb, FILE *stream);
size_t (fwrite)(const void *ptr, size_t size, size_t nmemb, FILE *stream);
int (fgetpos)(FILE *stream, fpos_t *pos);
int (fseek)(FILE *stream, long offset, int whence);
int (fsetpos)(FILE *stream, const fpos_t *pos);
long (ftell)(FILE *stream);
void (rewind)(FILE *stream);
void (clearerr)(FILE *stream);
int (feof)(FILE *stream);
int (ferror)(FILE *stream);
void (perror)(const char *s);
/*
* stdlib.h
*/
double (atof)(const char *nptr);
int (atoi)(const char *nptr);
long (atol)(const char *nptr);
double (strtod)(const char *nptr, char **endptr);
long (strtol)(const char *nptr, char **endptr, int base);
unsigned long (strtoul)(const char *nptr, char **endptr, int base);
int (rand)(void);
void (srand)(unsigned seed);
void *(calloc)(size_t nmemb, size_t size);
void (free)(void *ptr);
void *(malloc)(size_t size);
void *(realloc)(void *ptr, size_t size);
void (abort)(void);
int (atexit)(void (*func)(void));
void (exit)(int status);
char *(getenv)(const char *name);
int (system)(const char *string);
void *(bsearch)(const void *key, const void *base, size_t nmemb,
size_t size, int (*compar)(const void *, const void *));
void (qsort)(void *base, size_t nmemb, size_t size,
int (*compar)(const void *, const void *));
int (abs)(int j);
div_t (div)(int numer, int denom);
long (labs)(long j);
ldiv_t (ldiv)(long numer, long denom);
int (mblen)(const char *s, size_t n);
int (mbtowc)(wchar_t *PWC, const char *s, size_t n);
int (wctomb)(char *s, wchar_t wchar);
size_t (mbstowcs)(wchar_t *pwcs, const char *s, size_t n);
size_t (wcstombs)(char *s, const wchar_t *pwcs, size_t n);
/*
* string.h
*/
void *(memcpy)(void *s1, const void *s2, size_t n);
void *(memmove)(void *s1, const void *s2, size_t n);
char *(strcpy)(char *s1, const char *s2);
char *(strncpy)(char *s1, const char *s2, size_t n);
char *(strcat)(char *s1, const char *s2);
char *(strncat)(char *s1, const char *s2, size_t n);
int (memcmp)(const void *s1, const void *s2, size_t n);
int (strcmp)(const char *s1, const char *s2);
int (strcoll)(const char *s1, const char *s2);
int (strncmp)(const char *s1, const char *s2, size_t n);
size_t (strxfrm)(char *s1, const char *s2, size_t n);
void *(memchr)(const void *s, int c, size_t n);
char *(strchr)(const char *s, int c);
size_t (strcspn)(const char *s1, const char *s2);
char *(strpbrk)(const char *s1, const char *s2);
char *(strrchr)(const char *s1, int c);
size_t (strspn)(const char *s1, const char *s2);
char *(strstr)(const char *s1, const char *s2);
char *(strtok)(char *s1, const char *s2);
void *(memset)(void *s, int c, size_t n);
char *(strerror)(int errnom);
size_t (strlen)(const char *s);
/*
* time.h
*/
clock_t (clock)(void);
double (difftime)(time_t time1, time_t time2);
time_t (mktime)(struct tm *timeptr);
time_t (time)(time_t *timer);
char *(asctime)(const struct tm *timeptr);
char *(ctime)(const time_t *timer);
struct tm *(gmtime)(const time_t *timer);
struct tm *(localtime)(const time_t *timer);
size_t (strftime)(char *s, size_t maxsize, const char *format,
const struct tm *timeptr);

View File

@ -0,0 +1,17 @@
# $NetBSD: Makefile,v 1.2 1995/07/03 21:25:14 cgd Exp $
.PATH: ${.CURDIR}/../lint1
PROG= xlint
SRCS= xlint.c mem.c
MAN= lint.1
CFLAGS+=-I${.CURDIR}/../lint1
realinstall:
install ${COPY} ${STRIP} -o ${BINOWN} -g ${BINGRP} -m ${BINMODE} \
${PROG} ${DESTDIR}${BINDIR}/lint
.include "${.CURDIR}/../../Makefile.inc"
.include <bsd.prog.mk>

509
usr.bin/xlint/xlint/lint.1 Normal file
View File

@ -0,0 +1,509 @@
.\" $NetBSD: lint.1,v 1.3 1995/10/23 13:45:31 jpo Exp $
.\"
.\" Copyright (c) 1994, 1995 Jochen Pohl
.\" All Rights Reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
.\" 1. Redistributions of source code must retain the above copyright
.\" notice, this list of conditions and the following disclaimer.
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in the
.\" documentation and/or other materials provided with the distribution.
.\" 3. All advertising materials mentioning features or use of this software
.\" must display the following acknowledgement:
.\" This product includes software developed by Jochen Pohl for
.\" The NetBSD Project.
.\" 4. The name of the author may not be used to endorse or promote products
.\" derived from this software without specific prior written permission.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
.\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.\"
.Dd August 28, 1994
.Dt LINT 1
.Os NetBSD
.Sh NAME
.Nm lint
.Nd a C program verifier.
.Sh SYNOPSIS
.Nm lint
.Op Fl abceghprvxzHFV
.Op Fl s Ns | Ns Fl t
.Op Fl i Ns | Ns Fl nu
.Op Fl D Ns Ar name Ns Op =def
.Op Fl U Ns Ar name
.Op Fl I Ns Ar directory
.Op Fl L Ns Ar directory
.Op Fl l Ns Ar library
.Op Fl o Ns Ar outputfile
.Ar
.Nm lint
.Op Fl abceghprvzHFV
.Op Fl s Ns | Ns Fl t
.Fl C Ns Ar library
.Op Fl D Ns Ar name Ns Op =def
.Op Fl I Ns Ar directory
.Op Fl U Ns Ar name
.Ar
.Sh DESCRIPTION
.Nm
attempts to detect features of the named C program files
that are likely to be bugs, to be non-portable, or to be
wasteful. It also performs stricter type checking then does
the C compiler.
.Nm
runs the C preprocessor as its first phase, with the
preprocessor symbol
.Sy lint
defined to allow certain questionable code to be altered
or skipped by
.Nm lint .
Therefore, this symbol should be thought of as a reserved
word for all code that is to be checked by
.Nm lint .
.Pp
Among the possible problems that are currently noted are
unreachable statements, loops not entered at the top,
variables declared and not used, and logical expressions
with constant values. Function calls are checked for
inconsistencies, such as calls to functions that return
values in some places and not in others, functions called
with varying numbers of arguments, function calls that
pass arguments of a type other than the type the function
expects to receive, functions whose values are not used,
and calls to functions not returning values that use
the non-existent return value of the function.
.Pp
Filename arguments ending with
.Pa \&.c
are taken to be C source files. Filename arguments with
names ending with
.Pa \&.ln
are taken to be the result of an earlier invocation of
.Nm lint ,
with either the
.Fl i ,
.Fl o
or
.Fl C
option in effect. The
.Pa \&.ln
files are analogous to the
.Pa \&.o
(object) files produced by
.Xr cc 1
from
.Pa \&.c
files.
.Nm
also accepts special libraries specified with the
.Fl l
option, which contain definitions of library routines and
variables.
.Pp
.Nm
takes all the
.Pa \&.c , \&.ln ,
and
.Pa llib-l Ns Ar library Ns Pa \&.ln
(lint library) files and processes them in command-line order.
By default,
.Nm
appends the standard C lint library
.Pq Pa llib-lc.ln
to the end of the list of files. When the
.Fl i
option is used, the
.Pa \&.ln
files are ignored.
Also, when the
.Fl o
or
.Fl i
options are used, the
.Pa llib-l Ns Ar library Ns Pa \&.ln
files are ignored. When the
.Fl i
option is
.Em omitted
the second pass of
.Nm
checks this list of files for mutual compatibility. At this point,
if a complaint stems not from a given source file, but from one of
its included files, the source filename will be printed followed by
a question mark.
.Pp
.Sy Options
.Bl -tag -width Fl
.It Fl a
Report assignments of
.Sy long
values to variables that are not
.Sy long .
.It Fl aa
Additional to
.Fl a ,
report
.Em all
assignments of integer values to other integer values which
cause implicit narrowing conversion.
.It Fl b
Report
.Sy break
statements that cannot be reached. This is not the default
because, unfortunately, most
.Xr lex 1
and many
.Xr yacc 1
outputs produce many such complaints.
.It Fl c
Complain about casts which have questionable portability.
.It Fl e
Complain about unusual operations on
.Sy enum Ns -Types
and combinations of
.Sy enum Ns -
and
.Sy integer Ns -Types.
.It Fl g
Don't print warnings for some extensions of
.Xr gcc 1
to the C language. Currently these are nonconstant initializers in
automatic aggregate initializations, arithmetic on pointer to void,
zero sized structures, subscripting of non-lvalue arrays, prototypes
overriding old style function declarations and long long
integer types. The
.Fl g
flag also turns on the keywords
.Sy asm
and
.Sy inline
(alternate keywords with leading underscores for both
.Sy asm
and
.Sy inline
are always available).
.It Fl h
Apply a number of heuristic tests to attempt to intuit
bugs, improve style, and reduce waste.
.It Fl i
Produce a
.Pa \&.ln
file for every
.Pa \&.c
file on the command line. These
.Pa \&.ln
files are the product of
.Nm lint Ns 's
first pass only, and are not checked for compatibility
between functions.
.It Fl n
Do not check compatibility against the standard library.
.It Fl p
Attempt to check portability of code to other dialects of C.
.It Fl r
In case of redeclarations report the position of the
previous declaration.
.It Fl s
Strict ANSI C mode. Issue warnings and errors required by ANSI C.
Also do not produce warnings for constructs which behave
differently in traditional C and ANSI C. With the
.Fl s
flag,
.Li __STRICT_ANSI__
is a predefined preprocessor macro.
.It Fl t
Traditional C mode.
.Li __STDC__
is not predefined in this mode. Warnings are printed for constructs
not allowed in traditional C. Warnings for constructs which behave
differently in traditional C and ANSI C are suppressed. Preprocessor
macros describing the machine type (e.g.
.Li sun3 Ns )
and machine architecture (e.g.
.Li m68k Ns )
are defined without leading and trailing underscores. The keywords
.Sy const Ns ,
.Sy volatile
and
.Sy signed
are not available in traditional C mode (although the alternate
keywords with leading underscores still are).
.It Fl u
Do not complain about functions and external variables used
and not defined, or defined and not used (this is suitable
for running
.Nm
on a subset of files comprising part of a larger program).
.It Fl v
Suppress complaints about unused arguments in functions.
.It Fl x
Report variables refferd to by
.Sy extern
declarations, but never used.
.It Fl z
Do not complain about structures that are never defined
(for example, using a structure pointer without knowing
its contents).
.It Fl C Ns Ar library
Create a
.Nm
library with the name
.Pa llib-l Ns Ar library Ns Pa .ln .
This library is built from all
.Pa \&.c
and
.Pa \&.ln
input files. After all global definitions of functions and
variables in these files are written to the newly created library,
.Nm
checks all input files, including libraries specified with the
.Fl l
option, for mutual compatibility.
.It Fl D Ns Ar name Ns Op =def
Define
.Ar name
for
.Xr cpp 1 ,
as if by a
.Li #define
directive. If no definition is given,
.Ar name
is defined as 1.
.It Fl I Ns Ar directory
Add
.Ar directory
to the list of directories in which to search for include files.
.It Fl l Ns Ar library
Include the lint library
.Pa llib-l Ns Ar library Ns Pa \&.ln .
.It Fl L Ns Ar directory
Search for lint libraries in
.Ar directory
and
.Ar directory Ns Pa /lint
before searching the standard place.
.It Fl F
Print pathnames of files.
.Nm
normally prints the filename without the path.
.It Fl H
If a complaint stems from an included file
.Nm
prints the name of the included file instead of the source file name
followed by a question mark.
.It Fl o Ns Ar outputfile
Name the output file
.Ar outputfile .
The output file produced is the input that is given to
.Nm lint Ns 's
second pass. The
.Fl o
option simply saves this file in the named output file. If the
.Fl i
option is also used the files are not checked for compatibility.
To produce a
.Pa llib-l Ns Ar library Ns Pa \&.ln
without extraneous messages, use of the
.Fl u
option is suggested. The
.Fl v
option is useful if the source file(s) for the lint library
are just external interfaces.
.It Fl U Ns Ar name
Remove any initial definition of
.Ar name
for the preprocessor.
.It Fl V
Print the command lines constructed by the controller program to
run the C preprocessor and
.Nm lint Ns 's
first and second pass.
.El
.Pp
.Sy Input Grammar
.Pp
.Nm lint Ns 's
first pass reads standard C source files.
.Nm
recognizes the following C comments as commands.
.Bl -tag -width Fl
.It Li /* ARGSUSED Ns Ar n Li */
makes
.Nm
check only the first
.Ar n
arguments for usage; a missing
.Ar n
is taken to be 0 (this option acts like the
.Fl v
option for the next function).
.It Li /* CONSTCOND */ No or Xo
.Li /* CONSTANTCOND */ No or
.Li /* CONSTANTCONDITION */
.Xc
suppress complaints about constant operands for the next expression.
.It Li /*\ FALLTHRU\ */ No or Xo
.Li /* FALLTHROUGH */
.Xc
suppress complaints about fall through to a
.Sy case
or
.Sy default
labelled statement. This directive should be placed immediately
preceding the label.
.It Li /* LINTLIBRARY */
At the beginning of a file, mark all functions and variables defined
in this file as
.Em used .
Also shut off complaints about unused function arguments.
.It Li /* LINTED Xo
.Op Ar comment
.Li */ No or
.Li /* NOSTRICT
.Op Ar comment
.Li */
.Xc
Suppresses any intra-file warning except those dealing with
unused variables or functions. This directive should be placed
on the line immediately preceding where the lint warning occured.
.It Li /* LONGLONG */
Suppress complaints about use of long long integer types.
.It Li /* NOTREACHED */
At appropriate points, inhibit complaints about unreachable code.
(This comment is typically placed just after calls to functions
like
.Xr exit 2 ).
.It Li /* PRINTFLIKE Ns Ar n Li */
makes
.Nm
check the first
.Pq Ar n Ns No -1
arguments as usual. The
.Ar n Ns No -th
argument is interpreted as a
.Sy printf
format string that is used to check the remaining arguments.
.It Li /* PROTOLIB Ns Ar n Li */
causes
.Nm
to treat function declaration prototypes as function definitions
if
.Ar n
is non-zero. This directive can only be used in conjunction with
the
.Li /* LINTLIBRARY */
directive. If
.Ar n
is zero, function prototypes will be treated normally.
.It Li /* SCANFLIKE Ns Ar n Li */
makes
.Nm
check the first
.Pq Ar n Ns No -1
arguments as usual. The
.Ar n Ns No -th
argument is interpreted as a
.Sy scanf
format string that is used to check the remaining arguments.
.It Li /* VARARGS Ns Ar n Li */
Suppress the usual checking for variable numbers of arguments in
the following function declaration. The data types of the first
.Ar n
arguments are checked; a missing
.Ar n
is taken to be 0.
.El
.Pp
The behavior of the
.Fl i
and the
.Fl o
options allows for incremental use of
.Nm
on a set of C source files. Generally, one invokes
.Nm
once for each source file with the
.Fl i
option. Each of these invocations produces a
.Pa \&.ln
file that corresponds to the
.Pa \&.c
file, and prints all messages that are about just that
source file. After all the source files have been separetely
run through
.Nm lint ,
it is invoked once more (without the
.Fl i
option), listing all the
.Pa \&.ln
files with the needed
.Fl l Ns Ar library
options. this will print all the inter-file inconsistencies. This
scheme works well with
.Xr make 1 ;
it allows
.Xr make 1
to be used to
.Nm
only the source files that have been modified since the last
time the set of source files were
.Nm lint Ns No ed .
.Sh ENVIRONMENT
.Bl -tag -width Fl
.It Ev LIBDIR
the directory where the lint libraries specified by the
.Fl l Ns Ar library
option must exist. If this environment variable is undefined,
then the default path
.Pa /usr/libdata/lint
will be used to search for the libraries.
.It Ev TMPDIR
usually the path for temporary files can be redefined by setting
this environment variable.
.El
.Sh FILES
.Bl -tag -width /usr/libdata/lint/llib-lc.ln -compact
.It Pa /usr/libexec/lint Ns Bq 12
programs
.It Pa /usr/libdata/lint/llib-l*.ln
various prebuilt lint libraries
.It Pa /tmp/lint*
temporaries
.Sh SEE ALSO
.Xr cc 1 ,
.Xr cpp 1 ,
.Xr make 1
.Sh AUTHORS
Jochen Pohl
.Sh BUGS
The routines
.Xr exit 2 ,
.Xr longjmp 3
and other functions that do not return are not understood; this
causes various incorrect diagnostics.
.Pp
Static functions which are used only before their first
extern declaration are reported as unused.
.Pp
Libraries created by the
.Fl o
option will, when used in later
.Nm
runs, cause certain errors that were reported when the libraries
were created to be reported again, and cause line numbers and file
names from the original source used to create those libraries
to be reported in error messages. For these reasons, it is recommended
to use the
.Fl C
option to create lint libraries.

View File

@ -0,0 +1,38 @@
/* $NetBSD: pathnames.h,v 1.2 1995/07/03 21:25:20 cgd Exp $ */
/*
* Copyright (c) 1994, 1995 Jochen Pohl
* All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Jochen Pohl for
* The NetBSD Project.
* 4. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/* directory where lint1 and lint2 reside */
#define PATH_LIBEXEC "/usr/libexec"
/* default library search path */
#define PATH_LINTLIB "/usr/libdata/lint"

761
usr.bin/xlint/xlint/xlint.c Normal file
View File

@ -0,0 +1,761 @@
/* $NetBSD: xlint.c,v 1.3 1995/10/23 14:29:30 jpo Exp $ */
/*
* Copyright (c) 1994, 1995 Jochen Pohl
* All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Jochen Pohl for
* The NetBSD Project.
* 4. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef lint
static char rcsid[] = "$NetBSD: xlint.c,v 1.3 1995/10/23 14:29:30 jpo Exp $";
#endif
#include <sys/param.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <sys/utsname.h>
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <err.h>
#include <errno.h>
#include <paths.h>
#include "lint.h"
#include "pathnames.h"
/* directory for temporary files */
static const char *tmpdir;
/* path name for cpp output */
static char *cppout;
/* files created by 1st pass */
static char **p1out;
/* input files for 2nd pass (without libraries) */
static char **p2in;
/* library which will be created by 2nd pass */
static char *p2out;
/* flags always passed to cpp */
static char **cppflags;
/* flags for cpp, controled by sflag/tflag */
static char **lcppflgs;
/* flags for lint1 */
static char **l1flags;
/* flags for lint2 */
static char **l2flags;
/* libraries for lint2 */
static char **l2libs;
/* default libraries */
static char **deflibs;
/* additional libraries */
static char **libs;
/* search path for libraries */
static char **libsrchpath;
/* flags */
static int iflag, oflag, Cflag, sflag, tflag, Fflag;
/* print the commands executed to run the stages of compilation */
static int Vflag;
/* filename for oflag */
static char *outputfn;
/* reset after first .c source has been processed */
static int first = 1;
/*
* name of a file which is currently written by a child and should
* be removed after abnormal termination of the child
*/
static const char *currfn;
static void appstrg __P((char ***, char *));
static void appcstrg __P((char ***, const char *));
static void applst __P((char ***, char *const *));
static void freelst __P((char ***));
static char *concat2 __P((const char *, const char *));
static char *concat3 __P((const char *, const char *, const char *));
static void terminate __P((int));
static const char *basename __P((const char *, int));
static void appdef __P((char ***, const char *));
static void usage __P((void));
static void fname __P((const char *, int));
static void runchild __P((const char *, char *const *, const char *));
static void findlibs __P((char *const *));
static int rdok __P((const char *));
static void lint2 __P((void));
static void cat __P((char *const *, const char *));
/*
* Some functions to deal with lists of strings.
* Take care that we get no surprises in case of asyncron signals.
*/
static void
appstrg(lstp, s)
char ***lstp, *s;
{
char **lst, **olst;
int i;
olst = *lstp;
for (i = 0; olst[i] != NULL; i++) ;
lst = xmalloc((i + 2) * sizeof (char *));
(void)memcpy(lst, olst, i * sizeof (char *));
lst[i] = s;
lst[i + 1] = NULL;
*lstp = lst;
}
static void
appcstrg(lstp, s)
char ***lstp;
const char *s;
{
appstrg(lstp, xstrdup(s));
}
static void
applst(destp, src)
char ***destp;
char *const *src;
{
int i, k;
char **dest, **odest;
odest = *destp;
for (i = 0; odest[i] != NULL; i++) ;
for (k = 0; src[k] != NULL; k++) ;
dest = xmalloc((i + k + 1) * sizeof (char *));
(void)memcpy(dest, odest, i * sizeof (char *));
for (k = 0; src[k] != NULL; k++)
dest[i + k] = xstrdup(src[k]);
dest[i + k] = NULL;
*destp = dest;
free(odest);
}
static void
freelst(lstp)
char ***lstp;
{
char *s;
int i;
for (i = 0; (*lstp)[i] != NULL; i++) ;
while (i-- > 0) {
s = (*lstp)[i];
(*lstp)[i] = NULL;
free(s);
}
}
static char *
concat2(s1, s2)
const char *s1, *s2;
{
char *s;
s = xmalloc(strlen(s1) + strlen(s2) + 1);
(void)strcpy(s, s1);
(void)strcat(s, s2);
return (s);
}
static char *
concat3(s1, s2, s3)
const char *s1, *s2, *s3;
{
char *s;
s = xmalloc(strlen(s1) + strlen(s2) + strlen(s3) + 1);
(void)strcpy(s, s1);
(void)strcat(s, s2);
(void)strcat(s, s3);
return (s);
}
/*
* Clean up after a signal.
*/
static void
terminate(signo)
int signo;
{
int i;
if (cppout != NULL)
(void)remove(cppout);
if (p1out != NULL) {
for (i = 0; p1out[i] != NULL; i++)
(void)remove(p1out[i]);
}
if (p2out != NULL)
(void)remove(p2out);
if (currfn != NULL)
(void)remove(currfn);
exit(signo != 0 ? 1 : 0);
}
/*
* Returns a pointer to the last component of strg after delim.
* Returns strg if the string does not contain delim.
*/
static const char *
basename(strg, delim)
const char *strg;
int delim;
{
const char *cp, *cp1, *cp2;
cp = cp1 = cp2 = strg;
while (*cp != '\0') {
if (*cp++ == delim) {
cp2 = cp1;
cp1 = cp;
}
}
return (*cp1 == '\0' ? cp2 : cp1);
}
static void
appdef(lstp, def)
char ***lstp;
const char *def;
{
appstrg(lstp, concat2("-D__", def));
appstrg(lstp, concat3("-D__", def, "__"));
}
static void
usage()
{
(void)printf("lint [-abceghprvxzHF] [-s|-t] [-i|-nu] [-Dname[=def]] [-Uname]\n");
(void)printf(" [-Idirectory] [-Ldirectory] [-llibrary] [-ooutputfile] file ...\n");
(void)printf("\n");
(void)printf("lint [-abceghprvzHF] [-s|-t] -Clibrary [-Dname[=def]]\n");
(void)printf(" [-Idirectory] [-Uname] file ...\n");
terminate(-1);
}
int
main(argc, argv)
int argc;
char *argv[];
{
int c;
char flgbuf[3], *tmp, *s;
size_t len;
struct utsname un;
if ((tmp = getenv("TMPDIR")) == NULL || (len = strlen(tmp)) == 0) {
tmpdir = xstrdup(_PATH_TMP);
} else {
s = xmalloc(len + 2);
(void)sprintf(s, "%s%s", tmp, tmp[len - 1] == '/' ? "" : "/");
tmpdir = s;
}
cppout = xmalloc(strlen(tmpdir) + sizeof ("lint0.XXXXXX"));
(void)sprintf(cppout, "%slint0.XXXXXX", tmpdir);
if (mktemp(cppout) == NULL) {
warn("can't make temp");
terminate(-1);
}
p1out = xcalloc(1, sizeof (char *));
p2in = xcalloc(1, sizeof (char *));
cppflags = xcalloc(1, sizeof (char *));
lcppflgs = xcalloc(1, sizeof (char *));
l1flags = xcalloc(1, sizeof (char *));
l2flags = xcalloc(1, sizeof (char *));
l2libs = xcalloc(1, sizeof (char *));
deflibs = xcalloc(1, sizeof (char *));
libs = xcalloc(1, sizeof (char *));
libsrchpath = xcalloc(1, sizeof (char *));
appcstrg(&cppflags, "-lang-c");
appcstrg(&cppflags, "-undef");
appcstrg(&cppflags, "-$");
appcstrg(&cppflags, "-C");
appcstrg(&cppflags, "-Wcomment");
appcstrg(&cppflags, "-D__NetBSD__");
appcstrg(&cppflags, "-Dlint"); /* XXX don't def. with -s */
appdef(&cppflags, "lint");
appdef(&cppflags, "unix");
appcstrg(&lcppflgs, "-Wtraditional");
if (uname(&un) == -1)
err(1, "uname");
appdef(&cppflags, un.machine);
appstrg(&lcppflgs, concat2("-D", un.machine));
#ifdef MACHINE_ARCH
if (strcmp(un.machine, MACHINE_ARCH) != 0) {
appdef(&cppflags, MACHINE_ARCH);
appstrg(&lcppflgs, concat2("-D", MACHINE_ARCH));
}
#endif
appcstrg(&deflibs, "c");
if (signal(SIGHUP, terminate) == SIG_IGN)
(void)signal(SIGHUP, SIG_IGN);
(void)signal(SIGINT, terminate);
(void)signal(SIGQUIT, terminate);
(void)signal(SIGTERM, terminate);
while (argc > optind) {
argc -= optind;
argv += optind;
optind = 0;
c = getopt(argc, argv, "abceghil:no:prstuvxzC:D:FHI:L:U:V");
switch (c) {
case 'a':
case 'b':
case 'c':
case 'e':
case 'g':
case 'r':
case 'v':
case 'z':
(void)sprintf(flgbuf, "-%c", c);
appcstrg(&l1flags, flgbuf);
break;
case 'F':
Fflag = 1;
/* FALLTHROUGH */
case 'u':
case 'h':
(void)sprintf(flgbuf, "-%c", c);
appcstrg(&l1flags, flgbuf);
appcstrg(&l2flags, flgbuf);
break;
case 'i':
if (Cflag)
usage();
iflag = 1;
break;
case 'n':
freelst(&deflibs);
break;
case 'p':
appcstrg(&l1flags, "-p");
appcstrg(&l2flags, "-p");
if (*deflibs != NULL) {
freelst(&deflibs);
appcstrg(&deflibs, "c");
}
break;
case 's':
if (tflag)
usage();
freelst(&lcppflgs);
appcstrg(&lcppflgs, "-trigraphs");
appcstrg(&lcppflgs, "-Wtrigraphs");
appcstrg(&lcppflgs, "-pedantic");
appcstrg(&lcppflgs, "-D__STRICT_ANSI__");
appcstrg(&l1flags, "-s");
appcstrg(&l2flags, "-s");
sflag = 1;
break;
case 't':
if (sflag)
usage();
freelst(&lcppflgs);
appcstrg(&lcppflgs, "-traditional");
appstrg(&lcppflgs, concat2("-D", MACHINE));
appstrg(&lcppflgs, concat2("-D", MACHINE_ARCH));
appcstrg(&l1flags, "-t");
appcstrg(&l2flags, "-t");
tflag = 1;
break;
case 'x':
appcstrg(&l2flags, "-x");
break;
case 'C':
if (Cflag || oflag || iflag)
usage();
Cflag = 1;
appstrg(&l2flags, concat2("-C", optarg));
p2out = xmalloc(sizeof ("llib-l.ln") + strlen(optarg));
(void)sprintf(p2out, "llib-l%s.ln", optarg);
freelst(&deflibs);
break;
case 'D':
case 'I':
case 'U':
(void)sprintf(flgbuf, "-%c", c);
appstrg(&cppflags, concat2(flgbuf, optarg));
break;
case 'l':
appcstrg(&libs, optarg);
break;
case 'o':
if (Cflag || oflag)
usage();
oflag = 1;
outputfn = xstrdup(optarg);
break;
case 'L':
appcstrg(&libsrchpath, optarg);
break;
case 'H':
appcstrg(&l2flags, "-H");
break;
case 'V':
Vflag = 1;
break;
case '?':
usage();
/* NOTREACHED */
case -1:
/* filename */
fname(argv[0], argc == 1);
first = 0;
optind = 1;
}
}
if (first)
usage();
if (iflag)
terminate(0);
if (!oflag) {
if ((s = getenv("LIBDIR")) == NULL || strlen(s) == 0)
s = PATH_LINTLIB;
appcstrg(&libsrchpath, s);
findlibs(libs);
findlibs(deflibs);
}
(void)printf("Lint pass2:\n");
lint2();
if (oflag)
cat(p2in, outputfn);
if (Cflag)
p2out = NULL;
terminate(0);
/* NOTREACHED */
}
/*
* Read a file name from the command line
* and pass it through lint1 if it is a C source.
*/
static void
fname(name, last)
const char *name;
int last;
{
const char *bn, *suff;
char **args, *ofn, *path;
size_t len;
bn = basename(name, '/');
suff = basename(bn, '.');
if (strcmp(suff, "ln") == 0) {
/* only for lint2 */
if (!iflag)
appcstrg(&p2in, name);
return;
}
if (strcmp(suff, "c") != 0 &&
(strncmp(bn, "llib-l", 6) != 0 || bn != suff)) {
warnx("unknown file type: %s\n", name);
return;
}
if (!iflag || !first || !last)
(void)printf("%s:\n", Fflag ? name : bn);
/* build the name of the output file of lint1 */
if (oflag) {
ofn = outputfn;
outputfn = NULL;
oflag = 0;
} else if (iflag) {
ofn = xmalloc(strlen(bn) + (bn == suff ? 4 : 2));
len = bn == suff ? strlen(bn) : (suff - 1) - bn;
(void)sprintf(ofn, "%.*s", (int)len, bn);
(void)strcat(ofn, ".ln");
} else {
ofn = xmalloc(strlen(tmpdir) + sizeof ("lint1.XXXXXX"));
(void)sprintf(ofn, "%slint1.XXXXXX", tmpdir);
if (mktemp(ofn) == NULL) {
warn("can't make temp");
terminate(-1);
}
}
if (!iflag)
appcstrg(&p1out, ofn);
args = xcalloc(1, sizeof (char *));
/* run cpp */
path = xmalloc(strlen(PATH_LIBEXEC) + sizeof ("/cpp"));
(void)sprintf(path, "%s/cpp", PATH_LIBEXEC);
appcstrg(&args, path);
applst(&args, cppflags);
applst(&args, lcppflgs);
appcstrg(&args, name);
appcstrg(&args, cppout);
runchild(path, args, cppout);
free(path);
freelst(&args);
/* run lint1 */
path = xmalloc(strlen(PATH_LIBEXEC) + sizeof ("/lint1"));
(void)sprintf(path, "%s/lint1", PATH_LIBEXEC);
appcstrg(&args, path);
applst(&args, l1flags);
appcstrg(&args, cppout);
appcstrg(&args, ofn);
runchild(path, args, ofn);
free(path);
freelst(&args);
appcstrg(&p2in, ofn);
free(ofn);
free(args);
}
static void
runchild(path, args, crfn)
const char *path, *crfn;
char *const *args;
{
int status, rv, signo, i;
if (Vflag) {
for (i = 0; args[i] != NULL; i++)
(void)printf("%s ", args[i]);
(void)printf("\n");
}
currfn = crfn;
(void)fflush(stdout);
switch (fork()) {
case -1:
warn("cannot fork");
terminate(-1);
/* NOTREACHED */
default:
/* parent */
break;
case 0:
/* child */
(void)execv(path, args);
warn("cannot exec %s", path);
exit(1);
/* NOTREACHED */
}
while ((rv = wait(&status)) == -1 && errno == EINTR) ;
if (rv == -1) {
warn("wait");
terminate(-1);
}
if (WIFSIGNALED(status)) {
signo = WTERMSIG(status);
warnx("%s got SIG%s", path, sys_signame[signo]);
terminate(-1);
}
if (WEXITSTATUS(status) != 0)
terminate(-1);
currfn = NULL;
}
static void
findlibs(liblst)
char *const *liblst;
{
int i, k;
const char *lib, *path;
char *lfn;
size_t len;
lfn = NULL;
for (i = 0; (lib = liblst[i]) != NULL; i++) {
for (k = 0; (path = libsrchpath[k]) != NULL; k++) {
len = strlen(path) + strlen(lib);
lfn = xrealloc(lfn, len + sizeof ("/llib-l.ln"));
(void)sprintf(lfn, "%s/llib-l%s.ln", path, lib);
if (rdok(lfn))
break;
lfn = xrealloc(lfn, len + sizeof ("/lint/llib-l.ln"));
(void)sprintf(lfn, "%s/lint/llib-l%s.ln", path, lib);
if (rdok(lfn))
break;
}
if (path != NULL) {
appstrg(&l2libs, concat2("-l", lfn));
} else {
warnx("cannot find llib-l%s.ln", lib);
}
}
free(lfn);
}
static int
rdok(path)
const char *path;
{
struct stat sbuf;
if (stat(path, &sbuf) == -1)
return (0);
if ((sbuf.st_mode & S_IFMT) != S_IFREG)
return (0);
if (access(path, R_OK) == -1)
return (0);
return (1);
}
static void
lint2()
{
char *path, **args;
args = xcalloc(1, sizeof (char *));
path = xmalloc(strlen(PATH_LIBEXEC) + sizeof ("/lint2"));
(void)sprintf(path, "%s/lint2", PATH_LIBEXEC);
appcstrg(&args, path);
applst(&args, l2flags);
applst(&args, l2libs);
applst(&args, p2in);
runchild(path, args, p2out);
free(path);
freelst(&args);
free(args);
}
static void
cat(srcs, dest)
char *const *srcs;
const char *dest;
{
int ifd, ofd, i;
char *src, *buf;
ssize_t rlen;
if ((ofd = open(dest, O_WRONLY | O_CREAT | O_TRUNC, 0666)) == -1) {
warn("cannot open %s", dest);
terminate(-1);
}
buf = xmalloc(MBLKSIZ);
for (i = 0; (src = srcs[i]) != NULL; i++) {
if ((ifd = open(src, O_RDONLY)) == -1) {
free(buf);
warn("cannot open %s", src);
terminate(-1);
}
do {
if ((rlen = read(ifd, buf, MBLKSIZ)) == -1) {
free(buf);
warn("read error on %s", src);
terminate(-1);
}
if (write(ofd, buf, (size_t)rlen) == -1) {
free(buf);
warn("write error on %s", dest);
terminate(-1);
}
} while (rlen == MBLKSIZ);
(void)close(ifd);
}
(void)close(ofd);
free(buf);
}