many improvements
authordick <none@none>
Sun, 7 Aug 1988 22:55:20 +0000 (22:55 +0000)
committerdick <none@none>
Sun, 7 Aug 1988 22:55:20 +0000 (22:55 +0000)
lang/cem/lint/lpass2/ChangeLog
lang/cem/lint/lpass2/Makefile
lang/cem/lint/lpass2/class.c [new file with mode: 0644]
lang/cem/lint/lpass2/class.h [new file with mode: 0644]
lang/cem/lint/lpass2/inpdef.str
lang/cem/lint/lpass2/lpass2.c
lang/cem/lint/lpass2/read.c
lang/cem/lint/lpass2/report.c [new file with mode: 0644]

index 7853c69..23d4f6e 100644 (file)
@@ -1,3 +1,21 @@
+ 7-Aug-88  Dick Grune (dick) at dick
+       About the class of an inpdef, often set-like questions are asked.
+       To speed up answering these questions, a mapping has been created
+       of the values of `class' onto answers to these questions.  See
+       class.[ch].
+
+ 5-Aug-88  Dick Grune (dick) at dick
+       Streamlined the program by rearranging the input sequence:
+               - library
+               - external defs
+               - external decls
+               - external usage
+               - static defs
+               - static usage
+       This change to a much more natural order has been possible by the
+       introduction of the static file number.  Many pieces of code could
+       now be taken together and the program is much cleaner now.
+
  8-Jul-88  Dick Grune (dick) at dick
        Added a special meta-type (also in lpaas1) for non-negative
        constant actual arguments, because these may match both the signed
index a81e055..37a5df1 100644 (file)
@@ -1,26 +1,26 @@
 #      M A K E F I L E   F O R   L P A S S 2
 
 # Machine and environ dependent definitions
-EMHOME = /usr/em
-LPASS1 = ../lpass1
+EMHOME =       /usr/em
+LPASS1 =       ../lpass1
 
 # Libraries and EM interface definitions
-SYSLIB = $(EMHOME)/modules/lib/libsystem.a
-STRLIB = $(EMHOME)/modules/lib/libstring.a
-PRTLIB = $(EMHOME)/modules/lib/libprint.a
-INPLIB = $(EMHOME)/modules/lib/libinput.a
-ALLOCLIB = $(EMHOME)/modules/lib/liballoc.a
-MALLOC = $(EMHOME)/modules/lib/malloc.o
-LLIBS = $(INPLIB) $(PRTLIB) $(STRLIB) $(ALLOCLIB) $(MALLOC) $(SYSLIB)
+SYSLIB =       $(EMHOME)/modules/lib/libsystem.a
+STRLIB =       $(EMHOME)/modules/lib/libstring.a
+PRTLIB =       $(EMHOME)/modules/lib/libprint.a
+INPLIB =       $(EMHOME)/modules/lib/libinput.a
+ALLOCLIB =     $(EMHOME)/modules/lib/liballoc.a
+MALLOC =       $(EMHOME)/modules/lib/malloc.o
+LLIBS =                $(INPLIB) $(PRTLIB) $(STRLIB) $(ALLOCLIB) $(MALLOC) $(SYSLIB)
 
-CFLAGS = -I$(EMHOME)/modules/h -I$(EMHOME)/modules/pkg -I/usr/include
+CFLAGS =       -I$(EMHOME)/modules/h -I$(EMHOME)/modules/pkg -I/usr/include
 
 .SUFFIXES: .str .h
 .str.h:
        $(LPASS1)/make.allocd <$*.str >$*.h
 
-SRC =  lpass2.c read.c
-OBJ =  lpass2.o read.o
+SRC =  lpass2.c read.c report.c class.c
+OBJ =  lpass2.o read.o report.o class.o
 
 test:  lpass2
        make lint
@@ -32,7 +32,7 @@ lpass2:       $(OBJ) Makefile next.o
 lint:
        ../lint $(CFLAGS) $(SRC) next.c #???
 
-next.c:        inpdef.str
+next.c:        $(LPASS1)/make.next inpdef.str
        $(LPASS1)/make.next inpdef.str > next.c
 
 tags:  $(SRC)
@@ -42,4 +42,7 @@ clean:
        rm -f a.out core next.c inpdef.h $(OBJ) next.o
 
 #----------------------------------------------------------------
-lpass2.o: ../lpass1/errout.h ../lpass1/lint.h ../lpass1/l_class.h inpdef.h
+class.o: class.h
+lpass2.o: ../lpass1/l_class.h ../lpass1/l_lint.h class.h inpdef.h
+read.o: ../lpass1/l_class.h class.h inpdef.h
+report.o: inpdef.h
diff --git a/lang/cem/lint/lpass2/class.c b/lang/cem/lint/lpass2/class.c
new file mode 100644 (file)
index 0000000..b477e48
--- /dev/null
@@ -0,0 +1,47 @@
+#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
+};
+
+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");
+       }
+}
+
diff --git a/lang/cem/lint/lpass2/class.h b/lang/cem/lint/lpass2/class.h
new file mode 100644 (file)
index 0000000..4c961e6
--- /dev/null
@@ -0,0 +1,16 @@
+#define        CL_DEF          (1<<0)
+#define        CL_DECL         (1<<1)
+#define        CL_USAGE        (1<<2)
+
+#define        CL_FUNC         (1<<3)
+#define        CL_VAR          (1<<4)
+
+#define        CL_LIB          (1<<5)
+#define        CL_EXT          (1<<6)
+#define        CL_IMPL         (1<<7)
+#define        CL_STAT         (1<<8)
+
+extern int class[];
+
+#define        is_class(id,cl) ((class[(id)->id_class-'a'] & (cl)) == (cl))
+
index 7c85d18..aa907ac 100644 (file)
@@ -5,14 +5,22 @@
 
 struct inpdef {
        struct inpdef *next;
-       int id_class;
+
+       /* filled by get_id() */
+       int id_class;                   /* see ../lpass1/l_class.h */
        char id_name[NAMESIZE];
+       int id_statnr;
        char id_file[FNAMESIZE];
        int id_line;
-       int id_nrargs;
-       char id_argtps[ARGTPSSIZE];
-       int id_returns;
        char id_type[TYPESIZE];
+
+       int id_args;                    /* set if arguments given */
+       int id_nrargs;                  /* number of args, neg. for varargs */
+       char id_argtps[ARGTPSSIZE];     /* argument types, colon separated */
+       int id_valreturned;             /* for def/decl, set if val returned */
+       int id_valused;                 /* for FC, see ../lpass1/l_lint.h */
+
+       /* not filled by get_id() */
        int id_called;
        int id_used;
        int id_ignored;
index 4f42089..92a0f56 100644 (file)
@@ -1,46 +1,55 @@
-#include       <varargs.h>
+#include       <alloc.h>
 
 #include       "../lpass1/l_lint.h"
 #include       "../lpass1/l_class.h"
+#include       "class.h"
 #include       "inpdef.h"
 
-#include       <alloc.h>
-#include       <system.h>
-
-#define        MSGOUT          STDERR  /* filedes on which to write the messages */
-#define        ERROUT          STDERR  /* filedes on which to write the panics */
-
 #define        streq(s1,s2)    (strcmp(s1, s2) == 0)
 #define        min(a,b)        ((a) <= (b) ? (a) : (b))
 
-#define        type_equal(s1,s2)       (streq(s1, s2))
+char cur_name[NAMESIZE];
+struct inpdef *dot, *lib, *ext, *sta;
 
-char *cur_name;
-struct inpdef *dot_id,
-       *ext_def,
-       *static_def;
-struct inpdef *id_read();
+#define        same_name()     (dot && streq(cur_name, dot->id_name))
+#define        same_obj(stnr)  (same_name() && dot->id_statnr == stnr)
 
-#define        same_name()     streq(cur_name, dot_id->id_name)
+#define        defdec(id)      (is_class(id, CL_DEF) ? "defined" : "declared")
+
+
+/******** M A I N ********/
 
 main(argc, argv)
        char *argv[];
 {
-       struct inpdef *id;
-
        init(argc, argv);
 
-       get_dot_id();
-       while (dot_id) {
-               cur_name = dot_id->id_name;
-               read_defs();
-               while (dot_id && same_name()) {
-                       id = id_read();
-                       check(id);
-                       free_inpdef(id);
+       dot = new_inpdef();
+       get_dot();
+       while (dot) {
+               if (lib) {
+                       free_inpdef(lib);
+                       lib = 0;
+               }
+               if (ext) {
+                       free_inpdef(ext);
+                       ext = 0;
+               }
+               strcpy(cur_name, dot->id_name);
+               lib_def();
+               ext_def();
+               ext_decls();
+               usage(0);
+               if (ext)
+                       check_def(ext);
+               statics();
+               /* inpdefs of class ERRCL are never generated */
+               if (same_name()) {
+                       /*      there are more lines for this name that have
+                               not been absorbed
+                       */
+                       panic("sequence error in intermediate file");
                }
-               check_usage();
-               free_defs();
        }
 }
 
@@ -50,13 +59,14 @@ static char *table[] = {0};
 init(argc, argv)
        char *argv[];
 {
-/* Prepare standard input for reading using the input-package
- * Read first inpdef into dot_id
+/*
  * Parse options
+ * Prepare standard input for reading using the input-package
  */
-
        char *result;
 
+       init_class();
+
        while (argc > 1 && *argv[1] == '-') {
                switch (argv[1][1]) {
                case 'u':
@@ -67,7 +77,7 @@ init(argc, argv)
                        options[argv[1][1]] = 1;
                        break;
                default:
-                       /* ready to extend */
+                       /* ready to be extended */
                        break;
                }
                argc--, argv++;
@@ -77,248 +87,295 @@ init(argc, argv)
                panic("InsertFile() fails");
 }
 
-read_defs()
+get_dot()
 {
-       struct inpdef *id;
+       if (!get_id(dot)) {
+               free_inpdef(dot);
+               dot = 0;
+               cur_name[0] = '\0';
+       }
+}
 
-       if (ext_def || static_def)
-               panic("read_defs: slate not clean");/*???*/
-
-       while (dot_id && same_name() && is_def(dot_id)) {
-               id = id_read();
-               switch (id->id_class) {
-               case EFDF:
-               case EVDF:
-                       if (ext_def) {
-                               report("%L: %s also defined at %L",
-                                       id, id->id_name, ext_def);
-                               free_inpdef(id);
-                       }
-                       else {
-                               ext_def = id;
-                       }
-                       break;
-               case SFDF:
-               case SVDF:
-                       if (ext_def) {
-                               report("%L: %s also defined at %L",
-                                       id, id->id_name, ext_def);
-                               free_inpdef(id);
-                       }
-                       else {
-                               static_in_list(id);
-                       }
-                       break;
-               case LFDF:
-               case LVDF:
-                       if (ext_def) {
-                               /* Some libraries contain more than one
-                                * definition
-                                */
-                               if (is_lib_class(ext_def->id_class)) {
-                                       report("%L: %s redefined in library %L",
-                                               id, id->id_name, ext_def);
-                               }
-                               free_inpdef(id);
-                       }
-                       else {
-                               ext_def = id;
-                       }
-                       break;
-               default:
-                       panic("invalid class (%c) in read_defs", id->id_class);
+
+/******** L I B R A R Y ********/
+
+lib_def()
+{
+       if (same_obj(0) && is_class(dot, CL_LIB)) {
+               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();
+       }
+}
+
+
+/******** E X T E R N ********/
+
+ext_def()
+{
+       if (same_obj(0) && is_class(dot, CL_EXT|CL_DEF)) {
+               if (lib) {
+                       report("%L: %s also defined in library %L",
+                               dot, dot->id_name, lib);
                }
+               ext = dot;
+               dot = new_inpdef();
+               get_dot();
+       }
+
+       while (same_obj(0) && is_class(dot, CL_EXT|CL_DEF)) {
+               report("%L: %s also defined at %L",
+                       dot, dot->id_name, ext);
+               get_dot();
        }
 }
 
-struct inpdef *
-id_read()
+ext_decls()
 {
-/* Returns the value of dot_id if present, 0 otherwise.
- * Reads a new inpdef ahead, to which dot_id will be pointing.
- * Cur_name will be pointing to id_name of the returned inpdef.
- */
-       struct inpdef *old_id;
-
-       if (!dot_id)
-               return (0);
-       old_id = dot_id;
-       cur_name = old_id->id_name;
-       get_dot_id();
-       return (old_id);
+       while (same_obj(0) && dot->id_class == EFDC) {
+               one_ext_decl("function", "variable", CL_VAR);
+       }
+
+       while (same_obj(0) && dot->id_class == EVDC) {
+               one_ext_decl("variable", "function", CL_FUNC);
+       }
+
+       while (same_obj(0) && dot->id_class == IFDC) {
+               one_ext_decl("function", "variable", CL_VAR);
+       }
 }
 
-get_dot_id()
+one_ext_decl(kind, other_kind, other_class)
+       char *kind;
+       char *other_kind;
+       int other_class;
 {
-/* Allocates a new inpdef, calls it dot_id and fills it */
-       dot_id = new_inpdef();
-       if (!get_id(dot_id)) {
-               free_inpdef(dot_id);
-               cur_name = "";
-               dot_id = 0;
+       struct inpdef *def = ext ? ext : lib ? lib : 0;
+
+       if (!def) {
+               /* the declaration will have to serve */
+               if (!is_class(dot, CL_IMPL) && !options['u']) {
+                       report("%L: %s %s declared but never defined",
+                               dot, dot->id_name, kind);
+               }
+               ext = dot;
+               dot = new_inpdef();
+               get_dot();
+               return;
+       }
+
+       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);
+               /* no further testing possible */
+               return;
        }
+
+       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);
+       }
+
+       get_dot();
 }
 
-struct inpdef *definition();
 
-check(id)
-       struct inpdef *id;
+/******** U S A G E ********/
+
+usage(stnr)
+       int stnr;
 {
-/* Checks a declaration, function call or variable usage, described by id,
- * against the definitions.
- */
-       struct inpdef *idef;
+       struct inpdef *def = stnr ? sta : ext ? ext : lib ? lib : 0;
 
-       idef = definition(id);
-       switch (id->id_class) {
-       case EFDC:
-               if (!idef) {
-                       if (!options['u']) {
-                               report("%L: %s declared but never defined",
-                                       id, id->id_name);
-                       }
-                       discard_defs();
-                       break;
-               }
-               if (idef->id_class == EVDF || idef->id_class == LVDF) {
-                       report("%L: function %s declared as variable at %L",
-                               id, id->id_name, idef);
-                       break;
+       while (same_obj(stnr) && dot->id_class == FC) {
+               one_func_call(def);
+       }
+
+       while (same_obj(stnr) && dot->id_class == VU) {
+               one_var_usage(def);
+       }
+}
+
+one_func_call(def)
+       struct inpdef *def;
+{
+       if (!def) {
+               if (!options['u']) {
+                       report("%L: function %s used but not defined",
+                               dot, dot->id_name);
                }
-               if (!type_equal(id->id_type, idef->id_type)) {
-                       report("%L: value of function %s declared differently at %L",
-                               id, id->id_name, idef);
+               get_dot();
+               return;
+       }
+
+       def->id_called = 1;
+
+       if (def->id_args) {
+               check_args(dot, def);
+               if (dot->id_valused == USED && !def->id_valreturned) {
+                       report("%L: value of %s is used, but none is returned at %L",
+                               dot, dot->id_name, def);
                }
+       }
+
+       switch (dot->id_valused) {
+       case USED:
+               def->id_used = 1;
                break;
-       case EVDC:
-               if (!idef) {
-                       if (!options['u']) {
-                               report("%L: %s declared but never defined",
-                                       id, id->id_name);
-                       }
-                       discard_defs();
-                       break;
-               }
-               if (idef->id_class == EFDF || idef->id_class == LFDF) {
-                       report("%L: variable %s declared as function at %L",
-                               id, id->id_name, idef);
-                       break;
-               }
-               if (!type_equal(id->id_type, idef->id_type)) {
-                       report("%L: variable %s declared differently at %L",
-                               id, id->id_name, idef);
-               }
+       case IGNORED:
+               def->id_ignored = 1;
                break;
-       case IFDC:
-               if (!idef)
-                       break;          /* used but not defined */
-               if (idef->id_class == EVDF || idef->id_class == LVDF) {
-                       report("%L: function %s declared as variable at %L",
-                               id, id->id_name, idef);
-                       break;
-               }
-               if (!type_equal(id->id_type, idef->id_type)) {
-                       report("%L: function value of %s declared differently at %L",
-                               id, id->id_name, idef);
-               }
+       case VOIDED:
+               def->id_voided = 1;
                break;
-       case FC:
-               if (!idef) {
-                       if (!options['u']) {
-                               report("%L: function %s used but not defined",
-                                       id, id->id_name);
-                       }
-                       discard_defs();
-                       break;
+       default:
+               panic("invalid dot->id_valused in check");
+               break;
+       }
+
+       get_dot();
+}
+
+one_var_usage(def)
+       struct inpdef *def;
+{
+       if (!def) {
+               if (!options['u']) {
+                       report("%L: variable %s used but not defined",
+                               dot, dot->id_name);
                }
-               idef->id_called = 1;
-               check_args(id, idef);
-               if (id->id_returns == USED && !idef->id_returns) {
-                       report("%L: value of %s is used, but none is returned at %L",
-                               id, id->id_name, idef);
+               get_dot();
+               return;
+       }
+
+       def->id_called = 1;
+
+       get_dot();
+}
+
+
+/******** S T A T I C ********/
+
+statics()
+{
+       while (same_name() && dot->id_statnr != 0) {
+               one_static(dot->id_statnr);
+       }
+}
+
+one_static(stnr)
+       int stnr;
+{
+       while (same_obj(stnr)) {
+               if (sta) {
+                       free_inpdef(sta);
+                       sta = 0;
                }
-               switch (id->id_returns) {
-               case USED:
-                       idef->id_used = 1;
-                       break;
-               case IGNORED:
-                       idef->id_ignored = 1;
-                       break;
-               case VOIDED:
-                       idef->id_voided = 1;
-                       break;
-               default:
-                       panic("invalid id->id_returns in check");
+               stat_def(stnr);
+               usage(stnr);
+               if (sta)
+                       check_def(sta);
+               get_dot();
+       }
+}
+
+stat_def(stnr)
+       int stnr;
+{
+       if (same_obj(stnr) && is_class(dot, CL_STAT|CL_DEF)) {
+               if (lib) {
+                       report("%L: %s also defined in library %L",
+                               dot, dot->id_name, lib);
                }
-               break;
-       case VU:
-               if (!idef) {
-                       if (!options['u']) {
-                               report("%L: variable %s used but not defined",
-                                       id, id->id_name);
-                       }
-                       discard_defs();
-                       break;
+               if (ext) {
+                       report("%L: %s also %s at %L",
+                               dot, dot->id_name, defdec(ext), ext);
                }
-               idef->id_called = 1;
-               break;
-       case EFDF:
-       case SFDF:
-       case EVDF:
-       case SVDF:
-       case LFDF:
-       case LVDF:
-               panic("check() called for a definition");
-               break;
-       default:
-               panic("invalid class (%c) in check", id->id_class);
-               break;
+               sta = dot;
+               dot = new_inpdef();
+               get_dot();
+       }
+
+       while (same_obj(stnr) && is_class(dot, CL_STAT|CL_DEF)) {
+               report("%L: %s also defined at %L",
+                       dot, dot->id_name, sta);
+               get_dot();
        }
 }
 
-discard_defs()
+check_def(def)
+       struct inpdef *def;
 {
-/* Read until a definition having another name */
+       if (!def)
+               return;
 
-       struct inpdef *id;
+       if (!def->id_called) {
+               if (streq(def->id_name, "main")) {
+                       /* silent */
+               }
+               else if (ext && is_class(ext, CL_LIB)) {
+                       /* silent */
+               }
+               else {
+                       if (!options['u']) {
+                               report("%L: %s %s but never used",
+                                       def, def->id_name, defdec(def));
+                       }
+               }
+       }
 
-       while (dot_id && same_name()) {
-               id = id_read();
-               free_inpdef(id);
+       if (is_class(def, CL_DEF|CL_FUNC)) {
+               if (def->id_valreturned && def->id_called && def->id_ignored) {
+                       report("%L: %s returns value which is %s ignored",
+                               def, def->id_name,
+                               (def->id_used || def->id_voided) ?
+                                               "sometimes" : "always");
+               }
        }
 }
 
-check_args(id, idef)
-       struct inpdef *id, *idef;
+
+/******** T Y P E   C H E C K I N G ********/
+
+check_args(id, def)
+       struct inpdef *id, *def;
 {
        register char *act_tp = id->id_argtps;
-       register char *def_tp = idef->id_argtps;
+       register char *def_tp = def->id_argtps;
        register int i;
        register int nrargs;            /* # of args to be type-checked */
        register int varargs;
 
        /* determine nrargs */
-       if (idef->id_nrargs < 0) {
+       if (def->id_nrargs < 0) {
                varargs = 1;
-               nrargs = -idef->id_nrargs - 1;
+               nrargs = -def->id_nrargs - 1;
        }
        else {
                varargs = 0;
-               nrargs = idef->id_nrargs;
+               nrargs = def->id_nrargs;
        }
 
        /* adjust nrargs, if necessary */
        if (varargs) {
                if (nrargs > id->id_nrargs) {
                        report("%L: number of args to %s differs from %L",
-                               id, id->id_name, idef);
+                               id, id->id_name, def);
                        nrargs = id->id_nrargs;
                }
        }
        else {
                if (nrargs != id->id_nrargs) {
                        report("%L: number of args to %s differs from %L",
-                               id, id->id_name, idef);
+                               id, id->id_name, def);
                        nrargs = min(nrargs, id->id_nrargs);
                }
        }
@@ -346,19 +403,27 @@ check_args(id, idef)
 
                if (!type_match(act, def)) {
                        report("%L: arg %d of %s differs from that at %L",
-                               id, i, id->id_name, idef);
+                               id, i, id->id_name, def);
                }
                *act_tp++ = ':';
                *def_tp++ = ':';
        }
 }
 
+int
+type_equal(act, def)
+       char *act, *def;
+{
+       return streq(act, def);
+}
+
 int
 type_match(act, def)
        char *act, *def;
 {
        if (type_equal(act, def))
                return 1;
+
        if (act[0] == '+') {
                /* a non-negative constant */
                /* might be signed or unsigned */
@@ -373,181 +438,22 @@ type_match(act, def)
        return 0;
 }
 
-check_usage()
-{
-/* Checks if the defined function or variable is used.
- * There can be several static definitions.
- */
 
-       struct inpdef *sd = static_def;
-
-       if (ext_def)
-               check_def(ext_def);
-       while (sd) {
-               check_def(sd);
-               sd = sd->next;
-       }
-}
+/******** D E B U G G I N G ********/
 
-check_def(id)
-       struct inpdef *id;
-{
-       if (!id->id_called) {
-               if (streq(id->id_name, "main")) {
-                       /* silent */
-               }
-               else if (ext_def && is_lib_class(ext_def->id_class)) {
-                       /* silent */
-               }
-               else {
-                       if (!options['u']) {
-                               report("%L: %s defined but never used",
-                                       id, id->id_name);
-                       }
-               }
-       }
-
-       if (is_fundef_class(id->id_class)) {
-               if (id->id_returns && id->id_called && id->id_ignored) {
-                       report("%L: %s returns value which is %s ignored",
-                               id, id->id_name,
-                               (id->id_used || id->id_voided) ?
-                                               "sometimes" : "always");
-               }
-       }
-}
-
-static_in_list(id)
-       struct inpdef *id;
-{
-/* Put id in the list of static definitions.
- * static_def points to the first element.
- */
-       id->next = static_def;
-       static_def = id;
-}
-
-struct inpdef *
-definition(id)
-       struct inpdef *id;
-{
-/* If there is a static definition that comes from the same file, a pointer
- * to this definition will be returned.
- * Otherwise a pointer to the ext_def is returned (which may be null).
- */
-       struct inpdef *sd = static_def;
-
-       while (sd) {
-               if (id->id_statnr == sd->id_statnr)
-                       return (sd);
-               sd = sd->next;
-       }
-       return (ext_def);
-}
-
-free_defs()
-{
-/* Dispose the external definition and the static definitions. */
-       struct inpdef *sd;
-
-       if (ext_def) {
-               free_inpdef(ext_def);
-               ext_def = 0;
-       }
-       while (static_def) {
-               sd = static_def;
-               static_def = static_def->next;
-               free_inpdef(sd);
-       }
-}
-
-/* VARARGS */
-report(va_alist)
-       va_dcl
-{
-       va_list ap;
-
-       va_start(ap);
-       {
-               char *fmt = va_arg(ap, char*);
-               register char *f = fmt;
-               register char fc;
-
-               /*      First see if the first arg is an inpdef with
-                       a global file name; if so, skip this message.
-               */
-               if (f[0] == '%' && f[1] == 'L') {
-                       /* it is an inpdef */
-                       register struct inpdef *id =
-                               va_arg(ap, struct inpdef *);
-
-                       f += 2;
-                       /* is the file name global? */
-                       if (id->id_file[0] == '/')
-                               return;
-                       /*      if no, we have used up the argument,
-                               so print it here
-                       */
-                       fprint(MSGOUT, "\"%s\", line %d",
-                               id->id_file, id->id_line);
-               }
-               while ((fc = *f++)) {
-                       if (fc == '%') {
-                               switch (*f++) {
-                                       register struct inpdef *id;
-                                       register char *s;
-                                       register int i;
-                               case 'L':       /* a location item */
-                                       id = va_arg(ap, struct inpdef *);
-                                       fprint(MSGOUT, "\"%s\", line %d",
-                                               id->id_file, id->id_line);
-                                       break;
-                               case 's':       /* a string item */
-                                       s = va_arg(ap, char *);
-                                       fprint(MSGOUT, "%s", s);
-                                       break;
-                               case 'd':       /* an int item */
-                                       i = va_arg(ap, int);
-                                       fprint(MSGOUT, "%d", i);
-                                       break;
-                               default:
-                                       panic("bad format %s", fmt);
-                                       break;
-                               }
-                       }
-                       else {
-                               fprint(MSGOUT, "%c", fc);
-                       }
-               }
-               fprint(MSGOUT, "\n");
-       }
-       va_end(ap);
-}
-
-/* VARARGS1 */
-panic(fmt, args)
-       char *fmt;
-{
-       fprint(ERROUT, "PANIC, lint, pass2: ");
-       doprnt(ERROUT, fmt, &args);
-       fprint(ERROUT, "\n");
-       exit(1);
-}
-
-/* for DEBUGGING */
 print_id(id)
        struct inpdef *id;
 {
-       print("inpdef: %s, %s, %04d, \"%s\", %d, %d, %s, %d, %s\n",
-               id->id_class == EFDF ? "EFDF" :
-               id->id_class == SFDF ? "SFDF" :
-               id->id_class == EVDF ? "EVDF" :
-               id->id_class == SVDF ? "SVDF" :
+       print("inpdef: %s, %s, %04d, \"%s\", %d, %s",
                id->id_class == LFDF ? "LFDF" :
                id->id_class == LVDF ? "LVDF" :
+               id->id_class == EFDF ? "EFDF" :
+               id->id_class == EVDF ? "EVDF" :
                id->id_class == EFDC ? "EFDC" :
                id->id_class == EVDC ? "EVDC" :
                id->id_class == IFDC ? "IFDC" :
+               id->id_class == SFDF ? "SFDF" :
+               id->id_class == SVDF ? "SVDF" :
                id->id_class == FC ? "FC" :
                id->id_class == VU ? "VU" :
                id->id_class == ERRCL ? "ERRCL" : "<BADCLASS>",
@@ -555,9 +461,21 @@ print_id(id)
                id->id_statnr,
                id->id_file,
                id->id_line,
-               id->id_nrargs,
-               ((id->id_nrargs == 0) ? "" : id->id_argtps),
-               id->id_returns,
-               id->id_type);
+               id->id_type
+       );
+       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 ? "VALRETURNED" :
+                               "NOVALRETURNED")
+               );
+       }
+       print("\n");
 }
 
index 1c979d8..e97a0ca 100644 (file)
@@ -1,12 +1,13 @@
-#include "../lpass1/l_class.h"
-#include "inpdef.h"
+#include       "../lpass1/l_class.h"
+#include       "class.h"
+#include       "inpdef.h"
 
-#include <ctype.h>
+#include       <ctype.h>
 
 #define        INP_NPUSHBACK 2
 
-#include <inp_pkg.spec>
-#include <inp_pkg.body>
+#include       <inp_pkg.spec>
+#include       <inp_pkg.body>
 
 PRIVATE int LineNr = 1;
 
@@ -25,37 +26,49 @@ int
 get_id(id)
        struct inpdef *id;
 {
-/* A low-level function which just reads a definition */
+       /* A low-level function which just reads a definition */
 
        if (!ReadString(id->id_name, ':', NAMESIZE))
                return 0;
        if (!ReadInt(&id->id_statnr))
                return 0;
        SkipChar(':');
+
        loadchar(id->id_class);
        if (id->id_class == EOI)
                return 0;
        SkipChar(':');
-       switch (id->id_class) {
-       case EFDF:
-       case SFDF:
-       case LFDF:
-       case FC:
+
+       if (is_class(id, CL_FUNC|CL_DEF) || is_class(id, CL_FUNC|CL_USAGE)) {
+               /* read the argument information */
+               id->id_args = 1;
                if (!ReadInt(&id->id_nrargs))
                        return 0;
                SkipChar(':');
                if (!ReadArgs(id->id_nrargs, id->id_argtps))
                        return 0;
-               if (!ReadInt(&id->id_returns))
-                       return 0;
+               if (id->id_class == FC) {
+                       /* function call */
+                       if (!ReadInt(&id->id_valused))
+                               return 0;
+               }
+               else {
+                       /* function definition */
+                       if (!ReadInt(&id->id_valreturned))
+                               return 0;
+               }
                SkipChar(':');
-               break;
        }
+       else {
+               id->id_args = 0;
+       }
+
        if (!ReadString(id->id_type, ':', TYPESIZE))
                return 0;
        if (!ReadInt(&id->id_line))
                return 0;
        SkipChar(':');
+
        if (!ReadString(id->id_file, '\n', FNAMESIZE))
                return 0;
        {       extern char options[];
@@ -69,14 +82,16 @@ PRIVATE int
 ReadString(buf, delim, maxsize)
        char *buf;
 {
-/* Reads a string until 'delim' is encountered.
- * Delim is discarded.
- * If 'maxsize-1' is exceeded, "string too long" is written by panic().
- * A '\0' is appended to the string.
- * At EOI 0 is returned, else the length of the string (including
- * the appended '\0') is returned.
- */
-       int ch;
+       /*      Reads a string until 'delim' is encountered.
+               Delim is discarded.
+               If 'maxsize-1' is exceeded, "string too long" is written
+               by panic().
+               A '\0' is appended to the string.
+               At EOI 0 is returned, else the length of the string (including
+               the appended '\0') is returned.
+       */
+
+       int ch = 0;
        int nread = 0;
 
        while (nread < maxsize - 1) {
@@ -87,11 +102,11 @@ ReadString(buf, delim, maxsize)
                        break;
                buf[nread++] = (char)ch;
        }
+       buf[nread++] = '\0';
        if (ch != delim) {
                panic("line %d: string too long: %s", LineNr, buf);
                /*NOTREACHED*/
        }
-       buf[nread++] = '\0';
        return (nread);
 }
 
diff --git a/lang/cem/lint/lpass2/report.c b/lang/cem/lint/lpass2/report.c
new file mode 100644 (file)
index 0000000..14f54ba
--- /dev/null
@@ -0,0 +1,81 @@
+#include       <varargs.h>
+
+#include       <system.h>
+#include       "inpdef.h"
+
+#define        MSGOUT          STDERR  /* filedes on which to write the messages */
+#define        ERROUT          STDERR  /* filedes on which to write the panics */
+
+/* VARARGS */
+report(va_alist)
+       va_dcl
+{
+       va_list ap;
+
+       va_start(ap);
+       {
+               char *fmt = va_arg(ap, char*);
+               register char *f = fmt;
+               register char fc;
+
+               /*      First see if the first arg is an inpdef with
+                       a global file name; if so, skip this message.
+               */
+               if (f[0] == '%' && f[1] == 'L') {
+                       /* it is an inpdef */
+                       register struct inpdef *id =
+                               va_arg(ap, struct inpdef *);
+
+                       f += 2;
+                       /* is the file name global? */
+                       if (id->id_file[0] == '/')
+                               return;
+                       /*      if no, we have used up the argument,
+                               so print it here
+                       */
+                       fprint(MSGOUT, "\"%s\", line %d",
+                               id->id_file, id->id_line);
+               }
+               while ((fc = *f++)) {
+                       if (fc == '%') {
+                               switch (*f++) {
+                                       register struct inpdef *id;
+                                       register char *s;
+                                       register int i;
+                               case 'L':       /* a location item */
+                                       id = va_arg(ap, struct inpdef *);
+                                       fprint(MSGOUT, "\"%s\", line %d",
+                                               id->id_file, id->id_line);
+                                       break;
+                               case 's':       /* a string item */
+                                       s = va_arg(ap, char *);
+                                       fprint(MSGOUT, "%s", s);
+                                       break;
+                               case 'd':       /* an int item */
+                                       i = va_arg(ap, int);
+                                       fprint(MSGOUT, "%d", i);
+                                       break;
+                               default:
+                                       panic("bad format %s", fmt);
+                                       break;
+                               }
+                       }
+                       else {
+                               fprint(MSGOUT, "%c", fc);
+                       }
+               }
+               fprint(MSGOUT, "\n");
+       }
+       va_end(ap);
+}
+
+/* VARARGS1 */
+panic(fmt, args)
+       char *fmt;
+{
+       fprint(ERROUT, "PANIC, lint, pass2: ");
+       doprnt(ERROUT, fmt, &args);
+       fprint(ERROUT, "\n");
+       exit(1);
+}
+