lint: printf testing and FORMATs

This commit is contained in:
dick 1988-11-03 15:18:46 +00:00
parent 7267917050
commit 4ed20925c6
9 changed files with 107 additions and 32 deletions

View file

@ -125,7 +125,7 @@ SRC = $(CSRC) $(LCSRC) $(GCSRC)
LINT = /usr/bin/lint
LINTFLAGS =
MYLINT = ../lint
MYLINT = ../lpass2/lint
MYLINTFLAGS = #-xh
#EXCLEXCLEXCLEXCL

View file

@ -274,9 +274,13 @@ declare_idf(ds, dc, lvl)
#ifdef LINT
if ( def && def->df_level < lvl
&& !(lvl == L_FORMAL2 || def->df_level == L_UNIVERSAL)
&& !( lvl == L_FORMAL2
|| def->df_level == L_UNIVERSAL
|| sc == GLOBAL
|| sc == EXTERN
)
) {
/* there is already a definition for this name
/* there is already a definition for this non-extern name
on a more global level
*/
warning("%s is already defined as a %s",

View file

@ -14,6 +14,9 @@
#include <alloc.h>
#include "arith.h"
#include "l_state.h"
#include "l_comment.h"
extern char loptions[];
/* Since the lexical analyser does a one-token look-ahead, pseudo-
comments are read too soon. This is remedied by first storing them
@ -25,6 +28,7 @@ static int notreached;
static int varargsN = -1;
static int argsused;
static int formatN;
static int formatVAR;
static char *format;
static char *prev_format;
@ -34,6 +38,13 @@ int f_VARARGSn; /* function with variable # of args */
int f_ARGSUSED; /* function does not use all args */
int f_FORMATn; /* argument f_FORMATn is f_FORMAT */
char *f_FORMAT;
int f_FORMATvar; /* but the formal argument may be
absent because of varargs.h */
lint_init_comment()
{
LINTLIB = loptions['L'];
}
lint_comment_ahead()
{
@ -43,7 +54,7 @@ lint_comment_ahead()
lint_comment_function()
{
f_ARGSUSED = argsused;
f_ARGSUSED = argsused | loptions['v'];
argsused = 0;
f_VARARGSn = varargsN;
@ -55,6 +66,9 @@ lint_comment_function()
if (format)
prev_format = format;
format = 0;
f_FORMATvar = formatVAR;
formatVAR = 0;
}
static char buf[1000];
@ -97,14 +111,22 @@ lint_end_comment()
}
else
if (strncmp(bufpos, "VARARGS", 7) == 0) {
varargsN = isdigit(bufpos[7]) ? atoi(&bufpos[7]) : 0;
bufpos += 7;
varargsN = isdigit(*bufpos) ? atoi(bufpos) : 0;
}
else
if (strncmp(bufpos, "FORMAT", 6) == 0 && isdigit(bufpos[6])) {
int argn = bufpos[6] - '0';
register int argn;
bufpos += 6;
argn = *bufpos++ - '0';
varargsN = argn + 1;
make_format(argn, &bufpos[7]);
if (*bufpos == 'v') {
/* something like FORMAT3v */
formatVAR = 1;
bufpos++;
}
make_format(argn, bufpos);
}
}

View file

@ -10,4 +10,6 @@ extern int f_VARARGSn; /* function with variable # of args */
extern int f_ARGSUSED; /* function does not use all args */
extern int f_FORMATn; /* argument f_FORMATn is f_FORMAT */
extern char *f_FORMAT;
extern int f_FORMATvar; /* but the formal argument may be
absent because of varargs.h */

View file

@ -36,13 +36,8 @@ static struct expr_state *lint_oper();
lint_init()
{
/* Allocate some memory for the global stack_bottom
* and some other initializations
*/
extern struct lint_stack_entry stack_bottom;
stack_bottom.ls_current = new_state();
lint_init_comment();
lint_init_stack();
}
pre_lint_expr(expr, val, used)
@ -357,7 +352,7 @@ expr_ignored(expr)
break;
case Value:
hwarning("identifier as statement");
hwarning("value as statement");
break;
default: /* String Float */

View file

@ -22,6 +22,7 @@
#include "idf.h"
#include "level.h"
#include "label.h"
#include "code.h"
#include "expr.h"
#include "l_lint.h"
#include "l_comment.h"
@ -157,8 +158,10 @@ lint_formals()
}
if (f_FORMAT && nrargs == f_FORMATn) {
if ( type->tp_fund != POINTER
|| type->tp_up->tp_fund != CHAR
if ( !f_FORMATvar
&& ( type->tp_fund != POINTER
|| type->tp_up->tp_fund != CHAR
)
) {
warning("format parameter %d is not pointer to char",
nrargs);
@ -180,19 +183,47 @@ lint_formals()
se = se->next;
}
if (f_FORMAT) {
/* f_FORMAT has not been consumed, perhaps due to
a varargs-like construction; add erroneous ArgFormals
until f_FORMATn, then an ArgString, if necessary.
*/
if (!f_FORMATvar) {
warning("FORMAT%d function has only %d argument%s",
f_FORMATn, nrargs, nrargs == 1 ? "" : "s"
);
}
while (nrargs < f_FORMATn) {
register struct argument *arg = new_argument();
arg->ar_type = error_type;
arg->ar_class = ArgFormal;
*hook = arg;
hook = &arg->next;
nrargs++;
}
if (nrargs == f_FORMATn) {
register struct argument *arg = new_argument();
arg->ar_type = string_type;
arg->ar_class = ArgString;
arg->CAS_VALUE = f_FORMAT;
arg->CAS_LEN = strlen(f_FORMAT);
f_FORMAT = 0;
*hook = arg;
hook = &arg->next;
nrargs++;
}
/* life is full of duplicated code; this is no good */
}
if (f_VARARGSn > nrargs) {
warning("VARARGS%d function has only %d argument%s",
f_VARARGSn, nrargs, nrargs == 1 ? "" : "s"
);
f_VARARGSn = nrargs;
}
if (f_FORMAT) {
warning("FORMAT%d function has only %d argument%s",
f_FORMATn, nrargs, nrargs == 1 ? "" : "s"
);
f_FORMAT = 0;
}
OutDef.od_nrargs = nrargs;
}
@ -465,10 +496,24 @@ fill_arg(e)
arg->ar_class = ArgConst;
arg->CAA_VALUE = e->VL_VALUE;
}
else if (e->ex_class == String) {
arg->ar_class = ArgString;
arg->CAS_VALUE = e->SG_VALUE;
arg->CAS_LEN = e->SG_LEN - 1; /* SG_LEN includes the \0 */
else if (e->ex_class == Value && e->VL_CLASS == Label) {
/* it may be a string; let's look it up */
register struct string_cst *sc = str_list;
while (sc) {
if (sc->sc_dlb == e->VL_LBL)
break;
sc = sc->next;
}
if (sc) {
/* it was a string */
arg->ar_class = ArgString;
arg->CAS_VALUE = sc->sc_value;
arg->CAS_LEN = sc->sc_len - 1; /* included the \0 */
}
else {
arg->ar_class = ArgExpr;
}
}
else {
arg->ar_class = ArgExpr;

View file

@ -48,6 +48,13 @@ struct brace *top_br = &brace_bottom;
static print_autos();
lint_init_stack()
{
/* Allocate some memory for the global stack_bottom
*/
stack_bottom.ls_current = new_state();
}
lint_start_local()
{
register struct brace *br = new_brace();
@ -332,7 +339,6 @@ check_args_used()
register struct def *def = se->se_idf->id_def;
if ( (def && !def->df_used)
&& !loptions['v']
&& !(f_ARGSUSED || LINTLIB)
) {
def_warning(def, "argument %s not used in function %s",

View file

@ -96,9 +96,6 @@ main(argc, argv)
inc_max = 10;
init_pp(); /* initialise the preprocessor macros */
#ifdef LINT
lint_init();
#endif LINT
#endif NOPP
/* Note: source file "-" indicates that the source is supplied
@ -116,6 +113,9 @@ main(argc, argv)
do_option(par);
argc--, argv++;
}
#ifdef LINT
lint_init();
#endif LINT
compile(argc - 1, &argv[1]);
#ifdef DEBUG

View file

@ -80,6 +80,7 @@ next_option: /* to allow combined one-char options */
case 'b': /* don't report unreachable break-statements */
case 'x': /* complain about unused extern declared variables */
case 'u': /* no "used but not defined"; for pass 2 */
case 'L': /* lintlibrary */
loptions[opt] = 1;
goto next_option;
#endif LINT