This commit was generated by cvs2svn to compensate for changes in r12099,
which included commits to RCS files with non-trunk default branches.
This commit is contained in:
commit
f2959bfd1f
5
usr.bin/xlint/Makefile
Normal file
5
usr.bin/xlint/Makefile
Normal 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>
|
19
usr.bin/xlint/lint1/Makefile
Normal file
19
usr.bin/xlint/lint1/Makefile
Normal 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
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
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
241
usr.bin/xlint/lint1/emit.c
Normal 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
587
usr.bin/xlint/lint1/emit1.c
Normal 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
543
usr.bin/xlint/lint1/err.c
Normal 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);
|
||||
}
|
56
usr.bin/xlint/lint1/externs.h
Normal file
56
usr.bin/xlint/lint1/externs.h
Normal 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 *));
|
281
usr.bin/xlint/lint1/externs1.h
Normal file
281
usr.bin/xlint/lint1/externs1.h
Normal 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
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
513
usr.bin/xlint/lint1/init.c
Normal 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
118
usr.bin/xlint/lint1/lint.h
Normal 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
380
usr.bin/xlint/lint1/lint1.h
Normal 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
183
usr.bin/xlint/lint1/main1.c
Normal 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
91
usr.bin/xlint/lint1/mem.c
Normal 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
358
usr.bin/xlint/lint1/mem1.c
Normal 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
120
usr.bin/xlint/lint1/op.h
Normal 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
120
usr.bin/xlint/lint1/param.h
Normal 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
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
3924
usr.bin/xlint/lint1/tree.c
Normal file
File diff suppressed because it is too large
Load Diff
13
usr.bin/xlint/lint2/Makefile
Normal file
13
usr.bin/xlint/lint2/Makefile
Normal 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
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
236
usr.bin/xlint/lint2/emit2.c
Normal 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();
|
||||
}
|
87
usr.bin/xlint/lint2/externs2.h
Normal file
87
usr.bin/xlint/lint2/externs2.h
Normal 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
123
usr.bin/xlint/lint2/hash.c
Normal 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
177
usr.bin/xlint/lint2/lint2.h
Normal 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
190
usr.bin/xlint/lint2/main2.c
Normal 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);
|
||||
}
|
||||
|
97
usr.bin/xlint/lint2/mem2.c
Normal file
97
usr.bin/xlint/lint2/mem2.c
Normal 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
157
usr.bin/xlint/lint2/msg.c
Normal 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
1133
usr.bin/xlint/lint2/read.c
Normal file
File diff suppressed because it is too large
Load Diff
20
usr.bin/xlint/llib/Makefile
Normal file
20
usr.bin/xlint/llib/Makefile
Normal 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>
|
311
usr.bin/xlint/llib/llib-lposix
Normal file
311
usr.bin/xlint/llib/llib-lposix
Normal 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);
|
252
usr.bin/xlint/llib/llib-lstdc
Normal file
252
usr.bin/xlint/llib/llib-lstdc
Normal 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);
|
17
usr.bin/xlint/xlint/Makefile
Normal file
17
usr.bin/xlint/xlint/Makefile
Normal 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
509
usr.bin/xlint/xlint/lint.1
Normal 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.
|
38
usr.bin/xlint/xlint/pathnames.h
Normal file
38
usr.bin/xlint/xlint/pathnames.h
Normal 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
761
usr.bin/xlint/xlint/xlint.c
Normal 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);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user