LINT = /usr/bin/lint
LINTFLAGS =
-MYLINT = ../lint
+MYLINT = ../lpass2/lint
MYLINTFLAGS = #-xh
#EXCLEXCLEXCLEXCL
#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",
#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
static int varargsN = -1;
static int argsused;
static int formatN;
+static int formatVAR;
static char *format;
static char *prev_format;
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()
{
lint_comment_function()
{
- f_ARGSUSED = argsused;
+ f_ARGSUSED = argsused | loptions['v'];
argsused = 0;
f_VARARGSn = varargsN;
if (format)
prev_format = format;
format = 0;
+
+ f_FORMATvar = formatVAR;
+ formatVAR = 0;
}
static char buf[1000];
}
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);
}
}
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 */
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)
break;
case Value:
- hwarning("identifier as statement");
+ hwarning("value as statement");
break;
default: /* String Float */
#include "idf.h"
#include "level.h"
#include "label.h"
+#include "code.h"
#include "expr.h"
#include "l_lint.h"
#include "l_comment.h"
}
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);
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;
}
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;
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();
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",
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
do_option(par);
argc--, argv++;
}
+#ifdef LINT
+ lint_init();
+#endif LINT
compile(argc - 1, &argv[1]);
#ifdef DEBUG
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