ANSI C prototype handling added
authordick <none@none>
Fri, 8 Mar 1991 15:54:05 +0000 (15:54 +0000)
committerdick <none@none>
Fri, 8 Mar 1991 15:54:05 +0000 (15:54 +0000)
lang/cem/lint/lpass2/Makefile
lang/cem/lint/lpass2/checkargs.c
lang/cem/lint/lpass2/class.c
lang/cem/lint/lpass2/class.h
lang/cem/lint/lpass2/lpass2.c
lang/cem/lint/lpass2/read.c
lang/cem/lint/lpass2/report.c

index 605ac85..40cd686 100644 (file)
@@ -6,8 +6,8 @@
 #      M A K E F I L E   F O R   L P A S S 2
 
 # Machine and environ dependent definitions
-EMHOME =       /usr/proj/em/Work
-LPASS1 =       $(EMHOME)/lang/cem/cemcom
+EMHOME =       ../../..
+LPASS1 =       ../lpass1#                      ???
 
 # Libraries and EM interface definitions
 SYSLIB =       $(EMHOME)/modules/lib/libsystem.a
@@ -28,8 +28,8 @@ SRC = lpass2.c checkargs.c read.c report.c class.c l_print3ack.c
 OBJ =  lpass2.o checkargs.o read.o report.o class.o l_print3ack.o
 
 test:  lpass2
-       make lint.test
-#      lpass2 -xh <.i
+       lpass2 -xh <proto.tst
+#      make lint.test
 
 
 lpass2:        $(OBJ) Makefile next.o
@@ -37,7 +37,7 @@ lpass2:       $(OBJ) Makefile next.o
        size lpass2
 
 lint.test:
-       ./lint -xh $(CFLAGS) $(SRC) next.c #???
+       ./lint -h $(CFLAGS) $(SRC) next.c #???
 
 next.c:        $(LPASS1)/make.next inpdef.str
        $(LPASS1)/make.next inpdef.str > next.c
@@ -49,7 +49,8 @@ clean:
        rm -f a.out core next.c inpdef.h $(OBJ) next.o
 
 #----------------------------------------------------------------
+checkargs.o: inpdef.h private.h
 class.o: ../lpass1/l_class.h class.h
 lpass2.o: ../lpass1/l_class.h ../lpass1/l_lint.h class.h inpdef.h private.h
 read.o: ../lpass1/l_class.h class.h inpdef.h private.h
-report.o: inpdef.h
+report.o: ../lpass1/l_class.h class.h inpdef.h private.h
index 9793627..bd99f26 100644 (file)
@@ -18,7 +18,7 @@ PRIVATE int is_formatargs;            /* present or not */
 PRIVATE char formatargs[1000];         /* the definitions */
 
 PRIVATE chk_argtps();
-PRIVATE char *next_atype();
+PRIVATE char *next_argtype();
 PRIVATE int type_match();
 PRIVATE form_type();
 
@@ -37,6 +37,14 @@ chk_args(id, def)
        char *act_tp = id->id_argtps;
        int nrargs = 0;                 /* number of args */
 
+       /* void is a special case */
+       if (    /* the definition has one void argument */
+               def->id_nrargs == 1 && streq(def->id_argtps, "void:")
+       &&      /* the referent has no argumants */
+               id->id_nrargs == 0
+       )       /* we have a prefect match */
+               return;
+
        /* clear format */
        is_formatargs = 0;
 
@@ -49,7 +57,7 @@ chk_args(id, def)
 
                /* skip over the actuals already covered */
                for (i = 0; i < nrargs; i++) {
-                       act_tp = next_atype(act_tp);
+                       act_tp = next_argtype(act_tp);
                }
 
                /* and check the format arguments */
