lint: printf testing and FORMATs
authordick <none@none>
Thu, 3 Nov 1988 15:18:46 +0000 (15:18 +0000)
committerdick <none@none>
Thu, 3 Nov 1988 15:18:46 +0000 (15:18 +0000)
lang/cem/cemcom/Makefile
lang/cem/cemcom/idf.c
lang/cem/cemcom/l_comment.c
lang/cem/cemcom/l_comment.h
lang/cem/cemcom/l_lint.c
lang/cem/cemcom/l_outdef.c
lang/cem/cemcom/l_states.c
lang/cem/cemcom/main.c
lang/cem/cemcom/options.c

index 766165b..1c744df 100644 (file)
@@ -125,7 +125,7 @@ SRC =       $(CSRC) $(LCSRC) $(GCSRC)
 LINT = /usr/bin/lint
 LINTFLAGS =
 
-MYLINT = ../lint
+MYLINT = ../lpass2/lint
 MYLINTFLAGS = #-xh
 
 #EXCLEXCLEXCLEXCL
index 8a48ccf..e648e83 100644 (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",
index cd2bfb5..64e8ed7 100644 (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);
                
        }
 }
index 9b8776d..9340b08 100644 (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 */
 
index 45c2259..f28e47f 100644 (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 */
index 24f670b..eba9c38 100644 (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;
index b4d97ab..0c6df51 100644 (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",
index b8104bf..607a741 100644 (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
index e873061..2d627f9 100644 (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