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 # M A K E F I L E F O R L P A S S 2
# Machine and environ dependent definitions # Machine and environ dependent definitions
EMHOME = /usr/proj/em/Work EMHOME = ../../..
LPASS1 = $(EMHOME)/lang/cem/cemcom LPASS1 = ../lpass1# ???
# Libraries and EM interface definitions # Libraries and EM interface definitions
SYSLIB = $(EMHOME)/modules/lib/libsystem.a 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 OBJ = lpass2.o checkargs.o read.o report.o class.o l_print3ack.o
test: lpass2 test: lpass2
make lint.test lpass2 -xh <proto.tst
# lpass2 -xh <.i # make lint.test
lpass2: $(OBJ) Makefile next.o lpass2: $(OBJ) Makefile next.o
@ -37,7 +37,7 @@ lpass2: $(OBJ) Makefile next.o
size lpass2 size lpass2
lint.test: lint.test:
./lint -xh $(CFLAGS) $(SRC) next.c #??? ./lint -h $(CFLAGS) $(SRC) next.c #???
next.c: $(LPASS1)/make.next inpdef.str next.c: $(LPASS1)/make.next inpdef.str
$(LPASS1)/make.next inpdef.str > next.c $(LPASS1)/make.next inpdef.str > next.c
@ -49,7 +49,8 @@ clean:
rm -f a.out core next.c inpdef.h $(OBJ) next.o 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 class.o: ../lpass1/l_class.h class.h
lpass2.o: ../lpass1/l_class.h ../lpass1/l_lint.h class.h inpdef.h private.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 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 char formatargs[1000]; /* the definitions */
PRIVATE chk_argtps(); PRIVATE chk_argtps();
PRIVATE char *next_atype(); PRIVATE char *next_argtype();
PRIVATE int type_match(); PRIVATE int type_match();
PRIVATE form_type(); PRIVATE form_type();
@ -37,6 +37,14 @@ chk_args(id, def)
char *act_tp = id->id_argtps; char *act_tp = id->id_argtps;
int nrargs = 0; /* number of args */ 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 */ /* clear format */
is_formatargs = 0; is_formatargs = 0;
@ -49,7 +57,7 @@ chk_args(id, def)
/* skip over the actuals already covered */ /* skip over the actuals already covered */
for (i = 0; i < nrargs; i++) { for (i = 0; i < nrargs; i++) {
act_tp = next_atype(act_tp); act_tp = next_argtype(act_tp);
} }
/* and check the format arguments */ /* 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 *act_tp; /* actual types */
char *form_tp; /* formal type definitions */ 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 *act_start = act_tp;
register char *form_start = form_tp; register char *form_start = form_tp;
/* isolate actual argument type */ /* isolate actual argument type */
act_tp = next_atype(act_tp); act_tp = next_argtype(act_tp);
act_tp[-1] = '\0'; act_tp[-1] = '\0';
/* isolate formal argument type */ /* isolate formal argument type */
form_tp = next_atype(form_tp); form_tp = next_argtype(form_tp);
form_tp[-1] = '\0'; form_tp[-1] = '\0';
(*nrargs)++; (*nrargs)++;
@ -92,6 +100,9 @@ PRIVATE chk_argtps(id, def, nrargs, act_tp, form_tp)
form_tp[-1] = ':'; form_tp[-1] = ':';
} }
if (*form_tp == '.') /* ellipsis */
return;
if (*form_tp) { if (*form_tp) {
/* formal type definitions not exhausted */ /* formal type definitions not exhausted */
report("%L: %s has fewer arguments than in %L", 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 * PRIVATE char *
next_atype(tp) next_argtype(tp)
char *tp; char *tp;
{ {
while (*tp && *tp != ':') { while (*tp && *tp != ':') {

View file

@ -7,47 +7,23 @@
#include "../lpass1/l_class.h" #include "../lpass1/l_class.h"
#include "class.h" #include "class.h"
int class[] = { int class[MAX_CLASS_CONST-MIN_CLASS_CONST+1];
/* 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() init_class()
{ {
/* The initialization of class[] has been taken care of above. /* mapping of class values onto bit patterns */
For it to work, we have to test that the class values are class[LFDF-LFDF] = CL_LIB | CL_FUNC | CL_DEF;
in the right order. This is also necessary for the scanning class[LVDF-LFDF] = CL_LIB | CL_VAR | CL_DEF;
sequence in lpass2.c to work properly. class[PFDF-LFDF] = CL_EXT | CL_FUNC | CL_DEF;
*/ class[EFDF-LFDF] = CL_EXT | CL_FUNC | CL_DEF;
int i; class[EVDF-LFDF] = CL_EXT | CL_VAR | CL_DEF;
class[EFDC-LFDF] = CL_EXT | CL_FUNC | CL_DECL;
for (i = 0; i+1 < sizeof(val)/sizeof(val[0]); i++) { class[EVDC-LFDF] = CL_EXT | CL_VAR | CL_DECL;
if (val[i] >= val[i+1]) class[IFDC-LFDF] = CL_IMPL | CL_FUNC | CL_DECL;
panic("class values out of sequence"); 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[]; 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) #define streq(s1,s2) (strcmp(s1, s2) == 0)
PRIVATE char cur_name[NAMESIZE]; 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 chk_def();
PRIVATE ext_decls(); PRIVATE ext_decls();
PRIVATE proto_defs();
PRIVATE chk_proto();
PRIVATE ext_def(); PRIVATE ext_def();
PRIVATE get_dot(); PRIVATE get_dot();
PRIVATE init(); PRIVATE init();
@ -35,8 +38,8 @@ PRIVATE usage();
#define same_name() (dot && streq(cur_name, dot->id_name)) #define same_name() (dot && streq(cur_name, dot->id_name))
#define same_obj(stnr) (same_name() && dot->id_statnr == stnr) #define same_obj(stnr) (same_name() && dot->id_statnr == stnr)
#define defdec(id) (is_class(id, CL_DEF) ? "defined" : "declared") #define def_or_dec(id) (is_class(id, CL_DEF) ? "defined" : "declared")
#define funvar(id) (is_class(id, CL_FUNC) ? "function" : "variable") #define fun_or_var(id) (is_class(id, CL_FUNC) ? "function" : "variable")
/******** M A I N ********/ /******** M A I N ********/
@ -53,24 +56,15 @@ main(argc, argv)
free_inpdef(lib); free_inpdef(lib);
lib = 0; lib = 0;
} }
if (proto) {
free_inpdef(proto);
proto = 0;
}
if (ext) { if (ext) {
free_inpdef(ext); free_inpdef(ext);
ext = 0; ext = 0;
} }
strcpy(cur_name, dot->id_name); one_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");
}
} }
} }
@ -81,7 +75,7 @@ PRIVATE init(argc, argv)
char *argv[]; char *argv[];
{ {
/* /*
* Parse options * Get command line options
* Prepare standard input for reading using the input-package * Prepare standard input for reading using the input-package
*/ */
char *result; char *result;
@ -107,8 +101,9 @@ PRIVATE init(argc, argv)
argc--, argv++; argc--, argv++;
} }
if (!InsertFile((char *)0, table, &result)) if (!InsertFile((char *)0, table, &result)) {
panic("InsertFile() fails"); panic("InsertFile() fails");
}
} }
PRIVATE get_dot() PRIVATE get_dot()
@ -118,8 +113,32 @@ PRIVATE get_dot()
dot = 0; dot = 0;
cur_name[0] = '\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 ********/ /******** L I B R A R Y ********/
@ -129,12 +148,42 @@ PRIVATE lib_def()
lib = dot; lib = dot;
dot = new_inpdef(); dot = new_inpdef();
get_dot(); 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", /******** P R O T O T Y P E S ********/
dot, dot->id_name); 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(); 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() PRIVATE ext_def()
{ {
if (same_obj(0) && is_class(dot, CL_EXT|CL_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", 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; ext = dot;
dot = new_inpdef(); dot = new_inpdef();
get_dot(); get_dot();
} while (same_obj(0) && is_class(dot, CL_EXT|CL_DEF)) {
report("%L: %s %s also defined at %L",
while (same_obj(0) && is_class(dot, CL_EXT|CL_DEF)) { dot, fun_or_var(dot), dot->id_name, ext);
report("%L: %s %s also defined at %L", get_dot();
dot, funvar(dot), dot->id_name, ext); }
get_dot();
} }
} }
@ -180,7 +231,7 @@ PRIVATE one_ext_decl(kind, other_kind, other_class)
char *other_kind; char *other_kind;
int other_class; int other_class;
{ {
struct inpdef *def = ext ? ext : lib ? lib : 0; struct inpdef *def = (proto ? proto : ext ? ext : lib ? lib : 0);
if (!def) { if (!def) {
/* the declaration will have to serve */ /* 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)) { if (is_class(def, other_class)) {
/* e.g.: function FFF declared as variable at ... */ /* e.g.: function FFF declared as variable at ... */
report("%L: %s %s %s as %s at %L", 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 */ /* no further testing possible */
get_dot(); get_dot();
return; return;
@ -202,7 +255,11 @@ PRIVATE one_ext_decl(kind, other_kind, other_class)
if (!type_equal(dot->id_type, def->id_type)) { if (!type_equal(dot->id_type, def->id_type)) {
/* e.g.: type of variable VVV defined differently at ... */ /* e.g.: type of variable VVV defined differently at ... */
report("%L: type of %s %s %s differently at %L", 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(); get_dot();
@ -214,7 +271,8 @@ PRIVATE one_ext_decl(kind, other_kind, other_class)
PRIVATE usage(stnr) PRIVATE usage(stnr)
int 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_count = 0;
register int VU_samefile = 0; register int VU_samefile = 0;
@ -236,8 +294,9 @@ PRIVATE usage(stnr)
if ( stnr == 0 if ( stnr == 0
&& VU_count == 1 && VU_count == 1
&& VU_samefile == 1 && VU_samefile == 1
&& def == ext && ( def == proto
&& !is_class(ext, CL_IMPL) || (def == ext && !is_class(ext, CL_IMPL))
)
&& streq(&fn[strlen(fn)-2], ".c") && streq(&fn[strlen(fn)-2], ".c")
) { ) {
report("%L: extern %s could be declared static", report("%L: extern %s could be declared static",
@ -313,20 +372,25 @@ PRIVATE statics()
while (same_name()) { while (same_name()) {
int stnr = dot->id_statnr; int stnr = dot->id_statnr;
if (stnr == 0) if (stnr == 0) {
panic("sequence error in input"); panic("sequence error in intermediate file: externals after statics");
}
if (sta) { if (sta) {
free_inpdef(sta); free_inpdef(sta);
sta = 0; sta = 0;
} }
stat_def(stnr); stat_def(stnr);
usage(stnr); usage(stnr);
if (sta)
chk_def(sta);
if (same_obj(stnr)) if (sta) {
panic("sequence error in input"); 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 (same_obj(stnr) && is_class(dot, CL_STAT|CL_DEF)) {
if (lib) { if (lib) {
report("%L: %s %s also defined in %L", 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 (proto || ext) {
if (!streq(dot->id_file, ext->id_file)) { struct inpdef *def = (proto ? proto : ext);
if (!streq(dot->id_file, def->id_file)) {
report("%L: %s %s also %s at %L", report("%L: %s %s also %s at %L",
dot, funvar(dot), dot->id_name, dot, fun_or_var(dot), dot->id_name,
defdec(ext), ext); def_or_dec(def), def
);
} }
} }
sta = dot; sta = dot;
dot = new_inpdef(); dot = new_inpdef();
get_dot(); get_dot();
} while (same_obj(stnr) && is_class(dot, CL_STAT|CL_DEF)) {
report("%L: %s %s also defined at %L",
while (same_obj(stnr) && is_class(dot, CL_STAT|CL_DEF)) { dot, fun_or_var(dot), dot->id_name, sta);
report("%L: %s %s also defined at %L", get_dot();
dot, funvar(dot), dot->id_name, sta); }
get_dot();
} }
} }
@ -373,7 +439,7 @@ PRIVATE chk_def(def)
else { else {
if (!loptions['u']) { if (!loptions['u']) {
report("%L: %s %s not used anywhere", 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; char *name;
struct inpdef *id; struct inpdef *id;
{ {
if (!id) {
print("%s: <NO_INPDEF>\n", name);
return;
}
print("%s: %s, %s, %04d, \"%s\", %d, %s", name, print("%s: %s, %s, %04d, \"%s\", %d, %s", name,
id->id_class == LFDF ? "LFDF" : id->id_class == LFDF ? "LFDF" :
id->id_class == LVDF ? "LVDF" : id->id_class == LVDF ? "LVDF" :
id->id_class == PFDF ? "PFDF" :
id->id_class == EFDF ? "EFDF" : id->id_class == EFDF ? "EFDF" :
id->id_class == EVDF ? "EVDF" : id->id_class == EVDF ? "EVDF" :
id->id_class == EFDC ? "EFDC" : 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)) { if (is_class(id, CL_FUNC|CL_DEF) || is_class(id, CL_FUNC|CL_USAGE)) {
print(", %d, %s, %s", print(", %d, %s, %s",
id->id_nrargs, id->id_nrargs,
id->id_nrargs == 0 ? "" : id->id_argtps, (id->id_nrargs == 0 ? "" : id->id_argtps),
id->id_class == FC ? ( id->id_class == FC
(id->id_valused == USED ? "USED" : ? ( id->id_valused == USED ? "USED" :
id->id_valused == IGNORED ? "IGNORED" : id->id_valused == IGNORED ? "IGNORED" :
id->id_valused == VOIDED ? "VOIDED" : id->id_valused == VOIDED ? "VOIDED" :
"<BAD VALUSED>") "<BAD VALUSED>"
: (id->id_valreturned == NOVALRETURNED ?
"NOVALRETURNED" :
id->id_valreturned == VALRETURNED ?
"VALRETURNED" :
id->id_valreturned == NORETURN ?
"NORETURN" : "<BAD VALRETURNED>"
) )
: ( id->id_valreturned == NOVALRETURNED
? "NOVALRETURNED"
: id->id_valreturned == VALRETURNED
? "VALRETURNED"
: id->id_valreturned == NORETURN
? "NORETURN"
: "<BAD VALRETURNED>"
)
)
); );
} }
print("\n"); print("\n");

View file

@ -92,7 +92,7 @@ ReadString(buf, delim, maxsize)
/* Reads a string until 'delim' is encountered; delim is /* Reads a string until 'delim' is encountered; delim is
discarded. discarded.
If 'maxsize-1' is exceeded or the string contains a newline 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. A '\0' is appended to the string.
*/ */
@ -106,14 +106,14 @@ ReadString(buf, delim, maxsize)
if (ch == delim) if (ch == delim)
break; break;
if (ch == '\n') { if (ch == '\n') {
panic("newline in string"); panic("incomplete line in intermediate file");
/*NOTREACHED*/ /*NOTREACHED*/
} }
buf[nread++] = (char)ch; buf[nread++] = (char)ch;
} }
buf[nread++] = '\0'; buf[nread++] = '\0';
if (ch != delim) { if (ch != delim) {
panic("string too long"); panic("line too long in intermediate file");
/*NOTREACHED*/ /*NOTREACHED*/
} }
return 1; return 1;
@ -148,7 +148,7 @@ ReadInt(ip)
loadchar(ch); loadchar(ch);
} }
pushback(ch); pushback(ch);
*ip = negative ? -res : res; *ip = (negative ? -res : res);
return 1; return 1;
} }
@ -213,9 +213,11 @@ PRIVATE SkipChar(ch)
int c; int c;
loadchar(c); loadchar(c);
if (c != ch) { if (c == ch)
panic("bad format, '%c' expected; '%c' read", ch, c); return;
/*NOTREACHED*/ panic("bad format in intermediate file, '%c' expected; '%c' read",
} ch, c
);
/*NOTREACHED*/
} }

View file

@ -8,11 +8,12 @@
#include <system.h> #include <system.h>
#include "private.h" #include "private.h"
#include "../lpass1/l_class.h"
#include "class.h" #include "class.h"
#include "inpdef.h" #include "inpdef.h"
#define MSGOUT STDERR /* filedes on which to write the messages */ #define MSGOUT STDERR /* file descr. on which to write the messages */
#define ERROUT STDERR /* filedes on which to write the panics */ #define ERROUT STDERR /* file descr. on which to write the panics */
extern int LineNr; extern int LineNr;
@ -75,7 +76,8 @@ report(va_alist)
fprint(MSGOUT, "%d", i); fprint(MSGOUT, "%d", i);
break; break;
default: default:
panic("bad format %s", fmt); panic("internal error: bad format %s",
fmt);
break; break;
} }
} }