@@ -65,16 +73,16 @@ PRIVATE chk_argtps(id, def, nrargs, act_tp, form_tp)
        char *act_tp;                   /* actual types */
        char *form_tp;                  /* formal type definitions */
 {
-       while (*act_tp && *form_tp) {
+       while (*act_tp && *form_tp && *form_tp != '.') {
                register char *act_start = act_tp;
                register char *form_start = form_tp;
 
                /* isolate actual argument type */
-               act_tp = next_atype(act_tp);
+               act_tp = next_argtype(act_tp);
                act_tp[-1] = '\0';
 
                /* isolate formal argument type */
-               form_tp = next_atype(form_tp);
+               form_tp = next_argtype(form_tp);
                form_tp[-1] = '\0';
 
                (*nrargs)++;
@@ -92,6 +100,9 @@ PRIVATE chk_argtps(id, def, nrargs, act_tp, form_tp)
                form_tp[-1] = ':';
        }
 
+       if (*form_tp == '.')    /* ellipsis */
+               return;
+
        if (*form_tp) {
                /* formal type definitions not exhausted */
                report("%L: %s has fewer arguments than in %L",
@@ -110,7 +121,7 @@ PRIVATE chk_argtps(id, def, nrargs, act_tp, form_tp)
 }
 
 PRIVATE char *
-next_atype(tp)
+next_argtype(tp)
        char *tp;
 {
        while (*tp && *tp != ':') {
index d740526..aed5350 100644 (file)
@@ -7,47 +7,23 @@
 #include       "../lpass1/l_class.h"
 #include       "class.h"
 
-int class[] = {
-       /* mapping of class values onto bit patterns */
-       /* LFDF */ CL_LIB|CL_FUNC|CL_DEF,
-       /* LVDF */ CL_LIB|CL_VAR|CL_DEF,
-       /* EFDF */ CL_EXT|CL_FUNC|CL_DEF,
-       /* EVDF */ CL_EXT|CL_VAR|CL_DEF,
-       /* EFDC */ CL_EXT|CL_FUNC|CL_DECL,
-       /* EVDC */ CL_EXT|CL_VAR|CL_DECL,
-       /* IFDC */ CL_IMPL|CL_FUNC|CL_DECL,
-       /* SFDF */ CL_STAT|CL_FUNC|CL_DEF,
-       /* SVDF */ CL_STAT|CL_VAR|CL_DEF,
-       /* FC */ CL_FUNC|CL_USAGE,
-       /* VU */ CL_VAR|CL_USAGE
-};
-
-static int val[] = {
-       LFDF,
-       LVDF,
-       EFDF,
-       EVDF,
-       EFDC,
-       EVDC,
-       IFDC,
-       SFDF,
-       SVDF,
-       FC,
-       VU
-};
+int class[MAX_CLASS_CONST-MIN_CLASS_CONST+1];
 
 init_class()
 {
-       /*      The initialization of class[] has been taken care of above.
-               For it to work, we have to test that the class values are
-               in the right order.  This is also necessary for the scanning
-               sequence in lpass2.c to work properly.
-       */
-       int i;
-
-       for (i = 0; i+1 < sizeof(val)/sizeof(val[0]); i++) {
-               if (val[i] >= val[i+1])
-                       panic("class values out of sequence");
-       }
+       /* mapping of class values onto bit patterns */
+       class[LFDF-LFDF] = CL_LIB | CL_FUNC | CL_DEF;
+       class[LVDF-LFDF] = CL_LIB | CL_VAR | CL_DEF;
+       class[PFDF-LFDF] = CL_EXT | CL_FUNC | CL_DEF;
+       class[EFDF-LFDF] = CL_EXT | CL_FUNC | CL_DEF;
+       class[EVDF-LFDF] = CL_EXT | CL_VAR | CL_DEF;
+       class[EFDC-LFDF] = CL_EXT | CL_FUNC | CL_DECL;
+       class[EVDC-LFDF] = CL_EXT | CL_VAR | CL_DECL;
+       class[IFDC-LFDF] = CL_IMPL | CL_FUNC | CL_DECL;
+       class[SFDF-LFDF] = CL_STAT | CL_FUNC | CL_DEF;
+       class[SVDF-LFDF] = CL_STAT | CL_VAR | CL_DEF;
+       class[FC-LFDF] = CL_FUNC | CL_USAGE;
+       class[VU-LFDF] = CL_VAR | CL_USAGE;
+       class[XXDF-LFDF] = 0;
 }
 
index 29f012c..ed32b4a 100644 (file)
@@ -26,5 +26,5 @@
 
 extern int class[];
 
-#define        is_class(id,cl) ((class[(id)->id_class-'a'] & (cl)) == (cl))
+#define        is_class(id,cl) ((class[(id)->id_class-MIN_CLASS_CONST] & (cl)) == (cl))
 
index ca73e1a..87286a4 100644 (file)
@@ -17,10 +17,13 @@ extern char *strcpy();
 #define        streq(s1,s2)    (strcmp(s1, s2) == 0)
 
 PRIVATE char cur_name[NAMESIZE];
-PRIVATE struct inpdef *dot, *lib, *ext, *sta;
+PRIVATE struct inpdef *dot, *lib, *proto, *ext, *sta;
 
+PRIVATE one_name();
 PRIVATE chk_def();
 PRIVATE ext_decls();
+PRIVATE proto_defs();
+PRIVATE chk_proto();
 PRIVATE ext_def();
 PRIVATE get_dot();
 PRIVATE init();
@@ -35,8 +38,8 @@ PRIVATE usage();
 #define        same_name()     (dot && streq(cur_name, dot->id_name))
 #define        same_obj(stnr)  (same_name() && dot->id_statnr == stnr)
 
-#define        defdec(id)      (is_class(id, CL_DEF) ? "defined" : "declared")
-#define        funvar(id)      (is_class(id, CL_FUNC) ? "function" : "variable")
+#define        def_or_dec(id)  (is_class(id, CL_DEF) ? "defined" : "declared")
+#define        fun_or_var(id)  (is_class(id, CL_FUNC) ? "function" : "variable")
 
 
 /******** M A I N ********/
@@ -53,24 +56,15 @@ main(argc, argv)
                        free_inpdef(lib);
                        lib = 0;
                }
+               if (proto) {
+                       free_inpdef(proto);
+                       proto = 0;
+               }
                if (ext) {
                        free_inpdef(ext);
                        ext = 0;
                }
-               strcpy(cur_name, dot->id_name);
-               lib_def();
-               ext_def();
-               ext_decls();
-               usage(0);
-               if (ext)
-                       chk_def(ext);
-               statics();
-               if (same_name()) {
-                       /*      there are more lines for this name that have
-                               not been absorbed
-                       */
-                       panic("sequence error in intermediate file");
-               }
+               one_name();
        }
 }
 
@@ -81,7 +75,7 @@ PRIVATE init(argc, argv)
        char *argv[];
 {
 /*
- * Parse options
+ * Get command line options
  * Prepare standard input for reading using the input-package
  */
        char *result;
@@ -107,8 +101,9 @@ PRIVATE init(argc, argv)
                argc--, argv++;
        }
 
-       if (!InsertFile((char *)0, table, &result))
+       if (!InsertFile((char *)0, table, &result)) {
                panic("InsertFile() fails");
+       }
 }
 
 PRIVATE get_dot()
@@ -118,8 +113,32 @@ PRIVATE get_dot()
                dot = 0;
                cur_name[0] = '\0';
        }
