ANSI C prototype handling added

This commit is contained in:
dick 1991-03-08 15:54:05 +00:00
parent 30867cf631
commit 67a2cc281f
7 changed files with 196 additions and 129 deletions

View 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

View 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 != ':') {

View 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;
}

View 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))

View 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)
chk_def(sta);
if (same_obj(stnr))
panic("sequence error in input");
if (sta) {
chk_def(sta);
}
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");

View 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*/
}

View 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;
}
}