+       if (loptions['X']) {
+               print_id("get_dot", dot);
+       }
 }
 
+PRIVATE one_name()
+{
+       strcpy(cur_name, dot->id_name);
+       lib_def();
+       proto_defs();
+       ext_def();
+       ext_decls();
+       usage(0);
+       if (proto) {
+               chk_def(proto);
+       }
+       else
+       if (ext) {
+               chk_def(ext);
+       }
+       statics();
+       if (same_name()) {
+               /* there are lines for this name that have not been absorbed */
+               panic("sequence error in intermediate file");
+       }
+}
 
 /******** L I B R A R Y ********/
 
@@ -129,12 +148,42 @@ PRIVATE lib_def()
                lib = dot;
                dot = new_inpdef();
                get_dot();
+               while (same_obj(0) && is_class(dot, CL_LIB)) {
+                       report(">%L: multiple definition of %s in library",
+                               dot, dot->id_name);
+                       get_dot();
+               }
        }
+}
+
 
-       while (same_obj(0) && is_class(dot, CL_LIB)) {
-               report(">%L: multiple definition of %s in library",
-                       dot, dot->id_name);
+/******** P R O T O T Y P E S ********/
+PRIVATE proto_defs()
+{
+       if (same_obj(0) && dot->id_class == PFDF) {
+               if (lib) {
+                       report("%L: function %s also defined in %L",
+                               dot, dot->id_name, lib);
+               }
+               proto = dot;
+               dot = new_inpdef();
                get_dot();
+               while (same_obj(0) && dot->id_class == PFDF) {
+                       chk_proto(dot);
+                       get_dot();
+               }
+       }
+}
+
+PRIVATE chk_proto(def)
+       struct inpdef *def;
+{
+       if (proto->id_args) {
+               chk_args(def, proto);
+       }
+       if (!type_equal(def->id_type, proto->id_type)) {
+               report("%L: return type of function %s declared differently at %L",
+                       def, def->id_name, proto);
        }
 }
 
@@ -144,19 +193,21 @@ PRIVATE lib_def()
 PRIVATE ext_def()
 {
        if (same_obj(0) && is_class(dot, CL_EXT|CL_DEF)) {
-               if (lib) {
+               if (lib && !proto) {
                        report("%L: %s %s also defined in %L",
-                               dot, funvar(dot), dot->id_name, lib);
+                               dot, fun_or_var(dot), dot->id_name, lib);
+               }
+               if (proto) {
+                       chk_proto(dot);
                }
                ext = dot;
                dot = new_inpdef();
                get_dot();
-       }
-
-       while (same_obj(0) && is_class(dot, CL_EXT|CL_DEF)) {
-               report("%L: %s %s also defined at %L",
-                       dot, funvar(dot), dot->id_name, ext);
-               get_dot();
+               while (same_obj(0) && is_class(dot, CL_EXT|CL_DEF)) {
+                       report("%L: %s %s also defined at %L",
+                               dot, fun_or_var(dot), dot->id_name, ext);
+                       get_dot();
+               }
        }
 }
 
@@ -180,7 +231,7 @@ PRIVATE one_ext_decl(kind, other_kind, other_class)
        char *other_kind;
        int other_class;
 {
-       struct inpdef *def = ext ? ext : lib ? lib : 0;
+       struct inpdef *def = (proto ? proto : ext ? ext : lib ? lib : 0);
 
        if (!def) {
                /* the declaration will have to serve */
@@ -193,7 +244,9 @@ PRIVATE one_ext_decl(kind, other_kind, other_class)
        if (is_class(def, other_class)) {
                /* e.g.: function FFF declared as variable at ... */
                report("%L: %s %s %s as %s at %L",
-                       dot, kind, dot->id_name, defdec(def), other_kind, def);
+                       dot, kind, dot->id_name,
+                       def_or_dec(def), other_kind, def
+               );
                /* no further testing possible */
                get_dot();
                return;
@@ -202,7 +255,11 @@ PRIVATE one_ext_decl(kind, other_kind, other_class)
        if (!type_equal(dot->id_type, def->id_type)) {
                /* e.g.: type of variable VVV defined differently at ... */
                report("%L: type of %s %s %s differently at %L",
-                       dot, kind, dot->id_name, defdec(def), def);
+                       dot, kind, dot->id_name, def_or_dec(def), def);
+
+               /* no further testing needed */
+               get_dot();
+               return;
        }
 
        get_dot();
@@ -214,7 +271,8 @@ PRIVATE one_ext_decl(kind, other_kind, other_class)
 PRIVATE usage(stnr)
        int stnr;
 {
-       register struct inpdef *def = stnr ? sta : ext ? ext : lib ? lib : 0;
+       register struct inpdef *def =
+               (stnr ? sta : proto ? proto : ext ? ext : lib ? lib : 0);
        register int VU_count = 0;
        register int VU_samefile = 0;
 
@@ -236,8 +294,9 @@ PRIVATE usage(stnr)
                if (    stnr == 0
                &&      VU_count == 1
                &&      VU_samefile == 1
-               &&      def == ext
-               &&      !is_class(ext, CL_IMPL)
+               &&      (       def == proto
+                       ||      (def == ext && !is_class(ext, CL_IMPL))
+                       )
                &&      streq(&fn[strlen(fn)-2], ".c")
                ) {
                        report("%L: extern %s could be declared static",
@@ -313,20 +372,25 @@ PRIVATE statics()
        while (same_name()) {
                int stnr = dot->id_statnr;
 
-               if (stnr == 0)
-                       panic("sequence error in input");
+               if (stnr == 0) {
+                       panic("sequence error in intermediate file: externals after statics");
+               }
 
                if (sta) {
                        free_inpdef(sta);
                        sta = 0;
                }
+
                stat_def(stnr);
                usage(stnr);
-               if (sta)
+
+               if (sta) {
                        chk_def(sta);
+               }
 
-               if (same_obj(stnr))
-                       panic("sequence error in input");
+               if (same_obj(stnr)) {
+                       panic("sequence error in intermediate file: statics out of order");
+               }
        }
 }
 
@@ -336,24 +400,26 @@ PRIVATE stat_def(stnr)
        if (same_obj(stnr) && is_class(dot, CL_STAT|CL_DEF)) {
                if (lib) {
                        report("%L: %s %s also defined in %L",
-                               dot, funvar(dot), dot->id_name, lib);
+                               dot, fun_or_var(dot), dot->id_name, lib);
                }
-               if (ext) {
-                       if (!streq(dot->id_file, ext->id_file)) {
+               if (proto || ext) {
+                       struct inpdef *def = (proto ? proto : ext);
+
+                       if (!streq(dot->id_file, def->id_file)) {
                                report("%L: %s %s also %s at %L",
-                                       dot, funvar(dot), dot->id_name,
-                                       defdec(ext), ext);
+                                       dot, fun_or_var(dot), dot->id_name,
+                                       def_or_dec(def), def
+                               );
                        }
                }
                sta = dot;
                dot = new_inpdef();
                get_dot();
-       }
-
-       while (same_obj(stnr) && is_class(dot, CL_STAT|CL_DEF)) {
-               report("%L: %s %s also defined at %L",
-                       dot, funvar(dot), dot->id_name, sta);
-               get_dot();
+               while (same_obj(stnr) && is_class(dot, CL_STAT|CL_DEF)) {
+                       report("%L: %s %s also defined at %L",
+                               dot, fun_or_var(dot), dot->id_name, sta);
+                       get_dot();
+               }
        }
 }
 
@@ -373,7 +439,7 @@ PRIVATE chk_def(def)
                else {
                        if (!loptions['u']) {
                                report("%L: %s %s not used anywhere",
-                                       def, funvar(def), def->id_name);
+                                       def, fun_or_var(def), def->id_name);
                        }
                }
        }
@@ -398,9 +464,15 @@ print_id(name, id)
        char *name;
        struct inpdef *id;
 {
+       if (!id) {
+               print("%s: <NO_INPDEF>\n", name);
+               return;
+       }
+
        print("%s: %s, %s, %04d, \"%s\", %d, %s", name,
                id->id_class == LFDF ? "LFDF" :
                id->id_class == LVDF ? "LVDF" :
+               id->id_class == PFDF ? "PFDF" :
                id->id_class == EFDF ? "EFDF" :
                id->id_class == EVDF ? "EVDF" :
                id->id_class == EFDC ? "EFDC" :
@@ -419,19 +491,22 @@ print_id(name, id)
        if (is_class(id, CL_FUNC|CL_DEF) || is_class(id, CL_FUNC|CL_USAGE)) {
                print(", %d, %s, %s",
                        id->id_nrargs,
-                       id->id_nrargs == 0 ? "" : id->id_argtps,
-                       id->id_class == FC ?
-                               (id->id_valused == USED ? "USED" :
-                               id->id_valused == IGNORED ? "IGNORED" :
-                               id->id_valused == VOIDED ? "VOIDED" :
-                               "<BAD VALUSED>")
-                       :       (id->id_valreturned == NOVALRETURNED ?
-                                       "NOVALRETURNED" :
-                               id->id_valreturned == VALRETURNED ?
-                                       "VALRETURNED" :
-                               id->id_valreturned == NORETURN ?
-                                       "NORETURN" : "<BAD VALRETURNED>"
+                       (id->id_nrargs == 0 ? "" : id->id_argtps),
+                       (       id->id_class == FC
+                       ?       (       id->id_valused == USED ? "USED" :
+                                       id->id_valused == IGNORED ? "IGNORED" :
+                                       id->id_valused == VOIDED ? "VOIDED" :
+                                       "<BAD VALUSED>"
+                               )
+                       :       (       id->id_valreturned == NOVALRETURNED
+                               ?       "NOVALRETURNED"
+                               :       id->id_valreturned == VALRETURNED
+                               ?       "VALRETURNED"
+                               :       id->id_valreturned == NORETURN
+                               ?       "NORETURN"
+                               :       "<BAD VALRETURNED>"
                                )
+                       )
                );
        }
        print("\n");
index 6af6bcf..07a4318 100644 (file)
@@ -92,7 +92,7 @@ ReadString(buf, delim, maxsize)
        /*      Reads a string until 'delim' is encountered; delim is
                discarded.
                If 'maxsize-1' is exceeded or the string contains a newline
-               (which is not delim), panic() is called.
+               panic() is called (unless delim == newline).
                A '\0' is appended to the string.
        */
 
@@ -106,14 +106,14 @@ ReadString(buf, delim, maxsize)
                if (ch == delim)
                        break;
                if (ch == '\n') {
-                       panic("newline in string");
+                       panic("incomplete line in intermediate file");
                        /*NOTREACHED*/
                }
                buf[nread++] = (char)ch;
        }
        buf[nread++] = '\0';
        if (ch != delim) {
-               panic("string too long");
+               panic("line too long in intermediate file");
                /*NOTREACHED*/
        }
        return 1;
@@ -148,7 +148,7 @@ ReadInt(ip)
                loadchar(ch);
        }
        pushback(ch);
-       *ip = negative ? -res : res;
+       *ip = (negative ? -res : res);
        return 1;
 }
 
@@ -213,9 +213,11 @@ PRIVATE SkipChar(ch)
        int c;
 
        loadchar(c);
-       if (c != ch) {
-               panic("bad format, '%c' expected; '%c' read", ch, c);
-               /*NOTREACHED*/
-       }
+       if (c == ch)
+               return;
+       panic("bad format in intermediate file, '%c' expected; '%c' read",
+               ch, c
+       );
+       /*NOTREACHED*/
 }
 
index 7ca1700..010e21b 100644 (file)
@@ -8,11 +8,12 @@
 
 #include       <system.h>
 #include       "private.h"
+#include       "../lpass1/l_class.h"
 #include       "class.h"
 #include       "inpdef.h"
 
-#define        MSGOUT          STDERR  /* filedes on which to write the messages */
-#define        ERROUT          STDERR  /* filedes on which to write the panics */
+#define        MSGOUT          STDERR  /* file descr. on which to write the messages */
+#define        ERROUT          STDERR  /* file descr. on which to write the panics */
 
 extern int LineNr;
 
@@ -75,7 +76,8 @@ report(va_alist)
                                        fprint(MSGOUT, "%d", i);
                                        break;
                                default:
-                                       panic("bad format %s", fmt);
+                                       panic("internal error: bad format %s",
+                                               fmt);
                                        break;
                                }
                        }